Skip to content

Commit

Permalink
新增数据库配置信息和文档 (#67)
Browse files Browse the repository at this point in the history
* fix: add database sql file

* docs: update readme database

* fix: fix error log

* fix: fix token expire

* feat: auto create database

* docs: update pro readme

* docs: update pro readme

* docs: update pro readme

* fix: pro init log info
  • Loading branch information
wjiangwang authored Jun 29, 2023
1 parent 9318956 commit 4347b59
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 34 deletions.
37 changes: 29 additions & 8 deletions packages/toolkits/pro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ tiny-toolkit-pro 套件,开箱即用的中后台前端/设计解决方案
tiny init pro
```
### 配置项目名称、描述
项目名称默认是当前所在文件夹名称
项目名称默认是当前所在文件夹名称

```
? 请输入项目名称:
? 请输入项目描述: (基于TinyPro套件创建的中后台系统)
```
### 选择前端技术栈
目前支持```vue``` ```angular```两种前端技术栈。
目前支持`Vue` `Angular`两种前端技术栈。
```
? 请选择您希望使用的技术栈: (Use arrow keys)
> vue
angular
```
### 选择服务端技术栈(可选配置)
**目前仅 ```vue```工程支持对接服务端,且只支持```Egg.js```,剩余功能正在开发中**
**目前仅 `Vue`工程支持对接服务端,且只支持`Egg.js`,剩余功能正在开发中**
如果选择不对接服务端,全部接口将采用mock数据。
```
? 请选择您希望使用的服务端技术栈: (Use arrow keys)
Expand All @@ -35,30 +35,51 @@ tiny init pro
Nest.js
暂不配置
```
### 配置数据库信息(可选配置)

### 选择数据库(可选配置)
```
? 请选择数据库类型: (Use arrow keys)
> mySQL
暂不配置
```
### 数据库准备工作
可使用本地数据库或云数据库,请提前安装配置本地数据库服务或者云数据库服务,确保连接正常可用。
- MySQL[下载链接](https://dev.mysql.com/downloads/)
- 云数据库推荐使用[华为云数据库RDS](https://support.huaweicloud.com/productdesc-rds/zh-cn_topic_dashboard.html),可参考[云服务最佳实践](https://opentiny.design/vue-pro/docs/advanced/practiced) 创建数据库。


### 配置数据库信息

- **初始化过程中会自动创建数据库和表,建议输入新的数据库名称以免造成数据库覆盖风险。**
```
? 请输入数据库地址: (localhost)
? 请输入数据库端口: (3306)
? 请输入数据库名称:
? 请输入登录用户名: (root)
? 请输入密码: [input is hidden]
```
- 此处配置也可在项目创建完成后在`server/config/config.default.ts`中进行配置修改。
- pro套件会在初始化时自动创建数据库和表,如因配置等问题导致数据库初始化失败,有以下两种方式可帮助重新初始化数据库:
- 确认好正确配置后重新运行 `tiny init pro` 覆盖安装。
- 进入 `server/app/databases` 目录下手动执行相关sql。
- 数据库表中会自动插入一条用户信息(账号:[email protected] 密码:admin),可直接用于登录。
- 如server服务启动失败,请确保数据库服务的地址、名称、账号、密码等与`server/config/config.default.ts` 中配置一致。
- `server/app.ts` 中会同步ORM模型到数据库帮助新建表但只建议在开发环境下使用。

### 开启本地服务器

Web
```
cd web && npm run start
```
tiny start
Egg
```
cd server && npm run dev
```

### 代码打包

进入对应目录下执行
```
tiny build
npm run build
```

## 维护者
Expand Down
1 change: 1 addition & 0 deletions packages/toolkits/pro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"ejs": "^3.1.9",
"fs-extra": "^10.1.0",
"inquirer": "^8.0.2",
"mysql2": "^3.4.2",
"open": "^8.4.0"
},
"devDependencies": {
Expand Down
87 changes: 82 additions & 5 deletions packages/toolkits/pro/src/lib/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import chalk from 'chalk';
import spawn from 'cross-spawn';
import * as dotenv from 'dotenv';
import mysql from 'mysql2/promise';
import inquirer, { QuestionCollection } from 'inquirer';
import { cliConfig, logs, fs } from '@opentiny/cli-devkit';
import { ProjectInfo, ServerFrameworks } from './interfaces';
Expand Down Expand Up @@ -112,6 +113,57 @@ const getProjectInfo = (): Promise<ProjectInfo> => {
return inquirer.prompt(question);
};

/**
* 创建数据库、表、并插入一条用户(admin)数据
* @answers 询问客户端问题的选择值
*/
const createDatabase = async (answers: ProjectInfo) => {
const { dialect, host, port, database, username, password } = answers;
if (!dialect) return;

log.info('开始连接数据库服务...');
const connection = await mysql.createConnection({
host,
port,
user: username,
password,
multipleStatements: true,
});

// 连接数据库服务
await connection.connect();
log.info(`连接成功,准备创建数据库(${database})和用户数据表...`);

// 新建数据库
await connection.query(`CREATE DATABASE IF NOT EXISTS ${database}`);
await connection.query(` USE ${database}`);

// 读取sql文件、新建表
const serverPath = utils.getDistPath('server');
const databaseSqlDir = path.join(serverPath, 'app', 'database');
const tableSqlDirPath = path.join(databaseSqlDir, 'table');
const files = fs.readdirSync(tableSqlDirPath);
for (const file of files) {
if (/\.sql$/.test(file)) {
const sqlFilePath = path.join(tableSqlDirPath, file);
const createTableSql = fs.readFileSync(sqlFilePath).toString();
await connection.query(createTableSql);
}
}
log.info(
'创建成功,开始写入初始用户数据(账号:[email protected] 密码:admin)...'
);

// 插入初始用户数据
const createUserSqlPath = path.join(databaseSqlDir, 'createuser.sql');
const createUserSql = fs.readFileSync(createUserSqlPath).toString();
await connection.query(createUserSql);
log.success('数据库初始化成功!');

// 断开连接
await connection.end();
};

/**
* 同步创建服务端项目文件目录、文件
* @answers 询问客户端问题的选择值
Expand All @@ -131,6 +183,7 @@ const createServerSync = (answers: ProjectInfo) => {
password: '123456',
database: 'tiny_pro_server',
};

fs.copyTpl(serverFrom, serverTo, dialect ? answers : defaultConfig, {
overwrite: true,
});
Expand Down Expand Up @@ -214,11 +267,26 @@ export const installDependencies = (answers: ProjectInfo) => {
'\n--------------------初始化成功,请按下面提示进行操作--------------------\n'
)
);
console.log(
chalk.green(
`${chalk.yellow(`$ ${prefix} start`)} # 可一键开启项目开发环境`
)
);

