# ccweb **Repository Path**: ccait/ccweb ## Basic Information - **Project Name**: ccweb - **Description**: CCWEB是基于springboot设计的CQRS敏捷web api开发框架,CCWEB提倡动态向前端提供基础数据,由前端根据基础数据组装业务来提高开发效率;内置用户管理、权限设置 等安全模块,启动服务后无需添加任何后端代码前端便可以通过默认接口直接访问到自己在数据库建的表和查询视图 - **Primary Language**: Java - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-10-17 - **Last Updated**: 2025-04-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README c c# /c++) python #VB^ ccait' java ccait ccweb En ti #SPRING Babel^_^~ node CC" ''' CC" ''' ty Que ry MVC TS `VUE delphi CCC CCC ab /le go Docker Electron@, javascript, CC CC pg/ pay AOP ES 66, 2019@copyright v1.0.0 HTTP: // /// CCAIT.CN FREAMEWORK ========================================================================= :: CCWEB :: (v1.0.0-SNAPSHOT) Author: linlurui 2019@copyright CCWEB是基于springboot设计的CQRS敏捷web api开发框架,项目由深圳市春蚕智能信息技术有限公司启动于2018底,2019年发布第一个版本,经过多次迭代现已升级到2.0,CCWEB提倡动态向前端提供基础数据,由前端根据基础数据组装业务来提高开发效率;内置用户管理、权限设置 等安全模块,启动服务后无需添加任何后端代码前端便可以通过默认接口直接访问到自己在数据库建的表和查询视图;底层orm采用entityQueryable访问数据,支持SpringCloud微服务扩展;支持elasticSerach搜索引擎;在横向扩展方面ccweb兼容了多种数据库系统,包括主流的mysql、sqlserver、oralce、MariaDB、PostgreSQL、db2、sybase等,有易于数据集成及高度扩展的能力,可以让数据自由地穿梭于各种数据存储系统之间:项目包含ccweb-core、ccweb-api、ccweb-start、ccweb-socket、ccweb-auth、ccweb-config、ccweb-gateway、ccweb-logs、ccweb-office、ccweb-webagent、ccweb-iot,整个2.0版本除ccweb-core之外,其余均选择了开源。
捐赠给作者
# ccweb-start ccweb-start是ccweb的启动包,其中包含了springcloud的微服务组件与springboos2.0 ## 运行环境 * jdk1.8 ## release文件结构 * cc-service.jar 【ccweb默认服务启动包】 * application.yml 【应用程序主配置文件】 * Dockerfile 【docker容器部署脚本】 * install.sh【linux系统依赖包安装脚本,需要先安装JDK1.8并且使用JDK自带的JRE,windows下需要安装cygwin来运行该脚本】 * kill.sh【jar包启动时的kill掉进程的脚本】 * run.sh【jar包启动脚本】 * ccait.db【sqlite默认数据库】 * lang.yml【语言配置文件,可配置多语言】 * libs/entity.queryable-2.0-SNAPSHOT.jar【动态查询依赖包 [项目地址](https://github.com/linlurui/entityQueryable)】 * libs/rxjava-2.1.10.jar【查询结果异步IO依赖包】 * libs/spring-context-5.2.5.RELEASE.jar【动态实体注入依赖包)】 * libs/spring-context-support-5.2.5.RELEASE.jar【动态实体注入依赖包)】 * libs/easyexcel-2.1.3.jar【excel数据导入依赖包】 ## 开发包说明 * ccweb-start (一个集成了ccweb-api的一键启动服务包) * ccweb-api (rest接口基础服务包) * ccweb-office (办公室文档处理功能包,如Word、Excel、PowerPoint、PDF) * ccweb-socket (websocket消息推送功能包) * ccweb-auth (用户鉴权功能包,分布式登录需搭载redis) * ccweb-iot (mqtt消息传输功能包,内置一个定阅器和一个简单的服务) * ccweb-config (分布式配置中心,可将每个服务的配置存至统一的数据库进行管理) * ccweb-logs (一个基于kafka的分布式日志系统,如用作消息队列需要引用该项目做二次开发消费端) * ccweb-repo (数据仓库模式操作类,用于二次开发时简化数据库操作) * ccweb-gateway(zuul网关) * ccweb-webagent(第三方平台接口转发功能包,可通过application.yml配置什么样的请求需要转发到第三方平台接口处理) ## 服务启动命令 ***java -jar cc-service.jar*** ## 接口说明 ccweb-start内置了默认的api接口可以让前端直接通过表名操作数据,需要限制访问的可以设置系统默认创建的用户权限表进行控制,接口的请求类型同时支持json和表单提交,表单中存在文件上传的会自动上传到表的字段中,字段类型必须为blob。 ### 1. 新增 (可批量) * URL:/api/{datasource}/{table} * 请求方式:PUT * URL参数:{datasource},{table}为数据库表名称 * POST参数: ```javascript [ { "字段名": "值", ... } ... ] ``` ### 2. 删除 * URL:/api/{datasource}/{table}/{id} * 请求方式:DELETE * URL参数:{table}为数据库表名称,{id}为主键 * POST参数:无 ### 3. 修改 * URL:/api/{datasource}/{table}/{id} * 请求方式:PUT * URL参数:{table}为数据库表名称,{id}为主键 * POST参数: ```javascript { "字段名": "值", ... } ``` ### 4. 查询 * URL:/api/{datasource}/{table} * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "pageInfo" : { "pageIndex": 1, //页码 "pageSize": 50 //每页条数 }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "sortList": [{ //排序条件 "name": "id", //字段名 "desc": true //true为降序,false为升序 }, ... ], "groupList" : [ //分组条件 "id", //字段名 ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...], "selectList": [{ //显示字段 "field": "id", //字段名 "function": "MAX", //数据库相关函数:MAX, MIN, UPPER, LOWER, LENGTH, AVG, COUNT, SUM, GROUP_CONCAT等; }, ... ] } ``` ### 5. 查询总数 * URL:/api/{datasource}/{table}/count * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "pageInfo" : { "pageIndex": 1, //页码 "pageSize": 50 //每页条数 }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "sortList": [{ //排序条件 "name": "id", //字段名 "desc": true //true为降序,false为升序 }, ... ], "groupList" : [ //分组条件 "id", //字段名 ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...], "selectList": [{ //显示字段 "field": "id", //字段名 "function": "MAX", //数据库相关函数:MAX, MIN, UPPER, LOWER, LENGTH, AVG, COUNT, SUM, GROUP_CONCAT等; }, ... ] } ``` ### 6. 查询是否存在数据 * URL:/api/{datasource}/{table}/exist * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "pageInfo" : { "pageIndex": 1, //页码 "pageSize": 50 //每页条数 }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "sortList": [{ //排序条件 "name": "id", //字段名 "desc": true //true为降序,false为升序 }, ... ], "groupList" : [ //分组条件 "id", //字段名 ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...], "selectList": [{ //显示字段 "field": "id", //字段名 "function": "MAX", //数据库相关函数:MAX, MIN, UPPER, LOWER, LENGTH, AVG, COUNT, SUM, GROUP_CONCAT等; }, ... ] } ``` ### 7. 联表查询 * URL:/api/{datasource}/join * 请求方式:POST * URL参数:{datasource}为数据源ID * POST参数: ```javascript { "joinTables": [{ "tablename": "salary", "alias": "a", "joinMode": "inner" }, { "tablename": "archives", "alias": "b", "joinMode": "Inner", "onList": [{ "name": "b.id", "value": "a.archives_id", "algorithm": "EQ" }] }, ...], "pageInfo" : { "pageIndex": 1, //页码 "pageSize": 50 //每页条数 }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "sortList": [{ //排序条件 "name": "id", //字段名 "desc": true //true为降序,false为升序 }, ... ], "groupList" : [ //分组条件 "id", //字段名 ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...], "selectList": [{ //显示字段 "field": "id", //字段名 "function": "MAX", //数据库相关函数:MAX, MIN, UPPER, LOWER, LENGTH, AVG, COUNT, SUM, GROUP_CONCAT等; }, ... ] } ``` ### 8. 联表查询总数 * URL:/api/{datasource}/join/count * 请求方式:POST * URL参数:{datasource}为数据源ID * POST参数: ```javascript { "joinTables": [{ "tablename": "salary", "alias": "a", "joinMode": "inner" }, { "tablename": "archives", "alias": "b", "joinMode": "Inner", "onList": [{ "name": "b.id", "value": "a.archives_id", "algorithm": "EQ" }] }, ...], "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "groupList" : [ //分组条件 "id", //字段名 ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...] } ``` ### 9. ID查询 查询与联合查询加密的字段不会解密显示,多用于列表,而ID查询的结果可以显示解密后内容,可用于保密详情。 * URL:/api/{datasource}/{table}/{id} * 请求方式:GET * URL参数:{table}为数据库表名称,{id}为主键 * POST参数:无 ### 10. 登录 * URL:/api/{datasource}/login * 注:如果引用了ccweb-auth模块和redis,URL可以使用 /api/login做分布式登录 * 请求方式:POST * POST参数: ```javascript { "username": "用户名", "password": "密码", } ``` ### 11. 登出 * URL:/api/{datasource}/logout * 注:如果引用了ccweb-auth模块和redis,URL可以使用 /api/logout做分布式登出 * 请求方式:GET ### 12. 下载文件 * URL:/api/{datasource}/download/{table}/{field}/{id} * 请求方式:GET * URL参数:{table}为数据库表名称,{field}为字段名,{id}为主键 * POST参数:无 * 注:上传多文件字段可在URL后追加:/index/{index}指定要下载第几个文件,{index}为文件下标 ### 13. 文件预览(支持预览图片、视频、PPT) * URL:/api/{datasource}/preview/{table}/{field}/{id}/{page} * 请求方式:GET * URL参数:{table}为数据库表名称,{field}为字段名,{id}为主键,{page}为可选入参,可指定页码 * POST参数:无 * 注:上传多文件字段可在URL后追加:/index/{index}指定要预览第几个文件,{index}为文件下标 ### 14. 上传文件 * URL:/api/{datasource}/{table}/{field}/upload * 请求方式:POST * URL参数:{table}为数据库表名称,{field}为字段名 * POST参数: ```javascript 表单: name1: 文件1 name2: 文件2 name3: 文件3 ... ``` * 返回: ```javascript { name1: 相对路径1 name2: 相对路径2 name3: 相对路径3 } ``` ### 15. 批量更新 * URL:/api/{datasource}/{table}/update * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "data": { "字段名": "值", ... }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...] } ``` ### 16. 批量删除 * URL:/api/{datasource}/{table}/delete * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript [id1, id2, ...] ``` ### 17. 导出Excel * URL:/api/{datasource}/{table}/export * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...], "selectList": [{ //显示字段 "field": "name", //字段名 "function": "MAX", //数据库相关函数:MAX, MIN, UPPER, LOWER, LENGTH, AVG, COUNT, SUM, GROUP_CONCAT等; "alias": "姓名", //别名,导出字段的表头名称,可以是中文 }, ... ] } ``` ### 18. 联表导出Excel * URL:/api/{datasource}/export/join * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "joinTables": [{ "tablename": "salary", "alias": "a", "joinMode": "inner" }, { "tablename": "archives", "alias": "b", "joinMode": "Inner", "onList": [{ "name": "b.id", "value": "a.archives_id", "algorithm": "EQ" }] }, ...], "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2, "="), GT(3, ">"), LT(4, "<"), GTEQ(5, ">="), LTEQ(6, "<="), NOT(7, "<>"), NOTEQ(8, "!="), LIKE(9), START(10), END(11), IN(12), NOTIN(13) }, ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值 }, ...], "selectList": [{ //显示字段 "field": "id", //字段名 "function": "MAX", //数据库相关函数:MAX, MIN, UPPER, LOWER, LENGTH, AVG, COUNT, SUM, GROUP_CONCAT等; "alias": "姓名", //别名,导出字段的表头名称,可以是中文 }, ... ] } ``` ### 19. 新增并返回ID(返回指定字段的最大值) * URL:/api/{datasource}/{table}/max/{field} * 请求方式:PUT * URL参数:{datasource}数据源,{table}为数据库表名称,{field}为要返回的字段名,接口会返回该字段最后插入的值 * POST参数: ```javascript [ { "字段名": "值", ... } ... ] ``` ### 20. 视频播放 * URL:/api/{datasource}/play/{table}/{field}/{id} * 请求方式:GET * URL参数:{table}为数据库表名称,{field}为字段名,{id}为主键 * POST参数:无 * 注:上传多文件字段可在URL后追加:/index/{index}指定要播放第几个文件,{index}为文件下标 ### 21. 导入Excel * URL:/api/{datasource}/{table}/import * 请求方式:POST * URL参数:{datasource}数据源,{table}为数据库表名称,{field}为要返回的字段名,接口会返回该字段最后插入的值 * POST参数: ```javascript 表单: 文件名1: 文件1 文件名2: 文件2 文件名3: 文件3 ... ``` * Excel文件格式: 1. 需要导入的excel文件中新增一个名称为schema的sheet 2. schema的第一行为需要导入的表格表头 3. schema的第二行为对应数据库的字段名 ### 22. 获取登录用户 * URL:/api/{datasource}/session/user * 请求方式:GET ### 23. 消息推送 * URL:/api/message/send * 请求方式:POST * URL参数:无 * POST参数: * 注意:该接口需要引入ccweb-socket包 ```javascript 表单: { "message": "my message", //消息内容 "receiver": { //接收人 "groupId": "", //组ID "roleId": "", //角色ID "usernames": [] //用户名 }, "sendMode": "ALL" //发送方式: ALL(0, "ALL"), USER(1, "USER"), GROUP(2, "GROUP"), ROLE(3, "ROLE") } ``` ### 24. 搜索引擎查询(需要配置Elasticsearch服务器) * URL:/api/{datasource}/search/{table} * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: * 注意:使用该接口需要在application.yml配置中将elasticSearch.enable设为true,然后新增或修改数据时才会创建索引 ```javascript { "pageInfo" : { "pageIndex": 1, //页码 "pageSize": 50 //每页条数 }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2), GT(3), LT(4), GTEQ(5), LTEQ(6), NOT(7), LIKE(9), IN(12), NOTIN(13) }, ... ], "sortList": [{ //排序条件 "name": "id", //字段名 "desc": true //true为降序,false为升序 }, ... ], "groupList" : [ //分组条件 "max(id) as maxId", //格式类SQL的select子句写法,聚合函数参考Elasticsearch ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值(可写通配符*,中文通配符查询效果以分词准) }, ...] } ``` ### 25. 获取数据流 * URL:/api/{datasource}/{table}/stream * 请求方式:POST * URL参数:{table}为数据库表名称 * POST参数: ```javascript { "pageInfo" : { "pageIndex": 1, //页码 "pageSize": 50 //每页条数 }, "conditionList": [{ //查询条件 "name": "id", //字段名 "value": "1", //值 "algorithm": "EQ", //条件: EQ(2), GT(3), LT(4), GTEQ(5), LTEQ(6), NOT(7), LIKE(9), IN(12), NOTIN(13) }, ... ], "sortList": [{ //排序条件 "name": "id", //字段名 "desc": true //true为降序,false为升序 }, ... ], "groupList" : [ //分组条件 "max(id) as maxId", //格式类SQL的select子句写法,聚合函数参考Elasticsearch ... ], "keywords" : [{ //关键词模糊查询条件 "name": "id", //字段名 "value": "1" //值(可写通配符*,中文通配符查询效果以分词准) }, ...] } ``` ### 26. 导入为PDF(需要引用ccweb-office) * URL:/api/{datasource}/import/to/pdf * 请求方式:POST|PUT * URL参数:{table}为数据库表名称 * POST参数: ```javascript 表单: save_full_text: true //是否全文索引,可选项 字段: 文件 ... ``` ## 系统用户/权限表结构说明 用户权限相关表在服务启动时会自动创建,目的在于使用系统服务控制数据库表的访问权限,用户组是扁平结构的,需要更复杂的权限控制功能建议通过二次开发实现。 * 用户表 (user, 主键userId, username[用户名], password[密码], type[用户类型], status[状态]) * 用户组 (group, 主键groupId, groupName[组名], description[描述]) * 角色表 (role, 主键roleId, roleName[角色名]) * 用户/组/角色关联关系表 (userGroupRole, 主键userGroupRoleId, 外键关联userId、groupId、roleId、userPath[用户层级路径,每个组下创建的用户ID组成]、createBy[创建人,数据权限检查的依据]、createOn[创建时间]、modifyBy[修改人]、modifyOn[修改时间]) * 数据访问控制表 (acl, 主键aclId, 外键关联groupId, tableName[需要控制访问的表名]) * 操作权限表 (privilege, 主键privilegeId, 外键关联groupId、roleId、aclId, scope[数据权限控制范围]) ### privilege表scope字段说明: * SELF=0(自己的数据) * NO_GROUP=1(无分组数据) * GROUP=2(同组数据) * CHILD=3(子组数据) * PARENT_AND_CHILD=4(父与子) * ALL=5(所有) ### privilege表其它字段说明: * canAdd (允许新增,1为允许,默认值:0) * canDelete (允许删除) * canUpdate (允许修改) * canView (允许查看详情) * canDownload (允许下载) * canPreview (允许预览) * canPlayVideo (允许播放视频) * canUpload (允许上传) * canExport (允许导出Excel) * canImport (允许Excel导入) * canDecrypt (允许解密加密的内容) * canList (允许浏览列表) * canQuery (允许查询数据) # 二次开发 ccweb的二次开发实际就是自定义ccweb-start包的过程,springboot的启动类注解需要加上@SpringBootApplication(scanBasePackages = "ccait.ccweb")才会去扫描ccweb-core的bean。 ## jar包介绍 * ccweb-core: ccweb的核心公共库 * ccweb-api: 提供RESTful接口服务和websocket服务,内置ccweb-core,不能直接起动,需要在ccweb-start中提供入口启动jar包。 ## Maven仓库中引入jar包 ```xml