# online_booking_system
**Repository Path**: My-style/online_booking_system
## Basic Information
- **Project Name**: online_booking_system
- **Description**: 预约系统
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2020-04-07
- **Last Updated**: 2021-04-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# framework-base
# 一、安装与部署
## 1.简介
* 平台采用maven作为其依赖关系管理工具,项目拆分成多个module,module间存在依赖关系,每个module被打包成.jar文件,并且通过pom.xml文件添加依赖关系。实际开发过程中,可以将公共的module置于maven库中,无需下载其源码。
* 安装过程遵循以下规律:被依赖的module首先安装,项目入口的module为webapp,其为一个web项目,可以将其部署与tomcat服务器下。
## 2.数据库脚本
* 数据库脚本位于`webapp` module中,其具体位置为:`/src/main/resources/mysql.sql`
* 数据库脚本目前只有`mysql`的脚本,其余的脚本可以通过navicat进行导出。
## 3.配置文件
### 3.1.数据库及其他配置
#### 数据源配置
数据库配置文件位于webapp module中,具体位置为:`/src/main/resources/config/config.properties`。如使用的数据库部署mysql,需要修改`/src/main/resources/config/config.properties`文件,在其中,修改如下内容:
```sh
```
#### 异常页面映射配置
框架采用统一的json进行数据返回,在控制器中,使用抛出异常的手段来重定向至不同的异常页面。在异常中,会包含这种异常的“代码值”,通过配置配置文件可以将其指向不同页面,配置文件路径:`/src/main/resources/config/mapping.properties`,其key以`MP_代码值`命名,其默认配置如下:
| Key | Value | 说明 |
|----------|:-------------:|:------|
| DEFAULT | /view/sys/error.jsp | 默认的错误页面路径 |
| MP_000001 | /view/sys/error.jsp | 无 |
| MP_000008 | /view/sys/login.jsp | 无 |
| MP_000009 | /view/sys/error.jsp | 无 |
| MP_000010 | /view/sys/login.jsp | 无 |
#### 异常显示文本配置
其原理同上,配置文件路径:`/src/main/resources/config/msg.properties`,其key以`MSG_代码值`命名。
### 3.2.缓存配置
框架内置两种缓存方式:redis缓存以及ehcache缓存。缓存主要用于以下几个方面:
* spring接口缓存,以接口的形式对查询出来的数据进行缓存。
* shiro缓存,包含用户凭证、授权信息缓存等。
#### 3.2.1.缓存切换
当进行缓存切换时,如使用到了redis,则需要修改`spring-context.xml`文件,导入`spring-jedis.xml`文件,缓存切换方式如下:
##### 3.2.1.1.Ehcache(spring)缓存
配置文件位于:`/src/main/resources/xmls/spring-context.xml`,确保如下代码生效:
```sh
```
##### 3.2.1.2.Redis(spring)缓存
配置文件位于:`/src/main/resources/xmls/spring-context.xml`,确保如下代码生效:
```sh
```
##### 3.2.1.3.Redis(shiro)缓存
修改`spring-shiro.xml`文件,确保以下的代码生效:
```sh
```
##### 3.2.1.4.Ehcache(shiro)缓存
修改`spring-shiro.xml`文件,确保以下的代码生效:
```sh
```
### 3.3.工作流配置
平台中使用了activiti作为工作流引擎,其版本号为`6.0`。module名称为`activiti`,项目为模块化项目,可以随时对工作流进行装载、卸载,修改时,仅需修改webapp下的pom.xml,添加或者移除掉activiti的依赖。当然,移除后,理应将其关于工作流的菜单屏蔽掉。
### 3.4.接口文档配置
平台中使用了swagger2作为其接口文档,正式项目发布后,理应去掉在线接口文档,移除方式如下:
* 修改`spring-MVC.xml`,注释如下两句话:
```sh
```
* 修改`polar.island.web.api.DocConfig.java`文件,将类的注解注释掉。
PS:如果想要完全去除掉swagger的依赖,则需要修改根目录的pom.xml文件,移除swagger的依赖,同时,需要保留swagger的注解依赖,以免项目因缺少依赖而报错。
## 4.安装
安装时,使用maven的install命令进行安装,也可以使用`idea`进行安装。
### 4.1.普通版本
#### 4.1.1.依赖关系
#### 4.1.2.module介绍
| 名称 | 含义 |
|----------|:-------------|
| parent | 平台父级配置文件 |
| core | 平台的基础module |
| inlay | 平台内置功能的module,包含用户管理、组织机构管理、字典管理等。 |
| flow | 工作流相关的module |
| webapp | 项目入口,包含一些页面、js、css等 |
##### core子模块
| 名称 | 含义 |
|----------|:-------------|
| common | 基础支撑的module,包含一些公共类等 |
| database | sql数据库支撑,使用sql数据库时才会用到 |
| file-mongodb | 使用mongodb保存文件,一般用于分布式/负载均衡时存放文件 |
| mongodb | Nosql-mongodb数据库支撑,包含一些注解、普通的增删改查等 |
| payment | 支付相关的模块 |
| queue | 消息队列模块,主要用于异步通知、服务器协调、事务补偿 |
| security | 权限相关的支持 |
##### flow子模块
| 名称 | 含义 |
|----------|:-------------|
| flow-joggle | 工作流的接口以及实体 |
| flow-service | 工作流服务的实现类,包含数据库存储,工作流只支持SQL数据库,不支持mongodb |
| flow-web | 工作流页面跳转、接口相关的类 |
##### inlay子模块
| 名称 | 含义 |
|----------|:-------------|
| inlay-joggle | 内置模块的接口以及实体 |
| inlay-service | 内置模块的服务实现类 |
| inlay-service-mongodb | 内置模块的服务实现类,dao层使用mongodb实现 |
| inlay-web | 内置模块页面跳转、接口相关的类 |
#### 4.1.3.安装顺序
```sh
parent-->core-->flow,inlay-->web
```
### 4.2.分布式版本
#### 4.2.1.依赖关系
#### 4.2.2.module介绍
| 名称 | 含义 |
|----------|:-------------|
| parent | 平台父级配置文件 |
| core | 平台的基础module |
| inlay | 平台内置功能的module,包含用户管理、组织机构管理、字典管理等。 |
| flow | 工作流相关的module |
| webapp | 项目入口,包含一些页面、js、css等 |
##### core子模块
| 名称 | 含义 |
|----------|:-------------|
| common | 基础支撑的module,包含一些公共类等 |
| database | sql数据库支撑,使用sql数据库时才会用到 |
| file-mongodb | 使用mongodb保存文件,一般用于分布式/负载均衡时存放文件 |
| mongodb | Nosql-mongodb数据库支撑,包含一些注解、普通的增删改查等 |
| payment | 支付相关的模块 |
| queue | 消息队列模块,主要用于异步通知、服务器协调、事务补偿 |
| security | 权限相关的支持 |
##### flow子模块
| 名称 | 含义 |
|----------|:-------------|
| flow-joggle | 工作流的接口以及实体 |
| flow-service | 工作流服务的实现类,包含数据库存储,工作流只支持SQL数据库,不支持mongodb `包含服务发布的脚本` |
| flow-web | 工作流页面跳转、接口相关的类 |
##### inlay子模块
| 名称 | 含义 |
|----------|:-------------|
| inlay-joggle | 内置模块的接口以及实体 |
| inlay-service | 内置模块的服务实现类 `包含服务发布的脚本` |
| inlay-service-mongodb | 内置模块的服务实现类,dao层使用mongodb实现 `包含服务发布的脚本` |
| inlay-web | 内置模块页面跳转、接口相关的类 |
#### 4.2.3.安装顺序
```sh
parent-->core-->inlay,flow-->web
```
## 5.部署
### 5.1.普通版本
在项目安装完成后,可以在idea中通过tomcat启动项目,也可以将webapp/target下的war包部署到tomcat目录下。
### 5.2.分布式版本
#### 部署服务
在项目安装完成后,在`XX-service/target`下会生成`XX.tar.gz`文件,此文件为`linux`系统下的服务部署包,将其上传至linux服务器中,解压后运行如下命令:```sh service.sh start```命令,启动服务。
服务还支持如下命令:
```sh
sh service.sh stop 停止服务
sh service.sh status 查看服务运行状态
sh service.sh restart 重启服务
```
服务也支持在windows下部署(不建议使用此种部署方式):
* 将`XX-service/target/deploy`目录拷贝至windows服务器
* 使用cmd命令进入到此目录
* 运行命令:`java -jar xx-service.jar`
#### 部署web项目
在项目安装完成后,可以在idea中通过tomcat启动项目,也可以将webapp/target下的war包部署到tomcat目录下。
# 二、业务介绍
## 1.字典管理
在各种项目中,字典应用非常广泛,其主要用于下拉列表中,在此框架中,字典以“组编号”进行分组,字典加入了缓存,在jsp中提供了tag标签,可以使用如下形式获取字典数据:
* `${fns:getDict(groupId)}` 其获取到的是个集合
* `${fns:getDictJson(groupId)}` 其获取到的是json数据
```sh
表名:t_polar_dict
模块路径:polar.island.inlay.dict
归属module:inlay
```
| 字段名称 | 中文名称 | 备注 |
|----------|:-------------|:-------------|
|id | 编号 | 数据编号 |
|text | 文本内容 | 下拉列表中显示的文本内容 |
|value | 值 | 字典的真实数据 |
|remark | 备注 | 字典项的备注信息 |
|orderNum | 排序号 | 在一个组内,字典的排序号 |
|groupId | 组编号 | 字典的组编号 |
|groupName | 组名称 | 字典的组名称 |
## 2.树结构管理
树结构类似于字典,也是根据组编号进行分组,其提供两种计算父子关系的方式:编码类型、父子编号类型。在jsp页面中,可以使用如下方式来获取树结构数据:
* `${fns:getTree(groupId)}` 其获取到的是个集合
* `${fns:getTreeJson(groupId)}` 其获取到的是json数据
* 编码类型
编码类型的数据以树结构中的编码来计算其父子关系,编码类型仅支持6位的编码,每两位表示一个层级,00表示根节点。一个简单的区域编码示例如下:
| 编码 | 区域 | 上级区域 | 层级 |
|----------|:-------------|:-------------|:-------------|
| 000000 | 中国 | 无 | 0 |
| 010000 | 山东 |中国 | 1 |
| 020000 | 山西 |中国 | 1 |
| 020100 | 太原 |山西 | 2 |
| 010100 | 济南 |山东 | 2 |
| 010101 | 高新区 | 济南 | 3 |
| 010102 | 市中区 | 济南 | 3 |
| 010103 | 历下区 | 济南 | 3 |
* 父子编号类型
父子编号形式可以用于各种复杂的树结构,使用父子编号来确定层级关系,按照值进行排序。
```sh
表名: t_polar_tree
模块路径: polar.island.inlay.tree
归属module: inlay
```
| 字段名称 | 中文名称 | 备注 |
|----------|:-------------|:-------------|
| id | 编号 | 无 |
| text | 文本内容 | 树结构中显示的文本内容 |
| value | 值 | 树结构的真实数据 |
| textAlias | 别名 | 树结构的别名 |
| parentId | 父级编号 | 树结构的父级编号,对应textId |
| groupId | 组编号 | 树结构的组编号 |
| groupName | 组名称 | 树结构的组名称 |
| textId | 编号 | 用于计算父子依赖关系 |
| type | 类型 | 1:编码类型,2:父子编号类型 |
## 3.日志管理
日志管理主要用于记录系统运行过程中产生的各种不可知、预料不到的异常,其会将异常信息记录于此处,以便以后开发的过程中对系统进行排错。
系统对于异常均使用抛出异常的形式来处理,当异常属于框架内异常并且异常设置为“不记录”时不会记录异常信息,否则系统会记录异常信息。
## 4.权限管理
* 平台的权限为树形结构,当对角色分配权限时,如果某一个子项被选中,则其父项也会被选中,因此权限的父项不具有实际意义,其子项起到实际控制权限的作用。
* 当给角色分配权限后,由于有缓存,用户的权限不会立即生效,此时需要在用户管理中清除权限缓存。
* 权限与接口存在对应关系,在接口中可以使用如下形式声明此接口所需的权限:
```sh
@RequiresPermissions(value = {"polar:backstage", "polar:code:empty"})
```
## 5.角色管理
平台中,角色不会与用户进行关联,而是通过角色进行关联,即其关系为:用户->角色->权限,角色也可以在接口中声明,也可不声明:
```sh
@RequiresRoles(value = {"polar:backstage", "polar:code:empty"})
```
## 6.资源管理
平台中,资源管理主要用于动态的数据库连接,当某些接口需要的用户权限不一定时,可以通过此处进行控制,录入访问路径后,设置权限,则没有权限的用户均无法访问此路径。
PS:路径与权限的对应关系也设置了缓存,如做出修改,需要点击“重新加载资源”按钮,如涉及到负载均衡,此处应该使用redis作队列并分发给各个机器。
## 7.菜单模板管理
对于不同的用户,会存在不同的菜单,菜单模板就是为用户设置其不同的菜单,当未给用户分配菜单时,其会使用默认的菜单模板。
对于已有的菜单,可以在菜单模板中,点击分配菜单选项将菜单与菜单模板进行关联。
## 8.菜单管理
菜单为平台管理端端的菜单,为树形结构,在此处可以对菜单进行维护,包括菜单的图标、名称、访问路径、是否展开等进行维护。其图标使用`font-awesome`的图标库,可去网络搜索此图标对应的代码。
## 9.用户管理
系统对应用户的管理,可以新增用户、为用户分配角色,踢出在线用户、设置菜单、启用/禁用用户等操作。
* 新增用户,新增用户后,用户是没有任何权限的,新增后,需要对用户的角色进行配置。
* 角色分配,此处可以对用户的角色进行分配,用户角色对应权限,当分配完角色后,用户拥有对应的权限,如用户未登录,则权限信息未缓存,此时不需要清除用户的权限缓存,否则需要清除用户的权限缓存。
* 禁用/启用用户,禁用用户后,用户无法登录,已在线用户会被强制下线。启用用户后,用户可以登录。
* 设置菜单,可以为用户设置后台管理端的菜单,此处需要清空菜单缓存。
* 在线用户,可以对在线用户进行管理,包括查看本账号登录数、session编号等,同时可以对其进行强制下线处理。
## 10.机构管理
用户可以归属于某个机构,机构有其特有的权限,当用户归属于此机构后,其也会有本机构的所有权限。
机构为树形结构,为了系统的流畅性,其子机构不会继承父级机构的权限。
## 11.访问记录
访问记录可以查看每次用户访问平台的记录,其使用线程处理记录,不会对系统性能造成任何影响。
在开发过程中,接口默认是不会记录访问记录的,如果想要对其配置,则需要在接口中加入如下注解:
```sh
@ErrorMsg(tag = "更新表单", type = ErrorType.JSON,writeLogs=true)
```
其中,tag表示为接口名称,type用来表示错误发生后,返回的数据类型,writeLogs表示是否写出日志,默认为true。
## 12.操作组
操作组专为流程而设计,其将用户进行分组,流程中设置其操作组,则表示在这个组内的成员拥有这个操作的权限。
## 13.表单管理
表单管理为流程表单,在流程中,需要对每个操作设置、编辑表单,在流程中,需要将操作的id与表单一一绑定。
## 14.流程管理
1. 使用activiti工作流引擎对流程进行管理,其使用的是BPMN2.0规范,不支持1.0规范,支持在线流程编辑,流程编辑完成后,需要发布流程才会使流程能够真正的运行。
2. 在流程图中,每个用户任务需要用户去操作,并且需要录入操作日志,此处需要将用户任务与表单进行绑定。
在流程绘制的过程中,可以通过条件表达式来决定网关需要走哪一步。
3. `${start.xx}`表示启动流程中的参数,`${current.xx}`表示当前操作录入的数据。
4. 如果是流程刚刚启动,则直接使用`${xx}`的形式来表示数据。
## 15.代码生成器
代码生成器支持三种模式的表单:单表、父子表、树结构表单。
`单表`:只有一张表的表单,通常用于比较简单的业务逻辑中,在平台中,字典管理模块就是一个例子,其和别的表没有必然的联系。
`父子表`:父子表由两部分表单组成,父表以及子表,例如:在个人简历中,简历的基础信息,譬如姓名、年龄等属于父表数据、工作经验、项目经验与简历为多对一的关系,即:一个简历对应多条项目经验、工作经验,其就是子表。在平台中,一个父表可以对应多个子表。
`树结构表单`:树结构表单为一个树形结构,其必须包含两个参数,唯一编号以及父级唯一编号,在查询的过程中,父子表不会进行分页查询。
在代码生成器使用过程中,需要按照以下步骤来操作:
1. 设计数据库
在数据库设计表,其表名不能以“t_polar”或者“act_”开头,前者表示框架内的表,后者表示工作流的表。在数据库设计中,应该给每个字段添加注释。
2. 导入表
系统不支持新增表单,因此,表单需要从数据库中导入,点击导入表单后,选择需要导入的表单,导入即可。
3. 修改表单参数
点击表单后面的“修改”按钮,对表单参数进行配置,表单参数参加下面的表单参数一览表。
4. 修改列参数
在表单参数修改完成后,应该对列参数进行修改,此处可以对列进行添加、删除、调序等操作,需要注意的是,对于某些特殊类型的列属性,其某些扩展参数不能为空。
5. 生成代码
确保各个参数正确后,点击代码生成即可生成相应的代码,其代码生成后的路径参见`/src/main/resources/config/config.properties`中的CODE_PATH。对于父子表,其必须由父表生成代码。
6. 生成权限
代码生成完毕后,其会依据模块名称生成权限信息,此时需要对权限进行配置,否则会导致访问不到的情况,点击生成权限后,会一键配置权限信息,其会自动为系统管理员添加相应的权限。
7. 配置菜单
代码生成完毕后,需要配置菜单,具体参见菜单模板和菜单管理。
8. 重启服务
代码生成完毕后,重启服务即可看到相应的功能。
#### 15.1.1.表单参数一览表
| 名称 |
含义 |
| 基础参数 |
| 表名 |
数据库表的名字 |
| 中文名 |
对应中文名字 |
| 模型类型 |
其表示在service结果集返回的类型 |
| 表单类型 |
单表、父表、子表、树结构表 |
| 删除模式 |
是否从数据库删除 |
| 主键类型 |
如果选择long,则在表设计的过程中,必须设置其为自增。 |
| 主键名称 |
数据库主键的名字 |
| 包名 |
框架里面对应的包名 |
| 模块名称 |
框架里面所属的模块 |
| 作者 |
开发者 |
| 模块注释 |
框架里面的注释,其会在实体类中标识。 |
| WEB端配置(页面跳转控制器的配置) |
| 访问路径 |
页面跳转的基础路径 |
| 类名 |
控制器类名 |
| 标签 |
@Controller注解内的value值,其主要为了防止冲突 |
| JSON端配置(接口端控制器的配置) |
| 访问路径 |
访问接口的基础路径 |
| 类名 |
控制器类名 |
| 标签 |
@Controller注解内的value值,其主要为了防止冲突 |
| 服务端配置 |
| 接口类名 |
service接口的类名 |
| 标签 |
@Service注解内的value值 |
| 实现类类名 |
Service实现类的类名 |
| Dao配置 |
| 类名 |
Dao接口的名字 |
| 标签 |
@Dao注解内的value值 |
| 实体类名 |
实体类的名字 |
| 实体类别名 |
实体类的别名,使用于mapper文件中 |
| Mapper配置 |
| 文件夹名称 |
Mapper所在的文件夹 |
| 文件名称 |
Mapper文件的名字 |
| 页面配置 |
| 校验方式 |
Layui、bootstrapTable 可以使用两种方式对表单校验 |
| 列表模板 |
layui-table、bootstrap-table可以使用两种列表模板 |
| 列表页面名称 |
列表的展示文件名字 |
| 编辑页面名称 |
添加、编辑的文件名字 |
#### 15.1.2.列参数一览表
| 字段 | 含义 |
|----------|:-------------|
| 字段名称 | 在数据库中的字段名称 |
| Java列名称 | 在实体类中的字段名称 |
| 中文名 | 字段的中文名称 |
| 注释 | 字段的注释 |
| 字段类型 | 字段的类型 |
| 匹配方式 | 查询列表过程中字段的匹配方式 |
| 扩展参数 | 见扩展参数一览表 |
| 显示 | 是否在页面查询、是否在列表展示、列表查询时是否返回、是否允许行内编辑 |
| 校验 | 新增或者编辑时,数据字段的校验方式 |
#### 15.1.3.扩展参数一览表
| 字段名称 |
必填 |
备注 |
| 单行文本、整数、浮点数、大整数 |
| maxlength |
否 |
文本框的允许输入的最大长度,默认为50,如果填写-1,表示最大长度不限制 |
| minLength |
否 |
没有最小值,可以不填写 |
| 下拉列表 |
| emptyValue |
否 |
不选择时,字典默认显示文本 |
| name |
是 |
字典所属的组编号 |
| 日期 |
| format |
否 |
日期格式化,默认是:yyyy-MM-dd |
| 单图片 |
| height |
否 |
图片的高度,如果不写,默认为80px |
| width |
否 |
图片的宽度,如果不写,默认为80px |
| 多个文件 |
| type |
否 |
上传的文件类型,支持如下参数:images(图片)、file(所有文件)、video(视频)、audio(音频),默认值为file |
| max |
否 |
允许上传文件的最多个数,如果填写-1,表示不限制,默认为-1 |
| 富文本编辑器 |
| maxlength |
否 |
富文本编辑器允许输入的最大长度,默认为2000,包括标点 |
| 文本域 |
| maxlength |
否 |
文本域允许输入的最大长度,默认为500,包括标点 |
| 多图片 |
| height |
否 |
图片的高度,如果不写,默认为80px |
| width |
否 |
图片的宽度,如果不写,默认为80px |
| max |
否 |
允许上传图片的最多格式,如果填写-1,表示不限制,默认为-1 |
| 单文件 |
| type |
否 |
上传的文件类型,支持如下参数:images(图片)、file(所有文件)、video(视频)、audio(音频),默认值为file |
| 单选树形结构 |
| name |
是 |
树结构的组编号 |
| 多选树形结构 |
| name |
是 |
树结构的组编号 |
| 省市区选择、隐藏 |
| 无 |
#### 15.1.4.其他说明
* 当表单为父子表单时,子表中,父表的外键字段应设置为隐藏。
* 当表单为树结构表单时,父编号字段和子编号字段不能为空。
* 当对表单编辑完成后,最好重置一下列属性,以免部分字段出现问题。
# 三、常见问题
### Q:程序为什么要模块化,好处在哪里?
程序模块化之后,可以很方便的装载各个功能,例如:我不需要使用工作流,那么只需要在pom.xml中移除掉其相关的依赖即可。
### Q:每个模块为什么分为接口、服务、web三个模块?
项目这么分,是为了各个项目的解耦,例如:如果想要mongodb,那么引入mongodb的服务,普通的服务则引入普通的服务。同时,在分布式版本中,必须这么分,由web程序引入接口端以及web端,不去关心其真正的实现类,通过dubbo进行远程调用。
### Q:消息队列用在什么地方?
消息队列用于集群调度、分布式事务、异步通知。其分为广播与队列的模式。
* 广播:任何一台消息都能够接收到这条消息
* 队列:只有一台机器能够接收到。
分布式事务:其使用的是事务补偿原理,当系统发生异常时,发送消息队列,由固定的机器去处理这条消息,当处理次数过多时,将其持久化,由用户手动处理。
### Q:数据库有什么要求?
mongodb版本号不许大于4.0,并且需要做复制集,否则无法做事务管理。sql数据库支撑:oracle,mysql,sqlserver,可以通过配置文件去修改数据库类型。
### Q:为什么有了redis以后还提供ehcache?
ehcache是为单机准备的,在单机环境下,ehcache占用的仅仅是硬盘读取速度,而redis则会占用系统带宽,影响性能。
### Q:如何进行生产环境和测试环境打包?
在pom.xml文件下,增加profile,选择profile,使用maven命令打包。
### Q:作者帅不帅?
吴彦祖晓得伐?