logo
0
0
WeChat Login

WebServer - Midway.js + Vue3 + TypeScript 全栈模板项目

公司内部项目模板 - 基于 Midway.js + Vue3 + TypeScript + TypeORM + Bootstrap5 的现代化全栈开发模板,提供完整的用户管理、权限控制、文件上传等功能。

🚀 技术栈

后端技术栈

  • 框架: Midway.js 3.x (Node.js 企业级框架)
  • 语言: TypeScript
  • 数据库: MySQL + TypeORM
  • 认证: 基于 Session 的用户认证(支持本地验证和远程服务验证)
  • 文件上传: Busboy + 腾讯云 COS
  • API 文档: Swagger UI
  • 缓存: Cache Manager
  • 日志: 内置日志系统

前端技术栈

  • 框架: Vue 3.5.x + Composition API
  • 构建工具: Vite 7.x
  • UI 框架: Bootstrap 5 + Bootstrap Icons
  • 状态管理: Pinia + Vuex 4 (兼容模式)
  • 路由: Vue Router 4
  • 类型检查: TypeScript
  • 图表库: ECharts 6
  • 表格组件: Element Plus
  • 工具库: Lodash-es, Day.js, Axios

开发工具

  • 代码规范: ESLint + Prettier + mwts
  • 测试框架: Jest + Vitest
  • 容器化: Docker + Docker Compose
  • 进程管理: PM2

📁 项目结构

template/
├── bin/                    # 脚本文件
│   ├── init.js             # 项目初始化脚本(自动安装依赖)
│   ├── dev.sh              # 开发环境启动脚本
│   ├── build.sh            # 构建脚本
│   └── deploy.sh           # 部署脚本
├── src/                    # 后端源码
│   ├── config/             # 配置文件
│   │   ├── config.default.ts    # 默认配置
│   │   ├── config.local.ts      # 本地开发配置
│   │   └── devops.config.ts     # 部署配置(路由前缀等)
│   ├── controller/         # 控制器层(处理HTTP请求)
│   │   ├── admin.controller.ts  # 管理端接口代理
│   │   ├── user.controller.ts   # 用户管理接口
│   │   ├── session.controller.ts # 登录/登出接口
│   │   └── home.controller.ts   # 页面渲染入口
│   ├── service/            # 业务逻辑层
│   │   ├── user.service.ts      # 用户业务逻辑
│   │   ├── session.service.ts   # 会话管理逻辑
│   │   └── account.service.ts   # 账户服务(远程API)
│   ├── model/              # 数据模型 (TypeORM 实体)
│   │   └── user.entity.ts       # 用户实体定义
│   ├── dto/                # 数据传输对象(请求参数验证)
│   │   └── user.dto.ts          # 用户相关DTO
│   ├── filter/             # 异常过滤器
│   │   ├── default.filter.ts    # 全局异常处理
│   │   └── notfound.filter.ts   # 404处理
│   ├── guard/              # 守卫(预留目录)
│   ├── interface/          # 类型定义
│   ├── lib/                # 工具库
│   └── configuration.ts    # 应用入口配置
├── web/                    # 前端源码
│   ├── src/
│   │   ├── platform/       # 平台核心(入口、根组件)
│   │   ├── pages/         # 页面组件
│   │   ├── components/    # 公共组件
│   │   │   ├── dataGrid/        # 数据表格组件
│   │   │   ├── loading/         # 加载状态组件
│   │   │   ├── modal/           # 模态框组件
│   │   │   └── toast/           # 消息提示组件
│   │   ├── service/       # API 服务层
│   │   │   ├── base.ts          # 基础请求封装
│   │   │   ├── account.ts       # 账户相关API
│   │   │   └── mock/            # Mock数据
│   │   ├── stores/        # 状态管理 (Pinia)
│   │   │   └── session.ts       # 登录态管理
│   │   ├── utils/         # 工具函数
│   │   ├── base/          # 基础层(事件总线、配置等)
│   │   ├── domain/        # 领域层
│   │   ├── directives/    # Vue指令
│   │   └── assets/        # 静态资源
│   ├── public/            # 静态资源(构建后复制)
│   ├── view/              # HTML 模板入口
│   └── vite.config.ts     # Vite 配置
├── data/                   # 数据文件
│   └── db_myproject_t_user.sql  # 数据库初始化脚本
├── logs/                   # 日志目录(运行时生成)
├── dist/                   # 构建输出
├── typings/                # 类型定义
├── skills/                 # 开发规范文档
│   ├── SKILL.md           # 主入口文档
│   ├── coding-standards.md # 编码规范
│   ├── fullstack/         # 全栈开发技能
│   ├── database/          # 数据库开发技能
│   ├── frontend/          # 前端开发技能
│   └── backend/           # 后端开发技能
├── .env                    # 环境变量(需从 .tpl.env 复制)
├── .tpl.env               # 环境变量模板
├── bootstrap.js            # 生产环境启动入口
├── package.json            # 项目依赖和脚本
└── README.md               # 本文档

