2019-03-13 18:18
看一下 jfinal-club/src/main/webapp/assets/js/jfinal-admin.js 这个文件中的 clickSubMenu() 方法,其中有三行代码如下:
// 设置当前选中菜单样式
$(".jfa-sub-menu a").removeClass("jfa-cur-menu");
$(".jfa-main-menu[home='true']").removeClass("jfa-cur-menu");
$this.addClass("jfa-cur-menu");
按一下 F12 打开浏览器的开发者工具,然后按 esc 键将浏览器控制台打开,再点击菜单,看控制台有没有 js 脚本错误,如果有错误解决一下即可
在点击子菜单的同时看一下开发者工具的 dom 文档中的当前被选中的菜单上的 class= 是不是被赋上值了:
class = "jfa-cur-menu"
要确保被赋上值,如果赋上值还是没效果,那就是 css 的问题,只要确保 copy 已存在的纯正的菜单过去改改就好
总之就两类问题:
1:js 错误(包括 js 文件找不到)
2:css 错误,包括 css 未正确操控,或者正确操控但没不是想要的效果
2019-03-13 15:35
@goodsense 这个在框架层面是解决不了的,除非用 JDK 的 synchronized、lock 机制做一套 API 供大家在业务中使用,类似于一个多线程同步框架,这样来弄就与 JDK 提供的那套机制没多大差别了
注意一下,目前你的解决方案是不支持集群的,如果你用多个 JVM 跑你现在的同一个项目,即便用锁也是不行的,因为这个锁只是在同一个 JVM 中有效
使用我给的方案,由于是用的数据库事务机制,支持集群
2019-03-13 14:14
@416417521 打开浏览器开发者工具,看一下 js 不能用的原因,多数是 js 文件没被加载,很容解决
2019-03-13 13:47
1:假定有 A、B 两个并发线程
2:没加锁的那个版本,当 A 线程执行完下面代码得到 isSigned 后被操作系统挂起:
boolean isSigned = checkSignIn(userId, RuleID);
A 线程得到的 isSigned 是 false,并且在得到后立即被操作系统挂起
3:这时,线程 B 追上来,也执行到了 boolean isSigned = checkSignIn(userId, RuleID) 这行代码,也得到一个 false 值
4:接下来,A、B 继续向下执行,必然会引起重复签到和加分
这个问题显然是与 jfinal 无关的,是 java 的多线程基础问题。解决办法除了你的加锁版本以外,还可以通过数据库事务来解决,不要将 isSigned 读到内存中来,而是要让所有动作一气呵成,全部转化成数据库操作,大致如下:
Db.tx(() -> {
String sql = "(update user set score=score + 1 where id not in(select userId from user_signed where createDate = ?)";
int n1 = Db.update(sql, 今天日期);
// 插入一条签到数据
int n2 = Db.update("insert into user_signed ...");
return n1 > 0 && n2 > 0;
});
上面假定了你要更新的表是 user 的 score 字段,仅演示了加 1,假定签到表为 user_signed