fhs-framwork是一个集成了国内外诸多优秀开源项目的快速开发平台,除了在常规快速开发平台提供 用户,角色,权限,菜单,字典,操作日志,代码生成器 等功能的基础上,还在以下方面为您的快速开发做出了努力。
开箱即用:依赖redis和mysql,导入数基础的脚本后,修改下配置文件,即可使用。
- 减少手写sql
fhs 使用了Mybatis Jpa+Mybatis Plus 框架来帮大家自动生成常见sql,Mybatis Jpa是fhs-opensource下的一款基于Mybatis的JPA的实现,为了补足复杂sql的生成,又对Mybatis Jpa 又对Mybatis Plus做了兼容,可以使用Mybatis Plus的注解来实现sql自动生成,有了Mybatis Jpa+Mybatis Plus 实现80%的单表查询无需写一行sql的效果
- 数据源路由
通过简单的配置即可实现分库,分表,读写分离操作。
- 声明式事物
add,update,del,save 开头的service方法,会默认开启事物,自定义部分请使用注解。
- 数据权限控制
通过简单的配置即可实现组合或者单一数据权限控制
- 大量的base类使用
通过继承即可完成大部分CRUD操作。
- 提供常见的工具类
日期,日志,反射,网络,校验,文件等等。
- 其他
统一验证框架处理器,统一异常处理器,控制器返回数据json字段过滤器,xss,csrf拦截器等等
翻译服务用于根据表中存放的id来翻译出对应的文字来给做客户做显示使用,翻译服务使用进程缓存,当缓存有更新的时候会自动重新加载(支持分布式),有着很高的效率,可减少表关联sql的书写。
首先在pojo中添加注解
@Trans(type="wordbook",key="sex") private Integer sex; // type代表翻译类型是什么,上面写的是字典,key是sex 如果字典中配置了0-男 1 -女 如果这里的value是0 那么给前端就可以输出为男
自定义表加入到翻译服务demo:
//给这个组织机构翻译起个别名叫做org 需要翻译的字段是 org pojo的name字段 使用redis作为缓存 默认的别名是org
//实际组织机构在生成json的时候默认会为 orgName 而不是name
@AutoTrans(namespace = BaseTransConstant.ORG, fields = "name", useRedis = true, defaultAlias = "org")
public class UcenterMsOrganizationServiceImpl extends BaseServiceImpl<UcenterMsOrganizationVO, UcenterMsOrganizationDO> implements UcenterMsOrganizationService {
更多玩法请看gitee wiki.
几乎所有的项目中都提供了操作日志,操作日志对开发人员比较友好,对客户来说并不友好,比如奇奇怪怪的字段名客户看不懂,第二一些字典纸 比如isDelte:0 客户也看不懂,为了解决这些问题,我们可以根据swagger注解将英文字段名变为了中文字段名(没有配置swagger注解就还会保留英文字段名),并且接入了翻译服务,中间部分字段,比如外键,比如字典 都能看到其中文意思, 比如上面的 isDelete 我们会在transMap 这个map中包含一个key: 是否删除:否.客户能很容易看懂日志内容.
除了上述内容外,我们记录了数据的历史版本json,这样很容易能找到某个值是谁将其由A改为B的,张三修改这条数据修改了哪些内容(同上个版本比较字段值得出).
有了操作日志,我们还可以做数据分析,分析哪些人经常使用哪个模块,哪个模块的访问量最大等等.
- 给Easyui,Jquery Validform,My97做了整容手术
Easyui是一款颜值稍低但是功能强大上手容易开发效率极高的UI框架,为了让其能不被大家抛弃,继续让他发光发热,我们为其定制了一套BootStrap皮肤,效果堪比Layui。
- 使用Beetl标签技术对常见的表单控件做了封装
后台程序员有句俗话叫做后端10分钟,前端2小时。前端是很多人不愿意碰触的,于是有了很多公司一个项目要招聘2波人,后端专门写后端,前端专门写前段,但是命名一个人就能搞定的事情,非得要2个人?使用fhs的标签,所有的控件做到了统一化,不需要自己写js去初始化,去做校验,去赋值,只要使用了标签,标签中初始化,布局html,赋值,获取值,校验的js就都包含了,很大程度上降低了前端的学习和使用成本。
实例:
<%
include("/page/tags/form_include.html"){}
%>
<form id="addUpdateForm" method="post">
<#HideFormTag name='fatherMenuId' title='菜单名称' value='${parameter.parentId}' required='true'/>
<div class="fitem">
<#InputFormTag name='menuName' title='菜单名称' required='true' />
<#InputFormTag name='namespace' title='Namespace' required='true' />
</div>
<#BigInputFormTag name='menuUrl' title='链接地址' required='true' />
<div class="fitem">
<#WordBookFormTag name='isEnable' title='状态' code='is_enable' required='true' />
<#WordBookFormTag name='menuState' title='是否隐藏' code='yesOrNo' required='true' />
</div>
<div class="fitem">
<#SelectFormTag name='serverNameId' title='所在服务' url='${basePath}/ms/sett_ms_menu_server/findList' required='true' valueField= 'id'
textField= 'serverName' />
<#InputFormTag name='orderIndex' title='菜单序号' required='true' dataType="n"/>
</div>
<#BigInputFormTag name='image' placeholder="请将logo放到basics/images/menu下这里只写文件名" title='logo' />
<div class="fitem">
<#SelectFormTag name='systemId' title='子系统' url='${basePath}/ms/sett_ms_system/findList' required='true' valueField= 'id'
textField= 'name' />
<#WordBookFormTag name='menuType' title='菜单类型' code='menu_type' required='true' />
</div>
</form>
<script>
$(function () {
$('#isEnable').combobox('setValue',1);
$('#menuState').combobox('setValue',0);
})
function saveAfterSuccessHandler(){
document.getElementById('left').contentWindow.reloadData();
document.getElementById('rightFrame').contentWindow.reload();
}
</script>
<%
layout("/page/tags/add_update_tag.html",{'nameSpace':'sysMenu','idField':'menuId'}){}
%>
- 一款帮你写代码的引擎-PAGEX
使用市面上的代码生成器,你做一个CRUD的需要多久呢?如果加上Excel导出,校验,列点击排序这些功能呢?如果要加数据权限,分库,支持多租户呢?要写多少后台代码,写多少sql,写多少js和html?使用pagex,你只需要定义一个JS,你需要的java类框架在运行期(非生成到硬盘上噢)直接给你编译为class扔到classLoader了,Html JS SQL 后台接口 按照指定的路径请求引擎也帮你自动生成,而你无需担心JS被暴露,因为JS支持被PAGEX引擎加载当做配置文件用的,既然是配置文件为何选择JS呢?第一:JAVA有JS引擎,可以执行JS代码;第二:JS中有JSON格式,做配置比XML和YML方便,比Properties强大;第三:很多CRUD我们需要自己写一些JS方法,来控制一些插件的隐藏显示以及一些前端业务,把他们写到JS文件中总比写到XML中强很多倍吧。
PAGEX可以通过简单的配置自动生成CRUD代码,可实现导入,字段排序,数据权限,租户权限,字典翻译,表关联,各类表单插件一行json配置等功能,更让人惊喜的是,pagex的js可以通过Idea 的EasyCode插件自动生成,然后稍作改动就可以使用了。
下面是使用PAGEX引擎的一个我们项目中月租户管理的demo
var modelConfig= {title:'月租户类型',pkey:'id',type:'uuid',orderBy:'update_time Desc', namespace:"parking_lease_type",table:'t_park_lease_type',trans:true,db:"park"}; var listPage={ listFieldSett:function(){ return [ {name:'lease_name',title:'类型名称',width:'20%',align:'center'}, {name:'park_id',title:'停车场名称',width:'20%',isJoin:true,namespace:'parking',showField:'transMap.parkName',align:'center'},//自动表关联 {name:'is_disable',title:'是否禁用',width:'10%',formart:'formatRowColor',align:'center',trans:'book',key:'is_disable',showField:'transMap.is_disableName'},//字典翻译 {name:'create_user',title:'创建人',width:'8%',align:'center',trans:'user',showField:'transMap.create_userUserName'},//用户翻译 {name:'create_time',title:'创建时间',width:'10%',align:'center'}, {name:'update_user',title:'更新人',width:'8%',align:'center',trans:'user',showField:'transMap.create_userUserName'}, {name:'update_time',title:'更新时间',width:'10%',align:'center'}, {name:'is_sync',title:'是否已下发',width:'5%',align:'center',trans:'book',key:'yesOrNo',showField:'transMap.is_syncName'},//字典翻译 ]}, isColumnButton:function(){ return false; }, filters:function(){ return [ {name:'park_id',type:'select',url:'${path.basePath}/ms/x/parking/findListData', valuefield:'id',textfield:'parkName',title:'停车场'},//下拉插件 {name:'lease_name',type:'input',title:'出入口名称',filterType:'like'}, ]; }, buttons:function(){ return [ //自定义按钮数组 ]; }, disableButtons:function(){ return [];//禁用掉默认提供的按钮 默认提供了增删改查 + 导出 }, otherFunctions:function(){ return {}//其他的自定义方法 } }; var add={ formFields:function(){//表单内容 return [ {name:'park_id',type:'select',url:'${path.basePath}/ms/x/parking/findListData', valuefield:'id',textfield:'parkName',title:'停车场',required:true,},//一个下拉 {name:'lease_name',title:'名称',required:true,type:'input'},//一个input {name:'is_disable',title:'是否禁用',type:'switch',dft:false},//一个开关滑块 {name:'is_sync',title:'是否下发',type:'hide'},//一个隐藏域 ]; }, otherFunctions:function(){ return { ready:function(){ }, loadSuccess:function(info){//加载后台数据成功的事件 }, onSave:function(){//保存前执行方法 $('#isSync').val(0); }, saveSucess:function(){//保存成功执行方法 }, saveError:function(){//保存失败执行的方法 }, } } }
支持微信,支付宝 用户自动登陆接入。
支持分布式和单机2种模式.
工作流支持,在线任务支持,swagger文档,druid监控,服务器内存硬盘CPU监控.
新出炉的文档 https://gitee.com/fhs-opensource/fhs-framework/wikis/pages
官方QQ 群:976278956
体验地址:http://114.116.21.147:8081/ admin 123456
从dubbo转到springcloud,觉得springcloud家族组件很全,但是用起来稍微麻烦,每个api 都要写一个控制器来处理http请求 . 于是对相关代码进行抽象,使用统一控制器方法来处理请求,返回结果. 1 RPC接口定义 在定义接口的时候,url使用统一的开头 /api/*,将需要调用的类和方法标记到url中.比如 @RequestLine("GET /a
@Cached(name = "contractOrPdInfo",timeUnit = TimeUnit.HOURS,expire = 24) @CacheRefresh(refresh = 1,timeUnit = TimeUnit.HOURS) public ContractDetailVO findDetailByPdBaseIdAndContractBaseIdAndVer
Spring Framework 3.1.0 M2 Spring 3.1.0的第二个里程碑现已发布。 此发行版增加了对非标准JavaBeans设置程序注入,Servlet容器基于Servlet 3代码的配置以及Servlet 3 MultipartResolver的支持。 已验证@RequestBody方法参数,并且现在允许mvc:interceptor命名空间元素中的bean引用。 缓存抽象已进
Consider revisiting the entries above or defining a bean of type ‘org.springframework.data.redis.connection.RedisConnectionFactory’ in your configuration. Action: Consider revisiting the entries above
做SSH集成的时候,提示:找不到 org/springframework/dao/support/PersistenceExceptionTranslator,原来是缺少如果是3.2,就是:spring-tx-3.2.1.RELEASE.jar
在使用 SpringBoot 时不能自动注入 RestTemplate,具体报错信息如下 Field restTemplate in 'xxx' required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found. The injection point has the fol
移动互联快速开发平台 采用Mongodb为底层数据库:数据设计随需而变; 采用Mongodb集群,支撑大数据量,大并发实时查询,便于扩展; 采用SpringMongodb简化开发,简单得令人发指; 采用SpringRest提供JSON的输出,支持各种转换; 提供程序整合、兼容中文、跨域JSONP的支持; 进行了大数据量的压力测试,参数的最优配置; 各种最佳实践。 HTML5 快速开发的前端架构,专
一、安装 Maven Maven是一个项目构建和管理的工具,提供了帮助管理 构建、文档、报告、依赖、scms、发布、分发的方法。可以方便的编译代码、进行依赖管理、管理二进制库等等。 Maven的好处在于可以将项目过程规范化、自动化、高效化以及强大的可扩展,利用 Maven自身及其插件还可以获得代码检查报告、单元测试覆盖率、实现持续集成等等。 1. 下载 Maven http://maven.apa
本文向大家介绍基于javascript实现的快速排序,包括了基于javascript实现的快速排序的使用技巧和注意事项,需要的朋友参考一下 "妙味课堂"的一期视频教学。 主要原理是:快速排序的原理:找基准点、建立二个数组分别存储、递归 基准点:就是找到这个数组中间的一个数; 建立二个数组分别存储:就是以这个基准点,将它的左右数值,分别存放到两个定义的新数组当中; 递归:在函数内部调用自身;
前置技能 java基础 B/S应用开发经验 入门推荐学习路线 强烈要求,看本文档前,至少结合官方demo看过一遍pdf文档 官网:http://www.jfinal.com/ 手册:http://download.jfinal.com/upload/2.2/jfinal-2.2-manual.pdf IntelliJ IDEA开发环境搭建 前置条件 操作系统已经安装IntelliJ IDEA 14
本指南将解说如何构建并测试用于开发的 Ceph 。 开发 run-make-check.sh 脚本会安装 Ceph 依赖,一切都在调试模式下编译、并进行一系列测试,以验证结果正如所需。 $ ./run-make-check.sh 开发集群的部署 Ceph 包含一个名为 vstart.sh 的脚本(还有开发集群的部署),可以让开发者们在开发系统上用最简部署快速地测试代码。编译成功后,用下列命令开始部
4.1. 1、业务边界优化 创业公司有很多可变性,要做的系统也无数,如何保证业务系统的边界是非常难的,我们其实走了很多弯路,图-稍后补 4.2. 2、静态api理论 当需求和ue定下来之后,就开始编写静态api,这样app、h5、前端就可以使用静态api完成功能,而后端也可以以静态api为标准来实现,整体效率还是比较高的。 另外还有基于api生成http请求的思考(未完成) 4.3. 3、api约