if (answers.serverFramework) {
console.log(
chalk.green(
`${chalk.yellow('$ cd web && npm run start')} # 开启web开发环境`
)
);
console.log(
chalk.green(
`${chalk.yellow('$ cd server && npm run dev')} # 开启server开发环境`
)
);
} else {
console.log(
chalk.green(
`${chalk.yellow(`$ ${prefix} start`)} # 可一键开启项目开发环境`
)
);
}

console.log(
chalk.green(
`${chalk.yellow(`$ ${prefix} help`)} # 可查看当前套件的详细帮助`
Expand Down Expand Up @@ -250,6 +318,15 @@ export default async () => {
log.error('项目模板创建失败');
}

// 初始化数据库
try {
await createDatabase(projectInfo);
} catch (e) {
log.error(
'数据库初始化失败,请确认数据库配置信息正确并手动初始化数据库' + e
);
}

// 安装依赖
try {
installDependencies(projectInfo);
Expand Down
4 changes: 2 additions & 2 deletions packages/toolkits/pro/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export enum ServerFrameworks {
EggJs = 'eggJs',
NestJs = 'nestJs',
SpringCloud = 'springCloud',
Skip = ''
Skip = '',
}

/**
Expand All @@ -26,7 +26,7 @@ export interface ProjectInfo {
serverFramework: ServerFrameworks;
dialect?: string;
host?: string;
port?: Number;
port?: number;
database?: string;
username?: string;
password?: string;
Expand Down
14 changes: 14 additions & 0 deletions packages/toolkits/pro/template/server/eggJs/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Application } from 'egg';

export default (app: Application) => {
// 数据库模型同步,只建议在开发环境下使用
if (app.config.env === 'local') {
try {
app.beforeStart(async () => {
await app.model.sync({ alter: true });
});
} catch (error) {
console.error('数据库同步失败,请检查数据库配置信息或手动创建数据库', error);
}
}
};

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
INSERT INTO registeruser
VALUES (
null,
'[email protected]',
'$2b$10$W2NoJWWldrv4ksIalH7po.4vsczt3TlP8SepiEVNEanXzYTIxnIVu',
'email'
);

INSERT INTO userinfo
VALUES (
null,
(SELECT id
FROM registeruser
WHERE
user_name = '[email protected]')

,
'[email protected]',
'Tiny-Vue-Pro',
'social recruitment',
'admin',
'2023-06-01',
'2023-09-30',
'90',
'2023-06-01',
'2026-06-01',
'beijing',
'1',
'Front end'
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
DROP TABLE IF EXISTS `employee`;

CREATE TABLE
`employee` (
`id` bigint(16) NOT NULL,
`name` varchar(20) DEFAULT NULL COMMENT '姓名',
`employee_no` varchar(50) DEFAULT NULL COMMENT '工号',
`department` varchar(50) DEFAULT NULL COMMENT '部门',
`department_level` varchar(50) DEFAULT NULL COMMENT '部门层级',
`status` varchar(10) DEFAULT NULL COMMENT '状态',
`workbench_name` varchar(50) DEFAULT NULL COMMENT '工作台名称',
`project` varchar(50) DEFAULT NULL COMMENT '赋能项目',
`type` varchar(50) DEFAULT NULL COMMENT '人员类型',
`address` varchar(50) DEFAULT NULL COMMENT '研究所',
`roles` varchar(50) DEFAULT NULL COMMENT '角色',
`last_update_user` varchar(50) DEFAULT NULL COMMENT '最后更新人',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB DEFAULT CHARSET = utf8 ROW_FORMAT = DYNAMIC;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DROP TABLE IF EXISTS `registeruser`;
CREATE TABLE
`registeruser` (
`id` bigint(50) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(20) NOT NULL COMMENT '用户名',
`password` varchar(60) NOT NULL COMMENT '密码',
`register_type` varchar(10) DEFAULT NULL COMMENT '注册类型',
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
DROP TABLE IF EXISTS `userinfo`;

CREATE TABLE
`userinfo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned DEFAULT NULL,
`user_name` varchar(32) NOT NULL COMMENT '用户名',
`department` varchar(32) NOT NULL DEFAULT '' COMMENT '部门',
`employee_type` varchar(32) DEFAULT NULL COMMENT '招聘类型',
`role` varchar(32) DEFAULT NULL COMMENT '角色',
`probation_start` date DEFAULT NULL COMMENT '试用期开始时间',
`probation_end` date DEFAULT NULL COMMENT '试用期结束时间',
`probation_duration` bigint(11) unsigned DEFAULT NULL COMMENT '试用期时长',
`protocol_start` date DEFAULT NULL COMMENT '合同开始日期',
`protocol_end` date DEFAULT NULL COMMENT '合同结束日期',
`address` varchar(32) DEFAULT NULL COMMENT '地址',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`job` varchar(32) DEFAULT NULL COMMENT '职位',
PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module.exports = (app: any) => {
field: 'create_time',
type: DataTypes.TIME,
allowNull: true,
defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'),
defaultValue: DataTypes.NOW,
},
},
{
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { Modal } from '@opentiny/vue';
import locale from '@opentiny/vue-locale';
import router from '@/router';
import { getToken } from '@/utils/auth';
import { getToken, clearToken } from '@/utils/auth';

export interface HttpResponse<T = unknown> {
errMsg: string;
Expand Down Expand Up @@ -59,6 +59,7 @@ axios.interceptors.response.use(
(error) => {
const { status, data } = error.response;
if (status === 401) {
clearToken();
router.replace({ name: 'login' });
Modal.message({
message: locale.t('http.error.TokenExpire'),
Expand Down

0 comments on commit 4347b59

Please sign in to comment.