接口请求格式定义
前台显示需要后台数据,我们这里先把前后端交互接口定义好,没有后台的时候,也方便用mock模拟。
接口定义遵循几个规范:
1. 接口按功能模块划分。
系统登录:登录相关接口
用户管理:用户管理相关接口
机构管理:机构管理相关接口
角色管理 : 角色管理相关接口
菜单管理 : 菜单管理相关接口
字典管理 : 字典管理相关接口
日志管理 : 日志管理相关接口
2. 通用增删改查接口采用统一命名规范。
save : 保存操作
update: 更新操作
delete: 删除操作
findAll: 查询全部
findPage : 分页查询
findTree : 返回对象树
findByXX:根据XX查询
2. 统一请求响应结果。
格式如下:
{ "code": 200, // 状态吗,200:请求成功,其他:请求出错 "msg": null, // 错误消息,成功返回 null, 否则返回出错信息 "data": { // 返回请求数据,JSON 数据格式 ... } }
系统登录
登录接口
请求URL: /sys/login
请求类型: post
请求参数:
{ "captcha": "3323", "password": "admin", "username": "admin" }
请求结果:
{ "code": 200, "msg": null, "data": { "id": null, "userId": 1, "token": "77ae89be36504adfb5c09ef71409ea0e", "expireTime": "2018-09-01T16:24:50.473+0000", "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": "2018-09-01T04:24:50.473+0000" } }
用户管理
保存
请求URL: /user/save
请求类型: post
请求参数:
{ "createBy": 0, "createTime": "2018-09-01T05:40:23.342Z", "delFlag": 0, "deptId": 110, "deptName": "", "email": "test@qq.com", "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T05:40:23.342Z", "mobile": "18999878998", "password": "123456", "salt": "1312321321", "status": 0, "userId": 110, "username": "test" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
修改
请求URL: /user/update
请求类型: post
请求参数:
{ "mobile": "test2@qq.com", "userId": 110, "username": "test" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
删除
请求URL: /user/delete
请求类型: post
请求参数:
{ "userId": 110 }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
分页查询
请求URL: /user/findPage
请求类型: post
请求参数:
{ "pageNum": 1, "pageSize": 5 }
请求结果:
{ "code": 200, "msg": null, "data": { "pageNum": 1, "pageSize": 5, "totalSize": 5, "totalPages": 1, "content": [ { "userId": 1, "username": "admin", "password": "9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d", "salt": "YzcmCZNvbXocrsz9dm8e", "email": "admin@qq.com", "mobile": "13612345678", "status": 1, "deptId": null, "deptName": null, "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "userId": 2, "username": "Louis", "password": "9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d", "salt": "YzcmCZNvbXocrsz9dm8e", "email": "louis@qq.com", "mobile": "18200932238", "status": 1, "deptId": null, "deptName": null, "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "userId": 3, "username": "Kobe", "password": "9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d", "salt": "YzcmCZNvbXocrsz9dm8e", "email": "kobe@qq.com", "mobile": "18200932238", "status": 1, "deptId": null, "deptName": null, "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "userId": 4, "username": "Iverson", "password": "9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d", "salt": "YzcmCZNvbXocrsz9dm8e", "email": "iverson@qq.com", "mobile": "18200932238", "status": 1, "deptId": null, "deptName": null, "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "userId": 110, "username": "test", "password": "123456", "salt": "1312321321", "email": "test@qq.com", "mobile": "test2@qq.com", "status": 0, "deptId": 110, "deptName": null, "createBy": 0, "createTime": "2018-09-01T05:40:23.000+0000", "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T05:40:23.000+0000", "delFlag": 0 } ] } }
根据用户查询
请求URL: /user/findByUserName
请求类型: get
请求参数:
{ "userName": "admin" }
请求结果:
{ "code": 200, "msg": null, "data": { "userId": 1, "username": "admin", "password": "9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d", "salt": "YzcmCZNvbXocrsz9dm8e", "email": "admin@qq.com", "mobile": "13612345678", "status": 1, "deptId": null, "deptName": null, "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 } }
更新密码
请求URL: /user/updatePassword
请求类型: get
请求参数:
{ "password ": "password ", "newPassword ": "newPassword " }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
机构管理
保存
请求URL: /dept/save
请求类型: post
请求参数:
{ "children": [ null ], "createBy": 0, "createTime": "2018-09-01T05:34:44.618Z", "delFlag": 0, "deptId": 110, "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T05:34:44.618Z", "name": "110", "orderNum": 0, "parentId": 0 }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
修改
请求URL: /dept/update
请求类型: post
请求参数:
{ "deptId": 110, "name": "upate" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
删除
请求URL: /dept/delete
请求类型: post
请求参数:
{ "deptId": 110 }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
查询机构树
请求URL: /dept/findTree
请求类型: get
请求参数:
{
}
请求结果:
{ "code": 200, "msg": null, "data": [ { "deptId": 1, "parentId": 0, "name": "轻尘集团", "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "deptId": 2, "parentId": 1, "name": "北京分公司", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "deptId": 3, "parentId": 1, "name": "上海分公司", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "deptId": 4, "parentId": 3, "name": "技术部", "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "deptId": 6, "parentId": 3, "name": "宣传部", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "deptId": 7, "parentId": 3, "name": "销售部", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "deptId": 8, "parentId": 3, "name": "市场部", "orderNum": 3, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] } ] }, { "deptId": 9, "parentId": 0, "name": "牧尘集团", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "deptId": 10, "parentId": 9, "name": "北京分公司", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "deptId": 12, "parentId": 10, "name": "技术部", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "deptId": 13, "parentId": 10, "name": "宣传部", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "deptId": 11, "parentId": 9, "name": "上海分公司", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "deptId": 14, "parentId": 11, "name": "销售部", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "deptId": 15, "parentId": 11, "name": "市场部", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] } ] } ] }
角色管理
保存
请求URL: /role/save
请求类型: post
请求参数:
{ "createBy": 0, "createTime": "2018-09-01T05:54:31.748Z", "delFlag": 0, "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T05:54:31.748Z", "remark": "string", "roleId": 110, "roleName": "110" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
修改
请求URL: /role/update
请求类型: post
请求参数:
{ "remark": "1101111", "roleId": 110, "roleName": "1101" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
删除
请求URL: /role/delete
请求类型: post
请求参数:
{ "roleId": 110 }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
分页查询
请求URL: /role/findPage
请求类型: post
请求参数:
{ "pageNum": 1, "pageSize": 5 }
请求结果:
{ "code": 200, "msg": null, "data": { "pageNum": 1, "pageSize": 5, "totalSize": 4, "totalPages": 1, "content": [ { "roleId": 1, "roleName": "admin", "remark": "超级管理员", "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "roleId": 2, "roleName": "dev", "remark": "开发人员", "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "roleId": 3, "roleName": "test", "remark": "测试人员", "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "roleId": 110, "roleName": "1101", "remark": "1101111", "createBy": 0, "createTime": "2018-09-01T05:54:32.000+0000", "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T05:54:32.000+0000", "delFlag": 0 } ] } }
查询全部
请求URL: /role/findAll
请求类型: get
请求参数:
{ }
请求结果:
{ "code": 200, "msg": null, "data": [ { "roleId": 1, "roleName": "admin", "remark": "超级管理员", "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "roleId": 2, "roleName": "dev", "remark": "开发人员", "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "roleId": 3, "roleName": "test", "remark": "测试人员", "createBy": null, "createTime": "2018-08-14T03:11:11.000+0000", "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0 }, { "roleId": 110, "roleName": "1101", "remark": "1101111", "createBy": 0, "createTime": "2018-09-01T05:54:32.000+0000", "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T05:54:32.000+0000", "delFlag": 0 } ] }
菜单管理
保存
请求URL: /menu/save
请求类型: post
请求参数:
{ "createBy": 0, "createTime": "2018-09-01T06:01:47.825Z", "delFlag": 0, "icon": "string", "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T06:01:47.825Z", "menuId": 110, "name": "110", "orderNum": 0, "parentId": 0, "perms": "sys:menu:list", "type": 0, "url": "/sys/menu" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
修改
请求URL: /menu/update
请求类型: post
请求参数:
{ "menuId": 110, "name": "1101" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
删除
请求URL: /menu/delete
请求类型: post
请求参数:
{ "menuId": 110 }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
查询菜单树
请求URL: /menu/findTree
请求类型: get
请求参数:
{
}
请求结果:
{ "code": 200, "msg": null, "data": [ { "menuId": 1, "parentId": 0, "name": "系统管理", "url": null, "perms": null, "type": 0, "icon": "fa el-icon-setting", "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 2, "parentId": 1, "name": "用户管理", "url": "/sys/user", "perms": null, "type": 1, "icon": "el-icon-service", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 9, "parentId": 2, "name": "查看", "url": null, "perms": "sys:user:view", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 10, "parentId": 2, "name": "新增", "url": null, "perms": "sys:user:save", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 11, "parentId": 2, "name": "修改", "url": null, "perms": "sys:user:update", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 12, "parentId": 2, "name": "删除", "url": null, "perms": "sys:user:delete", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "menuId": 3, "parentId": 1, "name": "机构管理", "url": "/sys/dept", "perms": null, "type": 1, "icon": "el-icon-news", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 13, "parentId": 3, "name": "查看", "url": null, "perms": "sys:dept:view", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 14, "parentId": 3, "name": "新增", "url": null, "perms": "sys:dept:save", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 15, "parentId": 3, "name": "修改", "url": null, "perms": "sys:dept:update", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 16, "parentId": 3, "name": "删除", "url": null, "perms": "sys:dept:delete", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "menuId": 4, "parentId": 1, "name": "角色管理", "url": "/sys/role", "perms": null, "type": 1, "icon": "el-icon-view", "orderNum": 4, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 17, "parentId": 4, "name": "查看", "url": null, "perms": "sys:role:view", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 18, "parentId": 4, "name": "新增", "url": null, "perms": "sys:role:save", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 19, "parentId": 4, "name": "修改", "url": null, "perms": "sys:role:update", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 20, "parentId": 4, "name": "删除", "url": null, "perms": "sys:role:delete", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "menuId": 5, "parentId": 1, "name": "菜单管理", "url": "/sys/menu", "perms": null, "type": 1, "icon": "el-icon-menu", "orderNum": 5, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 21, "parentId": 5, "name": "查看", "url": null, "perms": "sys:menu:view", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 22, "parentId": 5, "name": "新增", "url": null, "perms": "sys:menu:save", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 23, "parentId": 5, "name": "修改", "url": null, "perms": "sys:menu:update", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 24, "parentId": 5, "name": "删除", "url": null, "perms": "sys:menu:delete", "type": 2, "icon": null, "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "menuId": 6, "parentId": 1, "name": "SQL监控", "url": "/druid/sql", "perms": null, "type": 1, "icon": "el-icon-info", "orderNum": 6, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 8, "parentId": 1, "name": "系统日志", "url": "/sys/log", "perms": "sys:log:list", "type": 1, "icon": "el-icon-info", "orderNum": 7, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "menuId": 25, "parentId": 0, "name": "内容管理", "url": null, "perms": null, "type": 0, "icon": "el-icon-document", "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 26, "parentId": 25, "name": "栏目管理", "url": "/content/category", "perms": null, "type": 1, "icon": "el-icon-tickets", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 27, "parentId": 25, "name": "文章管理", "url": "/content/artical", "perms": null, "type": 1, "icon": "el-icon-tickets", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] }, { "menuId": 28, "parentId": 0, "name": "使用案例", "url": null, "perms": null, "type": 0, "icon": "el-icon-picture-outline", "orderNum": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [ { "menuId": 29, "parentId": 28, "name": "国际化", "url": "/demo/i18n", "perms": null, "type": 1, "icon": "el-icon-edit", "orderNum": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] }, { "menuId": 30, "parentId": 28, "name": "换皮肤", "url": "/demo/theme", "perms": null, "type": 1, "icon": "el-icon-picture", "orderNum": 2, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "delFlag": 0, "children": [] } ] } ] }
字典管理
保存
请求URL: /dict/save
请求类型: post
请求参数:
{ "createBy": 0, "createTime": "2018-09-01T06:05:44.794Z", "delFlag": 0, "description": "aaaa", "id": 110, "label": "aa", "lastUpdateBy": 0, "lastUpdateTime": "2018-09-01T06:05:44.794Z", "remarks": "aaaaaa", "sort": 0, "type": "a", "value": "aaaaa" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
修改
请求URL: /dict/update
请求类型: post
请求参数:
{ "description": "bbbb", "id": 110, "label": "bbbb" }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
删除
请求URL: /dict/delete
请求类型: post
请求参数:
{ "id": 110 }
请求结果:
{ "code": 200, "msg": null, "data": 1 }
分页查询
请求URL: /dict/findPage
请求类型: get
请求参数:
{ "pageNum": 1, "pageSize": 5 }
请求结果:
{ "code": 200, "msg": null, "data": { "pageNum": 1, "pageSize": 5, "totalSize": 2, "totalPages": 1, "content": [ { "id": 1, "value": "male", "label": "男", "type": "sex", "description": "男性", "sort": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "remarks": null, "delFlag": 0 }, { "id": 2, "value": "female", "label": "女", "type": "sex", "description": "女性", "sort": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "remarks": null, "delFlag": 0 } ] } }
日志管理
分页查询
请求URL: /log/findPage
请求类型: get
请求参数:
{ "pageNum": 1, "pageSize": 5 }
请求结果:
{ "code": 200, "msg": null, "data": { "pageNum": 1, "pageSize": 5, "totalSize": 2, "totalPages": 1, "content": [ { "id": 1, "value": "male", "label": "男", "type": "sex", "description": "男性", "sort": 0, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "remarks": null, "delFlag": 0 }, { "id": 2, "value": "female", "label": "女", "type": "sex", "description": "女性", "sort": 1, "createBy": null, "createTime": null, "lastUpdateBy": null, "lastUpdateTime": null, "remarks": null, "delFlag": 0 } ] } }
好了,后续前台页面需要调用相关接口的时候,就可以用上面的格式进行 mock 模拟了。
原文出处:https://www.cnblogs.com/xifengxiaoma/
自己整理记录。