🛠️ 快速开始

环境要求

  • Node.js >= 20.0.0
  • MySQL >= 5.7
  • pnpm(推荐)或 npm

1. 克隆项目

git clone <repository-url>
cd template

2. 安装依赖

方式一:一键安装(推荐)

# 自动检测并使用 pnpm(优先)或 npm 安装所有依赖
npm run init

方式二:手动安装

# 安装后端依赖
pnpm install

# 安装前端依赖
cd web && pnpm install && cd ..

3. 环境配置

复制环境变量模板并修改:

cp .tpl.env .env

编辑 .env 文件,配置必要参数:

# ===== 服务配置 =====
PORT=8000                    # 服务端口
TITLE=管理系统               # 系统标题
PREFIX=my-project            # URL前缀(部署路径)

# ===== 数据库配置 =====
# 设置 DISABLE_DB=true 可无数据库启动(用于前端开发)
DISABLE_DB=false
DB_HOST=localhost            # 数据库地址
DB_PORT=3306                 # 数据库端口
DB_USERNAME=root             # 数据库用户名
DB_PASSWORD=your_password    # 数据库密码
DB_DATABASE=db_myproject     # 数据库名称

# ===== 安全配置(必填) =====
SESSION_SECRET=your-secret-key-at-least-32-chars  # Session密钥,至少32字符

# ===== API配置 =====
API_URL=                     # 后端API地址(留空使用本地验证)
BASE_SERVER_URL=             # 远程基础服务地址(可选)

# ===== 腾讯云配置(可选) =====
TENCENT_CREDENTIAL_SECRETID=     # 腾讯云SecretId
TENCENT_CREDENTIAL_SECRETKEY=    # 腾讯云SecretKey
TENCENT_COS_DEFAULT_BUCKET=      # COS存储桶名称
TENCENT_COS_DEFAULT_REGION=      # COS地域

4. 数据库初始化

# 创建数据库
mysql -u root -p -e "CREATE DATABASE db_myproject DEFAULT CHARSET utf8mb4"

# 导入初始数据(包含admin管理员账号)
mysql -u root -p db_myproject < data/db_myproject_t_user.sql

默认管理员账号: admin / admin123

5. 启动开发服务器

方式一:使用脚本启动(推荐)

npm run dev

这将同时启动前后端开发服务器,前端支持热更新。

方式二:分别启动

# 终端1:启动后端 (端口 8000)
npm run dev:midway

# 终端2:启动前端 (端口 5173)
npm run dev:vue

6. 访问应用

📖 核心功能

🔐 用户认证系统

  • 基于 Session 的用户认证
  • 支持本地账号密码验证和远程服务验证两种模式
  • 密码使用 bcrypt 加密存储(兼容旧版 MD5)
  • 登录状态持久化(SessionStorage)
  • 权限控制装饰器 @decorators.checkLogin()

👥 用户管理

