Compare commits

...

93 Commits

Author SHA1 Message Date
ef762ff21f 日志里把具体的文件加上吧 issues/I3BJDQ 2021-04-01 09:44:47 +08:00
02abd5c803 优化生成器模板:让代码更简洁,流程相关代码默认不生成 2021-04-01 09:42:47 +08:00
5e7342b27d 优化代码生成器模板:一对多代码生成(ERP模板)生成的子表实体ApiModel注释中value为附表名称 #2365 2021-04-01 09:40:43 +08:00
ca95d7090c minio上传文件,文件名包含点的时候拼接文件名有问题 issues/I3CLFL 2021-04-01 09:38:45 +08:00
cdec71999a spring-boot-starter-jimureport降低版本,公共仓库可以下载 2021-03-31 17:46:04 +08:00
7990eff7a4 JImageUpload组件单张无法预览和删除 #2382 2021-03-31 12:01:18 +08:00
280f8c26ac online报表配置支持多租户系统变量 issues/I3CL75 2021-03-31 12:00:51 +08:00
4e05eaa4c5 JEditableTable组件popup字段设置必填校验有问题 2021-03-31 11:59:47 +08:00
c6645ed800 描述文字写错修改 2021-03-28 19:51:53 +08:00
a674340c5e 微服务模式部署下,nacos的账户密码如果不使用默认提供的nacos/nacos,会导致gateway读取路由信息失败 #2375 2021-03-28 19:45:50 +08:00
cbd8890cb3 代码生成器,树列表新增,会默认加上上次选的父节点问题 2021-03-24 15:56:31 +08:00
b25fb55d10 代码生成器,树列表固定操作列,解决列表分类未翻译问题 2021-03-24 15:55:59 +08:00
88646bea1b 让不对接流程的表单,生成的页面代码更简洁 2021-03-23 22:26:19 +08:00
9915b84808 升级2.4.3后,微服务网关路由更新bug 2021-03-23 15:30:04 +08:00
35c1214de3 开发和测试环境取消swagger文档密码 2021-03-23 14:23:32 +08:00
434b1a7e63 BindingResult无法使用 #2219 2021-03-23 14:23:06 +08:00
5c7d84117c nacos分组配置问题 #2355 2021-03-23 14:22:37 +08:00
4b9890205e JeecgBoot2.4.3版本发布——企业级低代码平台 2021-03-18 13:43:13 +08:00
d5898139b5 2.3版本oracle、SqlServer数据库脚本 2021-03-18 12:57:39 +08:00
bf438069e2 2.4.3版本发布——企业级低代码平台 2021-03-17 18:46:12 +08:00
c5965b10d8 JeecgBoot2.4.3版本发布——企业级低代码平台 2021-03-17 18:43:44 +08:00
da5ace3397 JeecgBoot2.4.3版本发布——企业级低代码平台 2021-03-17 18:40:08 +08:00
4674097078 单体镜像制作脚本 2021-03-10 14:39:14 +08:00
fea1607f1b 单体镜像制作脚本 2021-03-10 14:35:50 +08:00
d2336bc5e1 依赖jar上传到maven官仓,简化使用 2021-03-09 22:20:12 +08:00
cf0d29557a 重写xxljob避免默认 9999端口冲突 2021-03-09 18:27:34 +08:00
bb4c3c86b0 官仓未同步成功,暂时用jeecg私服 2021-03-09 17:26:15 +08:00
84a6e28677 nacos server本地化采用jar方式启动,简化开发 2021-03-09 11:34:11 +08:00
5b70c1d8b8 nacos server本地化采用jar方式启动,简化开发 2021-03-09 11:33:03 +08:00
f942abe09b 微服务模式相关服务的链接改成host模式 2021-03-09 11:19:51 +08:00
ad4eb300f0 nacos server本地化采用jar方式启动,简化开发 2021-03-09 11:10:01 +08:00
064a5c4a0e nacos server本地化采用jar方式启动,简化开发 2021-03-09 10:33:28 +08:00
6d688a157b nacos server本地化采用jar方式启动,简化开发 2021-03-08 20:30:17 +08:00
d612af5e3b nacos server本地化采用jar方式启动,简化开发 2021-03-08 20:29:36 +08:00
e1c0b0fa38 system服务和demo服务有办法同时使用xxl-job吗 #2313 2021-03-05 17:13:44 +08:00
ac0979c824 system服务和demo服务有办法同时使用xxl-job吗 #2313 2021-03-05 17:08:56 +08:00
78ba7ccba8 system服务和demo服务有办法同时使用xxl-job吗 #2313 2021-03-05 17:02:49 +08:00
b8ff5ebd43 微服务部署下代码生成失效,单体模式下代码生成可用 #2324 2021-03-04 17:39:54 +08:00
5eb2541834 gateway访问默认进入swagger文档首页 2021-03-04 09:48:40 +08:00
462b0d17b1 字典【是否启用】按钮会错误的保存状态 #2311 2021-03-04 09:40:22 +08:00
7cc54084dc docker-compose脚本优化,nacos采用mysql方式自动初始化配置 2021-03-03 15:58:38 +08:00
32297110d9 docker-compose 微服务模式脚本优化 2021-03-02 19:25:55 +08:00
b7717d0461 docker-compose 微服务模式脚本优化 2021-03-02 19:09:39 +08:00
97c078c46a docker-compose 微服务模式脚步优化 2021-03-02 19:09:18 +08:00
17019e6261 docker-compose 镜像制作脚步 2021-03-01 10:31:54 +08:00
4a49479985 关于测边菜单遮挡内容问题详细说明 #2255 2021-02-24 15:26:21 +08:00
e49d76bc80 部门管理员添加上级用户时缺失负责部门列issues/I2SDU1 2021-02-24 15:25:31 +08:00
d6cf2b502b 批量导入部门以后,不能追加下一级部门 #2245 2021-02-24 15:23:13 +08:00
c741d779f2 【严重问题】issues/I37PNL 微服务化后-cloud-demo项目导出无法和字典关联 2021-02-21 15:45:24 +08:00
7f847c9721 删除jeecg-cloud-example例子模块,测试示例重构到jeecg-cloud-system-start中--- 2021-02-21 14:37:07 +08:00
fa2c5ecb73 删除jeecg-cloud-example例子模块,测试示例重构到jeecg-cloud-system-start中--- 2021-02-21 14:36:55 +08:00
eb1578ada3 删除jeecg-cloud-example例子模块,测试示例重构到jeecg-cloud-system-start中--- 2021-02-21 14:36:44 +08:00
90758f3b2a 有个小Bug issues/I3854N 2021-02-21 09:40:03 +08:00
766c48bdbf feign 动态创建client,拦截器执行多次 #2275 2021-02-20 20:59:13 +08:00
d16520cc59 swagger密码访问不生效 #2253 2021-02-17 23:04:22 +08:00
0252213b6e 微服务Feign调用Provider报错Token为空的问题 #2263 2021-02-17 21:05:14 +08:00
ce44147e6e 集成xxl-job-2.2.0之后,注解没有删掉,导致启动报端口冲突 #2228 2021-02-06 12:14:22 +08:00
0ea4ac910a 代码生成单表开关控件有问题 2021-02-06 12:13:28 +08:00
4f61f0ad48 重复check接口,sql注入检查 2021-02-01 20:33:10 +08:00
4a5ff61ef7 导入excel校验示例代码 2021-02-01 20:32:41 +08:00
88a0bb2d2d 文档地址写错了 2021-02-01 20:32:14 +08:00
b153669b69 图片导出报错,本地upload情况下,ImageBasePath未设置 2021-02-01 20:31:59 +08:00
449a7759be JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-25 18:31:46 +08:00
337920964d JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-25 16:43:09 +08:00
2a7946ae42 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-25 15:03:14 +08:00
c233f95f5f JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-25 14:13:20 +08:00
f87cc2d97f 更新数据库脚本 2021-01-25 12:55:15 +08:00
02bb521b8f Cloud demo 命名让人误解,改名为example 2021-01-25 12:38:31 +08:00
53e84ae34b Cloud demo 命名让人误解,更名 2021-01-25 12:32:41 +08:00
d6feeef7b5 Cloud demo 命名让人误解,更名 2021-01-25 12:32:25 +08:00
18fc7b146a Cloud demo 命名让人误解,改名为example 2021-01-25 12:31:42 +08:00
3792f46388 FeignConfig 重复注册问题处理 2021-01-25 12:01:40 +08:00
f35236609c TomcatServletWebServerFactory重复注册问题处理 2021-01-25 11:43:50 +08:00
e46b653bc4 JeecgBoot 2.4.2 积木报表版本发布(注释掉可以不用的测试类) 2021-01-25 11:29:00 +08:00
4437c749ca JeecgBoot 2.4.2 积木报表版本发布(微服务启动报错) 2021-01-25 11:26:50 +08:00
74ebac4967 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 14:44:10 +08:00
a9f21795cb JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 14:12:28 +08:00
a5ca8183cd JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 01:14:43 +08:00
e7970e52bc JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 01:14:13 +08:00
74a9e10ce6 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 01:01:12 +08:00
df5c106d94 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 00:13:15 +08:00
ae0f9edb27 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 00:06:48 +08:00
3d4bb704f1 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-24 00:02:38 +08:00
85efec3730 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-23 23:59:55 +08:00
8b0ee2d0a2 JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台 2021-01-23 23:59:31 +08:00
41c1572ad8 简化项目默认单体 2021-01-12 19:02:55 +08:00
5d555158fe 文字修改 2021-01-12 18:29:09 +08:00
1fd0b5d4db --date:20201226--for:--升级aliyun短信依赖、aliyun.oss云存储依赖、minio依赖、qiniu云依赖、justauth授权登录okhttp冲突问题----
jeecg-boot-base/jeecg-boot-base-core/org/jeecg/common/util/MinioUtil.java
jeecg-boot-base/jeecg-boot-base-core/pom.xml
pom.xml
2020-12-26 14:12:51 +08:00
693d86cf00 上传图片报错 #2090 cn.hutool.core.lang.Singleton.get(Ljava/lang/String;Lcn/hutool/core/lang/func/Func0;)Ljava/lang/Object; 2020-12-24 22:19:52 +08:00
9a3f872d63 Merge pull request #2107 from Junvary/master
修复  菜单管理-编辑-默认跳转地址   不显示内容的bug
2020-12-24 22:03:49 +08:00
5b82a1aa06 Merge pull request #1967 from tank99tank/char_400
SpringBoot 请求参数包含 [] 特殊符号 返回400状态
2020-12-24 22:01:03 +08:00
2fa1c7c17b 修复 菜单管理-编辑-默认跳转地址 不显示内容的bug
菜单管理-编辑-默认跳转地址   如果填写了内容并保存,再次编辑时,不会显示这些内容,实际上是有的。
2020-12-15 09:29:09 +08:00
94c0610496 SpringBoot 请求参数包含 [] 特殊符号 返回400状态 #1795 2020-11-11 13:04:29 +08:00
374 changed files with 229579 additions and 17796 deletions

1
.gitattributes vendored
View File

@ -2,3 +2,4 @@
*.css linguist-language=Java
*.html linguist-language=Java
*.vue linguist-language=Java
*.sql linguist-language=Java

View File

@ -7,12 +7,12 @@
JEECG BOOT 低代码开发平台(前后端分离版本)
===============
当前最新版本: 2.4.0发布日期2020-12-01
当前最新版本: 2.4.3发布日期2021-03-22
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
[![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](http://www.jeecg.com)
[![](https://img.shields.io/badge/version-2.4-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![](https://img.shields.io/badge/version-2.4.3-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)
@ -73,7 +73,7 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
为什么选择JEECG-BOOT?
-----------------------------------
* 1.采用最新主流前后分离框架Springboot+Mybatis+antd容易上手; 代码生成器依赖性低,灵活的扩展能力,可快速实现二次开发;
* 2.支持微服务SpringCloud Alibaba(Nacos、Gateway、Sentinel、Skywarking),提供切换机制支持单体和微服务自由切换
* 2.支持微服务SpringCloud Alibaba(Nacos、Gateway、Sentinel、Skywalking),提供切换机制支持单体和微服务自由切换
* 3.开发效率高,采用代码生成器,单表、树列表、一对多、一对一等数据模型,增删改查功能一键生成,菜单配置直接使用;
* 4.代码生成器提供强大模板机制,支持自定义模板,目前提供四套风格模板(单表两套、树模型一套、一对多三套)
* 5.代码生成器非常智能在线业务建模、在线配置、所见即所得支持23种类控件一键生成前后端代码大幅度提升开发效率不再为重复工作发愁。
@ -143,7 +143,7 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
- 安全框架Apache Shiro 1.7.0Jwt 3.11.0
- 微服务技术栈Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywarking
- 微服务技术栈Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
- 数据库连接池阿里巴巴Druid 1.1.22
@ -328,7 +328,7 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
8、服务监控 SpringBootAdmin√
9、链路跟踪 Skywarking [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1771670)
9、链路跟踪 Skywalking [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1771670)
10、消息中间件 RabbitMQ √
@ -336,7 +336,7 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
12、分布式事务 Seata
13、分布式日志 elk + kafa
13、分布式日志 elk + kafka
14、支持 docker-compose、k8s、jenkins
@ -349,7 +349,7 @@ Jeecg-Boot低代码开发平台可以应用在任何J2EE项目的开发中
![微服务架构图](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/jeecgboot-weifuwu-cloud.png "在这里输入图片标题")
### Jeecg Boot 产品功能蓝图
![功能蓝图](https://static.jeecg.com/upload/test/Jeecg-Boot-lantu202005_1590912449914.jpg "在这里输入图片标题")
![功能蓝图](https://jeecgos.oss-cn-beijing.aliyuncs.com/upload/test/Jeecg-Boot-lantu202005_1590912449914.jpg "在这里输入图片标题")
后台开发环境和依赖

View File

@ -1,3 +1,3 @@
NODE_ENV=production
VUE_APP_PLATFORM_NAME=Jeecg-Boot 企业级快速开发平台
VUE_APP_PLATFORM_NAME=JeecgBoot 企业级低代码平台
VUE_APP_SSO=false

View File

@ -1,4 +1,4 @@
NODE_ENV=production
VUE_APP_API_BASE_URL=https://bootapi.jeecg.com
VUE_APP_API_BASE_URL=http://localhost:8080/jeecg-boot
VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview

View File

@ -1,13 +1,13 @@
Ant Design Jeecg Vue
====
当前最新版本: 2.4.0发布日期20201201
当前最新版本: 2.4.3发布日期20210322
Overview
----
基于 [Ant Design of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 实现的 Ant Design Pro Vue 版
Jeecg-boot 的前段UI框架采用前后端分离方案提供强大代码生成器的快速开发平台。
Jeecg-boot 的前段UI框架采用前后端分离方案提供强大代码生成器的低代码平台。
前端页面代码和后端功能代码一键生成不需要写任何代码保持jeecg一贯的强大

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "vue-antd-jeecg",
"version": "2.4.0",
"version": "2.4.3",
"private": true,
"scripts": {
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
@ -10,8 +10,8 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@jeecg/antd-online-mini": "2.4.0-beta4",
"ant-design-vue": "^1.7.2",
"@jeecg/antd-online-mini": "2.4.3-RC",
"@antv/data-set": "^0.11.4",
"viser-vue": "^2.4.8",
"axios": "^0.18.0",
@ -96,7 +96,10 @@
"vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0,
"no-tabs": 0,
"indent": ["off", 2],
"indent": [
"off",
2
],
"no-console": 0,
"space-before-function-paren": 0
}

File diff suppressed because one or more lines are too long

View File

@ -2421,7 +2421,9 @@ a.listItemMetaTitle {
color: rgba(0, 0, 0, 0.85);
}
.main {
background-color: #fff;
//update-begin---author:liusq Date:20210108 for[JT-409]编译主题色,然后退出登录后的首页是这样子------------
//background-color: #fff;
//update-end---author:liusq Date:20210108 for[JT-409]编译主题色,然后退出登录后的首页是这样子------------
}
.main .leftmenu {
border-right: 1px solid #e8e8e8;
@ -7687,9 +7689,6 @@ font.weak {
color: @primary-color;
}
}
.ant-menu-submenu-selected {
color: @primary-color;
}
// begin -------- JAreaLinkage 三级联动样式 --------------
.cascader-menu-list .cascader-menu-option.hover,

View File

@ -5,7 +5,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Jeecg-Boot 企业级快速开发平台</title>
<title>JeecgBoot 企业级低代码平台</title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<style>
@ -251,7 +251,7 @@
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载 Jeecg-Boot 快速开发平台,请耐心等待
<div class="load_title">正在加载 JeecgBoot 低代码平台,请耐心等待
</div>
</div>

View File

@ -18,6 +18,7 @@ const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
//改变密码
const changePassword = (params)=>putAction("/sys/user/changePassword",params);
//权限管理
const addPermission= (params)=>postAction("/sys/permission/add",params);
const editPermission= (params)=>putAction("/sys/permission/edit",params);
@ -25,7 +26,6 @@ const getPermissionList = (params)=>getAction("/sys/permission/list",params);
const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params)
const queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params);
const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params);
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
@ -38,6 +38,7 @@ const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermission
// 部门管理
const queryDepartTreeList = (params)=>getAction("/sys/sysDepart/queryTreeList",params);
const queryDepartTreeSync = (params)=>getAction("/sys/sysDepart/queryDepartTreeSync",params);
const queryIdTree = (params)=>getAction("/sys/sysDepart/queryIdTree",params);
const queryParentName = (params)=>getAction("/sys/sysDepart/queryParentName",params);
const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params);
@ -68,7 +69,7 @@ export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItem
function getDictItemsFromCache(dictCode) {
if (Vue.ls.get(UI_CACHE_DB_DICT_DATA) && Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode]) {
let dictItems = Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode];
console.log("-----------getDictItemsFromCache----------dictCode="+dictCode+"---- dictItems=",dictItems)
//console.log("-----------getDictItemsFromCache----------dictCode="+dictCode+"---- dictItems=",dictItems)
return dictItems;
}
}
@ -79,8 +80,10 @@ const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",param
//获取系统访问量
const getLoginfo = (params)=>getAction("/sys/loginfo",params);
const getVisitInfo = (params)=>getAction("/sys/visitInfo",params);
// 根据部门主键查询用户信息
const queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params);
// 重复校验
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
// 加载分类字典
@ -98,6 +101,8 @@ export const transitRESTful = {
}
export {
// imgView,
// doMian,
addRole,
editRole,
checkRoleCode,
@ -121,6 +126,7 @@ export {
getPermissionRuleList,
queryPermissionRule,
queryDepartTreeList,
queryDepartTreeSync,
queryIdTree,
queryParentName,
searchByKeywords,

View File

@ -12,13 +12,13 @@ export default class Area {
let arr = []
const province = pcaa['86']
Object.keys(province).map(key=>{
arr.push({id:key, text:province[key], pid:'86'});
arr.push({id:key, text:province[key], pid:'86', index:1});
const city = pcaa[key];
Object.keys(city).map(key2=>{
arr.push({id:key2, text:city[key2], pid:key});
arr.push({id:key2, text:city[key2], pid:key, index:2});
const qu = pcaa[key2];
Object.keys(qu).map(key3=>{
arr.push({id:key3, text:qu[key3], pid:key2});
arr.push({id:key3, text:qu[key3], pid:key2, index:3});
})
})
})
@ -45,33 +45,35 @@ export default class Area {
return ''
}
let arr = []
this.getAreaBycode(code,arr);
this.getAreaBycode(code, arr, 3);
return arr.join('/')
}
getRealCode(code){
let arr = []
this.getPcode(code, arr)
this.getPcode(code, arr, 3)
return arr;
}
getPcode(id, arr){
getPcode(id, arr, index){
for(let item of this.all){
if(item.id === id){
if(item.id === id && item.index == index){
arr.unshift(id)
if(item.pid != '86'){
this.getPcode(item.pid,arr)
this.getPcode(item.pid, arr, --index)
}
}
}
}
getAreaBycode(code,arr){
//console.log("this.all.length",this.all)
getAreaBycode(code, arr, index){
for(let item of this.all){
if(item.id === code){
if(item.id === code && item.index == index){
arr.unshift(item.text);
this.getAreaBycode(item.pid,arr)
if(item.pid != '86'){
this.getAreaBycode(item.pid, arr, --index)
}
}
}
}

View File

@ -10,7 +10,7 @@
:disabled="disabled"
mode="multiple"
:placeholder="placeholder"
:getPopupContainer="(node) => node.parentNode"
:getPopupContainer="getParentContainer"
optionFilterProp="children"
:filterOption="filterOption"
allowClear>
@ -36,13 +36,23 @@
disabled: Boolean,
value: String,
type: String,
options:Array
options:Array,
spliter:{
type: String,
required: false,
default: ','
},
popContainer:{
type:String,
default:'',
required:false
},
},
data() {
return {
dictOptions: [],
tagType:"",
arrayValue:!this.value?[]:this.value.split(",")
arrayValue:!this.value?[]:this.value.split(this.spliter)
}
},
created() {
@ -68,7 +78,7 @@
if(!val){
this.arrayValue = []
}else{
this.arrayValue = this.value.split(",")
this.arrayValue = this.value.split(this.spliter)
}
}
},
@ -78,8 +88,9 @@
this.dictOptions = [...this.options]
}else{
//优先从缓存中读取字典配置
if(getDictItemsFromCache(this.dictCode)){
this.dictOptions = getDictItemsFromCache(this.dictCode);
let cacheOption = getDictItemsFromCache(this.dictCode)
if(cacheOption && cacheOption.length>0){
this.dictOptions = cacheOption
return
}
//根据字典Code, 初始化字典数组
@ -92,7 +103,7 @@
},
onChange (selectedValue) {
this.$emit('change', selectedValue.join(","));
this.$emit('change', selectedValue.join(this.spliter));
},
setCurrentDictOptions(dictOptions){
this.dictOptions = dictOptions
@ -100,6 +111,13 @@
getCurrentDictOptions(){
return this.dictOptions
},
getParentContainer(node){
if(!this.popContainer){
return node.parentNode
}else{
return document.querySelector(this.popContainer)
}
},
// update--begin--autor:lvdandan-----date:20201120------forLOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
filterOption(input, option) {
return option.componentOptions.children[0].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0

View File

@ -5,7 +5,7 @@
showSearch
labelInValue
:disabled="disabled"
:getPopupContainer="(node) => node.parentNode"
:getPopupContainer="getParentContainer"
@search="loadData"
:placeholder="placeholder"
v-model="selectedAsyncValue"
@ -21,7 +21,7 @@
<a-select
v-else
:getPopupContainer="(node) => node.parentNode"
:getPopupContainer="getParentContainer"
showSearch
:disabled="disabled"
:placeholder="placeholder"
@ -55,6 +55,16 @@
type:String,
default:"请选择",
required:false
},
popContainer:{
type:String,
default:'',
required:false
},
pageSize:{
type: Number,
default: 10,
required: false
}
},
data(){
@ -126,7 +136,7 @@
this.options = []
this.loading=true
// 字典code格式table,text,code
getAction(`/sys/dict/loadDict/${this.dict}`,{keyword:value}).then(res=>{
getAction(`/sys/dict/loadDict/${this.dict}`,{keyword:value, pageSize: this.pageSize}).then(res=>{
this.loading=false
if(res.success){
if(currentLoad!=this.lastLoad){
@ -171,6 +181,17 @@
})
}
}
}else{
//异步一开始也加载一点数据
this.loading=true
getAction(`/sys/dict/loadDict/${this.dict}`,{pageSize: this.pageSize, keyword:''}).then(res=>{
this.loading=false
if(res.success){
this.options = res.result
}else{
this.$message.warning(res.message)
}
})
}
},
filterOption(input, option) {
@ -182,9 +203,18 @@
this.callback()
},
handleAsyncChange(selectedObj){
this.selectedAsyncValue = selectedObj
this.selectedValue = selectedObj.key
//update-begin-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
if(selectedObj){
this.selectedAsyncValue = selectedObj
this.selectedValue = selectedObj.key
}else{
this.selectedAsyncValue = null
this.selectedValue = null
this.options = null
this.loadData("")
}
this.callback()
//update-end-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
},
callback(){
this.$emit('change', this.selectedValue);
@ -194,7 +224,14 @@
},
getCurrentDictOptions(){
return this.options
}
},
getParentContainer(node){
if(!this.popContainer){
return node.parentNode
}else{
return document.querySelector(this.popContainer)
}
},
},
model: {

View File

@ -1,11 +1,16 @@
import JDictSelectTag from './JDictSelectTag.vue'
import JMultiSelectTag from './JMultiSelectTag.vue'
import JSearchSelectTag from './JSearchSelectTag.vue'
import { filterMultiDictText,filterDictText,initDictOptions,filterDictTextByCache } from './JDictSelectUtil'
export default {
install: function (Vue) {
Vue.component('JDictSelectTag',JDictSelectTag);
Vue.component('JMultiSelectTag',JMultiSelectTag);
Vue.component('JSearchSelectTag',JSearchSelectTag);
Vue.prototype.$initDictOptions = (dictCode) => initDictOptions(dictCode)
Vue.prototype.$filterMultiDictText = (dictOptions, text) => filterMultiDictText(dictOptions, text)
Vue.prototype.$filterDictText = (dictOptions, text) => filterDictText(dictOptions, text)
Vue.prototype.$filterDictTextByCache = (...param) => filterDictTextByCache(...param)
}
}

View File

@ -251,6 +251,9 @@
},
style: {}
}
if(isIE() || isIE11()){
props.style['height'] = '240px'
}
if (this.fullCoder) {
props.style['z-index'] = this.zIndex
}

View File

@ -1,282 +0,0 @@
<template>
<div v-bind="fullScreenParentProps">
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
<div class="code-editor-cust full-screen-child">
<a-textarea auto-size v-model="textareaValue" :placeholder="placeholderShow" @change="handleChange" :style="{'max-height': maxHeight+'px','min-height': minHeight+'px'}"></a-textarea>
</div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: 'JCodeEditor',
props: {
value: {
type: String,
default: ''
},
placeholder: {
type: String,
default: null
},
// 是否显示全屏按钮
fullScreen: {
type: Boolean,
default: false
},
// 全屏以后的z-index
zIndex: {
type: [Number, String],
default: 999
},
// 是否自适应高度可以传String或Boolean
// 传 String 类型只能写"!ie"
// 填写这个字符串,代表其他浏览器自适应高度
// 唯独IE下不自适应高度因为IE下不支持min、max-height样式
// 如果填写的不是"!ie"就视为true
autoHeight: {
type: [String, Boolean],
default: true
},
// 不自适应高度的情况下生效的固定高度
height: {
type: [String, Number],
default: '240px'
},
language: {
type: String,
default: ''
},
minHeight:{
type:Number,
default: 100,
required:false
},
maxHeight:{
type:Number,
default: 320,
required:false
}
},
data () {
return {
textareaValue: '',
// 内部真实的内容
code: '',
iconType: 'fullscreen',
hasCode:false,
// 默认的语法类型
mode: 'javascript',
// 编辑器实例
coder: null,
// 默认配置
options: {
// 缩进格式
tabSize: 2,
// 主题,对应主题库 JS 需要提前引入
theme: 'panda-syntax',
line: true,
// extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
hintOptions: {
tables: {
users: ['name', 'score', 'birthDate'],
countries: ['name', 'population', 'size']
}
},
},
// code 编辑器 是否全屏
fullCoder: false
}
},
watch: {
fullCoder:{
handler(value) {
if(value){
this.iconType="fullscreen-exit"
}else{
this.iconType="fullscreen"
}
}
}
},
computed: {
placeholderShow() {
if (this.placeholder == null) {
return `请在此输入代码`
} else {
return this.placeholder
}
},
isAutoHeight() {
let {autoHeight} = this
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
autoHeight = !(isIE() || isIE11())
} else {
autoHeight = true
}
return autoHeight
},
fullScreenParentProps() {
let props = {
class: {
'full-screen-parent': true,
'full-screen': this.fullCoder,
'auto-height': this.isAutoHeight
},
style: {}
}
if (this.fullCoder) {
props.style['z-index'] = this.zIndex
}
if (!this.isAutoHeight) {
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
}
return props
}
},
mounted () {
// 初始化
this._initialize()
},
methods: {
// 初始化
_initialize () {
this.setCodeContent(this.value)
},
handleChange(e){
this.$emit('input', e.target.value)
},
getCodeContent(){
return this.value
},
setCodeContent(val){
setTimeout(()=>{
if(!val){
this.textareaValue = ''
}else{
this.textareaValue = val
}
},300)
},
nullTipClick(){
this.coder.focus()
}
}
}
</script>
<style lang="less">
.code-editor-cust{
flex-grow:1;
display:flex;
position:relative;
height:100%;
.CodeMirror{
flex-grow:1;
z-index:1;
.CodeMirror-code{
line-height:19px;
}
}
.code-mode-select{
position:absolute;
z-index:2;
right:10px;
top:10px;
max-width:130px;
}
.CodeMirror{
height: auto;
min-height:100%;
}
.null-tip{
position: absolute;
top: 4px;
left: 36px;
z-index: 10;
color: #ffffffc9;
line-height: initial;
}
.null-tip-hidden{
display: none;
}
}
/* 全屏样式 */
.full-screen-parent {
position: relative;
.full-screen-icon {
opacity: 0;
color: black;
width: 20px;
height: 20px;
line-height: 24px;
background-color: white;
position: absolute;
top: 2px;
right: 2px;
z-index: 9;
cursor: pointer;
transition: opacity 0.3s;
}
&:hover {
.full-screen-icon {
opacity: 1;
&:hover {
background-color: rgba(255, 255, 255, 0.88);
}
}
}
&.full-screen {
position: fixed;
top: 10px;
left: 10px;
width: calc(100% - 20px);
height: calc(100% - 20px);
padding: 10px;
background-color: #f5f5f5;
.full-screen-icon {
top: 12px;
right: 12px;
}
.full-screen-child {
height: 100%;
max-height: 100%;
min-height: 100%;
}
}
.full-screen-child {
height: 100%;
}
&.auto-height {
.full-screen-child {
min-height: 120px;
max-height: 320px;
height: unset;
overflow: hidden;
}
&.full-screen .full-screen-child {
height: 100%;
max-height: 100%;
min-height: 100%;
}
}
}
.CodeMirror-cursor{
height:18.4px !important;
}
</style>

