Compare commits

...

213 Commits

Author SHA1 Message Date
thinkgem
97e318725a 5.11.0 2025-03-24 14:42:12 +08:00
thinkgem
48801a5596 新增 sys.office.notAllowDeleteIfUserExists 和 sys.company.notAllowDeleteIfUserExists 参数,增加删除机构和公司数据的时候校验是否有用户 2025-03-24 14:03:51 +08:00
thinkgem
d127c2dc32 清理组织和公司下的用户缓存,包含子机构 2025-03-24 14:02:54 +08:00
thinkgem
4befea3e6f update productVersion 2025-03-24 13:59:26 +08:00
thinkgem
96a07e886d update 2025-03-22 18:52:01 +08:00
thinkgem
2f2b508225 网站优化一些基础样式 2025-03-22 18:48:57 +08:00
thinkgem
fbac25ef38 文章按权重排序修复 2025-03-22 18:48:12 +08:00
thinkgem
3aff37f35a add job init remarks 2025-03-17 15:41:47 +08:00
thinkgem
a1beed5b5e 属性获取工具,支持从系统环境变量中获取参数 2025-03-11 15:23:02 +08:00
thinkgem
fee4848ae2 update README.md 2025-03-11 15:22:26 +08:00
thinkgem
84d59dea96 jeesite-*.yml模块配置文件,增加IDEA提示助手 2025-03-08 10:11:37 +08:00
thinkgem
688797ae40 update 2025-03-04 13:03:34 +08:00
thinkgem
0132eb2a9e 修正安全管理器限制的本地调用 2025-03-04 09:51:14 +08:00
thinkgem
7eeae69a63 账号找回密码增加租户参数 2025-03-02 21:03:15 +08:00
thinkgem
6a83a0f8f2 登录界面租户框调整到上面 2025-02-28 16:55:15 +08:00
thinkgem
9c5dd7d7bb update config 2025-02-28 13:35:11 +08:00
thinkgem
14d772cf6d 个人中心代码优化 2025-02-26 14:21:31 +08:00
thinkgem
ee6715de0a next 2025-02-24 09:24:54 +08:00
thinkgem
52f3b0d2bf 新增字段权限接口,过滤 select 返回值,update 和 insert 字段值 2025-02-21 15:52:13 +08:00
thinkgem
f27dc31fb8 增加更严格的权限控制,对单条数据进行数据权限过滤 2025-02-21 15:47:17 +08:00
thinkgem
74b806ca1b AppComment合并更新状态方法 2025-02-21 15:45:05 +08:00
thinkgem
29f3c6894c 优化 编辑公司时,清理公司下的用户缓存 2025-02-20 17:50:06 +08:00
thinkgem
f9bcba6994 优化 编辑机构时,清理机构下的用户缓存 2025-02-20 17:49:44 +08:00
thinkgem
ed40654d6a 新增 findUserListByCompanyCodes 方法,根据公司编码获取用户编码和名称 2025-02-20 17:49:06 +08:00
thinkgem
208ba4a86e fileupload bizType参数为空时,readonly不生效问题 2025-02-20 17:47:42 +08:00
thinkgem
a88eca25ac update README.md 2025-02-17 10:49:20 +08:00
thinkgem
5191b82b0c 点击右上角【Star】收藏本软件 ^_^ 2025-02-17 10:49:08 +08:00
thinkgem
63e654977e 5.10.1 2025-02-15 21:16:53 +08:00
thinkgem
fed9b0b96c 自定义数据权限分配树,默认展开等级设为1 2025-02-15 16:41:18 +08:00
thinkgem
f049d83c5a 登录后不指定默认当前部门编号 2025-02-15 16:40:34 +08:00
thinkgem
8eab281a67 更新 visual 类名 2025-02-14 22:04:04 +08:00
thinkgem
6a985081b6 新增 条件规则数据权限、自定义SQL数据权限,暂存 2025-02-12 18:39:55 +08:00
thinkgem
af83d8fb2d 优化 二级管理员参数提示信息 2025-02-12 18:17:35 +08:00
thinkgem
46a1b57f63 remove aria-hidden="true" 2025-02-12 18:15:50 +08:00
thinkgem
5a3a04c987 新增 按菜单进行数据权限授权,后端通过addFilterByPermission方法调用权限。 2025-02-11 14:28:47 +08:00
thinkgem
728de01676 新增 user.dataScopeJoinMode 参数,默认关闭 JOIN 模式的数据权限,如有需要可打开此参数 2025-02-11 12:52:06 +08:00
thinkgem
ac699f9057 新增 列名 columnName 正则表达式的安全过滤 2025-02-11 12:46:41 +08:00
thinkgem
97b299a113 update 2025-02-11 12:43:57 +08:00
thinkgem
1b32b7700a 增加默认值 2025-02-07 20:44:16 +08:00
thinkgem
8b54a7c0e8 更新配置文件 2025-02-07 17:22:39 +08:00
thinkgem
b1b29715b8 代码优化 EmpUtils 增加 getCompanyCodes、getCompanyParentCodess 方法 2025-02-07 17:11:33 +08:00
thinkgem
477c5dcfbf 将 router.push 替换为 useGo 增加代码健壮性 2025-02-07 16:03:27 +08:00
thinkgem
761901e61d add ObjectUtilsTest.java 2025-02-05 21:10:28 +08:00
thinkgem
6de3df8c76 修正String转Long丢失精度问题 2025-02-05 21:09:53 +08:00
thinkgem
a790e357c7 新增 切换部门功能、多部门岗位权限 2025-02-01 16:22:34 +08:00
thinkgem
fa8d88285f 优化 查询当前员工关联的岗位信息和附属机构信息接口 2025-01-28 11:46:57 +08:00
thinkgem
2aa8472072 新增 获取当前用户岗位列表 EmpUtils.getEmployeePostList 缓存接口 2025-01-28 11:45:31 +08:00
thinkgem
83a8ed16d2 新增 岗位查询角色接口新增 postCode_in 查询条件 2025-01-28 11:44:10 +08:00
thinkgem
a7b458af90 丰富 EmployeeOffice 返回结果 2025-01-28 11:43:21 +08:00
thinkgem
4e6f27a2ab 新增 form:treeselect 组件 fieldNames 属性,自定义数据源的字段名 2025-01-28 11:41:17 +08:00
thinkgem
4287437d2e 从LoginController分离出SwitchController类 2025-01-27 23:43:11 +08:00
thinkgem
c86d16320f 修正 sqlserver 分页时,缺少 order by 的问题 2025-01-21 15:37:38 +08:00
thinkgem
30e725d256 优化 切换当前身份时,自动对应身份的桌面地址 2025-01-20 17:31:25 +08:00
thinkgem
dea24e73ec 新增 RSA 非对称加密工具 2025-01-16 17:36:02 +08:00
thinkgem
a5ae486f52 update README.md 2025-01-16 17:27:08 +08:00
thinkgem
34d55bfc4e format code 2025-01-14 10:37:46 +08:00
thinkgem
f591f4c07a update MsgPushTest 2025-01-13 15:09:47 +08:00
thinkgem
620b871368 update README.md 2025-01-10 14:00:31 +08:00
thinkgem
3d68d9f660 upgrade h2 to 2.2.224 2025-01-08 17:04:04 +08:00
thinkgem
696e6a97b1 update useless code 2025-01-08 17:02:48 +08:00
thinkgem
587ad5caef update README.md 2025-01-06 11:22:20 +08:00
thinkgem
d7d6bea8fe mybatis 3.5.16 2025-01-06 10:26:00 +08:00
thinkgem
2509d3cf2f next version 2025-01-06 09:58:43 +08:00
thinkgem
bb8a9e1054 update area data 2025-01-01 19:44:25 +08:00
thinkgem
55ad21e228 5.10.0 2025-01-01 11:05:38 +08:00
thinkgem
6b29c8c937 5.10.0 2024-12-31 21:04:15 +08:00
thinkgem
cf32922387 update import icon 2024-12-31 21:04:15 +08:00
thinkgem
5e87d44a3c 2025 2024-12-30 14:56:56 +08:00
thinkgem
0ef1eca662 update 2024-12-29 16:43:20 +08:00
thinkgem
203e21beed update bin 2024-12-26 11:42:58 +08:00
thinkgem
34b1ba00fd 上传文件必填时,防止表单验证提示输入历史 2024-12-25 16:20:46 +08:00
thinkgem
8e64c2c51b update README.md 2024-12-25 15:50:06 +08:00
thinkgem
62392702a6 update jdbc url 2024-12-25 10:30:26 +08:00
thinkgem
580f5eea55 remove beetl includeJSP 2024-12-23 17:15:54 +08:00
thinkgem
3623824a01 update README.md 2024-12-13 12:59:21 +08:00
thinkgem
b1409e88a1 update README.md 2024-12-12 18:16:41 +08:00
thinkgem
2b25eaa591 增加参考配置,可查看哪些用户的数据,ctrlPermi 更改为 0 后显示 2024-12-11 10:32:19 +08:00
thinkgem
38c8ea825a 细节优化,控制业务范围重命名为业务范围 2024-12-11 10:27:48 +08:00
thinkgem
56be7dd689 移除重复参数 2024-12-11 10:23:03 +08:00
thinkgem
8623b1a497 新增BigDecimalType 2024-12-05 11:12:14 +08:00
thinkgem
1c8a5adcd3 update 2024-12-05 11:12:07 +08:00
thinkgem
8d1bbde93b update version 2024-12-04 14:30:02 +08:00
thinkgem
a9054c7567 使用对象存储时,文件管理的在线预览文件中的下载地址修正 2024-12-04 14:17:22 +08:00
thinkgem
bca5facc4e update 2024-11-26 20:10:15 +08:00
thinkgem
a8d1080cfd update README.md 2024-11-24 20:36:53 +08:00
thinkgem
44ca71d681 5.9.2 2024-11-23 09:56:20 +08:00
thinkgem
6ecd94b954 update 2024-11-21 09:49:23 +08:00
thinkgem
cba1010a45 更新注册提示信息 2024-11-13 17:17:07 +08:00
thinkgem
9f1ebcd8e5 切换系统时,清除当前岗位和角色状态 2024-11-12 10:54:58 +08:00
thinkgem
998c3204a9 设备信息字段 device_info 长度调整为 4000 2024-11-11 17:12:05 +08:00
thinkgem
ac314d9070 登录后重定向地址验证,如果是非法地址,则指定默认的登录成功地址 2024-11-07 17:53:12 +08:00
thinkgem
7826863bb5 update README.md 2024-11-07 16:13:02 +08:00
thinkgem
4c96681055 新建 mini 迷你服务工具,最小化启动项目 2024-11-07 16:07:44 +08:00
thinkgem
7ca01a354a update version 2024-11-07 15:28:00 +08:00
thinkgem
71771421d5 Vue登录界面useCorpModel更改为loginCodeCorpUnique 2024-11-07 15:15:39 +08:00
thinkgem
5f664bd84b 新增 窗口右上角的头像下拉菜单,切换当前用户所属岗位,并联动切换当前菜单权限 2024-11-07 10:26:04 +08:00
thinkgem
5ea41881de 提升登录性能;支持普通用户升级为超管用户。 2024-11-07 10:22:36 +08:00
thinkgem
6e2843869d 优化 MenuDao.xml 接口 findByUserCode 替换为 findByRoleCodes 升级时注意 2024-11-07 10:19:30 +08:00
thinkgem
6a0ebd6c2d 新增 当前用户 user.getRoleList() 支持返回 岗位关联角色数据 2024-11-07 10:19:04 +08:00
thinkgem
48bd4778e6 新增 岗位关联角色(用户->岗位->角色)权限控制,可通过 user.postRolePermi=true 参数开启 2024-11-07 10:17:51 +08:00
thinkgem
d7ada6e4e6 增加岗位切换接口;优化登录菜单权限查询,直接通过当前用户角色查询,减少联表,提升查询效率。 2024-11-07 10:15:20 +08:00
thinkgem
f8a008d88b 优化 增加岗位保存时清理关联的用户缓存 2024-11-07 10:14:37 +08:00
thinkgem
7bfb458981 优化 超级管理员作为普通员工时的角色数据查询,允许修改超级管理员员工信息,不允许停用禁用删除超管 2024-11-07 10:12:46 +08:00
thinkgem
a2ffa1e47a 增加手机端单表代码生成模板 2024-11-05 11:25:53 +08:00
thinkgem
80b397e9e4 quartz 2.4.0.rc3 2024-11-04 18:14:03 +08:00
thinkgem
b008b0c956 修正代码生成时,子表文件生成目录不对问题,vue日期类型不匹配问题 2024-11-04 17:52:19 +08:00
thinkgem
d79339b891 jackson 2.18.1 2024-11-04 17:36:24 +08:00
thinkgem
81acccfe66 优化 mvc 接受字段类型不一致信息显示,方便调试 2024-11-01 19:59:56 +08:00
thinkgem
fe6004d81d 调整代码生成模板目录 2024-11-01 10:44:10 +08:00
thinkgem
e404d2652d 优化表单内表格的行高和边距 2024-10-28 21:27:42 +08:00
thinkgem
827d461437 update 2024-10-25 19:07:25 +08:00
thinkgem
a2da4f095b 5.9.1 2024-10-21 22:34:17 +08:00
thinkgem
302eb47b83 update app name 2024-10-21 14:12:03 +08:00
thinkgem
4fa6225017 logback 1.2.13 2024-10-14 21:16:38 +08:00
thinkgem
68058f948f spring 5.3.39 2024-10-10 20:48:58 +08:00
thinkgem
fc59e3a7aa 编辑表格中被隐藏的旧数据行控件忽略前端校验 2024-10-10 09:03:20 +08:00
thinkgem
d1cd3ad5ad update 2024-10-08 16:34:03 +08:00
thinkgem
213834810c 代码生成模板新增vue子表独立组件的生成 2024-10-08 14:13:37 +08:00
thinkgem
6d381b31da 代码生成支持带减号的工程模块名生成工程和微服务工程 2024-10-08 14:07:22 +08:00
thinkgem
5e55b5f4b3 驼峰命名法工具增加减号替换 2024-10-08 14:04:51 +08:00
thinkgem
e3dc77b75a 增加启动完成提示信息日志 2024-10-08 14:03:15 +08:00
thinkgem
58b22924dd 生成前端路径更改为 Vue 前端路径,仅用于分离端的代码生成路径。 2024-09-27 15:09:40 +08:00
thinkgem
f7cdda05d1 代码生成模板新增classNameSimple参数,不带模块名的类名。子表List字段名不带模块名。 2024-09-27 15:08:29 +08:00
thinkgem
cb52f25931 启动日志中显示 tomcat 版本号 2024-09-24 14:02:29 +08:00
thinkgem
5b9a7c1d2c 新增监控开关参数 服务器监控 state.server 缓存监控 state.cache 数据监控 state.druid 2024-09-23 13:32:53 +08:00
thinkgem
c295b87f35 文件预览列表增加文件名返回参数 2024-09-23 12:02:28 +08:00
thinkgem
d6eecc1c56 update upbw html 2024-09-22 19:28:28 +08:00
thinkgem
9d2a250d72 5.9.0 2024-09-18 09:45:20 +08:00
thinkgem
f0cc98e45b 增加 gen.simpleRequestMapping 默认参数 true 可简洁 url 地址 2024-09-18 09:08:41 +08:00
thinkgem
a8fbf4d2b1 fix 代码生成业务列表选择框i18n路径 2024-09-18 09:07:55 +08:00
thinkgem
2013201f06 数据源管理:新增连接等待时间、连接失败中断默认参数;新增集群支持,单机修改后自动同步到集群其它节点 2024-09-16 22:22:40 +08:00
thinkgem
425c74fab4 update README.md 2024-09-14 13:06:00 +08:00
thinkgem
b9fc0a9f86 update 2024-09-14 12:55:17 +08:00
thinkgem
ca256c1364 update 2024-09-14 12:54:35 +08:00
thinkgem
c484e19448 小屏幕下的菜单按钮布局优化 2024-09-13 10:47:33 +08:00
thinkgem
9275260019 默认显示列表搜索框 2024-09-13 10:46:31 +08:00
thinkgem
9a671d8dfd 默认显示列表搜索框 2024-09-13 10:46:24 +08:00
thinkgem
7b537b4c83 默认显示列表搜索框 2024-09-13 10:46:02 +08:00
thinkgem
223d05b8c1 默认显示列表搜索框 2024-09-13 10:45:55 +08:00
thinkgem
4ca8398f99 new version 2024-09-12 10:13:25 +08:00
thinkgem
cfc8681174 子表增加表单验证提示、代码格式化 2024-09-11 10:15:31 +08:00
thinkgem
9c5bfd9c59 update README.md 2024-08-29 16:23:08 +08:00
thinkgem
3f87f2a024 优化导入 2024-08-29 13:12:17 +08:00
thinkgem
c3a25b98ec update 2024-08-29 10:31:06 +08:00
thinkgem
5c09e3de51 新增支持 Vue 地址路由参数,使用 {param1} 自动替换为 :param1,用法详见 params.vue 2024-08-28 15:09:15 +08:00
thinkgem
91e08cf4df 新增导出Excel数据按钮loading状态 2024-08-27 14:40:41 +08:00
thinkgem
14a38abb6d update 2024-08-26 21:42:57 +08:00
thinkgem
99c778c92d update README.md 2024-08-22 17:40:54 +08:00
thinkgem
e51dd7c73c 优化流程表单模板,支持从表单进入显示审批意见框 2024-08-16 18:44:05 +08:00
thinkgem
67891ce361 update 2024-08-16 16:01:44 +08:00
thinkgem
25a192cd6a update 2024-08-15 19:59:47 +08:00
thinkgem
444463ed5e Merge branch 'refs/heads/v5.temp' into v5.8 2024-08-12 20:06:00 +08:00
thinkgem
77aeb4ac4f 5.8.1 2024-08-12 11:17:15 +08:00
thinkgem
2b122eecd5 优化查询的更多按钮,显示一个双箭头,增加动画效果 2024-08-12 10:21:41 +08:00
thinkgem
6ad196d82d 添加版本提示 2024-08-09 14:18:57 +08:00
thinkgem
b002592f4e 将账号+手机验证码登录,替换为手机号+验证码登录;当一个手机号绑定多个账号的时候,可以让用户选择登录的账号进行登录;新增userService.findListByMobile接口 2024-08-02 20:02:09 +08:00
thinkgem
3f6d1593b6 Excel导入导出支持ExcelFields注解添加到类上 2024-07-28 13:24:14 +08:00
thinkgem
db5f195fff 开放所有系统Controller给您足够的自定义空间 2024-07-26 11:20:50 +08:00
thinkgem
1c539f3796 代码优化 2024-07-26 11:04:34 +08:00
thinkgem
75e5e2765c 添加 webp 格式 2024-07-25 11:53:21 +08:00
thinkgem
fcf5d8a04c 代码优化 2024-07-25 11:36:22 +08:00
thinkgem
9f0d45cad9 新增 web.isDefaultResult 参数,默认全局进行接口结果包装为 { code: 200, msg: "", data: {} | [] };新增 web.resultParamName 和 headerParamName 参数,对个别结果进行包装 2024-07-24 14:59:19 +08:00
thinkgem
28ec083c26 update README.md 2024-07-24 14:54:42 +08:00
thinkgem
4c2d645b0a 新增 SM2Utils、SM3Utils、SM4Utils 国密算法工具类及测试类 2024-07-23 19:44:20 +08:00
thinkgem
eb94eba608 新增 encrypt.defaultKey 参数,适用于 Aes、M3 加密的默认秘钥;新增 encrypt.storeBase64 参数,是否将 Hex 编码改为 Base64 编码存储;新增 encrypt.smAlgorithm 参数,是否使用国密 SM 算法(一键替换 SHA-1 替换为 SM3、AES 替换为 SM4 算法) 2024-07-23 19:43:14 +08:00
thinkgem
bd5d543bf5 新增 encrypt.smAlgorithm 参数,是否使用国密 SM 算法(一键替换 SHA-1 替换为 SM3、AES 替换为 SM4 算法) 2024-07-23 19:42:29 +08:00
thinkgem
739f2d58b7 新增 EncryptTypeHandler、SM4TypeHandler 加密 MyBatis Handler 2024-07-23 19:39:49 +08:00
thinkgem
d62dc0310a 新增 encrypt.defaultKey 参数,适用于 Aes、M3 加密的默认秘钥;新增 encrypt.storeBase64 参数,是否将 Hex 编码改为 Base64 编码存储 2024-07-23 19:39:26 +08:00
thinkgem
f4456ec359 优化 加密算法工具类,增加测试类。 2024-07-23 19:37:47 +08:00
thinkgem
8cdd2fd99c 添加 bcprov 算法类库 2024-07-23 19:37:19 +08:00
thinkgem
7e3a55a578 open beetl <#form:xxx 控件 2024-07-22 15:42:51 +08:00
thinkgem
7ce1f84866 open beetl functions form 2024-07-22 15:39:44 +08:00
thinkgem
ccc3ea6894 open beetl functions menu 2024-07-22 15:39:33 +08:00
thinkgem
b5c100f9a6 open views upgrade.html 2024-07-22 15:38:54 +08:00
thinkgem
cf151678a9 open views tagsview/form 2024-07-22 15:38:28 +08:00
thinkgem
2ba4d16ef1 open views modules/sys 2024-07-22 15:38:06 +08:00
thinkgem
dfbc3284b4 webuploader move to static 2024-07-21 20:27:22 +08:00
thinkgem
9317d0e6bb wdScrollTab move to static 2024-07-21 20:26:48 +08:00
thinkgem
474fee2943 ueditor move to static 2024-07-21 18:33:57 +08:00
thinkgem
5d1fe5236a sys js and css move to static 2024-07-21 18:33:37 +08:00
thinkgem
808175d835 jquery-validation move to static 2024-07-21 18:32:37 +08:00
thinkgem
3ba3aa2b2b jquery-toastr move to static 2024-07-21 18:32:18 +08:00
thinkgem
aba56f7aa2 jquery-timeago move to static 2024-07-21 18:31:51 +08:00
thinkgem
648199245a jquery plugins move to static 2024-07-21 18:30:40 +08:00
thinkgem
893292ed20 jqGrid move to static 2024-07-21 18:28:22 +08:00
thinkgem
68a26fa727 images move to static 2024-07-21 18:17:15 +08:00
thinkgem
d0a2cbfa58 fullcalendar move to static 2024-07-21 18:16:58 +08:00
thinkgem
dffd48c454 echarts move to static 2024-07-21 18:16:43 +08:00
thinkgem
92c41f0cb5 cropper move to static 2024-07-21 18:15:46 +08:00
thinkgem
8e3992767c commonjs move to static 2024-07-21 18:15:23 +08:00
thinkgem
e3c2bb82fd colorpicker move to static 2024-07-21 18:14:53 +08:00
thinkgem
3924575550 ckplayer move to static 2024-07-21 18:10:26 +08:00
thinkgem
826698a809 ace-editor move to static 2024-07-21 18:10:04 +08:00
thinkgem
a0fa0281fa add static module 2024-07-21 17:55:49 +08:00
thinkgem
53bea929c1 add upbw page 2024-07-21 17:46:03 +08:00
thinkgem
2922d90dd9 add jquery layout 2024-07-21 17:45:29 +08:00
thinkgem
0ec8e0b89a add cascadeSelect js 2024-07-21 17:44:35 +08:00
thinkgem
184e7ad554 新增 PwdService 服务类方便自定义重写密码相关实现 2024-07-21 17:43:21 +08:00
thinkgem
49e669c47e 新增cas经典协议兼容模块 2024-07-21 17:42:51 +08:00
thinkgem
4469aad2c8 new version 2024-07-19 08:54:05 +08:00
thinkgem
18831ab95d 增加Excel导入导出测试类,增加模板导出。 2024-07-18 15:52:28 +08:00
thinkgem
bddf67e726 update README.md. 2024-07-17 08:59:09 +08:00
thinkgem
01779973e5 add ckplayer 2024-07-17 08:59:03 +08:00
卓源软件
97ebfe40be update README.md.
Signed-off-by: 卓源软件 <thinkgem@163.com>
2024-07-17 00:14:18 +00:00
thinkgem
4e249c116c 修复UEditor上传视频的首图不显示的问题 2024-07-11 10:22:51 +08:00
thinkgem
d909a2527a update 2024-07-11 09:47:21 +08:00
thinkgem
32a7e1a5f8 format pom.xml 2024-07-07 19:10:28 +08:00
thinkgem
e5d217f5b2 poi version 2024-07-07 12:21:30 +08:00
thinkgem
72b030bcc1 Merge poi version 2024-07-07 12:20:42 +08:00
thinkgem
090b2cd3fc 将 test 独立出模块,方便代码管理 2024-07-06 22:22:06 +08:00
thinkgem
9b4b4affa0 使用 __url 参数统一管理成功跳转地址 2024-07-06 10:23:10 +08:00
thinkgem
09d2af2491 update 2024-07-04 19:23:08 +08:00
thinkgem
e279700113 新增附属部门切换接口,方便获取当前默认部门 2024-07-04 16:45:07 +08:00
2268 changed files with 125099 additions and 22558 deletions

13
LICENSE
View File

