HelloWord
最后更新于:2022-04-01 23:47:42
Hello Eova
> Easy Object View Admin
> 最简单的开发平台,没有之一
最简单的开发平台,没有之一
插入视频
~~~[youku]
XMzAyMTY4NjI1Mg
~~~
';
如何自定义数据源
最后更新于:2022-04-01 23:47:39
如下基于 eova-1.6-beta3
Eova中默认提供了两个数据源:
eova Eova专用库
main 默认数据源->默认的业务库
默认main数据源中提供了oss demo演示所需的一些表,如果开始做业务,可以将数据库切换成自己的业务库。
**PS:如果只有一个真实的业务库,直接将main从demo库切换到自己的业务库即可!**
如果业务库有多个,这时候需要新增除了eova,main之外的数据源!
~~~
/**
* 自定义Main数据源Model映射
*
* @param arp
*/
@Override
protected void mapping(HashMap arps) {
// 获取主数据源的ARP
// ActiveRecordPlugin main = arps.get(xx.DS_MAIN);
// 自定义业务Model映射往这里加
// main.addMapping("user_info", UserInfo.class);
// main.addMapping("users", Users.class);
// main.addMapping("address", Address.class);
// main.addMapping("orders", Orders.class);
// 获取其它数据源的ARP
// ActiveRecordPlugin xxx = arps.get("xxx");
}
~~~
jdbc.config 中添加oss 数据源的 jdbc配置
~~~
#事务级别(MYSQL=4,Oralce=2)
db.transaction_level = 4
#是否输出SQL日志
db.showsql = true
#数据库命名规则(是否全小写,建议:Mysql=true,Oracle=false)
db.islowercase = true
#数据源集
db.datasource = eova,main,oss
#Eova数据源
eova.url = jdbc:mysql://127.0.0.1:3306/eova?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
eova.user = root
eova.pwd = root
#默认数据源
main.url = jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
main.user = root
main.pwd = root
#其它数据源
oss.url = jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
oss.user = root
oss.pwd = root
~~~
';
常见问题
最后更新于:2022-04-01 23:47:37
[如何自定义数据源](%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/%E5%A6%82%E4%BD%95%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E6%BA%90.md)
[HelloWord](%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8/HelloWord.md)
';
关于JAVA8的支持
最后更新于:2022-04-01 23:47:35
我使用的Java8 [下载地址](http://www.cr173.com/soft/33894.html)
修改 pom.xml 中jdk的版本号
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d59bb1467f4bd885e28b14a2638d70e6_439x166.png)
Eclipse配置JRE 新增JDK8
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/fb1f55c3099663d4135c8151c1653596_695x209.png)
> 如果看了图还不知道细节的同学,请自行百度!
使用Maven重新构建项目(Eclipse中在你的项目上右键)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/145d37088c73cb9b1047dfa13e00c4ca_703x258.png)
构建成功之后
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/be05c54412e3eac661cc4935e6ab7ebf_228x164.png)
启动成功之后的日志输出如下:2018-02-06 22:20
~~~
Starting JFinal 3.3
Starting web server on port: 80
02-06 21:50:59[INFO]jetty-8.1.8.v20121106
02-06 21:50:59[INFO]NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet
02-06 21:50:59[INFO]started o.e.j.w.WebAppContext{/,file:/D:/yun/project/eova-oss/src/main/webapp/}
02-06 21:50:59[INFO]started o.e.j.w.WebAppContext{/,file:/D:/yun/project/eova-oss/src/main/webapp/}
Config Constants Starting...
02-06 21:50:59[INFO]app.config
02-06 21:50:59[INFO]domain.config
02-06 21:50:59[INFO]eova.config
02-06 21:50:59[INFO]jdbc.config
02-06 21:50:59[INFO]默认配置加载成功:(resources/default)
02-06 21:50:59[INFO]app.config
02-06 21:50:59[INFO]domain.config
02-06 21:50:59[INFO]eova.config
02-06 21:50:59[INFO]jdbc.config
02-06 21:50:59[INFO]开发配置覆盖成功:(resources/dev)
Config Plugins Starting...
02-06 21:50:59[INFO]load data source:jdbc:mysql://127.0.0.1:3306/eova?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull > root
02-06 21:50:59[INFO]load data source:jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull > root
02-06 21:51:00[INFO]{dataSource-1} inited
02-06 21:51:00[INFO]{dataSource-2} inited
Config Routes Starting...
Load Page Const Starting:
Config Interceptors Starting...
Config Handlers Starting...
JFinal Started
~~~
> 因为项目需要所以安装了Java8,然后各种没毛病就可以直接跑起来了,如果改版本号和给Eclipse设置JRE算一种毛病!
> 在此之前,有很多同学问我是否支持Java8,因为我没试过所以我不知道,但是按Java一贯向下兼容的原则应该是没毛病的.
> (实际上早就有很多同学已经自己在Java8下玩了很多年Eova了)
> 所以今天特此现身说法,Eova可以基于Java8运行.
另外因为目前Java7是使用最广的JDK版本,但是已经有趋势,业界在慢慢普及Java8,所以小伙伴们先自便,Eova随后会跟上主流.
让我们一起期待Java9,展望Java10,幻想Java11...
';
关于分布式的支持
最后更新于:2022-04-01 23:47:33
集群之后Session问题4种解法
1.Session Sticky
2.Session Replication
3.Session数据集中储存
4.Cookie Based
1&2 省事 不用动代码
3 使用广泛
根据各团队 情况 自己选择 最合适的方案
具体 操作细节 自行百度一下
<<大型网站系统与Java中间件实践>> 一书中 有详细解说
* * * * *
Eova如何拓展成分布式Session
OSSController extends IndexController
@Override
public void doLogin() {
...省略....
setSessionAttr(EovaConst.USER, user); // 改成使用分布式Session 存用户登录对象
...省略....
LoginInterceptor
@Override
public void intercept(Invocation inv) {
...省略....
// 获取登录用户的角色
User user = inv.getController().getSessionAttr(EovaConst.USER); // 改成从分布式会话中读取
...省略....
* * * * *
后续版本中,会默认提供分布式的支持,即 使用分布式缓存实现session!
在默认未提供之前大家可以使用 上文提到的 1,2,4 方案,或自行实现.
如无技术能力进行相关开发的,可以联系Eova作者进行有偿私人定制开发!
QQ:1623736450 非VIP用户勿扰!
';
关于版本号
最后更新于:2022-04-01 23:47:30
举例:1.6.1-beta1
解释:大版本号.中版本号.小版本号-第一个公测版
**版本类型解释**
SNAPSHOT:封测版本,仅供小范围测试,不建议用于生产.
alpha:内测版本,仅供测试,不建议用于生产.
beta:公测版本,基本已经稳定
无后缀:相对稳定版
**大版本号.中版本号.小版本号**
大版本号:所有内容都需要升级(db + eova-oss + eova.jar) *重大重构或加入新功能*
中版本号:数据库无需升级(eova-oss + eova.jar) *小幅度功能调整*
小版本号:仅eova-oss需要更新 *优化和BUG修复*
特别版:单独提供更新升级说明
**如何升级 eova.jar (核心包)**
修改 pom.xml 中 eova 版本号 到指定版本
新的版本号
> 然后使用Maven重新构建工程
> 如果有侵入源码修改功能,请自行使用对比工具进行相关源码的手工升级
**如何升级 eova-oss (前端页面)**
1.新项目:下载并使用最新版本
2.老项目:下载最新版,复制`src\main\webapp\eova`目录覆盖到老项目
**如何升级 数据库**
1.新项目:使用最新的脚本建库(如果有全量脚本)
2.老项目:在上一个版本库中执行增量脚本(如果有增量脚本)
> 增量脚本适用于小版本更新
> 比如 1.6-beta1~4 DB未变更
> 1.6-beta5 提供了增量脚本,这时候只需要在已有库中执行增量脚本
> 一般增量脚本会放在根目录或者sql目录中醒目的地方
> 重新运行项目时必须清理浏览器全部缓存!
**历史旧版跨大版本升级**
[V1.5->V1.6 ](http://note.youdao.com/noteshare?id=86ab45904567825d4505e35dc29f5441&sub=70BC1C7037EB4F7DB0EA0CCBF8DC56F7)
[V1.4->V1.5](http://note.youdao.com/noteshare?id=b2f51fda68894e36a4ec33f8dfd1e100&sub=3CEB489395AC49C1AAD5B2022C90C051)
友情提示:
软件是一个持续迭代的过程,新版本相对肯定比旧版本要好.
如果想获得最好最新的版本请[成为VIP用户](http://www.eova.cn/help)
以便第一时间获取更新和最新补丁.
';
关于独立部署
最后更新于:2022-04-01 23:47:28
槽点:
Eova工程必须部署在/webapps/ROOT 目录中
可能带来的问题:
1.ROOT目录已经被其它项目占领,比如被主站使用.
2.服务器资源紧张,没有额外资源来单独部署.
3.没有权限,比如有关部门牛逼轰轰需求方的运维只给一个子目录权限.
4.还在使用传统IDC的Java虚拟主机,只有一个子目录
可能存在问题的场景/人群:
1.有关部门内部项目,因为是边缘项目不受重视,所以随便给个资源,开发者很被动没有话语权.
2.自学练习项目,因为老师上课演示的都是图方便,直接一个子目录一个项目,已经思维固化,对于新事物都是拒绝的,总觉得自己习惯的那种方式就是最好的.
3.其它传统开发者,因为历史习惯和历史原因以及其它各种不为人知的原因就想在子目录里部署.
部署目录问题的本质:
~~~
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
~~~
如上是我们曾经都写过的获取basePath的代码,在每个获取URL的地方都需要手工加上basePath,应该有很多人都因为忘记加或者写错加错的情况出现.
JFinal的理念->极速开发
Eova的理念->简单开发
JFinal默认提供的Demo访问的URL都是 http://127.0.0.1
同理Eova也推荐采用同样的方案.
不知不觉就没有了上面需要手工关注basePath的情况.
其它开发者怎么看?下面是CSDN某开发者发表的博文:
> 一个tomcat部署一个应用,我自己体会到的好处是在html中一些静态文件获取的时候不需要考虑相对路径或者绝对路径都以/开头就行。
实例独立部署除了能简化basePath的问题,还有什么好处?
项目隔离
多项目之间会互相影响,比如其中某工程出现了内存溢出会直接导致整个容器JVM被占满,而宕机,一损俱损.
负载均衡
敢把一堆项目部署在一个容器中,这些项目几乎都是边缘项目没什么流量,也没什么人关注.
例:tomcat默认不优化情况并发大约200+,均摊到每个项目可能就几十个,一般的项目也不做动静分离,服务+静态,每个项目都有10来个人就可能把系统点挂.
日志分离
多个项目在一个容器中,各项目的日志会互相刷屏,不方便进行线上问题追踪和排查.
在互联网+的时代,在微服务流行的今天,大家都在想办法拆分项目,拆分业务,拆分服务.
如果你还在因为部署多个实例而烦恼,是不是有点跟不上前进的节奏了.
你什么时候才能体验到持续集成 持续发布 Docker 这些技术.
当然,凡是没有绝对,如果有机智的人能想到不依赖第三方库,并且在不侵入现有代码的情况下可以一次性解决basepath的问题,那也是喜闻乐见的事.
好吧,如果你遇到了非人的待遇,急需解决这个问题,可参考:
https://www.oschina.net/question/1174006_137158
* * * * *
原始需求如下:
先有3个项目,分别为 PC站,手机站,后台
最简单的方式就是将这个3个项目部署到一个Tomcat下,然后通过子目录分别访问.
本地访问方式
~~~
http://localhost/web
http://localhost/wap
http://localhost/oss
~~~
外网访问方式,假设域名是`qq.com` 且tomcat(端口为:80)
~~~
http://qq.com/web
http://qq.com/wap
http://qq.com/oss
~~~
> 假如腾讯的应用都让你这么访问你咋想?
> 显然这种方式极不靠谱.
> 项目本身是3个独立的项目
那么我们换一种部署方式,3个项目分别部署到3个tomcat中
~~~
http://qq.com:8001
http://qq.com:8002
http://qq.com:8003
~~~
> 然而还是很奇葩,用户还得去记你的端口号,显然也不靠谱.
> 所以只有如下方式才是大家常用且体验良好的.
~~~
http://www.qq.com
http://m.qq.com
http://oss.qq.com
~~~
通过Nginx的反向代理我们可以做到这样的效果:
~~~
www.qq.com -> localhost:8001
m.qq.com -> localhost:8002
oss.qq.com -> localhost:8003
~~~
核心主要配置如下:(仅供参考,安装使用和配置请自行系统学习)
~~~
upstream web {
server localhost:8001;
}
upstream wap {
server localhost:8002;
}
upstream oss {
server localhost:8003;
}
server {
listen 80;
server_name www.qq.com qq.com;
location / {
proxy_pass http://web;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name m.qq.com;
location / {
proxy_pass http://wap;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name oss.qq.com;
location / {
proxy_pass http://oss;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
~~~
> 将上述配置保存为 vhost.conf
> 然后在nginx.conf 最后 include vhost.conf;
**相关资料**
[Nginx中文文档](http://www.nginx.cn/doc/index.html)
[安装Nginx](http://www.nginx.cn/install)
[Nginx基本配置与参数说明](http://www.nginx.cn/76.html)
[反向代理](http://www.nginx.cn/927.html)
';
关于Oracle
最后更新于:2022-04-01 23:47:26
**Oracle自增长的处理:**
众所周知,Oracle没有自增概念,需要创建一个sequence,然后获得唯一ID。
Eova的处理:
**1.自动指定约定Sequence**
规则:seq_表名.nextval
```
public class EovaDbPro extends DbPro {
public EovaDbPro(String configName) {
super(configName);
}
@Override
public boolean save(String tableName, String primaryKey, Record record) {
// Oracle && 单主键 && 主键没值 -> 指定Sequence
if (xx.isOracle() && !primaryKey.contains(",") && record.get(primaryKey) == null) {
record.set(primaryKey, EovaConst.SEQ_ + tableName + ".nextval");
}
return super.save(tableName, primaryKey, record);
}
}
```
使用默认Seq举例:
Sql: insert into eova_log(id, user_id, type, info, ip) values(seq_eova_log.nextval, ?, ?, ?, ?)
**2.通过默认值自定义:**
**2.1 自定义Sequence**
如果不想让系统指定固定Sequence
想自定义或者共用Sequence
可以使用默认值自行指定.
自定义Seq举例:
create sequence seq_eova_user increment by 1 start with 21 maxvalue 9999999999;
PS:这里对名字没有约束,sequence 可以随意取名,例如:my_seq_id
自行创建任意名字的sequence,然后通过 eova_field.defaulter 指定
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d51941fad10bd13e8e0facbee59d7284_922x292.png)
Sql: insert into eova_user(login_id, id, rid, nickname, login_pwd) values(?, seq_eova_user.nextval, ?, ?, ?)
**2.2 默认ID值**
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/279c71e3b650cf621d4564213047497c_915x280.png)
新增后:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d857b419a6c9391b0ee899d5d9b96c41_578x159.png)
**2.3 生成全局唯一ID**
默认值填写 UUID即可
UUID规则:32位无去中划线全大写
```
UUID.randomUUID().toString().replaceAll("-", "").toUpperCase()
```
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/9ac08bf6e0462cbf4ee48864be1fe5f5_295x313.png)
> 注意设置字段新增/更新状态=隐藏
**Other:**
Eova提供了由Mysql自动生成Oracle脚本的工具类:
DbUtil.createOracleSql();
使用方法:
连接到Mysql数据源上:
eova.config 配置:
initSql = true
系统启动时会将Sql脚本输出在控制台,复制执行即可!
';
关于工作流引擎
最后更新于:2022-04-01 23:47:24
**关于工作流的需求基本上可以归纳为两种**
1. 简单的工作流需求:来自各种互联网项目的后台管理系统
各种互联网业务流程,常见各种流程审批...
3. 复杂的工作流需求:来自各种重量级的信息系统,ERP等
流程未知,由用户来创建流程,其它复杂的拓展和定制。
先说复杂的需求,这种目前市面上的解决方案有Activiti/JBPM等,这块比较复杂,有需要可以自己做集成,EOVA的定位是简单,默认并不会集成这些重量级的工作流引擎,因为集成之后会使整个平台更复杂。
虽然默认不集成重量级的引擎,但是一些简单的工作流需求,咱们肯定得提供一定层度的支持。
*所以EOVA在后续的版本中,会利用平台本身的优点,创造轻量级的工作流解决方案。*
* * * * *
**在目前的版本中(V1.5+),可以这样去实现业务流程:**
例如:经典的 订单流程
* 仓库大妈 负责打包 完了选单子 按一下打包完成,进入一下个环节
* 核对大妈 负责核对 完了选单子 按一下核对完成,进入一下个环节
* 发货大叔 负责装车 完了选单子 按一下开始派送,进入一下个环节
* 购买用户 收到快递了 点一下 已收货,流程结束!
假设订单有3种状态
`已支付=1 已发货=2 已归档=3`
新增3个菜单
* * * * *
已支付订单 `eova_menu.fitler='status = 1'`
新增自定义按钮 开发发货 status -> 2
* * * * *
已发货订单 `eova_menu.fitler='status = 2'`
新增自定义按钮 归档 status -> 3
* * * * *
已归档订单 `eova_menu.fitler='status = 3'`
* * * * *
诸如此类的常规业务流程,这样实现基本能够满足使用!
我相信 不是每个人 都是接的ERP的活吧,上来就整工作流引擎 有意思吗 累不累?
一般也就定义3-5 流程 算吊炸天的需求了 有闲工夫 集成Activity,用Eova 早就交货 去外国 旅游去了!
熟练使用第三方工作流的复杂度不比用Eova直接做简单。
所以很多用户 进群 就问 支持工作流引擎不,真心不好回答这个问题,说不支持把,他想什么垃圾玩意,工作流都没有,说支持吧,你真的用的上,你真的会用?
**PS:Eova后续会提供基于Eova的轻量级业务流程引擎,让你快速搞定常规业务流程!**
';
关于浏览器兼容性
最后更新于:2022-04-01 23:47:21
在关于UI里已经介绍了在EOVA启动之初就打算使用GWT,目的就是全平台兼容。
可惜事与愿违,GWT学习和使用成本太高。
目前市场上可以完美全平台兼容的UI(包括IE6)只了解到两家EXTJS和DHTMLX。
但是很遗憾都是商业授权,对开源不友好。
所以一切的一切都回归的原点,成本、成本、成本!全平台兼容是需要付出代价的。
所以这里只能折中一下,兼容现代浏览器。老的浏览器IE6,IE8迟早会死在沙滩上,一个已经知道会淘汰的东西,我们就没必要去浪费无谓的功夫了,这里只能对做政企客户的开发者表示遗憾了。
兼容就是纵容:http://www.iefans.net/dibanben-ie-jianrongxing-wenti-tuoxie/
成本对比:
Baidu一年的研发费用¥70,0000,0000.0
EOVA一年的研发费用¥0.0
所以实际上Eova无法保证兼容所有浏览器,只能在效果和成本取中间值。
Chrome已经是最流行的浏览器了,市场份额持续上涨,而采用Webkit(Blink)内核的浏览器多不胜数,所以Eova会主要兼容webkit内核。国内知名的有,360,QQ,猎豹...,基本上能覆盖大部分用户了。
**惊喜:虽然Eova不保证能兼容webkit以外的浏览器,但是实际用户测试下来,在Firefox和高版本IE(10+)都能玩起来,几乎没什么问题,不推荐不代表不能玩,但是有问题需要自己解决一下!**
当然咯,有用户会说,我觉得Eova非常好,我很想用,但是我的客户是大爷(xx局的),非要用IE6什么的。
俗话说的好,有钱能使鬼推磨,可以定制专版,只要是钱能解决的问题都不是问题!好嘛,又回到了刚才的问题,效果和成本!
花巨资做定制版和说服大爷使用高级浏览器,自己权衡一下!想用简单免费的东西伺候好大爷,估计难咯!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/72780140daa405707886bf99a4470621_720x708.png)
Chrome 份额持续上涨中,随着Win10普及,IE6-8 会永久的退出历史的舞台.
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2b59c22f7216cc4fd9aa5660cb5a7d08_715x390.png)
';
关于UI
最后更新于:2022-04-01 23:47:19
**如果你爱一个人会在乎她的外表吗?
如果爱了就不会,如果在乎外表开始就没爱了!**
很多用户在第一次见到EOVA的时候都吐槽EOVA太丑了,不忍直视!
**我们先看一下大家都是怎么喷的!**
> leavegee:把UI换成amazeui吧.直接变成高大上项目
> 大东家:UI没有吸引力,希望楼主努力一把,用上现代的后台
> 道童:easyui的界面呀,丑到爆,用妹纸UI,或者Bootstrap高大上一万倍,看了UI就没兴趣了
> Rua:UI真的丑哭啊,大神快更新下UI吧,框架挺实用的,就是UI太丑,占时先等等。。。
听大家喷完,总结下来就是一句话 ,EasyUI太LOW了,已经过时了,OUT了!
* * * * *
这里先给大家介绍一下EOVA的UI框架的选型历程:
**选择GWT**
项目启动前看中了GWT,前后端Java通吃,组件强大(Google基于EXT的封装),全平台兼容
最后研究了2个月发现学习成本太高,太复杂,不合适。
站在Java服务端的角度来看,好的UI框架,应该是基于JS/JQuery,不需要额外学习新技能。
如下是GWT版本风格:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/22dfa87cf7d6f9afd3685b77b02076b6_354x408.png)
**选择DWZ**
开源中国当初最火爆UI,富客户端UI中颜值爆表的UI。
可惜用到一半,发现有很多缺陷,并且项目基本不怎么更新了,无奈放弃。
所以只能另寻他路了,找了一圈发现国产LigerUI做的不错。
如下是DWZ版本风格:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/a2342d0a7045a03c31e7c9d9d5a6fb5a_951x470.png)
**选择LigerUI:**
组件丰富,也有很多用户,中文文档。
实际使用中遇到了很多坑,无法满足需求。
在经过几个项目的实践之后,也只能继续寻找新的路子,这样一圈下来,新的选择已经不多了。
没有办法只能将视线重新转移到经典的EasyUI上。
**为什么去尝试EasyUI?**
在做EOVA之前,没有深入的用过EasyUI,对他的认知完全来自于网文或者其它开发者,对他的印象就是经典,在国内被众多公司和个人使用。并且从UI风格上看,国内很多UI都是参考EasyUI来的,然后EasyUI应该也是参考 Ext来的。
EXT是后台UI框架中的王者,无人出其左右。但是最大的优点就是最大的缺点,牛逼过头了,太重了,另外也需要额外学习ExtJS语法,所以很多开发者并不感冒这种方式,并且最新的版本都是纯商业的,无法应用于开源,综上所述,在没有选择的情况下,只能开始尝试EasyUI。
这里要解释一下,很多人关注的问题,我大Bootstrap(妹子UI/ACE...)呢?
个人认为Bootstrap非常棒,但是这种风格的UI比较适合做前台业务,不太适合复杂的后台系统,比如EOVA社区就是使用了类Bootstrap风格的框架来做的,效果还不错。
Bootstrap阵营的简称BS风格。
EXT阵营的简称EXT风格。
原因如下:
1.占地面积
BS的UI控件比较肥,占地面积比较大,而后台业务复杂,界面需要呈现很多的 Grid/Form,如果UI比较肥大就不太和谐了。
2.功能性
BS的UI比较注重UI效果,并且BS出来的时间还不长(相比EXT而言),所以组件都是一些比较基础简单的功能,一些比较复杂的就得自己实现了。
因为上述原因,所以尝试了EasyUI,总体效果还不错,就是大家现在看到的EOVA版本UI效果。
目前也有很多BS风格的UI做的越来越好了比如H-UI,ElementUI等。我相信BS肯定会越做越好,统一新时代,但至少目前还不够!比如N多人吹捧的MZUI,在用之前我也挺看好的,还给很多开发者推荐过,但是,在公司的某互联网产品项目上马实践之后,上至CTO,下至前端开发,中至产品经理,从此妹子是路人,无人再提,原因就不细说了,第一次不用是我的错,第二次不用...
**为什么又放弃EasyUI?**
1.丑哭,被喷成狗了,嗯,的确老掉牙了,不符合这个时代了,有点格格不入的感觉。
2.闭源,商业授权,复杂,高级功能不方便拓展。
3.不思进取,10多年了还是老样子,没有实质性的改变和更新,无法与时俱进。
就像很多小说里写的,别人创造的功法,始终是别人创造的,无法和自身高度契合,当修炼到一定境界之后就得自创功法了。
同样EOVA作为一个平台级别的项目,面向的是很多业务领域,所以对UI框架的要求和可定制性非常高,还要对开源友好。
所以没办法,只能重新造轮子了,别人的轮子跟不上节奏了。
虽然是重新造轮子,但是总得体现出造轮子的价值。
1.JS需要是OOP的,面向Java服务端开发者,方便上手。
2.API需要是简单的,不需要花太多精力去重新学习一套API接口。
3.量身定制的UI肯定是和EOVA业务完美契合的并且是可控的,并且是开源的。
所以最终会根据需求,慢慢积累成EovaUI。
> EOVA V2.0 开始会使用全新的UI风格,所以在此之前会稳定目前的经典版本!
> 因为可能新的UI或者风格会有一大波人不适应,所以。。。。
> 可能很多人关心新的UI长什么样?
> 新的UI既不是EasyUI,又不是Bootstrap,但是又比EasyUI高端很多,并且还是大家经常使用的!
biu biu biu... 专业版已经横空出世了 ! (专业版体验通道,QQ:1623736450)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/a8db084560d92d5a75c3421d012fdff6_1391x845.png)
EOVA专业版UI的主要成分:
1.EovaUI.Form 30%
2.EovaUI.Layout 30%
3.Layui.table 优化版 10%
4.Layui.layer 优化版 5%
5.Layui.Style 兼容版 5%
6.Ztree 美化版 5%
7.My97Date 美化版 5%
8.Other Plugins10%
';
关于源码
最后更新于:2022-04-01 23:47:17
普通用户从Maven或Git下载**公测版**源码:
http://mvnrepository.com/artifact/cn.eova/eova
VIP用户加入VIP群获得**封测版/内测版**源码和**补丁**:
[我要成为VIP](http://www.eova.cn.help)
捐赠500,私聊作者加群!
VIP用户的福利
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/bff5379b6d408031159f92d6092b150c_823x397.png)
';
特别解释
最后更新于:2022-04-01 23:47:15
[关于源码](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8E%E6%BA%90%E7%A0%81.md)
[关于UI](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8EUI.md)
[关于浏览器兼容性](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8E%E6%B5%8F%E8%A7%88%E5%99%A8%E5%85%BC%E5%AE%B9%E6%80%A7.md)
[关于工作流引擎](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8E%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%BC%95%E6%93%8E.md)
[关于Oracle](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8EOracle.md)
[关于独立部署](%E5%85%B3%E4%BA%8E%E7%8B%AC%E7%AB%8B%E9%83%A8%E7%BD%B2.md)
[关于版本号](%E5%85%B3%E4%BA%8E%E7%89%88%E6%9C%AC%E5%8F%B7.md)
[关于分布式的支持](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8E%E5%88%86%E5%B8%83%E5%BC%8F%E7%9A%84%E6%94%AF%E6%8C%81.md)
[关于JAVA8的支持](%E7%89%B9%E5%88%AB%E8%A7%A3%E9%87%8A/%E5%85%B3%E4%BA%8EJAVA8%E7%9A%84%E6%94%AF%E6%8C%81.md)
';
影子操控术の全局控制
最后更新于:2022-04-01 23:47:12
> ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/90c565cb7b7a6a822148857166011b57_277x211.png)
> 影子操控术可以同时控制多个敌对目标,控制目标后可以对目标做出各种指令.
在Eova的世界里是否也能拥有这样一种掌控全局的能力
是否能一次性搞定数据过滤,是否能一次性搞定各种字段的初始化赋值等.
#### 需求背景
1)复杂的业务系统,严谨的业务系统都有很多角色,很多数据,需要根据不同的业务进行角色和数据的权限过滤.
2)写了很多业务拦截器,每个业务拦截器里代码都差不多,都是干那几件事.
#### 功能解读
~~~
/**
* 全局Eova业务拦截器
* @author Jieven
*
*/
public class GlobalEovaIntercept extends EovaIntercept {
// -- > 命中 Grid,Tree,TreeGrid的查询,导出功能
@Override
public String filterQuery(EovaContext ec) throws Exception {
System.out.println("Query过滤");
// 可以通过元数据进行各种判定
// if (!ec.object.getCode().startsWith("eova_")) {
// return " and id < 999999 or id = 10086";
// }
return "";
}
// -- > 命中Find,Combo,ComboTree 的表达式条件过滤
@Override
public String filterExp(EovaContext ec) throws Exception {
System.out.println("Exp过滤");
// return " and id < 9999";
return "";
}
}
~~~
~~~
/**
* 公共元对象业务拦截器
*
';
* 使用场景: * 全局业务 例:增删改查日志记录 * 高频字段统一处理 例:create_time update_time ... * 其它更多高端玩法,请尽情的发挥想象吧! ** * @author Jieven * */ public class BaseMetaObjectIntercept extends MetaObjectIntercept { @Override public String updateBefore(AopContext ac) throws Exception { System.out.println("公共元对象业务拦截器"); for (MetaField f : ac.object.getFields()) { if (f.getEn().equals("update_time")) { ac.record.set("update_time", new Date()); } if (f.getEn().equals("user_id")) { ac.record.set("user_id", ac.user.getInt("id")); } } return null; } } ~~~ #### 如何配置? ~~~ // OSSConfig.java @Override public void configEova() { /* * 自定义Eova全局拦截器 * 全局的查询拦截,可快速集中解决系统的查询数据权限,严谨,高效! */ setEovaIntercept(new GlobalEovaIntercept()); /* * 默认元对象业务拦截器:未配置元对象业务拦截器会默认命中此拦截器 * 自定义元对象拦截器时自行考虑是否需要继承默认拦截器 */ setDefaultMetaObjectIntercept(new BaseMetaObjectIntercept()); } ~~~ #### 如何使用? 主要讲思路,不讲具体使用,大家请发挥自己的小宇宙想象,用好了绝对能省很多事. 1. 主要是提供一种全局掌控的能力 2. 可以做公共的逻辑 3. 可以做特征匹配 4. 可以简化冗余代码 5. 增强后续可维护性 6. 可以更专一的关注一个视角 7. 一次严谨的思考,全局受益 本技能将会在后续的项目实战视频教程中结合实际业务详细讲解,有兴趣可提前成为VIP用户,避免错过 [立即站队成为VIP](http://www.eova.cn/help)
象转之术の在线Office
最后更新于:2022-04-01 23:47:10
> ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/89366aace4fdbfba35b6366a369b462d_361x262.png)
> 象转之术为轮回眼所拥有的忍术之一。发动后可使其他人得到与特定人物相同的相貌并可使用特定人物会的一切术(包括血继限界),但只有本体所有能力的三成,行动受本体控制,永远失去自我意识,查克拉用完后,受控体死亡,死后恢复原貌。
**Version:V1.6 Beta2 新增技能**
本技能用于解决Office这个众所周知的老大难问题.
通常小伙伴们手工编码的时候,实现office报表都是,看起来很简单,实际实现起来复杂!如果数据和展现复杂更是令人崩溃.
常见痛点:
1.使用POI手工开发时,都是手工凑单元格,凑格式,很难和原始需求文档保持一致.
2.如果字段成百上千,工作量不说,操作起来很崩溃.
3.使用IReport或者其它设计器,需要学习成本,没弄过的小伙伴第一次也是崩溃的.
* * * * *
那么一切从简的Eova会如何解决这一领域的问题,让我们继续一起愉快的玩耍.对复杂Say No!
亮点:
1.代码量极少,快速实现复杂自定义报表
2.在线预览,在线打印,在线下载 三剑合并
3.多快好省,自行体会..
缺点:
1.可能不支持低版本Office,对WPS更友好(全程基于WPS进行测试)
2.数据太多会卡死,具体支持多少,自行测试.
* * * * *
如果你的需求复合上述条件,那么恭喜你,你即将高潮!
**Excel Demo: 高新园评分表**
需求背景:自行脑补,可支持如下图的效果,即可支持更复杂的表格.
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/737338560e3f265f0459cfaf7d6ef730_498x318.png)
第一步:准备Excel模版
1.使用WPS将`高新园评分表.xls`另存为`高新园评分表.html` [下载WPS](http://www.wps.cn)
> Excel文件中只能存在一个Sheet页,如果有多个则会生成一个目录,请拆分成单个后进行
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/93e72971e7088e369369e2b30073e63e_716x174.png)
2.然后将希望动态输出的内容替换成变量(和套JSP页面一个套路) [下载Dreamweaver](http://www.xiazaiba.com/html/127.html)
> 请勿直接在WPS或Office软件中进行,插入的模版语法,保存时会被格式化掉
> 可以使用Dreamweaver(以网页预览方式编辑更方便)
> 注意编码哦,默认转出来的模版都是GB2312,如果要搞成UTF-8 Dreamweaver支持转码(在打开html文件上右键->属性->编码)
> 要点:将字符串换成变量,然后不能动其它字符串,也要保证编码准确.
模版编辑好的效果如下所示(目前还是Beetl模版语法)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/fb2775746b80eda73f9af135f591f3aa_638x494.png)
第二步:新增菜单
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/eb22d21f84660b84ec3c400db94129ff_914x198.png)
如上图所示在Eova中配置菜单即可.
模版路径是Excel转html模版文件存放的位置.
第三步:编写Office拦截器
详细代码在eova-oss工程中查看
~~~
/**
* Office Excel Demo
* @author Jieven
*
*/
public class Xls1Intercept extends OfficeIntercept {
@Override
public void init(Controller ctrl, HashMap data) throws Exception {
// 获取业务数据
// 数据整理
// 把数据put到data 即可,和常规页面开发丢到Attribute作用域一样
data.put("x", x);
// Excel html 模版 取值使用 ${x.name} ${x.xxx}
}
}
~~~
第三步:菜单配置业务拦截器
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/14d23382939bf59ff3ae23c1cd1a2631_945x137.png)
> 如果模版已经确定
> 如果查询数据SQL已经确定
> 实现一个自定义报表应该5分钟可以搞定!
**Word Demo: 高新园检查表**
需求背景:自行脑补,可支持如下图的效果,即可支持更复杂的表格.
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/886c9b3a597562336a13cbdd722fada9_688x541.png)
套路同Excel配置,新增菜单时Office 文件类型选 Excel即可
PS:PDF后续版本提供!
**如果弄PDF仅仅只是为了不让别人编辑,可以直接使用Word然后设置禁止编辑.**
WPS和Office均可设置限制编辑
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/a59eebd25e4b5ca7feb6d6565c913ffe_266x158.png)
';
四象封印の数据过滤
最后更新于:2022-04-01 23:47:08
> ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/309b1a427717fdc1d620269049d178d2_258x276.png)
> 四象封印:用于封锁列数据或行数据,是利用数据过滤来封锁不想让别人看见的数据!
#### 需求背景
需求背景:列数据过滤
只有财务角色才可以看见订单金额字段,其它角色看其它字段信息.
需求背景:行数据过滤
上海总代理角色只能查看上海地区的数据
前置技能:元对象和菜单均可配置过滤条件
#### 行数据过滤条件举例
~~~
<%if(user.me.region != 0){%>
region = ${user.me.region}
<%}else if(user.me.city != 0){%>
city = ${user.me.city}
<%}else if(user.me.province != 0){%>
province = ${user.me.province}
<%}%>
~~~
解释:
user=eova.eova_user表
me=demo.member表 在登录时将member对象set到User对象上
region,city,province=省市区ID
效果解读:
省长看全省数据,市长看全市数据,区长看全区数据
> PS:角色判定直接使用 user.rid
#### 列数据按角色授权: 1.6-beta1 开始支持
OSSConfig override EovaConfig.authField()
~~~
@Override
protected void authField() {
super.authField();
//添加字段授权规则
//语法:元对象编码.元字段英文名->允许查看的角色1ID,角色2ID
addAuthField("orders.money->1,2");
}
~~~
> 同理,也可以用配置文件或DB进行管理,甚至可做成功能,根据需要进一步封装和扩展
';
六赤阳阵の多表级联
最后更新于:2022-04-01 23:47:05
> ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/c0fdbde29db035f09a04fc1b1eb07a93_673x320.png)
> 六赤阳阵-已知最强的结界术,但此术范围远大于四赤阳阵。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d3e16d08bca0c25da2e5183e40cfbf21_346x245.png)
实例:功能演示>酒店管理(主子)
Eova提供了如上图所示的主子模版可用于解决主子关系(仅支持1VN的主子关系)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/83b10372d13ea02ea1a3197fbfa77085_570x162.png)
实例:功能演示>酒店管理(关联)
但是实际业务系统,尤其是较为复杂的业务系统,往往各个业务功能之间都存在互相的关联关系,如上图所示.
例如:
主子孙: 用户 > 角色 > 权限
主子孙孙
主子多孙
主多子多孙
......复杂的需求有很多
实际复杂需求举例:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d70bfb0f5ad7c4841249a0a96cc633ae_950x600.png)
> 这种功能看着就有点头皮发麻的感觉,一个界面上9个表格,一路级联下来
> 如果你的需求场景就是这样,并且客户或者需求要求这样,那么这种功能建议你手工自定义开发(Grid用Eova组件一句话构建)
但是实际开发中,不应该是所有功能都是这样,极少数才会弄成这样,并且都是因为不得已的原因.
下面就给大家介绍在Eova中如何搞定复杂的多表业务关联.
权衡考虑:
1.开发量少
2.保持业务关系
3.体验不能太差
前置技能:[色诱术の格式化单元格](http://www.kancloud.cn/jieven/eova/217121)
思路:利用格式化单元格将关联字段进行格式化,建立点击事件,点击之后跳入级联目标界面.
效果如下图所示:
主表
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/cd927ad4ed1e72dad015b45143f40c67_1144x240.png)
关联子表
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/5e8adf918a02aaa3b2965a160138e90a_495x210.png)
格式化关联的代码实现:
格式化-链接
~~~
function(value, row, index, field) {
return '' + value + ''
}
~~~
格式化-新开关联页面 to 浏览器Tab
~~~
function(value, row, index, field) {
return '' + value + '';
}
~~~
格式化-新开关联页面 to Eova Tab
~~~
function(value, row, index, field) {
var url = '/single_grid/list/biz_demo_hotel_stock?query_hotel_id=' + row.id;
return '' + value + '';
}
~~~
> 关联功能链接分解:
> 目标功能列表URL:
> /single_grid/list/biz_demo_hotel_stock
> 级联条件参数:
> ?query_xxx字段名=条件值&query_xxx字段名=条件值
> 同理可支持主子表的多字段关联
PS:JS是万能的,只有你想不到的,没有你做不到的!大胆猜测,小心验证!
* * * * *
后续的故事:
在上面我们已经实现了不同功能界面之间的级联
那如何讲当前列表页的参数继续传递给Form编辑页,固定某些关联字段的值.
推荐方案:
自定义按钮,参考主子的参数传递.
主子模版是硬编码直接获取父Grid选中Row的关键字段值
这里的区别是从URL上获取指定的关联字段值.
~~~
自定义子表新增,自动获取主的某字段
~~~
> 当然这里需要考虑兼容默认列表的按钮操作和级联过来的按钮操作,如果有参则自动传递,否则走默认情况!
';
四赤阳阵の多表视图
最后更新于:2022-04-01 23:47:03
[TOC=3]
> ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d378f9e8f9b184b4bea76a622179de9f_341x201.png)
> 四赤阳阵是一种结界忍术,比“四紫炎阵”强上数十倍,必须要四位影级人物同时发动。
视图和四赤阳阵非常像,一般视图由多个表组成一个整体进行展示。
### 数据库View的概念
* 传统DB视图,主要用于多表内容聚合展示,不支持直接基于视图进行新增和修改。
* 视图的主要作用是聚合查询,并不是为了自动关联修改。
### 需求的合理性
* 1V1关联表,可以直接操作
* 1VN or NVN 关联,仅提供查询,不应该提供编辑功能
即使隔着屏幕,我仿佛也能感受到你们有些茫然的样子
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/7aee62f28419dd8bff2c7357ca856faa_208x159.png)
但是,相信看完这以下介绍您就会理解。
### 什么是1V1关联表?
~~~
SELECT
`users`.`id` AS `id`,
`users`.`status` AS `status`,
`users`.`login_id` AS `login_id`,
`users`.`login_pwd` AS `login_pwd`,
`users`.`nickname` AS `nickname`,
`users`.`reg_time` AS `reg_time`,
`users`.`info` AS `info`,
`users_exp`.`users_id` AS `users_id`,
`users_exp`.`exp` AS `exp`,
`users_exp`.`avg` AS `avg`,
`users_exp`.`qq` AS `qq`
FROM
(`users` JOIN `users_exp`)
WHERE
(
`users`.`id` = `users_exp`.`users_id`
)
~~~
上面的视图就是 users 1V1 users_exp ,关联条件是 ``users`.`id` = `users_exp`.`users_id``
所以称之为1V1关联,因为用户和用户扩展信息表是通过user id 进行关联的,一个对一个。
**反之除了1V1,其它的都是1VN or NVN**
在进行非1V1业务时,比如:老师和学生
老师有N个学生
学生有N个老师
学生列表
| ID | 姓名 | 我最喜欢的老师 |
| --- | --- | --- |
| 1 | 张三 | 熊雯 |
ID和姓名来自学生表,我的老师的名字来自老师表,通过中间关系表,多表联查形成上面的列表。
但是修改这个列表的时候,显然不能直接将老师的名字给改了并且更新到老师表中。
合理的需求是,可以修改学生的姓名,学生和老师的关系。
但你不能直接改老师名字,你能喜欢英语老师,别人也可以喜欢,你改了名,别人还咋喜欢,都不认识了。
好吧,扯这么多,就是希望大家不要在使用视图的时候陷入误区。
* * * * *
再看一个段子:
问程序员,你会啥?
我会增删改查。
问程序员,软件是啥?
软件除了增删改查,还是增删改查。
貌似听起来没啥毛病吧?
* * * * *
在实际企业级项目中,很少有功能模块是纯单表操作的,多多少少关联其它表的某些字段。
这时候除了增删改查,就是复杂的增删改查了,不是单表的增删改查。
一个业务,需要操作3张以内的表,我们可以简单的说这是一个简单的功能。
一个业务,需要操作5张以内的表,我们还可以说这是一个简单的功能吗。
5张表意味着什么?
5表联查,5表更新,5表。。。。尼玛想想都疼蛋。。。
> PS:所以在设计表结构的时候不要将关系复杂化,应该遵循大事化小小事化了的原则,该冗余的地方就冗余,不要盲目套三大范式,你设计的表是给人用的,不是给老师打分的。
但是往往,肯定会遇到一小波业务就是有那么复杂,需要三表,甚至更多的表,联合作业。
甚至在复杂业务的系统里,这是家常便饭?
怎么破?
> 在经历了很多方案的来回推倒,重写,来回折腾之后最终决定如下!
> 以下方案完全是在无尽的折磨中,尝试出来的,没有参考任何第三方系统和设计,如果雷同,纯属山寨!
> 至于下述方案到底能支撑什么样的业务场景,各位智者见智,应该拥有无限可能!
### EOVA视图处理的设计 V1.6
* 目的:让操作多表,像操作单表一样简单
### 使用思路
* 自建View 提供 元数据导入,支撑复杂的列表查询展现
* 复杂表单后端逻辑通过Aop增强(配合DIY_JS 操控前端)
* 超复杂的自定义按钮,自定义前端Form和后端逻辑
导入视图和导入普通数据表一样,没有什么特殊的地方!
列表查询和展现也没有什么特殊的地方
一个是form table
一个是form view
需求背景描述:
代码: com.oss.order.OrderIntercept By V1.6 OSS Demo
订单关联用户和收获地址:
orders 订单表
users 用户表
address 收获地址表
下面主要描述核心的也是最复杂多变的地方.
新增AOP:
~~~
/**
* 推荐使用Model来实现业务逻辑,万物皆对象,不要问我为什么!
*/
@Override
public String addBefore(AopContext ac) throws Exception {
Record data = ac.record;
// 获取用户信息 保存
Users user = RecordUtil.peelModel(Users.class, data, "login_id", "nickname", "info");
user.save();
int uid = user.getInt("id");
LogKit.info("新增用户成功:" + user.getInt("id"));
// 获取收获信息 保存
Address address = RecordUtil.peelModel(Address.class, data, "name", "full", "mobilephone");
address.save();
int aid = address.getInt("id");
LogKit.info("新增收获信息成功:" + aid);
Orders order = RecordUtil.peelModel(Orders.class, data);
order.set("address_id", aid);
order.set("create_user_id", uid);
order.set("update_user_id", uid);
order.set("create_time", new Date());
order.set("update_time", new Date());
order.save();
LogKit.info("新增订单信息成功:");
return super.addBefore(ac);
}
~~~
修改AOP:
~~~
/**
* 懒人做法Record,一条龙全部搞定,简单粗暴!
*/
@Override
public String updateBefore(AopContext ac) throws Exception {
Record r = ac.record;
// 获取用户信息 更新
Record user = RecordUtil.peel(r, "create_user_id -> id", "login_id", "nickname", "info");
Db.update("users", user);
int uid = user.getInt("id");
LogKit.info("更新用户成功:" + uid);
// 获取收获信息 更新(下面的特殊语法可自行研究源码)
Record address = RecordUtil.peel(r, "address_id -> id", "name", "full", "mobilephone");
Db.update("address", address);
int aid = address.getInt("id");
LogKit.info("更新收获信息成功:" + aid);
Db.update("orders", r);
LogKit.info("更新订单信息成功:");
return super.updateBefore(ac);
}
~~~
> 如上是不是分分钟搞定,复杂的多表业务逻辑!
';
秽土转生の数据迁移
最后更新于:2022-04-01 23:47:01
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/67705c02022b48e9b0c22931f20c64e5_355x186.png)
在EovaV1.5 之前的版本中,很多用户都被一个问题所困扰——版本升级!
因为升级级版本会开放很多新功能,导致数据库变动,升级就成了老大难的问题。
Stop
从EovaV1.5开始,提供业务导出功能,你新增的业务菜单、按钮、元数据,都可以一键导出,然后迁移到新版本,或新系统!
从此以后数据迁移So Easy!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/460dd5a5447a2cb581bdf3463db78ea6_644x148.png)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/36df533b74b686c8908b28c5f53da678_644x166.png)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/282146764766646f58718b6a6b765a51_644x123.png)
';
影分身の代码生成
最后更新于:2022-04-01 23:46:58
影分身之术:かげぶんしんのじゅつ(卡给咯新诺就茨)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/c07fbda611ea2fb510bb8c2d30f718e0_410x271.png)
提到快速开发,大部分人的第一反映就是代码生成器,觉得只有生成代码才是王道。
目前的快速开发主要是两大派系:引擎模式 VS 生成模式。两大派系的支持者都互相吐槽,其中不乏大能者。存在必有道理,任何东西都不是凭空产生的。
色不异空,空不异色,色即是空,空即是色,受想行识,亦复如是。 是诸法空相,不生不灭,不垢不净,不增不减。凡事不要太执着,任何事都具有双面性,有利有弊,工具永远都是工具,人才是造物主,人定胜天。人和动物的区别是,人会使用工具来改善自己的生活。
之前在用户手册文档中介绍说Eova是引擎模式的快速开发平台,不走生成代码的路线。但是不代表Eova不具备生成代码的能力和用法。
Eova理念是追求轻量级快速开发,无招胜有招!下面就为大家介绍,利用Eova来生成代码,然后快速定制个性化功能。
可能大家会好奇,说好了不生成代码的呢?怎么现在又要生成代码了,So 请不要执着于模式,用合适的办法快速解决合适的问题即可!废话不多说,下面请看操作!
**前置技能:**
1.Eova 自定义功能按钮
2.熟练使用浏览器的开发者功能(谷歌F12)
产品管理>修改产品
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/6c6d890509688142b412701258723e4d_920x161.png)
如上为系统默认的修改模版提供的功能
需求:分组显示表单控件
使用Eova如何快速实现?
有同学就说了,你看吧,Eova一点都不灵活,这种需求咋整,还要改模版,如果是生成的代码,直接在页面上改吧改吧就完成了。
OK,下面且看Eova如何快速实现!
开启浏览器的开发者模式,观察Network,找到【修改产品】对应的URL
http://127.0.0.1/form/update/product-28
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/534b89afddb269d87faca438b969faa3_592x282.png)
上图中Response 就是修改产品页面的HTML源码!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/27e52eceac0c75e3f289d7787cce282a_174x166.png)
1. 复制【修改产品页面】的HTML源码,另存为/product/update.html
2. 复制一个按钮代码,进行微调如下,保存为 /product/btn/update.html
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/33a3f9abc3641143dcf6a30937d96710_859x246.png)
新增自定义Controller 并配置
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/76675da18b7cd73204fecdbe1815dda5_411x210.png)
PS:product 用于动态输出修改值,和 常规开发手写页面一样,如果是新增页面直接render即可
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/6037ad342f43f71ebec0c015f18056ce_421x154.png)
快速添加一个自定义按钮
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/82598860edee9a3b95c3e5224fdcc038_485x131.png)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/a149325e8256f8ba40caaab50a67207e_688x233.png)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/b08c331c417e58ec6404f32d0a7d831f_564x37.png)
> PS:BS路径暂时可以随便写,因为还没用上!
手工对HTML进行排版或者重写均可,视需求而定!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/b1fb14964a4da0b29e7d2cd600ca0591_652x513.png)
> PS:上面的HTML由于是复制的浏览器生成的HTML,所以需要手工 用 `${product.xxx}` 来动态获取值
`
`
手工排版之后的分组效果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/f42e23df464a18e9599197b3bae6a6b1_921x241.png)
VS
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/6c6d890509688142b412701258723e4d_920x161.png)
YY:自己捣鼓的看着哪哪都舒服!
> **此文介绍的只是一种DIY思路,Form分组,Eova V 1.6 已经默认提供快速可配置功能!**
此致,利用Eova生成的HTML代码来进行额外扩展就完成了,可能有的人觉得简单,有的人觉得复杂。
这里只是介绍一种方案,当默认的模版无法满足需求时,如何在现有的模版基础上进行扩展,而不用自己手工编写大量代码。
上文中介绍的是,DIY Form 分组显示,同理不管你页面布局多奇葩,都可以自己重新排版!如果业务超级复杂可以将整个修改页面重写,甚至使用其它UI框架综合使用,这里就是一个完整的独立页面。
> 亮点:上述操作步骤中,我们真正意义上手写的代码不超过5行,其它的基本都是复制粘贴!懒货们干起来!
代码优化:上面复制的HTML源码可以套用模版
~~~
<%layout("/eova/layout/default.html",{'title' : 'Dialog' }){%>
// 你只需要复制HTML源码 body部分就行了,头和尾 模版里面有!
<%}%>
~~~
';