View File

@ -11,13 +11,13 @@
<a-col>
<!-- 操作按钮 -->
<div v-if="actionButton" class="action-button">
<a-button type="primary" icon="plus" @click="handleClickAdd" :disabled="disabled">新增</a-button>
<a-button v-if="buttonPermission('add')" type="primary" icon="plus" @click="handleClickAdd" :disabled="disabled">新增</a-button>
<span class="gap"></span>
<template v-if="selectedRowIds.length>0">
<a-popconfirm
:title="`确定要删除这 ${selectedRowIds.length} 项吗?`"
@confirm="handleConfirmDelete">
<a-button type="primary" icon="minus" :disabled="disabled">删除</a-button>
<a-button v-if="buttonPermission('batch_delete')" type="primary" icon="minus" :disabled="disabled">删除</a-button>
<span class="gap"></span>
</a-popconfirm>
<template v-if="showClearSelectButton">
@ -59,7 +59,7 @@
v-show="col.type !== formTypes.hidden"
class="td"
:key="col.key"
:style="buildTdStyle(col,true)">
:style="buildTdStyle(col)">
<span>{{ col.title }}</span>
</div>
@ -188,6 +188,7 @@
:getPopupContainer="getParentContainer"
:placeholder="replaceProps(col, col.placeholder)"
:filterOption="(i,o)=>handleSelectFilterOption(i,o,col)"
:maxTagCount="1"
@change="(v)=>handleChangeSelectCommon(v,id,row,col)"
@search="(v)=>handleSearchSelect(v,id,row,col)"
@blur="(v)=>handleBlurSearch(v,id,row,col)"
@ -201,6 +202,55 @@
>{{ getSelectTranslateText(selectValues[id], row, col) }}</span>
</a-tooltip>
</template>
<!-- 部门选择 -->
<template v-else-if="col.type === formTypes.sel_depart">
<a-tooltip v-bind="buildTooltipProps(row, col, id)">
<j-select-depart
v-if="isEditRow(row, col)"
:id="id"
:key="i"
v-bind="buildProps(row,col)"
style="width: 100%;"
:value="departCompValues[id]"
:placeholder="replaceProps(col, col.placeholder)"
:trigger-change="true"
:multi="true"
@change="(v)=>handleChangeDepartCommon(v,id,row,col)"
/>
<span
v-else
class="j-td-span no-edit"
:class="{disabled: buildProps(row,col).disabled}"
@click="handleEditRow(row, col)"
>{{ departCompValues[id] }}</span>
</a-tooltip>
</template>
<!-- 用户选择 -->
<template v-else-if="col.type === formTypes.sel_user">
<a-tooltip v-bind="buildTooltipProps(row, col, id)">
<j-select-user-by-dep
v-if="isEditRow(row, col)"
:id="id"
:key="i"
v-bind="buildProps(row,col)"
style="width: 100%;"
:value="userCompValues[id]"
:placeholder="replaceProps(col, col.placeholder)"
:trigger-change="true"
:multi="true"
@change="(v)=>handleChangeUserCommon(v,id,row,col)"
/>
<span
v-else
class="j-td-span no-edit"
:class="{disabled: buildProps(row,col).disabled}"
@click="handleEditRow(row, col)"
>{{ userCompValues[id] }}</span>
</a-tooltip>
</template>
<!-- date -->
<template v-else-if="col.type === formTypes.date || col.type === formTypes.datetime">
<a-tooltip v-bind="buildTooltipProps(row, col, id)">
@ -628,6 +678,7 @@
import { getFileAccessHttpUrl } from '@/api/manage';
import JInputPop from '@/components/jeecg/minipop/JInputPop'
import JFilePop from '@/components/jeecg/minipop/JFilePop'
import { getNoAuthCols } from "@/utils/authFilter"
// 行高,需要在实例加载完成前用到
let rowHeight = 61
@ -704,6 +755,11 @@
type: Boolean,
default: true
},
authPre: {
type: String,
required: false,
default: ''
},
},
data() {
return {
@ -749,6 +805,10 @@
uploadValues: {},
//popup信息
popupValues: {},
//部门组件信息
departCompValues:{},
//用户组件信息
userCompValues: {},
radioValues: {},
metaCheckboxValues: {},
@ -775,6 +835,8 @@
// 上次push数据的事件用于判断是否点击过快
lastPushTimeMap: new Map(),
number:0,
//不显示的按钮编码
excludeCode:[]
}
},
created() {
@ -883,6 +945,8 @@
columns: {
immediate: true,
handler(columns) {
//列改变的时候重新设置按钮权限信息
this.loadExcludeCode()
// 兼容IE
this.getElementPromise('tbody').then(() => {
columns.forEach(column => {
@ -964,41 +1028,46 @@
this.visibleTrEls = []
// 判断是否是首次进入该方法,如果是就不清空行,防止删除了预添加的数据
if (!this.isFirst) {
// inputValues用来存储input表单的值
// 数组里的每项都是一个对象对象里每个key都是input的rowKey值就是input的值其中有个id的字段来区分
// 示例:
// [{
// id: "_jet-4sp0iu-15541771111770"
// dbDefaultVal: "aaa",
// dbFieldName: "bbb",
// dbFieldTxt: "ccc",
// dbLength: 32
// }]
this.inputValues = []
this.rows = []
this.deleteIds = []
this.selectValues = {}
this.checkboxValues = {}
this.jdateValues = {}
this.jInputPopValues = {}
this.slotValues = {}
this.selectedRowIds = []
this.tooltips = {}
this.notPassedIds = []
this.uploadValues = []
this.popupValues = []
this.radioValues = []
this.multiSelectValues = []
this.searchSelectValues = []
this.scrollTop = 0
this.$nextTick(() => {
this.getElement('tbody').scrollTop = 0
})
this.clearRow();
} else {
this.isFirst = false
}
},
/**清空行*/
clearRow(){
// inputValues用来存储input表单的值
// 数组里的每项都是一个对象对象里每个key都是input的rowKey值就是input的值其中有个id的字段来区分
// 示例:
// [{
// id: "_jet-4sp0iu-15541771111770"
// dbDefaultVal: "aaa",
// dbFieldName: "bbb",
// dbFieldTxt: "ccc",
// dbLength: 32
// }]
this.inputValues = []
this.rows = []
this.deleteIds = []
this.selectValues = {}
this.checkboxValues = {}
this.jdateValues = {}
this.jInputPopValues = {}
this.departCompValues = {}
this.userCompValues = {}
this.slotValues = {}
this.selectedRowIds = []
this.tooltips = {}
this.notPassedIds = []
this.uploadValues = []
this.popupValues = []
this.radioValues = []
this.multiSelectValues = []
this.searchSelectValues = []
this.scrollTop = 0
this.$nextTick(() => {
this.getElement('tbody').scrollTop = 0
})
},
/** 同步滚动条状态 */
syncScrollBar(scrollLeft) {
// this.style.tbody.left = `${scrollLeft}px`
@ -1058,6 +1127,8 @@
let checkboxValues = { ...this.checkboxValues }
let selectValues = { ...this.selectValues }
let jdateValues = { ...this.jdateValues }
let departCompValues = { ...this.departCompValues }
let userCompValues = { ...this.userCompValues }
let jInputPopValues = { ...this.jInputPopValues }
let slotValues = { ...this.slotValues }
let uploadValues = { ...this.uploadValues }
@ -1144,6 +1215,10 @@
} else if (column.type === FormTypes.popup) {
popupValues[inputId] = sourceValue
} else if (column.type === FormTypes.sel_depart) {
departCompValues[inputId] = sourceValue
} else if (column.type === FormTypes.sel_user) {
userCompValues[inputId] = sourceValue
} else if (column.type === FormTypes.input_pop) {
jInputPopValues[inputId] = sourceValue
} else if (column.type === FormTypes.radio) {
@ -1225,6 +1300,8 @@
this.checkboxValues = checkboxValues
this.selectValues = selectValues
this.jdateValues = jdateValues
this.departCompValues = departCompValues
this.userCompValues = userCompValues
this.jInputPopValues = jInputPopValues
this.slotValues = slotValues
this.uploadValues = uploadValues
@ -1440,6 +1517,12 @@
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
value[column.key] = this.jdateValues[inputId]
} else if (column.type === FormTypes.sel_depart) {
value[column.key] = this.departCompValues[inputId]
} else if (column.type === FormTypes.sel_user) {
value[column.key] = this.userCompValues[inputId]
} else if (column.type === FormTypes.input_pop) {
value[column.key] = this.jInputPopValues[inputId]
@ -1579,6 +1662,8 @@
selectValues: this.selectValues,
checkboxValues: this.checkboxValues,
jdateValues: this.jdateValues,
departCompValues: this.departCompValues,
userCompValues: this.userCompValues,
jInputPopValues: this.jInputPopValues,
slotValues: this.slotValues,
uploadValues: this.uploadValues,
@ -1633,6 +1718,10 @@
edited = true
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
edited = this.setOneValue(this.jdateValues, modelKey, newValue)
} else if (column.type === FormTypes.sel_depart) {
edited = this.setOneValue(this.departCompValues, modelKey, newValue)
} else if (column.type === FormTypes.sel_user) {
edited = this.setOneValue(this.userCompValues, modelKey, newValue)
} else if (column.type === FormTypes.input_pop) {
edited = this.setOneValue(this.jInputPopValues, modelKey, newValue)
} else if (column.type === FormTypes.slot) {
@ -1809,7 +1898,7 @@
// 兼容 online 的规则
let foo = [
{ title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,18}$/ },
{ title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,16}$/ },
{ title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/ },
{ title: '6到18位字母', value: 's6-18', pattern: /^[a-z|A-Z]{6,18}$/ },
{ title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/ },
@ -2183,6 +2272,20 @@
this.elemValueChange(FormTypes.date, row, column, value)
}
},
//部门组件值改变
handleChangeDepartCommon(value, id, row, column){
this.departCompValues = this.bindValuesChange(value, id, 'departCompValues')
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange(FormTypes.sel_depart, row, column, value)
},
//用户组件值改变
handleChangeUserCommon(value, id, row, column){
this.userCompValues = this.bindValuesChange(value, id, 'userCompValues')
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange(FormTypes.sel_user, row, column, value)
},
handleChangeJInputPopCommon(value, id, row, column){
this.jInputPopValues = this.bindValuesChange(value, id, 'jInputPopValues')
// 做单个表单验证
@ -2462,7 +2565,7 @@
}
},
/** view辅助方法构建 td style */
buildTdStyle(col,isTitle) {
buildTdStyle(col) {
const isEmptyWidth = (column) => (column.type === FormTypes.hidden || column.width === '0px' || column.width === '0' || column.width === 0)
let style = {}
@ -2475,13 +2578,15 @@
style['width'] = '120px'
}
//update-begin-author:lvdandan date:20201116 for:LOWCOD-984 默认风格功能测试附表样式问题 日期时间控件长度太大
//是否为标题,如果是时间控件设为200时间控件的标题设为240 时间
//如果是时间控件设为200px
if(col.type === FormTypes.datetime){
if(true === isTitle){
style['width'] = '240px'
}else{
style['width'] = '200px'
}
style['width'] = '200px'
}
if(col.type === FormTypes.sel_user && !col.width){
style['width'] = '220px'
}
if(col.type === FormTypes.sel_depart && !col.width){
style['width'] = '160px'
}
//update-end-author:lvdandan date:20201116 for:LOWCOD-984 默认风格功能测试附表样式问题 日期时间控件长度太大
@ -2599,7 +2704,7 @@
}
this.setOneValue(this.popupValues, id, popupValue)
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
this.validateOneInput(popupValue, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange('input', row, column, value)
},
@ -2718,15 +2823,35 @@
removeEventListener() {
window.removeEventListener('mouseup', this.handleMouseup)
},
/* --------------------------- 2020年5月18日 默认span模式 ------------------------------ */
//获取没有授权的按钮编码
loadExcludeCode(){
if(!this.authPre || this.authPre.length==0){
this.excludeCode = []
}else{
let pre = this.authPre
if(!pre.endsWith(':')){
pre += ':'
}
this.excludeCode = getNoAuthCols(pre)
}
},
//判断button是否显示
buttonPermission(code){
if(!this.excludeCode || this.excludeCode.length==0){
return true
}else{
return this.excludeCode.indexOf(code)<0
}
}
},
beforeDestroy() {
this.removeEventListener()
this.destroyCleanGroupRequest = true
},
}
}
</script>

View File

@ -128,6 +128,9 @@
this.reload()
}
})
//update--begin--autor:liusq-----date:20210316------for富文本编辑器tab父组件可能导致的赋值问题------
this.reload()
//update--end--autor:liusq-----date:20210316------for富文本编辑器tab父组件可能导致的赋值问题------
}else{
//update--begin--autor:wangshuai-----date:20200724------for富文本编辑器切换tab无法修改------
let tabLayout = getVmParentByName(this, 'TabLayout')

View File

@ -11,13 +11,13 @@
:beforeUpload="beforeUpload"
:disabled="disabled"
:isMultiple="isMultiple"
:showUploadList="isMultiple"
@change="handleChange"
@preview="handlePreview"
:class="!isMultiple?'imgupload':''">
<div :style="{'width':(!isMultiple?'104px':'auto'),'height':(!isMultiple?'104px':'auto')}">
<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="width:100%;height:100%"/>
<div v-else class="iconp">
:class="[!isMultiple?'imgupload':'', (!isMultiple && picUrl)?'image-upload-single-over':'' ]">
<div>
<!--<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="width:100%;height:100%"/>-->
<div class="iconp">
<a-icon :type="uploadLoading ? 'loading' : 'plus'" />
<div class="ant-upload-text">{{ text }}</div>
</div>
@ -189,7 +189,7 @@
path = ''
}
let arr = [];
if(!this.isMultiple){
if(!this.isMultiple && uploadFiles.length>0){
arr.push(uploadFiles[uploadFiles.length-1].response.message)
}else{
for(let a=0;a<uploadFiles.length;a++){
@ -231,8 +231,9 @@
* https://github.com/zhangdaiscott/jeecg-boot/issues/1810
* https://github.com/zhangdaiscott/jeecg-boot/issues/1779
*/
/deep/ .imgupload .ant-upload-select{display:block}
/deep/ .imgupload .ant-upload.ant-upload-select-picture-card{ width:120px;height: 120px;}
/deep/ .imgupload .iconp{padding:32px;}
/deep/ .imgupload .iconp{padding:20px;}
/* update--end--autor:lvdandan-----date:20201016------forj-image-upload图片组件单张图片详情回显空白*/
/deep/ .image-upload-single-over .ant-upload-select{display: none}
</style>

View File

@ -8,10 +8,11 @@
v-on="$listeners"
@ok="handleOk"
@cancel="handleCancel"
destroyOnClose
>
<slot></slot>
<!--有设置标题-->
<template v-if="!isNoTitle" slot="title">
<a-row class="j-modal-title-row" type="flex">
<a-col class="left">
@ -22,6 +23,14 @@
</a-col>
</a-row>
</template>
<!--没有设置标题-->
<template v-else slot="title">
<a-row class="j-modal-title-row" type="flex">
<a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
<a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/>
</a-col>
</a-row>
</template>
<!-- 处理 scopedSlots -->
<template v-for="slotName of scopedSlotsKeys" :slot="slotName">
@ -161,7 +170,6 @@
<style lang="less">
.j-modal-box {
&.fullscreen {
top: 0;
left: 0;
@ -190,7 +198,6 @@
height: calc(100% - 55px);
}
}
&.no-title.no-footer {
.ant-modal-body {
height: 100%;
@ -217,6 +224,12 @@
}
}
}
&.no-title{
.ant-modal-header {
padding: 0px 24px;
border-bottom: 0px !important;
}
}
}
@media (max-width: 767px) {

View File

@ -82,6 +82,11 @@
required: false,
default: ()=>{}
},
spliter:{
type: String,
required: false,
default: ','
},
/** 分组ID用于将多个popup的请求合并到一起不传不分组 */
groupId: String
@ -108,7 +113,7 @@
if (!val) {
this.showText = ''
} else {
this.showText = val
this.showText = val.split(this.spliter).join(',')
}
}
}
@ -188,7 +193,11 @@
} else {
//v-model时 需要传一个参数field 表示当前这个字段 从而根据这个字段的顺序找到原始值
// this.$emit("input",row[orgFieldsArr[destFieldsArr.indexOf(this.field)]])
this.$emit('input', this.showText, res)
let str = ''
if(this.showText){
str = this.showText.split(',').join(this.spliter)
}
this.$emit('input', str, res)
}
}
}

View File

@ -3,6 +3,7 @@
<a-select-option
v-for="(item,index) in options"
:key="index"
:getPopupContainer="getParentContainer"
:value="item.value">
{{ item.text || item.label }}
</a-select-option>
@ -36,11 +37,21 @@
type: Boolean,
required: false,
default: false
}
},
spliter:{
type: String,
required: false,
default: ','
},
popContainer:{
type:String,
default:'',
required:false
},
},
data(){
return {
arrayValue:!this.value?[]:this.value.split(",")
arrayValue:!this.value?[]:this.value.split(this.spliter)
}
},
watch:{
@ -48,18 +59,25 @@
if(!val){
this.arrayValue = []
}else{
this.arrayValue = this.value.split(",")
this.arrayValue = this.value.split(this.spliter)
}
}
},
methods:{
onChange (selectedValue) {
if(this.triggerChange){
this.$emit('change', selectedValue.join(","));
this.$emit('change', selectedValue.join(this.spliter));
}else{
this.$emit('input', selectedValue.join(","));
this.$emit('input', selectedValue.join(this.spliter));
}
},
getParentContainer(node){
if(!this.popContainer){
return node.parentNode
}else{
return document.querySelector(this.popContainer)
}
}
},
}

View File

