├── .dockerignore
├── .eslintrc.js
├── .gitattributes
├── .gitignore
├── .prettierrc
├── .vscode
└── settings.json
├── Dockerfile
├── LICENSE
├── README.md
├── nest-cli.json
├── nest.sql
├── package.json
├── public
└── index.html
├── src
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── config
│ ├── constants.ts
│ ├── env
│ │ ├── development.ts
│ │ ├── production.ts
│ │ └── test.ts
│ ├── index.ts
│ └── log4js.ts
├── core
│ ├── code.enum.ts
│ ├── resultBean.ts
│ └── transform.ts
├── entities
│ ├── AdCodelist.ts
│ ├── AdCodelistType.ts
│ ├── Dept.ts
│ ├── Dynamictables.ts
│ ├── Form.ts
│ ├── Person.ts
│ ├── PersonEducation.ts
│ ├── PersonResume.ts
│ ├── Role.ts
│ └── Users.ts
├── events
│ ├── events.gateway.ts
│ └── events.module.ts
├── filter
│ ├── any-exception.filter.ts
│ ├── api-exception.filter.ts
│ └── http-exception.filter.ts
├── guards
│ ├── auth-guards.ts
│ ├── customize.ts
│ ├── jwt-auth.guard.ts
│ └── jwt.strategy.ts
├── interceptor
│ └── transform.interceptor.ts
├── main.ts
├── middleware
│ └── logger.middleware.ts
├── module
│ ├── ad-codelist-type
│ │ ├── ad-codelist-type.controller.ts
│ │ ├── ad-codelist-type.module.ts
│ │ └── ad-codelist-type.service.ts
│ ├── ad-codelist
│ │ ├── ad-codelist.controller.ts
│ │ ├── ad-codelist.module.ts
│ │ └── ad-codelist.service.ts
│ ├── auth
│ │ ├── auth.module.ts
│ │ └── auth.service.ts
│ ├── base
│ │ ├── base.controller.ts
│ │ └── base.service.ts
│ ├── dept
│ │ ├── dept.controller.ts
│ │ ├── dept.module.ts
│ │ └── dept.service.ts
│ ├── dynamictables
│ │ ├── dynamictables.controller.ts
│ │ ├── dynamictables.module.ts
│ │ └── dynamictables.service.ts
│ ├── form
│ │ ├── form.controller.ts
│ │ ├── form.module.ts
│ │ └── form.service.ts
│ ├── person
│ │ ├── education
│ │ │ ├── education.controller.ts
│ │ │ ├── education.module.ts
│ │ │ └── education.service.ts
│ │ ├── person.controller.ts
│ │ ├── person.module.ts
│ │ ├── person.service.ts
│ │ └── resume
│ │ │ ├── resume.controller.ts
│ │ │ ├── resume.module.ts
│ │ │ └── resume.service.ts
│ ├── role
│ │ ├── role.controller.ts
│ │ ├── role.module.ts
│ │ └── role.service.ts
│ ├── upload
│ │ ├── upload.controller.ts
│ │ ├── upload.module.ts
│ │ └── upload.service.ts
│ └── users
│ │ ├── users.controller.ts
│ │ ├── users.module.ts
│ │ └── users.service.ts
└── utils
│ ├── file.ts
│ └── log4js.ts
├── test
├── app.e2e-spec.ts
└── jest-e2e.json
├── tsconfig.build.json
├── tsconfig.json
└── yarn.lock
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Versioning and metadata
2 | .git
3 | .gitignore
4 | .dockerignore
5 |
6 | # Build dependencies
7 | dist
8 | node_modules
9 | coverage
10 |
11 | # Environment (contains sensitive data)
12 | .env
13 |
14 | # Files not required for production
15 | .editorconfig
16 | Dockerfile
17 | README.md
18 | tslint.json
19 | nodemon.json
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // .eslintrc.js
2 | module.exports = {
3 | parser: '@typescript-eslint/parser',
4 | extends: ['plugin:@typescript-eslint/recommended'],
5 | plugins: ['@typescript-eslint'],
6 | rules: {
7 | // 这条规则是为了防止写class interface的member时,分隔符和prettier产生冲突
8 | '@typescript-eslint/ban-ts-comment': 'off',
9 | '@typescript-eslint/no-var-requires': 'off',
10 | '@typescript-eslint/explicit-module-boundary-types': 'off',
11 | '@typescript-eslint/no-explicit-any': 'off',
12 | '@typescript-eslint/no-empty-function': 'off',
13 | '@typescript-eslint/member-delimiter-style': [
14 | 'error',
15 | {
16 | multiline: {
17 | delimiter: 'none',
18 | requireLast: false
19 | },
20 | singleline: {
21 | delimiter: 'comma',
22 | requireLast: false
23 | }
24 | }
25 | ]
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sql linguist-language=TypeScript
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /dist
3 | /node_modules
4 | /public/affix
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 |
13 | # OS
14 | .DS_Store
15 |
16 | # Tests
17 | /coverage
18 | /.nyc_output
19 |
20 | # IDEs and editors
21 | /.idea
22 | .project
23 | .classpath
24 | .c9/
25 | *.launch
26 | .settings/
27 | *.sublime-workspace
28 |
29 | # IDE - VSCode
30 | .vscode/*
31 | !.vscode/settings.json
32 | !.vscode/tasks.json
33 | !.vscode/launch.json
34 | !.vscode/extensions.json
35 | package-lock.json
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": false
4 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.validate": [
3 | "javascript",
4 | "typescript"
5 | ],
6 | "editor.codeActionsOnSave": {
7 | "source.fixAll.eslint": true
8 | }
9 | }
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16-alpine as builder
2 |
3 | ENV NODE_ENV build
4 |
5 | USER node
6 | WORKDIR /home/node
7 |
8 | COPY package*.json yarn.lock ./
9 | RUN npm ci
10 |
11 | COPY --chown=node:node . .
12 | RUN npm run build \
13 | && npm prune --production
14 |
15 | # ---
16 |
17 | FROM node:16-alpine
18 |
19 | ENV NODE_ENV production
20 |
21 | USER node
22 | WORKDIR /home/node
23 |
24 | COPY --from=builder --chown=node:node /home/node/package*.json ./
25 | COPY --from=builder --chown=node:node /home/node/node_modules/ ./node_modules/
26 | COPY --from=builder --chown=node:node /home/node/dist/ ./dist/
27 |
28 | CMD ["npm", "run pm2"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 BoBoooooo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BoBo-NestJS-Server
2 |
3 |
4 |
5 |
6 |
7 | [travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master
8 | [travis-url]: https://travis-ci.org/nestjs/nest
9 | [linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
10 | [linux-url]: https://travis-ci.org/nestjs/nest
11 |
12 | A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 | 🚀 轻量级 `NestJS-API` 脚手架,欢迎 Star!
31 |
32 | ## Demo
33 |
34 | **域名&服务器已过期...暂时没法访问,抱歉**
35 |
36 |
37 | ## 1. 开始使用
38 |
39 | * git clone https://github.com/BoBoooooo/NestJS-API-Server.git
40 | * yarn
41 | * 配置mysql数据库
42 | * 新建数据库 `nest`
43 | * 导入 `nest.sql`
44 | * 修改以下相关数据库配置
45 | * `package.json->scripts->db`
46 | * `/src/config/env/*`
47 | * yarn start
48 | * yarn db
49 |
50 | ## 2.目录结构
51 |
52 | ```bash
53 | ├── public # public
54 | │ └── index.html # 测试socket.io页面
55 | ├── src # src
56 | │ ├── config # 环境变量等配置文件
57 | │ ├── core # 通用定义文件
58 | │ ├── entities # 数据库ORM Entity
59 | │ ├── events # webSocket
60 | │ ├── filter # 全局异常filter
61 | │ ├── guards # 路由守卫(鉴权)
62 | │ ├── interceptor # interceptor
63 | │ ├── logs # logs
64 | │ ├── middleware # middleware logs
65 | │ ├── module # 各个业务模块,包含base module
66 | │ ├── utils # 工具函数
67 | ├── test # 测试
68 | ````
69 |
70 | ## 3. 功能
71 |
72 | - 登录、JWT鉴权
73 |
74 | - Socket.IO
75 |
76 | 默认Socket.IO监听8080端口 `/src/events/events.gateway.ts`
77 |
78 | client端实现查看 `/public/index.html`
79 |
80 | - `BaseController` `BaseService` 封装基础CRUD接口
81 | - /xxx/add
82 | - /xxx/update
83 | - /xxx/delete
84 | - /xxx/list
85 | - /xxx/tree
86 | - /xxx/detail
87 |
88 | - list接口支持`高级查询`,具体实现查看`BaseService`
89 |
90 | ```javascript
91 | 示例:
92 | curl - POST /users/list
93 | {
94 | "searchCondition":[{
95 | "field":"userName",
96 | "operator":"like",
97 | "value":"ce"
98 | },
99 | {
100 | "field":"userName",
101 | "operator":"like",
102 | "value":"shi"
103 | }],
104 | "pageIndex":1,
105 | "pageSize":1,
106 | "orderCondition":"id desc"
107 | }
108 | ===
109 | 最后生成的sql:
110 | select * from users where userName like '%ce%' and userName like '%shi%' order by id desc limit 1,1
111 |
112 | ```
113 |
114 | - 全局`http异常处理`以及`代码异常`处理
115 |
116 | - log 日志
117 |
118 | - HTTP返回值统一ResultBean封装
119 |
120 | - 文件上传,静态资源服务
121 |
122 | - 一键生成数据库模型 `yarn db` (typeorm-model-generator)
123 | ## 4. 部署
124 |
125 | ``` javascript
126 | // 项目提供了 /src/config/env/dev,prod,test 三种环境变量配置文件
127 |
128 | // main入口监听端口号
129 | await app.listen(process.env.PORT || 3000);
130 |
131 | // 采用不同的npm命令实现多环境部署
132 | cross-env NODE_ENV=production // npm 命令 cross-env指定当前环境
133 | PORT=3000 // 指定监听端口
134 | ```
135 |
136 | 具体流程
137 | * npm run build
138 | * 拷贝dist文件夹
139 | * 拷贝package.json
140 | * 服务器上执行 npm install 安装所需依赖 (此处大坑,依赖并不会被打包到dist文件夹中)
141 | * npm run start:prod / npm run pm2
142 |
--------------------------------------------------------------------------------
/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": "@nestjs/schematics",
3 | "sourceRoot": "src"
4 | }
5 |
--------------------------------------------------------------------------------
/nest.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat Premium Data Transfer
3 |
4 | Source Server : localhost
5 | Source Server Type : MySQL
6 | Source Server Version : 80027
7 | Source Host : localhost:3306
8 | Source Schema : nest
9 |
10 | Target Server Type : MySQL
11 | Target Server Version : 80027
12 | File Encoding : 65001
13 |
14 | Date: 26/01/2022 17:14:24
15 | */
16 |
17 | SET NAMES utf8mb4;
18 | SET FOREIGN_KEY_CHECKS = 0;
19 |
20 | -- ----------------------------
21 | -- Table structure for ad_codelist
22 | -- ----------------------------
23 | DROP TABLE IF EXISTS `ad_codelist`;
24 | CREATE TABLE `ad_codelist` (
25 | `id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'ID',
26 | `codeValue` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '字典值',
27 | `codeName` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '字典值描述',
28 | `codeType` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '字典类型',
29 | `codeOrder` decimal(8,0) DEFAULT NULL COMMENT '排序',
30 | `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
31 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
32 | PRIMARY KEY (`id`) USING BTREE
33 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='字典表';
34 |
35 | -- ----------------------------
36 | -- Records of ad_codelist
37 | -- ----------------------------
38 | BEGIN;
39 | INSERT INTO `ad_codelist` VALUES ('0a6d30ed-8670-4f65-9b92-5a5e24b53049', 'P6', 'P6', 'ac3f1996-bcec-4604-b465-eaf5d1208e79', 2, NULL, '2020-12-20 10:58:01');
40 | INSERT INTO `ad_codelist` VALUES ('154ba39b-4d6f-4e7e-8197-dcf7be5037da', 'P8', 'P8', 'ac3f1996-bcec-4604-b465-eaf5d1208e79', 4, NULL, '2020-12-20 10:58:23');
41 | INSERT INTO `ad_codelist` VALUES ('212c3189-e913-4b51-8e0c-6993d9c9f9fa', 'P5', 'P5', 'ac3f1996-bcec-4604-b465-eaf5d1208e79', 1, NULL, '2020-12-20 10:57:55');
42 | INSERT INTO `ad_codelist` VALUES ('2d09a14f-4032-4a27-9b16-946ab3950689', '8,15', '密度长度', 'f844cb90-1738-4013-b9f2-b0755b63b9dc', 4, 'passwordLength', '2020-12-20 11:46:35');
43 | INSERT INTO `ad_codelist` VALUES ('2dcba704-af95-44b9-9ad2-72b3d1992b81', '本科', '本科', '962e3a39-928d-4470-a9f3-8efda17f2692', 5, NULL, '2020-12-20 10:57:05');
44 | INSERT INTO `ad_codelist` VALUES ('3008950a-6246-4fbe-b0d0-538e0cdd0139', '大专及以下', '大专及以下', '962e3a39-928d-4470-a9f3-8efda17f2692', 6, NULL, '2020-12-20 10:56:59');
45 | INSERT INTO `ad_codelist` VALUES ('58fa976e-b0f1-464d-814b-afe172a6f023', 'P9', 'P9', 'ac3f1996-bcec-4604-b465-eaf5d1208e79', 5, NULL, '2020-12-20 10:58:28');
46 | INSERT INTO `ad_codelist` VALUES ('59778b04-2ed4-42ef-a3d4-aa330d0e3d54', '7', '密码过期时间(天)', 'f844cb90-1738-4013-b9f2-b0755b63b9dc', 2, 'passwordTime', '2020-09-17 10:31:39');
47 | INSERT INTO `ad_codelist` VALUES ('63aa209d-264a-4e38-8c4c-e83172e2a5f6', '1', '开发人员模式', 'f844cb90-1738-4013-b9f2-b0755b63b9dc', 5, 'isDev', '2020-12-20 12:25:07');
48 | INSERT INTO `ad_codelist` VALUES ('7461d8d4-45c5-4fd5-a87f-f04320a487d5', 'P7', 'P7', 'ac3f1996-bcec-4604-b465-eaf5d1208e79', 3, NULL, '2020-12-20 10:58:08');
49 | INSERT INTO `ad_codelist` VALUES ('7f81d7b5-c6b9-4412-8b00-8c9cf2482357', '20', '客户端超时时间(分钟)', 'f844cb90-1738-4013-b9f2-b0755b63b9dc', 3, 'clientTimeOut', '2020-09-17 10:31:39');
50 | INSERT INTO `ad_codelist` VALUES ('8062ca78-ce7f-402f-9623-22a185d4ff1b', '博士', '博士', '962e3a39-928d-4470-a9f3-8efda17f2692', 3, NULL, '2020-12-20 10:57:18');
51 | INSERT INTO `ad_codelist` VALUES ('8d6dcf21-8e7b-4ec6-ae8a-cacb3912870b', 'P10', 'P10', 'ac3f1996-bcec-4604-b465-eaf5d1208e79', 6, NULL, '2020-12-20 10:58:34');
52 | INSERT INTO `ad_codelist` VALUES ('9233c640-272a-4a4c-92c2-8952ec3dde7e', '研究生', '研究生', '962e3a39-928d-4470-a9f3-8efda17f2692', 4, NULL, '2020-12-20 10:57:13');
53 | INSERT INTO `ad_codelist` VALUES ('a42d675f-5f5e-4770-8587-53c9c04c9e72', '博士后', '博士后', '962e3a39-928d-4470-a9f3-8efda17f2692', 2, NULL, '2020-12-20 10:57:24');
54 | INSERT INTO `ad_codelist` VALUES ('b670bc8e-7a73-4fcc-875d-f2c9af01e329', 'BoBo Admin', '系统名称', 'f844cb90-1738-4013-b9f2-b0755b63b9dc', 1, 'systemName', '2020-09-17 10:31:39');
55 | INSERT INTO `ad_codelist` VALUES ('da332909-bef0-49c3-819e-e189f996bca0', '女', '女', '01eb097e-0d94-44cf-8796-157bba54f0bb', 2, NULL, '2020-09-17 10:31:39');
56 | INSERT INTO `ad_codelist` VALUES ('dd96514d-87cb-49c7-9191-5021aeabb639', '男', '男', '01eb097e-0d94-44cf-8796-157bba54f0bb', 1, NULL, '2020-09-17 10:31:39');
57 | COMMIT;
58 |
59 | -- ----------------------------
60 | -- Table structure for ad_codelist_type
61 | -- ----------------------------
62 | DROP TABLE IF EXISTS `ad_codelist_type`;
63 | CREATE TABLE `ad_codelist_type` (
64 | `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'ID',
65 | `typeName` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '字典类型名称',
66 | `order` decimal(8,0) DEFAULT NULL COMMENT '排序',
67 | `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
68 | `parentId` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '父级ID',
69 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
70 | PRIMARY KEY (`id`) USING BTREE
71 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='字典类型表';
72 |
73 | -- ----------------------------
74 | -- Records of ad_codelist_type
75 | -- ----------------------------
76 | BEGIN;
77 | INSERT INTO `ad_codelist_type` VALUES ('01eb097e-0d94-44cf-8796-157bba54f0bb', '性别', 1, '', 'bedac4aa-41c8-4fcd-911d-d79b3b5a2392', '2020-09-17 10:31:39');
78 | INSERT INTO `ad_codelist_type` VALUES ('962e3a39-928d-4470-a9f3-8efda17f2692', '文化程度', 0, '', 'bedac4aa-41c8-4fcd-911d-d79b3b5a2392', '2020-12-20 10:56:28');
79 | INSERT INTO `ad_codelist_type` VALUES ('ac3f1996-bcec-4604-b465-eaf5d1208e79', '职级', 0, '', 'bedac4aa-41c8-4fcd-911d-d79b3b5a2392', '2020-12-20 10:57:39');
80 | INSERT INTO `ad_codelist_type` VALUES ('bedac4aa-41c8-4fcd-911d-d79b3b5a2392', '常用', 0, '常用', 'fe980574-2552-4754-88c8-366eb5a22861', '2021-01-12 17:09:06');
81 | INSERT INTO `ad_codelist_type` VALUES ('f844cb90-1738-4013-b9f2-b0755b63b9dc', '系统配置', 2, '系统相关', 'fe980574-2552-4754-88c8-366eb5a22861', '2021-01-12 17:09:16');
82 | INSERT INTO `ad_codelist_type` VALUES ('fe980574-2552-4754-88c8-366eb5a22861', '数据字典', 1, '', '0', '2020-09-17 10:31:39');
83 | COMMIT;
84 |
85 | -- ----------------------------
86 | -- Table structure for dept
87 | -- ----------------------------
88 | DROP TABLE IF EXISTS `dept`;
89 | CREATE TABLE `dept` (
90 | `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
91 | `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '部门名称',
92 | `rank` int DEFAULT NULL COMMENT '排序码',
93 | `parentId` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '上级ID',
94 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
95 | PRIMARY KEY (`id`) USING BTREE,
96 | UNIQUE KEY `index_id` (`id`) USING BTREE
97 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
98 |
99 | -- ----------------------------
100 | -- Records of dept
101 | -- ----------------------------
102 | BEGIN;
103 | INSERT INTO `dept` VALUES ('2f8447de-5732-4fa4-8286-9a71b41dd1e7', '总部', 1, '0', '2020-09-18 15:17:45');
104 | INSERT INTO `dept` VALUES ('b987afc3-6969-4b87-85a4-f8e2029e4bee', '开发部', 1, '2f8447de-5732-4fa4-8286-9a71b41dd1e7', '2020-09-17 10:31:39');
105 | COMMIT;
106 |
107 | -- ----------------------------
108 | -- Table structure for dynamictables
109 | -- ----------------------------
110 | DROP TABLE IF EXISTS `dynamictables`;
111 | CREATE TABLE `dynamictables` (
112 | `id` char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
113 | `tableName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '表名',
114 | `formJson` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '数据',
115 | `position` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '使用位置',
116 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
117 | PRIMARY KEY (`id`) USING BTREE
118 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='表格设计';
119 |
120 | -- ----------------------------
121 | -- Records of dynamictables
122 | -- ----------------------------
123 | BEGIN;
124 | INSERT INTO `dynamictables` VALUES ('054cfb12-7db2-400b-9917-27d3105dbb09', 'dept', '{\"columns\":[{\"prop\":\"name\",\"label\":\"部门名称\",\"minWidth\":\"200\",\"sortable\":\"false\",\"searchable\":false,\"align\":\"left\",\"headerAlign\":\"center\"},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":\"280\",\"align\":\"center\",\"headerAlign\":\"center\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false}]}', 'Dept.vue/部门设置', '2020-09-17 10:32:10');
125 | INSERT INTO `dynamictables` VALUES ('3be21467-5c60-42eb-81ae-2e7bb81b6d64', 'person_resume', '{\"columns\":[{\"prop\":\"time\",\"label\":\"起止时间\",\"minWidth\":140,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"workunit\",\"label\":\"工作单位\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true},{\"prop\":\"workduty\",\"label\":\"职务\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":180,\"align\":\"center\",\"headerAlign\":\"center\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false}]}', '员工履历', '2020-12-20 10:37:25');
126 | INSERT INTO `dynamictables` VALUES ('58da681b-af8f-4733-b7b0-9c037e9d0d8f', 'users', '{\"columns\":[{\"prop\":\"realName\",\"label\":\"姓名\",\"minWidth\":\"100\",\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true},{\"prop\":\"userName\",\"label\":\"登录名\",\"minWidth\":\"100\",\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true},{\"prop\":\"roleName\",\"label\":\"角色\",\"minWidth\":\"100\",\"sortable\":\"custom\",\"slotName\":\"\",\"option\":{\"width\":\"\",\"placeholder\":\"\",\"remote\":\"custom\",\"remoteFunc\":\"funcGetRole\",\"props\":{\"label\":\"label\",\"value\":\"value\"},\"type\":\"select\",\"selectBy\":\"label\"},\"searchable\":true,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true},{\"prop\":\"deptName\",\"label\":\"部门\",\"minWidth\":\"100\",\"sortable\":\"custom\",\"searchable\":true,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true},{\"prop\":\"photo\",\"label\":\"头像\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":false,\"slotName\":\"columnFormatter\"},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":\"270\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false,\"align\":\"center\",\"headerAlign\":\"center\"}],\"name\":\"users\",\"position\":\"Users.vue系统设置/角色管理\"}', 'Users.vue系统设置/角色管理', '2021-01-08 09:16:22');
127 | INSERT INTO `dynamictables` VALUES ('72269942-3b4a-4000-b722-12c70febbab2', 'params', '{\"columns\":[{\"prop\":\"codeName\",\"label\":\"参数名称\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true},{\"prop\":\"remark\",\"label\":\"参数键名\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true},{\"prop\":\"codeValue\",\"label\":\"参数键值\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":180,\"align\":\"center\",\"headerAlign\":\"center\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false}]}', '参数设置', '2020-09-17 10:15:02');
128 | INSERT INTO `dynamictables` VALUES ('e2d577ac-6900-432f-a45c-ec086f668825', 'person', '{\"columns\":[{\"prop\":\"jobno\",\"label\":\"工号\",\"minWidth\":\"100\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"jobno\",\"searchable\":true},{\"prop\":\"personname\",\"label\":\"姓名\",\"minWidth\":\"70\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"personname\",\"searchable\":true},{\"prop\":\"jobtime\",\"label\":\"入职时间\",\"minWidth\":140,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"deptname\",\"label\":\"所在部门\",\"minWidth\":\"100\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"post\",\"label\":\"岗位\",\"minWidth\":\"100\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"level\",\"label\":\"职级\",\"minWidth\":\"100\",\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true,\"option\":{\"remote\":\"dict\",\"remoteFunc\":\"\",\"type\":\"select\",\"props\":{\"value\":\"\",\"label\":\"\"},\"dictType\":\"ac3f1996-bcec-4604-b465-eaf5d1208e79\"}},{\"prop\":\"mobile\",\"label\":\"联系方式\",\"minWidth\":140,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":\"240\",\"align\":\"center\",\"headerAlign\":\"center\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false}],\"name\":\"person\",\"position\":\"员工管理\"}', '员工管理', '2021-01-12 17:02:22');
129 | INSERT INTO `dynamictables` VALUES ('eb9388de-aa0c-4027-8653-b4e0c9a9cb1d', 'ad_codelist', '{\"columns\":[{\"prop\":\"codeName\",\"label\":\"字典名\",\"minWidth\":140,\"align\":\"left\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"codeValue\",\"label\":\"字典值\",\"minWidth\":140,\"align\":\"left\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"typeName\",\"label\":\"所属分类\",\"minWidth\":140,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true,\"option\":{\"width\":\"\",\"placeholder\":\"\",\"remote\":\"custom\",\"remoteFunc\":\"getDictType\",\"props\":{\"value\":\"value\",\"label\":\"label\"},\"options\":[{\"value\":\"下拉框1\"},{\"value\":\"下拉框2\"},{\"value\":\"下拉框3\"}],\"type\":\"select\",\"selectBy\":\"label\"}},{\"prop\":\"codeOrder\",\"label\":\"字典排序\",\"minWidth\":140,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"remark\",\"label\":\"备注\",\"minWidth\":140,\"align\":\"center\",\"headerAlign\":\"center\",\"showOverflowTooltip\":true,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":180,\"align\":\"center\",\"headerAlign\":\"center\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false}]}', '字典管理', '2020-12-20 11:05:38');
130 | INSERT INTO `dynamictables` VALUES ('f2ad95ae-61d7-4bc3-94d6-dc00e867fdbe', 'dynamictables', '{\"columns\":[{\"prop\":\"tableName\",\"label\":\"表名\",\"minWidth\":140,\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true,\"align\":\"left\",\"headerAlign\":\"center\"},{\"prop\":\"position\",\"label\":\"使用位置\",\"minWidth\":\"300\",\"sortable\":\"custom\",\"slotName\":\"\",\"searchable\":true,\"align\":\"left\",\"headerAlign\":\"center\"},{\"prop\":\"timestamp\",\"label\":\"更新时间\",\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true,\"align\":\"center\",\"headerAlign\":\"center\"},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":\"150\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false,\"align\":\"center\",\"headerAlign\":\"center\",\"width\":\"200\"}]}', 'TableDesigner.vue开发人员工具/表格设计', '2020-09-17 10:15:02');
131 | INSERT INTO `dynamictables` VALUES ('fb8a5d7c-2fda-4936-9da0-dc09354adfdc', 'form', '{\"columns\":[{\"prop\":\"tableName\",\"label\":\"表名\",\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true,\"align\":\"left\",\"headerAlign\":\"center\"},{\"prop\":\"position\",\"label\":\"使用位置\",\"minWidth\":\"300\",\"sortable\":\"custom\",\"searchable\":true,\"align\":\"left\",\"headerAlign\":\"center\"},{\"prop\":\"timestamp\",\"label\":\"更新时间\",\"minWidth\":140,\"sortable\":\"custom\",\"searchable\":true,\"align\":\"center\",\"headerAlign\":\"center\"},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":\"150\",\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false,\"align\":\"center\",\"headerAlign\":\"center\"}]}', 'FormDesigner.vue开发人员工具/表单设计', '2020-09-18 10:14:02');
132 | INSERT INTO `dynamictables` VALUES ('fc442e2b-a7f9-4fab-8d59-2803ae2a9215', 'role', '{\"columns\":[{\"prop\":\"roleName\",\"label\":\"角色\",\"minWidth\":140,\"sortable\":\"custom\",\"slotName\":\"\",\"align\":\"left\",\"headerAlign\":\"center\",\"searchable\":true},{\"prop\":\"roleAuthNameDict\",\"label\":\"菜单\",\"minWidth\":140,\"sortable\":\"custom\",\"slotName\":\"\",\"align\":\"left\",\"headerAlign\":\"center\",\"searchable\":true,\"showOverflowTooltip\":true},{\"prop\":\"rank\",\"label\":\"排序\",\"minWidth\":140,\"sortable\":\"custom\",\"slotName\":\"\",\"align\":\"center\",\"headerAlign\":\"center\",\"searchable\":true},{\"prop\":\"\",\"label\":\"操作\",\"minWidth\":180,\"slotName\":\"actionColumn\",\"fixed\":\"right\",\"sortable\":\"false\",\"searchable\":false,\"headerAlign\":\"center\",\"align\":\"center\"}]}', 'Role.vue系统设置/角色管理', '2020-09-18 10:14:50');
133 | COMMIT;
134 |
135 | -- ----------------------------
136 | -- Table structure for form
137 | -- ----------------------------
138 | DROP TABLE IF EXISTS `form`;
139 | CREATE TABLE `form` (
140 | `id` char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
141 | `tableName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '表名',
142 | `formJson` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '数据',
143 | `position` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '使用位置',
144 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
145 | PRIMARY KEY (`id`) USING BTREE
146 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='表单设计';
147 |
148 | -- ----------------------------
149 | -- Records of form
150 | -- ----------------------------
151 | BEGIN;
152 | INSERT INTO `form` VALUES ('08d0b5e4-92e4-431b-9b48-6189881335ed', 'role', '{\"list\":[{\"columns\":[{\"list\":[{\"name\":\"角色\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1543672671000_92966\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"roleName\",\"rules\":[{\"type\":\"string\",\"message\":\"角色格式不正确\"}],\"type\":\"input\",\"key\":\"1543672671000_92966\"}],\"span\":12},{\"list\":[{\"name\":\"排序\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1543672693000_86312\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"rank\",\"rules\":[],\"type\":\"input\",\"key\":\"1543672693000_86312\"}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1543672665000_69434\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1543672665000_69434\",\"rules\":[],\"type\":\"grid\",\"key\":\"1543672665000_69434\"},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":24,\"list\":[{\"type\":\"input\",\"name\":\"首页\",\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1554347848000_34718\"},\"key\":\"1554347848000_34718\",\"model\":\"homePageDict\",\"rules\":[{\"type\":\"string\",\"message\":\"单行文本格式不正确\"}]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1554347841000_92183\"},\"key\":\"1554347841000_92183\",\"model\":\"1554347841000_92183\",\"rules\":[]},{\"columns\":[{\"list\":[{\"name\":\"对应菜单\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1543672717000_46620\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"roleAuthNameDict\",\"rules\":[{\"type\":\"string\",\"message\":\"对应菜单格式不正确\"}],\"type\":\"input\",\"key\":\"1543672717000_46620\"}],\"span\":24}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1543672710000_2784\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1543672710000_2784\",\"rules\":[],\"type\":\"grid\",\"key\":\"1543672710000_2784\"}],\"config\":{\"size\":\"small\",\"labelPosition\":\"right\",\"labelWidth\":0,\"name\":\"role\"}}', 'Role.vue/角色设置', '2020-12-20 12:39:06');
153 | INSERT INTO `form` VALUES ('139d4ebc-d6a1-40bb-b063-2086c31e743d', 'ad_codelist_type', '{\"list\":[{\"columns\":[{\"list\":[{\"name\":\"字典类型名称\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542852872000_82944\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"codeValue\",\"rules\":[{\"type\":\"string\",\"message\":\"字典类型名称格式不正确\"}],\"type\":\"input\",\"key\":\"1542852872000_82944\"}],\"span\":12},{\"list\":[{\"name\":\"字典类型描述\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542852908000_20406\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"codeName\",\"rules\":[],\"type\":\"input\",\"key\":\"1542852908000_20406\"}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1542852751000_26540\",\"gutter\":10,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1542852751000_26540\",\"rules\":[],\"type\":\"grid\",\"key\":\"1542852751000_26540\"},{\"columns\":[{\"list\":[{\"name\":\"排序\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542852959000_72602\",\"defaultValue\":\"\",\"dataType\":\"number\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"codeOrder\",\"rules\":[{\"type\":\"number\",\"message\":\"排序格式不正确\"}],\"type\":\"input\",\"key\":\"1542852959000_72602\"}],\"span\":12},{\"list\":[{\"name\":\"备注\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542852978000_87249\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"remark\",\"rules\":[{\"type\":\"string\",\"message\":\"备注格式不正确\"}],\"type\":\"input\",\"key\":\"1542852978000_87249\"}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1542852934000_45834\",\"gutter\":10,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1542852934000_45834\",\"rules\":[],\"type\":\"grid\",\"key\":\"1542852934000_45834\"}],\"config\":{\"size\":\"small\",\"labelPosition\":\"top\",\"labelWidth\":0,\"name\":\"ad_codelist_type\"}}', 'DictType.vue开发人员工具/字典类型管理/字典类型列表', '2020-12-20 12:39:08');
154 | INSERT INTO `form` VALUES ('22727b7c-7d23-4f3f-ad5b-526eca8f8779', 'users', '{\"list\":[{\"columns\":[{\"list\":[{\"name\":\"姓名\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1543692259000_97262\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":true},\"model\":\"realName\",\"rules\":[{\"type\":\"string\",\"message\":\"姓名格式不正确\"},{\"required\":true,\"message\":\"姓名必须填写\"}],\"type\":\"input\",\"key\":\"1543692259000_97262\"}],\"span\":12},{\"list\":[{\"type\":\"input\",\"name\":\"登录名\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":true,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1599720592000_96541\"},\"key\":\"1599720592000_96541\",\"model\":\"userName\",\"rules\":[{\"type\":\"string\",\"message\":\"单行文本格式不正确\"},{\"required\":true,\"message\":\"登录名必须填写\"}]}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1543692232000_18760\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1543692232000_18760\",\"rules\":[],\"type\":\"grid\",\"key\":\"1543692232000_18760\"},{\"columns\":[{\"list\":[{\"name\":\"密码\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1543692382000_41790\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":true,\"message\":\"\"},\"model\":\"password\",\"rules\":[{\"type\":\"string\",\"message\":\"联系方式格式不正确\"},{\"required\":true,\"message\":\"密码必须填写\"}],\"type\":\"input\",\"key\":\"1543692382000_41790\"}],\"span\":24}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1543692369000_62178\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1543692369000_62178\",\"rules\":[],\"type\":\"grid\",\"key\":\"1543692369000_62178\"},{\"type\":\"grid\",\"name\":\"栅格布局(1列)\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"treeselect\",\"name\":\"部门\",\"icon\":\"tree\",\"options\":{\"remoteFunc\":\"funcGetDeptTree\",\"placeholder\":\"\",\"width\":\"\",\"maxHeight\":\"100\",\"multiple\":false,\"remote\":\"custom\",\"props\":{\"value\":\"name\",\"label\":\"id\",\"children\":\"children\"},\"clearable\":true,\"searchable\":true,\"noChildrenText\":\"暂无数据\",\"noOptionsText\":\"暂无数据\",\"noResultsText\":\"暂无数据\",\"searchNested\":true,\"required\":true,\"showValueLabelSlot\":false,\"disabled\":false,\"showCount\":false,\"disableBranchNodes\":false,\"remoteOptions\":[],\"tips\":\"选择所属部门\",\"defaultValue\":\"\"},\"key\":\"deptId\",\"model\":\"deptId\",\"rules\":[{\"required\":true,\"message\":\"部门必须填写\"}]}]},{\"span\":12,\"list\":[{\"type\":\"select\",\"name\":\"角色\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/caret-square-down\",\"options\":{\"defaultValue\":\"\",\"multiple\":false,\"disabled\":false,\"clearable\":false,\"placeholder\":\"\",\"required\":true,\"showLabel\":false,\"allowCreate\":false,\"width\":\"\",\"options\":[{\"value\":\"下拉框1\"},{\"value\":\"下拉框2\"},{\"value\":\"下拉框3\"}],\"remote\":\"custom\",\"remoteOptions\":[],\"props\":{\"value\":\"value\",\"label\":\"label\"},\"remoteFunc\":\"funcGetRole\"},\"key\":\"1599722385000_17600\",\"model\":\"roleId\",\"rules\":[{\"required\":true,\"message\":\"角色必须填写\"}]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1599722356000_92731\"},\"key\":\"1599722356000_92731\",\"model\":\"1599722356000_92731\",\"rules\":[]},{\"columns\":[{\"span\":12,\"list\":[{\"name\":\"排序\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1543692390000_91729\",\"defaultValue\":\"\",\"dataType\":\"number\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"rank\",\"rules\":[{\"type\":\"number\",\"message\":\"排序格式不正确\"}],\"type\":\"input\",\"key\":\"rank\"}]}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1543692434000_13772\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1543692434000_13772\",\"rules\":[],\"type\":\"grid\",\"key\":\"1543692434000_13772\"}],\"config\":{\"size\":\"small\",\"labelPosition\":\"right\",\"labelWidth\":0,\"name\":\"users\"}}', 'Users.vue系统设置/用户管理', '2021-01-07 17:14:54');
155 | INSERT INTO `form` VALUES ('2875cabf-19ca-46ee-abce-026dccbd9d6f', 'person_resume', '{\"list\":[{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":24,\"list\":[{\"type\":\"date\",\"name\":\"起止时间\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/calendar-alt\",\"options\":{\"defaultValue\":false,\"readonly\":false,\"disabled\":false,\"editable\":true,\"clearable\":true,\"placeholder\":\"\",\"startPlaceholder\":\"\",\"endPlaceholder\":\"\",\"type\":\"monthrange\",\"format\":\"yyyy-MM\",\"timestamp\":false,\"required\":false,\"width\":\"100%\",\"remoteFunc\":\"func_1608434790000_9491\"},\"key\":\"1608434790000_9491\",\"model\":\"time\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.7269407990573393\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"工作单位\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"workunit\",\"model\":\"workunit\",\"rules\":[]}]},{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"职务\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"workduty\",\"model\":\"workduty\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.0967080797051183\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局(1列)\",\"icon\":\"th\",\"columns\":[{\"span\":24,\"list\":[{\"type\":\"richtext\",\"name\":\"备注\",\"icon\":\"text-width\",\"hidden\":false,\"options\":{\"defaultValue\":\"\",\"readonly\":false,\"remoteFunc\":\"func_1608431672000_50519\"},\"key\":\"1608431672000_50519\",\"model\":\"remark\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1608431652000_51550\"},\"key\":\"1608431652000_51550\",\"model\":\"1608431652000_51550\",\"rules\":[]}],\"config\":{\"labelWidth\":140,\"labelPosition\":\"right\",\"size\":\"small\",\"isTableClass\":true}}', '员工履历', '2020-12-20 11:29:37');
156 | INSERT INTO `form` VALUES ('45a0da67-2713-42cb-bdb4-4e5cdbb8d436', 'ad_codelist', '{\"list\":[{\"columns\":[{\"list\":[{\"name\":\"字典值\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542782929000_93584\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"codeValue\",\"rules\":[{\"type\":\"string\",\"message\":\"字典值格式不正确\"}],\"type\":\"input\",\"key\":\"1542782929000_93584\"}],\"span\":12},{\"list\":[{\"name\":\"字典名\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542782931000_42300\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"codeName\",\"rules\":[{\"type\":\"string\",\"message\":\"字典名格式不正确\"}],\"type\":\"input\",\"key\":\"1542782931000_42300\"}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1542782926000_16479\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1542782926000_16479\",\"rules\":[],\"type\":\"grid\",\"key\":\"1542782926000_16479\"},{\"type\":\"grid\",\"name\":\"栅格布局(1列)\",\"icon\":\"th\",\"columns\":[{\"span\":24,\"list\":[{\"type\":\"select\",\"name\":\"所属分类\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/caret-square-down\",\"options\":{\"defaultValue\":\"\",\"multiple\":false,\"disabled\":false,\"clearable\":false,\"placeholder\":\"\",\"required\":false,\"showLabel\":false,\"allowCreate\":false,\"width\":\"\",\"options\":[{\"value\":\"下拉框1\"},{\"value\":\"下拉框2\"},{\"value\":\"下拉框3\"}],\"remote\":\"custom\",\"remoteOptions\":[],\"props\":{\"value\":\"value\",\"label\":\"label\"},\"remoteFunc\":\"getDictType\"},\"key\":\"1576489740000_96446\",\"model\":\"codeType\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1576489735000_66792\"},\"key\":\"1576489735000_66792\",\"model\":\"1576489735000_66792\",\"rules\":[]},{\"columns\":[{\"list\":[{\"name\":\"字典排序\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542783014000_32619\",\"defaultValue\":\"\",\"dataType\":\"number\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"codeOrder\",\"rules\":[{\"type\":\"number\",\"message\":\"字典排序格式不正确\"}],\"type\":\"input\",\"key\":\"codeorder\"}],\"span\":12},{\"list\":[{\"name\":\"备注\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542783045000_37663\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"remark\",\"rules\":[{\"type\":\"string\",\"message\":\"备注格式不正确\"}],\"type\":\"input\",\"key\":\"remark\"}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1542782963000_76757\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1542782963000_76757\",\"rules\":[],\"type\":\"grid\",\"key\":\"1542782963000_76757\"}],\"config\":{\"size\":\"small\",\"labelPosition\":\"right\",\"labelWidth\":0,\"name\":\"ad_codelist\"}}', 'Dict.vue开发人员工具/字典管理', '2020-12-20 12:39:11');
157 | INSERT INTO `form` VALUES ('6ce2aa72-c969-43cf-8370-c669e50b300b', 'dept', '{\"list\":[{\"columns\":[{\"list\":[{\"name\":\"部门名称\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1542344382000_98751\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":true},\"model\":\"name\",\"rules\":[{\"type\":\"string\",\"message\":\"部门名称格式不正确\"},{\"required\":true,\"message\":\"部门名称必须填写\"}],\"type\":\"input\",\"key\":\"1542344382000_98751\"}],\"span\":12},{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"部门排序\",\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"number\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_rank\"},\"key\":\"rank\",\"model\":\"rank\",\"rules\":[{\"type\":\"number\",\"message\":\"部门排序格式不正确\"}]}]}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1542344310000_82263\",\"gutter\":0,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"grid_1542344310000_82263\",\"rules\":[],\"type\":\"grid\",\"key\":\"1542344310000_82263\"}],\"config\":{\"size\":\"small\",\"labelPosition\":\"right\",\"labelWidth\":0,\"name\":\"dept\"}}', 'Dept.vue/系统设置/部门设置', '2020-12-20 12:39:12');
158 | INSERT INTO `form` VALUES ('786506c7-7d3a-4bec-a9fb-f374b9eecbb7', 'dynamictables', '{\"list\":[{\"columns\":[{\"list\":[{\"name\":\"表名\",\"icon\":\"regular/caret-square-down\",\"options\":{\"remoteFunc\":\"getTablesOfDB\",\"clearable\":false,\"defaultValue\":\"\",\"remoteOptions\":[],\"multiple\":false,\"remote\":\"custom\",\"required\":false,\"showLabel\":false,\"props\":{\"label\":\"label\",\"value\":\"value\"},\"allowCreate\":true,\"width\":\"100%\",\"options\":[{\"value\":\"下拉框1\"},{\"value\":\"下拉框2\"},{\"value\":\"下拉框3\"}],\"disabled\":false,\"placeholder\":\"\"},\"model\":\"tableName\",\"rules\":[],\"type\":\"select\",\"key\":\"1544270970000_6013\",\"labelWidth\":\"40\"}],\"span\":12},{\"list\":[{\"name\":\"使用位置\",\"icon\":\"regular/keyboard\",\"options\":{\"remoteFunc\":\"func_1544159524000_20194\",\"defaultValue\":\"\",\"dataType\":\"string\",\"width\":\"100%\",\"pattern\":\"\",\"placeholder\":\"\",\"required\":false},\"model\":\"position\",\"rules\":[{\"type\":\"string\",\"message\":\"使用位置格式不正确\"}],\"type\":\"input\",\"key\":\"1544159524000_20194\"}],\"span\":12}],\"name\":\"栅格布局\",\"icon\":\"th\",\"options\":{\"remoteFunc\":\"func_1544159335000_25819\",\"gutter\":10,\"justify\":\"start\",\"align\":\"top\"},\"model\":\"1544159335000_25819\",\"rules\":[],\"type\":\"grid\",\"key\":\"1544159335000_25819\"}],\"config\":{\"size\":\"small\",\"labelPosition\":\"right\",\"labelWidth\":80,\"name\":\"dynamictables\"}}', 'TableDesigner.vue开发人员工具/表格设计', '2020-12-20 12:39:14');
159 | INSERT INTO `form` VALUES ('bd70c78e-7678-4c06-a466-6760f29f73ad', 'person', '{\"list\":[{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"工号\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"请输入工号\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"jobno\",\"model\":\"jobno\",\"rules\":[{\"type\":\"string\",\"message\":\"工号格式不正确\"}]}]},{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"姓名\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"personname\",\"model\":\"personname\",\"rules\":[{\"type\":\"string\",\"message\":\"姓名1格式不正确\"}]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.0578278502302394\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"radio\",\"name\":\"性别\",\"icon\":\"regular/dot-circle\",\"labelWidth\":\"\",\"hidden\":false,\"options\":{\"inline\":true,\"defaultValue\":\"\",\"showLabel\":false,\"options\":[{\"value\":\"男\",\"label\":\"选项1\"},{\"value\":\"女\",\"label\":\"选项2\"}],\"required\":false,\"disabled\":false,\"width\":\"\",\"remote\":false,\"remoteOptions\":[],\"props\":{\"value\":\"value\",\"label\":\"label\"},\"remoteFunc\":\"func_1608432399000_10952\"},\"key\":\"1608432399000_10952\",\"model\":\"sex\",\"rules\":[{\"type\":\"string\",\"message\":\"性别格式不正确\"}]}]},{\"span\":12,\"list\":[{\"type\":\"select\",\"name\":\"文化程度\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/caret-square-down\",\"options\":{\"defaultValue\":\"\",\"multiple\":false,\"disabled\":false,\"clearable\":false,\"placeholder\":\"\",\"required\":false,\"showLabel\":false,\"allowCreate\":false,\"width\":\"100%\",\"options\":[{\"value\":\"下拉框1\"},{\"value\":\"下拉框2\"},{\"value\":\"下拉框3\"}],\"remote\":\"dict\",\"remoteOptions\":[{\"value\":\"本科\",\"label\":\"本科\"},{\"value\":\"大专及以下\",\"label\":\"大专及以下\"},{\"value\":\"博士\",\"label\":\"博士\"},{\"value\":\"研究生\",\"label\":\"研究生\"},{\"value\":\"博士后\",\"label\":\"博士后\"}],\"props\":{\"value\":\"value\",\"label\":\"label\"},\"remoteFunc\":\"func_1608433134000_41081\",\"dictType\":\"962e3a39-928d-4470-a9f3-8efda17f2692\"},\"key\":\"1608433134000_41081\",\"model\":\"education\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.4979627182416866\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"所在部门\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"deptname\",\"model\":\"deptname\",\"rules\":[]}]},{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"岗位\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"post\",\"model\":\"post\",\"rules\":[{\"type\":\"string\",\"message\":\"岗位格式不正确\"}]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.6063054944523363\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"select\",\"name\":\"职级\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/caret-square-down\",\"options\":{\"defaultValue\":\"\",\"multiple\":false,\"disabled\":false,\"clearable\":false,\"placeholder\":\"\",\"required\":false,\"showLabel\":false,\"allowCreate\":false,\"width\":\"100%\",\"options\":[{\"value\":\"下拉框1\"},{\"value\":\"下拉框2\"},{\"value\":\"下拉框3\"}],\"remote\":\"dict\",\"remoteOptions\":[{\"value\":\"P6\",\"label\":\"P6\"},{\"value\":\"P8\",\"label\":\"P8\"},{\"value\":\"P5\",\"label\":\"P5\"},{\"value\":\"P9\",\"label\":\"P9\"},{\"value\":\"P7\",\"label\":\"P7\"},{\"value\":\"P10\",\"label\":\"P10\"}],\"props\":{\"value\":\"value\",\"label\":\"label\"},\"remoteFunc\":\"func_1608433344000_95961\",\"dictType\":\"ac3f1996-bcec-4604-b465-eaf5d1208e79\"},\"key\":\"1608433344000_95961\",\"model\":\"level\",\"rules\":[{\"type\":\"string\",\"message\":\"岗位格式不正确\"}]}]},{\"span\":12,\"list\":[{\"type\":\"date\",\"name\":\"入职时间\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/calendar-alt\",\"options\":{\"defaultValue\":false,\"readonly\":false,\"disabled\":false,\"editable\":true,\"clearable\":true,\"placeholder\":\"\",\"startPlaceholder\":\"\",\"endPlaceholder\":\"\",\"type\":\"date\",\"format\":\"yyyy-MM-dd\",\"timestamp\":false,\"required\":false,\"width\":\"100%\",\"remoteFunc\":\"func_1608432345000_20310\"},\"key\":\"1608432345000_20310\",\"model\":\"jobtime\",\"rules\":[{\"type\":\"string\",\"message\":\"入职时间格式不正确\"}]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.9740509729876656\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"薪资\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"salary\",\"model\":\"salary\",\"rules\":[]}]},{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"联系方式\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"1575516931000_0.7423405755223678\",\"model\":\"mobile\",\"rules\":[{\"type\":\"string\",\"message\":\"单行文本格式不正确\"}]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.3680056593272678\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局\",\"icon\":\"th\",\"columns\":[{\"span\":12,\"list\":[{\"type\":\"input\",\"name\":\"专业\",\"labelWidth\":0,\"hidden\":false,\"icon\":\"regular/keyboard\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"readonly\":false,\"disabled\":false,\"required\":false,\"dataType\":\"string\",\"pattern\":\"\",\"placeholder\":\"\",\"remoteFunc\":\"func_1575516931000_89639\"},\"key\":\"major\",\"model\":\"major\",\"rules\":[]}]},{\"span\":12,\"list\":[{\"type\":\"date\",\"name\":\"出生年月\",\"labelWidth\":\"\",\"hidden\":false,\"icon\":\"regular/calendar-alt\",\"options\":{\"defaultValue\":false,\"readonly\":false,\"disabled\":false,\"editable\":true,\"clearable\":true,\"placeholder\":\"\",\"startPlaceholder\":\"\",\"endPlaceholder\":\"\",\"type\":\"month\",\"format\":\"yyyy-MM\",\"timestamp\":false,\"required\":false,\"width\":\"100%\",\"remoteFunc\":\"func_1608432438000_26217\"},\"key\":\"1608432438000_26217\",\"model\":\"birthdate\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1575516929000_36539\"},\"key\":\"1575516931000_0.22046952760726568\",\"model\":\"1575516929000_36539\",\"rules\":[]},{\"type\":\"grid\",\"name\":\"栅格布局(1列)\",\"icon\":\"th\",\"columns\":[{\"span\":24,\"list\":[{\"type\":\"table\",\"name\":\"工作履历\",\"icon\":\"table\",\"options\":{\"remoteFunc\":\"func_1608432102000_18779\",\"visibleList\":{\"actionColumnBtnEdit\":true,\"actionColumnBtnDetail\":false,\"btnAdd\":true,\"actionColumn\":true,\"tableTitle\":false,\"searchForm\":false,\"actionColumnBtnDel\":true,\"conditionTitle\":false,\"btnExport\":true,\"btnImport\":false},\"tableParams\":\"personid,id\",\"prefill\":\"personid,id\",\"tableTitle\":\"\",\"showPagination\":true,\"isMultiple\":false,\"tableName\":\"resume\",\"tableDesignerName\":\"person_resume\",\"dialogFormDesignerName\":\"person_resume\"},\"key\":\"1608432102000_18779\",\"model\":\"人员履历表\",\"rules\":[]}]}],\"options\":{\"gutter\":0,\"justify\":\"start\",\"align\":\"top\",\"remoteFunc\":\"func_1608432099000_43356\"},\"key\":\"1608432099000_43356\",\"model\":\"1608432099000_43356\",\"rules\":[]}],\"config\":{\"labelWidth\":140,\"labelPosition\":\"right\",\"size\":\"small\",\"isTableClass\":true,\"name\":\"person\"}}', '员工管理', '2020-12-20 12:39:38');
160 | COMMIT;
161 |
162 | -- ----------------------------
163 | -- Table structure for person
164 | -- ----------------------------
165 | DROP TABLE IF EXISTS `person`;
166 | CREATE TABLE `person` (
167 | `id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',
168 | `personname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
169 | `deptname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '所在部门',
170 | `salary` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '薪资',
171 | `post` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '岗位',
172 | `level` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '职级',
173 | `timestamp` datetime DEFAULT NULL COMMENT '时间戳',
174 | `jobtime` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '入职时间',
175 | `jobno` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '工号',
176 | `education` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文化程度',
177 | `major` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '专业',
178 | `mobile` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系方式',
179 | `birthdate` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '出生年月',
180 | `sex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '性别',
181 | `avatar` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '头像',
182 | PRIMARY KEY (`id`)
183 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
184 |
185 | -- ----------------------------
186 | -- Records of person
187 | -- ----------------------------
188 | BEGIN;
189 | INSERT INTO `person` VALUES ('038aa5c4-4274-11eb-bb0a-ed55e0675fa7', '邬彦皓', '研发部', '10000', '研发岗', 'P6', '2021-01-04 23:22:17', '2018-05-23', '2019548937', '博士', '专业', '15686640133', '2020-06', '男', NULL);
190 | INSERT INTO `person` VALUES ('038ac626-4274-11eb-bb0a-ed55e0675fa7', '路曼书', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-10-27', '2019614945', '本科', '专业', '17639302987', '2020-06', '男', NULL);
191 | INSERT INTO `person` VALUES ('038aeb06-4274-11eb-bb0a-ed55e0675fa7', '萧宏恩', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-12-04', '2019927916', '本科', '专业', '15620493978', '2020-06', '男', NULL);
192 | INSERT INTO `person` VALUES ('038afd1c-4274-11eb-bb0a-ed55e0675fa7', '戴会琦', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-03-02', '2019794742', '本科', '专业', '17623151335', '2020-06', '男', NULL);
193 | INSERT INTO `person` VALUES ('038b0d7a-4274-11eb-bb0a-ed55e0675fa7', '凤虎鹏', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-01-22', '2019689965', '本科', '专业', '17651279640', '2020-06', '男', NULL);
194 | INSERT INTO `person` VALUES ('038b221a-4274-11eb-bb0a-ed55e0675fa7', '乐冬若', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-10-18', '2019565599', '本科', '专业', '17646002851', '2020-06', '男', NULL);
195 | INSERT INTO `person` VALUES ('038b40ba-4274-11eb-bb0a-ed55e0675fa7', '鲁双健', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-10-17', '2019758100', '本科', '专业', '15613393016', '2020-06', '男', NULL);
196 | INSERT INTO `person` VALUES ('038b5d20-4274-11eb-bb0a-ed55e0675fa7', '石越延', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-08-02', '2019593703', '本科', '专业', '13625998336', '2020-06', '男', NULL);
197 | INSERT INTO `person` VALUES ('038b777e-4274-11eb-bb0a-ed55e0675fa7', '施心怡', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-07-20', '2019694217', '本科', '专业', '15675146795', '2020-06', '男', NULL);
198 | INSERT INTO `person` VALUES ('038b9330-4274-11eb-bb0a-ed55e0675fa7', '廉新奎', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-12-28', '2019689978', '本科', '专业', '13665657099', '2020-06', '男', NULL);
199 | INSERT INTO `person` VALUES ('038ba988-4274-11eb-bb0a-ed55e0675fa7', '柳翔伯', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-04-24', '2019867237', '本科', '专业', '13686623977', '2020-06', '男', NULL);
200 | INSERT INTO `person` VALUES ('038bd44e-4274-11eb-bb0a-ed55e0675fa7', '凌帆强', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-07-30', '2019766252', '本科', '专业', '17640824681', '2020-06', '男', NULL);
201 | INSERT INTO `person` VALUES ('038bed76-4274-11eb-bb0a-ed55e0675fa7', '熊一远', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-12-18', '2019729549', '本科', '专业', '15620496363', '2020-06', '男', NULL);
202 | INSERT INTO `person` VALUES ('038c03ec-4274-11eb-bb0a-ed55e0675fa7', '凌紫宗', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-01-28', '2019848988', '本科', '专业', '17637737408', '2020-06', '男', NULL);
203 | INSERT INTO `person` VALUES ('038c1d0a-4274-11eb-bb0a-ed55e0675fa7', '卜航钧', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-06-29', '2019556295', '本科', '专业', '15612689300', '2020-06', '男', NULL);
204 | INSERT INTO `person` VALUES ('038c2d36-4274-11eb-bb0a-ed55e0675fa7', '凌征柏', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-03-27', '2019734513', '本科', '专业', '15609813363', '2020-06', '男', NULL);
205 | INSERT INTO `person` VALUES ('038c3efc-4274-11eb-bb0a-ed55e0675fa7', '卜小双', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-09-13', '2019503680', '本科', '专业', '17688696112', '2020-06', '男', NULL);
206 | INSERT INTO `person` VALUES ('038c4e92-4274-11eb-bb0a-ed55e0675fa7', '强武中', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-10-17', '2019814860', '本科', '专业', '17608396635', '2020-06', '男', NULL);
207 | INSERT INTO `person` VALUES ('038c5f68-4274-11eb-bb0a-ed55e0675fa7', '屈华宇', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-11-11', '2019563259', '本科', '专业', '17690528348', '2020-06', '男', NULL);
208 | INSERT INTO `person` VALUES ('038c6ee0-4274-11eb-bb0a-ed55e0675fa7', '康媛征', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-12-10', '2019871719', '本科', '专业', '15614722132', '2020-06', '男', NULL);
209 | INSERT INTO `person` VALUES ('038c7f52-4274-11eb-bb0a-ed55e0675fa7', '诸忠泉', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-02-13', '2019668816', '本科', '专业', '15610097887', '2020-06', '男', NULL);
210 | INSERT INTO `person` VALUES ('038c8e52-4274-11eb-bb0a-ed55e0675fa7', '柯江瑜', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-10-07', '2019728923', '本科', '专业', '15616047698', '2020-06', '男', NULL);
211 | INSERT INTO `person` VALUES ('038c9eb0-4274-11eb-bb0a-ed55e0675fa7', '姚远博', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-06-22', '2019638168', '本科', '专业', '13622265870', '2020-06', '男', NULL);
212 | INSERT INTO `person` VALUES ('038caf18-4274-11eb-bb0a-ed55e0675fa7', '房良锦', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-01-25', '2019504073', '本科', '专业', '17639644735', '2020-06', '男', NULL);
213 | INSERT INTO `person` VALUES ('038cbea4-4274-11eb-bb0a-ed55e0675fa7', '麻冬圣', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-12-01', '2019605862', '本科', '专业', '17696416506', '2020-06', '男', NULL);
214 | INSERT INTO `person` VALUES ('038ccd68-4274-11eb-bb0a-ed55e0675fa7', '何钧坚', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-05-19', '2019517092', '本科', '专业', '17609460950', '2020-06', '男', NULL);
215 | INSERT INTO `person` VALUES ('038cdd30-4274-11eb-bb0a-ed55e0675fa7', '霍骏斌', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-02-23', '2019767873', '本科', '专业', '17619904819', '2020-06', '男', NULL);
216 | INSERT INTO `person` VALUES ('038cec62-4274-11eb-bb0a-ed55e0675fa7', '管晋芳', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-08-05', '2019788091', '本科', '专业', '13601406042', '2020-06', '男', NULL);
217 | INSERT INTO `person` VALUES ('038cfc52-4274-11eb-bb0a-ed55e0675fa7', '管珍家', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-07-13', '2019636837', '本科', '专业', '17666242878', '2020-06', '男', NULL);
218 | INSERT INTO `person` VALUES ('038d0bd4-4274-11eb-bb0a-ed55e0675fa7', '左彦琪', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-11-16', '2019819912', '本科', '专业', '15697115233', '2020-06', '男', NULL);
219 | INSERT INTO `person` VALUES ('038d1ade-4274-11eb-bb0a-ed55e0675fa7', '昌萌灿', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-10-11', '2019689048', '本科', '专业', '13615195848', '2020-06', '男', NULL);
220 | INSERT INTO `person` VALUES ('038d2be6-4274-11eb-bb0a-ed55e0675fa7', '王勤波', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-04-08', '2019985507', '本科', '专业', '15661602918', '2020-06', '男', NULL);
221 | INSERT INTO `person` VALUES ('038d3b5e-4274-11eb-bb0a-ed55e0675fa7', '高田元', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-01-01', '2019860392', '本科', '专业', '17601798270', '2020-06', '男', NULL);
222 | INSERT INTO `person` VALUES ('038d4bd0-4274-11eb-bb0a-ed55e0675fa7', '谈震方', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-03-14', '2019845437', '本科', '专业', '15632108246', '2020-06', '男', NULL);
223 | INSERT INTO `person` VALUES ('038d5b2a-4274-11eb-bb0a-ed55e0675fa7', '崔伯坤', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-12-30', '2019646011', '本科', '专业', '13644736018', '2020-06', '男', NULL);
224 | INSERT INTO `person` VALUES ('038d6af2-4274-11eb-bb0a-ed55e0675fa7', '章萌生', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-05-22', '2019693743', '本科', '专业', '13632922584', '2020-06', '男', NULL);
225 | INSERT INTO `person` VALUES ('038d7c18-4274-11eb-bb0a-ed55e0675fa7', '诸萌夫', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-12-12', '2019530682', '本科', '专业', '17657299789', '2020-06', '男', NULL);
226 | INSERT INTO `person` VALUES ('038d8d34-4274-11eb-bb0a-ed55e0675fa7', '米征智', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-07-30', '2019572182', '本科', '专业', '15694338276', '2020-06', '男', NULL);
227 | INSERT INTO `person` VALUES ('038d9e00-4274-11eb-bb0a-ed55e0675fa7', '殷广健', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-01-15', '2019768865', '本科', '专业', '13675781251', '2020-06', '男', NULL);
228 | INSERT INTO `person` VALUES ('038daf30-4274-11eb-bb0a-ed55e0675fa7', '汪洲健', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-06-23', '2019627781', '本科', '专业', '15646149452', '2020-06', '男', NULL);
229 | INSERT INTO `person` VALUES ('038dc4e8-4274-11eb-bb0a-ed55e0675fa7', '杜宏伊', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-04-04', '2019832308', '本科', '专业', '13642998592', '2020-06', '男', NULL);
230 | INSERT INTO `person` VALUES ('038de1d0-4274-11eb-bb0a-ed55e0675fa7', '范仲方', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-11-06', '2019778199', '本科', '专业', '15679605781', '2020-06', '男', NULL);
231 | INSERT INTO `person` VALUES ('038df346-4274-11eb-bb0a-ed55e0675fa7', '冯卓宝', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-06-23', '2019894071', '本科', '专业', '15628202263', '2020-06', '男', NULL);
232 | INSERT INTO `person` VALUES ('038e052a-4274-11eb-bb0a-ed55e0675fa7', '包轩化', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-11-01', '2019635757', '本科', '专业', '17645453153', '2020-06', '男', NULL);
233 | INSERT INTO `person` VALUES ('038e1538-4274-11eb-bb0a-ed55e0675fa7', '戴利菲', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-09-30', '2019996573', '本科', '专业', '15625999999', '2020-06', '男', NULL);
234 | INSERT INTO `person` VALUES ('038e2d48-4274-11eb-bb0a-ed55e0675fa7', '施美茜', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-03-27', '2019575594', '本科', '专业', '17698265022', '2020-06', '男', NULL);
235 | INSERT INTO `person` VALUES ('038e3f04-4274-11eb-bb0a-ed55e0675fa7', '郎希志', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-12-05', '2019888253', '本科', '专业', '13670147496', '2020-06', '男', NULL);
236 | INSERT INTO `person` VALUES ('038e4fc6-4274-11eb-bb0a-ed55e0675fa7', '孙志民', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-12-08', '2019714483', '本科', '专业', '15656813156', '2020-06', '男', NULL);
237 | INSERT INTO `person` VALUES ('038e60b0-4274-11eb-bb0a-ed55e0675fa7', '魏勤滨', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-11-22', '2019907656', '本科', '专业', '13682644748', '2020-06', '男', NULL);
238 | INSERT INTO `person` VALUES ('038e7140-4274-11eb-bb0a-ed55e0675fa7', '孙日富', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-08-29', '2019894830', '本科', '专业', '15695997014', '2020-06', '男', NULL);
239 | INSERT INTO `person` VALUES ('038e80a4-4274-11eb-bb0a-ed55e0675fa7', '钮孝来', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-08-14', '2019751184', '本科', '专业', '13685379554', '2020-06', '男', NULL);
240 | INSERT INTO `person` VALUES ('038e90d0-4274-11eb-bb0a-ed55e0675fa7', '王英阳', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-02-12', '2019571430', '本科', '专业', '13650381081', '2020-06', '男', NULL);
241 | INSERT INTO `person` VALUES ('038ea0e8-4274-11eb-bb0a-ed55e0675fa7', '袁淇虎', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-09-24', '2019603598', '本科', '专业', '15678872714', '2020-06', '男', NULL);
242 | INSERT INTO `person` VALUES ('038eb182-4274-11eb-bb0a-ed55e0675fa7', '滕萌若', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-04-18', '2019803699', '本科', '专业', '17607361041', '2020-06', '男', NULL);
243 | INSERT INTO `person` VALUES ('038ec208-4274-11eb-bb0a-ed55e0675fa7', '鲍鹏银', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-04-17', '2019707704', '本科', '专业', '13649590210', '2020-06', '男', NULL);
244 | INSERT INTO `person` VALUES ('038ed23e-4274-11eb-bb0a-ed55e0675fa7', '钟一百', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-07-28', '2019627422', '本科', '专业', '17631495657', '2020-06', '男', NULL);
245 | INSERT INTO `person` VALUES ('038ee328-4274-11eb-bb0a-ed55e0675fa7', '费靖豪', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-12-27', '2019514000', '本科', '专业', '15673191955', '2020-06', '男', NULL);
246 | INSERT INTO `person` VALUES ('038ef336-4274-11eb-bb0a-ed55e0675fa7', '韩大长', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-03-21', '2019687734', '本科', '专业', '15628591111', '2020-06', '男', NULL);
247 | INSERT INTO `person` VALUES ('038f02f4-4274-11eb-bb0a-ed55e0675fa7', '徐坚忠', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-02-20', '2019896670', '本科', '专业', '13689192591', '2020-06', '男', NULL);
248 | INSERT INTO `person` VALUES ('038f130c-4274-11eb-bb0a-ed55e0675fa7', '康宇剑', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-01-13', '2019920147', '本科', '专业', '17685125250', '2020-06', '男', NULL);
249 | INSERT INTO `person` VALUES ('038f2342-4274-11eb-bb0a-ed55e0675fa7', '范真虹', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-10-04', '2019910727', '本科', '专业', '13601525109', '2020-06', '男', NULL);
250 | INSERT INTO `person` VALUES ('038f3224-4274-11eb-bb0a-ed55e0675fa7', '钟洋兰', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-09-05', '2019793195', '本科', '专业', '13671341340', '2020-06', '男', NULL);
251 | INSERT INTO `person` VALUES ('038f40e8-4274-11eb-bb0a-ed55e0675fa7', '梅清铁', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-02-17', '2019733794', '本科', '专业', '17643378904', '2020-06', '男', NULL);
252 | INSERT INTO `person` VALUES ('038f5056-4274-11eb-bb0a-ed55e0675fa7', '鲁仪强', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-08-12', '2019789386', '本科', '专业', '15653795984', '2020-06', '男', NULL);
253 | INSERT INTO `person` VALUES ('038f641a-4274-11eb-bb0a-ed55e0675fa7', '郎庆涛', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-09-01', '2019745548', '本科', '专业', '17620427825', '2020-06', '男', NULL);
254 | INSERT INTO `person` VALUES ('038f7496-4274-11eb-bb0a-ed55e0675fa7', '陈蔚景', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-06-30', '2019859582', '本科', '专业', '17635922320', '2020-06', '男', NULL);
255 | INSERT INTO `person` VALUES ('038f847c-4274-11eb-bb0a-ed55e0675fa7', '曹其道', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-06-27', '2019561268', '本科', '专业', '13697089553', '2020-06', '男', NULL);
256 | INSERT INTO `person` VALUES ('038f94b2-4274-11eb-bb0a-ed55e0675fa7', '黄荣传', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-12-10', '2019727592', '本科', '专业', '15617357000', '2020-06', '男', NULL);
257 | INSERT INTO `person` VALUES ('9842bace-c4d6-4512-8406-9db5f0bac182', '张三', '研发部', '10000', '研发岗', 'P6', '2021-01-05 14:51:24', '2015-06-07', '2019697465', '本科', '专业', '17667768265', '2020-06', '男', NULL);
258 | INSERT INTO `person` VALUES ('fc7cb664-4273-11eb-bb0a-ed55e0675fa7', '毛石媛', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2018-07-06', '2019525695', '本科', '专业', '17664489380', '2020-06', '男', NULL);
259 | INSERT INTO `person` VALUES ('fd75f2ce-4273-11eb-bb0a-ed55e0675fa7', '贺亦思', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2016-04-05', '2019536080', '本科', '专业', '17619264321', '2020-06', '男', NULL);
260 | INSERT INTO `person` VALUES ('fdd8f66c-4273-11eb-bb0a-ed55e0675fa7', '宋星岩', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-10-08', '2019603316', '本科', '专业', '17631510757', '2020-06', '男', NULL);
261 | INSERT INTO `person` VALUES ('fe22aa46-4273-11eb-bb0a-ed55e0675fa7', '金义淇', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2015-01-22', '2019908343', '本科', '专业', '17613155865', '2020-06', '男', NULL);
262 | INSERT INTO `person` VALUES ('fe66142a-4273-11eb-bb0a-ed55e0675fa7', '尹华晖', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2017-12-28', '2019731765', '本科', '专业', '17665919362', '2020-06', '男', NULL);
263 | INSERT INTO `person` VALUES ('fe9ce572-4273-11eb-bb0a-ed55e0675fa7', '雷景双', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-10-11', '2019933797', '本科', '专业', '15681317336', '2020-06', '男', NULL);
264 | INSERT INTO `person` VALUES ('fedeea3a-4273-11eb-bb0a-ed55e0675fa7', '贾政政', '研发部', '10000', '研发岗', 'P6', '2020-12-20 11:30:42', '2019-11-29', '2019973692', '本科', '专业', '15689999903', '2020-06', '男', NULL);
265 | INSERT INTO `person` VALUES ('ff1b847c-4273-11eb-bb0a-ed55e0675fa7', '米儿天', '研发部', '10000', '研发岗', 'P6', '2021-01-04 17:45:58', '2015-03-22', '2019567070', '本科', '专业', '13696110769', '2020-06', '男', NULL);
266 | INSERT INTO `person` VALUES ('ff5d3a66-4273-11eb-bb0a-ed55e0675fa7', '郑士灵', '研发部', '10000', '研发岗', 'P6', '2021-01-04 17:52:28', '2016-05-17', '2019914272', '本科', '专业', '17684736967', '2020-06', '男', NULL);
267 | COMMIT;
268 |
269 | -- ----------------------------
270 | -- Table structure for person_education
271 | -- ----------------------------
272 | DROP TABLE IF EXISTS `person_education`;
273 | CREATE TABLE `person_education` (
274 | `id` char(36) NOT NULL,
275 | `personid` varchar(255) DEFAULT NULL,
276 | `time` varchar(255) DEFAULT NULL COMMENT '起止时间',
277 | `school` varchar(255) DEFAULT NULL COMMENT '学校',
278 | `type` varchar(255) DEFAULT NULL COMMENT '学校类型',
279 | `remark` text COMMENT '备注',
280 | `timestamp` datetime DEFAULT NULL,
281 | PRIMARY KEY (`id`)
282 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
283 |
284 | -- ----------------------------
285 | -- Records of person_education
286 | -- ----------------------------
287 | BEGIN;
288 | COMMIT;
289 |
290 | -- ----------------------------
291 | -- Table structure for person_resume
292 | -- ----------------------------
293 | DROP TABLE IF EXISTS `person_resume`;
294 | CREATE TABLE `person_resume` (
295 | `id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
296 | `personid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
297 | `time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '起止时间',
298 | `workunit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '工作单位',
299 | `workduty` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '职务',
300 | `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '备注',
301 | `timestamp` datetime DEFAULT NULL,
302 | PRIMARY KEY (`id`)
303 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
304 |
305 | -- ----------------------------
306 | -- Records of person_resume
307 | -- ----------------------------
308 | BEGIN;
309 | INSERT INTO `person_resume` VALUES ('4d660920-45d6-47d6-b366-5de31fdfa6da', '9842bace-c4d6-4512-8406-9db5f0bac182', '2019-01,2019-08', '江苏省xxx公司', '软件工程师', '相关备注
', '2020-12-20 11:29:54');
310 | INSERT INTO `person_resume` VALUES ('e1c2a250-2b94-45cb-a239-d7f9b690459d', '9842bace-c4d6-4512-8406-9db5f0bac182', '2019-10,2020-10', '苏州市某科技有限公司', '某技术组长', '\n\n\n123 | \n | \n | \n | \n | \n | \n | \n
\n\n123 | \n | \n | \n | \n | \n | \n | \n
\n\n123 | \n | \n | \n | \n | \n | \n | \n
\n\n | \n345 | \n | \n | \n | \n | \n | \n
\n\n | \n | \n567567 | \n | \n | \n | \n | \n
\n\n
', '2020-12-20 11:30:34');
311 | COMMIT;
312 |
313 | -- ----------------------------
314 | -- Table structure for role
315 | -- ----------------------------
316 | DROP TABLE IF EXISTS `role`;
317 | CREATE TABLE `role` (
318 | `id` char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
319 | `roleName` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '角色名',
320 | `roleAuthName` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '权限',
321 | `roleAuthNameDict` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '权限名称',
322 | `rank` int DEFAULT NULL COMMENT '排序',
323 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
324 | PRIMARY KEY (`id`) USING BTREE
325 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
326 |
327 | -- ----------------------------
328 | -- Records of role
329 | -- ----------------------------
330 | BEGIN;
331 | INSERT INTO `role` VALUES ('00000000-1000-0000-0000-000000000000', '超级管理员', 'AdminDashboardForAdmin,AdminDashboard,Users,Role,FormDesigner,TableDesigner,Dict,flowClueInfo,BusinessActClueInfo,System,DevTools', '运维桌面,用户管理,角色管理,表单设计,表格设计,字典管理,线索管理', 2, '2020-09-17 10:32:04');
332 | COMMIT;
333 |
334 | -- ----------------------------
335 | -- Table structure for users
336 | -- ----------------------------
337 | DROP TABLE IF EXISTS `users`;
338 | CREATE TABLE `users` (
339 | `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
340 | `userName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户名',
341 | `deptId` varchar(36) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
342 | `roleId` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
343 | `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '密码',
344 | `realName` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '真实姓名',
345 | `rank` int DEFAULT '0' COMMENT '排序码',
346 | `photo` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '照片',
347 | `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
348 | PRIMARY KEY (`id`) USING BTREE,
349 | KEY `index_id` (`id`) USING BTREE,
350 | KEY `index_username` (`userName`) USING BTREE,
351 | KEY `index_deptid` (`deptId`)
352 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
353 |
354 | -- ----------------------------
355 | -- Records of users
356 | -- ----------------------------
357 | BEGIN;
358 | INSERT INTO `users` VALUES ('00000000-1000-0000-0000-000000000000', 'admin', '2f8447de-5732-4fa4-8286-9a71b41dd1e7', '00000000-1000-0000-0000-000000000000', '123', '超级管理员', 0, 'data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3aiiigAqhrOs2Og6ZLqGoTCOCP8Sx7KB3Jq/0GTXgHxT8SjW/Ef2O1uFlsLJQqGNsq7kZZsjr6fgaAJPEPxZ1vVJXj0xv7Oteg2YMrD3bt+GPqa4m61O/vWLXd7czsepllZv5mqtFMkckjxtujdlPqpxWzp3jDxDpTqbTV7tQP4HkLp/3y2RWJRQB7d4M+K0WrXMWna3HHbXMhCx3CcRuewIP3T+n0r02vkSvpH4ea4+veD7SaeTfcw5gmJOSSvQn6jH60ho6qiiigYUUUUAFFFFAHL/EW8lsfAWqzQsVcxrHkdg7qp/Qmvmyvpnx3Zm/8DavAoywtzIB/uEP/wCy1478OfDGna1eXWo6zNHHpthtLrI4RXZs4BPpwfrxTEzl9O0TVdWJGn6fc3IBwTFEWA+p6Ctn/hXXi3Zv/sWbH++mfyzmvd7fxFoUVukdnIfs6jCfZrWRowPYquMU4eL/AA7v2PrFpE/92aQRn8mxSCx81X+k6jpUgj1CxuLVj0E0ZXP0z1qnX07e+IfCl1bPBeatpE8DD5o5LiNwfwzXneseB/CGpyGfRdUuLbdzsitZLiL8MDI/M0wseTV2nws1Gey8dWcMbsIroPFKueCNpI/IgfrXQeH/AIZ6DdX4ivPESXMi8mzjTyZCPcMd2PoPxrD+Fdg0/wAQbdsZFpHLI3/fJX+bCgD6DooopDCiiigAooooAzPEglPhfVhBnzvsc2zHXOw4rxzwz4Tjt/iBYWdy63OmyKt1EGORIGjd0yOhxtP5e9e7EAjBGQa8/Phn+zPFlvbR3jLb3EDHT22AtayRNvCf7S4kkGD/AA5HvQB6AOBgdK5jx/p9pqHhG8W4gSSYKBbEj5hKWAUA9eSQPxq/9r16IbH0q1mcf8tIrsqre+CuR9OfqaZDpl/fX8N5rMkAW3bfBZ25JjR/77MQC7DPHAA9M80AYL+EdD0/xrozJpdtFC1vMFAX5WmXYVyD1O3eR9Pau5qlqmmRaraCF5HikRxJDNH96Jx0Yf55BI71Sjn8RWwEc9jZ3uOBPDOYi3uUZTj8GNAGP8S9Ki1DwsZVVVvoZ4RbSjhlZpFXAPXHzfp7Vy3wq0S40vWkuZZQxvdNNwyD+BTIoTJ9ThjXW+JBftol1qGpJDClrGzW1pC5fdMRtQuxA6FhhQOvOTgVo+F/Dv8Awj9gFmnNxePHGkku3aAqLtRFHZQPzJJ70CN2iiigYUUUUAFFFFABWN4lsbi601LmyXdfWMq3Vuv99l6p/wACUsv41s0UAVdN1C31XToL61bdDMu5c9R6g+hB4I9RVquMlmutN8V3S+HrY3kO3ztStQ4VUkOMGMngSEZJXoQAeCat3XxC8OWNuXvLuS3nX71rLCyzA+hXH69PegDqKK4TTfi14Zv5zFM9zZf3XuIxtb8VJx+NX9R8TX2oWE//AAitlJeFUJN4y7Yh/wBc92PMb0A4z1PagCxqTf234ktNJj+a2sHW7vW7bx/qo/rn5iPRR610lY/hiHT49Dhl06Vp458yyTyHMksh+8z/AO1ngjtjHatigAooooAKKKKACuO134meHNEkaH7Q17cLwY7UBgD7tnH6muX+Lni+4tZE8P2ErR74w906nBIPRM9uOT9R7147QK56pf8AxsvXJGn6RbxDs08hkP5DbXNah8TfFeoKU/tH7Mh/htkCf+Pfe/WuQopgen/CrxmbPU5NG1GYtHeyb4pnOSJj2J77sD8frXWeJ/D1n4+1r7NAoiTTw0c+oqMkvjiJR0bBOW9Og5JrwUEqwZSQRyCO1enfDf4iR6UiaLrDhbQsTDcn/lmSckN7Enr2+nQAtwfBqe0iluZb2G9miIeK1CFEmAOSrNnIyMjjoT1rtNT8a6Zo/g0apboqsB5ENmw2sko48tl7bcc+w9xWh4k8W6Z4Z0r7ZczLI8i5ghRgWmPbHt79K+ctb1m613VbjULoqHmcuUQYVeAOB9ABnqcUgLVn4u1/T7ye6tNUniknkaWQA5RmJyTtPH6V09l8YvEdvgXMVldr3LxlG/NSB+lee0UxHtemfGnTZmVNT02e1zwXhcSL9SOD/OvQdJ1rTdctftOmXkVzF32HlfYjqD9a+U60tD1y+8PapFf2EpSRD8y5+WRe6sO4NA7n1TRVLSNSh1nSLTUYOI7iISAH+HPUfgcj8KKQz5u8Z351Lxlq1ySSDcsi/wC6p2j9AKwqt6lFcJfzvcwSws8jNiRCp5Oe9VKZIUUUUAFFFFACli2MknAwM9qSiigAooooAKKKMZOBQB7j8Kddhj8GfZrmTabe5dEH+yQG/mxorzrQP7VtNPZItOvXRpCwKQMQeB6D2opDPoySKOZCkqK6nqrDIrJuvCPh28yZ9EsGY9WECqfzAzRRQMx7j4W+EZ8401oSe8c7j9CSKxtQ+EHhyKB5Y7jUUIHQSoR+q0UUCOC1Twhp9izCKa5OP7zL/wDE1y13apA5CFjj1oopgQRIHfBz+Fb2naBa3ZHmSTDP90j/AAoooA7rRPhdoeojM11qA9lkQf8AsldLB8I/CkJ+eC6n/wCuk5H/AKDiiikBrW3gDwpaf6vRLZv+uuZP/Qia2bXStPsQPslha2+OnlQqv8hRRQMt0UUUAf/Z', '2021-01-05 15:00:15');
359 | COMMIT;
360 |
361 | -- ----------------------------
362 | -- Function structure for generatePhone
363 | -- ----------------------------
364 | DROP FUNCTION IF EXISTS `generatePhone`;
365 | delimiter ;;
366 | CREATE FUNCTION `generatePhone`()
367 | RETURNS char(11) CHARSET utf8mb3
368 | DETERMINISTIC
369 | BEGIN
370 | DECLARE head VARCHAR(100) DEFAULT '000,156,136,176';
371 | DECLARE content CHAR(10) DEFAULT '0123456789';
372 | DECLARE phone CHAR(11) DEFAULT substring(head, 1+(FLOOR(1 + (RAND() * 3))*4), 3);
373 |
374 | #SET phone = CONCAT(phone, substring('156,136,123,456,789', 1+(FLOOR(1 + (RAND() * 4))*4), 3));
375 |
376 | DECLARE i int DEFAULT 1;
377 | DECLARE len int DEFAULT LENGTH(content);
378 | WHILE i<9 DO
379 | SET i=i+1;
380 | SET phone = CONCAT(phone, substring(content, floor(1 + RAND() * len), 1));
381 | END WHILE;
382 |
383 | RETURN phone;
384 | END
385 | ;;
386 | delimiter ;
387 |
388 | -- ----------------------------
389 | -- Function structure for generateUserName
390 | -- ----------------------------
391 | DROP FUNCTION IF EXISTS `generateUserName`;
392 | delimiter ;;
393 | CREATE FUNCTION `generateUserName`()
394 | RETURNS varchar(255) CHARSET utf8mb3
395 | DETERMINISTIC
396 | BEGIN
397 | DECLARE xing varchar(2056) DEFAULT '赵钱孙李周郑王冯陈楮卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闽席季麻强贾路娄危江童颜郭梅盛林刁锺徐丘骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经裘缪干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁';
398 |
399 | DECLARE ming varchar(2056) DEFAULT '嘉懿煜城懿轩烨伟苑博伟泽熠彤鸿煊博涛烨霖烨华煜祺智宸正豪昊然明杰诚立轩立辉峻熙弘文熠彤鸿煊烨霖哲瀚鑫鹏致远俊驰雨泽烨磊晟睿天佑文昊修洁黎昕远航旭尧鸿涛伟祺轩越泽浩宇瑾瑜皓轩擎苍擎宇志泽睿渊楷瑞轩弘文哲瀚雨泽鑫磊梦琪忆之桃慕青问兰尔岚元香初夏沛菡傲珊曼文乐菱痴珊恨玉惜文香寒新柔语蓉海安夜蓉涵柏水桃醉蓝春儿语琴从彤傲晴语兰又菱碧彤元霜怜梦紫寒妙彤曼易南莲紫翠雨寒易烟如萱若南寻真晓亦向珊慕灵以蕊寻雁映易雪柳孤岚笑霜海云凝天沛珊寒云冰旋宛儿绿真盼儿晓霜碧凡夏菡曼香若烟半梦雅绿冰蓝灵槐平安书翠翠风香巧代云梦曼幼翠友巧听寒梦柏醉易访旋亦玉凌萱访卉怀亦笑蓝春翠靖柏夜蕾冰夏梦松书雪乐枫念薇靖雁寻春恨山从寒忆香觅波静曼凡旋以亦念露芷蕾千兰新波代真新蕾雁玉冷卉紫山千琴恨天傲芙盼山怀蝶冰兰山柏翠萱乐丹翠柔谷山之瑶冰露尔珍谷雪乐萱涵菡海莲傲蕾青槐冬儿易梦惜雪宛海之柔夏青亦瑶妙菡春竹修杰伟诚建辉晋鹏天磊绍辉泽洋明轩健柏煊昊强伟宸博超君浩子骞明辉鹏涛炎彬鹤轩越彬风华靖琪明诚高格光华国源宇晗昱涵润翰飞翰海昊乾浩博和安弘博鸿朗华奥华灿嘉慕坚秉建明金鑫锦程瑾瑜鹏经赋景同靖琪君昊俊明季同开济凯安康成乐语力勤良哲理群茂彦敏博明达朋义彭泽鹏举濮存溥心璞瑜浦泽奇邃祥荣轩';
400 |
401 | DECLARE I_xing int DEFAULT LENGTH(xing) / 3;
402 | DECLARE I_ming int DEFAULT LENGTH(ming) / 3;
403 | DECLARE return_str varchar(2056) DEFAULT '';
404 |
405 | SET return_str = CONCAT(return_str, substring(xing, floor(1 + RAND() * I_xing), 1));
406 | SET return_str = CONCAT(return_str, substring(ming, floor(1 + RAND() * I_ming), 1));
407 |
408 | IF RAND() > 0.400 THEN
409 | SET return_str = CONCAT(return_str, substring(ming, floor(1 + RAND() * I_ming), 1));
410 | END IF;
411 |
412 | RETURN return_str;
413 | END
414 | ;;
415 | delimiter ;
416 |
417 | SET FOREIGN_KEY_CHECKS = 1;
418 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nestjs-api-server",
3 | "version": "0.0.1",
4 | "description": "一套基于NestJS-API-Server",
5 | "author": "BoBo",
6 | "private": true,
7 | "license": "MIT",
8 | "scripts": {
9 | "prebuild": "rimraf dist",
10 | "build": "nest build",
11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
12 | "start": "cross-env NODE_ENV=development && nest start --watch",
13 | "start:debug": "cross-env NODE_ENV=development && nest start --debug --watch",
14 | "start:prod": "cross-env NODE_ENV=production && PORT=3000 node dist/main",
15 | "start:test": "cross-env NODE_ENV=test && cross-env NODE_ENV=test && node dist/main",
16 | "pm2": "pm2 start --name admin dist/main.js --env production",
17 | "db": "rm -rf src/entities & npx typeorm-model-generator -h localhost -d nest -p 3306 -u root -x root -e mysql -o src/entities --noConfig true --ce pascal --cp camel",
18 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
19 | "test": "jest",
20 | "test:watch": "jest --watch",
21 | "test:cov": "jest --coverage",
22 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
23 | "test:e2e": "jest --config ./test/jest-e2e.json"
24 | },
25 | "dependencies": {
26 | "@nestjs/common": "10.2.8",
27 | "@nestjs/config": "^3.1.1",
28 | "@nestjs/core": "10.2.8",
29 | "@nestjs/jwt": "^10.2.0",
30 | "@nestjs/platform-express": "10.2.8",
31 | "@nestjs/testing": "10.2.8",
32 | "@nestjs/passport": "^10.0.2",
33 | "@nestjs/platform-socket.io": "^10.2.8",
34 | "@nestjs/platform-ws": "^10.2.8",
35 | "@nestjs/swagger": "^7.1.15",
36 | "@nestjs/typeorm": "^10.0.0",
37 | "@nestjs/websockets": "^10.2.8",
38 | "@nestjs/serve-static": "^4.0.0",
39 | "compression": "^1.7.4",
40 | "dayjs": "^1.8.35",
41 | "helmet": "^4.0.0",
42 | "log4js": "^6.3.0",
43 | "moment": "^2.27.0",
44 | "mysql2": "^3.6.3",
45 | "passport": "^0.4.1",
46 | "passport-jwt": "^4.0.0",
47 | "passport-local": "^1.0.0",
48 | "path": "^0.12.7",
49 | "reflect-metadata": "^0.1.13",
50 | "rimraf": "^3.0.2",
51 | "rxjs": "7.5.5",
52 | "stacktrace-js": "^2.0.2",
53 | "swagger-ui-express": "^4.1.4",
54 | "typeorm": "^0.3.17",
55 | "uuid": "^8.3.0"
56 | },
57 | "devDependencies": {
58 | "@nestjs/cli": "^10.2.1",
59 | "@nestjs/schematics": "^10.0.3",
60 | "@nestjs/testing": "^10.2.8",
61 | "@types/express": "^4.17.3",
62 | "@types/helmet": "^0.0.47",
63 | "@types/jest": "25.2.3",
64 | "@types/node": "^13.9.1",
65 | "@types/passport-local": "^1.0.33",
66 | "@types/supertest": "^2.0.8",
67 | "@typescript-eslint/eslint-plugin": "6.11.0",
68 | "@typescript-eslint/parser": "6.11.0",
69 | "cross-env": "^7.0.3",
70 | "eslint": "8.53.0",
71 | "eslint-config-prettier": "^9.0.0",
72 | "eslint-plugin-import": "^2.29.0",
73 | "eslint-plugin-prettier": "^5.0.1",
74 | "husky": "^4.3.0",
75 | "jest": "26.0.1",
76 | "lint-staged": "^10.5.1",
77 | "prettier": "^3.1.0",
78 | "start-server-webpack-plugin": "^2.2.5",
79 | "supertest": "^4.0.2",
80 | "ts-jest": "26.1.0",
81 | "ts-node": "^8.6.2",
82 | "tsconfig-paths": "^4.2.0",
83 | "typescript": "5.2.2",
84 | "webpack-node-externals": "^2.5.1",
85 | "tsconfig-paths-webpack-plugin": "^4.1.0"
86 | },
87 | "husky": {
88 | "hooks": {
89 | "pre-commit": "lint-staged"
90 | }
91 | },
92 | "lint-staged": {
93 | "src/**/*.{js,ts}": [
94 | "prettier --write",
95 | "eslint --fix",
96 | "git add"
97 | ]
98 | },
99 | "jest": {
100 | "moduleFileExtensions": [
101 | "js",
102 | "json",
103 | "ts"
104 | ],
105 | "rootDir": "src",
106 | "testRegex": ".spec.ts$",
107 | "transform": {
108 | "^.+\\.(t|j)s$": "ts-jest"
109 | },
110 | "coverageDirectory": "../coverage",
111 | "testEnvironment": "node"
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Nest-Api-Server
5 |
6 |
7 |
8 |
9 | 如果对你有帮助的话,帮忙点点star! ^_^
10 |
11 |
12 |
13 | 打开console查看socket信息
14 |
15 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get, Redirect } from '@nestjs/common'
2 | import { AppService } from './app.service'
3 | import { NoAuth } from './guards/customize'
4 |
5 | @Controller()
6 | export class AppController {
7 | constructor(private readonly appService: AppService) {}
8 |
9 | @NoAuth()
10 | @Get()
11 | @Redirect('/public', 301)
12 | root(): string {
13 | return ''
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { EducationModule } from './module/person/education/education.module'
2 | import { ResumeModule } from './module/person/resume/resume.module'
3 | import { PersonModule } from './module/person/person.module'
4 | import { DynamictablesModule } from './module/dynamictables/dynamictables.module'
5 | import { FormModule } from './module/form/form.module'
6 | import { AdCodelistModule } from './module/ad-codelist/ad-codelist.module'
7 | import { RoleModule } from './module/role/role.module'
8 | import { Module } from '@nestjs/common'
9 | import { AppController } from './app.controller'
10 | import { AppService } from './app.service'
11 | import { UsersModule } from './module/users/users.module'
12 | import { AuthModule } from './module/auth/auth.module'
13 | import { Connection } from 'typeorm'
14 | import { APP_GUARD } from '@nestjs/core'
15 | import { RoleAuthGuard } from './guards/auth-guards'
16 | import { ServeStaticModule } from '@nestjs/serve-static'
17 | import { join } from 'path'
18 | import { TypeOrmModule } from '@nestjs/typeorm'
19 | import { UploadModule } from './module/upload/upload.module'
20 | import { EventsModule } from './events/events.module'
21 | import { ConfigModule, ConfigService } from '@nestjs/config'
22 | import customConfig from './config'
23 | import { AdCodelistTypeModule } from './module/ad-codelist-type/ad-codelist-type.module'
24 |
25 | @Module({
26 | imports: [
27 | ConfigModule.forRoot({
28 | isGlobal: true, // 作用于全局
29 | load: [customConfig] // 加载自定义配置项
30 | }),
31 | TypeOrmModule.forRootAsync({
32 | imports: [ConfigModule], // 数据库配置项依赖于ConfigModule,需在此引入
33 | useFactory: (configService: ConfigService) =>
34 | configService.get('DATABASE_CONFIG'),
35 | inject: [ConfigService] // 记得注入服务,不然useFactory函数中获取不到ConfigService
36 | }),
37 | ServeStaticModule.forRoot({
38 | rootPath: join(__dirname, '..', 'public'),
39 | exclude: ['/api*']
40 | }),
41 | EventsModule,
42 | AuthModule,
43 | UsersModule,
44 | UploadModule,
45 | RoleModule,
46 | PersonModule,
47 | AdCodelistModule,
48 | AdCodelistTypeModule,
49 | FormModule,
50 | DynamictablesModule,
51 | ResumeModule,
52 | EducationModule
53 | ],
54 | controllers: [AppController],
55 | providers: [
56 | AppService,
57 | {
58 | provide: APP_GUARD,
59 | useClass: RoleAuthGuard
60 | }
61 | ]
62 | })
63 | export class AppModule {
64 | constructor(private readonly connection: Connection) {}
65 | }
66 |
--------------------------------------------------------------------------------
/src/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common'
2 |
3 | @Injectable()
4 | export class AppService {}
5 |
--------------------------------------------------------------------------------
/src/config/constants.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 设置jwt相关参数
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月06 16:10:49
6 | */
7 | export const jwtConstants = {
8 | secret: 'shinobi7414', // 秘钥
9 | time: '24h'
10 | }
11 |
--------------------------------------------------------------------------------
/src/config/env/development.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 数据库配置文件 https://www.bookstack.cn/read/TypeORM-0.2.20-zh/connection-options.md
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年09月15 14:16:42
6 | */
7 | import { join } from 'path'
8 |
9 | export default {
10 | // 端口
11 | port: parseInt(process.env.PORT, 10) || 3000,
12 | // 是否开启swagger
13 | enableSwagger: true,
14 | // 数据库配置
15 | DATABASE_CONFIG: {
16 | type: 'mysql',
17 | host: 'localhost',
18 | port: 3306,
19 | username: 'root',
20 | password: 'root',
21 | database: 'nest',
22 | charset: 'utf8mb4',
23 | entities: [join(__dirname, '..', '..', '/entities/*{.ts,.js}')],
24 | synchronize: true, // 是否在每次应用程序启动时自动创建数据库架构
25 | logging: false,
26 | dateStrings: true, // 强制日期类型(TIMESTAMP,DATETIME,DATE)作为字符串返回,而不是转换为 JavaScript Date 对象
27 | },
28 | }
29 |
--------------------------------------------------------------------------------
/src/config/env/production.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 数据库配置文件 https://www.bookstack.cn/read/TypeORM-0.2.20-zh/connection-options.md
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年09月15 14:16:42
6 | */
7 | import { join } from 'path'
8 |
9 | export default {
10 | // 端口
11 | port: parseInt(process.env.PORT, 10) || 3000,
12 | // 是否开启swagger
13 | enableSwagger: true,
14 | // 数据库配置
15 | DATABASE_CONFIG: {
16 | type: 'mysql',
17 | host: 'localhost',
18 | port: 3306,
19 | username: 'root',
20 | password: '',
21 | database: 'nest',
22 | charset: 'utf8mb4',
23 | entities: [join(__dirname, '..', '..', '/entities/*{.ts,.js}')],
24 | synchronize: false, // 是否在每次应用程序启动时自动创建数据库架构
25 | logging: true,
26 | dateStrings: true // 强制日期类型(TIMESTAMP,DATETIME,DATE)作为字符串返回,而不是转换为 JavaScript Date 对象
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/config/env/test.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 数据库配置文件 https://www.bookstack.cn/read/TypeORM-0.2.20-zh/connection-options.md
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年09月15 14:16:42
6 | */
7 | import { join } from 'path'
8 |
9 | export default {
10 | // 端口
11 | port: parseInt(process.env.PORT, 10) || 3000,
12 | // 是否开启swagger
13 | enableSwagger: true,
14 | // 数据库配置
15 | DATABASE_CONFIG: {
16 | type: 'mysql',
17 | host: 'localhost',
18 | port: 3306,
19 | username: 'root',
20 | password: '',
21 | database: 'nest',
22 | charset: 'utf8mb4',
23 | entities: [join(__dirname, '..', '..', '/entities/*{.ts,.js}')],
24 | synchronize: true,
25 | logging: true
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
1 | import developmentConfig from './env/development'
2 | import testConfig from './env/test'
3 | import productionConfig from './env/production'
4 |
5 | const configs = {
6 | development: developmentConfig,
7 | test: testConfig,
8 | production: productionConfig
9 | }
10 | const env = process.env.NODE_ENV || 'development'
11 |
12 | export default () => configs[env]
13 |
--------------------------------------------------------------------------------
/src/config/log4js.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: log4j
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月06 16:14:34
6 | */
7 |
8 | import * as path from 'path'
9 | const baseLogPath = path.resolve(__dirname, '../../logs') // 日志要写入哪个目录
10 |
11 | const log4jsConfig = {
12 | appenders: {
13 | console: {
14 | type: 'console' // 会打印到控制台
15 | },
16 | access: {
17 | type: 'dateFile', // 会写入文件,并按照日期分类
18 | filename: `${baseLogPath}/access/access.log`, // 日志文件名,会命名为:access.20200320.log
19 | alwaysIncludePattern: true,
20 | pattern: 'yyyyMMdd',
21 | daysToKeep: 60,
22 | numBackups: 3,
23 | category: 'http',
24 | keepFileExt: true // 是否保留文件后缀
25 | },
26 | app: {
27 | type: 'dateFile',
28 | filename: `${baseLogPath}/app-out/app.log`,
29 | alwaysIncludePattern: true,
30 | layout: {
31 | type: 'pattern',
32 | pattern:
33 | '{"date":"%d","level":"%p","category":"%c","host":"%h","pid":"%z","data":\'%m\'}'
34 | },
35 | // 日志文件按日期(天)切割
36 | pattern: 'yyyyMMdd',
37 | daysToKeep: 60,
38 | // maxLogSize: 10485760,
39 | numBackups: 3,
40 | keepFileExt: true
41 | },
42 | errorFile: {
43 | type: 'dateFile',
44 | filename: `${baseLogPath}/errors/error.log`,
45 | alwaysIncludePattern: true,
46 | layout: {
47 | type: 'pattern',
48 | pattern:
49 | '{"date":"%d","level":"%p","category":"%c","host":"%h","pid":"%z","data":\'%m\'}'
50 | },
51 | // 日志文件按日期(天)切割
52 | pattern: 'yyyyMMdd',
53 | daysToKeep: 60,
54 | // maxLogSize: 10485760,
55 | numBackups: 3,
56 | keepFileExt: true
57 | },
58 | errors: {
59 | type: 'logLevelFilter',
60 | level: 'ERROR',
61 | appender: 'errorFile'
62 | }
63 | },
64 | categories: {
65 | default: {
66 | appenders: ['console', 'app', 'errors'],
67 | level: 'DEBUG'
68 | },
69 | info: { appenders: ['console', 'app', 'errors'], level: 'info' },
70 | access: { appenders: ['console', 'app', 'errors'], level: 'info' },
71 | http: { appenders: ['access'], level: 'DEBUG' }
72 | },
73 | pm2: true, // 使用 pm2 来管理项目时,打开
74 | pm2InstanceVar: 'INSTANCE_ID' // 会根据 pm2 分配的 id 进行区分,以免各进程在写日志时造成冲突
75 | }
76 |
77 | export default log4jsConfig
78 |
--------------------------------------------------------------------------------
/src/core/code.enum.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 状态码枚举
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月10 15:48:38
6 | */
7 | export enum StatusCode {
8 | TIMEOUT = -1, // 系统繁忙
9 | SUCCESS = 200, // 成功
10 | BUSINESS_FAIL = 400, // 业务类错误
11 | USER_ID_INVALID = 10001 // 用户id无效
12 | }
13 |
--------------------------------------------------------------------------------
/src/core/resultBean.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: ResultBean
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月10 15:56:42
6 | */
7 |
8 | import { StatusCode } from './code.enum'
9 |
10 | export interface ResultBean {
11 | code: number
12 | message: string
13 | data: any
14 | }
15 |
16 | export class ResultGenerator {
17 | static success(data: any = {}, message = 'success'): ResultBean {
18 | const result: ResultBean = {
19 | code: StatusCode.SUCCESS,
20 | message,
21 | data
22 | }
23 | return result
24 | }
25 |
26 | static fail(code: number, message: string) {
27 | const result: ResultBean = {
28 | code,
29 | message,
30 | data: undefined
31 | }
32 | return result
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/core/transform.ts:
--------------------------------------------------------------------------------
1 | import { ValueTransformer } from 'typeorm'
2 |
3 | /*
4 | * @file: typeorm bit(1) => 转换为 true false
5 | https://github.com/typeorm/typeorm/issues/3875
6 | * @copyright: BoBo
7 | * @author: BoBo
8 | * @Date: 2020年09月07 10:59:00
9 | */
10 | export class BoolBitTransformer implements ValueTransformer {
11 | // To db from typeorm
12 | to(value: boolean | null): Buffer | null {
13 | if (value === null) {
14 | return null
15 | }
16 | const res = new Buffer(1)
17 | res[0] = value ? 1 : 0
18 | return res
19 | }
20 | // From db to typeorm
21 | from(value: Buffer): boolean | null {
22 | if (value === null) {
23 | return null
24 | }
25 | return value[0] === 1
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/entities/AdCodelist.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('ad_codelist', { schema: 'nest' })
4 | export class AdCodelist {
5 | @Column('varchar', { primary: true, name: 'id', comment: 'ID', length: 50 })
6 | id: string
7 |
8 | @Column('text', { name: 'codeValue', nullable: true, comment: '字典值' })
9 | codeValue: string | null
10 |
11 | @Column('varchar', {
12 | name: 'codeName',
13 | nullable: true,
14 | comment: '字典值描述',
15 | length: 100
16 | })
17 | codeName: string | null
18 |
19 | @Column('varchar', {
20 | name: 'codeType',
21 | nullable: true,
22 | comment: '字典类型',
23 | length: 50
24 | })
25 | codeType: string | null
26 |
27 | @Column('decimal', {
28 | name: 'codeOrder',
29 | nullable: true,
30 | comment: '排序',
31 | precision: 8,
32 | scale: 0
33 | })
34 | codeOrder: string | null
35 |
36 | @Column('varchar', {
37 | name: 'remark',
38 | nullable: true,
39 | comment: '备注',
40 | length: 255
41 | })
42 | remark: string | null
43 |
44 | @Column('timestamp', {
45 | name: 'timestamp',
46 | comment: '创建时间',
47 | default: () => 'CURRENT_TIMESTAMP'
48 | })
49 | timestamp: Date
50 | }
51 |
--------------------------------------------------------------------------------
/src/entities/AdCodelistType.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('ad_codelist_type', { schema: 'nest' })
4 | export class AdCodelistType {
5 | @Column('varchar', { primary: true, name: 'id', comment: 'ID', length: 36 })
6 | id: string
7 |
8 | @Column('varchar', {
9 | name: 'typeName',
10 | nullable: true,
11 | comment: '字典类型名称',
12 | length: 100,
13 | })
14 | typeName: string | null
15 |
16 | @Column('decimal', {
17 | name: 'order',
18 | nullable: true,
19 | comment: '排序',
20 | precision: 8,
21 | scale: 0,
22 | })
23 | order: string | null
24 |
25 | @Column('varchar', {
26 | name: 'remark',
27 | nullable: true,
28 | comment: '备注',
29 | length: 255,
30 | })
31 | remark: string | null
32 |
33 | @Column('varchar', {
34 | name: 'parentId',
35 | nullable: true,
36 | comment: '父级ID',
37 | length: 36,
38 | })
39 | parentId: string | null
40 |
41 | @Column('timestamp', {
42 | name: 'timestamp',
43 | comment: '创建时间',
44 | default: () => 'CURRENT_TIMESTAMP',
45 | })
46 | timestamp: Date
47 | }
48 |
--------------------------------------------------------------------------------
/src/entities/Dept.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity, Index } from 'typeorm'
2 |
3 | @Index('index_id', ['id'], { unique: true })
4 | @Entity('dept', { schema: 'nest' })
5 | export class Dept {
6 | @Column('varchar', { primary: true, name: 'id', length: 36 })
7 | id: string
8 |
9 | @Column('varchar', {
10 | name: 'name',
11 | nullable: true,
12 | comment: '部门名称',
13 | length: 255
14 | })
15 | name: string | null
16 |
17 | @Column('int', { name: 'rank', nullable: true, comment: '排序码' })
18 | rank: number | null
19 |
20 | @Column('varchar', {
21 | name: 'parentId',
22 | nullable: true,
23 | comment: '上级ID',
24 | length: 36
25 | })
26 | parentId: string | null
27 |
28 | @Column('timestamp', {
29 | name: 'timestamp',
30 | comment: '创建时间',
31 | default: () => 'CURRENT_TIMESTAMP'
32 | })
33 | timestamp: Date
34 | }
35 |
--------------------------------------------------------------------------------
/src/entities/Dynamictables.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('dynamictables', { schema: 'nest' })
4 | export class Dynamictables {
5 | @Column('char', { primary: true, name: 'id', length: 36 })
6 | id: string
7 |
8 | @Column('varchar', {
9 | name: 'tableName',
10 | nullable: true,
11 | comment: '表名',
12 | length: 255
13 | })
14 | tableName: string | null
15 |
16 | @Column('text', { name: 'formJson', nullable: true, comment: '数据' })
17 | formJson: string | null
18 |
19 | @Column('text', { name: 'position', nullable: true, comment: '使用位置' })
20 | position: string | null
21 |
22 | @Column('timestamp', {
23 | name: 'timestamp',
24 | comment: '创建时间',
25 | default: () => 'CURRENT_TIMESTAMP'
26 | })
27 | timestamp: Date
28 | }
29 |
--------------------------------------------------------------------------------
/src/entities/Form.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('form', { schema: 'nest' })
4 | export class Form {
5 | @Column('char', { primary: true, name: 'id', length: 36 })
6 | id: string
7 |
8 | @Column('varchar', {
9 | name: 'tableName',
10 | nullable: true,
11 | comment: '表名',
12 | length: 255
13 | })
14 | tableName: string | null
15 |
16 | @Column('longtext', { name: 'formJson', nullable: true, comment: '数据' })
17 | formJson: string | null
18 |
19 | @Column('text', { name: 'position', nullable: true, comment: '使用位置' })
20 | position: string | null
21 |
22 | @Column('timestamp', {
23 | name: 'timestamp',
24 | comment: '创建时间',
25 | default: () => 'CURRENT_TIMESTAMP'
26 | })
27 | timestamp: Date
28 | }
29 |
--------------------------------------------------------------------------------
/src/entities/Person.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('person', { schema: 'nest' })
4 | export class Person {
5 | @Column('char', { primary: true, name: 'id', comment: '主键', length: 36 })
6 | id: string
7 |
8 | @Column('varchar', {
9 | name: 'personname',
10 | nullable: true,
11 | comment: '姓名',
12 | length: 255
13 | })
14 | personname: string | null
15 |
16 | @Column('varchar', {
17 | name: 'deptname',
18 | nullable: true,
19 | comment: '所在部门',
20 | length: 255
21 | })
22 | deptname: string | null
23 |
24 | @Column('varchar', {
25 | name: 'salary',
26 | nullable: true,
27 | comment: '薪资',
28 | length: 255
29 | })
30 | salary: string | null
31 |
32 | @Column('varchar', {
33 | name: 'post',
34 | nullable: true,
35 | comment: '岗位',
36 | length: 255
37 | })
38 | post: string | null
39 |
40 | @Column('varchar', {
41 | name: 'level',
42 | nullable: true,
43 | comment: '职级',
44 | length: 255
45 | })
46 | level: string | null
47 |
48 | @Column('datetime', { name: 'timestamp', nullable: true, comment: '时间戳' })
49 | timestamp: Date | null
50 |
51 | @Column('varchar', {
52 | name: 'jobtime',
53 | nullable: true,
54 | comment: '入职时间',
55 | length: 255
56 | })
57 | jobtime: string | null
58 |
59 | @Column('varchar', {
60 | name: 'jobno',
61 | nullable: true,
62 | comment: '工号',
63 | length: 255
64 | })
65 | jobno: string | null
66 |
67 | @Column('varchar', {
68 | name: 'education',
69 | nullable: true,
70 | comment: '文化程度',
71 | length: 255
72 | })
73 | education: string | null
74 |
75 | @Column('varchar', {
76 | name: 'major',
77 | nullable: true,
78 | comment: '专业',
79 | length: 255
80 | })
81 | major: string | null
82 |
83 | @Column('varchar', {
84 | name: 'mobile',
85 | nullable: true,
86 | comment: '联系方式',
87 | length: 100
88 | })
89 | mobile: string | null
90 |
91 | @Column('varchar', {
92 | name: 'birthdate',
93 | nullable: true,
94 | comment: '出生年月',
95 | length: 100
96 | })
97 | birthdate: string | null
98 |
99 | @Column('varchar', {
100 | name: 'sex',
101 | nullable: true,
102 | comment: '性别',
103 | length: 10
104 | })
105 | sex: string | null
106 |
107 | @Column('varchar', {
108 | name: 'avatar',
109 | nullable: true,
110 | comment: '头像',
111 | length: 255
112 | })
113 | avatar: string | null
114 | }
115 |
--------------------------------------------------------------------------------
/src/entities/PersonEducation.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('person_education', { schema: 'nest' })
4 | export class PersonEducation {
5 | @Column('char', { primary: true, name: 'id', length: 36 })
6 | id: string
7 |
8 | @Column('varchar', { name: 'personid', nullable: true, length: 255 })
9 | personid: string | null
10 |
11 | @Column('varchar', {
12 | name: 'time',
13 | nullable: true,
14 | comment: '起止时间',
15 | length: 255
16 | })
17 | time: string | null
18 |
19 | @Column('varchar', {
20 | name: 'school',
21 | nullable: true,
22 | comment: '学校',
23 | length: 255
24 | })
25 | school: string | null
26 |
27 | @Column('varchar', {
28 | name: 'type',
29 | nullable: true,
30 | comment: '学校类型',
31 | length: 255
32 | })
33 | type: string | null
34 |
35 | @Column('text', { name: 'remark', nullable: true, comment: '备注' })
36 | remark: string | null
37 |
38 | @Column('datetime', { name: 'timestamp', nullable: true })
39 | timestamp: Date | null
40 | }
41 |
--------------------------------------------------------------------------------
/src/entities/PersonResume.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('person_resume', { schema: 'nest' })
4 | export class PersonResume {
5 | @Column('char', { primary: true, name: 'id', length: 36 })
6 | id: string
7 |
8 | @Column('varchar', { name: 'personid', nullable: true, length: 255 })
9 | personid: string | null
10 |
11 | @Column('varchar', {
12 | name: 'time',
13 | nullable: true,
14 | comment: '起止时间',
15 | length: 255
16 | })
17 | time: string | null
18 |
19 | @Column('varchar', {
20 | name: 'workunit',
21 | nullable: true,
22 | comment: '工作单位',
23 | length: 255
24 | })
25 | workunit: string | null
26 |
27 | @Column('varchar', {
28 | name: 'workduty',
29 | nullable: true,
30 | comment: '职务',
31 | length: 255
32 | })
33 | workduty: string | null
34 |
35 | @Column('text', { name: 'remark', nullable: true, comment: '备注' })
36 | remark: string | null
37 |
38 | @Column('datetime', { name: 'timestamp', nullable: true })
39 | timestamp: Date | null
40 | }
41 |
--------------------------------------------------------------------------------
/src/entities/Role.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity } from 'typeorm'
2 |
3 | @Entity('role', { schema: 'nest' })
4 | export class Role {
5 | @Column('char', { primary: true, name: 'id', length: 36 })
6 | id: string
7 |
8 | @Column('text', { name: 'roleName', nullable: true, comment: '角色名' })
9 | roleName: string | null
10 |
11 | @Column('text', { name: 'roleAuthName', nullable: true, comment: '权限' })
12 | roleAuthName: string | null
13 |
14 | @Column('longtext', {
15 | name: 'roleAuthNameDict',
16 | nullable: true,
17 | comment: '权限名称'
18 | })
19 | roleAuthNameDict: string | null
20 |
21 | @Column('int', { name: 'rank', nullable: true, comment: '排序' })
22 | rank: number | null
23 |
24 | @Column('timestamp', {
25 | name: 'timestamp',
26 | comment: '创建时间',
27 | default: () => 'CURRENT_TIMESTAMP'
28 | })
29 | timestamp: Date
30 | }
31 |
--------------------------------------------------------------------------------
/src/entities/Users.ts:
--------------------------------------------------------------------------------
1 | import { Column, Entity, Index } from 'typeorm'
2 |
3 | @Index('index_id', ['id'], {})
4 | @Index('index_username', ['userName'], {})
5 | @Index('index_deptid', ['deptId'], {})
6 | @Entity('users', { schema: 'nest' })
7 | export class Users {
8 | @Column('varchar', { primary: true, name: 'id', length: 36 })
9 | id: string
10 |
11 | @Column('varchar', {
12 | name: 'userName',
13 | nullable: true,
14 | comment: '用户名',
15 | length: 50,
16 | })
17 | userName: string | null
18 |
19 | @Column('varchar', { name: 'deptId', nullable: true, length: 36 })
20 | deptId: string | null
21 |
22 | @Column('varchar', { name: 'roleId', nullable: true, length: 36 })
23 | roleId: string | null
24 |
25 | @Column('varchar', {
26 | name: 'password',
27 | nullable: true,
28 | comment: '密码',
29 | length: 50,
30 | })
31 | password: string | null
32 |
33 | @Column('varchar', {
34 | name: 'realName',
35 | nullable: true,
36 | comment: '真实姓名',
37 | length: 20,
38 | })
39 | realName: string | null
40 |
41 | @Column('int', {
42 | name: 'rank',
43 | nullable: true,
44 | comment: '排序码',
45 | default: () => "'0'",
46 | })
47 | rank: number | null
48 |
49 | @Column('longtext', { name: 'photo', nullable: true, comment: '照片' })
50 | photo: string | null
51 |
52 | @Column('timestamp', {
53 | name: 'timestamp',
54 | comment: '创建时间',
55 | default: () => 'CURRENT_TIMESTAMP',
56 | })
57 | timestamp: Date
58 | }
59 |
--------------------------------------------------------------------------------
/src/events/events.gateway.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: webSocket https://docs.nestjs.cn/6/websockets?id=websocket
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月13 16:48:08
6 | */
7 | import {
8 | SubscribeMessage,
9 | WebSocketGateway,
10 | WsResponse,
11 | WebSocketServer,
12 | OnGatewayConnection,
13 | OnGatewayInit,
14 | OnGatewayDisconnect
15 | } from '@nestjs/websockets'
16 | import { Observable, of } from 'rxjs'
17 |
18 | let num = 0
19 |
20 | @WebSocketGateway(8080)
21 | export class EventsGateway
22 | implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
23 | @WebSocketServer() server
24 |
25 | // 初始化
26 | afterInit() {}
27 |
28 | // 连接
29 | handleConnection() {}
30 |
31 | // 断开连接
32 | handleDisconnect() {}
33 |
34 | // 订阅消息事件
35 | @SubscribeMessage('message')
36 | handleEvent(client: any): Observable> {
37 | // 通知当前client message
38 | this.server.emit('message', new Date().toLocaleString())
39 | num++
40 | console.log(`有一位用户链接!> ${num}`)
41 | client.on('disconnect', () => {
42 | num--
43 | console.log(`有人离开了...> ${num}`)
44 | })
45 |
46 | return of({ event: 'message', data: '233' })
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/events/events.module.ts:
--------------------------------------------------------------------------------
1 | import { Module, Global } from '@nestjs/common'
2 | import { EventsGateway } from './events.gateway'
3 | @Global()
4 | @Module({
5 | providers: [EventsGateway],
6 | exports: [EventsGateway]
7 | })
8 | export class EventsModule {}
9 |
--------------------------------------------------------------------------------
/src/filter/any-exception.filter.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 全局异常拦截 http exception -> any exception
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月06 16:57:04
6 | */
7 |
8 | import {
9 | ExceptionFilter,
10 | Catch,
11 | ArgumentsHost,
12 | HttpException,
13 | HttpStatus
14 | } from '@nestjs/common'
15 | import { Logger } from '../utils/log4js'
16 |
17 | @Catch()
18 | export class AllExceptionsFilter implements ExceptionFilter {
19 | catch(exception: unknown, host: ArgumentsHost) {
20 | const ctx = host.switchToHttp()
21 | const response = ctx.getResponse()
22 | const request = ctx.getRequest()
23 |
24 | const status =
25 | exception instanceof HttpException
26 | ? exception.getStatus()
27 | : HttpStatus.INTERNAL_SERVER_ERROR
28 |
29 | const logFormat = ` <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
30 | Request original url: ${request.originalUrl}
31 | Method: ${request.method}
32 | IP: ${request.ip}
33 | Status code: ${status}
34 | Response: ${exception} \n <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
35 | `
36 | Logger.error(logFormat)
37 | response.status(status).json({
38 | code: status,
39 | message: `Service Error: ${exception}`,
40 | data: null
41 | })
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/filter/api-exception.filter.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: api异常拦截
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月10 15:55:37
6 | */
7 | import { StatusCode } from './../core/code.enum'
8 | import { HttpException, HttpStatus } from '@nestjs/common'
9 |
10 | export class ApiException extends HttpException {
11 | private errorMessage: string
12 | private errorCode: StatusCode
13 |
14 | constructor(
15 | errorMessage: string,
16 | errorCode: StatusCode,
17 | statusCode: HttpStatus
18 | ) {
19 | super(errorMessage, statusCode)
20 | this.errorMessage = errorMessage
21 | this.errorCode = errorCode
22 | }
23 |
24 | getErrorCode(): StatusCode {
25 | return this.errorCode
26 | }
27 |
28 | getErrorMessage(): string {
29 | return this.errorMessage
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/filter/http-exception.filter.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 全局http异常拦截
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月10 15:51:14
6 | */
7 | import {
8 | ExceptionFilter,
9 | ArgumentsHost,
10 | Catch,
11 | HttpException
12 | } from '@nestjs/common'
13 | import { ApiException } from './api-exception.filter'
14 |
15 | @Catch(HttpException)
16 | export class HttpExceptionFilter implements ExceptionFilter {
17 | catch(exception, host: ArgumentsHost) {
18 | const ctx = host.switchToHttp()
19 | const response = ctx.getResponse()
20 | const status = exception.getStatus()
21 | if (exception instanceof ApiException) {
22 | response.status(status).json({
23 | code: exception.getErrorCode(),
24 | message: exception.getErrorMessage(),
25 | data: null
26 | })
27 | } else {
28 | response.status(status).json({
29 | code: status,
30 | data: new Date().toLocaleDateString(),
31 | message: exception.message
32 | })
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/guards/auth-guards.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: 全局jwt guard
3 | 接口上添加@NoAuth() 则跳过校验
4 | * @copyright: BoBo
5 | * @author: BoBo
6 | * @Date: 2020年08月07 14:53:52
7 | */
8 | import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'
9 | import { Observable } from 'rxjs'
10 | import { Reflector } from '@nestjs/core'
11 | import { AuthGuard, IAuthGuard } from '@nestjs/passport'
12 |
13 | @Injectable()
14 | export class RoleAuthGuard implements CanActivate {
15 | constructor(private readonly reflector: Reflector) {}
16 | canActivate(
17 | context: ExecutionContext
18 | ): boolean | Promise | Observable {
19 | // 在这里取metadata中的no-auth,得到的会是一个bool
20 | const noAuth = this.reflector.get('no-auth', context.getHandler())
21 | const guard = RoleAuthGuard.getAuthGuard(noAuth)
22 | return typeof guard === 'boolean' ? guard : guard.canActivate(context) //执行所选策略Guard的canActivate方法
23 | }
24 |
25 | // @NoAuth() 则表示直接放行不校验token
26 | private static getAuthGuard(noAuth: boolean): IAuthGuard | boolean {
27 | if (noAuth) {
28 | return true
29 | } else {
30 | return new (AuthGuard('jwt'))()
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/guards/customize.ts:
--------------------------------------------------------------------------------
1 | import { SetMetadata } from '@nestjs/common'
2 |
3 | export const NoAuth = () => SetMetadata('no-auth', true)
4 |
--------------------------------------------------------------------------------
/src/guards/jwt-auth.guard.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common'
2 | import { AuthGuard } from '@nestjs/passport'
3 |
4 | @Injectable()
5 | export class JwtAuthGuard extends AuthGuard('jwt') {}
6 |
--------------------------------------------------------------------------------
/src/guards/jwt.strategy.ts:
--------------------------------------------------------------------------------
1 | // src/logical/auth/jwt.strategy.ts
2 | import { ExtractJwt, Strategy } from 'passport-jwt'
3 | import { PassportStrategy } from '@nestjs/passport'
4 | import { Injectable } from '@nestjs/common'
5 | import { jwtConstants } from '../config/constants'
6 |
7 | @Injectable()
8 | export class JwtStrategy extends PassportStrategy(Strategy) {
9 | constructor() {
10 | super({
11 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
12 | ignoreExpiration: false,
13 | secretOrKey: jwtConstants.secret
14 | })
15 | }
16 |
17 | // JWT验证 - Step 4: 被守卫调用
18 | async validate(payload: any) {
19 | console.log(`JWT验证 - Step 4: 被守卫调用`)
20 | return {
21 | userId: payload.userID,
22 | userName: payload.userName,
23 | realName: payload.realName,
24 | roleID: payload.roleID,
25 | deptID: payload.deptID
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/interceptor/transform.interceptor.ts:
--------------------------------------------------------------------------------
1 | // src/interceptor/transform.interceptor.ts
2 | import {
3 | CallHandler,
4 | ExecutionContext,
5 | Injectable,
6 | NestInterceptor
7 | } from '@nestjs/common'
8 | import { Observable } from 'rxjs'
9 | import { map } from 'rxjs/operators'
10 | import { Logger } from '../utils/log4js'
11 |
12 | @Injectable()
13 | export class TransformInterceptor implements NestInterceptor {
14 | intercept(context: ExecutionContext, next: CallHandler): Observable {
15 | const req = context.getArgByIndex(1).req
16 | return next.handle().pipe(
17 | map(data => {
18 | const logFormat = ` <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
19 | Request original url: ${req.originalUrl}
20 | Method: ${req.method}
21 | IP: ${req.ip}
22 | User: ${JSON.stringify(req.user)}
23 | Response data:\n ${JSON.stringify(data.data)}
24 | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<`
25 | Logger.info(logFormat)
26 | Logger.access(logFormat)
27 | return data
28 | })
29 | )
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: main.ts
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月06 16:10:49
6 | */
7 | import { NestFactory } from '@nestjs/core'
8 | import { NestExpressApplication } from '@nestjs/platform-express'
9 | import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'
10 | import { AppModule } from './app.module'
11 | import { logger } from './middleware/logger.middleware'
12 | import * as express from 'express'
13 | import { TransformInterceptor } from './interceptor/transform.interceptor'
14 | import { AllExceptionsFilter } from './filter/any-exception.filter'
15 | import * as compression from 'compression'
16 | import { HttpExceptionFilter } from './filter/http-exception.filter'
17 | import { join } from 'path'
18 |
19 | async function bootstrap() {
20 | const app = await NestFactory.create(AppModule, {
21 | cors: true,
22 | })
23 | app.enableCors({
24 | origin: true,
25 | })
26 | // helmet安全
27 | // app.use(helmet());
28 | const options = new DocumentBuilder()
29 | .setTitle('Nestjs Swagger')
30 | .setDescription('API description')
31 | .setVersion('1.0')
32 | .addTag('cats')
33 | .build()
34 | const document = SwaggerModule.createDocument(app, options)
35 | SwaggerModule.setup('api', app, document)
36 | app.use(express.json()) // For parsing application/json
37 | app.use(express.urlencoded({ extended: true })) // For parsing application/x-www-form-urlencoded
38 | // 监听所有的请求路由,并打印日志
39 | app.use(logger)
40 | // 使用全局拦截器打印出参
41 | app.useGlobalInterceptors(new TransformInterceptor())
42 | // 全局异常
43 | app.useGlobalFilters(new AllExceptionsFilter())
44 | // 开启gzip
45 | app.use(compression())
46 |
47 | app.useGlobalFilters(new HttpExceptionFilter())
48 |
49 | // 配置静态资源
50 | app.useStaticAssets(join(__dirname, '../public', '/'), {
51 | prefix: '/',
52 | setHeaders: (res) => {
53 | res.set('Cache-Control', 'max-age=2592000')
54 | },
55 | })
56 |
57 | await app.listen(process.env.PORT || 7788)
58 | }
59 | bootstrap()
60 |
--------------------------------------------------------------------------------
/src/middleware/logger.middleware.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: log中间件
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月06 16:17:03
6 | */
7 | import { Injectable, NestMiddleware } from '@nestjs/common'
8 | import { Request, Response } from 'express'
9 | import { Logger } from '../utils/log4js'
10 |
11 | @Injectable()
12 | export class LoggerMiddleware implements NestMiddleware {
13 | use(req: Request, res: Response, next: () => void) {
14 | const code = res.statusCode // 响应状态码
15 | // 组装日志信息
16 | const logFormat = `Method: ${req.method} \n Request original url: ${req.originalUrl} \n IP: ${req.ip} \n Status code: ${code} \n`
17 | // 根据状态码,进行日志类型区分
18 | if (code >= 500) {
19 | Logger.error(logFormat)
20 | } else if (code >= 400) {
21 | Logger.warn(logFormat)
22 | } else {
23 | Logger.access(logFormat)
24 | Logger.log(logFormat)
25 | }
26 | next()
27 | }
28 | }
29 |
30 | // 函数式中间件
31 | export function logger(req: Request, res: Response, next: () => any) {
32 | const code = res.statusCode // 响应状态码
33 | next()
34 | // 组装日志信息
35 | const logFormat = ` >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
36 | Request original url: ${req.originalUrl}
37 | Method: ${req.method}
38 | IP: ${req.ip}
39 | Status code: ${code}
40 | Parmas: ${JSON.stringify(req.params)}
41 | Query: ${JSON.stringify(req.query)}
42 | Body: ${JSON.stringify(
43 | req.body
44 | )} \n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
45 | `
46 | // 根据状态码,进行日志类型区分
47 | if (code >= 500) {
48 | Logger.error(logFormat)
49 | } else if (code >= 400) {
50 | Logger.warn(logFormat)
51 | } else {
52 | Logger.access(logFormat)
53 | Logger.log(logFormat)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/module/ad-codelist-type/ad-codelist-type.controller.ts:
--------------------------------------------------------------------------------
1 | import { AdCodelistTypeService } from './ad-codelist-type.service'
2 | import { Controller } from '@nestjs/common'
3 | import { ApiHeader } from '@nestjs/swagger'
4 | import { AdCodelistType } from '@/entities/AdCodelistType'
5 | import { BaseController } from 'src/module/base/base.controller'
6 |
7 | @ApiHeader({
8 | name: '字典类型设置',
9 | description: '字典类型设置',
10 | })
11 | @Controller('ad_codelist_type')
12 | export class AdCodelistController extends BaseController {
13 | constructor(private adCodelistTypeService: AdCodelistTypeService) {
14 | super(adCodelistTypeService)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/module/ad-codelist-type/ad-codelist-type.module.ts:
--------------------------------------------------------------------------------
1 | import { AdCodelistController } from './ad-codelist-type.controller'
2 | import { AdCodelistTypeService } from './ad-codelist-type.service'
3 | import { Module } from '@nestjs/common'
4 | import { TypeOrmModule } from '@nestjs/typeorm'
5 | import { AdCodelistType } from '@/entities/AdCodelistType'
6 |
7 | @Module({
8 | imports: [TypeOrmModule.forFeature([AdCodelistType])],
9 | providers: [AdCodelistTypeService],
10 | controllers: [AdCodelistController],
11 | exports: [AdCodelistTypeService],
12 | })
13 | export class AdCodelistTypeModule {}
14 |
--------------------------------------------------------------------------------
/src/module/ad-codelist-type/ad-codelist-type.service.ts:
--------------------------------------------------------------------------------
1 | import { BaseService } from 'src/module/base/base.service'
2 | import { Injectable } from '@nestjs/common'
3 | import { InjectRepository } from '@nestjs/typeorm'
4 | import { Repository } from 'typeorm'
5 | import { AdCodelistType } from '@/entities/AdCodelistType'
6 |
7 | @Injectable()
8 | export class AdCodelistTypeService extends BaseService {
9 | adCodelistTypeRepository: Repository
10 | constructor(
11 | @InjectRepository(AdCodelistType)
12 | adCodelistTypeRepository: Repository,
13 | ) {
14 | super(adCodelistTypeRepository)
15 | this.adCodelistTypeRepository = adCodelistTypeRepository
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/module/ad-codelist/ad-codelist.controller.ts:
--------------------------------------------------------------------------------
1 | import { ResultGenerator } from './../../core/resultBean'
2 | import { AdCodelistService } from './ad-codelist.service'
3 | import { Controller, Post, Body } from '@nestjs/common'
4 | import { ApiHeader } from '@nestjs/swagger'
5 | import { AdCodelist } from '@/entities/AdCodelist'
6 | import { BaseController } from 'src/module/base/base.controller'
7 | import { NoAuth } from 'src/guards/customize'
8 |
9 | @ApiHeader({
10 | name: '字典设置',
11 | description: '字典设置',
12 | })
13 | @Controller('ad_codelist')
14 | export class AdCodelistController extends BaseController {
15 | constructor(private adCodelistService: AdCodelistService) {
16 | super(adCodelistService)
17 | }
18 |
19 | @NoAuth()
20 | @Post('list')
21 | public async list(@Body() body) {
22 | // const code = await this.adCodelistService.repository
23 | // .createQueryBuilder('code')
24 | // .leftJoinAndSelect(AdCodelistType, 'type', 'type.id = code.codeType')
25 | // .select('code.*')
26 | // .addSelect('type.codeName', 'typeName')
27 | // .getRawMany();
28 | // const code = await this.adCodelistService.repository.query('select t.*,c.codeName as typeName from ad_codelist t join ad_codelist_type c on (t.codeType = c.id)')
29 | return ResultGenerator.success(await this.adCodelistService.find(body))
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/module/ad-codelist/ad-codelist.module.ts:
--------------------------------------------------------------------------------
1 | import { AdCodelistController } from './ad-codelist.controller'
2 | import { AdCodelistService } from './ad-codelist.service'
3 | import { Module } from '@nestjs/common'
4 | import { TypeOrmModule } from '@nestjs/typeorm'
5 | import { AdCodelist } from '@/entities/AdCodelist'
6 |
7 | @Module({
8 | imports: [TypeOrmModule.forFeature([AdCodelist])],
9 | providers: [AdCodelistService],
10 | controllers: [AdCodelistController],
11 | exports: [AdCodelistService],
12 | })
13 | export class AdCodelistModule {}
14 |
--------------------------------------------------------------------------------
/src/module/ad-codelist/ad-codelist.service.ts:
--------------------------------------------------------------------------------
1 | import { BaseService } from 'src/module/base/base.service'
2 | import { Injectable } from '@nestjs/common'
3 | import { InjectRepository } from '@nestjs/typeorm'
4 | import { Repository } from 'typeorm'
5 | import { AdCodelist } from '@/entities/AdCodelist'
6 |
7 | @Injectable()
8 | export class AdCodelistService extends BaseService {
9 | adCodelistRepository: Repository
10 | constructor(
11 | @InjectRepository(AdCodelist) adCodelistRepository: Repository,
12 | ) {
13 | super(adCodelistRepository)
14 | this.adCodelistRepository = adCodelistRepository
15 | }
16 |
17 | async find(body) {
18 | const qb = this.adCodelistRepository
19 | .createQueryBuilder('code')
20 | .innerJoin('ad_codelist_type', 'type', 'type.id = code.codeType')
21 | this.splitSql(qb, body)
22 | qb.select('code.*')
23 | .addSelect('type.typeName', 'typeName')
24 | .addOrderBy('code.codeOrder', 'ASC') // 此处返回字段为 type_typeName
25 |
26 | const list = await qb.getRawMany()
27 | const total = await qb.getCount()
28 | return {
29 | list,
30 | total,
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/module/auth/auth.module.ts:
--------------------------------------------------------------------------------
1 | import { RoleModule } from './../role/role.module'
2 | import { JwtStrategy } from './../../guards/jwt.strategy'
3 | import { UsersModule } from '../users/users.module'
4 | import { Module, Global } from '@nestjs/common'
5 | import { AuthService } from './auth.service'
6 | import { PassportModule } from '@nestjs/passport'
7 | import { JwtModule } from '@nestjs/jwt'
8 | import { jwtConstants } from 'src/config/constants'
9 | import { DeptModule } from '../dept/dept.module'
10 |
11 | @Global()
12 | @Module({
13 | imports: [
14 | PassportModule.register({ defaultStrategy: 'jwt' }),
15 | JwtModule.register({
16 | secret: jwtConstants.secret,
17 | signOptions: { expiresIn: jwtConstants.time } // token 过期时效
18 | }),
19 | UsersModule,
20 | DeptModule,
21 | RoleModule
22 | ],
23 | providers: [AuthService, JwtStrategy],
24 | exports: [AuthService]
25 | })
26 | export class AuthModule {}
27 |
--------------------------------------------------------------------------------
/src/module/auth/auth.service.ts:
--------------------------------------------------------------------------------
1 | import { DeptService } from './../dept/dept.service'
2 | import { RoleService } from './../role/role.service'
3 | import { Users } from './../../entities/Users'
4 | import { UsersService } from '../users/users.service'
5 | import { Injectable } from '@nestjs/common'
6 | import { JwtService } from '@nestjs/jwt'
7 |
8 | @Injectable()
9 | export class AuthService {
10 | user
11 | constructor(
12 | private readonly usersService: UsersService,
13 | private readonly roleService: RoleService,
14 | private readonly deptService: DeptService,
15 | private readonly jwtService: JwtService
16 | ) {}
17 |
18 | // 校验用户信息
19 | async validateUser(username: string, password: string): Promise {
20 | const user = await this.usersService.findByUserName(username)
21 | if (user) {
22 | if (password === user.password) {
23 | // 密码正确
24 | return {
25 | code: 200,
26 | user
27 | }
28 | } else {
29 | // 密码错误
30 | return {
31 | code: 800,
32 | user: null
33 | }
34 | }
35 | }
36 | // 查无此人
37 | return {
38 | code: 801,
39 | user: null
40 | }
41 | }
42 |
43 | // 签发jwt
44 | async certificate(user: Users) {
45 | // 查找当前用户角色/部门
46 | const role = await this.roleService.findById(user.roleId)
47 | const dept = await this.deptService.findById(user.deptId)
48 |
49 | const payload = {
50 | userName: user.userName,
51 | userID: user.id,
52 | deptID: user.deptId,
53 | realName: user.realName,
54 | roleID: user.roleId,
55 | roleName: role.roleName,
56 | deptName: dept.name,
57 | roleAuthName: role.roleAuthName,
58 | photo: ''
59 | }
60 | const token = this.jwtService.sign(payload)
61 | this.user = {
62 | ...payload,
63 | photo: user.photo
64 | }
65 | return token
66 | }
67 |
68 | getUser() {
69 | return this.user
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/module/base/base.controller.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: BaseController
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月10 11:45:59
6 | */
7 | import { BaseService } from './base.service'
8 | import { Body, Controller, Post, Query } from '@nestjs/common'
9 | import { ResultGenerator } from './../../core/resultBean'
10 |
11 | @Controller()
12 | export abstract class BaseController {
13 | protected constructor(protected service: BaseService) {}
14 |
15 | @Post('list')
16 | public async list(@Body() body) {
17 | return ResultGenerator.success(await this.service.find(body))
18 | }
19 |
20 | @Post('add')
21 | public async add(@Body() data: T) {
22 | return ResultGenerator.success(await this.service.add(data), '新增成功')
23 | }
24 |
25 | @Post('update')
26 | public async update(@Body() data: T) {
27 | return ResultGenerator.success(await this.service.update(data), '更新成功')
28 | }
29 |
30 | @Post('detail')
31 | public async detail(@Query() id: string) {
32 | return ResultGenerator.success(await this.service.findById(id))
33 | }
34 |
35 | @Post('delete')
36 | public async delete(@Query() id: string) {
37 | return ResultGenerator.success(await this.service.delete(id), '删除成功')
38 | }
39 |
40 | /**
41 | * 批量删除接口
42 | * @param id
43 | */
44 | @Post('deleteByIds')
45 | public async deleteByIds(@Body() id: string[]) {
46 | return ResultGenerator.success(
47 | await this.service.deleteByIds(id),
48 | '删除成功'
49 | )
50 | }
51 |
52 | /**
53 | * tree 接口
54 | */
55 | @Post('tree')
56 | public async tree() {
57 | return ResultGenerator.success(await this.service.tree())
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/module/base/base.service.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @file: BaseService
3 | * @copyright: BoBo
4 | * @author: BoBo
5 | * @Date: 2020年08月10 10:44:35
6 | */
7 | import { Injectable } from '@nestjs/common'
8 | import * as jwt from 'jsonwebtoken'
9 | import { jwtConstants } from '../../config/constants'
10 |
11 | const guid = require('uuid')
12 | const dayjs = require('dayjs')
13 |
14 | import { BaseEntity, Repository, SelectQueryBuilder } from 'typeorm'
15 | import { InjectRepository } from '@nestjs/typeorm'
16 |
17 | interface searchType {
18 | field: string
19 | operator: string
20 | value: any
21 | }
22 |
23 | interface SearchCondition {
24 | orderCondition: string
25 | searchCondition: searchType[]
26 | pageIndex: number
27 | pageSize: number
28 | }
29 |
30 | @Injectable()
31 | export abstract class BaseService {
32 | public repository: Repository
33 | constructor(@InjectRepository(BaseEntity) repository: Repository) {
34 | this.repository = repository
35 | }
36 |
37 | /**
38 | * 获取当前token携带信息
39 | * jwt token
40 | * @param authorization
41 | */
42 | getUserInfoFromToken(authorization) {
43 | if (!authorization) return null
44 |
45 | const token = authorization.split(' ')[1]
46 | const user = jwt.verify(token, jwtConstants.secret)
47 | return user
48 | }
49 |
50 | // 新增接口
51 | async add(entity: T) {
52 | const obj = JSON.parse(JSON.stringify(entity as any))
53 |
54 | // id为null则自动生成guid
55 | if (!obj.id) {
56 | obj.id = guid.v4()
57 | }
58 | obj.timestamp = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
59 |
60 | await this.repository.insert(obj)
61 | return entity
62 | }
63 | // 更新接口
64 | async update(entity: T) {
65 | const obj = JSON.parse(JSON.stringify(entity as any))
66 |
67 | // 此处大坑,如果有更好的方案欢迎PR!
68 | // 更新的时候去除伪列 (此处由于ts的类型检查不带入运行时,不会自动映射属性,否则数据库没有这个字段会报错)
69 | Object.keys(obj).forEach((k) => {
70 | // 去除伪列, 伪列格式默认为 表名_字段名 例如保存users表 (dept_name) 详见/users/list方法
71 | if (k.includes('_')) {
72 | delete obj[k]
73 | }
74 | })
75 | // 更新时间戳
76 | obj.timestamp = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
77 |
78 | await this.repository.update(obj.id, obj)
79 | return (entity as any).id
80 | }
81 |
82 | // 删除接口
83 | async delete(id: string) {
84 | await this.repository.delete(id)
85 | return id
86 | }
87 |
88 | // 批量删除接口
89 | async deleteByIds(ids: string[]) {
90 | await this.repository.delete(ids)
91 | return ids
92 | }
93 |
94 | // 查询ById接口
95 | async findById(id: string) {
96 | // ts bug https://github.com/typeorm/typeorm/issues/8939
97 | const result = await this.repository.findOneBy({
98 | id,
99 | } as any)
100 | return result
101 | }
102 |
103 | // tree接口
104 | async tree() {
105 | const result = await this.repository.find()
106 | // 此处默认顶层parentId 为 0 , 自行修改
107 | return toTree(result, '0')
108 | }
109 |
110 | async find(args: SearchCondition) {
111 | const qb = this.repository.createQueryBuilder()
112 |
113 | // 拼接sql
114 | this.splitSql(qb, args)
115 |
116 | const [list, total] = await qb.getManyAndCount()
117 |
118 | return {
119 | list,
120 | total,
121 | }
122 | }
123 |
124 | splitSql(qb: SelectQueryBuilder, args: SearchCondition) {
125 | const { pageIndex, pageSize, searchCondition, orderCondition } = args
126 | if (Array.isArray(searchCondition) && searchCondition.length > 0) {
127 | // 拼接高级查询条件
128 | this.getSearchCondition(searchCondition, qb)
129 | }
130 | // 拼接order条件
131 | if (orderCondition && orderCondition.includes(' ')) {
132 | const [field, order] = orderCondition.split(' ')
133 | qb.orderBy(field, order.toUpperCase() as any)
134 | }
135 | // 拼接分页条件
136 | // 若pageIndex,pageSize = 0,0
137 | // 则默认查询全部
138 | if (pageIndex && pageSize && pageIndex + pageSize > 1) {
139 | qb.skip((pageIndex - 1) * pageSize)
140 | qb.take(pageSize)
141 | }
142 | }
143 |
144 | getSearchCondition(searchCondition: searchType[], qb: SelectQueryBuilder) {
145 | // 一键搜 查询方式为orlike拼接
146 | const orLike = searchCondition.find((item) => item.operator === 'orlike')
147 | if (orLike) {
148 | const fields = orLike.field.split(',')
149 | fields.forEach((field) => {
150 | qb.orWhere(`${field} LIKE :value`, { value: `%${orLike.value}%` })
151 | })
152 | } else {
153 | // ...
154 | qb.where('1 = 1')
155 | searchCondition.forEach((obj) => {
156 | const { value, operator, field } = obj
157 | switch (operator) {
158 | case 'eq':
159 | qb.where(`${field} = :value`, { value })
160 | break
161 | case 'neq':
162 | qb.where(`${field} <> :value`, { value })
163 | break
164 | case 'notNull':
165 | qb.where(`${field} is not null`)
166 | break
167 | case 'isNull':
168 | qb.where(`${field} is null`)
169 | break
170 | case 'gt':
171 | qb.where(`${field} > :value`, { value })
172 | break
173 | case 'lt':
174 | qb.where(`${field} < :value`, { value })
175 | break
176 | case 'egt':
177 | qb.where(`${field} >= :value`, { value })
178 | break
179 | case 'elt':
180 | qb.where(`${field} <= :value`, { value })
181 | break
182 | case 'like':
183 | qb.where(`${field} LIKE :value`, { value: `%${value}%` })
184 | break
185 | default:
186 | break
187 | }
188 | })
189 | }
190 | }
191 | }
192 |
193 | /**
194 | * 递归遍历list,返回tree结构
195 | */
196 | function toTree(list, parId) {
197 | const len = list.length
198 | function loop(parId) {
199 | const res = []
200 | for (let i = 0; i < len; i++) {
201 | const item = list[i]
202 | if (item.parentId === parId) {
203 | item.children = loop(item.id)
204 | res.push(item)
205 | }
206 | }
207 | return res
208 | }
209 | return loop(parId)
210 | }
211 |
--------------------------------------------------------------------------------
/src/module/dept/dept.controller.ts:
--------------------------------------------------------------------------------
1 | import { DeptService } from './dept.service'
2 | import { Controller } from '@nestjs/common'
3 | import { ApiHeader } from '@nestjs/swagger'
4 | import { BaseController } from '../base/base.controller'
5 | import { Dept } from '@/entities/Dept'
6 |
7 | @ApiHeader({
8 | name: 'dept Module',
9 | description: '部门设置',
10 | })
11 | @Controller('dept')
12 | export class DeptController extends BaseController {
13 | constructor(private deptService: DeptService) {
14 | super(deptService)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/module/dept/dept.module.ts:
--------------------------------------------------------------------------------
1 | import { DeptController } from './dept.controller'
2 | import { DeptService } from './dept.service'
3 | import { Module } from '@nestjs/common'
4 | import { TypeOrmModule } from '@nestjs/typeorm'
5 | import { Dept } from '@/entities/Dept'
6 |
7 | @Module({
8 | imports: [TypeOrmModule.forFeature([Dept])],
9 | providers: [DeptService],
10 | controllers: [DeptController],
11 | exports: [DeptService],
12 | })
13 | export class DeptModule {}
14 |
--------------------------------------------------------------------------------
/src/module/dept/dept.service.ts:
--------------------------------------------------------------------------------
1 | import { BaseService } from 'src/module/base/base.service'
2 | import { Injectable } from '@nestjs/common'
3 | import { InjectRepository } from '@nestjs/typeorm'
4 | import { Repository } from 'typeorm'
5 | import { Dept } from '@/entities/Dept'
6 |
7 | @Injectable()
8 | export class DeptService extends BaseService {
9 | deptRepository: Repository
10 | constructor(@InjectRepository(Dept) deptRepository: Repository) {
11 | super(deptRepository)
12 | this.deptRepository = deptRepository
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/module/dynamictables/dynamictables.controller.ts:
--------------------------------------------------------------------------------
1 | import { DynamictablesService } from './dynamictables.service'
2 | import { Controller, Post, Query } from '@nestjs/common'
3 | import { ApiHeader } from '@nestjs/swagger'
4 | import { Dynamictables } from '@/entities/Dynamictables'
5 | import { BaseController } from 'src/module/base/base.controller'
6 | import { ResultGenerator } from 'src/core/resultBean'
7 |
8 | @ApiHeader({
9 | name: '表格管理',
10 | description: '表单管理',
11 | })
12 | @Controller('dynamictables')
13 | export class DynamictablesController extends BaseController {
14 | constructor(private dynamictablesService: DynamictablesService) {
15 | super(dynamictablesService)
16 | }
17 | @Post('detail')
18 | async getFormJson(@Query() query) {
19 | const table = await this.dynamictablesService.repository.findOne({
20 | where: {
21 | tableName: query.tablename,
22 | },
23 | })
24 | return ResultGenerator.success(table)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/module/dynamictables/dynamictables.module.ts:
--------------------------------------------------------------------------------
1 | import { DynamictablesController } from './dynamictables.controller'
2 | import { DynamictablesService } from './dynamictables.service'
3 | import { Module } from '@nestjs/common'
4 | import { TypeOrmModule } from '@nestjs/typeorm'
5 | import { Dynamictables } from '@/entities/Dynamictables'
6 |
7 | @Module({
8 | imports: [TypeOrmModule.forFeature([Dynamictables])],
9 | providers: [DynamictablesService],
10 | controllers: [DynamictablesController],
11 | exports: [DynamictablesService],
12 | })
13 | export class DynamictablesModule {}
14 |
--------------------------------------------------------------------------------
/src/module/dynamictables/dynamictables.service.ts:
--------------------------------------------------------------------------------
1 | import { BaseService } from 'src/module/base/base.service'
2 | import { Injectable } from '@nestjs/common'
3 | import { InjectRepository } from '@nestjs/typeorm'
4 | import { Repository } from 'typeorm'
5 | import { Dynamictables } from '@/entities/Dynamictables'
6 |
7 | @Injectable()
8 | export class DynamictablesService extends BaseService {
9 | DynamictablesRepository: Repository
10 | constructor(
11 | @InjectRepository(Dynamictables)
12 | DynamictablesRepository: Repository,
13 | ) {
14 | super(DynamictablesRepository)
15 | this.DynamictablesRepository = DynamictablesRepository
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/module/form/form.controller.ts:
--------------------------------------------------------------------------------
1 | import { ResultGenerator } from './../../core/resultBean'
2 | import { FormService } from './form.service'
3 | import { Controller, Post, Query } from '@nestjs/common'
4 | import { ApiHeader } from '@nestjs/swagger'
5 | import { Form } from '@/entities/Form'
6 | import { BaseController } from 'src/module/base/base.controller'
7 |
8 | @ApiHeader({
9 | name: '表单管理',
10 | description: '表单管理',
11 | })
12 | @Controller('form')
13 | export class FormController extends BaseController