功能接口描述
用户搜索POST /api/user/search分页获取用户列表,支持多字段筛选
用户详情POST /api/user/getUserDetail获取用户详细信息
创建用户POST /api/user/create创建新用户(需管理员权限)
更新用户POST /api/user/update更新用户信息(需管理员权限)
修改密码POST /api/user/updatePassword修改用户密码
设置状态POST /api/user/setStatus启用/禁用用户(需管理员权限)
上传头像POST /api/user/uploadAvatar上传用户头像到腾讯云COS

📁 文件上传

  • 支持多种图片格式
  • 自动上传到腾讯云 COS
  • 文件大小限制
  • 临时文件自动清理

🎨 前端特性

  • 响应式设计,支持移动端
  • 组件化开发
  • 状态管理(Pinia)
  • 路由懒加载
  • TypeScript 类型检查
  • Vite 热更新
  • Mock 数据支持

🔧 开发指南

后端开发

创建新的控制器

// src/controller/example.controller.ts
import { Controller, Get, Post, Provide, Body } from '@midwayjs/core';
import { BaseController, decorators } from '@cicctencent/midwayjs-base';

@Provide()
@Controller('/api/example')
export class ExampleController extends BaseController {
    
    @Get('/list')
    async list() {
        return { ret: 0, data: [], msg: 'success' };
    }

    @Post('/create')
    @decorators.checkLogin(true)  // 需要登录
    async create(@Body() data: CreateDTO) {
        // 业务逻辑
        return { ret: 0, msg: '创建成功' };
    }
}

创建新的服务

// src/service/example.service.ts
import { Provide, Inject } from '@midwayjs/core';
import { BaseService } from '@cicctencent/midwayjs-base';
import { InjectDataSource } from '@midwayjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import ExampleEntity from '../model/example.entity';

@Provide()
export class ExampleService extends BaseService {
    @InjectDataSource('default')
    dataSource: DataSource;

    get model(): Repository<ExampleEntity> {
        return this.dataSource.getRepository(ExampleEntity);
    }

    async search(params: SearchParams) {
        // 查询逻辑
        return await this.model.find({ where: params });
    }
}

创建数据模型

// src/model/example.entity.ts
import BaseEntity from '@fefeding/common/dist/models/base/baseORM';
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity('t_example')
export default class ExampleEntity extends BaseEntity {
    @PrimaryGeneratedColumn({ name: 'id', comment: '自增主键' })
    id: number;

    @Column({ name: 'Fname', length: 100, comment: '名称' })
    name: string;

    @Column({ name: 'Fstatus', type: 'smallint', default: 1, comment: '状态' })
    status: number;
}

创建 DTO(请求参数验证)

// src/dto/example.dto.ts
import { Rule, RuleType } from '@midwayjs/validate';

@Rule(RuleType.object())
export class CreateExampleDTO {
    @Rule(RuleType.string().min(2).max(100).required())
    name: string;

    @Rule(RuleType.number().integer().positive().optional())
    status?: number;
}

前端开发

创建新的页面

<!-- web/src/pages/example.vue -->
<template>
  <div class="container">
    <h1>示例页面</h1>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useSessionStore } from '@/stores/session';

const sessionStore = useSessionStore();

onMounted(() => {
  console.log('页面加载完成');
});
</script>

创建 API 服务

// web/src/service/example.ts
import { request } from './base';

export async function getExampleList(params: any) {
    return request('/api/example/list', params);
}

export async function createExample(data: any) {
    return request('/api/example/create', data);
}

使用状态管理

import { useSessionStore } from '@/stores/session';

const sessionStore = useSessionStore();

// 检查登录状态
if (sessionStore.isLoggedIn) {
    console.log('当前用户:', sessionStore.userName);
}

// 更新用户信息
sessionStore.updateUserInfo({ name: '新名称' });

🚀 部署指南

1. 构建项目

npm run build

构建完成后,产物在 dist/ 目录。

2. 生产环境启动

# 使用 PM2 启动(推荐)
npm start

# 或直接启动
node bootstrap.js

3. Docker 部署

构建镜像

npm run docker

运行容器

docker run -d -p 8000:8000 -v $(pwd)/.env:/app/.env --name web-server base-server