@ -101,7 +101,15 @@
</a-col>
<a-col :md="8" :xs="24" style="margin-bottom: 12px;">
<template v-if="item.dictCode">
<!-- 下拉搜索 -->
<j-search-select-tag v-if="item.type==='sel_search'" v-model="item.val" :dict="getDictInfo(item)" placeholder="请选择"/>
<!-- 下拉多选 -->
<template v-else-if="item.type==='list_multi'">
<j-multi-select-tag v-if="item.options" v-model="item.val" :options="item.options" placeholder="请选择"/>
<j-multi-select-tag v-else v-model="item.val" :dictCode="getDictInfo(item)" placeholder="请选择"/>
</template>
<template v-else-if="item.dictCode">
<template v-if="item.type === 'table-dict'">
<j-popup
v-model="item.val"
@ -109,6 +117,7 @@
:field="item.dictCode"
:orgFields="item.dictCode"
:destFields="item.dictCode"
:multi="true"
></j-popup>
</template>
<template v-else>
@ -116,7 +125,13 @@
<j-dict-select-tag v-show="!allowMultiple(item)" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
</template>
</template>
<j-popup v-else-if="item.type === 'popup'" :value="item.val" v-bind="item.popup" group-id="superQuery" @input="(e,v)=>handleChangeJPopup(item,e,v)"/>
<j-popup
v-else-if="item.type === 'popup'"
:value="item.val"
v-bind="item.popup"
group-id="superQuery"
@input="(e,v)=>handleChangeJPopup(item,e,v)"
:multi="true"/>
<j-select-multi-user
v-else-if="item.type === 'select-user' || item.type === 'sel_user'"
v-model="item.val"
@ -338,6 +353,17 @@
}
this.visible = true
},
getDictInfo(item) {
let str = ''
if(!item.dictTable){
str = item.dictCode
}else{
str = item.dictTable+','+item.dictText+','+item.dictCode
}
console.log('高级查询字典信息',str)
return str
},
handleOk() {
if (!this.isNullArray(this.queryParamsModel)) {
let event = {
@ -386,11 +412,12 @@
this.queryParamsModel.splice(index, 1)
},
handleSelected(node, item) {
let { type, options, dictCode, dictTable, customReturnField, popup } = node.dataRef
let { type, options, dictCode, dictTable, dictText, customReturnField, popup } = node.dataRef
item['type'] = type
item['options'] = options
item['dictCode'] = dictCode
item['dictTable'] = dictTable
item['dictText'] = dictText
item['customReturnField'] = customReturnField
if (popup) {
item['popup'] = popup

View File

@ -374,14 +374,17 @@
},
mounted(){
const moverObj = document.getElementById(this.containerId+'-mover');
moverObj.addEventListener('mouseover',()=>{
this.moverHold = true
this.moveDisplay = 'block';
});
moverObj.addEventListener('mouseout',()=>{
this.moverHold = false
this.moveDisplay = 'none';
});
if(moverObj){
moverObj.addEventListener('mouseover',()=>{
this.moverHold = true
this.moveDisplay = 'block';
});
moverObj.addEventListener('mouseout',()=>{
this.moverHold = false
this.moveDisplay = 'none';
});
}
let picList = document.getElementById(this.containerId)?document.getElementById(this.containerId).getElementsByClassName('ant-upload-list-picture-card'):[];
if(picList && picList.length>0){
picList[0].addEventListener('mouseover',(ev)=>{

View File

@ -1,5 +1,5 @@
<template>
<a-popover :visible="visible" placement="bottom" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle">
<a-popover :visible="visible" :placement="placement" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle">
<div class="j-vxe-popover-title" slot="title">
<div>子表</div>
<div class="j-vxe-popover-title-close" @click="close">
@ -34,6 +34,7 @@
width: null,
zIndex: 100
},
placement: 'bottom'
}
},
created() {
@ -41,6 +42,14 @@
methods: {
toggle(event) {
//update-begin-author:taoyan date:20200921 for: 弹出子表时,子表会闪一下,类似重新计算子表的位置
if(document.body.clientHeight - event.$event.clientY > 350){
this.placement = 'bottom'
}else{
this.placement = 'top'
}
//update-end-author:taoyan date:20200921 for: 弹出子表时,子表会闪一下,类似重新计算子表的位置
if (this.row == null) {
this.open(event)
} else {
@ -83,13 +92,22 @@
this.$refs.div.style.height = clientHeight + 'px'
this.overlayStyle.width = Number.parseInt((clientWidth - clientWidth * 0.04)) + 'px'
this.overlayStyle.maxWidth = this.overlayStyle.width
domAlign(this.$refs.div, tr, {
//update-begin-author:taoyan date:20200921 for: 子表弹出位置存在现实位置问题。
//let realTable = getParentNodeByTagName(tr, 'table')
//let left = realTable.parentNode.scrollLeft
let h = event.$event.clientY
if(h){
h = h-140
}
let toolbar = this.$refs.div.nextSibling
domAlign(this.$refs.div, toolbar, {
points: ['tl', 'tl'],
offset: [0, 0],
offset: [0, h],
overflow: {
alwaysByViewport: true
},
})
//update-end-author:taoyan date:20200921 for: 子表弹出位置存在现实位置问题。
this.$nextTick(() => {
this.visible = true
this.$nextTick(() => {

View File

@ -1,6 +1,6 @@
import XEUtils from 'xe-utils'
import PropTypes from 'ant-design-vue/es/_util/vue-types'
import { JVXETypes } from '@/components/jeecg/JVxeTable/index'
import { JVXETypes } from '@/components/jeecg/JVxeTable/jvxeTypes'
import VxeWebSocketMixins from '../mixins/vxe.web.socket.mixins'
import { initDictOptions } from '@/components/dict/JDictSelectUtil'
@ -188,6 +188,21 @@ export default {
}
}
// update--begin--autor:lvdandan-----date:20201019------for:LOWCOD-882 【新行编辑】列表上带按钮的遮挡问题
// update--begin--autor:lvdandan-----date:20201211------for:JT-118 【online】 日期、时间控件长度较小
if (column.$type === JVXETypes.datetime || column.$type === JVXETypes.userSelect || column.$type === JVXETypes.departSelect) {
let width = column.width && column.width.endsWith('px')?Number.parseInt(column.width.substr(0,column.width.length-2)):0;
if(width <= 190){
column.width = '190px'
}
}
if (column.$type === JVXETypes.date) {
let width = column.width && column.width.endsWith('px')?Number.parseInt(column.width.substr(0,column.width.length-2)):0;
if(width <= 135){
column.width = '135px'
}
}
// update--end--autor:lvdandan-----date:20201211------for:JT-118 【online】 日期、时间控件长度较小
})
return this._innerColumns
},
@ -709,6 +724,11 @@ export default {
deleteData: this.getDeleteData()
}
},
/** 获取表格表单里的值 */
getValues(callback, rowIds) {
let tableData = this.getTableData({rowIds: rowIds})
callback('', tableData)
},
/** 获取表格数据 */
getTableData(options = {}) {
let {rowIds} = options
@ -887,7 +907,11 @@ export default {
}
})
},
//options自定义赋值 刷新
virtualRefresh(){
this.scrolling = true
this.closeScrolling()
},
// 设置 this.scrolling 防抖模式
closeScrolling: simpleDebounce(function () {
this.scrolling = false
@ -1203,7 +1227,7 @@ export default {
// 兼容 online 的规则
const fooPatterns = [
{title: '非空', value: '*', pattern: /^.+$/},
{title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,18}$/},
{title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,16}$/},
{title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/},
{title: '6到18位字母', value: 's6-18', pattern: /^[a-z|A-Z]{6,18}$/},
{title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/},

View File

@ -59,7 +59,7 @@
// TODO 需要将remove替换batch_delete
// 系统默认的批量删除编码配置为 batch_delete 此处需要转化一下
if(exclude.indexOf('batch_delete')>=0){
exclude.add('remove')
exclude.push('remove')
}
// 按钮权限 需要去掉不被授权的按钮
return arr.filter(item=>{

View File

@ -0,0 +1,138 @@
<template>
<div>
<a-input
v-show="!departIds"
@click="openSelect"
placeholder="请点击选择部门"
v-model="departNames"
readOnly
:disabled="componentDisabled"
class="jvxe-select-input">
<a-icon slot="prefix" type="cluster" title="部门选择控件"/>
</a-input>
<j-select-depart-modal
ref="innerDepartSelectModal"
:modal-width="modalWidth"
:multi="multi"
:rootOpened="rootOpened"
:depart-id="departIds"
@ok="handleOK"
@initComp="initComp"/>
<span style="display: inline-block;height:100%;padding-left:14px" v-if="departIds" >
<span @click="openSelect" style="display: inline-block;vertical-align: middle">{{ departNames }}</span>
<a-icon style="margin-left:5px;vertical-align: middle" type="close-circle" @click="handleEmpty" title="清空"/>
</span>
</div>
</template>
<script>
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
import JSelectDepartModal from '@/components/jeecgbiz/modal/JSelectDepartModal'
export default {
name: 'JVxeDepartSelectCell',
mixins: [JVxeCellMixins],
components:{
JSelectDepartModal
},
data() {
return {
departNames: '',
departIds: '',
selectedOptions: [],
customReturnField: 'id'
}
},
computed: {
custProps() {
const {departIds, originColumn: col, caseId, cellProps} = this
return {
...cellProps,
value: departIds,
field: col.field || col.key,
groupId: caseId,
class: 'jvxe-select'
}
},
componentDisabled(){
if(this.cellProps.disabled==true){
return true
}
return false
},
modalWidth(){
if(this.cellProps.modalWidth){
return this.cellProps.modalWidth
}else{
return 500
}
},
multi(){
if(this.cellProps.multi==false){
return false
}else{
return true
}
},
rootOpened(){
if(this.cellProps.open==false){
return false
}else{
return true
}
}
},
watch: {
innerValue: {
immediate: true,
handler(val) {
if (val == null || val === '') {
this.departIds = ''
} else {
this.departIds = val
}
}
}
},
methods: {
openSelect(){
this.$refs.innerDepartSelectModal.show()
},
handleEmpty(){
this.handleOK('')
},
handleOK(rows, idstr) {
let value = ''
if (!rows && rows.length <= 0) {
this.departNames = ''
this.departIds = ''
} else {
value = rows.map(row => row[this.customReturnField]).join(',')
this.departNames = rows.map(row => row['departName']).join(',')
this.departIds = idstr
}
this.handleChangeCommon(this.departIds)
},
initComp(departNames){
this.departNames = departNames
},
handleChange(value) {
this.handleChangeCommon(value)
}
},
enhanced: {
switches: {
visible: true
},
translate: {
enabled: false
}
}
}
</script>
<style scoped>
/deep/ .jvxe-select-input .ant-input{
border: none !important;
}
</style>

View File

@ -0,0 +1,136 @@
<template>
<div>
<a-input
v-show="!userIds"
@click="openSelect"
placeholder="请选择用户"
v-model="userNames"
readOnly
class="jvxe-select-input"
:disabled="componentDisabled">
<a-icon slot="prefix" type="user" title="用户选择控件"/>
</a-input>
<j-select-user-by-dep-modal
ref="selectModal"
:modal-width="modalWidth"
:multi="multi"
:user-ids="userIds"
@ok="selectOK"
@initComp="initComp"/>
<span style="display: inline-block;height:100%;padding-left:14px" v-if="userIds" >
<span @click="openSelect" style="display: inline-block;vertical-align: middle">{{ userNames }}</span>
<a-icon style="margin-left:5px;vertical-align: middle" type="close-circle" @click="handleEmpty" title="清空"/>
</span>
</div>
<!-- <j-select-user-by-dep
v-bind="custProps"
@change="handleChange"
:trigger-change="true">
</j-select-user-by-dep>-->
</template>
<script>
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
import JSelectUserByDepModal from '@/components/jeecgbiz/modal/JSelectUserByDepModal'
export default {
name: 'JVxeUserSelectCell',
mixins: [JVxeCellMixins],
components: { JSelectUserByDepModal },
data() {
return {
userIds:'',
userNames:'',
innerUserValue: '',
selectedOptions: []
}
},
computed: {
custProps() {
const {userIds, originColumn: col, caseId, cellProps} = this
return {
...cellProps,
value: userIds,
field: col.field || col.key,
groupId: caseId,
class: 'jvxe-select'
}
},
componentDisabled(){
console.log('333',this.cellProps)
if(this.cellProps.disabled==true){
return true
}
return false
},
modalWidth(){
if(this.cellProps.modalWidth){
return this.cellProps.modalWidth
}else{
return 1250
}
},
multi(){
if(this.cellProps.multi==false){
return false
}else{
return true
}
}
},
watch: {
innerValue: {
immediate: true,
handler(val) {
if (val == null || val === '') {
this.userIds = ''
} else {
this.userIds = val
}
}
}
},
methods: {
openSelect() {
this.$refs.selectModal.showModal()
},
selectOK(rows, idstr) {
console.log("当前选中用户", rows)
console.log("当前选中用户ID", idstr)
if (!rows) {
this.userNames = ''
this.userIds = ''
} else {
let temp = ''
for (let item of rows) {
temp += ',' + item.realname
}
this.userNames = temp.substring(1)
this.userIds = idstr
}
this.handleChangeCommon(this.userIds)
},
handleEmpty(){
this.selectOK('')
},
initComp(userNames) {
this.userNames = userNames
},
},
enhanced: {
switches: {
visible: true
},
translate: {
enabled: false
}
}
}
</script>
<style scoped>
/deep/ .jvxe-select-input .ant-input {
border: none !important;
}
</style>

View File

@ -1,3 +1,4 @@
import * as jvxeTypes from './jvxeTypes'
import { installCell, mapCell } from './install'
import JVxeTable from './components/JVxeTable'
@ -12,46 +13,13 @@ import { TagsInputCell, TagsSpanCell } from './components/cells/JVxeTagsCell'
import JVxeProgressCell from './components/cells/JVxeProgressCell'
import JVxeTextareaCell from './components/cells/JVxeTextareaCell'
import JVxeDragSortCell from './components/cells/JVxeDragSortCell'
import JVxeDepartSelectCell from './components/cells/JVxeDepartSelectCell'
import JVxeUserSelectCell from './components/cells/JVxeUserSelectCell'
//update--begin--autor:lvdandan-----date:20201216------forJVxeTable--JVXETypes 【online】代码结构调整便于online打包
// 组件类型
export const JVXETypes = {
// 为了防止和 vxe 内置的类型冲突,所以加上一个前缀
// 前缀是自动加的代码中直接用就行JVXETypes.input
_prefix: 'j-',
// 行号列
rowNumber: 'row-number',
// 选择列
rowCheckbox: 'row-checkbox',
// 单选列
rowRadio: 'row-radio',
// 展开列
rowExpand: 'row-expand',
// 上下排序
rowDragSort: 'row-drag-sort',
input: 'input',
inputNumber: 'inputNumber',
textarea: 'textarea',
select: 'select',
date: 'date',
datetime: 'datetime',
checkbox: 'checkbox',
upload: 'upload',
// 下拉搜索
selectSearch: 'select-search',
// 下拉多选
selectMultiple: 'select-multiple',
// 进度条
progress: 'progress',
// 拖轮Tags暂无用
tags: 'tags',
slot: 'slot',
normal: 'normal',
hidden: 'hidden',
}
export const JVXETypes = jvxeTypes.JVXETypes
//update--end--autor:lvdandan-----date:20201216------forJVxeTable--JVXETypes 【online】代码结构调整便于online打包
// 注册自定义组件
export const AllCells = {
@ -72,6 +40,8 @@ export const AllCells = {
...mapCell(JVXETypes.rowDragSort, JVxeDragSortCell),
...mapCell(JVXETypes.slot, JVxeSlotCell),
...mapCell(JVXETypes.departSelect, JVxeDepartSelectCell),
...mapCell(JVXETypes.userSelect, JVxeUserSelectCell)
/* hidden 是特殊的组件,不在这里注册 */
}

View File

@ -62,8 +62,8 @@ VXETable.interceptor.add('event.clearActived', function (params, event, target)
if (className.includes('j-input-pop')) {
return false
}
// 点击的标签是JPopup的弹出层
if (className.includes('j-popup-modal')) {
// 点击的标签是JPopup的弹出层、部门选择、用户选择
if (className.includes('j-popup-modal') || className.includes('j-depart-select-modal') || className.includes('j-user-select-modal')) {
return false
}
// 执行增强

View File

@ -0,0 +1,44 @@
// 组件类型
export default JVXETypes
export const JVXETypes = {
// 为了防止和 vxe 内置的类型冲突,所以加上一个前缀
// 前缀是自动加的代码中直接用就行JVXETypes.input
_prefix: 'j-',
// 行号列
rowNumber: 'row-number',
// 选择列
rowCheckbox: 'row-checkbox',
// 单选列
rowRadio: 'row-radio',
// 展开列
rowExpand: 'row-expand',
// 上下排序
rowDragSort: 'row-drag-sort',
input: 'input',
inputNumber: 'inputNumber',
textarea: 'textarea',
select: 'select',
date: 'date',
datetime: 'datetime',
checkbox: 'checkbox',
upload: 'upload',
// 下拉搜索
selectSearch: 'select-search',
// 下拉多选
selectMultiple: 'select-multiple',
// 进度条
progress: 'progress',
//部门选择
departSelect: 'sel_depart',
//用户选择
userSelect: 'sel_user',
// 拖轮Tags暂无用
tags: 'tags',
slot: 'slot',
normal: 'normal',
hidden: 'hidden',
}

View File

@ -298,7 +298,11 @@ export function dispatchEvent({cell, $event}, className, handler) {
handler(element[0])
} else {
// 模拟触发点击事件
element[0].dispatchEvent($event)
console.log($event)
if($event){
console.log("$event===>",$event)
element[0].dispatchEvent($event)
}
}
}
}, 10)

View File

@ -141,6 +141,33 @@ export async function validateFormAndTables(form, cases, autoJumpTab) {
return dataMap
}
/**
* 一次性验证主表单和所有的次表单
* @param form 主表单 form 对象
* @param cases 接收一个数组每项都是一个JVxeTable实例
* @param autoJumpTab
* @returns {Promise<any>}
* @author sunjianlei
*/
export async function validateFormModelAndTables(form,formData, cases, autoJumpTab) {
if (!(form && typeof form.validate === 'function')) {
throw `form 参数需要的是一个form对象而传入的却是${typeof form}`
}
let dataMap = {}
let values = await new Promise((resolve, reject) => {
// 验证主表表单
form.validate((valid,obj) => {
valid ?resolve(formData): reject({error: VALIDATE_FAILED, originError: valid})
})
})
Object.assign(dataMap, {formValue: values})
// 验证所有子表的表单
let subData = await validateTables(cases, autoJumpTab)
// 合并最终数据
dataMap = Object.assign(dataMap, {tablesValue: subData})
return dataMap
}
/**
* 验证并获取一个或多个表格的所有值
*

View File

@ -1,246 +0,0 @@
<template>
<div class="tinymce-containerty" :style="{width:containerWidth}">
<textarea :id="tinymceId" class="tinymce-textarea" @change="ada"/>
</div>
</template>
<script>
/**
* docs:
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
*/
import load from './load'
//const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
//const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
export default {
name: 'JEditorDyn',
props: {
id: {
type: String,
default: function() {
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
value: {
type: String,
default: ''
},
toolbar: {
type: [String, Array],
required: false,
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists link unlink image media table | removeformat | fullscreen',
},
menubar: {
type: String,
default: 'file edit insert view format table'
},
height: {
type: [Number, String],
required: false,
default: 360
},
width: {
type: [Number, String],
required: false,
default: 'auto'
},
plugins: {
type: [String, Array],
default: 'lists image link media table textcolor wordcount contextmenu fullscreen'
}
},
data() {
return {
hasChange: false,
hasInit: false,
tinymceId: this.id,
fullscreen: false,
languageTypeList: {
'en': 'en',
'zh': 'zh_CN',
'es': 'es_MX',
'ja': 'ja'
}
}
},
computed: {
containerWidth() {
const width = this.width
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
return `${width}px`
}
return width
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || ''))
}
}
},
mounted() {
this.init()
},
activated() {
if (window.tinymce) {
this.initTinymce()
}
},
deactivated() {
this.destroyTinymce()
},
destroyed() {
this.destroyTinymce()
},
methods: {
ada() {
console.log('change')
},
init() {
// dynamic load tinymce from cdn
load(tinymceCDN, (err) => {
if (err) {
this.$message.error(err.message)
return
}
this.initTinymce()
})
},
initTinymce() {
const _this = this
window.tinymce.init({
selector: `#${this.tinymceId}`,
language: this.languageTypeList['zh'],
height: this.height,
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar,
menubar: false,
plugins: this.plugins,
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
link_title: false,
nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
},
setup(editor) {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
},
// it will try to keep these URLs intact
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
convert_urls: false
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('err')
// console.log(err);
// });
// },
})
},
destroyTinymce() {
const tinymce = window.tinymce.get(this.tinymceId)
if (this.fullscreen) {
tinymce.execCommand('mceFullScreen')
}
if (tinymce) {
tinymce.destroy()
}
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
},
imageSuccessCBK(arr) {
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
}
}
}
</script>
<style lang="less" scoped>
.tinymce-containerty {
position: relative;
line-height: normal;
}
.tinymce-containerty {
::v-deep {
.mce-fullscreen {
z-index: 10000;
}
}
}
.tinymce-textarea {
visibility: hidden;
z-index: -1;
}
.editor-custom-btn-container {
position: absolute;
right: 4px;
top: 4px;
/*z-index: 2005;*/
}
.fullscreen .editor-custom-btn-container {
z-index: 10000;
position: fixed;
}
.editor-upload-btn {
display: inline-block;
}
</style>

View File

@ -1,142 +0,0 @@
<template>
<div class="j-markdown-editor" :id="dynamicId"/>
</template>
<script>
import load from './load'
import { md_js, md_zh_cn_js } from './Resource'
import defaultOptions from '@/components/jeecg/JMarkdownEditor/default-options.js'
export default {
name: 'JMdEditorDyn',
props: {
value: {
type: String,
default: ''
},
id: {
type: String,
required: false,
default() {
return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
options: {
type: Object,
default() {
return defaultOptions
}
},
mode: {
type: String,
default: 'markdown'
},
height: {
type: String,
required: false,
default: '300px'
},
language: {
type: String,
required: false,
default: 'zh-CN'
}
},
data() {
return {
editor: null,
dynamicId: this.id
}
},
computed: {
editorOptions() {
const options = Object.assign({}, defaultOptions, this.options)
options.initialEditType = this.mode
options.height = this.height
options.language = this.language
return options
}
},
watch: {
value(newValue, preValue) {
if (newValue !== preValue && newValue !== this.editor.getMarkdown()) {
this.editor.setMarkdown(newValue)
}
},
language(val) {
this.destroyEditor()
this.initEditor()
},
height(newValue) {
this.editor.height(newValue)
},
mode(newValue) {
this.editor.changeMode(newValue)
}
},
mounted() {
this.init()
},
destroyed() {
this.destroyEditor()
},
methods: {
init(){
this.initEditor()
/* load(md_js,'',()=>{
load(md_zh_cn_js,'',()=>{
})
})*/
},
initEditor() {
const Editor = toastui.Editor
this.editor = new Editor({
el: document.getElementById(this.dynamicId),
...this.editorOptions
})
if (this.value) {
this.editor.setMarkdown(this.value)
}
this.editor.on('change', () => {
this.$emit('change', this.editor.getMarkdown())
})
},
destroyEditor() {
if (!this.editor) return
this.editor.off('change')
this.editor.remove()
},
setMarkdown(value) {
this.editor.setMarkdown(value)
},
getMarkdown() {
return this.editor.getMarkdown()
},
setHtml(value) {
this.editor.setHtml(value)
},
getHtml() {
return this.editor.getHtml()
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped lang="less">
.j-markdown-editor {
/deep/ .tui-editor-defaultUI {
.te-mode-switch,
.tui-scrollsync
{
line-height: 1.5;
}
}
}
</style>

View File

@ -1,325 +0,0 @@
<template>
<div class="jeecg-editor-ty" :class="fullCoder?'jeecg-editor-max':'jeecg-editor-min'">
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
<textarea :id="dynamicId" />
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden': hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
</div>
</template>
<script>
import load from './load'
import '@/assets/less/codemirror_idea.css'
import './cm_sql_hint.js'
import { sql_keyword } from './Resource'
export default {
name: 'JSqlCodeEditorDyn',
props:{
id: {
type: String,
default: function() {
return 'vue-editor-' + new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
value: {
type: String,
default: ''
},
// 显示行号
lineNumbers: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: ''
},
zIndex: {
type: [Number, String],
default: 999
},
autoHeight: {
type: [String, Boolean],
default: true
},
// 不自适应高度的情况下生效的固定高度
height: {
type: [String, Number],
default: '240px'
},
autoHeight: {
type: [String, Boolean],
default: true
},
// 是否显示全屏按钮
fullScreen: {
type: Boolean,
default: false
},
autoHint:{
type: Boolean,
default: true
}
},
data(){
return {
dynamicId: this.id,
coder: '',
hasCode: false,
code: '',
// code 编辑器 是否全屏
fullCoder: false,
iconType: 'fullscreen',
}
},
computed:{
placeholderShow() {
if (this.placeholder == null) {
return `请在此输入javascript代码`
} else {
return this.placeholder
}
},
nullTipStyle(){
if (this.lineNumbers) {
return { left: '36px' }
} else {
return { left: '12px' }
}
},
isAutoHeight() {
let {autoHeight} = this
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
autoHeight = !(isIE() || isIE11())
} else {
autoHeight = true
}
return autoHeight
},
fullScreenParentProps() {
let props = {
class: {
'full-screen-parent': true,
'full-screen': this.fullCoder,
'auto-height': this.isAutoHeight
},
style: {}
}
if (this.fullCoder) {
props.style['z-index'] = this.zIndex
}
if (!this.isAutoHeight) {
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
}
return props
}
},
watch: {
fullCoder:{
handler(value) {
if(value){
this.iconType="fullscreen-exit"
}else{
this.iconType="fullscreen"
}
}
}
},
mounted() {
this.init()
},
methods:{
init(){
this.main();
},
main(){
let obj = document.getElementById(this.dynamicId);
const that = this;
let editor = CodeMirror.fromTextArea(obj,{
theme:'idea',
lineNumbers: this.lineNumbers,
lineWrapping: true,
mode: "sql",
indentUnit: 1,
indentWithTabs: true,
styleActiveLine: true,
/* styleSelectedText: false, */
extraKeys: {
"F11": function(cm) {
that.fullCoder = !that.fullCoder
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
},
"Esc": function(cm) {
that.fullCoder = false
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
},
"Alt-/": function(cm) {
cm.showHint();
},
"Tab": (cm) => {
if (cm.somethingSelected()) {
cm.indentSelection('add');
} else {
//cm.indentLine(cm.getCursor().line, "add");
//走两格 第三格输入
cm.replaceSelection(Array(3).join(" "), "end", "+input");
}
},
"Shift-Tab": (cm) => {
if (cm.somethingSelected()) {
cm.indentSelection('subtract');
} else {
// cm.indentLine(cm.getCursor().line, "subtract");
const cursor = cm.getCursor();
// 光标回退 indexUnit 字符
cm.setCursor({line: cursor.line, ch: cursor.ch - 4});
}
return ;
}
}
})
this.coder = editor
this.addEvent();
this.setCoderValue();
this.addSystemHint();
},
setCoderValue(){
if(this.value||this.code){
this.hasCode=true
this.setCodeContent(this.value || this.code)
}else{
this.coder.setValue('')
this.hasCode=false
}
},
getCodeContent(){
return this.code
},
setCodeContent(val){
setTimeout(()=>{
if(!val){
this.coder.setValue('')
}else{
this.coder.setValue(val)
}
},300)
},
addSystemHint(){
this.coder.setOption('hintOptions', {
completeSingle: false,
tables: sql_keyword
});
},
addEvent(){
if(this.autoHint){
this.coder.on('cursorActivity', ()=>{
this.coder.showHint();
});
}
this.coder.on('change', (coder) => {
this.code = coder.getValue()
if(this.code){
this.hasCode=true
}else{
this.hasCode=false
}
if (this.$emit) {
this.$emit('input', this.code)
}
});
this.coder.on('focus', () => {
this.hasCode=true
});
this.coder.on('blur', () => {
if(this.code){
this.hasCode=true
}else{
this.hasCode=false
}
});
},
loadResource(src,type){
return new Promise((resolve,reject)=>{
load(src,type,(msg)=>{
if(!msg){
resolve();
}else{
reject(msg)
}
})
})
},
nullTipClick(){
this.coder.focus()
},
fullToggle(){
this.fullCoder = !this.fullCoder
this.coder.setOption("fullScreen", this.fullCoder);
}
}
}
</script>
<style lang="less" >
.jeecg-editor-ty{
position: relative;
.full-screen-icon {
opacity: 0;
color: black;
width: 20px;
height: 20px;
line-height: 24px;
background-color: white;
position: absolute;
top: 4px;
right: 2px;
z-index: 9;
cursor: pointer;
transition: opacity 0.3s;
}
&:hover {
.full-screen-icon {
opacity: 1;
&:hover {
background-color: rgba(255, 255, 255, 0.88);
}
}
}
.null-tip{
position: absolute;
top: 4px;
left: 36px;
z-index: 10;
font-size:16px;
color: #acaaaac9;
line-height: initial;
}
.null-tip-hidden{
display: none;
}
}
.jeecg-editor-max{
position: fixed;
left: 0;
top: 0;
z-index: 999;
height: 100%;
width: 100% !important;
.CodeMirror{
position: inherit !important;
width: 100%;
height: 100%;
}
.full-screen-icon{
z-index:9999;
}
}
</style>

View File

@ -1,319 +0,0 @@
<template>
<div class="jeecg-editor-ty" :class="fullCoder?'jeecg-editor-max':'jeecg-editor-min'">
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
<textarea :id="dynamicId" />
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden': hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
</div>
</template>
<script>
import '@/assets/less/codemirror_idea.css'
import './cm_hint.js'
export default {
name: 'JsCodeEditorDyn',
props:{
id: {
type: String,
default: function() {
return 'vue-editor-' + new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
value: {
type: String,
default: ''
},
// 显示行号
lineNumbers: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: ''
},
zIndex: {
type: [Number, String],
default: 999
},
autoHeight: {
type: [String, Boolean],
default: true
},
// 不自适应高度的情况下生效的固定高度
height: {
type: [String, Number],
default: '240px'
},
autoHeight: {
type: [String, Boolean],
default: true
},
// 是否显示全屏按钮
fullScreen: {
type: Boolean,
default: false
},
},
data(){
return {
dynamicId: this.id,
coder: '',
hasCode: false,
code: '',
// code 编辑器 是否全屏
fullCoder: false,
iconType: 'fullscreen',
}
},
computed:{
placeholderShow() {
if (this.placeholder == null) {
return `请在此输入javascript代码`
} else {
return this.placeholder
}
},
nullTipStyle(){
if (this.lineNumbers) {
return { left: '36px' }
} else {
return { left: '12px' }
}
},
isAutoHeight() {
let {autoHeight} = this
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
autoHeight = !(isIE() || isIE11())
} else {
autoHeight = true
}
return autoHeight
},
fullScreenParentProps() {
let props = {
class: {
'full-screen-parent': true,
'full-screen': this.fullCoder,
'auto-height': this.isAutoHeight
},
style: {}
}
if (this.fullCoder) {
props.style['z-index'] = this.zIndex
}
if (!this.isAutoHeight) {
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
}
return props
}
},
watch: {
fullCoder:{
handler(value) {
if(value){
this.iconType="fullscreen-exit"
}else{
this.iconType="fullscreen"
}
}
}
},
mounted() {
this.init()
},
methods:{
init(){
this.main();
},
main(){
let obj = document.getElementById(this.dynamicId);
const that = this;
let editor = CodeMirror.fromTextArea(obj,{
theme:'idea',
lineNumbers: this.lineNumbers,
lineWrapping: true,
mode: "javascript",
indentUnit: 1,
indentWithTabs: true,
styleActiveLine: true,
/* styleSelectedText: false, */
extraKeys: {
"F11": function(cm) {
that.fullCoder = !that.fullCoder
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
},
"Esc": function(cm) {
that.fullCoder = false
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
},
"Alt-/": function(cm) {
let a = cm.getValue()+""
console.log('a',a)
cm.showHint();
},
"Tab": (cm) => {
if (cm.somethingSelected()) {
cm.indentSelection('add');
} else {
//cm.indentLine(cm.getCursor().line, "add");
//走两格 第三格输入
cm.replaceSelection(Array(3).join(" "), "end", "+input");
}
},
"Shift-Tab": (cm) => {
if (cm.somethingSelected()) {
cm.indentSelection('subtract');
} else {
// cm.indentLine(cm.getCursor().line, "subtract");
const cursor = cm.getCursor();
// 光标回退 indexUnit 字符
cm.setCursor({line: cursor.line, ch: cursor.ch - 4});
}
return ;
}
}
})
this.coder = editor
this.addEvent();
this.setCoderValue();
},
setCoderValue(){
if(this.value||this.code){
this.hasCode=true
this.setCodeContent(this.value || this.code)
}else{
this.coder.setValue('')
this.hasCode=false
}
},
getCodeContent(){
return this.code
},
setCodeContent(val){
setTimeout(()=>{
if(!val){
this.coder.setValue('')
}else{
this.coder.setValue(val)
}
},300)
},
addEvent(){
const that = this;
this.coder.on('cursorActivity',function(wl) {
let arr = wl.state.activeLines
if(arr && arr.length>0){
let text = arr[0].text
if(text.lastIndexOf('that.')>=0){
that.coder.showHint();
}
}
});
this.coder.on('change', (coder) => {
this.code = coder.getValue()
if(this.code){
this.hasCode=true
}else{
this.hasCode=false
}
if (this.$emit) {
this.$emit('input', this.code)
}
});
this.coder.on('focus', () => {
this.hasCode=true
});
this.coder.on('blur', () => {
if(this.code){
this.hasCode=true
}else{
this.hasCode=false
}
});
},
loadResource(src,type){
return new Promise((resolve,reject)=>{
load(src,type,(msg)=>{
if(!msg){
resolve();
}else{
reject(msg)
}
})
})
},
nullTipClick(){
this.coder.focus()
},
fullToggle(){
this.fullCoder = !this.fullCoder
this.coder.setOption("fullScreen", this.fullCoder);
}
}
}
</script>
<style lang="less" >
.jeecg-editor-ty{
position: relative;
.full-screen-icon {
opacity: 0;
color: black;
width: 20px;
height: 20px;
line-height: 24px;
background-color: white;
position: absolute;
top: 4px;
right: 2px;
z-index: 9;
cursor: pointer;
transition: opacity 0.3s;
}
&:hover {
.full-screen-icon {
opacity: 1;
&:hover {
background-color: rgba(255, 255, 255, 0.88);
}
}
}
.null-tip{
position: absolute;
top: 4px;
left: 36px;
z-index: 10;
font-size:16px;
color: #acaaaac9;
line-height: initial;
}
.null-tip-hidden{
display: none;
}
}
.jeecg-editor-max{
position: fixed;
left: 0;
top: 0;
z-index: 999;
height: 100%;
width: 100% !important;
.CodeMirror{
position: inherit !important;
width: 100%;
height: 100%;
}
.full-screen-icon{
z-index:9999;
}
}
</style>

View File

@ -1,24 +0,0 @@
/**js编辑器关键词用于提示*/
const js_keyword = [
'that',
'getAction','postAction','deleteAction',
'beforeAdd','beforeEdit','beforeDelete','mounted','created','show'
]
/**js编辑器 方法名用于提示*/
const js_method = [
'.getSelectOptions','.changeOptions','.triggleChangeValues','.immediateEnhance ','.simpleDateFormat','.lodash'
]
/**sql编辑器 表名字段名用于提示*/
const sql_keyword = {
sys_user: ['USERNAME', 'REALNAME', 'ID','BIRTHDAY','AGE'],
demo: ['name', 'age', 'id', 'sex']
}
export {
js_keyword,
js_method,
sql_keyword
}

View File

@ -1,177 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
import { js_keyword, js_method } from './Resource'
(function(mod) {
mod(CodeMirror);
/*if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env*/
})(function(CodeMirror) {
var Pos = CodeMirror.Pos;
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}
function scriptHint(editor, keywords, getToken, options) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur);
if (/\b(?:string|comment)\b/.test(token.type)) return;
var innerMode = CodeMirror.innerMode(editor.getMode(), token.state);
if (innerMode.mode.helperType === "json") return;
token.state = innerMode.state;
if('.' === token.string){
let arr = []
for(let k of js_method){
arr.push(k)
}
return {
list: arr,
from: Pos(cur.line, token.start),
to: Pos(cur.line, token.end)
};
}
// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) {
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
type: token.string == "." ? "property" : null};
} else if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}
var tprop = token;
// If it is a property, find out what it is a property of.
while (tprop.type == "property") {
tprop = getToken(editor, Pos(cur.line, tprop.start));
if (tprop.string != ".") return;
tprop = getToken(editor, Pos(cur.line, tprop.start));
if (!context) var context = [];
context.push(tprop);
}
return {list: getCompletions(token, context, keywords, options),
from: Pos(cur.line, token.start),
to: Pos(cur.line, token.end)};
}
function javascriptHint(editor, options) {
return scriptHint(editor, javascriptKeywords,
function (e, cur) {return e.getTokenAt(cur);},
options);
};
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
function getCoffeeScriptToken(editor, cur) {
// This getToken, it is for coffeescript, imitates the behavior of
// getTokenAt method in javascript.js, that is, returning "property"
// type and treat "." as indepenent token.
var token = editor.getTokenAt(cur);
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
token.end = token.start;
token.string = '.';
token.type = "property";
}
else if (/^\.[\w$_]*$/.test(token.string)) {
token.type = "property";
token.start++;
token.string = token.string.replace(/\./, '');
}
return token;
}
function coffeescriptHint(editor, options) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
}
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
"toUpperCase toLowerCase split concat match replace search").split(" ");
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
var funcProps = "prototype apply call bind".split(" ");
var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " +
"if in import instanceof new null return super switch this throw true try typeof var void while with yield that").split(" ");
for(let jk of js_keyword){
javascriptKeywords.push(jk)
}
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
function forAllProps(obj, callback) {
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
for (var name in obj) callback(name)
} else {
for (var o = obj; o; o = Object.getPrototypeOf(o))
Object.getOwnPropertyNames(o).forEach(callback)
}
}
function getCompletions(token, context, keywords, options) {
var found = [], start = token.string, global = options && options.globalScope || window;
function maybeAdd(str) {
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
}
function gatherCompletions(obj) {
if (typeof obj == "string") forEach(stringProps, maybeAdd);
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
forAllProps(obj, maybeAdd)
}
if (context && context.length) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.type && obj.type.indexOf("variable") === 0) {
if (options && options.additionalContext)
base = options.additionalContext[obj.string];
if (!options || options.useGlobalScope !== false)
base = base || global[obj.string];
} else if (obj.type == "string") {
base = "";
} else if (obj.type == "atom") {
base = 1;
} else if (obj.type == "function") {
if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
(typeof global.jQuery == 'function'))
base = global.jQuery();
else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
base = global._();
}
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
} else {
// If not, just look in the global object, any local scope, and optional additional-context
// (reading into JS mode internals to get at the local and global variables)
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
for (var c = token.state.context; c; c = c.prev)
for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
if (options && options.additionalContext != null)
for (var key in options.additionalContext)
maybeAdd(key);
if (!options || options.useGlobalScope !== false)
gatherCompletions(global);
forEach(keywords, maybeAdd);
}
return found;
}
});