@@ -206,15 +206,16 @@
1. 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款。
2. 不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者
3. 在使用本软件时,由于它集成了众多第三方开源软件,请共同遵守这些开源软件的使用许可条款规定。
4. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者
规定需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`Copyright`和`@author`信息)
更不要,全局替换源代码中的 jeesite 或 ThinkGem 等字样,否则你将违反本协议条款承担责任。
4. 您若套用本软件的一些代码或功能参考,请保留源文件中的版权和作者,需要在您的软件介绍明显位置
5. 您若套用本软件的一些代码或功能参考,请保留源文件中的版权和作者,需要在您的软件介绍明显位置
说明出处,举例:本软件基于 JeeSite 快速开发平台并附带链接http://jeesite.com
5. 任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
6. 如果你对本软件有改进,希望可以贡献给我们,共同进步。
7. 本项目已申请软件著作权,请尊重开源,感谢阅读。
8. 无用户数限制,无在线人数限制,放心使用。
6. 任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
7. 如果你对本软件有改进,希望可以贡献给我们,共同进步。
8. 本项目已申请软件著作权,请尊重开源,感谢阅读。
9. 无用户数限制,无在线人数限制,放心使用。
版权所有:济南卓源软件有限公司

View File

@@ -4,10 +4,13 @@
</p>
<h3 align="center" style="margin:30px 0 30px;font-weight:bold;font-size:30px;">快速开发平台 - Spring Boot</h3>
<p align="center">
<a href="https://jeesite.com/docs/upgrade/" target="__blank"><img alt="JeeSite-V5.7" src="https://img.shields.io/badge/JeeSite-V5.7-success.svg"></a>
<a href="https://spring.io/projects/spring-boot#learn" target="__blank"><img alt="SpringBoot-2.7" src="https://img.shields.io/badge/SpringBoot-2.7-blue.svg"></a>
<a href="https://gitee.com/thinkgem/jeesite5/stargazers" target="__blank"><img alt="star" src="https://gitee.com/thinkgem/jeesite5/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/thinkgem/jeesite5/members" target="__blank"><img alt="fork" src="https://gitee.com/thinkgem/jeesite5/badge/fork.svg?theme=dark"></a>
<a href="https://spring.io/projects/spring-boot" target="__blank"><img alt="SpringBoot-V2.7/3.4" src="https://img.shields.io/badge/SpringBoot-V2.7/3.4-blue.svg"></a>
<a href="https://v3.cn.vuejs.org/" target="__blank"><img alt="TypeScript-Vue3" src="https://img.shields.io/badge/TypeScript-Vue3-green.svg"></a>
<a href="https://jeesite.com/docs/upgrade/" target="__blank"><img alt="JeeSite-V5.x" src="https://img.shields.io/badge/JeeSite-V5.x-success.svg"></a>
<a href="https://gitee.com/thinkgem/jeesite5" target="__blank"><img alt="star" src="https://gitee.com/thinkgem/jeesite5/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/thinkgem/jeesite-vue" target="__blank"><img alt="star" src="https://gitee.com/thinkgem/jeesite-vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/thinkgem/jeesite" target="__blank"><img alt="star" src="https://gitee.com/thinkgem/jeesite/badge/star.svg?theme=gvp"></a>
<a href="https://gitcode.com/thinkgem/jeesite" target="__blank"><img alt="star" src="https://gitcode.com/thinkgem/jeesite/star/badge.svg"></a>
</p>
------
@@ -24,25 +27,40 @@
* 使用文档:<https://jeesite.com/docs>
* 问题反馈:<http://jeesite.net> [【新手必读】](https://gitee.com/thinkgem/jeesite5/issues/I18ARR)
* 需求收集:<https://gitee.com/thinkgem/jeesite5/issues/new>
* QQ 群:`127515876``209330483``223507718``709534275``730390092``1373527``183903863(外包)`
* 联系我们:<http://s.jeesite.com>
* 关注微信公众号,了解最新动态:
<p style="padding-left:40px">
<img alt="JeeSite微信公众号" src="https://images.gitee.com/uploads/images/2020/0727/091951_a3ab258c_6732.jpeg" width="220" height="220">
<p style="padding-left:40px">  
<img alt="JeeSite微信公众号" src="https://jeesite.com/assets/images/mp.png" width="200">
</p>
* 源码仓库地址1<https://gitee.com/thinkgem/jeesite5>
* 源码仓库地址2<https://github.com/thinkgem/jeesite5>
* 分离版前端源码仓库地址1<https://gitee.com/thinkgem/jeesite-vue>
* 分离版前端源码仓库地址2<https://github.com/thinkgem/jeesite-vue>
* QQ 群:`127515876``209330483``223507718``709534275``730390092``1373527``183903863(外包)`
* 微信群:如果二维码过期,请尝试刷新图片,或者添加客服微信 jeesitex 邀请您进群
<p style="padding-left:40px"><a href="https://jeesite.com/assets/images/wxg_cur.png" target="_blank">  
<img alt="JeeSite微信群" src="https://jeesite.com/assets/images/wxg_cur.png" width="200"/></a>
</p>
* 源码仓库地址:
[Gitee](https://gitee.com/thinkgem/jeesite5)、
[GitCode](https://gitcode.com/thinkgem/jeesite5)、
[GitHub](https://github.com/thinkgem/jeesite5)
* 分离版源码仓库地址:
[Gitee](https://gitee.com/thinkgem/jeesite-vue)、
[GitCode](https://gitcode.com/thinkgem/jeesite-vue)、
[GitHub](https://github.com/thinkgem/jeesite-vue)
* 源码合集仓库地址:
[GVP](https://gitee.com/thinkgem/jeesite/tree/v5.springboot3)、
[G-Star](https://gitcode.com/thinkgem/jeesite/overview?ref=v5.springboot3)、
[GitHub](https://github.com/thinkgem/jeesite/tree/v5.springboot3)
## 平台介绍
* JeeSite 快速开发平台,不仅仅是一个后台开发框架,它是一个企业级快速开发解决方案,后端基于经典组合 Spring Boot、Shiro、MyBatis前端采用 Beetl、Bootstrap、AdminLTE 经典开发模式,或者分离版 Vue3、Vite、Ant Design Vue、TypeScript、Vben Admin 最先进技术栈。
* JeeSite 快速开发平台,低代码,轻量级,不仅仅是一个后台开发框架,它是一个企业级快速开发解决方案,后端基于经典组合 Spring Boot、Shiro、MyBatis前端采用分离版 Vue3、Vite、Ant Design Vue、TypeScript、Vben Admin 最先进技术栈,或者 Beetl、Bootstrap、AdminLTE 经典开发模式
* 提供在线数据源管理、数据表建模、代码生成等功能,可自动创建业务模块代码工程和微服务模块代码工程,自动生成前端代码和后端代码;包括核心功能模块如:组织机构、用户、角色、岗位、管理员、权限审计、菜单及按钮权限、数据权限、模块管理、系统参数、字典管理、系统监控、数据监控等;扩展功能如:工作流引擎、内容管理、消息推送、单点登录、第三方登录、在线作业调度、对象存储、可视化数据大屏、报表设计器、在线文件预览、国际化、全文检索、统一认证服务等。
* 本平台采用松耦合设计,微内核和插件架构,模块增减便捷,支持集群,支持 SaaS 架构,支持读写分离、分库分表、Spring Cloud 微服务架构;并内置了众多账号安全设置、密码策略、系统访问限制等安全解决方案,支持等保评测。
* 本平台采用松耦合设计,真正的轻量级,微内核,快速部署,插件架构,模块增减便捷,支持扩展 SaaS 架构、集群部署、读写分离、分库分表、Spring Cloud 微服务架构;并内置了众多账号安全设置、密码策略、系统访问限制等安全解决方案,支持等保评测。
* 本平台专注于为初级研发人员提供强大的支持,使他们能够高效、快速地开发出复杂的业务功能,同时为中高级人员腾出宝贵的时间,专注于更具战略性和创新性的任务。我们致力于让开发者能够全心投入业务逻辑中,而将繁琐的技术细节交由平台来封装处理。这不仅降低了技术实现的难度,还确保了系统架构的稳定性和安全性,进而帮助企业节省人力成本、缩短项目周期,并提高整体软件的安全性和质量。
@@ -52,11 +70,13 @@
* 2021 年终发布 Vue3 的前后分离版本,使得 JeeSite 拥有同一个后台服务 Web 来支撑分离版和全栈版两套前端技术栈。
* 支持国产化软硬件环境,如国产芯片、操作系统、数据库、中间件、国密算法等。
## 核心优势
* JeeSite 非常易于二次开发,可控性高,整体架构清晰、技术稳定而先进、源代码书写规范、经典技术会的人多、易于维护、易于扩展、安全稳定。
* JeeSite 功能全,知识点非常多,也非常少。因为她使用的都是一些通用的技术,通俗的设计风格,大多数基础知识点,多数人都能掌握,所以每一个 JeeSite 的功能点都非常容易掌握。只要您学会使用这些功能和组件的应用,就可以顺利完成系统开发了。
* JeeSite 功能全,知识点非常多,也非常少。因为她使用的都是一些通用的技术,通俗的设计风格,大多数基础知识点,多数人都能掌握,所以每一个 JeeSite 的功能点都非常容易掌握。只要您学会使用这些功能和组件的应用,就可以顺利完成系统开发了。
* JeeSite 是一个低代码开发平台具有较高的封装度、扩展性封装不是限制您去做一些事情而是在便捷的同时也具有较好的扩展性在不具备一些功能的情况下JeeSite 提供了扩展接口,提供了原生调用方法。
@@ -81,7 +101,7 @@
* 前端组件jQuery 3.7、jqGrid 4.7、layer 3.5、zTree 3.5、jQuery Validation
* 分离前端版Node.js、TypeScript、Vue3、Vite、Ant Design Vue、Vue Vben Admin
* 工作流引擎Flowable 6.6、符合 BPMN 规范、在线流程设计器、中国式流程、退回、撤回、自由流
* Bootstrap 版 支持 IE9 及以上版本及其他所有现代浏览器,如:谷歌、火狐、国产浏览器 等
* Bootstrap 版 支持 IE10 及以上版本及其他所有现代浏览器,如:谷歌、火狐、国产浏览器 等
* Vue3 版 支持现代浏览器,如:谷歌 Chrome 86+、火狐、国产浏览器 等
* 技术选型(详细):<http://jeesite.com/docs/technology/>
* JeeSite Vue 版本:<https://gitee.com/thinkgem/jeesite-vue>
@@ -119,7 +139,7 @@
### 本地运行
1. 环境准备:`JDK 1.8 or 11、17``Maven 3.6+`、使用 `MySQL 5.7 or 8.0` 数据库、[其它数据库](https://jeesite.com/docs/technology/#_8、已支持数据库)
2. 下载源码:<https://gitee.com/thinkgem/jeesite5/repository/archive/v5.7.zip> 并解压
2. 下载源码:<https://gitee.com/thinkgem/jeesite5/repository/archive/v5.9.zip> 并解压
3. 打开文件:`/web/src/main/resources/config/application.yml` 配置JDBC连接
4. 执行脚本:`/web/bin/init-data.bat` 初始化数据库
5. 执行脚本:`/web/bin/run-tomcat.bat` 启动服务即可
@@ -130,11 +150,11 @@
### 快速运行
1. 环境准备:`JDK 1.8 or 11、17``Maven 3.6+`、无需准备数据库(使用内嵌 H2 DB、Vue资源包
2. 下载源码:<https://gitee.com/thinkgem/jeesite5/repository/archive/v5.7.zip> 并解压
2. 下载源码:<https://gitee.com/thinkgem/jeesite5/repository/archive/v5.9.zip> 并解压
3. 执行脚本:`/web-fast/bin/run-tomcat.bat` 启动服务即可(自动初始化库)
4. 全栈版本地址:<http://127.0.0.1:8980/a/login>
5. Vue分离版本地址:<http://127.0.0.1:8980/vue/login>
6. 默认超级管理员账号system 密码 admin
4. Vue分离版本地址:<http://127.0.0.1:8980/vue/login>
5. 全栈版本地址:<http://127.0.0.1:8980/a/login>
6. 初始登录账号:超级管理员system 密码admin
7. 部署常见问题:<https://jeesite.com/docs/faq/>
### 容器运行
@@ -213,20 +233,22 @@ docker run --name jeesite-web -p 8980:8980 -d --restart unless-stopped \
1. 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款。
2. 不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
3.延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者
3.使用本软件时,由于它集成了众多第三方开源软件,请共同遵守这些开源软件的使用许可条款规定。
4. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者
规定需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`Copyright``@author`信息)
更不要,全局替换源代码中的 jeesite 或 ThinkGem 等字样,否则你将违反本协议条款承担责任。
4. 您若套用本软件的一些代码或功能参考,请保留源文件中的版权和作者,需要在您的软件介绍明显位置
5. 您若套用本软件的一些代码或功能参考,请保留源文件中的版权和作者,需要在您的软件介绍明显位置
说明出处,举例:本软件基于 JeeSite 快速开发平台并附带链接http://jeesite.com
5. 任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
6. 如果你对本软件有改进,希望可以贡献给我们,共同进步。
7. 本项目已申请软件著作权,请尊重开源,感谢阅读。
8. 无用户数限制,无在线人数限制,放心使用。
6. 任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
7. 如果你对本软件有改进,希望可以贡献给我们,共同进步。
8. 本项目已申请软件著作权,请尊重开源,感谢阅读。
9. 无用户数限制,无在线人数限制,放心使用。
## 技术服务与支持
## 技术支持与服务
* 本软件免费,我们也提供了相应的收费服务,因为:
* 没有资金的支撑就很难得到发展,特别是一个好的产品,如果 JeeSite 帮助了您,请为我们点赞。支持我们,您可以获得更多回馈,我们会把公益事业做的更好,开放更多资源,回报社区和社会。请给我们一些动力吧,在此非常感谢已支持我们的朋友!
* **联系我们**:请访问技术支持服务页面:<https://jeesite.com/docs/support/>
* **联系我们**:请访问技术支持服务页面:<http://s.jeesite.com>
## 今后如何升级?

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>5.8.0-SNAPSHOT</version>
<version>5.11.0-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
@@ -34,7 +34,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
<version>${commons-text.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -91,6 +91,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- Email -->
@@ -118,7 +119,7 @@
<artifactId>metadata-extractor</artifactId>
<version>${metadata-extractor.version}</version>
</dependency> -->
<!-- 缩略图工具 -->
<!-- 缩略图工具 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
@@ -130,7 +131,7 @@
<artifactId>imageio-jpeg</artifactId>
<version>${twelvemonkeys.version}</version>
</dependency>
<!-- 图片验证码生成 -->
<!-- 图片验证码生成 -->
<dependency>
<groupId>com.bladejava</groupId>
<artifactId>blade-patchca</artifactId>
@@ -161,7 +162,7 @@
</exclusions>
</dependency>
<!-- 条形码、二维码生成 -->
<!-- 条形码、二维码生成 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
@@ -196,12 +197,19 @@
<version>${poi.version}</version>
</dependency>
<!-- pinyin4j -->
<!-- Pinyin4j -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>${pinyin4j.version}</version>
</dependency>
<!-- BC Provider -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>${bcprov.version}</version>
</dependency>
<!-- Logging begin -->
<dependency>
@@ -256,13 +264,13 @@
</dependencies>
<developers>
<developers>
<developer>
<id>thinkgem</id>
<name>WangZhen</name>
<email>thinkgem at 163.com</email>
<roles><role>Project lead</role></roles>
<timezone>+8</timezone>
<timezone>+8</timezone>
</developer>
</developers>

View File

@@ -4,176 +4,175 @@
*/
package com.jeesite.common.codec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import com.jeesite.common.io.PropertiesUtils;
import com.jeesite.common.lang.ExceptionUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.jeesite.common.lang.ExceptionUtils;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
/**
* AES加密解密工具类
* AES 加密解密工具类
* @author ThinkGem
*/
public class AesUtils {
private static final String AES = "AES";
private static final String AES_CBC = "AES/CBC/PKCS5Padding";
private static final int DEFAULT_AES_KEYSIZE = 128; // 生成AES密钥, 默认长度为128位(16字节).
private static final int DEFAULT_IVSIZE = 16; // 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节
private static final int DEFAULT_KEY_SIZE = 128; // 生成AES密钥, 默认长度为128位(16字节).
private static final int DEFAULT_IV_SIZE = 16; // 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节
private static final SecureRandom RANDOM = new SecureRandom(); // 用于 生成 generateIV随机数对象
private static final byte[] DEFAULT_KEY = new byte[]{-97,88,-94,9,70,-76,126,25,0,3,-20,113,108,28,69,125};
private static final byte[] DEFAULT_KEY = EncodeUtils.decodeHex(PropertiesUtils.getInstance()
.getProperty("encrypt.defaultKey", "9f58a20946b47e190003ec716c1c457d"));
private static final boolean STORE_BASE64 = PropertiesUtils.getInstance()
.getPropertyToBoolean("encrypt.storeBase64", "false");
/**
* 生成AES密钥,返回字节数组, 默认长度为128位(16字节).
*/
public static String genKeyString() {
return EncodeUtils.encodeHex(genKey(DEFAULT_AES_KEYSIZE));
}
/**
* 使用AES加密原始字符串.
*
* @param input 原始输入字符数组
*/
public static String encode(String input) {
try {
return EncodeUtils.encodeHex(encode(input.getBytes(EncodeUtils.UTF_8), DEFAULT_KEY));
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES加密原始字符串.
*
* @param input 原始输入字符数组
* @param key 符合AES要求的密钥
*/
public static String encode(String input, String key) {
try {
return EncodeUtils.encodeHex(encode(input.getBytes(EncodeUtils.UTF_8), EncodeUtils.decodeHex(key)));
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex编码的加密字符串
*/
public static String decode(String input) {
try {
return new String(decode(EncodeUtils.decodeHex(input), DEFAULT_KEY), EncodeUtils.UTF_8);
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex编码的加密字符串
* @param key 符合AES要求的密钥
*/
public static String decode(String input, String key) {
try {
return new String(decode(EncodeUtils.decodeHex(input), EncodeUtils.decodeHex(key)), EncodeUtils.UTF_8);
} catch (UnsupportedEncodingException e) {
return "";
}
}
/**
* 生成AES密钥,返回字节数组, 默认长度为128位(16字节).
* 生成 AES 密钥,返回字节数组, 默认长度为128位(16字节)
*/
public static byte[] genKey() {
return genKey(DEFAULT_AES_KEYSIZE);
return genKey(DEFAULT_KEY_SIZE);
}
/**
* 生成AES密钥,可选长度为128,192,256位.
* 生成 AES 密钥, 返回字节数组, 默认长度为128位(16字节)
*/
public static byte[] genKey(int keysize) {
public static String genKeyString() {
return EncodeUtils.encodeHex(genKey());
}
/**
* 生成 AES 密钥, 可选长度为128,192,256位
*/
public static byte[] genKey(int keySize) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
keyGenerator.init(keysize);
keyGenerator.init(keySize);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (GeneralSecurityException e) {
throw ExceptionUtils.unchecked(e);
}
}
/**
* 生成随机向量,默认大小为cipher.getBlockSize(), 16字节.
* 生成随机向量, 默认大小为cipher.getBlockSize(), 16字节
*/
public static byte[] genIV() {
byte[] bytes = new byte[DEFAULT_IVSIZE];
byte[] bytes = new byte[DEFAULT_IV_SIZE];
RANDOM.nextBytes(bytes);
return bytes;
}
/**
* 使用 AES 加密原始字符串
* @param input 原始输入字符串
* @author ThinkGem
*/
public static String encode(String input) {
if (STORE_BASE64) {
return EncodeUtils.encodeBase64(encode(input.getBytes(StandardCharsets.UTF_8), DEFAULT_KEY));
}
return EncodeUtils.encodeHex(encode(input.getBytes(StandardCharsets.UTF_8), DEFAULT_KEY));
}
/**
* 使用AES加密原始字符串.
*
* 使用 AES 加密原始字符串
* @param input 原始输入字符数组
* @param key 符合AES要求的密钥
* @param key 符合要求的密钥
* @author ThinkGem
*/
public static byte[] encode(byte[] input, byte[] key) {
return aes(input, key, Cipher.ENCRYPT_MODE);
}
/**
* 使用AES加密原始字符串.
*
* 使用 AES 加密原始字符串
* @param input 原始输入字符串
* @param key 符合要求的密钥
* @author ThinkGem
*/
public static String encode(String input, String key) {
if (STORE_BASE64) {
return EncodeUtils.encodeBase64(encode(input.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(key)));
}
return EncodeUtils.encodeHex(encode(input.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(key)));
}
/**
* 使用 AES 加密原始字符串
* @param input 原始输入字符数组
* @param key 符合AES要求的密钥
* @param key 符合要求的密钥
* @param iv 初始向量
* @author ThinkGem
*/
public static byte[] encode(byte[] input, byte[] key, byte[] iv) {
return aes(input, key, iv, Cipher.ENCRYPT_MODE);
}
/**
* 使用 AES 解密数据, 返回原始字符串
* @param input Hex 或 Base64 编码的加密字符串
* @author ThinkGem
*/
public static String decode(String input) {
if (STORE_BASE64) {
return new String(decode(EncodeUtils.decodeBase64(input), DEFAULT_KEY), StandardCharsets.UTF_8);
}
return new String(decode(EncodeUtils.decodeHex(input), DEFAULT_KEY), StandardCharsets.UTF_8);
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* @param input Hex编码的加密字符串
* @param key 符合AES要求的密钥
* 使用 AES 解密数据, 返回原始字符串
* @param input 加密输入字符数组
* @param key 符合要求的密钥
* @author ThinkGem
*/
public static byte[] decode(byte[] input, byte[] key) {
return aes(input, key, Cipher.DECRYPT_MODE);
}
/**
* 使用AES解密字符串, 返回原始字符串.
*
* 使用 AES 解密数据, 返回原始字符串
* @param input Hex 或 Base64 编码的加密字符串
* @param key 符合要求的密钥
* @author ThinkGem
*/
public static String decode(String input, String key) {
if (STORE_BASE64) {
return new String(decode(EncodeUtils.decodeBase64(input), EncodeUtils.decodeHex(key)), StandardCharsets.UTF_8);
}
return new String(decode(EncodeUtils.decodeHex(input), EncodeUtils.decodeHex(key)), StandardCharsets.UTF_8);
}
/**
* 使用 AES 解密数据, 返回原始字符串
* @param input Hex编码的加密字符串
* @param key 符合AES要求的密钥
* @param iv 初始向量
* @author ThinkGem
*/
public static byte[] decode(byte[] input, byte[] key, byte[] iv) {
return aes(input, key, iv, Cipher.DECRYPT_MODE);
}
/**
* 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果.
*
* 使用 AES 加密或解密无编码的原始字节数组, 返回无编码的字节数组结果
* @param input 原始字节数组
* @param key 符合AES要求的密钥
* @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
* @author ThinkGem
*/
private static byte[] aes(byte[] input, byte[] key, int mode) {
try {
SecretKey secretKey = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES);
SecretKey secretKey = new SecretKeySpec(key, AES);
cipher.init(mode, secretKey);
return cipher.doFinal(input);
} catch (GeneralSecurityException e) {
@@ -182,18 +181,18 @@ public class AesUtils {
}
/**
* 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果.
*
* 使用 AES 加密或解密无编码的原始字节数组, 返回无编码的字节数组结果
* @param input 原始字节数组
* @param key 符合AES要求的密钥
* @param iv 初始向量
* @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE
* @author ThinkGem
*/
private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mode) {
try {
Cipher cipher = Cipher.getInstance(AES_CBC);
SecretKey secretKey = new SecretKeySpec(key, AES);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance(AES_CBC);
cipher.init(mode, secretKey, ivSpec);
return cipher.doFinal(input);
} catch (GeneralSecurityException e) {
@@ -201,18 +200,4 @@ public class AesUtils {
}
}
// public static void main(String[] args) {
//
// String s = "hello word!";
// System.out.println(s);
//
// String k = genKeyString();
// System.out.println(k);
// String ss = encode(s, k);
// System.out.println(ss);
// String sss = decode(ss, k);
// System.out.println(sss);
//
// }
}

View File

@@ -4,15 +4,13 @@
*/
package com.jeesite.common.codec;
import com.jeesite.common.lang.ExceptionUtils;
import org.apache.commons.lang3.Validate;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import org.apache.commons.lang3.Validate;
import com.jeesite.common.lang.ExceptionUtils;
import java.security.*;
/**
* 不可逆加密工具类
@@ -20,11 +18,15 @@ import com.jeesite.common.lang.ExceptionUtils;
*/
public class DigestUtils {
private static SecureRandom random = new SecureRandom();
public static final String SHA1 = "SHA-1";
public static final String MD5 = "MD5";
public static final String SM3 = "SM3";
private static final SecureRandom random = new SecureRandom();
/**
* 生成随机的Byte[]作为salt密钥.
* @param numBytes byte数组的大小
* 生成随机的 Byte[] 作为 salt 密钥.
* @param numBytes byte 数组的大小
*/
public static byte[] genSalt(int numBytes) {
Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", numBytes);
@@ -32,25 +34,41 @@ public class DigestUtils {
random.nextBytes(bytes);
return bytes;
}
/**
* 生成随机的 Byte[] 作为 salt 密钥,返回 HEX 值
* @param numBytes byte 数组的大小
*/
public static String genSaltString(int numBytes) {
return EncodeUtils.encodeHex(genSalt(numBytes));
}
/**
* 获取 MessageDigest
*/
private static MessageDigest getMessageDigest(String algorithm) throws GeneralSecurityException {
if (SM3.equals(algorithm)) {
return MessageDigest.getInstance(algorithm, BouncyCastleProvider.PROVIDER_NAME);
} else {
return MessageDigest.getInstance(algorithm);
}
}
/**
* 对字符串进行散列, 支持md5与sha1算法.
* @param input 需要散列的字符串
* @param algorithm 散列算法("SHA-1"、"MD5"
* @param salt
* @param algorithm 散列算法("SHA-1"、"MD5"、"SM3"
* @param salt 可为空
* @param iterations 迭代次数
* @return
*/
public static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
MessageDigest digest = getMessageDigest(algorithm);
if (salt != null) {
digest.update(salt);
}
byte[] result = digest.digest(input);
for (int i = 1; i < iterations; i++) {
digest.reset();
result = digest.digest(result);
@@ -64,20 +82,18 @@ public class DigestUtils {
/**
* 对文件进行sha1散列.
* @param input 需要散列的流
* @param algorithm 散列算法("SHA-1"、"MD5"
* @param algorithm 散列算法("SHA-1"、"MD5"、"SM3"
*/
public static byte[] digest(InputStream input, String algorithm) throws IOException {
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
MessageDigest messageDigest = getMessageDigest(algorithm);
int bufferLength = 8 * 1024;
byte[] buffer = new byte[bufferLength];
int read = input.read(buffer, 0, bufferLength);
while (read > -1) {
messageDigest.update(buffer, 0, read);
read = input.read(buffer, 0, bufferLength);
}
return messageDigest.digest();
} catch (GeneralSecurityException e) {
throw ExceptionUtils.unchecked(e);

View File

@@ -26,11 +26,11 @@ import java.util.regex.Pattern;
/**
* 封装各种格式的编码解码工具类.
* 1.Commons-Codec的 hex/base64 编码
* 2.自制的base62 编码
* 3.Commons-Langxml/html escape
* 4.JDK提供的URLEncoder
* 5XSS、SQL、orderBy 过滤器
* 1. Commons-Codec 的 hex/base64 编码
* 2. 自制的 base62 编码
* 3. Commons-Langxml/html escape
* 4. JDK 提供的 URLEncoder
* 5. XSS、SQL、orderBy 过滤器
* @author calvin、ThinkGem
* @version 2022-2-17
*/
@@ -226,7 +226,6 @@ public class EncodeUtils {
// 如果开始不是HTMLXMLJOSN格式则再进行HTML的 "、<、> 转码。
if (!StringUtils.startsWithIgnoreCase(value, "<!--HTML-->") // HTML
&& !StringUtils.startsWithIgnoreCase(value, "<?xml ") // XML
&& !StringUtils.contains(value, "id=\"FormHtml\"") // JFlow
&& !(StringUtils.startsWith(value, "{") && StringUtils.endsWith(value, "}")) // JSON Object
&& !(StringUtils.startsWith(value, "[") && StringUtils.endsWith(value, "]")) // JSON Array
){
@@ -267,7 +266,8 @@ public class EncodeUtils {
"(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|((extractvalue|updatexml|if|mid|database|rand|user)([\\s]*?)\\()"
+ "|(\\b(select|update|and|or|delete|insert|trancate|substr|ascii|declare|exec|count|master|into"
+ "|drop|execute|case when|sleep|union|load_file)\\b)", Pattern.CASE_INSENSITIVE);
private static final Pattern orderByPattern = Pattern.compile("[a-z0-9_\\.\\, ]*", Pattern.CASE_INSENSITIVE);
private static final Pattern simplePattern = Pattern.compile("[a-z0-9_\\.\\, ]*", Pattern.CASE_INSENSITIVE);
private static final Pattern columnNamePattern = Pattern.compile("[a-z0-9_\\.`\"\\[\\]]*", Pattern.CASE_INSENSITIVE);
/**
* SQL过滤防止注入传入参数输入有select相关代码替换空。
@@ -284,8 +284,13 @@ public class EncodeUtils {
public static String sqlFilter(String text, String source){
if (text != null){
String value = text;
if ("orderBy".equals(source)) {
Matcher matcher = orderByPattern.matcher(value);
if (StringUtils.inString(source, "simple", "orderBy")) {
Matcher matcher = simplePattern.matcher(value);
if (!matcher.matches()) {
value = StringUtils.EMPTY;
}
} else if (StringUtils.inString(source, "columnName")) {
Matcher matcher = columnNamePattern.matcher(value);
if (!matcher.matches()) {
value = StringUtils.EMPTY;
}
@@ -304,38 +309,4 @@ public class EncodeUtils {
return null;
}
// public static void main(String[] args) {
// xssFilter("1 你好 <script>alert(document.cookie)</script>我还在。");
// xssFilter("2 你好 <strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->3 你好 \"><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->4 你好 <iframe src=\"abcdef\"></iframe><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->5 你好 <iframe src=\"abcdef\"/><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->6 你好 <iframe src=\"abcdef\"><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->7 你好 <script type=\"text/javascript\">alert(document.cookie)</script>我还在。");
// xssFilter("<!--HTML-->8 你好 <script\n type=\"text/javascript\">\nalert(document.cookie)\n</script>我还在。");
// xssFilter("<!--HTML-->9 你好 <script src='' onerror='alert(document.cookie)'></script>我还在。");
// xssFilter("<!--HTML-->10 你好 <script type=text/javascript>alert()我还在。");
// xssFilter("<!--HTML-->11 你好 <script>alert(document.cookie)</script>我还在。");
// xssFilter("<!--HTML-->12 你好 <script>window.location='url'我还在。");
// xssFilter("<!--HTML-->13 你好 </script></iframe>我还在。");
// xssFilter("<!--HTML-->14 你好 eval(abc)我还在。");
// xssFilter("<!--HTML-->15 你好 expression(abc)我还在。");
// xssFilter("<!--HTML-->16 你好 <img src='abc.jpg' onerror='location='';alert(document.cookie);'></img>我还在。");
// xssFilter("<!--HTML-->17 你好 <img src='abc.jpg' onerror='alert(document.cookie);'/>我还在。");
// xssFilter("<!--HTML-->18 你好 <img src='abc.jpg' onerror='alert(document.cookie);'>我还在。");
// xssFilter("<!--HTML-->19 你好 <a onload='alert(\"abc\")'>hello</a>我还在。");
// xssFilter("<!--HTML-->20 你好 <a href=\"/abc\">hello</a>我还在。");
// xssFilter("<!--HTML-->21 你好 <a href='/abc'>hello</a>我还在。");
// xssFilter("<!--HTML-->22 你好 <a href='vbscript:alert(\"abc\");'>hello</a>我还在。");
// xssFilter("<!--HTML-->23 你好 <a href='javascript:alert(\"abc\");'>hello</a>我还在。");
// xssFilter("<!--HTML-->24 你好 ?abc=def&hello=123&world={\"a\":1}我还在。");
// xssFilter("<!--HTML-->25 你好 ?abc=def&hello=123&world={'a':1}我还在。");
// sqlFilter("1 你好 select * from xxx where abc=def and 1=1我还在。");
// sqlFilter("2 你好 insert into xxx values(1,2,3,4,5)我还在。");
// sqlFilter("3 你好 delete from xxx我还在。");
// sqlFilter("4 a.audit_result asc,case when 1 like case when length(database())=6 then 1 else exp(111) end then 1 else 1/0 end", "orderBy");
// sqlFilter("5 if(1=2,1,SLEEP(10)), if(mid(database(),{},1)=\\\"{}\\\",a.id,a.login_name)", "orderBy");
// sqlFilter("6 a.audit_result asc, b.audit_result2 desc, b.AuditResult3 desc", "orderBy");
// }
}

View File

@@ -4,22 +4,25 @@
*/
package com.jeesite.common.codec;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import com.jeesite.common.lang.StringUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* MD5不可逆加密工具类
* @author ThinkGem
*/
public class Md5Utils {
private static final String MD5 = "MD5";
/**
* 对输入字符串进行md5散列.
* @param input 加密字符串
*/
public static byte[] md5(byte[] input) {
return md5(input, 1);
}
/**
* 对输入字符串进行md5散列.
* @param input 加密字符串
@@ -33,36 +36,24 @@ public class Md5Utils {
* @param input 加密字符串
* @param iterations 迭代次数
*/
public static String md5(String input, int iterations) {
try {
return EncodeUtils.encodeHex(DigestUtils.digest(input.getBytes(EncodeUtils.UTF_8), MD5, null, iterations));
} catch (UnsupportedEncodingException e) {
return StringUtils.EMPTY;
}
public static byte[] md5(byte[] input, int iterations) {
return DigestUtils.digest(input, DigestUtils.MD5, null, iterations);
}
/**
* 对输入字符串进行md5散列.
* @param input 加密字符串
*/
public static byte[] md5(byte[] input) {
return md5(input, 1);
}
/**
* 对输入字符串进行md5散列.
* @param input 加密字符串
* @param iterations 迭代次数
*/
public static byte[] md5(byte[] input, int iterations) {
return DigestUtils.digest(input, MD5, null, iterations);
public static String md5(String input, int iterations) {
return EncodeUtils.encodeHex(DigestUtils.digest(input.getBytes(StandardCharsets.UTF_8), DigestUtils.MD5, null, iterations));
}
/**
* 对文件进行md5散列.
*/
public static byte[] md5(InputStream input) throws IOException {
return DigestUtils.digest(input, MD5);
return DigestUtils.digest(input, DigestUtils.MD5);
}
/**

View File

@@ -0,0 +1,185 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.common.codec;
import com.jeesite.common.io.PropertiesUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA 加密解密工具类,非对称加密
* @author ThinkGem
*/
public class RsaUtils {
private static final String RSA = "RSA";
private static final String algorithm = "SHA256withRSA";
private static final boolean STORE_BASE64 = PropertiesUtils.getInstance()
.getPropertyToBoolean("encrypt.storeBase64", "false");
/**
* 生成 RSA 秘钥对
*/
public static String[] genKeys() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA);
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
return new String[]{
EncodeUtils.encodeBase64(publicKey.getEncoded()),
EncodeUtils.encodeBase64(privateKey.getEncoded()),
};
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 将 Base64 公钥串,转化为公钥对象
* @author ThinkGem
*/
public static PublicKey toPublicKey(String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(EncodeUtils.decodeBase64(publicKey));
return keyFactory.generatePublic(publicKeySpec);
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 将 Base64 私钥串,转化为私钥对象
* @author ThinkGem
*/
public static PrivateKey toPrivateKey(String privateKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(EncodeUtils.decodeBase64(privateKey));
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 公钥加密
* @author ThinkGem
*/
public static byte[] encode(byte[] input, PublicKey publicKey) {
try {
Cipher encryptCipher = Cipher.getInstance(RSA);
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
return encryptCipher.doFinal(input);
} catch (InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException |
NoSuchAlgorithmException | BadPaddingException e) {
throw new RuntimeException(e);
}
}
/**
* 公钥加密
* @author ThinkGem
*/
public static String encode(String input, PublicKey publicKey) {
if (STORE_BASE64) {
return EncodeUtils.encodeBase64(encode(input.getBytes(StandardCharsets.UTF_8), publicKey));
}
return EncodeUtils.encodeHex(encode(input.getBytes(StandardCharsets.UTF_8), publicKey));
}
/**
* 私钥解密
* @author ThinkGem
*/
public static byte[] decode(byte[] input, PrivateKey privateKey) {
return decodeImpl(input, privateKey);
}
private static byte[] decodeImpl(byte[] input, PrivateKey privateKey) {
try {
Cipher decryptCipher = Cipher.getInstance(RSA);
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
return decryptCipher.doFinal(input);
} catch (InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException |
NoSuchAlgorithmException | BadPaddingException e) {
throw new RuntimeException(e);
}
}
/**
* 私钥解密
* @author ThinkGem
*/
public static String decode(String input, PrivateKey privateKey) {
if (STORE_BASE64) {
return new String(decode(EncodeUtils.decodeBase64(input), privateKey), StandardCharsets.UTF_8);
}
return new String(decode(EncodeUtils.decodeHex(input), privateKey), StandardCharsets.UTF_8);
}
/**
* 私钥签名
* @author ThinkGem
*/
public static byte[] sign(byte[] input, PrivateKey privateKey) {
try {
Signature sig = Signature.getInstance(algorithm);
sig.initSign(privateKey);
sig.update(input);
return sig.sign();
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
throw new RuntimeException(e);
}
}
/**
* 私钥签名
* @author ThinkGem
*/
public static String sign(String input, PrivateKey privateKey) {
if (STORE_BASE64) {
return EncodeUtils.encodeBase64(sign(input.getBytes(StandardCharsets.UTF_8), privateKey));
}
return EncodeUtils.encodeHex(sign(input.getBytes(StandardCharsets.UTF_8), privateKey));
}
/**
* 公钥验签
* @author ThinkGem
*/
public static boolean verify(byte[] input, PublicKey publicKey, byte[] signature) {
try {
Signature sig = Signature.getInstance(algorithm);
sig.initVerify(publicKey);
sig.update(input);
return sig.verify(signature);
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
throw new RuntimeException(e);
}
}
/**
* 公钥验签
* @author ThinkGem
*/
public static boolean verify(String input, PublicKey publicKey, String signature) {
if (STORE_BASE64) {
return verify(input.getBytes(StandardCharsets.UTF_8), publicKey, EncodeUtils.decodeBase64(signature));
}
return verify(input.getBytes(StandardCharsets.UTF_8), publicKey, EncodeUtils.decodeHex(signature));
}
}

View File

@@ -6,17 +6,16 @@ package com.jeesite.common.codec;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
/**
* SHA-1不可逆加密工具类
* SHA-1 加密工具类,散列加密,不可逆加密
* @author ThinkGem
*/
public class Sha1Utils {
private static final String SHA1 = "SHA-1";
/**
* 生成随机的Byte[]作为salt密钥.
* 生成随机的 Byte[] 作为 salt 密钥.
* @param numBytes byte数组的大小
*/
public static byte[] genSalt(int numBytes) {
@@ -24,31 +23,60 @@ public class Sha1Utils {
}
/**
* 对输入字符串进行sha1散列.
* 生成随机的 Byte[] 作为 salt 密钥,返回 HEX 值
* @param numBytes byte 数组的大小
*/
public static String genSaltString(int numBytes) {
return DigestUtils.genSaltString(numBytes);
}
/**
* 对输入字符串进行 SHA-1 散列.
*/
public static byte[] sha1(byte[] input) {
return DigestUtils.digest(input, SHA1, null, 1);
return DigestUtils.digest(input, DigestUtils.SHA1, null, 1);
}
/**
* 对输入字符串进行sha1散列.
* 对输入字符串进行 SHA-1 散列.
*/
public static String sha1(String input) {
return EncodeUtils.encodeHex(sha1(input.getBytes(StandardCharsets.UTF_8)));
}
/**
* 对输入字符串进行 SHA-1 散列.
*/
public static byte[] sha1(byte[] input, byte[] salt) {
return DigestUtils.digest(input, SHA1, salt, 1);
return DigestUtils.digest(input, DigestUtils.SHA1, salt, 1);
}
/**
* 对输入字符串进行sha1散列.
* 对输入字符串进行 SHA-1 散列.
*/
public static String sha1(String data, String salt) {
return EncodeUtils.encodeHex(sha1(data.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(salt)));
}
/**
* 对输入字符串进行 SHA-1 散列.
*/
public static byte[] sha1(byte[] input, byte[] salt, int iterations) {
return DigestUtils.digest(input, SHA1, salt, iterations);
return DigestUtils.digest(input, DigestUtils.SHA1, salt, iterations);
}
/**
* 对文件进行sha1散列.
* 对输入字符串进行 SHA-1 散列.
*/
public static String sha1(String input, String salt, int iterations) {
return EncodeUtils.encodeHex(sha1(input.getBytes(StandardCharsets.UTF_8), EncodeUtils.decodeHex(salt), iterations));
}
/**
* 对文件进行 SHA-1 散列.
*/
public static byte[] sha1(InputStream input) throws IOException {
return DigestUtils.digest(input, SHA1);
return DigestUtils.digest(input, DigestUtils.SHA1);
}
}

View File

@@ -41,7 +41,7 @@ public class PropertiesUtils {
"file:bootstrap.yml", "file:config/bootstrap.yml",
};
private static Logger logger = PropertiesUtils.initLogger();
private static final Logger logger = PropertiesUtils.initLogger();
private final Set<String> configSet = SetUtils.newLinkedHashSet();
private final Properties properties = new Properties();
private static Environment environment;
@@ -174,7 +174,7 @@ public class PropertiesUtils {
private static final Pattern p1 = Pattern.compile("\\$\\{.*?\\}");
/**
* 获取属性值取不到从System.getProperty()获取都取不到返回null
* 获取属性值取不到从System.getProperty和System.getenv获取都取不到返回null
*/
public String getProperty(String key) {
if (environment != null){
@@ -196,9 +196,10 @@ public class PropertiesUtils {
String systemProperty = System.getProperty(key);
if (systemProperty != null) {
return systemProperty;
}else{
return System.getenv(key);
}
}
return null;
}
/**

View File

@@ -28,6 +28,8 @@ public class ExceptionUtils {
ex = (Throwable) request.getAttribute("exception");
} else if (request.getAttribute(RequestDispatcher.ERROR_EXCEPTION) != null) {
ex = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
} else if (request.getAttribute("org.springframework.web.servlet.DispatcherServlet.EXCEPTION") != null) {
ex = (Throwable) request.getAttribute("org.springframework.web.servlet.DispatcherServlet.EXCEPTION");
}
return ex;
}

View File

@@ -24,7 +24,7 @@ import java.lang.reflect.InvocationTargetException;
*/
public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
private static Logger logger = LoggerFactory.getLogger(ObjectUtils.class);
private static final Logger logger = LoggerFactory.getLogger(ObjectUtils.class);
private static final boolean isJavaSerialize;
static {
@@ -73,14 +73,37 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
* 转换为 Long 类型
*/
public static Long toLong(final Object val) {
return toDouble(val).longValue();
if (val == null) {
return 0L;
}
try {
String str = val.toString();
if (StringUtils.isBlank(str)) {
return 0L;
}
if (StringUtils.contains(str, "*")) {
Long number = null, d = null;
for (String s : StringUtils.split(str, "*")) {
d = Long.parseLong(StringUtils.trim(s));
if (number == null) {
number = d;
} else {
number *= d;
}
}
return number;
}
return Long.parseLong(StringUtils.trim(str));
} catch (Exception e) {
return 0L;
}
}
/**
* 转换为 Integer 类型
*/
public static Integer toInteger(final Object val) {
return toDouble(val).intValue();
return toLong(val).intValue();
}
/**
@@ -122,7 +145,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
*/
public static String toStringIgnoreNull(final Object val, String defaultVal) {
String str = ObjectUtils.toString(val);
return !"".equals(str) && !"null".equals(str.trim().toLowerCase()) ? str : defaultVal;
return !"".equals(str) && !"null".equalsIgnoreCase(str.trim()) ? str : defaultVal;
}
/**
@@ -153,8 +176,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
return null;
}
byte[] bytes = ObjectUtils.serialize(source);
Object target = ObjectUtils.unserialize(bytes);
return target;
return ObjectUtils.unserialize(bytes);
}
/**

View File

@@ -26,6 +26,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
public static final String COLON = ":";
public static final String TILDE = "~";
public static final String UNDERLINE = "_";
public static final String MINUS = "-";
/**
* 分隔字符串(逗号分隔)
@@ -284,7 +285,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == UNDERLINE.charAt(0)) {
if (c == UNDERLINE.charAt(0) || c == MINUS.charAt(0)) {
upperCase = i != 1; // 不允许第二个字符是大写
} else if (upperCase) {
sb.append(Character.toUpperCase(c));

View File

@@ -50,7 +50,7 @@ public class JsonMapper extends ObjectMapper {
private static final class JsonMapperHolder {
private static final JsonMapper INSTANCE = new JsonMapper();
}
public JsonMapper() {
// Spring ObjectMapper 初始化配置,支持 @JsonView
new Jackson2ObjectMapperBuilder().configure(this);
@@ -182,8 +182,8 @@ public class JsonMapper extends ObjectMapper {
* 反序列化POJO或简单Collection如List<String>.
* 如果JSON字符串为Null或"null"字符串, 返回Null.
* 如果JSON字符串为"[]", 返回空集合.
* 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)
* @see #fromJson(String, JavaType)
* 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String, Class)
* @see #fromJson(String, Class)
*/
public <T> T fromJsonString(String jsonString, Class<T> clazz) {
if (StringUtils.isEmpty(jsonString) || "<CLOB>".equals(jsonString)) {

View File

@@ -16,7 +16,7 @@ import com.jeesite.common.io.PropertiesUtils;
*/
public class EmailUtils {
private final static Logger logger = LoggerFactory.getLogger(EmailUtils.class);
private static final Logger logger = LoggerFactory.getLogger(EmailUtils.class);
/**
* 发送邮件

View File

@@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory;
*/
public class SmsUtils {
private final static Logger logger = LoggerFactory.getLogger(SmsUtils.class);
private static final Logger logger = LoggerFactory.getLogger(SmsUtils.class);
/**
* 模拟发送短信

View File

@@ -77,7 +77,6 @@ public class ReflectUtils {
//Method method = getAccessibleMethodByName(object, methodName, 0);
//if (method == null) { return; }
//Class<?> returnType = method.getReturnType();
System.out.println(object.getClass());
MethodAccess ma = MethodAccess.get(object.getClass());
Class<?> returnType = ma.getReturnTypes()[ma.getIndex(methodName)];
childObj = returnType.getDeclaredConstructor().newInstance();

View File

@@ -39,12 +39,12 @@ import java.util.*;
*/
public class ExcelExport implements Closeable{
private static Logger log = LoggerFactory.getLogger(ExcelExport.class);
private static final Logger log = LoggerFactory.getLogger(ExcelExport.class);
/**
* 工作薄对象
*/
private Workbook wb;
private final Workbook wb;
/**
* 工作表对象
@@ -59,7 +59,7 @@ public class ExcelExport implements Closeable{
/**
* 当前行号
*/
private int rownum;
private int rowNum;
/**
* 注解列表Object[]{ ExcelField, Field/Method }
@@ -69,7 +69,7 @@ public class ExcelExport implements Closeable{
/**
* 存储字段类型临时数据
*/
private Map<Class<? extends FieldType>, FieldType> fieldTypes = MapUtils.newHashMap();
private final Map<Class<? extends FieldType>, FieldType> fieldTypes = MapUtils.newHashMap();
@SuppressWarnings("rawtypes")
private static Class dictUtilsClass = null;
@@ -158,6 +158,16 @@ public class ExcelExport implements Closeable{
}
this.createSheet(sheetName, title, headerList, headerWidthList);
}
/**
* 构造函数
*/
public ExcelExport(ExcelImport excelImport) {
this.wb = excelImport.getWorkbook();
this.styles = createStyles(wb);
this.sheet = excelImport.getSheet();
this.rowNum = excelImport.getHeaderNum();
}
/**
* 创建一个工作簿
@@ -184,6 +194,13 @@ public class ExcelExport implements Closeable{
*/
public void createSheet(String sheetName, String title, Class<?> cls, Type type, String... groups){
this.annotationList = ListUtils.newArrayList();
// Get class annotation
ExcelFields cfs = cls.getAnnotation(ExcelFields.class);
if (cfs != null && cfs.value() != null){
for (ExcelField ef : cfs.value()){
addAnnotation(annotationList, ef, cfs, type, groups);
}
}
// Get constructor annotation
Constructor<?>[] cs = cls.getConstructors();
for (Constructor<?> c : cs) {
@@ -286,12 +303,12 @@ public class ExcelExport implements Closeable{
* @param headerWidthList 表头字段宽度设置
*/
public void createSheet(String sheetName, String title, List<String> headerList, List<Integer> headerWidthList) {
this.sheet = wb.createSheet(StringUtils.defaultString(sheetName, StringUtils.defaultString(title, "Sheet1")));
this.sheet = wb.createSheet(StringUtils.defaultIfBlank(sheetName, StringUtils.defaultIfBlank(title, "Sheet1")));
this.styles = createStyles(wb);
this.rownum = 0;
this.rowNum = 0;
// Create title
if (StringUtils.isNotBlank(title)){
Row titleRow = sheet.createRow(rownum++);
Row titleRow = sheet.createRow(rowNum++);
titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("title"));
@@ -303,7 +320,7 @@ public class ExcelExport implements Closeable{
if (headerList == null){
throw new ExcelException("headerList not null!");
}
Row headerRow = sheet.createRow(rownum++);
Row headerRow = sheet.createRow(rowNum++);
headerRow.setHeightInPoints(16);
for (int i = 0; i < headerList.size(); i++) {
Cell cell = headerRow.createCell(i);
@@ -412,7 +429,7 @@ public class ExcelExport implements Closeable{
* @return 行对象
*/
public Row addRow(){
return sheet.createRow(rownum++);
return sheet.createRow(rowNum++);
}
/**
@@ -633,54 +650,5 @@ public class ExcelExport implements Closeable{
e.printStackTrace();
}
}
// /**
// * 导出测试
// */
// public static void main(String[] args) throws Throwable {
//
// // 初始化表头
// List<String> headerList = ListUtils.newArrayList();
// for (int i = 1; i <= 10; i++) {
// headerList.add("表头"+i);
// }
//
// // 初始化数据集
// List<String> rowList = ListUtils.newArrayList();
// for (int i = 1; i <= headerList.size(); i++) {
// rowList.add("数据"+i);
// }
// List<List<String>> dataList = ListUtils.newArrayList();
// for (int i = 1; i <=100; i++) {
// dataList.add(rowList);
// }
//
// // 创建一个Sheet表并导入数据
// try(ExcelExport ee = new ExcelExport("表格1", "表格标题1", headerList, null)){
//
// for (int i = 0; i < dataList.size(); i++) {
// Row row = ee.addRow();
// for (int j = 0; j < dataList.get(i).size(); j++) {
// ee.addCell(row, j, dataList.get(i).get(j));
// }
// }
//
// // 再创建一个Sheet表并导入数据
// ee.createSheet("表格2", "表格标题2", headerList, null);
// for (int i = 0; i < dataList.size(); i++) {
// Row row = ee.addRow();
// for (int j = 0; j < dataList.get(i).size(); j++) {
// ee.addCell(row, j, dataList.get(i).get(j)+"2");
// }
// }
//
// // 输出到文件
// ee.writeFile("target/export.xlsx");
//
// }
//
// log.debug("Export success.");
//
// }
}

View File

@@ -41,12 +41,12 @@ import java.util.*;
*/
public class ExcelImport implements Closeable {
private static Logger log = LoggerFactory.getLogger(ExcelImport.class);
private static final Logger log = LoggerFactory.getLogger(ExcelImport.class);
/**
* 工作薄对象
*/
private Workbook wb;
private final Workbook wb;
/**
* 工作表对象
@@ -61,20 +61,39 @@ public class ExcelImport implements Closeable {
/**
* 存储字段类型临时数据
*/
private Map<Class<? extends FieldType>, FieldType> fieldTypes = MapUtils.newHashMap();
private final Map<Class<? extends FieldType>, FieldType> fieldTypes = MapUtils.newHashMap();
@SuppressWarnings("rawtypes")
private static Class dictUtilsClass = null;
/**
* 构造函数
* @param path 导入文件对象,读取第一个工作表
* @param fileName 导入文件对象,读取第一个工作表
* @throws InvalidFormatException
* @throws IOException
*/
public ExcelImport(String fileName) throws InvalidFormatException, IOException {
this(new File(fileName));
}
/**
* 构造函数
* @param file 导入文件对象,读取第一个工作表
* @throws InvalidFormatException
* @throws IOException
*/
public ExcelImport(File file) throws InvalidFormatException, IOException {
this(file, 0, 0);
}
/**
* 构造函数
* @param fileName 导入文件对象,读取第一个工作表
* @throws InvalidFormatException
* @throws IOException
*/
public ExcelImport(String fileName, int headerNum) throws InvalidFormatException, IOException {
this(new File(fileName), headerNum);
}
/**
* 构造函数
@@ -88,6 +107,19 @@ public class ExcelImport implements Closeable {
this(file, headerNum, 0);
}
/**
* 构造函数
* @param fileName 导入文件对象
* @param headerNum 标题行数,数据行号=标题行数+1
* @param sheetIndexOrName 工作表编号或名称从0开始
* @throws InvalidFormatException
* @throws IOException
*/
public ExcelImport(String fileName, int headerNum, Object sheetIndexOrName)
throws InvalidFormatException, IOException {
this(new File(fileName), headerNum, sheetIndexOrName);
}
/**
* 构造函数
* @param file 导入文件对象
@@ -170,7 +202,21 @@ public class ExcelImport implements Closeable {
public Workbook getWorkbook() {
return wb;
}
/**
* 获取当前工作表
*/
public Sheet getSheet() {
return sheet;
}
/**
* 获取当前标题行数
*/
public int getHeaderNum() {
return headerNum;
}
/**
* 设置当前工作表和标题行数
* @author ThinkGem
@@ -339,6 +385,13 @@ public class ExcelImport implements Closeable {
@SuppressWarnings("unchecked")
public <E> List<E> getDataList(Class<E> cls, MethodCallback exceptionCallback, String... groups) throws Exception{
List<Object[]> annotationList = ListUtils.newArrayList();
// Get class annotation
ExcelFields cfs = cls.getAnnotation(ExcelFields.class);
if (cfs != null && cfs.value() != null){
for (ExcelField ef : cfs.value()){
addAnnotation(annotationList, ef, cls, Type.IMPORT, groups);
}
}
// Get constructor annotation
Constructor<?>[] cs = cls.getConstructors();
for (Constructor<?> c : cs) {
@@ -528,25 +581,4 @@ public class ExcelImport implements Closeable {
}
}
// /**
// * 导入测试
// */
// public static void main(String[] args) throws Throwable {
//
// ImportExcel ei = new ImportExcel("target/export.xlsx", 1);
//
// for (int i = ei.getDataRowNum(); i < ei.getLastDataRowNum(); i++) {
// Row row = ei.getRow(i);
// if (row == null){
// continue;
// }
// for (int j = 0; j < ei.getLastCellNum(); j++) {
// Object val = ei.getCellValue(row, j);
// System.out.print(val+", ");
// }
// System.out.println();
// }
//
// }
}

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.common.utils.excel.fieldtype;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
/**
* BigDecimal类型转换
* @author ThinkGem
* @version 2020-3-5
* @example fieldType = BigDecimalType.class
*/
public class BigDecimalType implements FieldType {
/**
* 获取对象值(导入)
*/
@Override
public Object getValue(String val) {
return new BigDecimal(val);
}
/**
* 获取对象值(导出)
*/
@Override
public String setValue(Object val) {
return val == null ? StringUtils.EMPTY : val.toString();
}
/**
* 获取对象值格式(导出)
*/
@Override
public String getDataFormat() {
return "0.00";
}
}

View File

@@ -0,0 +1,80 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.common.web.http;
import com.jeesite.common.io.PropertiesUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 统一包装结果输出类:{ code: 200, msg: "", data: {} | [] }
* @author ThinkGem
* @version 2024-07-24
*/
public class ResultUtils {
private static final boolean isDefaultResult = PropertiesUtils.getInstance()
.getPropertyToBoolean("web.isDefaultResult", "false");
private static final String resultParamName = PropertiesUtils.getInstance()
.getProperty("web.resultParamName", "__data");
private static final String headerParamName = PropertiesUtils.getInstance()
.getProperty("web.headerParamName", "x-data");
/**
* 设置 web.isResult 参数可强制全局使用统一结果输出,否则,传递 __data=true 参数,或 x-data 请求头为 true 时启用
* @author ThinkGem
*/
public static Object result(Object data, HttpServletRequest request, HttpServletResponse response) {
if (request != null && response != null && (isDefaultResult || (
"true".equals(request.getParameter(resultParamName))
|| "true".equals(request.getHeader(headerParamName))))) {
Object msg = request.getAttribute("message");
return new Result(response.getStatus(), msg, data);
}
return data;
}
/**
* 结果对象
* @author ThinkGem
* @version 2024-07-24
*/
private static class Result {
private int code;
private String msg;
private Object data;
public Result(int code, Object msg, Object data) {
this.code = code;
this.msg = msg != null ? msg.toString() : null;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
}

View File

@@ -12,14 +12,15 @@ import com.jeesite.common.lang.ExceptionUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.mapper.JsonMapper;
import com.jeesite.common.mapper.XmlMapper;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.Validate;
import org.springframework.http.MediaType;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
@@ -57,6 +58,11 @@ public class ServletUtils {
// 是否打印错误信息参数到视图页面(生产环境关闭)
private static final Boolean PRINT_ERROR_INFO = PROPS.getPropertyToBoolean("error.page.printErrorInfo", "true");
// 允许重定向的地址不设置为全部允许设置this只允许本项目内部跳转多个用逗号隔开例如this,http://*.jeesite.com
private static final String[] ALLOW_REDIRECTS = PROPS.getPropertyToArray("shiro.allowRedirects", "");
private static final Boolean SCHEME_HTTPS = PROPS.getPropertyToBoolean("server.schemeHttps", "false");
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
/**
* 获取当前请求对象
* web.xml: <listener><listener-class>
@@ -64,13 +70,8 @@ public class ServletUtils {
* </listener-class></listener>
*/
public static HttpServletRequest getRequest(){
HttpServletRequest request = null;
try{
request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
if (request == null){
return null;
}
return request;
return ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
}catch(Exception e){
return null;
}
@@ -83,16 +84,11 @@ public class ServletUtils {
* <filter-name>requestContextFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
*/
public static HttpServletResponse getResponse(){
HttpServletResponse response = null;
try{
response = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getResponse();
if (response == null){
return null;
}
return ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getResponse();
}catch(Exception e){
return null;
}
return response;
}
/**
@@ -122,9 +118,8 @@ public class ServletUtils {
public static boolean isStaticFile(String uri){
if (STATIC_FILE == null){
try {
throw new Exception("检测到“application.yml”中没有配置“web.staticFile”属性。"
+ "配置示例:\n#静态文件后缀\nweb.staticFile=.css,.js,.png,.jpg,.gif,"
+ ".jpeg,.bmp,.ico,.swf,.psd,.htc,.crx,.xpi,.exe,.ipa,.apk");
throw new Exception("检测到“application.yml”中没有配置“web.staticFile”属性。配置示例:\n#静态文件后缀\nweb.staticFile=" +
".css,.js,.map,.png,.jpg,.gif,.jpeg,.webp,.bmp,.ico,.swf,.psd,.htc,.crx,.xpi,.exe,.ipa,.apk,.otf,.eot,.svg,.ttf,.woff,.woff2");
} catch (Exception e) {
e.printStackTrace();
}
@@ -258,6 +253,7 @@ public class ServletUtils {
if (object == null) {
object = resultMap;
}
object = ResultUtils.result(object, request, response);
if (jsonView != null) {
return JsonMapper.toJson(object, jsonView);
}else {
@@ -331,6 +327,7 @@ public class ServletUtils {
object = new JSONPObject(functionName, object);
}
}
object = ResultUtils.result(object, request, response);
if (jsonView != null) {
return renderString(response, JsonMapper.toJson(object, jsonView));
}else {
@@ -358,18 +355,7 @@ public class ServletUtils {
try {
// response.reset(); // 注释掉否则以前设置的Header会被清理掉如ajax登录设置记住我的Cookie信息
if (type == null && StringUtils.isBlank(response.getContentType())){
if ((StringUtils.startsWith(string, "{") && StringUtils.endsWith(string, "}"))
|| (StringUtils.startsWith(string, "[") && StringUtils.endsWith(string, "]"))){
type = MediaType.APPLICATION_JSON_VALUE;
}else if (StringUtils.startsWith(string, "<") && StringUtils.endsWith(string, ">")){
if (StringUtils.startsWith(string, "<!DOCTYPE")){
type = MediaType.TEXT_HTML_VALUE;
}else{
type = MediaType.APPLICATION_XML_VALUE;
}
}else{
type = MediaType.TEXT_PLAIN_VALUE;
}
type = getContentType(string);
}
if (type != null) {
response.setContentType(type);
@@ -383,10 +369,36 @@ public class ServletUtils {
}
/**
* 获取请求的域名(含端口)
* 根据内容判断相应类型 MediaType
* @return application/json、text/html、application/xml、text/plain
*/
public static String getRequestDomain(String url) {
public static String getContentType(String string) {
String type;
if ((StringUtils.startsWith(string, "{") && StringUtils.endsWith(string, "}"))
|| (StringUtils.startsWith(string, "[") && StringUtils.endsWith(string, "]"))){
type = MediaType.APPLICATION_JSON_VALUE;
}else if (StringUtils.startsWith(string, "<") && StringUtils.endsWith(string, ">")){
if (StringUtils.startsWith(string, "<!DOCTYPE")){
type = MediaType.TEXT_HTML_VALUE;
}else{
type = MediaType.APPLICATION_XML_VALUE;
}
}else{
type = MediaType.TEXT_PLAIN_VALUE;
}
return type;
}
/**
* 获取当前请求的域名(含端口)
* @author ThinkGem
*/
public static String getThisDomain(HttpServletRequest request) {
String url = request.getRequestURL().toString();
String scheme = StringUtils.substringBefore(url, "://");
if (SCHEME_HTTPS && StringUtils.equals(scheme, "http")) {
scheme = "https";
}
String domain = StringUtils.substringAfter(url, "://");
if (StringUtils.contains(domain, "/")) {
domain = StringUtils.substringBefore(domain, "/");
@@ -394,6 +406,28 @@ public class ServletUtils {
return scheme + "://" + domain;
}
/**
* 验证地址是否允许重定向
* @author ThinkGem
*/
public static boolean isAllowRedirects(HttpServletRequest request, String url) {
if (ALLOW_REDIRECTS == null || ALLOW_REDIRECTS.length == 0) {
return true;
}
boolean allow = false;
for (String pattern : ALLOW_REDIRECTS) {
String p = StringUtils.trim(pattern);
if ("this".equals(p)) {
p = getThisDomain(request);
}
if (PATH_MATCHER.match(p + "/**", url)){
allow = true;
break;
}
}
return allow;
}
/**
* 获得请求参数值
*/

View File

@@ -235,3 +235,6 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.ui-jqgrid .ui-jqgrid-frozen .ui-jqgrid-htable th div {height:46px!important;}
.ui-jqgrid .ui-jqgrid-htable th div {padding:15px 0 15px 2px;}
.ui-jqgrid tr.jqgrow td {height: 49px;}
.table-form .ui-jqgrid .ui-jqgrid-frozen .ui-jqgrid-htable th div {height:36px!important;}
.table-form .ui-jqgrid .ui-jqgrid-htable th div {padding:9px 0 8px 2px;}
.table-form .ui-jqgrid tr.jqgrow td {height: 39px;}

View File

@@ -235,3 +235,6 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.ui-jqgrid .ui-jqgrid-frozen .ui-jqgrid-htable th div {height:46px!important;}
.ui-jqgrid .ui-jqgrid-htable th div {padding:15px 0 15px 2px;}
.ui-jqgrid tr.jqgrow td {height: 49px;}
.table-form .ui-jqgrid .ui-jqgrid-frozen .ui-jqgrid-htable th div {height:36px!important;}
.table-form .ui-jqgrid .ui-jqgrid-htable th div {padding:9px 0 8px 2px;}
.table-form .ui-jqgrid tr.jqgrow td {height: 39px;}

View File

@@ -296,6 +296,9 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.ui-jqgrid .ui-jqgrid-frozen .ui-jqgrid-htable th div {height:46px!important;}
.ui-jqgrid .ui-jqgrid-htable th div {padding:15px 0 15px 2px;}
.ui-jqgrid tr.jqgrow td {height: 49px;}
.table-form .ui-jqgrid .ui-jqgrid-frozen .ui-jqgrid-htable th div {height:36px!important;}
.table-form .ui-jqgrid .ui-jqgrid-htable th div {padding:9px 0 8px 2px;}
.table-form .ui-jqgrid tr.jqgrow td {height: 39px;}
.ui-jqgrid tr.jqgroup td, .ui-jqgrid tr.footrow td, .ui-jqgrid tr.jqfoot td {background:#323232;}
.ui-jqgrid .actions .moreItems {background:#1a1a1a;border-color:#3c3c3c;box-shadow:none;}

View File

@@ -0,0 +1,249 @@
/*
* Default Layout Theme
* Created for jquery.layout
* Copyright (c) 2010
* Fabrizio Balliano (http://www.fabrizioballiano.net)
* Kevin Dalman (http://allpro.net)
* Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
* and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
* Last Updated: 2010-02-10、2022-09-27 jeesite
* NOTE: For best code readability, view this with a fixed-space font and tabs equal to 4-chars
*/
.ui-draggable-handle{-ms-touch-action:none;touch-action:none}
/*
* DEFAULT FONT
* Just to make demo-pages look better - not actually relevant to Layout!
*/
/* body { */
/* font-family: Geneva, Arial, Helvetica, sans-serif; */
/* font-size: 100%; */
/* *font-size: 80%; */
/* } */
/*
* PANES & CONTENT-DIVs
*/
.ui-layout-pane { /* all 'panes' */
/* background: #fff; */
/* border: 1px solid #eee; */
/* padding: 10px; */
overflow: auto;
/* DO NOT add scrolling (or padding) to 'panes' that have a content-div,
otherwise you may get double-scrollbars - on the pane AND on the content-div
- use ui-layout-wrapper class if pane has a content-div
- use ui-layout-container if pane has an inner-layout
*/
}
/* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */
.ui-layout-content {
padding: 10px;
position: relative; /* contain floated or positioned elements */
overflow: auto; /* add scrolling to content-div */
width: 100%;
border: 0;
}
/*
* UTILITY CLASSES
* Must come AFTER pane-class above so will override
* These classes are NOT auto-generated and are NOT used by Layout
*/
.layout-child-container,
.layout-content-container {
padding: 0;
overflow: hidden;
}
.layout-child-container {
border: 0; /* remove border because inner-layout-panes probably have borders */
}
.layout-scroll {
overflow: auto;
}
.layout-hide {
display: none;
}
/*
* RESIZER-BARS
*/
.ui-layout-resizer { /* all 'resizer-bars' */
background: #fafafa;
border: 1px solid #eee;
border-width: 0;
}
.ui-layout-resizer-drag { /* REAL resizer while resize in progress */
}
.ui-layout-resizer-hover { /* affects both open and closed states */
}
/* NOTE: It looks best when 'hover' and 'dragging' are set to the same color,
otherwise color shifts while dragging when bar can't keep up with mouse */
.ui-layout-resizer-open-hover , /* hover-color to 'resize' */
.ui-layout-resizer-dragging { /* resizer beging 'dragging' */
background: #fafafa;
}
.ui-layout-resizer-dragging { /* CLONED resizer being dragged */
border: 1px solid #eee;
}
.ui-layout-resizer-north-dragging,
.ui-layout-resizer-south-dragging {
border-width: 1px 0;
}
.ui-layout-resizer-west-dragging,
.ui-layout-resizer-east-dragging {
border-width: 0 1px;
}
/* NOTE: Add a 'dragging-limit' color to provide visual feedback when resizer hits min/max size limits */
.ui-layout-resizer-dragging-limit { /* CLONED resizer at min or max size-limit */
background: #E1A4A4; /* red */
}
.ui-layout-resizer-closed-hover { /* hover-color to 'slide open' */
background: #EBD5AA;
}
.ui-layout-resizer-sliding { /* resizer when pane is 'slid open' */
/* opacity: .10; show only a slight shadow */
/* filter: alpha(opacity=10); */
}
.ui-layout-resizer-sliding-hover { /* sliding resizer - hover */
/* opacity: 1.00; on-hover, show the resizer-bar normally */
/* filter: alpha(opacity=100); */
}
/* sliding resizer - add 'outside-border' to resizer on-hover
* this sample illustrates how to target specific panes and states */
.ui-layout-resizer-north-sliding-hover { border-bottom-width: 1px; }
.ui-layout-resizer-south-sliding-hover { border-top-width: 1px; }
.ui-layout-resizer-west-sliding-hover { border-right-width: 1px; }
.ui-layout-resizer-east-sliding-hover { border-left-width: 1px; }
/*
* TOGGLER-BUTTONS
*/
.ui-layout-toggler {
/* border: 1px solid #eee;
background-color: #eee; */
border-radius: 8px;
}
.ui-layout-resizer-hover .ui-layout-toggler {
opacity: 1.00;
filter: alpha(opacity=100);
}
.ui-layout-toggler-hover , /* need when NOT resizable */
.ui-layout-resizer-hover .ui-layout-toggler-hover { /* need specificity when IS resizable */
background-color: #dfdfdf;
opacity: 1.00;
filter: alpha(opacity=100);
}
.skin-dark .ui-layout-toggler-hover ,
.skin-dark .ui-layout-resizer-hover .ui-layout-toggler-hover {
background-color: #2e2e2e;
}
.ui-layout-toggler-north ,
.ui-layout-toggler-south {
border-width: 0 1px; /* left/right borders */
}
.ui-layout-toggler-west ,
.ui-layout-toggler-east {
border-width: 1px 0; /* top/bottom borders */
}
/* hide the toggler-button when the pane is 'slid open' */
.ui-layout-resizer-sliding .ui-layout-toggler {
display: none;
}
/*
* style the text we put INSIDE the togglers
*/
.ui-layout-toggler .ui-content {
color: #666;
font-size: 12px;
font-weight: bold;
line-height: 8px;
width: 100%;
padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */
}
.ui-layout-toggler .ui-content .fa{
line-height: 8px;
}
.ui-layout-toggler-north-closed .fa:before,
.ui-layout-toggler-south-open .fa:before {
content: "\f0d7";/* 下 */
}
.ui-layout-toggler-south-closed .fa:before,
.ui-layout-toggler-north-open .fa:before {
content: "\f0d8";/* 上 */
}
.ui-layout-toggler-west-closed .fa:before,
.ui-layout-toggler-east-open .fa:before {
content: "\f0da";/* 右 */
}
.ui-layout-toggler-east-closed .fa:before,
.ui-layout-toggler-west-open .fa:before {
content: "\f0d9";/* 左 */
}
/*
* PANE-MASKS
* these styles are hard-coded on mask elems, but are also
* included here as !important to ensure will overrides any generic styles
*/
.ui-layout-mask {
border: none !important;
padding: 0 !important;
margin: 0 !important;
overflow: hidden !important;
position: absolute !important;
opacity: 0 !important;
filter: Alpha(Opacity="0") !important;
}
.ui-layout-mask-inside-pane { /* masks always inside pane EXCEPT when pane is an iframe */
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
}
div.ui-layout-mask {} /* standard mask for iframes */
iframe.ui-layout-mask {} /* extra mask for objects/applets */
/*
* Default printing styles
*/
@media print {
/*
* Unless you want to print the layout as it appears onscreen,
* these html/body styles are needed to allow the content to 'flow'
*/
html {
height: auto !important;
overflow: visible !important;
}
body.ui-layout-container {
position: static !important;
top: auto !important;
bottom: auto !important;
left: auto !important;
right: auto !important;
/* only IE6 has container width & height set by Layout */
_width: auto !important;
_height: auto !important;
}
.ui-layout-resizer, .ui-layout-toggler {
display: none !important;
}
/*
* Default pane print styles disables positioning, borders and backgrounds.
* You can modify these styles however it suit your needs.
*/
.ui-layout-pane {
border: none !important;
background: transparent !important;
position: relative !important;
top: auto !important;
bottom: auto !important;
left: auto !important;
right: auto !important;
width: auto !important;
height: auto !important;
overflow: visible !important;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
.strength {position:relative;}
.strength .strength_input {position:absolute;left:0;top:0;height:30px;background:transparent;border:transparent;z-index:2;color:#333;}
.strength .strength_input:focus {background:transparent;}
.strength .strength_meter {position:absolute;left:0;top:0;width:100%;height:30px;z-index:1;border:1px solid #dedede;border-radius:4px;}
.strength .strength_meter.veryweak {border-color:#F04040!important;}
.strength .strength_meter.weak {border-color:#FF853C!important;}
.strength .strength_meter.medium {border-color:#FC0!important;}
.strength .strength_meter.strong {border-color:#8DFF1C!important;}
.strength .strength_meter div {width:0%;height:28px;text-align:right;-webkit-transition:all .3s ease-in-out;border-radius:4px;}
.strength .strength_meter div.veryweak {background-color:#FFA0A0;width:25%!important;}
.strength .strength_meter div.weak {background-color:#FFB78C;width:50%!important;}
.strength .strength_meter div.medium {background-color:#FFEC8B;width:75%!important;}
.strength .strength_meter div.strong {background-color:#C3FF88;width:100%!important;}
.strength .strength_meter div p {position:absolute;right:15px;font-size:13px;line-height:29px;font-weight:bold;color:#333}
.strength .button_strength {text-decoration:none;display:block;padding-top:43px;color:#f59942;}

View File

@@ -0,0 +1,140 @@
/*!
* strength.js
* Original author: @aaronlumsden
* Further changes, comments: jeesite
* Licensed under the MIT license
*/
;(function ($, window, document, undefined) {
var pluginName = "strength";
function Plugin(element, options) {
this.element = element;
this.$elem = $(this.element);
this.options = $.extend({}, $.fn.strength.defaults, options);
this._defaults = $.fn.strength.defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init : function () {
var options = this.options;
var upperCaseExp = new RegExp("[A-Z]");
var lowerCaseExp = new RegExp("[a-z]");
var numberExp = new RegExp("[0-9]");
var specialExp = new RegExp("[~!@#$%\\^&\\*()_+\\{\\}:\"\\|<>?`\\-=\\[\\];\\\'\\\\,\\./]");
function check_strength(thisval, thisid) {
var charLength = thisval.length >= 8 ? 1 : 0;
var upperCase = thisval.match(upperCaseExp) ? 1 : 0;
var lowerCase = thisval.match(lowerCaseExp) ? 1 : 0;
var number = thisval.match(numberExp) ? 1 : 0;
var special = thisval.match(specialExp) ? 1 : 0;
var total = charLength + upperCase + lowerCase + number + special;
get_total(total, thisid);
options.strengthCheck(thisval, total);
}
function get_total(total, thisid) {
var thismeter = $('div[data-meter="' + thisid + '"]').removeClass();
thismeter.parent().removeClass().addClass(options.strengthMeterClass);
if (total == 1) {
thismeter.parent().addClass('veryweak');
thismeter.addClass('veryweak').html('<p>'+options.veryweakText+'</p>');
} else if (total == 2) {
thismeter.parent().addClass('weak');
thismeter.addClass('weak').html('<p>'+options.weakText+'</p>');
} else if (total == 3 || total == 4) {
thismeter.parent().addClass('medium');
thismeter.addClass('medium').html('<p>'+options.mediumText+'</p>');
} else if (total > 4) {
thismeter.parent().addClass('strong');
thismeter.addClass('strong').html('<p>'+options.strongText+'</p>');
} else {
thismeter.html('');
}
}
var isShown = false;
var strengthButtonText = options.strengthTipText + ' ' + options.strengthButtonText;
var strengthButtonTextToggle = options.strengthTipText + ' ' + options.strengthButtonTextToggle;
var thisid = this.$elem.attr('id');
this.$elem.parent().addClass(options.strengthClass);
this.$elem.addClass(options.strengthInputClass).attr('data-password', thisid)
.after('<input style="display:none" class="' + this.$elem.attr('class') + '" data-password="'
+ thisid + '" type="text" name="" value=""><a data-password-button="' + thisid
+ '" href="javascript:" class="' + options.strengthButtonClass + '" tabindex="-1">'
+ strengthButtonText + '</a><div class="' + options.strengthMeterClass
+ '"><div data-meter="' + thisid + '"><p></p></div></div>');
this.$elem.bind('keyup keydown', function (event) {
thisval = $('#' + thisid).val();
var st = $('input[type="text"][data-password="' + thisid + '"]').val(thisval);
try{st.resetValid();}catch(e){}; // 如果表单加了验证,则验证。
check_strength(thisval, thisid);
});
$('input[type="text"][data-password="' + thisid + '"]').bind('keyup keydown', function (event) {
thisval = $('input[type="text"][data-password="' + thisid + '"]').val();
$('input[type="password"][data-password="' + thisid + '"]').val(thisval);
check_strength(thisval, thisid);
});
$(document.body).on('click', '.' + options.strengthButtonClass, function (e) {
e.preventDefault();
thisclass = 'hide_' + $(this).attr('class');
if (isShown) {
$('input[type="text"][data-password="' + thisid + '"]').hide();
$('input[type="password"][data-password="' + thisid + '"]').show().focus();
$('a[data-password-button="' + thisid + '"]').removeClass(thisclass).html(strengthButtonText);
isShown = false;
} else {
$('input[type="text"][data-password="' + thisid + '"]').show().focus();
$('input[type="password"][data-password="' + thisid + '"]').hide();
$('a[data-password-button="' + thisid + '"]').addClass(thisclass).html(strengthButtonTextToggle);
isShown = true;
}
});
}
};
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
};
$.fn[pluginName].defaults = {
strengthClass : 'strength',
strengthInputClass : 'strength_input',
strengthMeterClass : 'strength_meter',
strengthButtonClass : 'button_strength',
strengthTipText: '建议长度不小于8位且包含大写英文字母、小写英文字母、数字和符号。',
strengthButtonText: '点击显示密码。',
strengthButtonTextToggle: '点击隐藏密码。',
veryweakText: '密码太弱啦!',
weakText: '密码比较弱哦!',
mediumText: '密码较安全!',
strongText: '密码很强很安全!',
// 验证后调用方法(当前值,安全级别)
strengthCheck: function(thisval, thislevel){ }
};
})(jQuery, window, document);

View File

@@ -1,170 +0,0 @@
=ZTree v3.x (JQuery Tree插件) 更新日志=
<font color="red">为了更好的优化及扩展zTree, 因此决定升级为v3.x并且对之前的v2.x不兼容会有很多结构上的修改对此深感无奈与抱歉请大家谅解。</font>
<font color="red">
具体修改内容可参考:
* [http://www.ztree.me/v3/api.php zTree v3.0 API 文档]
* [http://www.ztree.me/v3/demo.php#_101 zTree v3.0 Demo 演示]
* [http://www.ztree.me/v3/faq.php#_101 zTree v3.0 常见问题]
</font>
<font color=#041594>
*2013.03.11* v3.5.12
* 【修改】由于 jquery 1.9 中移除 event.srcElement 导致的 js 报错的bug。
* 【修改】在异步加载模式下,使用 moveNode 方法,且 moveType != "inner" 时,也会导致 targetNode 自动加载子节点的 bug
* 【修改】对已经显示的节点(nochecked=true)使用 showNodes 或 showNode 方法后导致勾选框出现的bug。
* 【修改】对已经隐藏的节点(nochecked=false)使用 hideNodes 或 hideNode 方法后导致勾选框消失的bug。
* 【修改】getNodesByParamFuzzy 支持 大小写模糊。
* 【修改】className 结构,提取 _consts.className.BUTTON / LEVEL / ICO_LOADING / SWITCH便于快速修改 css 冲突。
例如:与 WordPress 产生冲突后,直接修改 core 中的 "button" 和 "level" 即可。 Issue: https://github.com/zTree/zTree_v3/issues/2
*2013.01.28* v3.5.02
* 【增加】setting.check.chkDisabledInherit 属性,用于设置 chkDisabled 在初始化时子节点是否可以继承父节点的 chkDisabled 属性
* 【删除】内部 noSel 方法,使用 selectstart事件 和 "-moz-user-select"样式 处理禁止 节点文字被选择的功能
* 【修改】不兼容 jQuery 1.9 的bug
* 【修改】onDrop 的触发规则,保证异步加载模式下,可以在延迟加载结束后触发,避免 onDrop 中被拖拽的节点是已经更新后的数据。
* 【修改】setChkDisabled 方法,增加 inheritParent, inheritChildren 参数设置是否让父子节点继承 disabled
* 【修改】异步加载时 拼接参数的方法,由 string 修改为 json 对象
* 【修正】1-2-3 3级节点时如果 2级节点 全部设置为 nocheck 或 chkDisabled后勾选3级节点时1级节点的半勾选状态错误的 bug
* 【修改】Demo: checkbox_nocheck.html & checkbox_chkDisabled.html;
* 【修改】Demo: edit_super.html增加 showRenameBtn & showRemoveBtn 的演示
* 【修改】Demo: asyncForAll, 将 post 修改为 get为了避免由于 IE10 的 bug 造成的客户端 以及 服务端崩溃
IE10 ajax Post 无法提交参数的bug (http://bugs.jquery.com/ticket/12790)
*2012.12.21* v3.5.01
* 【优化】clone 方法
* 【修正】对于初始化无 children 属性的父节点进行 reAsyncChildNodes 操作时出错的 bug
* 【修正】beforeRename 回调中使用 cancelEditName 方法后,再 return false 导致无法重新进行编辑的 bug
* 【修正】exedit 扩展包让 setting.data.key.url 失效的 bug
* 【修正】setting.check.autoCheckTrigger 设置为 true 时onCheck 回调缺少 event 参数的 bug
* 【修正】singlepath.html Demo 中的 bug
*2012.11.20* v3.5
* 【优化】原先的 clone 方法 (特别感谢:愚人码头)
* 【修改】隐藏父节点后,使用 expandAll 方法导致 父节点展开的 bug
* 【修改】使用 jQuery v1.7 以上时,设置 zTree 容器 ul 隐藏visibility: hidden;)后, 调用 selectNode 导致 IE 浏览器报错 Can't move focus 的 bug
* 【修改】正在异步加载时,执行 destory 或 init 方法后,异步加载的节点影响新树的 bug
* 【修改】方法 reAsyncChildNodes 在 refresh 的时候未清空内部 cache 导致内存泄露 的 bug
* 【修改】批量节点拖拽到其他父节点内inner导致顺序反转 的 bug
* 【修改】对于 使用 html格式的 节点无法触发 双击事件 的 bug
* 【修改】onCheck 回调中的 event ,保证与触发事件中的 event 一致
* 【修改】异步加载时,在 onNodeCreated 中执行 selectNode 后,导致节点折叠的 bug
* 【修改】API 中 dataFilter 的参数名称 childNodes -> responseData
* 【修改】API 中 iconSkin 的 举例内容
* 【修改】API 中 chkDisabled 的说明
* 【修改】Demo 中 index.html 内的 loadReady 重复绑定问题
*2012.09.03* v3.4
* 【增加】 Demo —— OutLook 样式的左侧菜单
* 【增加】清空 zTree 的方法 $.fn.zTree.destory(treeId) & zTree.destory()
* 【修改】core核心文件内 _eventProxy 方法中获取 tId 的方法,提高 DOM 的灵活性
* 【修改】初始化时 多层父节点的 checkbox 半选状态计算错误的 bug
* 【修改】同时选中父、子节点后,利用 getSelectedNodes 获取选中节点并利用 removeNode 删除时报错的 bug
* 【修改】treeNode.chkDisabled / nocheck 属性,支持字符串格式的 "false"/"true"
* 【修改】异步加载模式下无法利用 server 返回 xml 并且 在 dataFilter 中继续处理的 bug
* 【修改】title 只允许设置为 string 类型值的问题。 修正后允许设置为 number 类型的值
* 【修改】zId 计数规则 & Cache 保存,减少 IE9 的 bug 造成的内存泄漏
* 【修改】API 页面搜索功能导致 IE 崩溃的 bug
*2012.07.16* v3.3
* 【增加】扩展库 exhide -- 节点隐藏功能
* 【修改】getNodesByFilter 方法,添加 invokeParam 自定义参数
* 【修改】拖拽中测试代码未删除,导致出现黄颜色的 iframe 遮罩层的 bug
* 【修改】延迟加载方法 对于使用 expandAll 进行全部展开时,导致 onNodeCreated 回调 和 addDiyDom 方法触发过早的 bug
* 【修改】使用 moveNode 移动尚未生成 DOM 的节点时,视图会出现异常的 bug
* 【修改】删除节点后,相关节点的 isFirstNode 属性未重置的 bug
* 【修改】getPreNode(),getNextNode() 方法在对于特殊情况时计算错误的 bug
* 【修改】设置 title 之后,如果重新将 title 内容设置为空后,会导致无法更新 title 的 bug
* 【修改】针对 setting.check.chkStyle=="radio" && setting.check.radioType=="all" 的情况时getTreeCheckedNodes方法优化找到一个结果就 break
* 【修改】zTreeObj.getCheckedNodes(false) 在 radioType = "all" 时计算错误的 bug
* 【修改】完善 API 中 beforeDrop / onDrop 的关于 treeId 的说明
*2012.05.13* v3.2
* 【增加】setting.data.key.url 允许修改 treeNode.url 属性
* 【增加】getNodesByFilter(filter, isSingle) 方法
* 【增加】"与其他 DOM 拖拽互动" 的 Demo (http://www.ztree.me/v3/demo.php#_511)
* 【增加】"异步加载模式下全部展开" 的 Demo (http://www.ztree.me/v3/demo.php#_512)
* 【修改】代码结构,将 addNodes、removeNode、removeChildNodes 方法 和 beforeRemove、onRemove 回调 转移到 core 内
* 【修改】IE7的环境下无子节点的父节点反复展开出现多余空行的 bug
* 【修改】异步加载时,如果出现网络异常等,会导致 图标显示错误的 bug
* 【修改】dataFilter中 return null 导致异常 的 bug
* 【修改】removeChildNodes 方法清空子节点后,无法正常添加节点的 bug
* 【修改】moveNode 后节点中的自定义元素的事件丢失的 bug
* 【修改】moveNode 方法中设置 isSilent = true 时,如果移动到已展开的 父节点后,出现异常的 bug
* 【修改】onClick/onDrag/onDrop 回调中 event 不是原始 event 的 bug
* 【修改】onDrop 回调中 当拖拽无效时,无法获得 treeNodes 的 bug
* 【修改】onDrop 无法判断拖拽是 移动还是复制的问题
* 【修改】未开启异步加载模式时,拖拽节点到子节点为空的父节点内时 出现异常 的 bug
* 【修改】拖拽过程中,反复在 父节点图标上划动时,会出现停顿的 bug
(需要css 结构—— button -> span.button)
* 【修改】拖拽操作时箭头 与 targetNode 背景之间的细节现实问题,便于用户拖拽时更容易区分 prev、next 和 inner 操作
* 【修改】拖拽操作时IE6/7 下 在 节点<a> 右侧 10px 内会导致 targetNode = root 的 bug
* 【修改】编辑模式下 默认的编辑按钮、删除按钮点击后,如果相应的 before 回调 return false 时会触发 onClick 回调的 bug
*2012.02.14* v3.1
* 【增加】ajax 的参数 setting.async.contentType ,让提交参数适用于 json 数据提交 (主要适用于 .Net 的开发)。
* 【增加】setting.edit.editNameSelectAll, 用于设定编辑节点名称时初次显示 input 后 text 内容为全选
* 【修改】异步加载 规则,不再仅仅依靠父节点的子节点数来判定,增加内部属性 zAsync保证默认状态下父节点及时无子节点也只能异步加载一次除非使用 reAsyncChildNodes 方法强行控制异步加载。
* 【修改】放大浏览器后导致 界面出现多余连接线的bug 需要更新icon 图标和 css
* 【修改】在编辑状态如果节点名超过编辑框宽度左右键在框内不起作用的bugIE 6 7 8 出现)
CSS 中 filter:alpha(opacity=80) 造成的,应该是 ie 的 bug需要更新 css 文件
* 【修改】title 设置后,如果属性不存在,则默认为 title 为空,便于数据容错和用户灵活使用
* 【修改】editName 方法如果针对尚未展开的 父节点,会导致该父节点自动展开的 bug
* 【修改】title 中存在标签时导致 title 显示异常的bug例如蓝色字22%"'`<input/>`
*2012.01.10* v3.0
* 【增加】setting.check.autoCheckTrigger 默认值 false可以设置联动选中时是否触发事件回调函数
* 【增加】setting.callback.beforeEditName 回调函数,以保证用户可以捕获点击编辑按钮的事件
* 【增加】treeNode.chkDisabled 属性,显示 checkbox 但是用户无法修改 checkbox 状态,并且该 checkbox 会影响父节点的 checkbox 的半选状态
* 【增加】setting.check.nocheckInherit 属性,用户设置子节点继承 nocheck 属性,用于批量初始化节点,不适用于已经显示的节点
* 【增加】setting.edit.drag.autoExpandTrigger 默认值 false可以设置自动展开、折叠操作时是否触发事件回调函数
* 【增加】setting.view.nameIsHTML 默认值 false允许用户对 name 设置 DOM 对象
* 【增加】treeNode.click 属性的说明文档
* 【增加】treeObj.setChkDisabled 方法用于设置 checkbox / radio disabled 状态
* 【增加】treeNode.halfCheck 属性,用于强制设定节点的半选状态
* 【修改】异步加载 & 编辑功能 共存时,拖拽节点 或 增加节点 导致 ie 上报错的 bug apply 方法引起)
* 【修改】zTreeStyle 样式冲突
* 【修改】setting.data.key.title 默认值设置为 "",初始化时自动赋值为 setting.data.key.name 这样可避免希望 title 与 name 一致的用户反复设置参数
* 【修改】点击叶子节点的连接线会触发 expand 事件的 bug
* 【修改】IE 下 点击叶子节点连线会出现虚线框的 bug
* 【修改】updateNode 导致 checkbox 半选状态错误的 bug
* 【修改】checkNode 方法实现 toggle 操作, 取消 expandAll 方法的 toggle 操作
* 【修改】zTree 内鼠标移动会抢页面上 input 内的焦点的 bug
* 【修改】beforeRename / onRename 的触发方式——即使名称内容未改变也会触发,便于用户配合 beforeEditName 捕获编辑状态的结束,赋予用户更多调整规则的权利
* 【修改】与 easyUI 共存时无法拖拽的bug
* 【修改】beforeRename 在 Firefox 下如果利用 alert会触发两次的 bug
* 【修改】checkNode/expandNode/removeNode 方法,默认不触发回调函数,恢复 v2.6 的默认状态,同时增加 callbackFlag 参数,设置为 true 时,可以触发回调函数
* 【修改】IE9下“根据参数查找节点”的Demo 报错行14 重新声明常量属性(Demo 自身的问题定义了history变量)
* 【修改】初始化 zTree 时 onNodeCreated 事件回调函数中无法 用 getZTreeObj 获取 zTree 对象的 bug
* 【修改】setting.edit.drag.prev / next / inner 参数,增加被拖拽的节点集合
* 【修改】异步加载模式下otherParam 使用Array数组会出错的 bug。例如 ["id", "1", "name", "test"]
* 【修改】FireFox 下多棵树拖拽异常的 bug
* 【修改】exedit 中调用 excheck库的方法时没有进行容错处理导致如果只加入 exedit 而没有 excheck的时候会出现 js 错误
* 【修改】显示 checkbox 的 zTree 在编辑模式下,移动节点不会更新父节点半选状态的 bug
* 【修改】treeNode.childs --> children; treeObject.removeChilds --> removeChildNodes; setting.data.key.childs --> children英文不好惹的祸抱歉了
* 【修改】onRemove 回调中得到的 treeNode 还可以查找 preNode、nextNode 的bug。 修正后getPreNode 和 getNextNode 都返回 null 为了便于查找父节点getParentNode 仍保留
* 【修改】简单数据模式下,如果 id 与 pId 的值相同会导致该节点无法正常加载的 bug
* 【修改】移动或删除中间节点会导致最后一个节点连接线图标变小的 bug
*2011.09.05* v3.0 beta
* 【修改】zTree 的 js 代码架构全面修改,并且拆分
* 【修改】zTree 的 css 样式全面修改对浏览器可以更好地兼容同时解决了以前1个像素差的问题
* 【优化】采用延迟加载技术,一次性加载大数据量的节点性能飞速提升
* 【增加】支持多节点同时选中、拖拽
* 【增加】checkNode、checkAllNodes 等多种方法
* 【增加】IE6 自动取消动画展开、折叠的功能
* 【修正】异步加载 & 编辑模式 能够更完美的共存
* 【修正】setting 配置更加合理,并且增加了若干项配置参数
* 【修正】treeNode 节点数据的属性更加合理,并且增加了一些方法
* 【修正】拖拽操作更加灵活方便,更容易制定自己的规则
* 【修正】其他若干修改,详细对比请参考 url[http://www.ztree.me/v3/faq.php#_101 zTree v3.0 常见问题]

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,42 @@
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved.
No deletion without permission, or be held responsible to law. -->
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8" />
<title>请升级您的浏览器</title><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
<meta name="renderer" content="webkit"><base target="_blank" /><style type="text/css">
a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;}
body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;}
h1{font-size:30px;line-height:80px;font-weight:100;margin-bottom:10px;}
h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;}
p{margin-bottom:10px;font-size:16px;}
hr{margin:20px 0;border:0;border-top:1px solid #dadada}
img{width:34px;height:34px;border:0;float:left;margin-right:10px;}
span{display:block;font-size:12px;line-height:12px;}
.browser{padding:10px 0;}
.browser li{width:180px;height:34px;line-height:22px;float:left;list-style:none;padding-left:25px}
.clean{clear:both;}
</style></head><body>
<h1>浏览器版本过低,是时候升级您的浏览器了</h1>
<p>本系统 <a href="http://jeesite.com">JeeSite</a> 支持 IE9 及以上版本及其他所有现代浏览器,如:谷歌浏览器、火狐浏览器、国产浏览器 等。</p>
<p>您正在使用 Internet Explorer 的过期版本IE6、IE7、IE8 内核的浏览器)。这意味着在升级浏览器前,您将无法继续访问。</p>
<hr>
<h2>为什么会出现这个页面?</h2>
<p>如果您不知道升级浏览器是什么意思请请教一些熟练电脑操作的朋友。如果您使用的不是Internet Explorer而是360、QQ、搜狗等双核浏览器出现这个页面可能是您切换到了兼容模式<strong style="color:#f00;">切换到极速模式</strong>下,如果还不行请升级至最新版浏览器。</p>
<hr>
<h2>请注意微软Microsoft对 Windows XP、Vista、7、8、8.1 及 Internet Explorer 的支持已经结束</h2>
<p>微软Microsoft不再为已经结束的版本提供相应支持和更新。如果您继续使用这些您将可能受到病毒、间谍软件和其他恶意软件的攻击无法确保个人信息的安全。请参阅 <a href="http://windows.microsoft.com/zh-cn/windows/end-support-help">Windows XP 支持已经结束的说明</a></p>
<p>于 2022 年 6 月 15 日,微软对 Internet Explorer 11 的支持也已结束。请参阅 <a href="http://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> Internet Explorer 浏览器下载</a></p>
<hr>
<h2>您可以选择更先进的浏览器</h2>
<p>推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问 <b id="url"></b>即可。</p>
<div class="browser"><ul>
<li><img src="img/chrome360.jpg"><a href="http://chrome.360.cn/"> 360极速浏览器<span>360 Chrome</span></a></li>
<li><img src="img/chrome.jpg"><a href="http://www.google.cn/intl/zh-CN/chrome/browser/desktop/index.html"> 谷歌浏览器<span>Google Chrome</span></a></li>
<li><img src="img/firefox.jpg"><a href="http://www.firefox.com.cn/download/"> 火狐浏览器<span>Mozilla Firefox</span></a></li>
<li><img src="img/edge.png"><a href="https://www.microsoft.com/zh-cn/edge"> Edge 浏览器<span>Microsoft Edge</span></a></li>
</ul><div class="clean"></div></div>
<hr><br/>
<script>
var url = location.href; url = url.substring(0, url.indexOf('/static/upbw'));
document.getElementById("url").innerHTML = '<a href="' + url + '">' + url + '</a>&nbsp;';
</script>
</body></html>

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.codec;
import com.jeesite.common.codec.AesUtils;
import com.jeesite.common.codec.EncodeUtils;
import java.nio.charset.StandardCharsets;
/**
* AES 加密解密工具类
* @author ThinkGem
* @version 2024-07-22
*/
public class AesUtilsTest {
public static void main(String[] args) {
String s = "Hello word! 你好,中文!";
System.out.println(s);
String k = AesUtils.genKeyString();
System.out.println(k);
String s1 = AesUtils.encode(s, k);
System.out.println(s1);
String s2 = AesUtils.decode(s1, k);
System.out.println(s2);
byte[] key = AesUtils.genKey();
byte[] iv = AesUtils.genIV();
byte[] data = AesUtils.encode(s.getBytes(StandardCharsets.UTF_8), key, iv);
System.out.println(EncodeUtils.encodeHex(data));
byte[] data2 = AesUtils.decode(data, key, iv);
System.out.println(new String(data2, StandardCharsets.UTF_8));
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.codec;
import com.jeesite.common.codec.EncodeUtils;
/**
* 封装各种格式的编码解码工具测试类
* @author ThinkGem
* @version 2024-07-22
*/
public class EncodeUtilsTest {
public static void main(String[] args) {
EncodeUtils.xssFilter("1 你好 <script>alert(document.cookie)</script>我还在。");
EncodeUtils.xssFilter("2 你好 <strong>加粗文字</strong>我还在。");
EncodeUtils.xssFilter("<!--HTML-->3 你好 \"><strong>加粗文字</strong>我还在。");
EncodeUtils.xssFilter("<!--HTML-->4 你好 <iframe src=\"abcdef\"></iframe><strong>加粗文字</strong>我还在。");
EncodeUtils.xssFilter("<!--HTML-->5 你好 <iframe src=\"abcdef\"/><strong>加粗文字</strong>我还在。");
EncodeUtils.xssFilter("<!--HTML-->6 你好 <iframe src=\"abcdef\"><strong>加粗文字</strong>我还在。");
EncodeUtils.xssFilter("<!--HTML-->7 你好 <script type=\"text/javascript\">alert(document.cookie)</script>我还在。");
EncodeUtils.xssFilter("<!--HTML-->8 你好 <script\n type=\"text/javascript\">\nalert(document.cookie)\n</script>我还在。");
EncodeUtils.xssFilter("<!--HTML-->9 你好 <script src='' onerror='alert(document.cookie)'></script>我还在。");
EncodeUtils.xssFilter("<!--HTML-->10 你好 <script type=text/javascript>alert()我还在。");
EncodeUtils.xssFilter("<!--HTML-->11 你好 <script>alert(document.cookie)</script>我还在。");
EncodeUtils.xssFilter("<!--HTML-->12 你好 <script>window.location='url'我还在。");
EncodeUtils.xssFilter("<!--HTML-->13 你好 </script></iframe>我还在。");
EncodeUtils.xssFilter("<!--HTML-->14 你好 eval(abc)我还在。");
EncodeUtils.xssFilter("<!--HTML-->15 你好 expression(abc)我还在。");
EncodeUtils.xssFilter("<!--HTML-->16 你好 <img src='abc.jpg' onerror='location='';alert(document.cookie);'></img>我还在。");
EncodeUtils.xssFilter("<!--HTML-->17 你好 <img src='abc.jpg' onerror='alert(document.cookie);'/>我还在。");
EncodeUtils.xssFilter("<!--HTML-->18 你好 <img src='abc.jpg' onerror='alert(document.cookie);'>我还在。");
EncodeUtils.xssFilter("<!--HTML-->19 你好 <a onload='alert(\"abc\")'>hello</a>我还在。");
EncodeUtils.xssFilter("<!--HTML-->20 你好 <a href=\"/abc\">hello</a>我还在。");
EncodeUtils.xssFilter("<!--HTML-->21 你好 <a href='/abc'>hello</a>我还在。");
EncodeUtils.xssFilter("<!--HTML-->22 你好 <a href='vbscript:alert(\"abc\");'>hello</a>我还在。");
EncodeUtils.xssFilter("<!--HTML-->23 你好 <a href='javascript:alert(\"abc\");'>hello</a>我还在。");
EncodeUtils.xssFilter("<!--HTML-->24 你好 ?abc=def&hello=123&world={\"a\":1}我还在。");
EncodeUtils.xssFilter("<!--HTML-->25 你好 ?abc=def&hello=123&world={'a':1}我还在。");
EncodeUtils.sqlFilter("1 你好 select * from xxx where abc=def and 1=1我还在。");
EncodeUtils.sqlFilter("2 你好 insert into xxx values(1,2,3,4,5)我还在。");
EncodeUtils.sqlFilter("3 你好 delete from xxx我还在。");
EncodeUtils.sqlFilter("4 a.audit_result asc,case when 1 like case when length(database())=6 then 1 else exp(111) end then 1 else 1/0 end", "orderBy");
EncodeUtils.sqlFilter("5 if(1=2,1,SLEEP(10)), if(mid(database(),{},1)=\\\"{}\\\",a.id,a.login_name)", "orderBy");
EncodeUtils.sqlFilter("6 a.audit_result asc, b.audit_result2 desc, b.AuditResult3 desc", "orderBy");
}
}

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.codec;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.codec.RsaUtils;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
/**
* RSA 加密解密工具类,非对称加密
* @author ThinkGem
*/
public class RsaUtilsTest {
public static void main(String[] args) {
String s = "Hello word! 你好,中文!";
System.out.println(s);
String[] keys = RsaUtils.genKeys();
System.out.println("公钥:" + keys[0]);
PublicKey publicKey = RsaUtils.toPublicKey(keys[0]);
System.out.println("私钥:" + keys[1]);
PrivateKey privateKey = RsaUtils.toPrivateKey(keys[1]);
byte[] data = RsaUtils.encode(s.getBytes(), publicKey);
String dataString = EncodeUtils.encodeBase64(data);
System.out.println("加密数据:" + dataString);
byte[] data2 = RsaUtils.decode(data, privateKey);
String dataString2 = new String(data2, StandardCharsets.UTF_8);
System.out.println("解密数据:" + dataString2);
byte[] sign = RsaUtils.sign(s.getBytes(), privateKey);
System.out.println("数据签名:" + EncodeUtils.encodeBase64(sign));
boolean b = RsaUtils.verify(s.getBytes(), publicKey, sign);
System.out.println("数据验签:" + b);
}
}

View File

@@ -0,0 +1,28 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.codec;
import com.jeesite.common.codec.Sha1Utils;
/**
* SHA-1 加密工具类,散列加密,不可逆加密
* @author ThinkGem
* @version 2024-07-22
*/
public class Sha1UtilsTest {
public static void main(String[] args) {
String s = "Hello word! 你好,中文!";
System.out.println(s);
String salt = Sha1Utils.genSaltString(8);
System.out.println(salt);
String data = Sha1Utils.sha1(s, salt);
System.out.println(data);
}
}

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.lang;
import com.jeesite.common.lang.ObjectUtils;
import java.text.ParseException;
/**
* 对象操作工具测试类
* @author ThinkGem
* @version 2025-02-05
*/
public class ObjectUtilsTest {
public static void main(String[] args) throws ParseException {
String str = "1738746499603094500";
System.out.println(ObjectUtils.toDouble(str));
System.out.println(ObjectUtils.toFloat(str));
System.out.println(ObjectUtils.toLong(str));
System.out.println(ObjectUtils.toInteger(str));
}
}

View File

@@ -230,7 +230,7 @@ public class ReflectUtilsTest {
*/
class ReflectUtils2 {
private static Logger logger = LoggerFactory.getLogger(ReflectUtils2.class);
private static final Logger logger = LoggerFactory.getLogger(ReflectUtils2.class);
private static final String SETTER_PREFIX = "set";
private static final String GETTER_PREFIX = "get";
private static Class baseEntityClass = null;

View File

@@ -0,0 +1,92 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.utils.excel;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.utils.excel.ExcelExport;
import com.jeesite.common.utils.excel.ExcelImport;
import org.apache.poi.ss.usermodel.Row;
import java.io.File;
import java.util.List;
/**
* 导出Excel文件测试类
* @author ThinkGem
* @version 2020-3-5
*/
public class ExcelExportTest {
/**
* 导出测试
*/
public static void main(String[] args) throws Throwable {
File classPath = new File(ExcelExportTest.class.getResource("/").getFile());
String fileName = classPath.getParentFile().getAbsoluteFile() + "/export.xlsx";
// 初始化表头
List<String> headerList = ListUtils.newArrayList();
for (int i = 1; i <= 10; i++) {
headerList.add("表头"+i);
}
// 初始化数据集
List<String> rowList = ListUtils.newArrayList();
for (int i = 1; i <= headerList.size(); i++) {
rowList.add("数据"+i);
}
List<List<String>> dataList = ListUtils.newArrayList();
for (int i = 1; i <=100; i++) {
dataList.add(rowList);
}
// 创建一个Sheet表并导入数据
try(ExcelExport ee = new ExcelExport("表格1", "表格标题1", headerList, null)){
for (int i = 0; i < dataList.size(); i++) {
Row row = ee.addRow();
for (int j = 0; j < dataList.get(i).size(); j++) {
ee.addCell(row, j, dataList.get(i).get(j));
}
}
// 再创建一个Sheet表并导入数据
ee.createSheet("表格2", "表格标题2", headerList, null);
for (int i = 0; i < dataList.size(); i++) {
Row row = ee.addRow();
for (int j = 0; j < dataList.get(i).size(); j++) {
ee.addCell(row, j, dataList.get(i).get(j)+"2");
}
}
// 输出到文件
ee.writeFile(fileName);
}
System.out.println("Export success.");
// 按模板导出,从第 3 行开始
ExcelImport ei = new ExcelImport(fileName, 3);
try(ExcelExport ee = new ExcelExport(ei)){
for (int i = 0; i < dataList.size(); i++) {
Row row = ee.addRow();
for (int j = 0; j < dataList.get(i).size(); j++) {
ee.addCell(row, j, dataList.get(i).get(j) + "-plus");
}
}
// 输出到文件
ee.writeFile(fileName);
}
System.out.println("Export success by template.");
}
}

View File

@@ -0,0 +1,45 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.test.utils.excel;
import com.jeesite.common.utils.excel.ExcelImport;
import org.apache.poi.ss.usermodel.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* 导入Excel文件测试类
* @author ThinkGem
* @version 2020-3-5
*/
public class ExcelImportTest {
/**
* 导入测试
*/
public static void main(String[] args) throws Throwable {
File classPath = new File(ExcelExportTest.class.getResource("/").getFile());
String fileName = classPath.getParentFile().getAbsoluteFile() + "/export.xlsx";
ExcelImport ei = new ExcelImport(fileName, 1);
for (int i = ei.getDataRowNum(); i < ei.getLastDataRowNum(); i++) {
Row row = ei.getRow(i);
if (row == null){
continue;
}
for (int j = 0; j < ei.getLastCellNum(); j++) {
Object val = ei.getCellValue(row, j);
System.out.print(val+", ");
}
System.out.println();
}
System.out.println("Import success.");
}
}

View File

@@ -329,7 +329,7 @@
</word>
<word>
<id>a63e3fda50530388ba263296184d8a6919a75791</id>
<length>1000</length>
<length>4000</length>
<decimal>null</decimal>
<array>false</array>
<array_dimension>null</array_dimension>

View File

@@ -16,7 +16,7 @@ CREATE TABLE js_app_comment
update_date timestamp NOT NULL,
remarks vargraphic(500),
create_by_name varchar(200),
device_info varchar(1000),
device_info varchar(4000),
reply_date date,
reply_content vargraphic(500),
reply_user_code varchar(64),

View File

@@ -16,7 +16,7 @@ CREATE TABLE js_app_comment
update_date datetime NOT NULL,
remarks varchar(500),
create_by_name varchar(200),
device_info varchar(1000),
device_info varchar(4000),
reply_date date,
reply_content varchar(500),
reply_user_code varchar(64),

View File

@@ -16,7 +16,7 @@ CREATE TABLE [js_app_comment]
[update_date] datetime NOT NULL,
[remarks] nvarchar(500),
[create_by_name] varchar(200),
[device_info] varchar(1000),
[device_info] varchar(4000),
[reply_date] date,
[reply_content] nvarchar(500),
[reply_user_code] varchar(64),

View File

@@ -17,7 +17,7 @@ CREATE TABLE js_app_comment
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
create_by_name varchar(200) COMMENT '提问人员姓名',
device_info varchar(1000) COMMENT '设备信息',
device_info varchar(4000) COMMENT '设备信息',
reply_date date COMMENT '回复时间',
reply_content varchar(500) COMMENT '回复意见',
reply_user_code varchar(64) COMMENT '回复人员',

View File

@@ -16,7 +16,7 @@ CREATE TABLE js_app_comment
update_date timestamp NOT NULL,
remarks nvarchar2(500),
create_by_name varchar2(200),
device_info varchar2(1000),
device_info varchar2(4000),
reply_date date,
reply_content nvarchar2(500),
reply_user_code varchar2(64),

View File

@@ -16,7 +16,7 @@ CREATE TABLE js_app_comment
update_date timestamp NOT NULL,
remarks varchar(500),
create_by_name varchar(200),
device_info varchar(1000),
device_info varchar(4000),
reply_date date,
reply_content varchar(500),
reply_user_code varchar(64),

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>5.8.0-SNAPSHOT</version>
<version>5.11.0-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
@@ -38,13 +38,13 @@
</pluginManagement>
</build>
<developers>
<developers>
<developer>
<id>thinkgem</id>
<name>WangZhen</name>
<email>thinkgem at 163.com</email>
<roles><role>Project lead</role></roles>
<timezone>+8</timezone>
<timezone>+8</timezone>
</developer>
</developers>

View File

@@ -4,18 +4,16 @@
*/
package com.jeesite.modules.app.entity;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.mapper.query.QueryType;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
/**
* APP意见反馈Entity
* @author ThinkGem
@@ -26,13 +24,14 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
@Column(name="category", attrName="category", label="问题分类"),
@Column(name="content", attrName="content", label="问题和意见"),
@Column(name="contact", attrName="contact", label="联系方式"),
@Column(includeEntity=DataEntity.class),
@Column(name="create_by_name", attrName="createByName", label="提问人员姓名", queryType=QueryType.LIKE),
@Column(name="device_info", attrName="deviceInfo", label="设备信息"),
@Column(name="reply_date", attrName="replyDate", label="回复时间"),
@Column(name="reply_content", attrName="replyContent", label="回复意见"),
@Column(name="reply_user_code", attrName="replyUserCode", label="回复人员"),
@Column(name="reply_user_name", attrName="replyUserName", label="回复人员姓名", queryType=QueryType.LIKE),
@Column(name="status", attrName="status", label="状态", isUpdate=true), // save时允许更新status字段
@Column(includeEntity=DataEntity.class),
}, orderBy="a.create_date DESC"
)
public class AppComment extends DataEntity<AppComment> {
@@ -84,7 +83,7 @@ public class AppComment extends DataEntity<AppComment> {
this.contact = contact;
}
@Size(min=0, max=1000, message="设备信息长度不能超过 1000 个字符")
@Size(min=0, max=4000, message="设备信息长度不能超过 4000 个字符")
public String getDeviceInfo() {
return deviceInfo;
}

View File

@@ -4,11 +4,11 @@
*/
package com.jeesite.modules.app.web;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.app.entity.AppComment;
import com.jeesite.modules.app.service.AppCommentService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,11 +20,9 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.app.entity.AppComment;
import com.jeesite.modules.app.service.AppCommentService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
/**
* APP意见反馈Controller
@@ -97,7 +95,6 @@ public class AppCommentController extends BaseController {
}
}
appCommentService.save(appComment);
appCommentService.updateStatus(appComment);
return renderResult(Global.TRUE, text("保存意见成功!"));
}

View File

@@ -16,7 +16,7 @@ CREATE TABLE ${_prefix}app_comment
update_date timestamp NOT NULL,
remarks vargraphic(500),
create_by_name varchar(200),
device_info varchar(1000),
device_info varchar(4000),
reply_date date,
reply_content vargraphic(500),
reply_user_code varchar(64),

View File

@@ -16,7 +16,7 @@ CREATE TABLE ${_prefix}app_comment
update_date datetime NOT NULL,
remarks varchar(500),
create_by_name varchar(200),
device_info varchar(1000),
device_info varchar(4000),
reply_date date,
reply_content varchar(500),
reply_user_code varchar(64),

View File

@@ -16,7 +16,7 @@ CREATE TABLE [${_prefix}app_comment]
[update_date] datetime NOT NULL,
[remarks] nvarchar(500),
[create_by_name] varchar(200),
[device_info] varchar(1000),
[device_info] varchar(4000),
[reply_date] date,
[reply_content] nvarchar(500),
[reply_user_code] varchar(64),

View File

@@ -17,7 +17,7 @@ CREATE TABLE ${_prefix}app_comment
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
create_by_name varchar(200) COMMENT '提问人员姓名',
device_info varchar(1000) COMMENT '设备信息',
device_info varchar(4000) COMMENT '设备信息',
reply_date date COMMENT '回复时间',
reply_content varchar(500) COMMENT '回复意见',
reply_user_code varchar(64) COMMENT '回复人员',

View File

@@ -16,7 +16,7 @@ CREATE TABLE ${_prefix}app_comment
update_date timestamp NOT NULL,
remarks nvarchar2(500),
create_by_name varchar2(200),
device_info varchar2(1000),
device_info varchar2(4000),
reply_date date,
reply_content nvarchar2(500),
reply_user_code varchar2(64),

View File

@@ -16,7 +16,7 @@ CREATE TABLE ${_prefix}app_comment
update_date timestamp NOT NULL,
remarks varchar(500),
create_by_name varchar(200),
device_info varchar(1000),
device_info varchar(4000),
reply_date date,
reply_content varchar(500),
reply_user_code varchar(64),

View File

@@ -18,4 +18,11 @@
5.6.1
5.7.0
5.7.1
5.8.0
5.8.0
5.8.1
5.9.0
5.9.1
5.9.2
5.10.0
5.10.1
5.11.0

View File

@@ -14,7 +14,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${appComment}" action="${ctx}/app/appComment/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${appComment}" action="${ctx}/app/appComment/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('问题分类')}</label>

View File

@@ -14,7 +14,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${appUpgrade}" action="${ctx}/app/appUpgrade/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${appUpgrade}" action="${ctx}/app/appUpgrade/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('应用代号')}</label>
@@ -37,7 +37,7 @@
<div class="form-group">
<label class="control-label">${text('发布时间')}</label>
<div class="control-inline">
<#form:input path="upDate" readonly="true" maxlength="20" class="form-control laydate width-datetime"
<#form:input path="upDate" readonly="true" maxlength="20" class="form-control laydate width-date"
dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
</div>
</div>

View File

@@ -1,51 +0,0 @@
# 技术交流
* 交流 QQ 群(千人大群):`127515876``209330483``223507718``709534275``730390092``1373527``183903863(外包)`
* 码云Gitee<https://gitee.com/thinkgem/jeesite5>
* GitHub<https://github.com/thinkgem/jeesite5>
* 作者博客:<https://my.oschina.net/thinkgem>
* **帮助文档:**<http://docs.jeesite.com>
* 官方网站:<http://jeesite.com>
* 问题反馈:<http://jeesite.net> [【新手必读】](https://gitee.com/thinkgem/jeesite5/issues/I18ARR)
* 关注微信公众号,了解最新动态:
![JeeSite微信公众号](https://images.gitee.com/uploads/images/2020/0727/091951_a3ab258c_6732.jpeg "JeeSite微信公众号")
## 介绍
JeeSite CMS 内容管理,是一个轻量级的 Web 建站神器,可以快速进行企业网站、门户网站、个人博客、知识库等建设。
* 基础功能:站点管理、栏目管理、栏目权限、模板管理、内容发布
* 高级功能:多租户、多站点、页面静态化访问、全文检索
规划内容:站内统计、标签管理、留言管理、相关文章选取、文章多栏目
## 快速体验
### 在线演示
1. 前端演示:<http://demo.jeesite.com/js/f/index-main.html>
2. 后端演示:<http://demo.jeesite.com/js/a/index#/js/a/cms/index#内容发布>
3. 账号system
4. 密码admin
### 本地运行
1. 环境准备:`JDK 1.8 or 11、17``Maven 3.6+``MySQL 5.7 or 8.0`
2. 下载源码:<https://gitee.com/thinkgem/jeesite5/tree/master/modules/cms>
3. 打开文件:/web`/src/main/resources/config/application.yml` 配置JDBC连接
4. 打开文件:/web`/pom.xml` 打开 `jeesite-module-cms` 模块(去掉的注释标记)
5. 执行脚本:/web`/bin/init-data.bat` 初始化数据库
5. 执行脚本:/web`/bin/run-tomcat.bat` 启动服务即可
6. 浏览器访问:<http://127.0.0.1:8980/js/> 账号 system 密码 admin
7. 部署常见问题:<https://jeesite.com/docs/faq/>
### 开发环境
1. 部署运行文档:<https://jeesite.com/docs/install-deploy/>
2. 部署常见问题:<https://jeesite.com/docs/faq/>
## 在线文档
* <http://docs.jeesite.com>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>5.8.0-SNAPSHOT</version>
<version>5.11.0-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
@@ -24,6 +24,12 @@
<artifactId>jeesite-module-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

View File

@@ -61,7 +61,7 @@ import java.util.Date;
@Column(name = "site_code"),
@Column(name = "site_name"),
})
}, orderBy = "a.update_date DESC", extWhereKeys = "dsfCategory"
}, extWhereKeys = "dsfCategory", orderBy = "a.weight DESC, a.update_date DESC"
)
public class Article extends DataEntity<Article> {

View File

@@ -44,7 +44,7 @@ import java.util.List;
on = "s.site_code = a.site_code", columns = {
@Column(name = "site_name"),
})
}, orderBy = "a.tree_sorts, a.category_code", extWhereKeys = "dsfCategory"
}, extWhereKeys = "dsfCategory", orderBy = "a.tree_sorts, a.category_code"
)
public class Category extends TreeEntity<Category> {

View File

@@ -0,0 +1,81 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.modules.cms.properties.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* CmsProperties
* @author ThinkGem
* @version 2022-4-10
*/
@ConfigurationProperties(prefix = "cms")
public class CmsProperties {
private PageCache pageCache = new PageCache();
public static class PageCache {
/**
* 是否开启页面静态化缓存
*/
private Boolean enabled = false;
/**
* 缓存名称标识
*/
private String cacheName = "cmsPageCache";
/**
* 拦截的网页地址
*/
private String urlPatterns = "${frontPath}/*";
/**
* 只静态化 .html 后缀的网页
*/
private String urlSuffixes = ".html";
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public String getCacheName() {
return cacheName;
}
public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}
public String getUrlPatterns() {
return urlPatterns;
}
public void setUrlPatterns(String urlPatterns) {
this.urlPatterns = urlPatterns;
}
public String getUrlSuffixes() {
return urlSuffixes;
}
public void setUrlSuffixes(String urlSuffixes) {
this.urlSuffixes = urlSuffixes;
}
}
public PageCache getPageCache() {
return pageCache;
}
public void setPageCache(PageCache pageCache) {
this.pageCache = pageCache;
}
}

View File

@@ -9,7 +9,6 @@ import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.lang.TimeUtils;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.cms.entity.Article;
import com.jeesite.modules.cms.entity.Category;
@@ -19,7 +18,6 @@ import com.jeesite.modules.cms.service.FileTempleteService;
import com.jeesite.modules.cms.utils.CmsUtils;
import com.jeesite.modules.sys.entity.Office;
import com.jeesite.modules.sys.utils.DictUtils;
import com.jeesite.modules.sys.utils.UserUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
@@ -325,7 +323,7 @@ public class CategoryController extends BaseController {
@RequestMapping(value = "fixTreeData")
@ResponseBody
public String fixTreeData(Category category) {
if (!UserUtils.getUser().isAdmin()) {
if (!category.currentUser().isAdmin()) {
return renderResult(Global.FALSE, "操作失败,只有管理员才能进行修复!");
}
categoryService.fixTreeData();

View File

@@ -0,0 +1,12 @@
## 重要提示Tip
## 请勿在该配置文件中添加其它任何配置(添加也不会生效)。
## 该文件,仅仅是为了让 jeesite-cms.yml 文件,
## 在 IDEA 中有一个自动完成及帮助提示,并无其它用意。
## 参数配置请在 jeesite-cms.yml 文件中添加。
spring:
config:
import:
- classpath:config/jeesite-cms.yml

View File

@@ -3,7 +3,7 @@
cms:
pageCache:
# 是否开启页面静态化缓存
#enabled: true
enabled: false
# 缓存名称标识
cacheName: cmsPageCache
# 拦截的网页地址

View File

@@ -26,4 +26,11 @@
5.6.1
5.7.0
5.7.1
5.8.0
5.8.0
5.8.1
5.9.0
5.9.1
5.9.2
5.10.0
5.10.1
5.11.0

View File

@@ -4,6 +4,10 @@ body>.navbar{-webkit-transition:background-color .3s ease-in;transition:backgrou
body>.navbar-transparent{background-color:transparent}
body>.navbar-transparent .navbar-nav>.open>a{background-color:transparent!important}
}
h1,.h1{font-size:26px}
h2,.h2{font-size:24px}
h3,.h3{font-size:22px}
p{margin:5px 0 10px;line-height:1.75;}
#home{padding-top:0}
#home .navbar-brand{padding:13.5px 15px 12.5px}
#home .navbar-brand>img{display:inline;margin:0 10px;height:100%}
@@ -80,7 +84,7 @@ footer p{clear:left;margin-bottom:0}
.article-title {color:#333;font-size:30px;text-align:center;border-bottom:1px solid #ddd;padding:15px 20px 20px 20px;margin-bottom:30px;}
.article-info {border-top:1px solid #ddd;padding:10px;margin:30px 0 0;}
.article-desc {padding:8px 10px 8px;margin:10px 20px 20px 35px;font-size:14px;}
.article-content {padding-top:20px;}
.article-content {padding-top:10px;}
.pagination {margin:8px 0;display:block;/* text-align:center; */font-size:13px;} /* .pagination .controls a{border:0;} */
.pagination>li>a, .pagination>li>span {min-width:37px;text-align:center;padding:6px;border:1px solid #ddd;background:transparent;/* border-radius:3px; */}

View File

@@ -1210,7 +1210,7 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
@@ -1255,7 +1255,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Source Code</h4>
</div>
<div class="modal-body">

View File

@@ -14,7 +14,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${article}" action="${ctx}/cms/article/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${article}" action="${ctx}/cms/article/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('栏目编码')}</label>
@@ -54,7 +54,7 @@
<script>
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text("标题")}', name:'title', index:'a.category_code', width:350, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/cms/article/form?id='+row.id+'" class="btnList" data-title="${text("编辑文章")}">'+(val||row.id)+'</a>';

View File

@@ -29,7 +29,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${category}" action="${ctx}/cms/category/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${category}" action="${ctx}/cms/category/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<#form:hidden path="site.siteCode" maxlength="64" class="form-control width-120" />
<div class="form-group">
@@ -69,7 +69,7 @@
<script>
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text("名称")}', name:'categoryName', index:'a.category_name', width:250, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '( '+row.categoryCode+' ) '+'<a href="${ctx}/cms/category/form?categoryCode='+row.categoryCode+'" class="btnList" data-title="${text("编辑栏目表")}">'+(val||row.id)+'</a>';

View File

@@ -13,7 +13,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${comment}" action="${ctx}/cms/comment/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${comment}" action="${ctx}/cms/comment/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('栏目编码')}</label>
@@ -107,7 +107,7 @@
<script>
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text('栏目编码')}', name:'categoryCode', index:'a.category_code', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/cms/comment/form?id='+row.id+'" class="btnList" data-title="${text('编辑文章评论表')}">'+(val||row.id)+'</a>';

View File

@@ -13,7 +13,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${report}" action="${ctx}/cms/report/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${report}" action="${ctx}/cms/report/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('举报来源')}</label>
@@ -59,7 +59,7 @@
<script>
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text('举报来源')}', name:'reportSource', index:'a.report_source', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/cms/report/form?id='+row.id+'" class="btnList" data-title="${text('编辑内容举报表')}">'+(val||row.id)+'</a>';

View File

@@ -13,7 +13,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${site}" action="${ctx}/cms/site/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${site}" action="${ctx}/cms/site/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('站点名称')}</label>

View File

@@ -13,7 +13,7 @@
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${visitLog}" action="${ctx}/cms/visitLog/listData" method="post" class="form-inline hide"
<#form:form id="searchForm" model="${visitLog}" action="${ctx}/cms/visitLog/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('请求的URL地址')}</label>
@@ -66,7 +66,7 @@
<script>
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text('请求的URL地址')}', name:'requestUrl', index:'a.request_url', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/cms/visitLog/form?id='+row.id+'" class="btnList" data-title="${text('编辑访问日志表')}">'+(val||row.id)+'</a>';

View File

@@ -13,4 +13,6 @@
</div>
</footer>
<script src="${ctxStatic}/modules/cmsfront/themes/js/bootstrap.min.js?${_version}"></script>
<script src="${ctxStatic}/modules/cmsfront/themes/js/custom.js?${_version}"></script>
<script src="${ctxStatic}/modules/cmsfront/themes/js/custom.js?${_version}"></script>
<script src="${ctxStatic}/ueditor/1.4/ueditor.parse.js"></script>
<script>uParse('.uparse',{rootPath:'${ctxStatic}/ueditor/1.4/'})</script>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,31 @@
/* Create Tables */
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL,
view_code varchar(500),
category_name varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(767) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks vargraphic(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
);
-- 代码生成表
CREATE TABLE js_gen_table
(
@@ -79,31 +104,6 @@ CREATE TABLE js_sys_area
);
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL,
view_code varchar(500),
category_name varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(767) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks vargraphic(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
);
-- 公司表
CREATE TABLE js_sys_company
(
@@ -492,6 +492,21 @@ CREATE TABLE js_sys_menu
);
-- 菜单数据权限
CREATE TABLE js_sys_menu_data_scope
(
id varchar(64) NOT NULL,
role_code varchar(64) NOT NULL,
menu_code varchar(64) NOT NULL,
rule_name varchar(100),
rule_type char(1),
rule_config clob,
status char(1),
remarks vargraphic(500),
PRIMARY KEY (id)
);
-- 模块表
CREATE TABLE js_sys_module
(
@@ -767,7 +782,8 @@ CREATE TABLE js_sys_role_data_scope
ctrl_type varchar(20) NOT NULL,
ctrl_data varchar(64) NOT NULL,
ctrl_permi varchar(64) NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi)
menu_code varchar(64) DEFAULT '0' NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi, menu_code)
);
@@ -934,6 +950,8 @@ CREATE INDEX idx_sys_menu_sc ON js_sys_menu (sys_code);
CREATE INDEX idx_sys_menu_is ON js_sys_menu (is_show);
CREATE INDEX idx_sys_menu_mcs ON js_sys_menu (module_codes);
CREATE INDEX idx_sys_menu_wt ON js_sys_menu (weight);
CREATE INDEX idx_sys_menu_ds_mc ON js_sys_menu_data_scope (menu_code);
CREATE INDEX idx_sys_menu_ds_rc ON js_sys_menu_data_scope (role_code);
CREATE INDEX idx_sys_module_status ON js_sys_module (status);
CREATE INDEX idx_sys_msg_inner_cb ON js_sys_msg_inner (create_by);
CREATE INDEX idx_sys_msg_inner_status ON js_sys_msg_inner (status);

View File

@@ -2,6 +2,31 @@
/* Create Tables */
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL,
view_code varchar(500),
category_name varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(767) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date datetime NOT NULL,
update_by varchar(64) NOT NULL,
update_date datetime NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
);
-- 代码生成表
CREATE TABLE js_gen_table
(
@@ -79,31 +104,6 @@ CREATE TABLE js_sys_area
);
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL,
view_code varchar(500),
category_name varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(767) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date datetime NOT NULL,
update_by varchar(64) NOT NULL,
update_date datetime NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
);
-- 公司表
CREATE TABLE js_sys_company
(
@@ -492,6 +492,21 @@ CREATE TABLE js_sys_menu
);
-- 菜单数据权限
CREATE TABLE js_sys_menu_data_scope
(
id varchar(64) NOT NULL,
role_code varchar(64) NOT NULL,
menu_code varchar(64) NOT NULL,
rule_name varchar(100),
rule_type char(1),
rule_config clob,
status char(1),
remarks varchar(500),
PRIMARY KEY (id)
);
-- 模块表
CREATE TABLE js_sys_module
(
@@ -767,7 +782,8 @@ CREATE TABLE js_sys_role_data_scope
ctrl_type varchar(20) NOT NULL,
ctrl_data varchar(64) NOT NULL,
ctrl_permi varchar(64) NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi)
menu_code varchar(64) DEFAULT '0' NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi, menu_code)
);
@@ -934,6 +950,8 @@ CREATE INDEX idx_sys_menu_sc ON js_sys_menu (sys_code);
CREATE INDEX idx_sys_menu_is ON js_sys_menu (is_show);
CREATE INDEX idx_sys_menu_mcs ON js_sys_menu (module_codes);
CREATE INDEX idx_sys_menu_wt ON js_sys_menu (weight);
CREATE INDEX idx_sys_menu_ds_mc ON js_sys_menu_data_scope (menu_code);
CREATE INDEX idx_sys_menu_ds_rc ON js_sys_menu_data_scope (role_code);
CREATE INDEX idx_sys_module_status ON js_sys_module (status);
CREATE INDEX idx_sys_msg_inner_cb ON js_sys_msg_inner (create_by);
CREATE INDEX idx_sys_msg_inner_status ON js_sys_msg_inner (status);
@@ -999,6 +1017,25 @@ CREATE INDEX idx_sys_user_cc ON js_sys_user (corp_code);
/* Comments */
COMMENT ON TABLE js_biz_category IS '业务分类';
COMMENT ON COLUMN js_biz_category.category_code IS '流程分类';
COMMENT ON COLUMN js_biz_category.view_code IS '分类代码';
COMMENT ON COLUMN js_biz_category.category_name IS '分类名称';
COMMENT ON COLUMN js_biz_category.parent_code IS '父级编号';
COMMENT ON COLUMN js_biz_category.parent_codes IS '所有父级编号';
COMMENT ON COLUMN js_biz_category.tree_sort IS '排序号(升序)';
COMMENT ON COLUMN js_biz_category.tree_sorts IS '所有排序号';
COMMENT ON COLUMN js_biz_category.tree_leaf IS '是否最末级';
COMMENT ON COLUMN js_biz_category.tree_level IS '层次级别';
COMMENT ON COLUMN js_biz_category.tree_names IS '全节点名';
COMMENT ON COLUMN js_biz_category.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_biz_category.create_by IS '创建者';
COMMENT ON COLUMN js_biz_category.create_date IS '创建时间';
COMMENT ON COLUMN js_biz_category.update_by IS '更新者';
COMMENT ON COLUMN js_biz_category.update_date IS '更新时间';
COMMENT ON COLUMN js_biz_category.remarks IS '备注信息';
COMMENT ON COLUMN js_biz_category.corp_code IS '租户代码';
COMMENT ON COLUMN js_biz_category.corp_name IS '租户名称';
COMMENT ON TABLE js_gen_table IS '代码生成表';
COMMENT ON COLUMN js_gen_table.table_name IS '表名';
COMMENT ON COLUMN js_gen_table.class_name IS '实体类名称';
@@ -1058,25 +1095,6 @@ COMMENT ON COLUMN js_sys_area.create_date IS '创建时间';
COMMENT ON COLUMN js_sys_area.update_by IS '更新者';
COMMENT ON COLUMN js_sys_area.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_area.remarks IS '备注信息';
COMMENT ON TABLE js_biz_category IS '业务分类';
COMMENT ON COLUMN js_biz_category.category_code IS '流程分类';
COMMENT ON COLUMN js_biz_category.view_code IS '分类代码';
COMMENT ON COLUMN js_biz_category.category_name IS '分类名称';
COMMENT ON COLUMN js_biz_category.parent_code IS '父级编号';
COMMENT ON COLUMN js_biz_category.parent_codes IS '所有父级编号';
COMMENT ON COLUMN js_biz_category.tree_sort IS '排序号(升序)';
COMMENT ON COLUMN js_biz_category.tree_sorts IS '所有排序号';
COMMENT ON COLUMN js_biz_category.tree_leaf IS '是否最末级';
COMMENT ON COLUMN js_biz_category.tree_level IS '层次级别';
COMMENT ON COLUMN js_biz_category.tree_names IS '全节点名';
COMMENT ON COLUMN js_biz_category.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_biz_category.create_by IS '创建者';
COMMENT ON COLUMN js_biz_category.create_date IS '创建时间';
COMMENT ON COLUMN js_biz_category.update_by IS '更新者';
COMMENT ON COLUMN js_biz_category.update_date IS '更新时间';
COMMENT ON COLUMN js_biz_category.remarks IS '备注信息';
COMMENT ON COLUMN js_biz_category.corp_code IS '租户代码';
COMMENT ON COLUMN js_biz_category.corp_name IS '租户名称';
COMMENT ON TABLE js_sys_company IS '公司表';
COMMENT ON COLUMN js_sys_company.company_code IS '公司编码';
COMMENT ON COLUMN js_sys_company.view_code IS '公司代码';
@@ -1375,6 +1393,15 @@ COMMENT ON COLUMN js_sys_menu.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN js_sys_menu.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN js_sys_menu.extend_d4 IS '扩展 Date 4';
COMMENT ON COLUMN js_sys_menu.extend_json IS '扩展 JSON';
COMMENT ON TABLE js_sys_menu_data_scope IS '菜单数据权限';
COMMENT ON COLUMN js_sys_menu_data_scope.id IS '编号';
COMMENT ON COLUMN js_sys_menu_data_scope.role_code IS '角色编码';
COMMENT ON COLUMN js_sys_menu_data_scope.menu_code IS '菜单编码';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_name IS '规则名称';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_type IS '规则类型1 角色数据范围 2自定义条件规则 3自定义SQL';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_config IS '规则配置JSON';
COMMENT ON COLUMN js_sys_menu_data_scope.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_menu_data_scope.remarks IS '备注信息';
COMMENT ON TABLE js_sys_module IS '模块表';
COMMENT ON COLUMN js_sys_module.module_code IS '模块编码';
COMMENT ON COLUMN js_sys_module.module_name IS '模块名称';
@@ -1551,7 +1578,7 @@ COMMENT ON COLUMN js_sys_role.is_sys IS '系统内置1是 0否';
COMMENT ON COLUMN js_sys_role.is_show IS '是否显示';
COMMENT ON COLUMN js_sys_role.user_type IS '用户类型employee员工 member会员';
COMMENT ON COLUMN js_sys_role.desktop_url IS '桌面地址(仪表盘地址)';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围设置0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.biz_scope IS '适应业务范围(不同的功能,不同的数据权限支持)';
COMMENT ON COLUMN js_sys_role.sys_codes IS '包含系统(多个用逗号隔开)';
COMMENT ON COLUMN js_sys_role.status IS '状态0正常 1删除 2停用';
@@ -1588,6 +1615,7 @@ COMMENT ON COLUMN js_sys_role_data_scope.role_code IS '控制角色编码';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_type IS '控制类型';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_data IS '控制数据';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_permi IS '控制权限';
COMMENT ON COLUMN js_sys_role_data_scope.menu_code IS '菜单编码';
COMMENT ON TABLE js_sys_role_menu IS '角色与菜单关联表';
COMMENT ON COLUMN js_sys_role_menu.role_code IS '角色编码';
COMMENT ON COLUMN js_sys_role_menu.menu_code IS '菜单编码';

View File

@@ -2,6 +2,31 @@
/* Create Tables */
-- 业务分类
CREATE TABLE [js_biz_category]
(
[category_code] varchar(64) NOT NULL,
[view_code] varchar(500),
[category_name] varchar(64) NOT NULL,
[parent_code] varchar(64) NOT NULL,
[parent_codes] varchar(767) NOT NULL,
[tree_sort] decimal(10) NOT NULL,
[tree_sorts] varchar(767) NOT NULL,
[tree_leaf] char(1) NOT NULL,
[tree_level] decimal(4) NOT NULL,
[tree_names] varchar(767) NOT NULL,
[status] char(1) DEFAULT '0' NOT NULL,
[create_by] varchar(64) NOT NULL,
[create_date] datetime NOT NULL,
[update_by] varchar(64) NOT NULL,
[update_date] datetime NOT NULL,
[remarks] nvarchar(500),
[corp_code] varchar(64) DEFAULT '0' NOT NULL,
[corp_name] nvarchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY ([category_code])
);
-- 代码生成表
CREATE TABLE [js_gen_table]
(
@@ -79,31 +104,6 @@ CREATE TABLE [js_sys_area]
);
-- 业务分类
CREATE TABLE [js_biz_category]
(
[category_code] varchar(64) NOT NULL,
[view_code] varchar(500),
[category_name] varchar(64) NOT NULL,
[parent_code] varchar(64) NOT NULL,
[parent_codes] varchar(767) NOT NULL,
[tree_sort] decimal(10) NOT NULL,
[tree_sorts] varchar(767) NOT NULL,
[tree_leaf] char(1) NOT NULL,
[tree_level] decimal(4) NOT NULL,
[tree_names] varchar(767) NOT NULL,
[status] char(1) DEFAULT '0' NOT NULL,
[create_by] varchar(64) NOT NULL,
[create_date] datetime NOT NULL,
[update_by] varchar(64) NOT NULL,
[update_date] datetime NOT NULL,
[remarks] nvarchar(500),
[corp_code] varchar(64) DEFAULT '0' NOT NULL,
[corp_name] nvarchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY ([category_code])
);
-- 公司表
CREATE TABLE [js_sys_company]
(
@@ -492,6 +492,21 @@ CREATE TABLE [js_sys_menu]
);
-- 菜单数据权限
CREATE TABLE [js_sys_menu_data_scope]
(
[id] varchar(64) NOT NULL,
[role_code] varchar(64) NOT NULL,
[menu_code] varchar(64) NOT NULL,
[rule_name] varchar(100),
[rule_type] char(1),
[rule_config] text,
[status] char(1),
[remarks] nvarchar(500),
PRIMARY KEY ([id])
);
-- 模块表
CREATE TABLE [js_sys_module]
(
@@ -767,7 +782,8 @@ CREATE TABLE [js_sys_role_data_scope]
[ctrl_type] varchar(20) NOT NULL,
[ctrl_data] varchar(64) NOT NULL,
[ctrl_permi] varchar(64) NOT NULL,
PRIMARY KEY ([role_code], [ctrl_type], [ctrl_data], [ctrl_permi])
[menu_code] varchar(64) DEFAULT '0' NOT NULL,
PRIMARY KEY ([role_code], [ctrl_type], [ctrl_data], [ctrl_permi], [menu_code])
);
@@ -934,6 +950,8 @@ CREATE INDEX [idx_sys_menu_sc] ON [js_sys_menu] ([sys_code]);
CREATE INDEX [idx_sys_menu_is] ON [js_sys_menu] ([is_show]);
CREATE INDEX [idx_sys_menu_mcs] ON [js_sys_menu] ([module_codes]);
CREATE INDEX [idx_sys_menu_wt] ON [js_sys_menu] ([weight]);
CREATE INDEX [idx_sys_menu_ds_mc] ON [js_sys_menu_data_scope] ([menu_code]);
CREATE INDEX [idx_sys_menu_ds_rc] ON [js_sys_menu_data_scope] ([role_code]);
CREATE INDEX [idx_sys_module_status] ON [js_sys_module] ([status]);
CREATE INDEX [idx_sys_msg_inner_cb] ON [js_sys_msg_inner] ([create_by]);
CREATE INDEX [idx_sys_msg_inner_status] ON [js_sys_msg_inner] ([status]);

View File

@@ -3,6 +3,31 @@ SET SESSION FOREIGN_KEY_CHECKS=0;
/* Create Tables */
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL COMMENT '流程分类',
view_code varchar(500) COMMENT '分类代码',
category_name varchar(64) NOT NULL COMMENT '分类名称',
parent_code varchar(64) NOT NULL COMMENT '父级编号',
parent_codes varchar(767) NOT NULL COMMENT '所有父级编号',
tree_sort decimal(10) NOT NULL COMMENT '排序号(升序)',
tree_sorts varchar(767) NOT NULL COMMENT '所有排序号',
tree_leaf char(1) NOT NULL COMMENT '是否最末级',
tree_level decimal(4) NOT NULL COMMENT '层次级别',
tree_names varchar(767) NOT NULL COMMENT '全节点名',
status char(1) DEFAULT '0' NOT NULL COMMENT '状态0正常 1删除 2停用',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',
update_by varchar(64) NOT NULL COMMENT '更新者',
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
corp_code varchar(64) DEFAULT '0' NOT NULL COMMENT '租户代码',
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL COMMENT '租户名称',
PRIMARY KEY (category_code)
) COMMENT = '业务分类';
-- 代码生成表
CREATE TABLE js_gen_table
(
@@ -80,31 +105,6 @@ CREATE TABLE js_sys_area
) COMMENT = '行政区划';
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL COMMENT '流程分类',
view_code varchar(500) COMMENT '分类代码',
category_name varchar(64) NOT NULL COMMENT '分类名称',
parent_code varchar(64) NOT NULL COMMENT '父级编号',
parent_codes varchar(767) NOT NULL COMMENT '所有父级编号',
tree_sort decimal(10) NOT NULL COMMENT '排序号(升序)',
tree_sorts varchar(767) NOT NULL COMMENT '所有排序号',
tree_leaf char(1) NOT NULL COMMENT '是否最末级',
tree_level decimal(4) NOT NULL COMMENT '层次级别',
tree_names varchar(767) NOT NULL COMMENT '全节点名',
status char(1) DEFAULT '0' NOT NULL COMMENT '状态0正常 1删除 2停用',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',
update_by varchar(64) NOT NULL COMMENT '更新者',
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
corp_code varchar(64) DEFAULT '0' NOT NULL COMMENT '租户代码',
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL COMMENT '租户名称',
PRIMARY KEY (category_code)
) COMMENT = '业务分类';
-- 公司表
CREATE TABLE js_sys_company
(
@@ -493,6 +493,21 @@ CREATE TABLE js_sys_menu
) COMMENT = '菜单表';
-- 菜单数据权限
CREATE TABLE js_sys_menu_data_scope
(
id varchar(64) NOT NULL COMMENT '编号',
role_code varchar(64) NOT NULL COMMENT '角色编码',
menu_code varchar(64) NOT NULL COMMENT '菜单编码',
rule_name varchar(100) COMMENT '规则名称',
rule_type char(1) COMMENT '规则类型1 角色数据范围 2自定义条件规则 3自定义SQL',
rule_config text COMMENT '规则配置JSON',
status char(1) COMMENT '状态0正常 1删除 2停用',
remarks varchar(500) COMMENT '备注信息',
PRIMARY KEY (id)
) COMMENT = '菜单数据权限';
-- 模块表
CREATE TABLE js_sys_module
(
@@ -725,7 +740,7 @@ CREATE TABLE js_sys_role
is_show char(1) DEFAULT '1' COMMENT '是否显示',
user_type varchar(16) COMMENT '用户类型employee员工 member会员',
desktop_url varchar(255) COMMENT '桌面地址(仪表盘地址)',
data_scope char(1) COMMENT '数据范围设置0未设置 1全部数据 2自定义数据',
data_scope char(1) COMMENT '数据范围0未设置 1全部数据 2自定义数据',
biz_scope varchar(255) COMMENT '适应业务范围(不同的功能,不同的数据权限支持)',
sys_codes varchar(500) COMMENT '包含系统(多个用逗号隔开)',
status char(1) DEFAULT '0' NOT NULL COMMENT '状态0正常 1删除 2停用',
@@ -768,7 +783,8 @@ CREATE TABLE js_sys_role_data_scope
ctrl_type varchar(20) NOT NULL COMMENT '控制类型',
ctrl_data varchar(64) NOT NULL COMMENT '控制数据',
ctrl_permi varchar(64) NOT NULL COMMENT '控制权限',
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi)
menu_code varchar(64) DEFAULT '0' NOT NULL COMMENT '菜单编码',
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi, menu_code)
) COMMENT = '角色数据权限表';
@@ -935,6 +951,8 @@ CREATE INDEX idx_sys_menu_sc ON js_sys_menu (sys_code ASC);
CREATE INDEX idx_sys_menu_is ON js_sys_menu (is_show ASC);
CREATE INDEX idx_sys_menu_mcs ON js_sys_menu (module_codes ASC);
CREATE INDEX idx_sys_menu_wt ON js_sys_menu (weight ASC);
CREATE INDEX idx_sys_menu_ds_mc ON js_sys_menu_data_scope (menu_code ASC);
CREATE INDEX idx_sys_menu_ds_rc ON js_sys_menu_data_scope (role_code ASC);
CREATE INDEX idx_sys_module_status ON js_sys_module (status ASC);
CREATE INDEX idx_sys_msg_inner_cb ON js_sys_msg_inner (create_by ASC);
CREATE INDEX idx_sys_msg_inner_status ON js_sys_msg_inner (status ASC);

View File

@@ -2,6 +2,31 @@
/* Create Tables */
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar2(64) NOT NULL,
view_code varchar2(500),
category_name varchar2(64) NOT NULL,
parent_code varchar2(64) NOT NULL,
parent_codes varchar2(767) NOT NULL,
tree_sort number(10) NOT NULL,
tree_sorts varchar2(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level number(4) NOT NULL,
tree_names varchar2(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar2(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar2(64) NOT NULL,
update_date timestamp NOT NULL,
remarks nvarchar2(500),
corp_code varchar2(64) DEFAULT '0' NOT NULL,
corp_name nvarchar2(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
);
-- 代码生成表
CREATE TABLE js_gen_table
(
@@ -79,31 +104,6 @@ CREATE TABLE js_sys_area
);
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar2(64) NOT NULL,
view_code varchar2(500),
category_name varchar2(64) NOT NULL,
parent_code varchar2(64) NOT NULL,
parent_codes varchar2(767) NOT NULL,
tree_sort number(10) NOT NULL,
tree_sorts varchar2(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level number(4) NOT NULL,
tree_names varchar2(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar2(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar2(64) NOT NULL,
update_date timestamp NOT NULL,
remarks nvarchar2(500),
corp_code varchar2(64) DEFAULT '0' NOT NULL,
corp_name nvarchar2(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
);
-- 公司表
CREATE TABLE js_sys_company
(
@@ -492,6 +492,21 @@ CREATE TABLE js_sys_menu
);
-- 菜单数据权限
CREATE TABLE js_sys_menu_data_scope
(
id varchar2(64) NOT NULL,
role_code varchar2(64) NOT NULL,
menu_code varchar2(64) NOT NULL,
rule_name varchar2(100),
rule_type char(1),
rule_config clob,
status char(1),
remarks nvarchar2(500),
PRIMARY KEY (id)
);
-- 模块表
CREATE TABLE js_sys_module
(
@@ -767,7 +782,8 @@ CREATE TABLE js_sys_role_data_scope
ctrl_type varchar2(20) NOT NULL,
ctrl_data varchar2(64) NOT NULL,
ctrl_permi varchar2(64) NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi)
menu_code varchar2(64) DEFAULT '0' NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi, menu_code)
);
@@ -934,6 +950,8 @@ CREATE INDEX idx_sys_menu_sc ON js_sys_menu (sys_code);
CREATE INDEX idx_sys_menu_is ON js_sys_menu (is_show);
CREATE INDEX idx_sys_menu_mcs ON js_sys_menu (module_codes);
CREATE INDEX idx_sys_menu_wt ON js_sys_menu (weight);
CREATE INDEX idx_sys_menu_ds_mc ON js_sys_menu_data_scope (menu_code);
CREATE INDEX idx_sys_menu_ds_rc ON js_sys_menu_data_scope (role_code);
CREATE INDEX idx_sys_module_status ON js_sys_module (status);
CREATE INDEX idx_sys_msg_inner_cb ON js_sys_msg_inner (create_by);
CREATE INDEX idx_sys_msg_inner_status ON js_sys_msg_inner (status);
@@ -999,6 +1017,25 @@ CREATE INDEX idx_sys_user_cc ON js_sys_user (corp_code);
/* Comments */
COMMENT ON TABLE js_biz_category IS '业务分类';
COMMENT ON COLUMN js_biz_category.category_code IS '流程分类';
COMMENT ON COLUMN js_biz_category.view_code IS '分类代码';
COMMENT ON COLUMN js_biz_category.category_name IS '分类名称';
COMMENT ON COLUMN js_biz_category.parent_code IS '父级编号';
COMMENT ON COLUMN js_biz_category.parent_codes IS '所有父级编号';
COMMENT ON COLUMN js_biz_category.tree_sort IS '排序号(升序)';
COMMENT ON COLUMN js_biz_category.tree_sorts IS '所有排序号';
COMMENT ON COLUMN js_biz_category.tree_leaf IS '是否最末级';
COMMENT ON COLUMN js_biz_category.tree_level IS '层次级别';
COMMENT ON COLUMN js_biz_category.tree_names IS '全节点名';
COMMENT ON COLUMN js_biz_category.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_biz_category.create_by IS '创建者';
COMMENT ON COLUMN js_biz_category.create_date IS '创建时间';
COMMENT ON COLUMN js_biz_category.update_by IS '更新者';
COMMENT ON COLUMN js_biz_category.update_date IS '更新时间';
COMMENT ON COLUMN js_biz_category.remarks IS '备注信息';
COMMENT ON COLUMN js_biz_category.corp_code IS '租户代码';
COMMENT ON COLUMN js_biz_category.corp_name IS '租户名称';
COMMENT ON TABLE js_gen_table IS '代码生成表';
COMMENT ON COLUMN js_gen_table.table_name IS '表名';
COMMENT ON COLUMN js_gen_table.class_name IS '实体类名称';
@@ -1058,25 +1095,6 @@ COMMENT ON COLUMN js_sys_area.create_date IS '创建时间';
COMMENT ON COLUMN js_sys_area.update_by IS '更新者';
COMMENT ON COLUMN js_sys_area.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_area.remarks IS '备注信息';
COMMENT ON TABLE js_biz_category IS '业务分类';
COMMENT ON COLUMN js_biz_category.category_code IS '流程分类';
COMMENT ON COLUMN js_biz_category.view_code IS '分类代码';
COMMENT ON COLUMN js_biz_category.category_name IS '分类名称';
COMMENT ON COLUMN js_biz_category.parent_code IS '父级编号';
COMMENT ON COLUMN js_biz_category.parent_codes IS '所有父级编号';
COMMENT ON COLUMN js_biz_category.tree_sort IS '排序号(升序)';
COMMENT ON COLUMN js_biz_category.tree_sorts IS '所有排序号';
COMMENT ON COLUMN js_biz_category.tree_leaf IS '是否最末级';
COMMENT ON COLUMN js_biz_category.tree_level IS '层次级别';
COMMENT ON COLUMN js_biz_category.tree_names IS '全节点名';
COMMENT ON COLUMN js_biz_category.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_biz_category.create_by IS '创建者';
COMMENT ON COLUMN js_biz_category.create_date IS '创建时间';
COMMENT ON COLUMN js_biz_category.update_by IS '更新者';
COMMENT ON COLUMN js_biz_category.update_date IS '更新时间';
COMMENT ON COLUMN js_biz_category.remarks IS '备注信息';
COMMENT ON COLUMN js_biz_category.corp_code IS '租户代码';
COMMENT ON COLUMN js_biz_category.corp_name IS '租户名称';
COMMENT ON TABLE js_sys_company IS '公司表';
COMMENT ON COLUMN js_sys_company.company_code IS '公司编码';
COMMENT ON COLUMN js_sys_company.view_code IS '公司代码';
@@ -1375,6 +1393,15 @@ COMMENT ON COLUMN js_sys_menu.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN js_sys_menu.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN js_sys_menu.extend_d4 IS '扩展 Date 4';
COMMENT ON COLUMN js_sys_menu.extend_json IS '扩展 JSON';
COMMENT ON TABLE js_sys_menu_data_scope IS '菜单数据权限';
COMMENT ON COLUMN js_sys_menu_data_scope.id IS '编号';
COMMENT ON COLUMN js_sys_menu_data_scope.role_code IS '角色编码';
COMMENT ON COLUMN js_sys_menu_data_scope.menu_code IS '菜单编码';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_name IS '规则名称';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_type IS '规则类型1 角色数据范围 2自定义条件规则 3自定义SQL';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_config IS '规则配置JSON';
COMMENT ON COLUMN js_sys_menu_data_scope.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_menu_data_scope.remarks IS '备注信息';
COMMENT ON TABLE js_sys_module IS '模块表';
COMMENT ON COLUMN js_sys_module.module_code IS '模块编码';
COMMENT ON COLUMN js_sys_module.module_name IS '模块名称';
@@ -1551,7 +1578,7 @@ COMMENT ON COLUMN js_sys_role.is_sys IS '系统内置1是 0否';
COMMENT ON COLUMN js_sys_role.is_show IS '是否显示';
COMMENT ON COLUMN js_sys_role.user_type IS '用户类型employee员工 member会员';
COMMENT ON COLUMN js_sys_role.desktop_url IS '桌面地址(仪表盘地址)';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围设置0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.biz_scope IS '适应业务范围(不同的功能,不同的数据权限支持)';
COMMENT ON COLUMN js_sys_role.sys_codes IS '包含系统(多个用逗号隔开)';
COMMENT ON COLUMN js_sys_role.status IS '状态0正常 1删除 2停用';
@@ -1588,6 +1615,7 @@ COMMENT ON COLUMN js_sys_role_data_scope.role_code IS '控制角色编码';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_type IS '控制类型';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_data IS '控制数据';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_permi IS '控制权限';
COMMENT ON COLUMN js_sys_role_data_scope.menu_code IS '菜单编码';
COMMENT ON TABLE js_sys_role_menu IS '角色与菜单关联表';
COMMENT ON COLUMN js_sys_role_menu.role_code IS '角色编码';
COMMENT ON COLUMN js_sys_role_menu.menu_code IS '菜单编码';

View File

@@ -2,6 +2,31 @@
/* Create Tables */
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL,
view_code varchar(500),
category_name varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(767) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
) WITHOUT OIDS;
-- 代码生成表
CREATE TABLE js_gen_table
(
@@ -79,31 +104,6 @@ CREATE TABLE js_sys_area
) WITHOUT OIDS;
-- 业务分类
CREATE TABLE js_biz_category
(
category_code varchar(64) NOT NULL,
view_code varchar(500),
category_name varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(767) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(767) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(767) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (category_code)
) WITHOUT OIDS;
-- 公司表
CREATE TABLE js_sys_company
(
@@ -492,6 +492,21 @@ CREATE TABLE js_sys_menu
) WITHOUT OIDS;
-- 菜单数据权限
CREATE TABLE js_sys_menu_data_scope
(
id varchar(64) NOT NULL,
role_code varchar(64) NOT NULL,
menu_code varchar(64) NOT NULL,
rule_name varchar(100),
rule_type char(1),
rule_config text,
status char(1),
remarks varchar(500),
PRIMARY KEY (id)
) WITHOUT OIDS;
-- 模块表
CREATE TABLE js_sys_module
(
@@ -767,7 +782,8 @@ CREATE TABLE js_sys_role_data_scope
ctrl_type varchar(20) NOT NULL,
ctrl_data varchar(64) NOT NULL,
ctrl_permi varchar(64) NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi)
menu_code varchar(64) DEFAULT '0' NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi, menu_code)
) WITHOUT OIDS;
@@ -934,6 +950,8 @@ CREATE INDEX idx_sys_menu_sc ON js_sys_menu (sys_code);
CREATE INDEX idx_sys_menu_is ON js_sys_menu (is_show);
CREATE INDEX idx_sys_menu_mcs ON js_sys_menu (module_codes);
CREATE INDEX idx_sys_menu_wt ON js_sys_menu (weight);
CREATE INDEX idx_sys_menu_ds_mc ON js_sys_menu_data_scope (menu_code);
CREATE INDEX idx_sys_menu_ds_rc ON js_sys_menu_data_scope (role_code);
CREATE INDEX idx_sys_module_status ON js_sys_module (status);
CREATE INDEX idx_sys_msg_inner_cb ON js_sys_msg_inner (create_by);
CREATE INDEX idx_sys_msg_inner_status ON js_sys_msg_inner (status);
@@ -999,6 +1017,25 @@ CREATE INDEX idx_sys_user_cc ON js_sys_user (corp_code);
/* Comments */
COMMENT ON TABLE js_biz_category IS '业务分类';
COMMENT ON COLUMN js_biz_category.category_code IS '流程分类';
COMMENT ON COLUMN js_biz_category.view_code IS '分类代码';
COMMENT ON COLUMN js_biz_category.category_name IS '分类名称';
COMMENT ON COLUMN js_biz_category.parent_code IS '父级编号';
COMMENT ON COLUMN js_biz_category.parent_codes IS '所有父级编号';
COMMENT ON COLUMN js_biz_category.tree_sort IS '排序号(升序)';
COMMENT ON COLUMN js_biz_category.tree_sorts IS '所有排序号';
COMMENT ON COLUMN js_biz_category.tree_leaf IS '是否最末级';
COMMENT ON COLUMN js_biz_category.tree_level IS '层次级别';
COMMENT ON COLUMN js_biz_category.tree_names IS '全节点名';
COMMENT ON COLUMN js_biz_category.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_biz_category.create_by IS '创建者';
COMMENT ON COLUMN js_biz_category.create_date IS '创建时间';
COMMENT ON COLUMN js_biz_category.update_by IS '更新者';
COMMENT ON COLUMN js_biz_category.update_date IS '更新时间';
COMMENT ON COLUMN js_biz_category.remarks IS '备注信息';
COMMENT ON COLUMN js_biz_category.corp_code IS '租户代码';
COMMENT ON COLUMN js_biz_category.corp_name IS '租户名称';
COMMENT ON TABLE js_gen_table IS '代码生成表';
COMMENT ON COLUMN js_gen_table.table_name IS '表名';
COMMENT ON COLUMN js_gen_table.class_name IS '实体类名称';
@@ -1058,25 +1095,6 @@ COMMENT ON COLUMN js_sys_area.create_date IS '创建时间';
COMMENT ON COLUMN js_sys_area.update_by IS '更新者';
COMMENT ON COLUMN js_sys_area.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_area.remarks IS '备注信息';
COMMENT ON TABLE js_biz_category IS '业务分类';
COMMENT ON COLUMN js_biz_category.category_code IS '流程分类';
COMMENT ON COLUMN js_biz_category.view_code IS '分类代码';
COMMENT ON COLUMN js_biz_category.category_name IS '分类名称';
COMMENT ON COLUMN js_biz_category.parent_code IS '父级编号';
COMMENT ON COLUMN js_biz_category.parent_codes IS '所有父级编号';
COMMENT ON COLUMN js_biz_category.tree_sort IS '排序号(升序)';
COMMENT ON COLUMN js_biz_category.tree_sorts IS '所有排序号';
COMMENT ON COLUMN js_biz_category.tree_leaf IS '是否最末级';
COMMENT ON COLUMN js_biz_category.tree_level IS '层次级别';
COMMENT ON COLUMN js_biz_category.tree_names IS '全节点名';
COMMENT ON COLUMN js_biz_category.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_biz_category.create_by IS '创建者';
COMMENT ON COLUMN js_biz_category.create_date IS '创建时间';
COMMENT ON COLUMN js_biz_category.update_by IS '更新者';
COMMENT ON COLUMN js_biz_category.update_date IS '更新时间';
COMMENT ON COLUMN js_biz_category.remarks IS '备注信息';
COMMENT ON COLUMN js_biz_category.corp_code IS '租户代码';
COMMENT ON COLUMN js_biz_category.corp_name IS '租户名称';
COMMENT ON TABLE js_sys_company IS '公司表';
COMMENT ON COLUMN js_sys_company.company_code IS '公司编码';
COMMENT ON COLUMN js_sys_company.view_code IS '公司代码';
@@ -1375,6 +1393,15 @@ COMMENT ON COLUMN js_sys_menu.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN js_sys_menu.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN js_sys_menu.extend_d4 IS '扩展 Date 4';
COMMENT ON COLUMN js_sys_menu.extend_json IS '扩展 JSON';
COMMENT ON TABLE js_sys_menu_data_scope IS '菜单数据权限';
COMMENT ON COLUMN js_sys_menu_data_scope.id IS '编号';
COMMENT ON COLUMN js_sys_menu_data_scope.role_code IS '角色编码';
COMMENT ON COLUMN js_sys_menu_data_scope.menu_code IS '菜单编码';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_name IS '规则名称';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_type IS '规则类型1 角色数据范围 2自定义条件规则 3自定义SQL';
COMMENT ON COLUMN js_sys_menu_data_scope.rule_config IS '规则配置JSON';
COMMENT ON COLUMN js_sys_menu_data_scope.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_menu_data_scope.remarks IS '备注信息';
COMMENT ON TABLE js_sys_module IS '模块表';
COMMENT ON COLUMN js_sys_module.module_code IS '模块编码';
COMMENT ON COLUMN js_sys_module.module_name IS '模块名称';
@@ -1551,7 +1578,7 @@ COMMENT ON COLUMN js_sys_role.is_sys IS '系统内置1是 0否';
COMMENT ON COLUMN js_sys_role.is_show IS '是否显示';
COMMENT ON COLUMN js_sys_role.user_type IS '用户类型employee员工 member会员';
COMMENT ON COLUMN js_sys_role.desktop_url IS '桌面地址(仪表盘地址)';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围设置0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.biz_scope IS '适应业务范围(不同的功能,不同的数据权限支持)';
COMMENT ON COLUMN js_sys_role.sys_codes IS '包含系统(多个用逗号隔开)';
COMMENT ON COLUMN js_sys_role.status IS '状态0正常 1删除 2停用';
@@ -1588,6 +1615,7 @@ COMMENT ON COLUMN js_sys_role_data_scope.role_code IS '控制角色编码';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_type IS '控制类型';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_data IS '控制数据';
COMMENT ON COLUMN js_sys_role_data_scope.ctrl_permi IS '控制权限';
COMMENT ON COLUMN js_sys_role_data_scope.menu_code IS '菜单编码';
COMMENT ON TABLE js_sys_role_menu IS '角色与菜单关联表';
COMMENT ON COLUMN js_sys_role_menu.role_code IS '角色编码';
COMMENT ON COLUMN js_sys_role_menu.menu_code IS '菜单编码';

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>5.8.0-SNAPSHOT</version>
<version>5.11.0-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
@@ -73,16 +73,16 @@
<!-- 达梦数据库
<dependency>
<groupId>com.dameng</groupId>
<artifactId>Dm8JdbcDriver18</artifactId>
<version>8.1.1.49</version>
<groupId>com.dameng</groupId>
<artifactId>Dm8JdbcDriver18</artifactId>
<version>8.1.1.49</version>
</dependency> -->
<!-- 人大金仓数据库
<dependency>
<groupId>com.kingbase</groupId>
<artifactId>kingbasejdbc8</artifactId>
<version>8.6.0</version>
<groupId>com.kingbase</groupId>
<artifactId>kingbasejdbc8</artifactId>
<version>8.6.0</version>
</dependency> -->
<!-- Web Server -->
@@ -113,6 +113,20 @@
<version>${project.parent.version}</version>
</dependency>
<!-- Core Static -->
<dependency>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-module-static</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- CAS 单点登录模块 -->
<dependency>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-module-cas</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- ELK 日志收集 -->
<dependency>
<groupId>net.logstash.logback</groupId>
@@ -122,13 +136,13 @@
</dependencies>
<developers>
<developers>
<developer>
<id>thinkgem</id>
<name>WangZhen</name>
<email>thinkgem at 163.com</email>
<roles><role>Project lead</role></roles>
<timezone>+8</timezone>
<timezone>+8</timezone>
</developer>
</developers>

View File

@@ -7,6 +7,7 @@ package com.jeesite.autoconfigure.core;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.shiro.cas.CasOutHandler;
import com.jeesite.common.shiro.cas.CasSubjectFactory;
import com.jeesite.common.shiro.config.FilterChainDefinitionMap;
import com.jeesite.common.shiro.filter.*;
import com.jeesite.common.shiro.realm.AuthorizingRealm;
@@ -17,7 +18,6 @@ import com.jeesite.common.shiro.session.SessionManager;
import com.jeesite.common.shiro.web.ShiroFilterFactoryBean;
import com.jeesite.common.shiro.web.WebSecurityManager;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;

View File

@@ -7,6 +7,7 @@ package com.jeesite.common.shiro.filter;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.ExceptionUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.shiro.cas.CasBaseFilter;
import com.jeesite.common.shiro.realm.BaseAuthorizingRealm;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.sys.utils.UserUtils;
@@ -26,7 +27,7 @@ import javax.servlet.http.HttpServletResponse;
* @version 2020-9-19
*/
@SuppressWarnings("deprecation")
public class CasFilter extends org.apache.shiro.cas.CasFilter {
public class CasFilter extends CasBaseFilter {
private BaseAuthorizingRealm authorizingRealm;

View File

@@ -8,6 +8,7 @@ import com.jeesite.common.codec.DesUtils;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.collect.SetUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.lang.StringUtils;
@@ -17,13 +18,8 @@ import com.jeesite.common.shiro.realm.BaseAuthorizingRealm;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.common.web.CookieUtils;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.sys.entity.Log;
import com.jeesite.modules.sys.entity.Role;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.utils.CorpUtils;
import com.jeesite.modules.sys.utils.LogUtils;
import com.jeesite.modules.sys.utils.UserUtils;
import com.jeesite.modules.sys.utils.ValidCodeUtils;
import com.jeesite.modules.sys.entity.*;
import com.jeesite.modules.sys.utils.*;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
@@ -45,6 +41,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* 表单验证(包含验证码)过滤类
@@ -57,8 +54,11 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
public static final String MESSAGE_PARAM = "message"; // 登录返回消息
public static final String REMEMBER_USERCODE_PARAM = "rememberUserCode"; // 记住用户名
public static final String EXCEPTION_ATTRIBUTE_NAME = "exception"; // 异常类属性名
public static final String LOGIN_PARAM = "__login"; // 支持GET方式登录的参数
public static final String LOGIN_PARAM = "__login"; // 支持GET方式登录的参数
public static final Boolean POST_ROLE_PERMI = Global.getConfigToBoolean("user.postRolePermi", "false");
public static final Boolean SWITCH_OFFICE = Global.getConfigToBoolean("user.switchOffice", "false");
private static final Logger logger = LoggerFactory.getLogger(FormFilter.class);
private static FormFilter instance;
@@ -261,21 +261,19 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
// 是否在登录后生成新的Session默认false
if (Global.getPropertyToBoolean("shiro.isGenerateNewSessionAfterLogin", "false")){
String[] keys = new String[] {ValidCodeUtils.VALID_CODE};
Map<String, Object> map = MapUtils.newHashMap();
String[] keys = new String[] { ValidCodeUtils.VALID_CODE };
Map<String, Object> attrMap = MapUtils.newHashMap();
final Session sessionOld = UserUtils.getSession();
for (String key : keys) {
Object value = sessionOld.getAttribute(key);
if (value != null) {
map.put(key, value);
attrMap.put(key, value);
}
}
UserUtils.getSubject().logout();
// 恢复生成新的Session之前的Session数据
final Session sessionNew = UserUtils.getSession();
map.forEach((key, value) -> {
sessionNew.setAttribute(key, value);
});
attrMap.forEach(sessionNew::setAttribute);
}
return super.executeLogin(request, response);
}
@@ -300,15 +298,10 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
HttpServletRequest request = (HttpServletRequest)servletRequest;
// 登录成功后初始化授权信息并处理登录后的操作
authorizingRealm.onLoginSuccess(UserUtils.getLoginInfo(), request);
// 跳转到登录成功页面
String successUrl = getSuccessUrl(); // shiro.successUrl in application.yml
if (StringUtils.contains((request).getRequestURI(), "/oauth2/callback/")) {
successUrl = Global.getConfig("oauth2.successUrl", successUrl);
} else if (StringUtils.contains((request).getRequestURI(), "/sso")) {
String ssoSuccessUrl = (String)request.getAttribute("__url");
if (StringUtils.isNotBlank(ssoSuccessUrl)) {
successUrl = ssoSuccessUrl;
}
// 跳转到登录成功页面,若未指定则获取默认 shiro.successUrl in application.yml
String successUrl = (String)request.getAttribute("__url");
if (StringUtils.isBlank(successUrl)) {
successUrl = getSuccessUrl();
}
ServletUtils.redirectUrl(request, (HttpServletResponse)response, successUrl);
return false;
@@ -431,9 +424,12 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
Global.setLang((String)paramMap.get("lang"), request, response);
}
data.put("demoMode", Global.isDemoMode());
data.put("useCorpModel", Global.isUseCorpModel()
&& Global.getConfigToBoolean("user.loginCodeCorpUnique", "false"));
data.put("useCorpModel", Global.isUseCorpModel());
data.put("loginCodeCorpUnique", Global.getConfigToBoolean("user.loginCodeCorpUnique", "false"));
data.put("title", Global.getProperty("productName"));
data.put("company", Global.getProperty("companyName"));
data.put("version", Global.getProperty("productVersion"));
data.put("year", Global.getProperty("copyrightYear"));
}
/**
@@ -456,10 +452,15 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
data.put("msgEnabled", Global.getPropertyToBoolean("msg.enabled", "false"));
data.put("sysCode", session.getAttribute("sysCode"));
data.put("roleCode", session.getAttribute("roleCode"));
data.put("postCode", session.getAttribute("postCode"));
data.put("title", Global.getProperty("productName"));
data.put("company", Global.getProperty("companyName"));
data.put("version", Global.getProperty("productVersion"));
data.put("year", Global.getProperty("copyrightYear"));
data.put("lang", Global.getLang());
List<Map<String, Object>> roleList = ListUtils.newArrayList();
String desktopUrl = null;
String desktopUrl = null; String roleCode = (String)session.getAttribute("roleCode");
Set<String> roleCodes = roleCode != null ? SetUtils.newHashSet(StringUtils.splitComma(roleCode)) : null;
for (Role role : user.getRoleList()){
Map<String, Object> roleMap = MapUtils.newHashMap();
roleMap.put("roleCode", role.getRoleCode());
@@ -467,11 +468,38 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
roleMap.put("isShow", role.getIsShow());
roleMap.put("sysCodes", role.getSysCodes());
roleList.add(roleMap);
if (desktopUrl == null && StringUtils.isNotBlank(role.getDesktopUrl())) {
desktopUrl = role.getDesktopUrl();
// 根据当前身份,选择桌面地址(先得到先受用)
if (desktopUrl == null) {
if (roleCodes != null){
if (roleCodes.contains(role.getRoleCode()) && StringUtils.isNotBlank(role.getDesktopUrl())) {
desktopUrl = role.getDesktopUrl();
}
}else if (StringUtils.isNotBlank(role.getDesktopUrl())) {
desktopUrl = role.getDesktopUrl();
}
}
}
data.put("roleList", roleList);
if (POST_ROLE_PERMI && User.USER_TYPE_EMPLOYEE.equals(user.getUserType())) {
List<Map<String, Object>> postList = ListUtils.newArrayList();
data.put("postRolePermi", "true");
Employee employee = user.getRefObj();
for (EmployeePost ep : EmpUtils.getEmployeePostList(employee.getEmpCode())){
Post post = ep.getPost();
if (post != null) {
Map<String, Object> postMap = MapUtils.newHashMap();
postMap.put("postCode", post.getPostCode());
postMap.put("postName", post.getPostName());
postList.add(postMap);
}
}
data.put("postList", postList);
}
if (SWITCH_OFFICE && User.USER_TYPE_EMPLOYEE.equals(user.getUserType())) {
data.put("switchOffice", "true");
data.put("officeCode", session.getAttribute("officeCode"));
data.put("officeName", EmpUtils.getCurrentOfficeName());
}
data.put("desktopUrl", desktopUrl != null ? desktopUrl : Global.getConfig("sys.index.desktopUrl"));
return data;
}

View File

@@ -5,7 +5,9 @@
package com.jeesite.common.shiro.realm;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.codec.SM3Utils;
import com.jeesite.common.codec.Sha1Utils;
import com.jeesite.common.config.Global;
import com.jeesite.common.shiro.authc.FormToken;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.modules.sys.entity.Log;
@@ -30,19 +32,15 @@ import javax.servlet.http.HttpServletRequest;
public class AuthorizingRealm extends BaseAuthorizingRealm {
public static final String HASH_ALGORITHM = "SHA-1";
public static final int HASH_INTERATIONS = 1024;
public static final int HASH_ITERATIONS = 1024;
public static final int SALT_SIZE = 8;
private UserService userService;
public AuthorizingRealm() {
super();
// // 设定密码校验的Hash算法与迭代次数V4.1.4及以上版本不需要了统一使用validatePassword验证密码
// HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
// matcher.setHashIterations(HASH_INTERATIONS);
// this.setCredentialsMatcher(matcher);
}
/**
* 获取登录凭证,将 authcToken 转换为 FormToken参考 CAS 实现
*/
@@ -50,7 +48,7 @@ public class AuthorizingRealm extends BaseAuthorizingRealm {
protected FormToken getFormToken(AuthenticationToken authcToken) {
return super.getFormToken(authcToken);
}
/**
* 用于用户根据登录信息获取用户信息<br>
* 1、默认根据登录账号登录信息UserUtils.getByLoginCode(formToken.getUsername(), formToken.getParam("corpCode"));<br>
@@ -61,7 +59,7 @@ public class AuthorizingRealm extends BaseAuthorizingRealm {
protected User getUserInfo(FormToken formToken) {
return super.getUserInfo(formToken);
}
/**
* 校验登录凭证如密码验证token验证验证失败抛出 AuthenticationException 异常
*/
@@ -86,9 +84,13 @@ public class AuthorizingRealm extends BaseAuthorizingRealm {
@Override
public String encryptPassword(String plainPassword) {
String plain = EncodeUtils.decodeHtml(plainPassword);
byte[] salt = Sha1Utils.genSalt(SALT_SIZE);
byte[] hashPassword = Sha1Utils.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
return EncodeUtils.encodeHex(salt) + EncodeUtils.encodeHex(hashPassword);
String salt = SM3Utils.genSaltString(SALT_SIZE);
if (Global.isSmAlgorithm()) {
String data = SM3Utils.sm3(plain, salt, HASH_ITERATIONS);
return salt + data;
}
String data = Sha1Utils.sha1(plain, salt, HASH_ITERATIONS);
return salt + data;
}
/**
@@ -101,9 +103,13 @@ public class AuthorizingRealm extends BaseAuthorizingRealm {
public boolean validatePassword(String plainPassword, String password) {
try{
String plain = EncodeUtils.decodeHtml(plainPassword);
byte[] salt = EncodeUtils.decodeHex(password.substring(0, 16));
byte[] hashPassword = Sha1Utils.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
return password.equals(EncodeUtils.encodeHex(salt) + EncodeUtils.encodeHex(hashPassword));
String salt = password.substring(0, SALT_SIZE * 2);
if (Global.isSmAlgorithm()) {
String data = SM3Utils.sm3(plain, salt, HASH_ITERATIONS);
return password.equals(salt + data);
}
String data = Sha1Utils.sha1(plain, salt, HASH_ITERATIONS);
return password.equals(salt + data);
}catch(Exception e){
return false;
}

View File

@@ -10,6 +10,7 @@ import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.shiro.authc.FormToken;
import com.jeesite.common.shiro.cas.CasCreateUser;
import com.jeesite.common.shiro.cas.CasOutHandler;
import com.jeesite.common.shiro.cas.CasToken;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.sys.entity.EmpUser;
@@ -22,7 +23,6 @@ import com.jeesite.modules.sys.utils.UserUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.cas.CasToken;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;

View File

@@ -12,7 +12,6 @@ import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.biz.entity.BizCategory;
import com.jeesite.modules.biz.service.BizCategoryService;
import com.jeesite.modules.sys.utils.UserUtils;
import io.swagger.annotations.Api;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
@@ -236,7 +235,7 @@ public class BizCategoryController extends BaseController {
@RequestMapping(value = "fixTreeData")
@ResponseBody
public String fixTreeData(BizCategory bizCategory){
if (!UserUtils.getUser().isAdmin()){
if (!bizCategory.currentUser().isAdmin()){
return renderResult(Global.FALSE, "操作失败,只有管理员才能进行修复!");
}
bizCategoryService.fixTreeData();

View File

@@ -25,7 +25,7 @@ import java.io.IOException;
* @version 2017年11月30日
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name="state.enabled", havingValue="true", matchIfMissing=true)
@ConditionalOnProperty(name={"state.enabled","state.druid"}, havingValue="true", matchIfMissing=true)
public class DruidStatConfig {
/**
@@ -43,7 +43,7 @@ public class DruidStatConfig {
bean.addUrlPatterns("/*");
return bean;
}
/**
* 注册DruidServlet
*/

Some files were not shown because too many files have changed in this diff Show More