4. TARS 部署(腾讯云)

npm run tars:deploy

📝 API 文档

统一返回格式

interface ApiResponse<T> {
    ret: number;    // 0 成功,非 0 失败
    data?: T;       // 响应数据
    msg: string;    // 提示信息
}

常见错误码

错误码描述
0成功
1业务错误
1000未知错误
50001登录态失效

会话接口 (Session)

接口方法路径描述权限
账号登录POST/api/session/loginByAccount账号密码登录无需登录
微信登录POST/api/session/loginByWx微信扫码登录无需登录
登出POST/api/session/logout退出登录无需登录
获取会话POST/api/session/getLoginSession获取当前登录态无需登录
授权码登录POST/api/session/loginByCode临时授权码登录无需登录

用户接口 (User)

接口方法路径描述权限
用户搜索POST/api/user/search分页搜索用户需要登录
用户详情POST/api/user/getUserDetail获取用户详情需要登录
创建用户POST/api/user/create创建新用户管理员
更新用户POST/api/user/update更新用户信息管理员
修改密码POST/api/user/updatePassword修改密码需要登录
设置状态POST/api/user/setStatus启用/禁用用户管理员
上传头像POST/api/user/uploadAvatar上传头像需要登录

🧪 测试

运行测试

# 后端单元测试
npm test

# 测试覆盖率
npm run cov

代码检查

# 代码规范检查
npm run lint

# 自动修复
npm run lint:fix

📦 常用命令

开发相关

命令描述
npm run init一键安装所有依赖
npm run dev启动开发环境(前后端)
npm run dev:midway仅启动后端
npm run dev:vue仅启动前端

构建相关

命令描述
npm run build构建生产版本
npm run build:vue仅构建前端
npm run build:midway仅构建后端

部署相关

命令描述
npm startPM2 启动生产服务
npm restart重启服务
npm stop停止服务
npm run deploy完整部署流程
npm run zip打包为 server.zip
npm run docker构建 Docker 镜像

🔧 配置说明

后端配置文件

文件用途
config.default.ts默认配置(数据库、Session、COS等)
config.local.ts本地开发配置(视图路径、静态文件)
devops.config.ts部署配置(URL前缀、系统标题)

前端配置文件

文件用途
vite.config.tsVite 构建配置
tsconfig.jsonTypeScript 配置

环境变量说明

变量必填描述
PORT服务端口,默认 7001
SESSION_SECRETSession密钥,至少32字符
DB_HOST数据库地址
DB_DATABASE数据库名称
DISABLE_DB设为 true 可无数据库启动
PREFIXURL前缀(部署路径)
API_URL远程API地址
TITLE系统标题

🤝 开发规范

详见 skills/README.mdskills/coding-standards.md

Git 提交规范

feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 重构
test: 测试相关
chore: 构建/工具链相关

🆘 常见问题

Q: 如何无数据库启动?

A: 设置 DISABLE_DB=true,适用于纯前端开发场景。

Q: 如何修改 API 前缀?

A: 修改 .env 中的 PREFIX 变量,如 PREFIX=my-app

Q: 如何添加新的权限控制?

A: 使用 @decorators.checkLogin(true) 装饰器,或在配置中添加 auth.ignores 规则。

Q: 登录态失效怎么办?

A: 检查 SESSION_SECRET 是否正确配置,确保 Session 存储正常。

Q: 如何配置 CORS?

A: 后端默认支持 CORS,可在 config.default.ts 中详细配置。

Q: 如何对接远程用户服务?

A: 配置 BASE_SERVER_URL 指向远程服务地址,系统会自动使用远程验证。

📞 技术支持

如有问题,请联系项目维护者或提交 Issue。


版本: 2.0.0
更新日期: 2026-05-21
作者: fefeding

About

项目模板

7.54 MiB
Skills
0 forks0 stars1 branches0 TagREADME
Language
Vue59.8%
TypeScript34.6%
Smarty0.7%
Dockerfile0.6%
Others4.3%