View File

@ -1,305 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
/*if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
else */
// Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var tables;
var defaultTable;
var keywords;
var identifierQuote;
var CONS = {
QUERY_DIV: ";",
ALIAS_KEYWORD: "AS"
};
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
function getKeywords(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).keywords;
}
function getIdentifierQuote(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).identifierQuote || "`";
}
function getText(item) {
return typeof item == "string" ? item : item.text;
}
function wrapTable(name, value) {
if (isArray(value)) value = {columns: value}
if (!value.text) value.text = name
return value
}
function parseTables(input) {
var result = {}
if (isArray(input)) {
for (var i = input.length - 1; i >= 0; i--) {
var item = input[i]
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
}
} else if (input) {
for (var name in input)
result[name.toUpperCase()] = wrapTable(name, input[name])
}
return result
}
function getTable(name) {
return tables[name.toUpperCase()]
}
function shallowClone(object) {
var result = {};
for (var key in object) if (object.hasOwnProperty(key))
result[key] = object[key];
return result;
}
function match(string, word) {
var len = string.length;
var sub = getText(word).substr(0, len);
return string.toUpperCase() === sub.toUpperCase();
}
function addMatches(result, search, wordlist, formatter) {
if (isArray(wordlist)) {
for (var i = 0; i < wordlist.length; i++)
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
} else {
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
var val = wordlist[word]
if (!val || val === true)
val = word
else
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
if (match(search, val)) result.push(formatter(val))
}
}
}
function cleanName(name) {
// Get rid name from identifierQuote and preceding dot(.)
if (name.charAt(0) == ".") {
name = name.substr(1);
}
// replace doublicated identifierQuotes with single identifierQuotes
// and remove single identifierQuotes
var nameParts = name.split(identifierQuote+identifierQuote);
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
return nameParts.join(identifierQuote);
}
function insertIdentifierQuotes(name) {
var nameParts = getText(name).split(".");
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = identifierQuote +
// doublicate identifierQuotes
nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
identifierQuote;
var escaped = nameParts.join(".");
if (typeof name == "string") return escaped;
name = shallowClone(name);
name.text = escaped;
return name;
}
function nameCompletion(cur, token, result, editor) {
// Try to complete table, column names and return start position of completion
var useIdentifierQuotes = false;
var nameParts = [];
var start = token.start;
var cont = true;
while (cont) {
cont = (token.string.charAt(0) == ".");
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
start = token.start;
nameParts.unshift(cleanName(token.string));
token = editor.getTokenAt(Pos(cur.line, token.start));
if (token.string == ".") {
cont = true;
token = editor.getTokenAt(Pos(cur.line, token.start));
}
}
// Try to complete table names
var string = nameParts.join(".");
addMatches(result, string, tables, function(w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns from defaultTable
addMatches(result, string, defaultTable, function(w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns
string = nameParts.pop();
var table = nameParts.join(".");
var alias = false;
var aliasTable = table;
// Check if table is available. If not, find table by Alias
if (!getTable(table)) {
var oldTable = table;
table = findTableByAlias(table, editor);
if (table !== oldTable) alias = true;
}
var columns = getTable(table);
if (columns && columns.columns)
columns = columns.columns;
if (columns) {
addMatches(result, string, columns, function(w) {
var tableInsert = table;
if (alias == true) tableInsert = aliasTable;
if (typeof w == "string") {
w = tableInsert + "." + w;
} else {
w = shallowClone(w);
w.text = tableInsert + "." + w.text;
}
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
}
return start;
}
function eachWord(lineText, f) {
var words = lineText.split(/\s+/)
for (var i = 0; i < words.length; i++)
if (words[i]) f(words[i].replace(/[,;]/g, ''))
}
function findTableByAlias(alias, editor) {
var doc = editor.doc;
var fullQuery = doc.getValue();
var aliasUpperCase = alias.toUpperCase();
var previousWord = "";
var table = "";
var separator = [];
var validRange = {
start: Pos(0, 0),
end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
};
//add separator
var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
while(indexOfSeparator != -1) {
separator.push(doc.posFromIndex(indexOfSeparator));
indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
}
separator.unshift(Pos(0, 0));
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
//find valid range
var prevItem = null;
var current = editor.getCursor()
for (var i = 0; i < separator.length; i++) {
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
validRange = {start: prevItem, end: separator[i]};
break;
}
prevItem = separator[i];
}
if (validRange.start) {
var query = doc.getRange(validRange.start, validRange.end, false);
for (var i = 0; i < query.length; i++) {
var lineText = query[i];
eachWord(lineText, function(word) {
var wordUpperCase = word.toUpperCase();
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
table = previousWord;
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
previousWord = word;
});
if (table) break;
}
}
return table;
}
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
tables = parseTables(options && options.tables)
var defaultTableName = options && options.defaultTable;
var disableKeywords = options && options.disableKeywords;
defaultTable = defaultTableName && getTable(defaultTableName);
keywords = getKeywords(editor);
identifierQuote = getIdentifierQuote(editor);
if (defaultTableName && !defaultTable)
defaultTable = findTableByAlias(defaultTableName, editor);
defaultTable = defaultTable || [];
if (defaultTable.columns)
defaultTable = defaultTable.columns;
var cur = editor.getCursor();
var result = [];
var token = editor.getTokenAt(cur), start, end, search;
if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}
if (token.string.match(/^[.`"'\w@][\w$#]*$/g)) {
search = token.string;
start = token.start;
end = token.end;
} else {
start = end = cur.ch;
search = "";
}
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
start = nameCompletion(cur, token, result, editor);
} else {
var objectOrClass = function(w, className) {
if (typeof w === "object") {
w.className = className;
} else {
w = { text: w, className: className };
}
return w;
};
addMatches(result, search, defaultTable, function(w) {
return objectOrClass(w, "CodeMirror-hint-table CodeMirror-hint-default-table");
});
addMatches(
result,
search,
tables, function(w) {
return objectOrClass(w, "CodeMirror-hint-table");
}
);
if (!disableKeywords)
addMatches(result, search, keywords, function(w) {
return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword");
});
}
return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
});
});

View File

@ -1,92 +0,0 @@
let callbacks = []
function loadSuccess(key) {
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
// check is successfully downloaded script
return window[key]
}
const load = (src, type, callback) => {
if(type=='link'){
loadStyle(src, callback)
}else{
let loadKey = ''
if(src.indexOf('tinymce')>=0){
loadKey = 'tinymce'
}else if(src.indexOf('codemirror')>=0){
loadKey = 'CodeMirror'
}
const scriptTag = document.getElementById(src)
//const cb = callback || function() {}
if (!scriptTag) {
const script = document.createElement('script')
script.src = src // src url for the third-party library being loaded.
script.id = src
script.onload=()=>callback()
script.onerror=()=>callback('加载失败'+src)
document.body.appendChild(script)
//callbacks.push(cb)
// const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
// onEnd(script)
}else{
if (loadSuccess(loadKey)) {
callback()
}
}
if (scriptTag) {
/* else {
callbacks.push(cb)
}*/
}
}
function stdOnEnd(script) {
script['onload'] = function() {
// this.onload = null here is necessary
// because even IE9 works not like others
this.onerror = this.onload = null
for (const cb of callbacks) {
cb(null, script)
}
callbacks = null
}
script['onerror'] = function() {
this.onerror = this.onload = null
cb(new Error('Failed to load ' + src), script)
}
}
function ieOnEnd(script) {
script.onreadystatechange = function() {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
for (const cb of callbacks) {
cb(null, script) // there is no way to catch loading errors in IE8
}
callbacks = null
}
}
function loadStyle(src, callback) {
const link = document.getElementById(src)
if (!link) {
const link = document.createElement('link')
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", src);
link.id = src
let heads = document.getElementsByTagName("head")
if(heads.length){
heads[0].appendChild(link)
}else{
document.documentElement.appendChild(link)
}
}
callback();
}
}
export default load

View File

@ -27,6 +27,13 @@ import JSwitch from './JSwitch.vue'
import JTime from './JTime.vue'
import JTreeTable from './JTreeTable.vue'
//jeecgbiz
import JSelectDepart from '../jeecgbiz/JSelectDepart.vue'
import JSelectMultiUser from '../jeecgbiz/JSelectMultiUser.vue'
import JSelectPosition from '../jeecgbiz/JSelectPosition.vue'
import JSelectRole from '../jeecgbiz/JSelectRole.vue'
import JSelectUserByDep from '../jeecgbiz/JSelectUserByDep.vue'
export default {
install(Vue) {
Vue.component('JMarkdownEditor', JMarkdownEditor)
@ -57,5 +64,12 @@ export default {
Vue.component('JTreeSelect', JTreeSelect)
Vue.component('JTreeTable', JTreeTable)
Vue.component('JUpload', JUpload)
//jeecgbiz
Vue.component('JSelectDepart', JSelectDepart)
Vue.component('JSelectMultiUser', JSelectMultiUser)
Vue.component('JSelectPosition', JSelectPosition)
Vue.component('JSelectRole', JSelectRole)
Vue.component('JSelectUserByDep', JSelectUserByDep)
}
}

View File

@ -14,7 +14,6 @@
</template>
<script>
import JUpload from '@/components/jeecg/JUpload'
import { getFileAccessHttpUrl } from '@/api/manage';
const getFileName=(path)=>{
@ -27,7 +26,7 @@
export default {
name: 'JFilePop',
components: { JUpload },
components: { },
props:{
title:{
type:String,

View File

@ -121,7 +121,7 @@
},
cgRpConfigId:"",
modalWidth:MODAL_WIDTH,
tableScroll:{x:MODAL_WIDTH-100},
tableScroll:{x:true},
dynamicParam:{}
}
@ -342,7 +342,13 @@
combineRowKey(record){
let res = ''
Object.keys(record).forEach(key=>{
res+=record[key]
//update-begin---author:liusq Date:20210203 forpop选择器列主键问题 issues/I29P9Q------------
if(key=='id'){
res=record[key]+res
}else{
res+=record[key]
}
//update-end---author:liusq Date:20210203 forpop选择器列主键问题 issues/I29P9Q------------
})
if(res.length>50){
res = res.substring(0,50)

View File

@ -53,6 +53,11 @@
customReturnField: {
type: String,
default: 'id'
},
backDepart: {
type: Boolean,
default: false,
required: false
}
},
data(){
@ -91,6 +96,23 @@
}
//update-end-author:lvdandan date:20200513 for:TESTA-438 部门选择组件自定义返回值,数据无法回填
},
//返回选中的部门信息
backDeparInfo(){
if(this.backDepart===true){
if(this.departIds && this.departIds.length>0){
let arr1 = this.departIds.split(',')
let arr2 = this.departNames.split(',')
let info = []
for(let i=0;i<arr1.length;i++){
info.push({
value: arr1[i],
text: arr2[i]
})
}
this.$emit('back', info)
}
}
},
openModal(){
this.$refs.innerDepartSelectModal.show()
},
@ -105,6 +127,7 @@
this.departIds = idstr
}
this.$emit("change", value)
this.backDeparInfo()
},
getDepartNames(){
return this.departNames

View File

@ -38,6 +38,11 @@
default: true,
required: false
},
backUser: {
type: Boolean,
default: false,
required: false
}
},
data() {
return {
@ -61,6 +66,23 @@
initComp(userNames) {
this.userNames = userNames
},
//返回选中的用户信息
backDeparInfo(){
if(this.backUser===true){
if(this.userIds && this.userIds.length>0){
let arr1 = this.userIds.split(',')
let arr2 = this.userNames.split(',')
let info = []
for(let i=0;i<arr1.length;i++){
info.push({
value: arr1[i],
text: arr2[i]
})
}
this.$emit('back', info)
}
}
},
onSearchDepUser() {
this.$refs.selectModal.showModal()
},

View File

@ -6,6 +6,7 @@
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
wrapClassName="j-depart-select-modal"
switchFullscreen
cancelText="关闭">
<a-spin tip="Loading..." :spinning="false">
@ -166,7 +167,9 @@
if(!this.checkedKeys || this.checkedKeys.length==0){
this.$emit("ok",'')
}else{
this.$emit("ok",this.checkedRows,this.checkedKeys.join(","))
let checkRow = this.getCheckedRows(this.checkedKeys)
let keyStr = this.checkedKeys.join(",")
this.$emit("ok", checkRow, keyStr)
}
this.handleClear()
},

View File

@ -4,6 +4,7 @@
:visible="visible"
:title="title"
switchFullscreen
wrapClassName="j-user-select-modal"
@ok="handleSubmit"
@cancel="close"
style="top:50px"

View File

@ -19,14 +19,14 @@
</a-tab-pane>
</a-tabs>
<div style="margin: 12px 12px 0;">
<transition name="page-toggle">
<keep-alive v-if="multipage">
<router-view v-if="reloadFlag"/>
</keep-alive>
<template v-else>
<router-view v-if="reloadFlag"/>
</template>
</transition>
<!-- update-begin-author:taoyan date:20201221 for:此处删掉transition标签 不知道为什么加上后 页面路由切换的时候即1及菜单切到2及菜单的时候 两个菜单页面会同时出现300-500秒左右 -->
<keep-alive v-if="multipage">
<router-view v-if="reloadFlag"/>
</keep-alive>
<template v-else>
<router-view v-if="reloadFlag"/>
</template>
<!-- update-end-author:taoyan date:20201221 for:此处删掉transition标签 不知道为什么加上后 页面路由切换的时候即1及菜单切到2及菜单的时候 两个菜单页面会同时出现300-500秒左右 -->
</div>
</global-layout>
</template>
@ -171,7 +171,7 @@
// update-begin-author:sunjianlei date:20200120 for: 动态更改页面标题
changeTitle(title) {
let projectTitle = "Jeecg-Boot 企业级快速开发平台"
let projectTitle = "Jeecg-Boot 企业级低代码平台"
// 首页特殊处理
if (this.$route.path === indexKey) {
document.title = projectTitle

View File

@ -9,7 +9,7 @@
</a>
</div>
<div class="desc">
Jeecg Boot 是中国最具影响力的 企业级 快速开发平台
Jeecg Boot 是中国最具影响力的 企业级 低代码平台
</div>
</div>

View File

@ -54,6 +54,10 @@ import {
Carousel,
Pagination,
FormModel,
Cascader,
Slider,
Transfer,
Rate
} from 'ant-design-vue'
import Viser from 'viser-vue'
@ -104,6 +108,10 @@ Vue.use(TreeSelect)
Vue.use(Carousel)
Vue.use(Pagination)
Vue.use(FormModel)
Vue.use(Cascader)
Vue.use(Slider)
Vue.use(Transfer)
Vue.use(Rate)
Vue.prototype.$confirm = Modal.confirm
Vue.prototype.$message = message

View File

@ -136,41 +136,8 @@
background-color: #999999;
}
}
background-color: rgb(48, 65, 86);
/deep/ .ant-menu-submenu-title:hover{
background-color: #263445;
}
/deep/ .ant-menu-item:hover{
background-color: #263445;
}
/deep/ .ant-menu-item-selected {
background-color: #263445;
}
/deep/ .ant-menu-item-selected i{
color: rgb(24, 144, 255);
}
/deep/ .ant-menu-item-selected span{
color: rgb(24, 144, 255);
}
/deep/ .ant-menu-inline.ant-menu-sub{
background-color: #1f2d3d;
}
/deep/ .ant-menu-inline.ant-menu-sub li:hover{
background-color: #1f2d3d;
}
/deep/ .ant-menu-inline.ant-menu-sub .ant-menu-submenu-title:hover{
background-color: #1f2d3d;
}
/deep/ .ant-menu-inline.ant-menu-sub .ant-menu-item-selected{
background-color: #1f2d3d;
}
/deep/ .ant-menu-inline.ant-menu-sub .ant-menu-item-selected span{
color: rgb(24, 144, 255);
}
/deep/ .ant-menu-inline.ant-menu-sub .ant-menu-item-selected i{
color: rgb(24, 144, 255);
}
}
}
/* update_end author:sunjianlei date:20190509 for: 修改侧边导航栏滚动条的样式 */

View File

@ -17,7 +17,7 @@
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="toggle"/>
<span v-if="device === 'desktop'">欢迎进入 Jeecg-Boot 企业级快速开发平台</span>
<span v-if="device === 'desktop'">欢迎进入 Jeecg-Boot 企业级低代码平台</span>
<span v-else>Jeecg-Boot</span>
<user-menu :theme="theme"/>
@ -42,6 +42,7 @@
<user-menu class="header-index-right" :theme="theme" :style="topMenuStyle.headerIndexRight"/>
</div>
</div>
</a-layout-header>
</template>
@ -49,7 +50,6 @@
import UserMenu from '../tools/UserMenu'
import SMenu from '../menu/'
import Logo from '../tools/Logo'
import { mixin } from '@/utils/mixin.js'
export default {

View File

@ -131,6 +131,11 @@
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置判断是否路由菜单字段动态选择是否生成路由为了支持参数URL菜单------
//this.menus = this.mainRouters.find((item) => item.path === '/').children;
this.menus = this.permissionMenuList
//--update-begin----author:liusq---date:20210223------for:关于测边菜单遮挡内容问题详细说明 #2255
this.collapsed=!this.sidebarOpened;
//--update-begin----author:liusq---date:20210223------for:关于测边菜单遮挡内容问题详细说明 #2255
// 根据后台配置菜单,重新排序加载路由信息
//console.log('----加载菜单逻辑----')
//console.log(this.mainRouters)
@ -528,43 +533,8 @@
margin: 0 auto;
width: 100%;
}
/deep/ .ant-menu-dark{
background-color: rgb(48, 65, 86);
/deep/ .ant-menu-submenu:hover{
background-color: #263445;
}
/deep/ .ant-menu-item:hover{
background-color: #263445;
}
}
/deep/ .ant-menu.ant-menu-dark .ant-menu-item-selected{
background-color: #263445;
}
/deep/ .ant-menu.ant-menu-dark .ant-menu-item-selected i{
color: rgb(24, 144, 255);
}
/deep/ .ant-menu.ant-menu-dark .ant-menu-item-selected span{
color: rgb(24, 144, 255);
}
/deep/ .ant-menu-dark .ant-menu-submenu-active{
color: #FFFFFF !important;
}
}
.dark.header-index-right{
background-color: rgb(48, 65, 86) !important;
}
.layout .top-nav-header-index.dark .user-wrapper .action:hover{
background-color: #263445 !important;
}
.layout .top-nav-header-index .dark .user-wrapper .action i{
color: #FFFFFF !important;
}
.layout .top-nav-header-index .user-wrapper .action .anticon{
color: inherit !important;
}
.dark.ant-dropdown-menu{
background-color: #999999;
}
// drawer-sider 自定义
.ant-drawer.drawer-sider {
.sider {
@ -715,22 +685,4 @@
}
}
}
.ant-menu-dark .ant-menu-vertical.ant-menu-sub li:hover{
background-color: #001528;
}
.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected{
background-color: #001528 !important;
}
.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected span{
color: rgb(24, 144, 255);
}
.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected i{
color: rgb(24, 144, 255);
}
.ant-menu-dark .ant-menu-sub{
background: #1f2d3d !important;
.ant-menu-submenu-open,.ant-menu-submenu-active{
color: #FFFFFF !important;
}
}
</style>

View File

@ -6,7 +6,7 @@
:closable="false"
@close="onClose"
:visible="visible"
:style="{}"
style="height: 100%;overflow: auto;"
>
<div class="setting-drawer-index-content">
@ -178,19 +178,12 @@
mixins: [mixin, mixinDevice],
data() {
return {
visible: true,
visible: false,
colorList,
dataFixSiderbar: false
}
},
watch: {
},
mounted () {
const vm = this
setTimeout(() => {
vm.visible = false
}, 16)
// 当主题色不是默认色时,才进行主题编译
if (this.primaryColor !== config.primaryColor) {
updateTheme(this.primaryColor)

View File

@ -20,7 +20,6 @@ import 'ant-design-vue/dist/antd.less'; // or 'ant-design-vue/dist/antd.less'
import '@/permission' // permission control
import '@/utils/filter' // base filter
import Print from 'vue-print-nb-jeecg'
/*import '@babel/polyfill'*/
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
import SSO from '@/cas/sso.js'
@ -47,7 +46,9 @@ import '@/assets/less/JAreaLinkage.less'
import VueAreaLinkage from 'vue-area-linkage'
import '@/components/jeecg/JVxeTable/install'
import '@/components/JVxeCells/install'
//表单验证
import { rules } from '@/utils/rules'
Vue.prototype.rules = rules
Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions)
Vue.use(Antd)

View File

@ -50,6 +50,7 @@ export const JEditableTableMixin = {
add() {
//update-begin-author:lvdandan date:20201113 for:LOWCOD-1049 JEditaTable,子表默认添加一条数据addDefaultRowNum设置无效 #1930
return new Promise((resolve) => {
this.tableReset();
resolve();
}).then(() => {
// 默认新增空数据
@ -68,6 +69,9 @@ export const JEditableTableMixin = {
},
/** 当点击了编辑(修改)按钮时调用此方法 */
edit(record) {
if(record && '{}'!=JSON.stringify(record)){
this.tableReset();
}
if (typeof this.editBefore === 'function') this.editBefore(record)
this.visible = true
this.activeKey = this.refKeys[0]
@ -78,12 +82,14 @@ export const JEditableTableMixin = {
/** 关闭弹窗并将所有JEditableTable实例回归到初始状态 */
close() {
this.visible = false
this.eachAllTable((item) => {
item.initialize()
})
this.$emit('close')
},
//清空子表table的数据
tableReset(){
this.eachAllTable((item) => {
item.clearRow()
})
},
/** 查询某个tab的数据 */
requestSubTableData(url, params, tab, success) {
tab.loading = true

View File

@ -0,0 +1,190 @@
import JEditableTable from '@/components/jeecg/JEditableTable'
import { VALIDATE_NO_PASSED, getRefPromise,validateFormModelAndTables} from '@/utils/JEditableTableUtil'
import { httpAction, getAction } from '@/api/manage'
export const JEditableTableModelMixin = {
components: {
JEditableTable
},
data() {
return {
title: '操作',
visible: false,
confirmLoading: false,
model:{},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 18 }
}
}
},
methods: {
/** 获取所有的editableTable实例 */
getAllTable() {
if (!(this.refKeys instanceof Array)) {
throw this.throwNotArray('refKeys')
}
let values = this.refKeys.map(key => getRefPromise(this, key))
return Promise.all(values)
},
/** 遍历所有的JEditableTable实例 */
eachAllTable(callback) {
// 开始遍历
this.getAllTable().then(tables => {
tables.forEach((item, index) => {
if (typeof callback === 'function') {
callback(item, index)
}
})
})
},
/** 当点击新增按钮时调用此方法 */
add() {
//update-begin-author:lvdandan date:20201113 for:LOWCOD-1049 JEditaTable,子表默认添加一条数据addDefaultRowNum设置无效 #1930
return new Promise((resolve) => {
this.tableReset();
resolve();
}).then(() => {
// 默认新增空数据
let rowNum = this.addDefaultRowNum
if (typeof rowNum !== 'number') {
rowNum = 1
console.warn('由于你没有在 data 中定义 addDefaultRowNum addDefaultRowNum 不是数字所以默认添加一条空数据如果不想默认添加空数据请将定义 addDefaultRowNum 0')
}
this.eachAllTable((item) => {
item.add(rowNum)
})
if (typeof this.addAfter === 'function') this.addAfter(this.model)
this.edit(this.model)
})
//update-end-author:lvdandan date:20201113 for:LOWCOD-1049 JEditaTable,子表默认添加一条数据addDefaultRowNum设置无效 #1930
},
/** 当点击了编辑(修改)按钮时调用此方法 */
edit(record) {
if(record && '{}'!=JSON.stringify(record)&&record.id){
this.tableReset();
}
if (typeof this.editBefore === 'function') this.editBefore(record)
this.visible = true
this.activeKey = this.refKeys[0]
this.$refs.form.resetFields()
this.model = Object.assign({}, record)
if (typeof this.editAfter === 'function') this.editAfter(this.model)
},
/** 关闭弹窗并将所有JEditableTable实例回归到初始状态 */
close() {
this.visible = false
this.$emit('close')
},
//清空子表table的数据
tableReset(){
this.eachAllTable((item) => {
item.clearRow()
})
},
/** 查询某个tab的数据 */
requestSubTableData(url, params, tab, success) {
tab.loading = true
getAction(url, params).then(res => {
let { result } = res
let dataSource = []
if (result) {
if (Array.isArray(result)) {
dataSource = result
} else if (Array.isArray(result.records)) {
dataSource = result.records
}
}
tab.dataSource = dataSource
typeof success === 'function' ? success(res) : ''
}).finally(() => {
tab.loading = false
})
},
/** 发起请求,自动判断是执行新增还是修改操作 */
request(formData) {
let url = this.url.add, method = 'post'
if (this.model.id) {
url = this.url.edit
method = 'put'
}
this.confirmLoading = true
httpAction(url, formData, method).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
},
/* --- handle 事件 --- */
/** ATab 选项卡切换事件 */
handleChangeTabs(key) {
// 自动重置scrollTop状态防止出现白屏
getRefPromise(this, key).then(editableTable => {
editableTable.resetScrollTop()
})
},
/** 关闭按钮点击事件 */
handleCancel() {
this.close()
},
/** 确定按钮点击事件 */
handleOk() {
/** 触发表单验证 */
this.getAllTable().then(tables => {
/** 一次性验证主表和所有的次表 */
return validateFormModelAndTables(this.$refs.form,this.model, tables)
}).then(allValues => {
/** 一次性验证一对一的所有子表 */
return this.validateSubForm(allValues)
}).then(allValues => {
if (typeof this.classifyIntoFormData !== 'function') {
throw this.throwNotFunction('classifyIntoFormData')
}
let formData = this.classifyIntoFormData(allValues)
// 发起请求
return this.request(formData)
}).catch(e => {
if (e.error === VALIDATE_NO_PASSED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
//update--begin--autor:liusq-----date:20210316------for未通过表单验证跳转tab问题------
this.activeKey = e.index == null ? this.activeKey : (e.paneKey?e.paneKey:this.refKeys[e.index])
//update--end--autor:liusq-----date:20210316------for未通过表单验证跳转tab问题------
} else {
console.error(e)
}
})
},
//校验所有子表表单
validateSubForm(allValues){
return new Promise((resolve) => {
resolve(allValues)
})
},
/* --- throw --- */
/** not a function */
throwNotFunction(name) {
return `${name} 未定义或不是一个函数`
},
/** not a array */
throwNotArray(name) {
return `${name} 未定义或不是一个数组`
}
}
}

View File

@ -52,10 +52,13 @@ export const JVxeTableMixin = {
rowNum = 1
console.warn('由于你没有在 data 中定义 addDefaultRowNum addDefaultRowNum 不是数字所以默认添加一条空数据如果不想默认添加空数据请将定义 addDefaultRowNum 0')
}
//update-begin-author:taoyan date:20210315 for: 一对多jvex 默认几行不好使了 LOWCOD-1349
this.eachAllTable((item) => {
item.addRows()
//item.add(rowNum)
setTimeout(()=>{
item.addRows()
}, 30)
})
//update-end-author:taoyan date:20210315 for: 一对多jvex 默认几行不好使了 LOWCOD-1349
if (typeof this.addAfter === 'function') this.addAfter(this.model)
this.edit({})
},

View File

@ -0,0 +1,181 @@
import { VALIDATE_FAILED, getRefPromise, validateFormAndTables,validateFormModelAndTables} from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
import { httpAction, getAction } from '@/api/manage'
export const JVxeTableModelMixin = {
data() {
return {
title: '操作',
visible: false,
confirmLoading: false,
scrolling: true,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 18 }
}
}
},
methods: {
/** 获取所有的JVxeTable实例 */
getAllTable() {
if (!(this.refKeys instanceof Array)) {
throw this.throwNotArray('refKeys')
}
let values = this.refKeys.map(key => getRefPromise(this, key))
return Promise.all(values)
},
/** 遍历所有的JVxeTable实例 */
eachAllTable(callback) {
// 开始遍历
this.getAllTable().then(tables => {
console.log("tables",tables)
tables.forEach((item, index) => {
if (typeof callback === 'function') {
callback(item, index)
}
})
})
},
/** 当点击新增按钮时调用此方法 */
add() {
if (typeof this.addBefore === 'function') this.addBefore()
// 默认新增空数据
let rowNum = this.addDefaultRowNum
if (typeof rowNum !== 'number') {
rowNum = 1
console.warn('由于你没有在 data 中定义 addDefaultRowNum addDefaultRowNum 不是数字所以默认添加一条空数据如果不想默认添加空数据请将定义 addDefaultRowNum 0')
}
this.eachAllTable((item) => {
//update-begin-author:taoyan date:20210315 for: 一对多jvex 默认几行不好使了 LOWCOD-1349
setTimeout(()=>{
item.addRows()
}, 30)
//update-end-author:taoyan date:20210315 for: 一对多jvex 默认几行不好使了 LOWCOD-1349
})
if (typeof this.addAfter === 'function') this.addAfter(this.model)
this.edit(this.model)
},
/** 当点击了编辑(修改)按钮时调用此方法 */
edit(record) {
if (typeof this.editBefore === 'function') this.editBefore(record)
this.visible = true
this.activeKey = this.refKeys[0]
this.$refs.form.resetFields()
this.model = Object.assign({}, record)
if (typeof this.editAfter === 'function') this.editAfter(this.model)
},
/** 关闭弹窗并将所有JVxeTable实例回归到初始状态 */
close() {
this.visible = false
this.eachAllTable((item) => {
item._remove()
})
this.$emit('close')
},
/** 查询某个tab的数据 */
requestSubTableData(url, params, tab, success) {
tab.loading = true
getAction(url, params).then(res => {
let { result } = res
let dataSource = []
if (result) {
if (Array.isArray(result)) {
dataSource = result
} else if (Array.isArray(result.records)) {
dataSource = result.records
}
}
tab.dataSource = dataSource
typeof success === 'function' ? success(res) : ''
}).finally(() => {
tab.loading = false
})
},
/** 发起请求,自动判断是执行新增还是修改操作 */
request(formData) {
let url = this.url.add, method = 'post'
if (this.model.id) {
url = this.url.edit
method = 'put'
}
this.confirmLoading = true
console.log("formData===>",formData);
httpAction(url, formData, method).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
},
/* --- handle 事件 --- */
/** ATab 选项卡切换事件 */
handleChangeTabs(key) {
// 自动重置scrollTop状态防止出现白屏
getRefPromise(this, key).then(vxeTable => {
vxeTable.resetScrollTop()
})
},
/** 关闭按钮点击事件 */
handleCancel() {
this.close()
},
/** 确定按钮点击事件 */
handleOk() {
/** 触发表单验证 */
this.getAllTable().then(tables => {
/** 一次性验证主表和所有的次表 */
return validateFormModelAndTables(this.$refs.form,this.model, tables)
}).then(allValues => {
/** 一次性验证一对一的所有子表 */
return this.validateSubForm(allValues)
}).then(allValues => {
if (typeof this.classifyIntoFormData !== 'function') {
throw this.throwNotFunction('classifyIntoFormData')
}
let formData = this.classifyIntoFormData(allValues)
// 发起请求
return this.request(formData)
}).catch(e => {
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
} else {
console.error(e)
}
})
},
//校验所有子表表单
validateSubForm(allValues){
return new Promise((resolve) => {
resolve(allValues)
})
},
/* --- throw --- */
/** not a function */
throwNotFunction(name) {
return `${name} 未定义或不是一个函数`
},
/** not a array */
throwNotArray(name) {
return `${name} 未定义或不是一个数组`
}
}
}

View File

@ -6,15 +6,13 @@
import { filterObj } from '@/utils/util';
import { deleteAction, getAction,downFile,getFileAccessHttpUrl } from '@/api/manage'
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
import store from '@/store'
import {Modal} from 'ant-design-vue'
export const JeecgListMixin = {
data(){
return {
//token header
tokenHeader: {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)},
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
queryParam: {},
/* 数据源 */
@ -62,6 +60,17 @@ export const JeecgListMixin = {
this.initDictConfig();
}
},
computed: {
//token header
tokenHeader(){
let head = {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)}
let tenantid = Vue.ls.get(TENANT_ID)
if(tenantid){
head['tenant-id'] = tenantid
}
return head;
}
},
methods:{
loadData(arg) {
if(!this.url.list){
@ -81,6 +90,8 @@ export const JeecgListMixin = {
if(res.result.total)
{
this.ipagination.total = res.result.total;
}else{
this.ipagination.total = 0;
}
//update-end---author:zhangyafei Date:20201118 for适配不分页的数据列表------------
}
@ -166,6 +177,8 @@ export const JeecgListMixin = {
that.loading = true;
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) {
//重新计算分页问题
that.reCalculatePage(that.selectedRowKeys.length)
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
@ -187,6 +200,8 @@ export const JeecgListMixin = {
var that = this;
deleteAction(that.url.delete, {id: id}).then((res) => {
if (res.success) {
//重新计算分页问题
that.reCalculatePage(1)
that.$message.success(res.message);
that.loadData();
} else {
@ -194,6 +209,17 @@ export const JeecgListMixin = {
}
});
},
reCalculatePage(count){
//总数量-count
let total=this.ipagination.total-count;
//获取删除后的分页数
let currentIndex=Math.ceil(total/this.ipagination.pageSize);
//删除后的分页数<所在当前页
if(currentIndex<this.ipagination.current){
this.ipagination.current=currentIndex;
}
console.log('currentIndex',currentIndex)
},
handleEdit: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "编辑";
@ -207,6 +233,7 @@ export const JeecgListMixin = {
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
console.log(pagination)
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
@ -224,6 +251,8 @@ export const JeecgListMixin = {
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
//清空列表选中
this.onClearSelected()
},
handleDetail:function(record){
this.$refs.modalForm.edit(record);
@ -278,8 +307,7 @@ export const JeecgListMixin = {
let href = window._CONFIG['domianURL'] + fileUrl
this.$warning({
title: message,
content: (
<div>
content: (<div>
<span>{msg}</span><br/>
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
</div>

View File

@ -155,6 +155,8 @@ const user = {
commit('SET_TOKEN', '')
commit('SET_PERMISSIONLIST', [])
Vue.ls.remove(ACCESS_TOKEN)
Vue.ls.remove(USER_INFO)
Vue.ls.remove(USER_NAME)
Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
Vue.ls.remove(CACHE_INCLUDED_ROUTES)
//console.log('logoutToken: '+ logoutToken)

View File

@ -21,7 +21,6 @@ export const TENANT_ID = 'TENANT_ID'
export const ONL_AUTH_FIELDS = 'ONL_AUTH_FIELDS'
//路由缓存问题关闭了tab页时再打开就不刷新 #842
export const CACHE_INCLUDED_ROUTES = 'CACHE_INCLUDED_ROUTES'
export const CONTENT_WIDTH_TYPE = {
Fluid: 'Fluid',
Fixed: 'Fixed'

View File

@ -17,7 +17,8 @@ const FormTypes = {
radio:'radio',
checkbox_meta:"checkbox_meta",
input_pop:'input_pop',
sel_depart: 'sel_depart',
sel_user: 'sel_user',
slot: 'slot',
hidden: 'hidden'
}
@ -75,6 +76,36 @@ export function validateFormAndTables(form, cases) {
return Promise.reject(error)
})
}
/**
* 一次性验证主表单和所有的次表单(新版本)
* @param form 主表单 form 对象
* @param cases 接收一个数组每项都是一个JEditableTable实例
* @returns {Promise<any>}
* @author sunjianlei
*/
export function validateFormModelAndTables(form,values, cases) {
if (!(form && typeof form.validate === 'function')) {
throw `form 参数需要的是一个form对象而传入的却是${typeof form}`
}
let options = {}
return new Promise((resolve, reject) => {
// 验证主表表单
form.validate((valid,obj) => {
valid ?resolve(values):reject({ error: VALIDATE_NO_PASSED })
})
}).then(values => {
Object.assign(options, { formValue: values })
// 验证所有子表的表单
return validateTables(cases)
}).then(all => {
Object.assign(options, { tablesValue: all })
return Promise.resolve(options)
}).catch(error => {
return Promise.reject(error)
})
}
/**

View File

@ -9,10 +9,10 @@ export function disabledAuthFilter(code,formData) {
}
function nodeDisabledAuth(code,formData){
console.log("页面权限禁用--NODE--开始");
//console.log("页面权限禁用--NODE--开始");
let permissionList = [];
try {
console.log("页面权限禁用--NODE--开始",formData);
//console.log("页面权限禁用--NODE--开始",formData);
if (formData) {
let bpmList = formData.permissionList;
permissionList = bpmList.filter(item=>item.type=='2')
@ -53,7 +53,7 @@ function nodeDisabledAuth(code,formData){
}
function globalDisabledAuth(code){
console.log("全局页面禁用权限--Global--开始");
//console.log("全局页面禁用权限--Global--开始");
let permissionList = [];
let allPermissionList = [];
@ -106,7 +106,7 @@ function globalDisabledAuth(code){
}else{
for (let item2 of permissionList) {
if(code === item2.action){
console.log("全局页面权限解除禁用--Global--生效");
//console.log("全局页面权限解除禁用--Global--生效");
gFlag = false;
}
}
@ -206,6 +206,37 @@ export function getNoAuthCols(pre){
return cols;
}
/**
* 将Online的行编辑按钮权限添加至本地存储
*/
export function addOnlineBtAuth2Storage(pre, authList){
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
let newAuthList = allAuthList.filter(item=>{
if(!item.action){
return true
}
return item.action.indexOf(pre)<0
})
if(authList && authList.length>0){
for(let item of authList){
newAuthList.push({
action: pre+item,
type:1,
status:1
})
}
let temp = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
let newArr = temp.filter(item=>{
if(!item.action){
return true
}
return item.action.indexOf(pre)<0 || authList.indexOf(item.action.replace(pre, ''))<0
})
sessionStorage.setItem(USER_AUTH, JSON.stringify(newArr))
}
sessionStorage.setItem(SYS_BUTTON_AUTH, JSON.stringify(newAuthList))
}
/**

View File

@ -5,7 +5,7 @@ const hasPermission = {
//console.log(options);
Vue.directive('has', {
inserted: (el, binding, vnode)=>{
console.log("页面权限控制----");
//console.log("页面权限控制----");
//console.time()
//节点权限处理,如果命中则不进行全局权限处理
if(!filterNodePermission(el, binding, vnode)){
@ -68,7 +68,7 @@ export function filterNodePermission(el, binding, vnode) {
* 全局权限控制
*/
export function filterGlobalPermission(el, binding, vnode) {
console.log("全局页面权限--Global--");
//console.log("全局页面权限--Global--");
let permissionList = [];
let allPermissionList = [];
@ -108,6 +108,7 @@ export function filterGlobalPermission(el, binding, vnode) {
}
let permissions = [];
for (let item of permissionList) {
//权限策略1显示2禁用
if(item.type != '2'){
//update--begin--autor:wangshuai-----date:20200729------for按钮权限授权标识的提示信息是多个用逗号分隔逻辑处理 gitee#I1OUGU-------
if(item.action){

View File

@ -22,7 +22,6 @@ const service = axios.create({
const err = (error) => {
if (error.response) {
let that=this;
let data = error.response.data
const token = Vue.ls.get(ACCESS_TOKEN)
console.log("------异常响应------",token)
@ -105,7 +104,7 @@ service.interceptors.request.use(config => {
if (!tenantid) {
tenantid = 0;
}
config.headers[ 'tenant_id' ] = tenantid
config.headers[ 'tenant-id' ] = tenantid
//update-end-author:taoyan date:2020707 for:多租户
if(config.method=='get'){
if(config.url.indexOf("sys/dict/getDictItems")<0){

View File

@ -0,0 +1,110 @@
const validateMobile = (rule, value, callback) => {
let reg = /^1(3|4|5|7|8)\d{9}$/
if (!reg.test(value)) {
callback('请输入正确手机号')
} else {
callback()
}
}
const validateEn = (rule, value, callback) => {
let reg = /^[_a-zA-Z0-9]+$/
let reg2 = /^.{4,18}$/
// 长度为6到18个字符
if (value !== '' && !reg.test(value)) {
callback('只允许字母数字下划线')
} else if (value !== '' && !reg2.test(value)) {
callback('长度6到18个字符')
} else {
callback()
}
}
export const rules = {
mobile: [{
required: true,
message: '请输入手机号',
trigger: 'blur'
}, { validator: validateMobile, trigger: 'blur' }],
userName: [{
required: true, message: '请输入用户名', trigger: 'blur'
}, { validator: validateEn }],
email: [
{ required: false, type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
],
// 验证自然数
naturalNumber: /^(([0-9]*[1-9][0-9]*)|(0+))$/,
naturalNumberMsg: '请输入自然数',
// 英文
english: /^.[A-Za-z]+$/,
englishMsg: '请输入英文字符',
// 座机
telephone: /^\d{3}-\d{7,8}|\d{4}-\d{7,8}$/,
telephoneMsg: '请输入正确的座机号',
// 银行卡号码
bankCard: /^[1-9]\d{9,19}$/,
bankCardMsg: '请输入正确的银行卡号码',
// 证件号码
IDNumber: /^[a-z0-9A-Z]{0,50}$/,
IDNumberMsg: '请输入正确的证件号码',
// 身份证号码,包括15位和18位的
IDCard: /(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{7}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/,
IDCardMsg: '请输入正确的身份证号码',
// QQ号码
qq: /^[1-9]\d{4,11}$/,
qqMsg: '请输入正确的QQ号码',
// 网址, 仅支持http和https开头的
url: /^(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?$/,
urlMsg: '请输入以http和https开头的网址',
// 0到20位的英文字符和数字
enNum0to20: /^[a-z0-9A-Z]{0,20}$/,
enNum0to20Msg: '请输入20位以内的英文字符和数字',
// 2到100位的中英文字符和空格
cnEnSpace2to100: /^[a-zA-Z\u4E00-\u9FA5\s*]{2,100}$/,
cnEnSpace2to100Msg: '请输入2到100位的中英文字符和空格',
// 数字和换行符
numLinefeed: /^[0-9\n*]+$/,
numLinefeedMsg: '请输入数字和换行符',
// 255位以内的字符
char0to255: /^.{0,255}$/,
char0to255Msg: '请输入255位以内的字符',
required: function(min, max) {
let rule = [{ required: true, message: '', trigger: 'blur' }]
if (min) {
let r = { min: min, message: '最小长度' + min + '位字符' }
rule.push(r)
}
if (max) {
let m = { max: max, message: '最大长度' + max + '位字符' }
rule.push(m)
}
return rule
},
select: function() {
let rule = [{ required: true, message: '', trigger: 'change' }]
return rule
},
checked: function(min, max) {
let rule = [{ required: true, type: 'array', message: '', trigger: 'change' }]
if (min) {
let r = { type: 'array', min: min, message: '最少选择' + min + '项' }
rule.push(r)
}
if (max) {
let m = { type: 'array', max: max, message: '最多选择' + max + '项' }
rule.push(m)
}
return rule
}
}
/**
* @description 排序值验证排序值不可以大于255
*/
export const validateOrder = function(rule, value, callback) {
if (parseInt(value) > 255) {
return callback(new Error('排序值不可以大于255'))
} else {
callback()
}
}

View File

@ -539,4 +539,24 @@ export function getVmParentByName(vm, name) {
*/
export function neverNull(value, def) {
return value == null ? (neverNull(def, '')) : value
}
/**
* 根据元素值移除数组中的一个元素
* @param array 数组
* @param prod 属性名
* @param value 属性值
* @returns {string}
*/
export function removeArrayElement(array, prod, value) {
let index = -1
for(let i = 0;i<array.length;i++){
if(array[i][prod] == value){
index = i;
break;
}
}
if(index>=0){
array.splice(index, 1);
}
}

View File

@ -8,6 +8,10 @@
<a-tab-pane tab="高级示例" key="2" forceRender>
<j-vxe-demo2/>
</a-tab-pane>
<a-tab-pane tab="联动示例" key="3" forceRender>
<j-vxe-demo3/>
</a-tab-pane>
</a-tabs>
@ -17,10 +21,11 @@
<script>
import JVxeDemo1 from '@views/jeecg/JVxeDemo/JVxeDemo1'
import JVxeDemo2 from '@views/jeecg/JVxeDemo/JVxeDemo2'
import JVxeDemo3 from '@views/jeecg/JVxeDemo/JVxeDemo3'
export default {
name: 'JVXETableDemo',
components: {JVxeDemo2, JVxeDemo1},
components: {JVxeDemo2, JVxeDemo1,JVxeDemo3},
data() {
return {}
},

View File

@ -134,7 +134,7 @@
title: '下拉框_多选',
key: 'select_multiple',
type: JVXETypes.selectMultiple,
width: '180px',
width: '205px',
options: [
{title: 'String', value: 'string'},
{title: 'Integer', value: 'int'},

View File

@ -0,0 +1,132 @@
<template>
<j-vxe-table
ref="vTable"
toolbar
row-number
row-selection
keep-source
:height="484"
:dataSource="dataSource"
:columns="columns"
@valueChange="handleValueChange"
/>
</template>
<script>
import moment from 'moment'
import { randomNumber, randomUUID } from '@/utils/util'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
export default {
name: 'JVxeDemo2',
data() {
return {
columns: [
{
title: '/直辖市/自治区',
key: 's1',
type: JVXETypes.select,
width: '240px',
options: [],
placeholder: '请选择${title}'
},
{
title: '市',
key: 's2',
type: JVXETypes.select,
width: '240px',
options: [],
placeholder: '请选择${title}'
},
{
title: '/',
key: 's3',
type: JVXETypes.select,
width: '240px',
options: [],
placeholder: '请选择${title}'
}
],
dataSource: [],
mockData: [
{ text: '北京市', value: '110000', parent: null },
{ text: '天津市', value: '120000', parent: null },
{ text: '河北省', value: '130000', parent: null },
{ text: '上海市', value: '310000', parent: null },
{ text: '北京市', value: '110100', parent: '110000' },
{ text: '天津市市', value: '120100', parent: '120000' },
{ text: '石家庄市', value: '130100', parent: '130000' },
{ text: '唐山市', value: '130200', parent: '130000' },
{ text: '秦皇岛市', value: '130300', parent: '130000' },
{ text: '上海市', value: '310100', parent: '310000' },
{ text: '东城区', value: '110101', parent: '110100' },
{ text: '西城区', value: '110102', parent: '110100' },
{ text: '朝阳区', value: '110105', parent: '110100' },
{ text: '和平区', value: '120101', parent: '120100' },
{ text: '河东区', value: '120102', parent: '120100' },
{ text: '河西区', value: '120103', parent: '120100' },
{ text: '黄浦区', value: '310101', parent: '310100' },
{ text: '徐汇区', value: '310104', parent: '310100' },
{ text: '长宁区', value: '310105', parent: '310100' },
{ text: '长安区', value: '130102', parent: '130100' },
{ text: '桥西区', value: '130104', parent: '130100' },
{ text: '新华区', value: '130105', parent: '130100' },
{ text: '路南区', value: '130202', parent: '130200' },
{ text: '路北区', value: '130203', parent: '130200' },
{ text: '古冶区', value: '130204', parent: '130200' },
{ text: '海港区', value: '130302', parent: '130300' },
{ text: '山海关区', value: '130303', parent: '130300' },
{ text: '北戴河区', value: '130304', parent: '130300' },
]
}
},
created() {
// 初始化数据
this.columns[0].options = this.request(null)
},
methods: {
request(parentId) {
return this.mockData.filter(i => i.parent === parentId)
},
/** 当选项被改变时,联动其他组件 */
handleValueChange(event) {
const { type, row, column, value, target } = event
console.log("event",event)
if (type === JVXETypes.select) {
// 第一列
if (column.key === 's1') {
// 设置第二列的 options
console.log('this.request(value)::',this.request(value))
target.$refs.vxe.columns[3].options = this.request(value)
// 清空后两列的数据
target.setValues([{
rowKey: row.id,
values: { s2: '', s3: '' }
}])
target.$refs.vxe.columns[4].options = []
} else
// 第二列
if (column.key === 's2') {
target.$refs.vxe.columns[4].options = this.request(value)
target.setValues([{
rowKey: row.id,
values: { s3: '' }
}])
}
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,215 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :md="6" :sm="24">
<a-form-item label="订单号">
<a-input placeholder="请输入订单号" v-model="queryParam.orderCode"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-form-item label="订单类型">
<a-select placeholder="请输入订单类型" v-model="queryParam.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
<span>已选择</span>
<a style="font-weight: 600">
{{ selectedRowKeys.length }}
</a>
<span>项</span>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<jeecg-order-modal-for-j-vextable ref="modalForm" @ok="modalFormOk"></jeecg-order-modal-for-j-vextable>
</a-card>
</template>
<script>
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import JeecgOrderModalForJVextable from './modules/JeecgOrderModalForJVexTable'
export default {
name: 'JeecgOrderMainListForJVxeTable',
mixins: [JeecgListMixin],
components: {
JeecgOrderModalForJVextable
},
data() {
return {
description: '订单管理页面',
// 请求参数
url: {
list: '/test/jeecgOrderMain/list',
delete: '/test/jeecgOrderMain/delete',
deleteBatch: '/test/jeecgOrderMain/deleteBatch'
},
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '订单号',
align: 'center',
dataIndex: 'orderCode'
},
{
title: '订单类型',
align: 'center',
dataIndex: 'ctype',
customRender: (text) => {
let re = ''
if (text === '1') {
re = '国内订单'
} else if (text === '2') {
re = '国际订单'
}
return re
}
},
{
title: '订单日期',
align: 'center',
dataIndex: 'orderDate'
},
{
title: '订单金额',
align: 'center',
dataIndex: 'orderMoney'
},
{
title: '订单备注',
align: 'center',
dataIndex: 'content'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
]
}
},
methods: {
initDictConfig() {
}
}
}
</script>
<style scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
</style>

View File

@ -56,6 +56,7 @@
placeholder="请做出你的选择"
v-model="formData.asyncSelectValue"
dict="sys_depart,depart_name,id"
:pageSize="6"
:async="true">
</j-search-select-tag>
</a-form-item>
@ -130,7 +131,7 @@
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择职务">
<j-select-position :buttons="false" :disabled="true" v-model="formData.selectPosition" />
<j-select-position :buttons="false" v-model="formData.selectPosition" />
</a-form-item>
</a-col>
<a-col :span="12">选中值:{{ formData.selectPosition}}</a-col>
@ -362,10 +363,10 @@
<a-col :span="12">
<a-form-item label="特殊查询组件">
<a-row>
<a-col :span="16">
<a-col :span="15">
<j-input v-model="formData.jInput" :type="jInput.type"/>
</a-col>
<a-col :span="3" style="text-align: right;" >查询类型:</a-col>
<a-col :span="4" style="text-align: right;" >查询类型:</a-col>
<a-col :span="5">
<a-select v-model="jInput.type" :options="jInput.options"></a-select>
</a-col>

View File

@ -1,11 +1,14 @@
<template>
<a-card :bordered="false">
<a-form @submit="handleSubmit" :form="form">
<a-row>
<a-col :md="24" :sm="24">
<a-form-item label="Note" :labelCol="{ span: 7 }" :wrapperCol="{ span: 15 }">
<a-input v-decorator="['note',{rules: [{ required: true, message: 'Please input your note!' }]}]"/>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :md="24" :sm="24">
<a-form-item label="Gender" :labelCol="{ span: 7 }" :wrapperCol="{ span: 15 }">
<a-select v-decorator="['gender',{rules: [{ required: true, message: 'Please select your gender!' }]}]" placeholder="Select a option and change input text above" @change="this.handleSelectChange">
@ -14,11 +17,14 @@
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :md="24" :sm="24">
<a-form-item label="Gender" :labelCol="{ span: 7 }" :wrapperCol="{ span: 15 }">
<a-cascader :options="areaOptions" @change="onChange" :showSearch="{filter}" placeholder="Please select" />
</a-form-item>
</a-col>
</a-row>
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-col :md="24" :sm="24">
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">

View File

@ -7,80 +7,47 @@
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="姓名"
hasFeedback >
<a-input placeholder="请输入姓名" v-decorator="['name', {}]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="关键词"
hasFeedback >
<a-input placeholder="请输入关键词" v-decorator="['keyWord', {}]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="打卡时间"
hasFeedback >
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" v-decorator="[ 'punchTime', {}]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="性别">
<!-- <a-select v-decorator="['sex', {}]" placeholder="请选择性别">
<a-select-option value="">请选择</a-select-option>
<a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option>
</a-select>-->
<j-dict-select-tag type="radio" v-decorator="['sex', {}]" :trigger-change="true" dictCode="sex"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="年龄"
hasFeedback >
<a-input placeholder="请输入年龄" v-decorator="['age', {}]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="生日"
hasFeedback >
<a-date-picker v-decorator="[ 'birthday', {}]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="邮箱"
hasFeedback >
<a-input placeholder="请输入邮箱" v-decorator="['email', {}]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="个人简介"
hasFeedback >
<a-input placeholder="请输入个人简介" v-decorator="['content', {}]" />
</a-form-item>
</a-form>
<a-form-model ref="form" :label-col="labelCol" :wrapper-col="wrapperCol" :model="model" :rules="validatorRules">
<a-form-model-item label="姓名" required prop="name" hasFeedback>
<a-input v-model="model.name" placeholder="请输入姓名"/>
</a-form-model-item>
<a-form-model-item label="关键词" prop="keyWord" hasFeedback>
<a-input v-model="model.keyWord" placeholder="请输入关键词"/>
</a-form-model-item>
<a-form-model-item label="打卡时间" prop="punchTime" hasFeedback>
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model="model.punchTime" />
</a-form-model-item>
<a-form-model-item label="性别" prop="sex" hasFeedback>
<j-dict-select-tag type="radio" v-model="model.sex" :trigger-change="true" dictCode="sex"/>
</a-form-model-item>
<a-form-model-item label="年龄" prop="age" hasFeedback>
<a-input placeholder="请输入年龄" v-model="model.age"/>
</a-form-model-item>
<a-form-model-item label="生日" prop="age" hasFeedback>
<a-date-picker valueFormat="YYYY-MM-DD" v-model="model.birthday"/>
</a-form-model-item>
<a-form-model-item label="邮箱" prop="email" hasFeedback >
<a-input placeholder="请输入邮箱" v-model="model.email"/>
</a-form-model-item>
<a-form-model-item label="个人简介" prop="content" hasFeedback>
<a-input type="textarea" placeholder="请输入个人简介" v-model="model.content"/>
</a-form-model-item>
</a-form-model>
</a-spin>
</a-modal>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "JeecgDemoModal",
@ -89,18 +56,28 @@
title:"操作",
visible: false,
model: {},
layout: {
labelCol: { span: 3 },
wrapperCol: { span: 14 },
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
sm: { span: 3 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
name: [
{ required: true, message: '请输入姓名!' },
{ min: 2, max: 30, message: '长度在 2 30 个字符', trigger: 'blur' }
],
email: [
{ required: false, type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
]
},
url: {
add: "/test/jeecgDemo/add",
@ -115,26 +92,19 @@
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,'name','keyWord','sex','age','email','content'))
//时间格式化
this.form.setFieldsValue({punchTime:this.model.punchTime?moment(this.model.punchTime,'YYYY-MM-DD HH:mm:ss'):null})
this.form.setFieldsValue({birthday:this.model.birthday?moment(this.model.birthday):null})
});
},
close () {
this.$refs.form.resetFields();
this.$emit('close');
this.visible = false;
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -145,13 +115,7 @@
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
formData.punchTime = formData.punchTime?formData.punchTime.format('YYYY-MM-DD HH:mm:ss'):null;
formData.birthday = formData.birthday?formData.birthday.format():null;
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -162,17 +126,12 @@
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel () {
this.close()
},
}
}
}
</script>

View File

@ -63,7 +63,7 @@
<a-table :columns="columns" :dataSource="data" :pagination="false" size="middle">
<template v-for="(col, i) in ['name', 'workId', 'department']" :slot="col" slot-scope="text, record, index">
<a-tooltip title="必填项" :defaultVisible="false" overlayStyle="{ color: 'red' }">
<a-tooltip title="必填项" :defaultVisible="false" :overlayStyle="{ color: 'red' }">
<a-input :key="col" v-if="record.editable" style="margin: -5px 0" :value="text" :placeholder="columns[i].title" @change="e => handlerRowChange(e.target.value, record.key, col)"/>
<template v-else>{{ text }}</template>
</a-tooltip>

View File

@ -8,53 +8,38 @@
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :label-col="labelCol" :wrapper-col="wrapperCol" :model="orderMainModel" :rules="validatorRules">
<!-- 主表单区域 -->
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单号">
<a-input placeholder="请输入订单号" v-decorator="['orderCode', {rules: [{ required: true, message: '请输入订单号!' }]}]" />
</a-form-item>
<a-form-model-item label="订单号" required prop="orderCode">
<a-input v-model="orderMainModel.orderCode" placeholder="请输入订单号"/>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单类型">
<a-select placeholder="请输入订单类型" v-decorator="['ctype',{}]">
<a-form-model-item label="订单类型" prop="ctype">
<a-select placeholder="请选择订单类型" v-model="orderMainModel.ctype" >
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单日期">
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" v-decorator="[ 'orderDate',{}]"/>
</a-form-item>
<a-form-model-item label="订单日期" prop="orderDate">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" v-model="orderMainModel.orderDate"/>
</a-form-model-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="16">
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单金额">
<a-input-number style="width: 200px" v-decorator="[ 'orderMoney', {}]" />
</a-form-item>
<a-form-model-item label="订单金额" prop="orderMoney">
<a-input-number style="width: 200px" v-model="orderMainModel.orderMoney"/>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单备注">
<a-input placeholder="请输入订单备注" v-decorator="['content', {}]" />
</a-form-item>
<a-form-model-item label="订单备注" prop="content">
<a-input placeholder="请输入订单备注" v-model="orderMainModel.content" />
</a-form-model-item>
</a-col>
</a-row>
@ -65,47 +50,49 @@
<a-row type="flex" style="margin-bottom:10px" :gutter="16">
<a-col :span="5">客户名</a-col>
<a-col :span="5">性别</a-col>
<a-col :span="5">身份证号码</a-col>
<a-col :span="5">手机号</a-col>
<a-col :span="4">操作</a-col>
<a-col :span="6">身份证号码</a-col>
<a-col :span="6">手机号</a-col>
<a-col :span="2">操作</a-col>
</a-row>
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in orderMainModel.jeecgOrderCustomerList" :key="index">
<a-col :span="6" style="display: none">
<a-form-item>
<a-input placeholder="id" v-decorator="['jeecgOrderCustomerList['+index+'].id', {'initialValue':item.id}]" />
</a-form-item>
<a-form-model-item>
<a-input placeholder="id" v-model="item.id" />
</a-form-model-item>
</a-col>
<a-col :span="5">
<a-form-item>
<a-input placeholder="客户名" v-decorator="['jeecgOrderCustomerList['+index+'].name', {'initialValue':item.name,rules: [{ required: true, message: '请输入用户名!' }]}]" />
</a-form-item>
<a-form-model-item>
<a-input placeholder="客户名" v-model="item.name" />
</a-form-model-item>
</a-col>
<a-col :span="5">
<a-form-item>
<a-select placeholder="性别" v-decorator="['jeecgOrderCustomerList['+index+'].sex', {'initialValue':item.sex}]">
<a-form-model-item>
<a-select placeholder="性别" v-model="item.sex" >
<a-select-option value="1">男</a-select-option>
<a-select-option value="2">女</a-select-option>
</a-select>
</a-form-item>
</a-form-model-item>
</a-col>
<a-col :span="5">
<a-form-item>
<a-input placeholder="身份证号" v-decorator="['jeecgOrderCustomerList['+index+'].idcard', {'initialValue':item.idcard,rules: [{ pattern: '^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|[xX])$', message: '身份证号格式不对!' }]}]"/>
</a-form-item>
<a-col :span="6">
<a-form-model-item :prop="'jeecgOrderCustomerList.' + index + '.idcard'" :rules="[{required: true,message: '请输入身份证号',trigger: 'blur'},{ pattern: rules.IDCard, message: '身份证号格式不对!' }]">
<a-input placeholder="身份证号" v-model="item.idcard" />
</a-form-model-item>
</a-col>
<a-col :span="5">
<a-form-item>
<a-input placeholder="手机号" v-decorator="['jeecgOrderCustomerList['+index+'].telphone', {'initialValue':item.telphone,rules: [{ pattern: '^1(3|4|5|7|8)\\d{9}$', message: '手机号格式不对!' }]}]"/>
</a-form-item>
<a-col :span="6">
<a-form-model-item :prop="'jeecgOrderCustomerList.' + index + '.telphone'" :rules="rules.mobile">
<a-input placeholder="手机号" v-model="item.telphone"/>
</a-form-model-item>
</a-col>
<a-col :span="4">
<a-form-item>
<a-button @click="addRowCustom" icon="plus"></a-button>&nbsp;
<a-button @click="delRowCustom(index)" icon="minus"></a-button>
</a-form-item>
<a-col :span="2">
<a-form-model-item>
<a-icon type="minus-circle" @click="delRowCustom(index)" style="fontSize :20px"/>
</a-form-model-item>
</a-col>
</a-row>
<a-button type="dashed" style="width: 98%;margin-top: 10px" @click="addRowCustom">
<a-icon type="plus" /> 添加客户信息
</a-button>
</div>
</a-tab-pane>
@ -118,32 +105,34 @@
</a-row>
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in orderMainModel.jeecgOrderTicketList" :key="index">
<a-col :span="6" style="display: none">
<a-form-item>
<a-input placeholder="id" v-decorator="['jeecgOrderTicketList['+index+'].id', {'initialValue':item.id}]" />
</a-form-item>
<a-form-model-item>
<a-input placeholder="id" v-model="item.id" />
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-form-item>
<a-input placeholder="航班号" v-decorator="['jeecgOrderTicketList['+index+'].ticketCode', {'initialValue':item.ticketCode,rules: [{ required: true, message: '请输入航班号!' }]}]" />
</a-form-item>
<a-form-model-item :prop="'jeecgOrderTicketList.' + index + '.ticketCode'" :rules="{required: true,message: '请输入航班号',trigger: 'blur'}">
<a-input placeholder="航班号" v-model="item.ticketCode"/>
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-form-item>
<j-date placeholder="航班时间" :trigger-change="true" v-decorator="['jeecgOrderTicketList['+index+'].tickectDate', {'initialValue':item.tickectDate}]"></j-date>
</a-form-item>
<a-form-model-item>
<a-date-picker placeholder="航班时间" valueFormat="YYYY-MM-DD" v-model="item.tickectDate" />
</a-form-model-item>
</a-col>
<a-col :span="6">
<a-form-item>
<a-button @click="addRowTicket" icon="plus"></a-button>&nbsp;
<a-button @click="delRowTicket(index)" icon="minus"></a-button>
</a-form-item>
<a-form-model-item>
<a-icon type="minus-circle" @click="delRowTicket(index)" style="fontSize :20px"/>
</a-form-model-item>
</a-col>
</a-row>
<a-button type="dashed" style="width: 98%;margin-top: 10px" @click="addRowTicket">
<a-icon type="plus" /> 添加机票信息
</a-button>
</div>
</a-tab-pane>
</a-tabs>
</a-form>
</a-form-model>
</a-spin>
</a-modal>
</template>
@ -151,9 +140,6 @@
<script>
import { httpAction,getAction } from '@/api/manage'
import JDate from '@/components/jeecg/JDate'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "JeecgOrderMainModal",
components: {
@ -163,8 +149,10 @@
return {
title:"操作",
visible: false,
orderMainModel: {jeecgOrderCustomerList: [{}],
jeecgOrderTicketList: [{}]},
orderMainModel: {
jeecgOrderCustomerList: [{}],
jeecgOrderTicketList: [{}]
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
@ -173,10 +161,11 @@
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
orderCode: [
{ required: true, message: '订单号不能为空', trigger: 'blur' }
]
},
url: {
add: "/test/jeecgOrderMain/add",
@ -193,10 +182,10 @@
this.edit({});
},
edit (record) {
this.form.resetFields();
this.orderMainModel = Object.assign({}, record);
this.orderMainModel.jeecgOrderCustomerList = [{}];
this.orderMainModel.jeecgOrderTicketList = [{}];
this.orderMainModel = Object.assign({
jeecgOrderCustomerList: [{}],
jeecgOrderTicketList: [{}]
}, record);
//--------------------------------------------------------
//初始化明细表数据
console.log(this.orderMainModel.id)
@ -217,12 +206,7 @@
}
})
}
//--------------------------------------------------------
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.orderMainModel,'orderCode','ctype','orderMoney','content'))
this.form.setFieldsValue({orderDate:this.orderMainModel.orderDate?moment(this.orderMainModel.orderDate):null}) //时间格式化
});
},
close () {
this.$emit('close');
@ -231,8 +215,8 @@
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -241,18 +225,9 @@
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
method = 'put';
}
let orderMainData = Object.assign(this.orderMainModel, values);
//时间格式化
orderMainData.orderDate = orderMainData.orderDate?orderMainData.orderDate.format('YYYY-MM-DD HH:mm:ss'):null;
let formData = {
...orderMainData,
jeecgOrderCustomerList: orderMainData.jeecgOrderCustomerList,
jeecgOrderTicketList: orderMainData.jeecgOrderTicketList
}
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
httpAction(httpurl,this.orderMainModel,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
@ -276,9 +251,8 @@
},
delRowCustom (index) {
console.log(index)
let all = this.form.getFieldsValue()
let all = this.orderMainModel
all['jeecgOrderCustomerList'].splice(index,1);
this.form.setFieldsValue(all)
this.orderMainModel.jeecgOrderCustomerList.splice(index,1);
this.$forceUpdate();
},
@ -289,9 +263,8 @@
},
delRowTicket (index) {
console.log(index)
let all = this.form.getFieldsValue()
let all = this.orderMainModel
all['jeecgOrderTicketList'].splice(index,1);
this.form.setFieldsValue(all)
this.orderMainModel.jeecgOrderTicketList.splice(index,1);
this.$forceUpdate();
},

View File

@ -9,58 +9,41 @@
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :label-col="labelCol" :wrapper-col="wrapperCol" :model="model" >
<!-- 主表单区域 -->
<a-row class="form-row" :gutter="0">
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单号">
<a-input
placeholder="请输入订单号"
v-decorator="['orderCode', {rules: [{ required: true, message: '请输入订单号!' }]}]"/>
</a-form-item>
<a-form-model-item label="订单号" prop="orderCode" :rules="[{ required: true, message: '请输入订单号!' }]">
<a-input placeholder="请输入订单号" v-model="model.orderCode"/>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单类型">
<a-select placeholder="请选择订单类型" v-decorator="['ctype',{}]">
<a-form-model-item label="订单类型">
<a-select placeholder="请选择订单类型" v-model="model.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单日期">
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" style="width: 100%" v-decorator="[ 'orderDate',{}]"/>
</a-form-item>
<a-form-model-item label="订单日期">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" style="width: 100%" v-model="model.orderDate"/>
</a-form-model-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="0">
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单金额">
<a-input-number placeholder="请输入订单金额" style="width: 100%" v-decorator="[ 'orderMoney', {}]"/>
</a-form-item>
<a-form-model-item label="订单金额">
<a-input-number placeholder="请输入订单金额" style="width: 100%" v-model="model.orderMoney"/>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单备注">
<a-input placeholder="请输入订单备注" v-decorator="['content', {}]"/>
</a-form-item>
<a-form-model-item label="订单备注">
<a-input placeholder="请输入订单备注" v-model="model.content"/>
</a-form-model-item>
</a-col>
</a-row>
</a-form>
</a-form-model>
<!-- 子表单区域 -->
<a-tabs v-model="activeKey" @change="handleChangeTabs">
@ -100,11 +83,9 @@
<script>
import JEditableTable from '@/components/jeecg/JEditableTable'
import { FormTypes, VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables } from '@/utils/JEditableTableUtil'
import { FormTypes, VALIDATE_NO_PASSED, getRefPromise, validateFormModelAndTables } from '@/utils/JEditableTableUtil'
import { httpAction, getAction } from '@/api/manage'
import JDate from '@/components/jeecg/JDate'
import pick from 'lodash.pick'
import moment from 'moment'
export default {
name: 'JeecgOrderModalForJEditableTable',
@ -115,7 +96,6 @@
return {
title: '操作',
visible: false,
form: this.$form.createForm(this),
confirmLoading: false,
model: {},
labelCol: {
@ -235,15 +215,7 @@
edit(record) {
this.visible = true
this.activeKey = '1'
this.form.resetFields()
this.model = Object.assign({}, record)
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'orderCode', 'ctype', 'orderMoney', 'content'))
//时间格式化
this.form.setFieldsValue({ orderDate: this.model.orderDate ? moment(this.model.orderDate) : null })
})
// 加载子表数据
if (this.model.id) {
let params = { id: this.model.id }
@ -259,6 +231,7 @@
editableTables[1].initialize()
})
this.$emit('close')
this.$refs.form.resetFields();
},
/** 查询某个tab的数据 */
requestTableData(url, params, tab) {
@ -286,7 +259,7 @@
validateFields() {
this.getAllTable().then(tables => {
/** 一次性验证主表和所有的次表 */
return validateFormAndTables(this.form, tables)
return validateFormModelAndTables(this.$refs.form,this.model, tables)
}).then(allValues => {
let formData = this.classifyIntoFormData(allValues)
// 发起请求
@ -303,8 +276,6 @@
/** 整理成formData */
classifyIntoFormData(allValues) {
let orderMain = Object.assign(this.model, allValues.formValue)
//时间格式化
orderMain.orderDate = orderMain.orderDate ? orderMain.orderDate.format('YYYY-MM-DD HH:mm:ss') : null
return {
...orderMain, // 展开
jeecgOrderCustomerList: allValues.tablesValue[0].values,

View File

@ -0,0 +1,312 @@
<template>
<a-modal
:title="title"
:width="1200"
:visible="visible"
:destroyOnClose="true"
:maskClosable="false"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<a-form-model ref="form" :label-col="labelCol" :wrapper-col="wrapperCol" :model="model" >
<!-- 主表单区域 -->
<a-row class="form-row" :gutter="0">
<a-col :lg="8">
<a-form-model-item label="订单号" prop="orderCode" :rules="[{ required: true, message: '请输入订单号!' }]">
<a-input placeholder="请输入订单号" v-model="model.orderCode"/>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-model-item label="订单类型">
<a-select placeholder="请选择订单类型" v-model="model.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-model-item label="订单日期">
<a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" style="width: 100%" v-model="model.orderDate"/>
</a-form-model-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="0">
<a-col :lg="8">
<a-form-model-item label="订单金额">
<a-input-number placeholder="请输入订单金额" style="width: 100%" v-model="model.orderMoney"/>
</a-form-model-item>
</a-col>
<a-col :lg="8">
<a-form-model-item label="订单备注">
<a-input placeholder="请输入订单备注" v-model="model.content"/>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
<!-- 子表单区域 -->
<a-tabs v-model="activeKey" @change="handleChangeTabs">
<a-tab-pane tab="客户信息" key="1" :forceRender="true">
<j-vxe-table
ref="editableTable1"
toolbar
row-number
row-selection
keep-source
:height="300"
:loading="table1.loading"
:dataSource="table1.dataSource"
:columns="table1.columns"
style="margin-top: 8px;"/>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="2" :forceRender="true">
<j-vxe-table
ref="editableTable2"
toolbar
row-number
row-selection
keep-source
:height="300"
:loading="table2.loading"
:dataSource="table2.dataSource"
:columns="table2.columns"
style="margin-top: 8px;"/>
</a-tab-pane>
</a-tabs>
</a-spin>
</a-modal>
</template>
<script>
import JEditableTable from '@/components/jeecg/JEditableTable'
import { VALIDATE_FAILED, getRefPromise, validateFormModelAndTables } from '@/components/jeecg/JVxeTable/utils/vxeUtils'
import { httpAction, getAction } from '@/api/manage'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import JDate from '@/components/jeecg/JDate'
export default {
name: 'JeecgOrderModalForJvexTable',
components: {
JDate, JEditableTable
},
data() {
return {
title: '操作',
visible: false,
confirmLoading: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 24 - 6 }
},
activeKey: '1',
// 客户信息
table1: {
loading: false,
dataSource: [],
columns: [
{
title: '客户名',
key: 'name',
width: '24%',
type: JVXETypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [{ required: true, message: '${title}不能为空' }]
},
{
title: '性别',
key: 'sex',
width: '18%',
type: JVXETypes.select,
options: [ // 下拉选项
{ title: '男', value: '1' },
{ title: '女', value: '2' }
],
defaultValue: '',
placeholder: '请选择${title}'
},
{
title: '身份证号',
key: 'idcard',
width: '24%',
type: JVXETypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [{
pattern: '^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|[xX])$',
message: '${title}格式不正确'
}]
},
{
title: '手机号',
key: 'telphone',
width: '24%',
type: JVXETypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [{
pattern: '^1(3|4|5|7|8)\\d{9}$',
message: '${title}格式不正确'
}]
}
]
},
// 机票信息
table2: {
loading: false,
dataSource: [],
columns: [
{
title: '航班号',
key: 'ticketCode',
width: '40%',
type: JVXETypes.input,
defaultValue: '',
placeholder: '请输入${title}',
validateRules: [{ required: true, message: '${title}不能为空' }]
},
{
title: '航班时间',
key: 'tickectDate',
width: '30%',
type: JVXETypes.date,
placeholder: '请选择${title}',
defaultValue: ''
}
]
},
url: {
add: '/test/jeecgOrderMain/add',
edit: '/test/jeecgOrderMain/edit',
orderCustomerList: '/test/jeecgOrderMain/queryOrderCustomerListByMainId',
orderTicketList: '/test/jeecgOrderMain/queryOrderTicketListByMainId'
}
}
},
created() {
},
methods: {
// 获取所有的editableTable实例
getAllTable() {
return Promise.all([
getRefPromise(this, 'editableTable1'),
getRefPromise(this, 'editableTable2')
])
},
add() {
// 默认新增一条数据
this.getAllTable().then(editableTables => {
//editableTables[0].add()
//editableTables[1].add()
})
this.edit({})
},
edit(record) {
this.visible = true
this.activeKey = '1'
this.model = Object.assign({}, record)
// 加载子表数据
if (this.model.id) {
let params = { id: this.model.id }
this.requestTableData(this.url.orderCustomerList, params, this.table1)
this.requestTableData(this.url.orderTicketList, params, this.table2)
}
},
close() {
this.visible = false
this.getAllTable().then(editableTables => {
this.table1.dataSource=[];
this.table2.dataSource=[];
})
this.$emit('close')
},
/** 查询某个tab的数据 */
requestTableData(url, params, tab) {
tab.loading = true
getAction(url, params).then(res => {
tab.dataSource = res.result || []
}).finally(() => {
tab.loading = false
})
},
handleOk() {
this.validateFields()
},
handleCancel() {
this.close()
},
/** ATab 选项卡切换事件 */
handleChangeTabs(key) {
getRefPromise(this, `editableTable${key}`).then(editableTable => {
editableTable.resetScrollTop()
})
},
/** 触发表单验证 */
validateFields() {
this.getAllTable().then(tables => {
/** 一次性验证主表和所有的次表 */
return validateFormModelAndTables(this.$refs.form,this.model, tables)
}).then(allValues => {
let formData = this.classifyIntoFormData(allValues)
// 发起请求
return this.requestAddOrEdit(formData)
}).catch(e => {
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
this.activeKey = e.index == null ? this.activeKey : (e.index + 1).toString()
} else {
console.error(e)
}
})
},
/** 整理成formData */
classifyIntoFormData(allValues) {
let orderMain = Object.assign(this.model, allValues.formValue)
return {
...orderMain, // 展开
jeecgOrderCustomerList: allValues.tablesValue[0].tableData,
jeecgOrderTicketList: allValues.tablesValue[1].tableData
}
},
/** 发起新增或修改的请求 */
requestAddOrEdit(formData) {
let url = this.url.add, method = 'post'
if (this.model.id) {
url = this.url.edit
method = 'put'
}
this.confirmLoading = true
httpAction(url, formData, method).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
}
}
}
</script>
<style scoped>
</style>

View File

@ -11,64 +11,64 @@
<!-- 编辑 -->
<a-spin :spinning="confirmLoading" v-if="editStatus">
<a-form :form="form">
<a-form-item
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="客户姓名"
prop="name"
required
hasFeedback>
<a-input placeholder="请输入客户姓名" v-decorator="['name', {rules: [{ required: true, message: '请输入客户姓名!' }]}]"
:readOnly="disableSubmit"/>
</a-form-item>
<a-form-item
<a-input placeholder="请输入客户姓名" v-model="model.name" :readOnly="disableSubmit"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="性别"
hasFeedback>
<a-select v-decorator="['sex', {}]" placeholder="请选择性别">
<a-select v-model="model.sex" placeholder="请选择性别">
<a-select-option value="1">男性</a-select-option>
<a-select-option value="2">女性</a-select-option>
</a-select>
</a-form-item>
<a-form-item
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="身份证号码"
prop="idcard"
hasFeedback>
<a-input placeholder="请输入身份证号码" v-decorator="['idcard', validatorRules.idcard]" :readOnly="disableSubmit"/>
</a-form-item>
<a-form-item
<a-input placeholder="请输入身份证号码" v-model="model.idcard" :readOnly="disableSubmit"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="身份证扫描件"
hasFeedback>
<j-image-upload text="上传" v-model="fileList" :isMultiple="true"></j-image-upload>
</a-form-item>
<a-form-item
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="联系方式"
prop="telphone"
hasFeedback>
<a-input v-decorator="[ 'telphone', validatorRules.telphone]" :readOnly="disableSubmit"/>
</a-form-item>
<a-form-item
<a-input v-model="model.telphone" :readOnly="disableSubmit"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单号码"
v-model="this.orderId"
:hidden="hiding"
hasFeedback>
<a-input v-decorator="[ 'orderId', {}]" disabled="disabled"/>
</a-form-item>
</a-form>
<a-input v-model="model.orderId" disabled="disabled"/>
</a-form-model-item>
</a-form-model>
</a-spin>
</a-modal>
</template>
<script>
import {httpAction} from '@/api/manage'
import pick from 'lodash.pick'
import Vue from 'vue'
import {ACCESS_TOKEN} from "@/store/mutation-types"
import JImageUpload from '../../../../components/jeecg/JImageUpload'
@ -89,59 +89,6 @@
xs: {span: 24},
sm: {span: 16},
},
// 表头
columns: [
{
title: '客户名',
align: "center",
dataIndex: 'name',
},
{
title: '性别',
align: "center",
dataIndex: 'sex',
},
{
title: '身份证号码',
align: "center",
dataIndex: 'idcard',
},
{
title: '身份证扫描件',
align: "center",
dataIndex: 'idcardPic',
},
{
title: '电话',
dataIndex: 'telphone',
align: "center",
},
{
title: '订单号码',
dataIndex: 'orderId',
align: "center",
},
{
title: '创建人',
dataIndex: 'createBy',
align: "center",
},
{
title: '创建时间',
dataIndex: 'createTime',
align: "center",
},
{
title: '更新时间',
dataIndex: 'updateBy',
align: "center",
},
{
title: '更新人',
dataIndex: 'updateTime',
align: "center",
},
],
fileList: [],
disableSubmit: false,
selectedRowKeys: [],
@ -155,7 +102,6 @@
addStatus: false,
editStatus: false,
confirmLoading: false,
form: this.$form.createForm(this),
url: {
add: "/test/order/addCustomer",
edit: "/test/order/editCustomer",
@ -163,8 +109,9 @@
getOrderCustomerList: "/test/order/listOrderCustomerByMainId",
},
validatorRules: {
telphone: {rules: [{validator: this.validateMobile}]},
idcard: {rules: [{validator: this.validateIdCard}]}
name :[{required: true, message: '请输入客户姓名!'}],
telphone: [{validator: this.validateMobile}],
idcard: [{validator: this.validateIdCard}]
},
}
},
@ -181,7 +128,6 @@
add(orderId) {
this.hiding = true;
if (orderId) {
this.orderId = orderId;
this.edit({orderId}, '');
} else {
this.$message.warning("请选择一个客户信息");
@ -201,17 +147,12 @@
this.hiding = true;
this.disableSubmit = false;
}
this.form.resetFields();
this.orderId = record.orderId;
this.model = Object.assign({}, record);
if (record.id) {
this.hiding = false;
this.addStatus = false;
this.editStatus = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'id', 'name', 'sex', 'idcard','telphone', 'orderId', 'createBy', 'createTime', 'updateBy', 'updateTime'))
});
setTimeout(() => {
this.fileList = record.idcardPic
}, 5)
@ -226,12 +167,13 @@
this.visible = false;
this.picUrl = "";
this.fileList=[];
this.$refs.form.resetFields();
},
handleOk() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -242,9 +184,7 @@
httpurl += this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
console.log(formData);
formData.orderId = this.orderId;
let formData = Object.assign({}, this.model);
if(this.fileList != '') {
formData.idcardPic = this.fileList;
}else{
@ -261,6 +201,8 @@
that.confirmLoading = false;
that.close();
})
}else{
return false;
}
})
},

View File

@ -8,46 +8,45 @@
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="orderMainModel" :rules="validatorRules">
<!-- 主表单区域 -->
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
prop="orderCode"
label="订单号"
required
hasFeedback>
<a-input
placeholder="请输入订单号"
v-decorator="['orderCode', {rules: [{ required: true, message: '请输入订单号!' }]}]"
/>
</a-form-item>
<a-form-item
<a-input placeholder="请输入订单号" v-model="orderMainModel.orderCode" />
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单类型">
<a-select placeholder="请输入订单类型" v-decorator="['ctype',{}]">
<a-select placeholder="请输入订单类型" v-model="orderMainModel.ctype">
<a-select-option value="1">国内订单</a-select-option>
<a-select-option value="2">国际订单</a-select-option>
</a-select>
</a-form-item>
<a-form-item
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单日期">
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ 'orderDate',{}]"/>
</a-form-item>
<a-form-item
<a-date-picker showTime valueFormat='YYYY-MM-DD HH:mm:ss' v-model="orderMainModel.orderDate"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单金额">
<a-input-number style="width: 200px" v-decorator="[ 'orderMoney', {}]"/>
</a-form-item>
<a-form-item
<a-input-number style="width: 200px" v-model="orderMainModel.orderMoney" />
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单备注">
<a-input placeholder="请输入订单备注" v-decorator="['content', {}]"/>
</a-form-item>
</a-form>
<a-input placeholder="请输入订单备注" v-model="orderMainModel.content"/>
</a-form-model-item>
</a-form-model>
</a-spin>
</a-modal>
</template>
@ -80,8 +79,11 @@
sm: {span: 16},
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {},
validatorRules: {
orderCode: [
{ required: true, message: '请输入订单号!' }
]
},
url: {
add: "/test/order/add",
edit: "/test/order/edit",
@ -95,26 +97,21 @@
this.edit({});
},
edit(record) {
this.form.resetFields();
this.orderMainModel = Object.assign({}, record);
//初始化明细表数据
console.log(this.orderMainModel.id)
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.orderMainModel, 'orderCode', 'ctype', 'orderMoney', 'content'))
this.form.setFieldsValue({orderDate: this.orderMainModel.orderDate ? moment(this.orderMainModel.orderDate) : null}) //时间格式化
});
console.log(this.orderMainModel)
//初始化明细表数据
this.visible = true;
},
close() {
this.$emit('close');
this.visible = false;
this.$refs.form.resetFields();
},
handleOk() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -125,15 +122,8 @@
httpurl += this.url.edit;
method = 'put';
}
let orderMainData = Object.assign(this.orderMainModel, values);
//时间格式化
orderMainData.orderDate = orderMainData.orderDate ? orderMainData.orderDate.format('YYYY-MM-DD HH:mm:ss') : null;
let formData = {
...orderMainData
}
console.log(formData)
httpAction(httpurl, formData, method).then((res) => {
httpAction(httpurl, this.orderMainModel, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok');
@ -144,6 +134,8 @@
that.confirmLoading = false;
that.close();
})
}else{
return false;
}
})
},

View File

@ -10,58 +10,56 @@
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="航班号"
prop="ticketCode"
hasFeedback>
<a-input
placeholder="请输入航班号"
:readOnly="disableSubmit"
v-decorator="['ticketCode', {rules:[{ required: true,message: '请输入航班号!'}]}]"/>
</a-form-item>
<a-form-item
<a-input placeholder="请输入航班号" :readOnly="disableSubmit" v-model="model.ticketCode"></a-input>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="航班时间"
prop="tickectDate"
hasFeedback>
<j-date :trigger-change="true" v-decorator="['tickectDate',{rules:[{ required: true,message: '请输入航班号!'}]}]"></j-date>
</a-form-item>
<a-form-item
<j-date v-model="model.tickectDate"></j-date>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单号码"
v-model="this.orderId"
:hidden="hiding"
hasFeedback>
<a-input v-decorator="[ 'orderId', {}]" disabled="disabled"/>
</a-form-item>
<a-form-item
<a-input v-model="model.orderId" disabled="disabled"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="创建人"
:hidden="hiding"
hasFeedback>
<a-input v-decorator="[ 'createBy', {}]" :readOnly="disableSubmit"/>
</a-form-item>
<a-form-item
<a-input v-model="model.createBy" :readOnly="disableSubmit"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="创建时间"
:hidden="hiding"
hasFeedback>
<a-input v-decorator="[ 'createTime', {}]" :readOnly="disableSubmit"/>
</a-form-item>
</a-form>
<a-input v-model="model.createTime" :readOnly="disableSubmit"/>
</a-form-model-item>
</a-form-model>
</a-spin>
</a-modal>
</template>
<script>
import {httpAction} from '@/api/manage'
import pick from 'lodash.pick'
import moment from 'moment'
import JDate from '@/components/jeecg/JDate'
@ -89,8 +87,10 @@
orderId: '',
hiding: false,
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {},
validatorRules: {
ticketCode:[{required : true, message: '请输入航班号!'}],
tickectDate:[{required : true, message: '请输入航班时间!'}]
},
url: {
add: '/test/order/addTicket',
edit: '/test/order/editTicket'
@ -121,23 +121,19 @@
this.hiding = true;
this.disableSubmit = false;
}
this.form.resetFields();
this.orderId = record.orderId;
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'ticketCode', 'tickectDate', 'orderId', 'createBy', 'createTime', 'updateBy', 'updateTime'))
})
},
close() {
this.$emit('close');
this.visible = false;
this.$refs.form.resetFields();
},
handleOk() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
@ -148,9 +144,8 @@
httpurl += this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
formData.mainId = this.orderId;
httpAction(httpurl, formData, method).then((res) => {
this.model.mainId = this.model.orderId;
httpAction(httpurl, this.model, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok')
@ -161,6 +156,8 @@
that.confirmLoading = false;
that.close();
})
}else{
return false;
}
})
},

View File

@ -74,14 +74,11 @@
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="基本信息" key="1" >
<a-card :bordered="false" v-if="selectedKeys.length>0">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构名称">
<a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
</a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="departName" label="机构名称">
<a-input placeholder="请输入机构/部门名称" v-model="model.departName" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
<a-tree-select
style="width:100%"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
@ -90,26 +87,20 @@
v-model="model.parentId"
placeholder="">
</a-tree-select>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构编码">
<a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="orgCode" label="机构编码">
<a-input disabled placeholder="请输入机构编码" v-model="model.orgCode" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="orgCategory" label="机构类型">
<template v-if="orgCategoryDisabled">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio-group v-model="model.orgCategory" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
</template>
<template v-else>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio-group v-model="model.orgCategory" placeholder="请选择机构类型">
<a-radio value="2">
部门
</a-radio>
@ -118,32 +109,20 @@
</a-radio>
</a-radio-group>
</template>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="排序">
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="手机号">
<a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="地址">
<a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
<a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/>
</a-form-item>
</a-form>
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="排序">
<a-input-number v-model="model.departOrder" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="手机号">
<a-input placeholder="请输入手机号" v-model="model.mobile" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="地址">
<a-input placeholder="请输入地址" v-model="model.address"/>
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="备注">
<a-textarea placeholder="请输入备注" v-model="model.memo"/>
</a-form-model-item>
</a-form-model>
<div class="anty-form-btn">
<a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync">重置</a-button>
<a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form">保存</a-button>
@ -166,7 +145,6 @@
</template>
<script>
import DepartModal from './modules/DepartModal'
import pick from 'lodash.pick'
import {queryDepartTreeList, searchByKeywords, deleteByDepartId} from '@/api/api'
import {httpAction, deleteAction} from '@/api/manage'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
@ -240,11 +218,8 @@
selectedKeys: [],
autoIncr: 1,
currSelected: {},
allTreeKeys:[],
checkStrictly: true,
form: this.$form.createForm(this),
labelCol: {
xs: {span: 24},
sm: {span: 5}
@ -258,10 +233,10 @@
edges: []
},
validatorRules: {
departName: {rules: [{required: true, message: '请输入机构/部门名称!'}]},
orgCode: {rules: [{required: true, message: '请输入机构编码!'}]},
orgCategory: {rules: [{required: true, message: '请输入机构类型!'}]},
mobile: {rules: [{validator: this.validateMobile}]}
departName: [{required: true, message: '请输入机构/部门名称!'}],
orgCode: [{required: true, message: '请输入机构编码!'}],
orgCategory:[{required: true, message: '请输入机构类型!'}],
mobile:[{validator: this.validateMobile}]
},
url: {
delete: '/sys/sysDepart/delete',
@ -323,8 +298,6 @@
},
onExpand(expandedKeys) {
console.log('onExpand', expandedKeys)
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
this.iExpandedKeys = expandedKeys
this.autoExpandParent = false
},
@ -337,7 +310,7 @@
this.dropTrigger = ''
}
},
// 右键店家下拉关闭下拉框
// 右键下拉关闭下拉框
closeDrop() {
this.dropTrigger = ''
},
@ -402,14 +375,13 @@
onCheck(checkedKeys, info) {
console.log('onCheck', checkedKeys, info)
this.hiding = false
//this.checkedKeys = checkedKeys.checked
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
//---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------
if(this.checkStrictly){
this.checkedKeys = checkedKeys.checked;
}else{
this.checkedKeys = checkedKeys
}
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
//---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------
},
onSelect(selectedKeys, e) {
console.log('selected', selectedKeys, e)
@ -431,10 +403,6 @@
}else{
this.orgCategoryDisabled = false;
}
this.$nextTick(() => {
this.form.getFieldDecorator('fax', {initialValue: ''})
this.form.setFieldsValue(pick(record, 'departName','orgCategory', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
})
},
getCurrSelectedTitle() {
return !this.currSelected.title ? '' : this.currSelected.title
@ -443,7 +411,6 @@
this.hiding = true
this.checkedKeys = []
this.currSelected = {}
this.form.resetFields()
this.selectedKeys = []
this.$refs.departAuth.departId = ''
},
@ -457,16 +424,14 @@
this.currSelected.receiptTriggerType = value
},
submitCurrForm() {
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
if (!this.currSelected.id) {
this.$message.warning('请点击选择要修改部门!')
return
}
let formData = Object.assign(this.currSelected, values)
console.log('Received values of form: ', formData)
httpAction(this.url.edit, formData, 'put').then((res) => {
httpAction(this.url.edit, this.currSelected, 'put').then((res) => {
if (res.success) {
this.$message.success('保存成功!')
this.loadTree()
@ -478,12 +443,13 @@
})
},
emptyCurrForm() {
this.form.resetFields()
this.$refs.form.resetFields();
this.model={}
},
nodeSettingFormSubmit() {
this.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
this.$refs.form.validate(valid => {
if (valid) {
console.log('Received values of form: ', this.model)
}
})
},
@ -520,7 +486,7 @@
that.$message.success('删除成功!')
that.loadTree()
//删除后同步清空右侧基本信息内容
let orgCode=that.form.getFieldValue("orgCode");
let orgCode=that.model.orgCode;
if(orgCode && orgCode === that.rightClickSelectedOrgCode){
that.onClearSelected()
}
@ -552,7 +518,7 @@
}
}
},
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
//---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------
expandAll () {
this.iExpandedKeys = this.allTreeKeys
},
@ -583,7 +549,7 @@
}
}
}
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
//---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------
},
created() {

View File

@ -0,0 +1,679 @@
<template xmlns:background-color="http://www.w3.org/1999/xhtml">
<a-row :gutter="10">
<a-col :md="12" :sm="24">
<a-card :bordered="false">
<!-- 按钮操作区域 -->
<a-row style="margin-left: 14px">
<a-button @click="handleAdd(1)" type="primary">添加部门</a-button>
<a-button @click="handleAdd(2)" type="primary">添加下级</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('部门信息')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-button title="删除多条数据" @click="batchDel" type="default">批量删除</a-button>
</a-row>
<div style="background: #fff;padding-left:16px;height: 100%; margin-top: 5px">
<a-alert type="info" :showIcon="true">
<div slot="message">
当前选择<span v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</span>
<a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected">取消选择</a>
</div>
</a-alert>
<a-input-search @search="onSearch" style="width:100%;margin-top: 10px" placeholder="请输入部门名称"/>
<!-- -->
<a-col :md="10" :sm="24">
<template>
<a-dropdown :trigger="[this.dropTrigger]" @visibleChange="dropStatus">
<span style="user-select: none">
<a-tree
checkable
multiple
@select="onSelect"
@check="onCheck"
@rightClick="rightHandle"
:selectedKeys="selectedKeys"
:checkedKeys="checkedKeys"
:treeData="departTree"
:checkStrictly="checkStrictly"
:expandedKeys="iExpandedKeys"
:load-data="loadSubTree"
@expand="onExpand"/>
</span>
<!--新增右键点击事件,和增加添加和删除功能-->
<a-menu slot="overlay">
<a-menu-item @click="handleAdd(3)" key="1">添加</a-menu-item>
<a-menu-item @click="handleDelete" key="2">删除</a-menu-item>
<a-menu-item @click="closeDrop" key="3">取消</a-menu-item>
</a-menu>
</a-dropdown>
</template>
</a-col>
</div>
</a-card>
<!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
<div class="drawer-bootom-button">
<a-dropdown :trigger="['click']" placement="topCenter">
<a-menu slot="overlay">
<a-menu-item key="1" @click="switchCheckStrictly(1)">父子关联</a-menu-item>
<a-menu-item key="2" @click="switchCheckStrictly(2)">取消关联</a-menu-item>
<a-menu-item key="3" @click="checkALL">全部勾选</a-menu-item>
<a-menu-item key="4" @click="cancelCheckALL">取消全选</a-menu-item>
<a-menu-item key="5" @click="expandAll">展开所有</a-menu-item>
<a-menu-item key="6" @click="closeAll">合并所有</a-menu-item>
</a-menu>
<a-button>
树操作 <a-icon type="up" />
</a-button>
</a-dropdown>
</div>
<!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
</a-col>
<a-col :md="12" :sm="24">
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="基本信息" key="1" >
<a-card :bordered="false" v-if="selectedKeys.length>0">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构名称">
<a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
</a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
<a-tree-select
style="width:100%"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="treeData"
:disabled="disable"
v-model="model.parentId"
placeholder="">
</a-tree-select>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构编码">
<a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
<template v-if="orgCategoryDisabled">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
</template>
<template v-else>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="2">
部门
</a-radio>
<a-radio value="3">
岗位
</a-radio>
</a-radio-group>
</template>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="排序">
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="手机号">
<a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="地址">
<a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
<a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/>
</a-form-item>
</a-form>
<div class="anty-form-btn">
<a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync">重置</a-button>
<a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form">保存</a-button>
</div>
</a-card>
<a-card v-else >
<a-empty>
<span slot="description"> 请先选择一个部门! </span>
</a-empty>
</a-card>
</a-tab-pane>
<a-tab-pane tab="部门权限" key="2" forceRender>
<depart-auth-modal ref="departAuth"/>
</a-tab-pane>
</a-tabs>
</a-col>
<depart-modal ref="departModal" @ok="loadTree"></depart-modal>
</a-row>
</template>
<script>
import DepartModal from './modules/DepartModal'
import pick from 'lodash.pick'
import {queryDepartTreeSync, searchByKeywords, deleteByDepartId} from '@/api/api'
import {httpAction, deleteAction} from '@/api/manage'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import DepartAuthModal from './modules/DepartAuthModal'
// 表头
const columns = [
{
title: '机构名称',
dataIndex: 'departName'
},
{
title: '机构类型',
align: 'center',
dataIndex: 'orgType'
},
{
title: '机构编码',
dataIndex: 'orgCode',
},
{
title: '手机号',
dataIndex: 'mobile'
},
{
title: '传真',
dataIndex: 'fax'
},
{
title: '地址',
dataIndex: 'address'
},
{
title: '排序',
align: 'center',
dataIndex: 'departOrder'
},
{
title: '操作',
align: 'center',
dataIndex: 'action',
scopedSlots: {customRender: 'action'}
}
]
export default {
name: 'DepartList',
mixins: [JeecgListMixin],
components: {
DepartAuthModal,
DepartModal
},
data() {
return {
iExpandedKeys: [],
loading: false,
autoExpandParent: false,
currFlowId: '',
currFlowName: '',
disable: true,
treeData: [],
visible: false,
departTree: [],
departTreeAll: [],
loadedKeys: [],
allIds: [],
rightClickSelectedKey: '',
rightClickSelectedOrgCode: '',
hiding: true,
model: {},
dropTrigger: '',
depart: {},
columns: columns,
disableSubmit: false,
checkedKeys: [],
selectedKeys: [],
autoIncr: 1,
currSelected: {},
allTreeKeys:[],
checkStrictly: true,
form: this.$form.createForm(this),
labelCol: {
xs: {span: 24},
sm: {span: 5}
},
wrapperCol: {
xs: {span: 24},
sm: {span: 16}
},
graphDatasource: {
nodes: [],
edges: []
},
validatorRules: {
departName: {rules: [{required: true, message: '请输入机构/部门名称!'}]},
orgCode: {rules: [{required: true, message: '请输入机构编码!'}]},
orgCategory: {rules: [{required: true, message: '请输入机构类型!'}]},
mobile: {rules: [{validator: this.validateMobile}]}
},
url: {
delete: '/sys/sysDepart/delete',
edit: '/sys/sysDepart/edit',
deleteBatch: '/sys/sysDepart/deleteBatch',
exportXlsUrl: "sys/sysDepart/exportXls",
importExcelUrl: "sys/sysDepart/importExcel",
},
orgCategoryDisabled:false,
}
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
}
},
methods: {
loadData() {
this.refresh();
},
loadTree() {
var that = this
//上级部门树信息
that.treeData = []
//保存的树信息,搜索是需要用到
that.departTreeAll = []
//所有的树信息
that.departTree = []
//所有的树节点key信息
that.allIds = []
queryDepartTreeSync().then((res) => {
if (res.success) {
this.allTreeKeys = [];
for (let i = 0; i < res.result.length; i++) {
let temp = res.result[i]
that.treeData.push(temp)
that.departTreeAll.push(temp)
that.departTree.push(temp)
that.allIds.push(temp.key)
that.allTreeKeys.push(temp.key)
}
this.loading = false
}
})
},
loadSubTree(treeNode) {
var that = this;
return new Promise(resolve => {
queryDepartTreeSync({pid:treeNode.dataRef.id}).then((res) => {
if (res.success) {
//判断chidlren是否为空并修改isLeaf属性值
if(res.result.length == 0){
treeNode.dataRef['isLeaf']=true
return;
}else{
treeNode.dataRef['children']= res.result;
}
for (let i = 0; i < res.result.length; i++) {
let temp = res.result[i]
that.allIds.push(temp.key)
}
}
})
resolve();
});
//保存全部部门信息,方便后面搜索使用
that.departTreeAll=that.departTree
},
refresh() {
this.loading = true
this.loadTree()
},
// 右键操作方法
rightHandle(node) {
this.dropTrigger = 'contextmenu'
console.log(node.node.eventKey)
//注释异步书加载key拼接__,以便于每次展开节点会刷新数据
this.rightClickSelectedKey = node.node.eventKey.split('__')[0]
this.rightClickSelectedOrgCode = node.node.dataRef.orgCode
},
onExpand(expandedKeys) {
console.log('onExpand', expandedKeys)
this.iExpandedKeys = expandedKeys
this.autoExpandParent = false
this.allTreeKeys=expandedKeys
},
backFlowList() {
this.$router.back(-1)
},
// 右键点击下拉框改变事件
dropStatus(visible) {
if (visible == false) {
this.dropTrigger = ''
}
},
// 右键店家下拉关闭下拉框
closeDrop() {
this.dropTrigger = ''
},
addRootNode() {
this.$refs.nodeModal.add(this.currFlowId, '')
},
batchDel: function () {
console.log(this.checkedKeys)
if (this.checkedKeys.length <= 0) {
this.$message.warning('请选择一条记录!')
} else {
var ids = ''
for (var a = 0; a < this.checkedKeys.length; a++) {
ids += this.checkedKeys[a].split('__')[0] + ','
}
var that = this
this.$confirm({
title: '确认删除',
content: '确定要删除所选中的 ' + this.checkedKeys.length + ' 条数据,以及子节点数据吗?',
onOk: function () {
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) {
that.$message.success(res.message)
that.loadTree()
that.onClearSelected()
} else {
that.$message.warning(res.message)
}
})
}
})
}
},
onSearch(value) {
let that = this
if (value) {
searchByKeywords({keyWord: value}).then((res) => {
if (res.success) {
that.departTree = []
for (let i = 0; i < res.result.length; i++) {
let temp = res.result[i]
that.departTree.push(temp)
}
} else {
that.$message.warning(res.message)
}
})
} else {
that.departTree=that.departTreeAll
}
},
nodeModalOk() {
this.loadTree()
},
nodeModalClose() {
},
hide() {
this.visible = false
},
onCheck(checkedKeys, info) {
console.log('onCheck', checkedKeys, info)
this.hiding = false
//this.checkedKeys = checkedKeys.checked
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
if(this.checkStrictly){
this.checkedKeys = checkedKeys.checked;
}else{
this.checkedKeys = checkedKeys
}
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
},
onSelect(selectedKeys, e) {
console.log('selected', selectedKeys, e)
this.hiding = false
let record = e.node.dataRef
console.log('onSelect-record', record)
this.currSelected = Object.assign({}, record)
this.model = this.currSelected
this.selectedKeys = [record.key]
this.model.parentId = record.parentId
this.setValuesToForm(record)
this.$refs.departAuth.show(record.id);
},
// 触发onSelect事件时,为部门树右侧的form表单赋值
setValuesToForm(record) {
if(record.orgCategory == '1'){
this.orgCategoryDisabled = true;
}else{
this.orgCategoryDisabled = false;
}
this.$nextTick(() => {
this.form.getFieldDecorator('fax', {initialValue: ''})
this.form.setFieldsValue(pick(record, 'departName','orgCategory', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
})
},
getCurrSelectedTitle() {
return !this.currSelected.title ? '' : this.currSelected.title
},
onClearSelected() {
this.hiding = true
this.checkedKeys = []
this.currSelected = {}
this.form.resetFields()
this.selectedKeys = []
this.$refs.departAuth.departId = ''
},
handleNodeTypeChange(val) {
this.currSelected.nodeType = val
},
notifyTriggerTypeChange(value) {
this.currSelected.notifyTriggerType = value
},
receiptTriggerTypeChange(value) {
this.currSelected.receiptTriggerType = value
},
submitCurrForm() {
this.form.validateFields((err, values) => {
if (!err) {
if (!this.currSelected.id) {
this.$message.warning('请点击选择要修改部门!')
return
}
let formData = Object.assign(this.currSelected, values)
console.log('Received values of form: ', formData)
httpAction(this.url.edit, formData, 'put').then((res) => {
if (res.success) {
this.$message.success('保存成功!')
this.loadTree()
} else {
this.$message.error(res.message)
}
})
}
})
},
emptyCurrForm() {
this.form.resetFields()
},
nodeSettingFormSubmit() {
this.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
},
openSelect() {
this.$refs.sysDirectiveModal.show()
},
handleAdd(num) {
if (num == 1) {
this.$refs.departModal.add()
this.$refs.departModal.title = '新增'
} else if (num == 2) {
let key = this.currSelected.key
if (!key) {
this.$message.warning('请先点击选中上级部门!')
return false
}
this.$refs.departModal.add(this.selectedKeys[0].split('__')[0])
this.$refs.departModal.title = '新增'
} else {
this.$refs.departModal.add(this.rightClickSelectedKey)
this.$refs.departModal.title = '新增'
}
},
handleDelete() {
var that = this
this.$confirm({
title: '确认删除',
content: '确定要删除此部门以及子节点数据吗?',
onOk: function () {
deleteByDepartId({id: that.rightClickSelectedKey}).then((resp) => {
if (resp.success) {
//删除成功后,去除已选中中的数据
that.checkedKeys.splice(that.checkedKeys.findIndex(key => key === that.rightClickSelectedKey), 1);
that.$message.success('删除成功!')
that.loadTree()
//删除后同步清空右侧基本信息内容
let orgCode=that.form.getFieldValue("orgCode");
if(orgCode && orgCode === that.rightClickSelectedOrgCode){
that.onClearSelected()
}
} else {
that.$message.warning('删除失败!')
}
})
}
})
},
selectDirectiveOk(record) {
console.log('选中指令数据', record)
this.nodeSettingForm.setFieldsValue({directiveCode: record.directiveCode})
this.currSelected.sysCode = record.sysCode
},
getFlowGraphData(node) {
this.graphDatasource.nodes.push({
id: node.id,
text: node.flowNodeName
})
if (node.children.length > 0) {
for (let a = 0; a < node.children.length; a++) {
let temp = node.children[a]
this.graphDatasource.edges.push({
source: node.id,
target: temp.id
})
this.getFlowGraphData(temp)
}
}
},
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
expandAll () {
this.iExpandedKeys = this.allTreeKeys
},
closeAll () {
this.iExpandedKeys = []
},
checkALL () {
this.checkStriccheckStrictlytly = false
//this.checkedKeys = this.allTreeKeys
this.checkedKeys = this.allIds
},
cancelCheckALL () {
//this.checkedKeys = this.defaultCheckedKeys
this.checkedKeys = []
},
switchCheckStrictly (v) {
if(v==1){
this.checkStrictly = false
}else if(v==2){
this.checkStrictly = true
}
},
getAllKeys(node) {
// console.log('node',node);
this.allTreeKeys.push(node.key)
if (node.children && node.children.length > 0) {
for (let a = 0; a < node.children.length; a++) {
this.getAllKeys(node.children[a])
}
}
}
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
},
created() {
this.currFlowId = this.$route.params.id
this.currFlowName = this.$route.params.name
// this.loadTree()
},
}
</script>
<style scoped>
.ant-card-body .table-operator {
margin: 15px;
}
.anty-form-btn {
width: 100%;
text-align: center;
}
.anty-form-btn button {
margin: 0 5px;
}
.anty-node-layout .ant-layout-header {
padding-right: 0
}
.header {
padding: 0 8px;
}
.header button {
margin: 0 3px
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
#app .desktop {
height: auto !important;
}
/** Button按钮间距 */
.ant-btn {
margin-left: 3px
}
.drawer-bootom-button {
/*position: absolute;*/
bottom: 0;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: left;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

View File

@ -167,6 +167,9 @@
},
getQueryParams() {
//update--begin--autor:wangshuai-----date:20191204------for清空总条数 teambition JT-113------
this.ipagination.total=0;
//update--end--autor:wangshuai-----date:20191204------for清空总条数 teambition JT-113------
var param = Object.assign({}, this.queryParam);
param.dictId = this.dictId;
param.field = this.getQueryField();

View File

@ -192,12 +192,14 @@
if (res.success) {
let childrenMap = res.result
let fn = (list) => {
list.forEach(data => {
if (this.expandedRowKeys.includes(data.id)) {
data.children = childrenMap[data.id]
fn(data.children)
}
})
if(list&&list.length>0){
list.forEach(data => {
if (this.expandedRowKeys.includes(data.id)) {
data.children = childrenMap[data.id]
fn(data.children)
}
})
}
}
fn(dataList)
}
@ -212,9 +214,8 @@
},
handleAddSub(record) {
this.$refs.modalForm.title = "添加子菜单";
this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id,menuType:1});
},
handleExpandedRowsChange(expandedRows) {
this.expandedRowKeys = expandedRows

View File

@ -181,9 +181,8 @@
},
handleAddSub(record) {
this.$refs.modalForm.title = "添加子菜单";
this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id,menuType:1});
},
handleExpandedRowsChange(expandedRows) {
this.expandedRowKeys = expandedRows

View File

@ -384,11 +384,8 @@
this.$message.error('请选择一个角色!')
} else {
this.$refs.modalForm2.roleDisabled = true
this.$refs.modalForm2.selectedRole = [this.currentRoleId]
this.$refs.modalForm2.add()
this.$refs.modalForm2.title = '新增'
this.$refs.modalForm2.edit({activitiSync:'1',userIdentity:1,selectedroles:this.currentRoleId})
}
},
modalFormOk2() {

View File

@ -283,6 +283,12 @@
syncHeadNotic(anntId){
getAction("sys/annountCement/syncNotic",{anntId:anntId})
},
handleDetail:function(record){
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title="详情";
this.$refs.modalForm.disableSubmit = true;
this.$refs.modalForm.disabled = true;
},
}
}
</script>

View File

@ -91,6 +91,7 @@
url: {
list: "/sys/category/rootList",
childList: "/sys/category/childList",
getChildListBatch: "/sys/category/getChildListBatch",
delete: "/sys/category/delete",
deleteBatch: "/sys/category/deleteBatch",
exportXlsUrl: "/sys/category/exportXls",
@ -125,7 +126,6 @@
this.ipagination.current=1
}
this.loading = true
this.expandedRowKeys = []
let params = this.getQueryParams()
return new Promise((resolve) => {
getAction(this.url.list,params).then(res=>{
@ -134,7 +134,9 @@
if(Number(result.total)>0){
this.ipagination.total = Number(result.total)
this.dataSource = this.getDataByResult(res.result.records)
resolve()
//update--begin--autor:lvdandan-----date:20201204------forJT-31 删除成功后默认展开已展开信息
return this.loadDataByExpandedRows(this.dataSource)
//update--end--autor:lvdandan-----date:20201204------forJT-31 删除成功后默认展开已展开信息
}else{
this.ipagination.total=0
this.dataSource=[]
@ -142,19 +144,22 @@
}else{
this.$message.warning(res.message)
}
}).finally(()=>{
this.loading = false
})
})
},
getDataByResult(result){
return result.map(item=>{
//判断是否标记了带有子节点
if(item[this.hasChildrenField]=='1'){
let loadChild = { id: item.id+'_loadChild', name: 'loading...', isLoading: true }
item.children = [loadChild]
}
return item
})
if(result && result.length>0){
return result.map(item=>{
//判断是否标记了带有子节点
if(item[this.hasChildrenField]=='1'){
let loadChild = { id: item.id+'_loadChild', name: 'loading...', isLoading: true }
item.children = [loadChild]
}
return item
})
}
},
handleExpand(expanded, record){
// 判断是否是展开状态
@ -265,15 +270,9 @@
let that = this;
deleteAction(that.url.delete, {id: record.id}).then((res) => {
if (res.success) {
if (record.pid && record.pid!='0') {
let formData = {pid: record.pid};
that.$message.success(res.message);
that.subExpandedKeys = [];
that.getExpandKeysByPid(record.pid, this.dataSource, this.dataSource)
that.addOk(formData, this.subExpandedKeys.reverse())
} else {
that.loadData();
}
//update--begin--autor:lvdandan-----date:20201204------forJT-31 删除成功后默认展开已展开信息
that.loadData();
//update--end--autor:lvdandan-----date:20201204------forJT-31 删除成功后默认展开已展开信息
} else {
that.$message.warning(res.message);
}
@ -292,6 +291,43 @@
}
}
},
// 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
loadDataByExpandedRows(dataList) {
if (this.expandedRowKeys.length > 0) {
return getAction(this.url.getChildListBatch,{ parentIds: this.expandedRowKeys.join(',') }).then(res=>{
if (res.success && res.result.records.length>0) {
//已展开的数据批量子节点
let records = res.result.records
const listMap = new Map();
for (let item of records) {
let pid = item[this.pidField];
if (this.expandedRowKeys.join(',').includes(pid)) {
let mapList = listMap.get(pid);
if (mapList == null) {
mapList = [];
}
mapList.push(item);
listMap.set(pid, mapList);
}
}
let childrenMap = listMap;
let fn = (list) => {
if(list) {
list.forEach(data => {
if (this.expandedRowKeys.includes(data.id)) {
data.children = this.getDataByResult(childrenMap.get(data.id))
fn(data.children)
}
})
}
}
fn(dataList)
}
})
} else {
return Promise.resolve()
}
},
}

View File

@ -162,7 +162,7 @@
delete: '/sys/position/delete',
deleteBatch: '/sys/position/deleteBatch',
exportXlsUrl: '/sys/position/exportXls',
importExcelUrl: '/sys/position/importExcel',
importExcelUrl: 'sys/position/importExcel',
},
}
},

View File

@ -17,8 +17,8 @@
<a-form-item label="性别">
<a-select v-model="queryParam.sex" placeholder="请选择性别">
<a-select-option value="">请选择</a-select-option>
<a-select-option value="1">男</a-select-option>
<a-select-option value="2">女</a-select-option>
<a-select-option value="1">男</a-select-option>
<a-select-option value="2">女</a-select-option>
</a-select>
</a-form-item>
</a-col>
@ -154,7 +154,6 @@
<a>解冻</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
@ -165,7 +164,8 @@
<!-- table区域-end -->
<user-modal ref="modalForm" @ok="modalFormOk"></user-modal>
<password-modal ref="passwordmodal"></password-modal>
<password-modal ref="passwordmodal" @ok="passwordModalOk"></password-modal>
<!-- 用户回收站 -->
<user-recycle-bin-modal :visible.sync="recycleBinVisible" @ok="modalFormOk"/>
@ -179,7 +179,6 @@
import {putAction,getFileAccessHttpUrl} from '@/api/manage';
import {frozenBatch} from '@/api/api'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import SysUserAgentModal from "./modules/SysUserAgentModal";
import JInput from '@/components/jeecg/JInput'
import UserRecycleBinModal from './modules/UserRecycleBinModal'
import JSuperQuery from '@/components/jeecg/JSuperQuery'
@ -188,7 +187,6 @@
name: "UserList",
mixins: [JeecgListMixin],
components: {
SysUserAgentModal,
UserModal,
PasswordModal,
JInput,
@ -368,6 +366,9 @@
handleChangePassword(username) {
this.$refs.passwordmodal.show(username);
},
passwordModalOk() {
//TODO 密码修改完成 不需要刷新页面可以把datasource中的数据更新一下
}
}
}

View File

@ -11,16 +11,17 @@
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构名称"
prop="departName"
:hidden="false"
hasFeedback >
<a-input id="departName" placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
</a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :hidden="seen" label="上级部门" hasFeedback>
<a-input id="departName" placeholder="请输入机构/部门名称" v-model="model.departName"/>
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" :hidden="seen" label="上级部门" hasFeedback>
<a-tree-select
style="width:100%"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
@ -29,20 +30,20 @@
placeholder="请选择上级部门"
:disabled="condition">
</a-tree-select>
</a-form-item>
<a-form-item
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
<template v-if="seen">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
<template v-if="seen">
<a-radio-group v-model="model.orgCategory" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
</template>
<template v-else>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio-group v-model="model.orgCategory" placeholder="请选择机构类型">
<a-radio value="2">
部门
</a-radio>
@ -50,40 +51,41 @@
岗位
</a-radio>
</a-radio-group>
</template>
</a-form-item>
<a-form-item
</template>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
prop="mobile"
label="电话">
<a-input placeholder="请输入电话" v-decorator="['mobile',validatorRules.mobile]" />
</a-form-item>
<a-form-item
<a-input placeholder="请输入电话" v-model="model.mobile"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="传真">
<a-input placeholder="请输入传真" v-decorator="['fax', {}]" />
</a-form-item>
<a-form-item
<a-input placeholder="请输入传真" v-model="model.fax"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="地址">
<a-input placeholder="请输入地址" v-decorator="['address', {}]" />
</a-form-item>
<a-form-item
<a-input placeholder="请输入地址" v-model="model.address"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="排序">
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]" />
</a-form-item>
<a-form-item
<a-input-number v-model="model.departOrder"/>
</a-form-model-item>
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
<a-textarea placeholder="请输入备注" v-decorator="['memo', {}]" />
</a-form-item>
<a-textarea placeholder="请输入备注" v-model="model.memo"/>
</a-form-model-item>
</a-form>
</a-form-model>
</a-spin>
</a-modal>
</template>
@ -107,7 +109,10 @@
visible: false,
condition:true,
disableSubmit:false,
model: {},
model: {
departOrder:0,
orgCategory:'1'
},
menuhidden:false,
menuusing:true,
labelCol: {
@ -120,11 +125,11 @@
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
departName:{rules: [{ required: true, message: '请输入机构/部门名称!' }]},
orgCode:{rules: [{ required: true, message: '请输入机构编码!' }]},
mobile:{rules: [{validator:this.validateMobile}]}
departName:[{ required: true, message: '请输入机构/部门名称!' }],
orgCode:[{ required: true, message: '请输入机构编码!' }],
mobile: [{validator:this.validateMobile}],
orgCategory:[{required: true, message: '请输入机构类型!'}]
},
url: {
add: "/sys/sysDepart/add",
@ -159,35 +164,28 @@
this.edit(depart);
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, {});
this.visible = true;
this.loadTreeData();
this.model.parentId = record!=null?record.toString():null;
if(this.seen){
this.model.orgCategory = '1';
}else{
this.model.orgCategory = '2';
}
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,'orgCategory','departName','departNameEn','departNameAbbr','departOrder','description','orgType','orgCode','mobile','fax','address','memo','status','delFlag'))
});
if(this.seen){
this.model.orgCategory = '1';
}else{
this.model.orgCategory = '2';
}
},
close () {
this.$emit('close');
this.disableSubmit = false;
this.visible = false;
this.$refs.form.resetFields();
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let formData = Object.assign(this.model, values);
//时间格式化
console.log(formData)
httpAction(this.url.add,formData,"post").then((res)=>{
httpAction(this.url.add,this.model,"post").then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadTreeData();
@ -200,6 +198,8 @@
that.close();
})
}else{
return false;
}
})
},

View File

@ -38,11 +38,9 @@
import pick from 'lodash.pick'
import { getAction } from '@/api/manage'
import { queryIdTree } from '@/api/api'
import userModal from './UserModal'
export default {
name: "DepartWindow",
components: {
userModal,
},
data () {
return {

View File

@ -10,11 +10,6 @@
<a-input placeholder="请输入账号" v-model="queryParam.username"></a-input>
</a-form-item>
</a-col>
<!--<a-col :md="8" :sm="8">-->
<!--<a-form-item label="用户名称" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">-->
<!--<a-input placeholder="请输入名称查询" v-model="queryParam.realname"></a-input>-->
<!--</a-form-item>-->
<!--</a-col>-->
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24">
<a-button type="primary" @click="searchQuery" icon="search" style="margin-left: 18px">查询</a-button>
@ -76,7 +71,7 @@
</a>
<a-menu slot="overlay">
<a-menu-item>
<a href="javascript:;" @click="handleDeptRole(record)">分配部门角色</a>
<a href="javascript:;" @click="handleDeptRole(record)">部门角色</a>
</a-menu-item>
<a-menu-item>
@ -123,6 +118,7 @@
return {
description: '用户信息',
currentDeptId: '',
currentDept: {},
// 表头
columns: [{
title: '用户账号',
@ -260,6 +256,7 @@
open(record) {
//console.log(record);
this.currentDeptId = record.id;
this.currentDept = record;
this.loadData(1);
},
clearList() {
@ -291,9 +288,10 @@
this.$message.error("请选择一个部门!")
} else {
this.$refs.modalForm.departDisabled = true;
this.$refs.modalForm.userDepartModel.departIdList = [this.currentDeptId]; //传入一个部门id
this.$refs.modalForm.add();
//初始化负责部门
this.$refs.modalForm.nextDepartOptions=[{value:this.currentDept.key,label:this.currentDept.title}]
this.$refs.modalForm.title = "新增";
this.$refs.modalForm.edit({activitiSync:'1',userIdentity:1,selecteddeparts:this.currentDeptId})
}
},
selectOK(data) {

View File

@ -9,46 +9,48 @@
cancelText="关闭"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
prop="itemText"
label="名称">
<a-input placeholder="请输入名称" v-decorator.trim="['itemText', validatorRules.itemText]"/>
</a-form-item>
<a-input placeholder="请输入名称" v-model="model.itemText"/>
</a-form-model-item>
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
prop="itemValue"
label="数据值">
<a-input placeholder="请输入数据值" v-decorator.trim="['itemValue', validatorRules.itemValue]"/>
</a-form-item>
<a-input placeholder="请输入数据值" v-model="model.itemValue" />
</a-form-model-item>
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="描述">
<a-input v-decorator="['description']"/>
</a-form-item>
<a-input v-model="model.description" />
</a-form-model-item>
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="排序值">
<a-input-number :min="1" v-decorator="['sortOrder',{'initialValue':1}]"/>
值越小越靠前支持小数
</a-form-item>
<a-input-number :min="1" v-model="model.sortOrder" />
值越小越靠前
</a-form-model-item>
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="是否启用"
hasFeedback>
<a-switch checkedChildren="启用" unCheckedChildren="禁用" @change="onChose" v-model="visibleCheck"/>
</a-form-item>
</a-form-model-item>
</a-form>
</a-form-model>
</a-spin>
</a-modal>
</template>
@ -56,6 +58,7 @@
<script>
import pick from 'lodash.pick'
import {addDictItem, editDictItem} from '@/api/api'
import { getAction } from '@api/manage'
export default {
name: "DictItemModal",
@ -76,10 +79,9 @@
sm: {span: 16},
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
itemText: {rules: [{required: true, message: '请输入名称!'}]},
itemValue: {rules: [{required: true, message: '请输入数据值!'},{validator: this.validateItemValue}]},
itemText: [{required: true, message: '请输入名称!'}],
itemValue: [{required: true, message: '请输入数据值!'},{validator: this.validateItemValue}],
},
}
},
@ -88,21 +90,19 @@
methods: {
add(dictId) {
this.dictId = dictId;
this.edit({});
//初始化默认值
this.edit({sortOrder:1,status:1});
},
edit(record) {
if (record.id) {
this.dictId = record.dictId;
this.visibleCheck = (record.status == 1) ? true : false;
}
this.form.resetFields();
this.status = record.status;
this.visibleCheck = (record.status == 1) ? true : false;
this.model = Object.assign({}, record);
this.model.dictId = this.dictId;
this.model.status = this.status;
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'itemText', 'itemValue', 'description', 'sortOrder'))
});
},
onChose(checked) {
if (checked) {
@ -117,19 +117,18 @@
handleOk() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
values.itemText = (values.itemText || '').trim()
values.itemValue = (values.itemValue || '').trim()
values.description = (values.description || '').trim()
let formData = Object.assign(this.model, values);
formData.status = this.status;
this.model.itemText = (this.model.itemText || '').trim()
this.model.itemValue = (this.model.itemValue || '').trim()
this.model.description = (this.model.description || '').trim()
this.model.status = this.status;
let obj;
if (!this.model.id) {
obj = addDictItem(formData);
obj = addDictItem(this.model);
} else {
obj = editDictItem(formData);
obj = editDictItem(this.model);
}
obj.then((res) => {
if (res.success) {
@ -142,6 +141,8 @@
that.confirmLoading = false;
that.close();
})
}else{
return false;
}
})
},
@ -152,14 +153,30 @@
close() {
this.$emit('close');
this.visible = false;
this.$refs.form.resetFields();
},
validateItemValue(rule, value, callback){
let param = {
itemValue:value,
dictId:this.dictId,
}
if(this.model.id){
param.id = this.model.id
}
if(value){
let reg=new RegExp("[`_~!@#$^&*()=|{}'.<>《》/?!¥()—【】‘;:”“。,、?]")
if(reg.test(value)){
callback("数据值不能包含特殊字符!")
}else{
callback()
//update--begin--autor:lvdandan-----date:20201203------forJT-27【数据字典】字典 - 数据值可重复
getAction("/sys/dictItem/dictItemCheck",param).then((res)=>{
if(res.success){
callback()
}else{
callback(res.message);
}
});
//update--end--autor:lvdandan-----date:20201203------forJT-27【数据字典】字典 - 数据值可重复
}
}else{
callback()

View File

@ -9,30 +9,34 @@
cancelText="关闭"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
prop="dictName"
required
label="字典名称">
<a-input placeholder="请输入字典名称" v-decorator.trim="[ 'dictName', validatorRules.dictName]"/>
</a-form-item>
<a-input placeholder="请输入字典名称" v-model="model.dictName"/>
</a-form-model-item>
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
prop="dictCode"
required
label="字典编码">
<a-input placeholder="请输入字典编码" v-decorator.trim="[ 'dictCode', validatorRules.dictCode]"/>
</a-form-item>
<a-input placeholder="请输入字典编码" v-model="model.dictCode"/>
</a-form-model-item>
<a-form-item
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="描述">
<a-input v-decorator="[ 'description']"/>
</a-form-item>
<a-input v-model="model.description"/>
</a-form-model-item>
</a-form>
</a-form-model>
</a-spin>
</a-modal>
</template>
@ -58,14 +62,12 @@
sm: { span: 16 }
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
dictName: { rules: [{ required: true, message: '请输入字典名称!' }] },
dictCode: {
rules: [{ required: true, message: '请输入字典编码!' },
{ validator: this.validateDictCode }]
dictName: [{ required: true, message: '请输入字典名称!' }],
dictCode: [
{ required: true, message: '请输入字典编码!' },
{ validator: this.validateDictCode }]
}
}
}
},
created() {
@ -99,30 +101,24 @@
} else {
this.visiblekey = false
}
this.form.resetFields()
this.model = Object.assign({}, record)
this.visible = true
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'dictName', 'dictCode', 'description'))
})
},
// 确定
handleOk() {
const that = this
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true
values.dictName = (values.dictName || '').trim()
values.dictCode = (values.dictCode || '').trim()
values.description = (values.description || '').trim()
let formData = Object.assign(this.model, values)
this.model.dictName = (this.model.dictName || '').trim()
this.model.dictCode = (this.model.dictCode || '').trim()
this.model.description = (this.model.description || '').trim()
let obj
console.log(formData)
if (!this.model.id) {
obj = addDict(formData)
obj = addDict(this.model)
} else {
obj = editDict(formData)
obj = editDict(this.model)
}
obj.then((res) => {
if (res.success) {
@ -135,6 +131,8 @@
that.confirmLoading = false
that.close()
})
}else{
return false;
}
})
},
@ -145,6 +143,7 @@
close() {
this.$emit('close')
this.visible = false
this.$refs.form.resetFields();
}
}
}

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