Compare commits

..

45 Commits

Author SHA1 Message Date
06847cd801 论坛变更域名:bbs.jeecg.com 2020-01-19 09:28:12 +08:00
365810d4e6 字典排序问题合并 2020-01-13 12:03:30 +08:00
ed83135062 Merge pull request #844 from yyri/master
<a-form-item> should be nested under <a-col>
2020-01-13 11:47:00 +08:00
beabf9b6dd README.md 2020-01-13 11:37:30 +08:00
238b4898c7 20191227 取消系统功能的权限注解 2019-12-27 15:00:22 +08:00
4372773924 <a-form-item> should be nested under <a-col> 2019-12-26 11:11:12 +08:00
d399ec904a Jeecg-Boot 2.1.3 大屏版本发布 2019-12-25 15:50:15 +08:00
8ecc971940 Jeecg-Boot 2.1.3 大屏版本发布 2019-12-25 15:14:54 +08:00
66b3b290fb Jeecg-Boot 2.1.3 大屏版本发布 2019-12-25 13:36:36 +08:00
a9c7f3e547 Jeecg-Boot 2.1.3 大屏版本发布 2019-12-25 13:34:06 +08:00
b54dada91e 2.1.2 大屏版本发布 2019-12-25 13:28:04 +08:00
3ead7c3ae1 Merge branch 'master' of https://github.com/zhangdaiscott/jeecg-boot.git 2019-12-25 13:26:13 +08:00
9c44ffaa8e 2.1.3 大屏版本发布 2019-12-25 13:25:10 +08:00
ea5ef384f2 2.1.3 大屏版本发布 2019-12-25 13:14:08 +08:00
73f7acfd5a Merge pull request #787 from a63149300/patch-1
Update UserList.vue
2019-12-15 16:38:43 +08:00
728d62f851 Jeecg-Boot 2.1.2版本发布 2019-12-09 14:46:40 +08:00
cd471735d7 Update UserList.vue
修改状态文字
2019-12-06 09:13:44 +08:00
30b35af000 提供oracle11g\sqlserver2017脚步 2019-11-27 15:56:17 +08:00
3372c88607 统计 2019-11-25 15:04:34 +08:00
ce95008fdd 统计下载量 2019-11-25 14:58:00 +08:00
bb54b20734 统计下载 2019-11-25 14:56:27 +08:00
bd790ee24b 统计下载 2019-11-25 14:54:46 +08:00
11018ab29f 统计下载 2019-11-25 14:53:26 +08:00
67c4f7b3d9 Jeecg-Boot 2.1.2 版本发布 2019-11-22 09:45:28 +08:00
9bd67f9905 Jeecg-Boot 2.1.2版本发布 2019-11-21 18:20:40 +08:00
283be0480e Jeecg-Boot 2.1.2版本发布 2019-11-21 18:17:25 +08:00
f0d372d008 Merge branch 'master' of https://github.com/zhangdaiscott/jeecg-boot.git 2019-11-21 12:26:02 +08:00
65180733e1 Signed-off-by: zhangdaihao <zhangdaiscott@163.com> 2019-11-21 12:25:58 +08:00
c1dab6276a Merge pull request #647 from klniu/master
返回前端数据去除密码与盐
2019-11-19 16:35:41 +08:00
a6b0dccded 投票 2019-11-18 20:02:28 +08:00
bb24448ea2 QQ群支持 2019-10-29 12:04:17 +08:00
07694cf42b 数据库版本描述 2019-10-29 12:04:02 +08:00
2b544b74f7 返回前端数据去除密码与盐 2019-10-21 16:50:25 +08:00
ac891d81ab 返回前端数据去除密码与盐 2019-10-21 14:49:17 +08:00
0640f0b421 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-21 12:10:39 +08:00
ee5fa7ec22 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-21 12:08:30 +08:00
8b41076a27 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-21 11:30:26 +08:00
492ce922e9 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-21 11:27:42 +08:00
fce50e5209 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-21 11:26:02 +08:00
107e901853 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-20 22:49:11 +08:00
c69884c84f JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-20 22:11:27 +08:00
5e2eba86e7 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-19 16:03:45 +08:00
9c6f68fd4a JeecgBoot 2.1.1 版本发布 2019-10-19 15:44:19 +08:00
fd57f233e5 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-18 19:38:34 +08:00
04c0ea55f2 JeecgBoot 2.1.1 代码生成器AI版本发布 2019-10-18 18:37:41 +08:00
469 changed files with 72936 additions and 25853 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
## ide
**/.idea
*.iml
## backend
**/target
**/logs
## front
**/*.lock

View File

@ -1,4 +1,5 @@
![JEECG](https://static.oschina.net/uploads/img/201905/24164523_XDhg.png "JeecgBoot快速开发平台")
@ -6,11 +7,12 @@
Jeecg-Boot 快速开发平台(前后端分离版本)
===============
当前最新版本: 2.1.0发布日期20190826
当前最新版本: 2.1.3发布日期20191226
[![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-JEECG团队-orange.svg)](http://www.jeecg.com)
[![](https://img.shields.io/badge/version-2.0-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![](https://img.shields.io/badge/version-2.1.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)
@ -21,7 +23,8 @@ Jeecg-Boot 快速开发平台(前后端分离版本)
<h3 align="center">Java RAD framework for enterprise web applications</h3>
Jeecg-Boot 是一款基于SpringBoot+代码生成器的快速开发平台前后端分离架构SpringBoot,Ant Design Vue,Mybatis,Shiro,JWT。强大的代码生成器让前端和后台代码一键生成,不需要写任何代码保持jeecg一贯的强大绝对是全栈开发福音 JeecgBoot在提高UI能力的同时降低了前后分离的开发成本JeecgBoot还独创在线开发模式No代码概念,一系列在线智能开发:在线配置表单、在线配置报表、在线图表设计、在线设计流程等等
JeecgBoot 是一款基于代码生成器的J2EE快速开发平台!采用前后端分离架构SpringBoot2.xAnt Design&VueMybatis-plusShiroJWT。强大的代码生成器让前端代码一键生成,无需写任何代码! JeecgBoot引领新的开发模式(Online Coding模式-> 代码生成器模式-> 手工MERGE智能开发) 帮助解决Java项目70%的重复工作,让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省成本,同时又不失灵活性!JeecgBoot还独创在线开发模式No代码概念在线表单配置表单设计器)、移动配置能力、工作流配置(在线设计流程)、报表配置能力、在线图表配置、插件能力(可插拔)等等
JEECG宗旨是: 简单功能由Online Coding配置实现在线配置表单、在线配置报表、在线图表设计、在线设计流程、在线设计表单复杂功能由代码生成器生成进行手工Merge既保证了智能又兼顾了灵活;
业务流程采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计松耦合、并支持任务节点灵活配置既保证了公司流程的保密性又减少了开发人员的工作量。
@ -44,7 +47,7 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
- 视频教程 [JeecgBoot入门系列视频](https://space.bilibili.com/454617261/channel/detail?cid=84186)
- 常见问题: [入门常见问题大全](http://www.jeecg.org/forum.php?mod=viewthread&tid=7816&extra=page%3D1)
- 常见问题: [入门常见问题大全](http://bbs.jeecg.com/forum.php?mod=viewthread&tid=7816&extra=page%3D1)
- 更新日志: [版本日志](http://www.jeecg.com/#/doc/changelog)
@ -53,7 +56,7 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
交流互动
-----------------------------------
- QQ交流群 ①284271917、②769925425
- QQ交流群 ②769925425、①284271917
- 反馈问题: [反馈问题请按格式发Issues](https://github.com/zhangdaiscott/jeecg-boot/issues/new)
@ -162,6 +165,8 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
│ └─树分类字典
│ └─系统公告
│ └─我的组织机构
│ └─职务管理
│ └─通讯录
├─消息中心
│ ├─消息管理
│ ├─模板管理
@ -199,7 +204,12 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
│ └─进度条
│ └─排名列表
│ └─等等
│─大屏模板
│ ├─作战指挥中心大屏
│ └─物流服务中心大屏
│─常用示例
│ ├─自定义组件
│ ├─对象存储(对接阿里云)
│ ├─单表模型例子
│ └─一对多模型例子
│ └─打印例子
@ -208,7 +218,10 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
│ └─常用选择组件
│ └─异步树table
│ └─接口模拟测试
│ └─表格合计示例
│ └─异步树列表示例
│ └─一对多JEditable
│ └─JEditable组件示例
│ └─图片拖拽排序
│ └─图片翻页
│ └─图片预览
@ -240,15 +253,16 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
│ └─异常页面
│ └─个人页面
├─高级功能
│ ├─系统编码规则
│ ├─提供单点登录CAS集成方案
│ ├─提供APP发布方案
│ ├─集成Websocket消息通知机制
├─Online在线开发(暂未开源)
│ ├─Online在线表单 - 功能已开放
│ ├─在线代码生成器 - 功能已开放
│ ├─Online在线报表 - 功能已开放
│ ├─Online在线图表
│ ├─Online图表模板配置
│ ├─Online在线报表
│ ├─高级表单设计器
│─流程模块功能 (暂不开源)
│ ├─流程设计器
@ -277,7 +291,7 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
- jdk8
- mysql
- redis
- 数据库脚jeecg-boot\docs\jeecg-boot-mysql.sql
- 数据库脚jeecg-boot\docs\jeecg-boot-mysql.sql
- 默认登录账号: admin/123456
@ -327,10 +341,13 @@ yarn run lint
系统效果
----
##### 大屏模板
![输入图片说明](https://static.oschina.net/uploads/img/201912/25133248_Ag1C.jpg "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201912/25133301_k9Kc.jpg "在这里输入图片标题")
##### PC端
![输入图片说明](https://static.oschina.net/uploads/img/201904/14155402_AmlV.png "在这里输入图片标题")
![输入图片说明](https://oscimg.oschina.net/oscnet/ba807921197596ba56f495d4b22ee3280ca.jpg "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160657_cHwb.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160813_KmXS.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160935_Nibs.png "在这里输入图片标题")

View File

@ -1,13 +1,13 @@
Ant Design Jeecg Vue
====
当前最新版本: 2.1.0发布日期20190826
当前最新版本: 2.1.3发布日期20191226
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,7 +1,7 @@
{
"name": "vue-antd-jeecg",
"version": "2.1.0",
"private": false,
"version": "2.1.3",
"private": true,
"scripts": {
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
"serve": "vue-cli-service serve",
@ -10,9 +10,9 @@
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"@jeecg/antd-onine": "^1.0.1",
"@jeecg/antd-online-re": "2.1.3",
"@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "^1.3.9",
"ant-design-vue": "^1.4.0",
"apexcharts": "^3.6.5",
"axios": "^0.18.0",
"clipboard": "^2.0.4",
@ -34,7 +34,7 @@
"vue-loader": "^15.7.0",
"vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.8",
"vue-print-nb-jeecg": "^1.0.9",
"vue-property-decorator": "^7.3.0",
"vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4",
@ -55,7 +55,8 @@
"less-loader": "^4.1.0",
"node-sass": "^4.11.0",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.6.10"
"vue-template-compiler": "^2.6.10",
"html-webpack-plugin": "^4.0.0-beta.11"
},
"eslintConfig": {
"root": true,

View File

@ -245,6 +245,7 @@
window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot';
window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas';
window._CONFIG['imgDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/view';
window._CONFIG['downloadUrl'] = window._CONFIG['domianURL'] + '/sys/common/download';
window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe';
</script>
</head>

View File

@ -31,6 +31,11 @@ const changPassword = (params)=>putAction("/sys/user/changPassword",params);
const addPermission= (params)=>postAction("/sys/permission/add",params);
const editPermission= (params)=>putAction("/sys/permission/edit",params);
const getPermissionList = (params)=>getAction("/sys/permission/list",params);
/*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
/*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
// const deletePermission = (params)=>deleteAction("/sys/permission/delete",params);
// const deletePermissionList = (params)=>deleteAction("/sys/permission/deleteBatch",params);
const queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params);
@ -87,6 +92,8 @@ const queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params
const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params);
// 重复校验
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
// 加载分类字典
const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params);
export {
// imgView,
@ -133,6 +140,9 @@ export {
queryUserRoleMap,
duplicateCheck,
queryTreeListForRole,
getSystemMenuList,
getSystemSubmenu,
loadCategoryData
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -40,3 +40,8 @@
/*列表中范围查询样式*/
.query-group-cust{width: calc(50% - 10px)}
.query-group-split-cust:before{content:"~";width: 20px;display: inline-block;text-align: center}
/*erp风格子表外框padding设置*/
.ant-card-wider-padding.cust-erp-sub-tab>.ant-card-body{padding:5px 12px}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,7 +1,7 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<div :style="{ padding: '0 50px 32px 0' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding">
<v-tooltip/>
<v-legend/>
<v-axis/>
@ -23,13 +23,13 @@
dataSource: {
type: Array,
default: () => [
{ type: '10:10', bar: 2, line: 2 },
{ type: '10:15', bar: 6, line: 3 },
{ type: '10:20', bar: 2, line: 5 },
{ type: '10:25', bar: 9, line: 1 },
{ type: '10:30', bar: 2, line: 3 },
{ type: '10:35', bar: 2, line: 1 },
{ type: '10:40', bar: 1, line: 2 }
{ type: '10:10', bar: 200, line: 1000 },
{ type: '10:15', bar: 600, line: 1000},
{ type: '10:20', bar: 200, line: 1000},
{ type: '10:25', bar: 900, line: 1000},
{ type: '10:30', bar: 200, line: 1000},
{ type: '10:35', bar: 200, line: 1000},
{ type: '10:40', bar: 100, line: 1000}
]
},
height: {
@ -39,6 +39,7 @@
},
data() {
return {
padding: { top:50, right:50, bottom:100, left:50 },
scale: [{
dataKey: 'bar',
min: 0

View File

@ -1,7 +1,7 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :forceFit="true" :height="height" :data="data">
<v-chart :forceFit="true" :height="254" :data="chartData" :padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-legend />
@ -13,6 +13,11 @@
<script>
import { DataSet } from '@antv/data-set'
const sourceDataConst = [
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 },
];
const fieldsConst = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.'];
export default {
name: 'BarMultid',
props: {
@ -20,46 +25,47 @@
type: String,
default: ''
},
dataSource:{
type: Array,
default: () => [
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }
]
sourceData:{
type:Array,
default:()=>[]
},
fields:{
type: Array,
default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.']
},
height: {
type: Number,
default: 254
type:Array,
default:()=>[]
}
},
data() {
return {
chartData:"",
height: 400,
adjust: [{
type: 'dodge',
marginRatio: 1 / 32
}]
marginRatio: 1 / 32,
}],
};
},
watch: {
'sourceData': function () {
this.drawChart();
}
},
computed: {
data() {
const dv = new DataSet.View().source(this.dataSource)
mounted(){
this.drawChart()
},
methods:{
drawChart(){
let temp = sourceDataConst;
if(this.sourceData && this.sourceData.length>0){
temp = this.sourceData
}
const dv = new DataSet.View().source(temp);
dv.transform({
type: 'fold',
fields: this.fields,
fields:(!this.fields||this.fields.length==0)?fieldsConst:this.fields,
key: 'x',
value: 'y'
})
// bar 使用不了 - 和 / 所以替换下
return dv.rows.map(row => {
row.x = row.x.replace(/[-/]/g, '_')
return row
})
value: 'y',
});
this.chartData=dv.rows;
}
}
}

View File

@ -1,6 +1,6 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<v-chart :forceFit="true" :height="350" :data="chartData" :scale="scale">
<v-chart :forceFit="true" :height="300" :data="chartData" :scale="scale">
<v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord>
<v-axis
dataKey="value"
@ -32,7 +32,7 @@
type="arc"
:zIndex="1"
:start="arcGuide2Start"
:end="getArcGuide2End()"
:end="getArcGuide2End"
:vStyle="arcGuide2Style"
></v-guide>
<v-guide
@ -88,7 +88,7 @@
}];
const data = [
{ value: 0},
{ value: 7.0 },
];
export default {
@ -96,7 +96,7 @@
props:{
datasource:{
type: Number,
default:0
default:7
},
title: {
type: String,

View File

@ -0,0 +1,61 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart
height="254"
:data="datasource"
:forceFit="true"
:padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
const data = []
for (let i = 0; i < 12; i += 1) {
data.push({
x: `${i + 1}`,
y: Math.floor(Math.random() * 1000) + 200
})
}
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 22
}]
export default {
name: "Bar",
props: {
title: {
type: String,
default: ''
}
},
mounted(){
this.datasource = data
},
data () {
return {
datasource:[],
scale,
tooltip
}
}
}
</script>

View File

@ -42,6 +42,11 @@
type: Array,
default: () => ['jeecg', 'jeebt']
},
// 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}]
aliases:{
type: Array,
default: () => []
},
height: {
type: Number,
default: 254
@ -66,7 +71,17 @@
key: 'x',
value: 'y'
})
return dv.rows
let rows = dv.rows
// 替换别名
rows.forEach(row => {
for (let item of this.aliases) {
if (item.field === row.x) {
row.x = item.alias
break
}
}
})
return rows
}
}
}

View File

@ -3,7 +3,7 @@
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group>
<a-select v-else-if="tagType=='select'" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput">
<a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput">
<a-select-option value="">请选择</a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
@ -32,15 +32,23 @@
tagType:""
}
},
watch:{
dictCode:{
immediate:true,
handler() {
this.initDictData()
},
}
},
created() {
console.log(this.dictCode);
// console.log(this.dictCode);
if(!this.type || this.type==="list"){
this.tagType = "select"
}else{
this.tagType = this.type
}
//获取字典数据
this.initDictData();
// this.initDictData();
},
methods: {
initDictData() {

View File

@ -28,13 +28,16 @@ export async function initDictOptions(dictCode) {
* @return String
*/
export function filterDictText(dictOptions, text) {
let re = "";
dictOptions.forEach(function (option) {
if (text === option.value) {
re = option.text;
//--update-begin----author:sunjianlei---date:20191025------for:修复字典替换方法在字典没有加载完成之前报错的问题、修复没有找到字典时返回空值的问题---
if (dictOptions instanceof Array) {
for (let dictItem of dictOptions) {
if (text === dictItem.value) {
return dictItem.text
}
}
});
return re;
}
return text
//--update-end----author:sunjianlei---date:20191025------for:修复字典替换方法在字典没有加载完成之前报错的问题、修复没有找到字典时返回空值的问题---
}
/**
@ -44,7 +47,7 @@ export function filterDictText(dictOptions, text) {
* @return String
*/
export function filterMultiDictText(dictOptions, text) {
if(!text){
if(!text || !dictOptions || dictOptions.length==0){
return ""
}
let re = "";
@ -58,7 +61,7 @@ export function filterMultiDictText(dictOptions, text) {
}
});
if(re==""){
return "";
return text;
}
return re.substring(0,re.length-1);
}

View File

@ -9,7 +9,8 @@
@change="onChange"
:disabled="disabled"
mode="multiple"
:placeholder="placeholder">
:placeholder="placeholder"
allowClear>
<a-select-option
v-for="(item,index) in dictOptions"
:key="index"

View File

@ -10,6 +10,7 @@
style="width: 100%"
:filterOption="false"
@change="handleAsyncChange"
allowClear
:notFoundContent="loading ? undefined : null"
>
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
@ -25,6 +26,7 @@
@change="handleChange"
:filterOption="filterOption"
v-model="selectedValue"
allowClear
:notFoundContent="loading ? undefined : null">
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>

View File

@ -0,0 +1,240 @@
<template>
<a-tree-select
allowClear
labelInValue
style="width: 100%"
:disabled="disabled"
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
:placeholder="placeholder"
:loadData="asyncLoadTreeData"
:value="treeValue"
:treeData="treeData"
:multiple="multiple"
@change="onChange">
</a-tree-select>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
name: 'JCategorySelect',
props: {
value:{
type: String,
required: false
},
placeholder:{
type: String,
default: '请选择',
required: false
},
disabled:{
type:Boolean,
default:false,
required:false
},
condition:{
type:String,
default:'',
required:false
},
// 是否支持多选
multiple: {
type: Boolean,
default: false,
},
loadTriggleChange:{
type: Boolean,
default: false,
required:false
},
pid:{
type:String,
default:'',
required:false
},
pcode:{
type:String,
default:'',
required:false
},
back:{
type:String,
default:'',
required:false
}
},
data () {
return {
treeValue:"",
treeData:[],
url:"/sys/category/loadTreeData",
view:'/sys/category/loadDictItem/',
tableName:"",
text:"",
code:"",
}
},
watch: {
value () {
this.loadItemByCode()
},
pcode(){
this.loadRoot();
}
},
created(){
this.validateProp().then(()=>{
this.loadRoot()
this.loadItemByCode()
})
},
methods: {
/**加载一级节点 */
loadRoot(){
let param = {
pid:this.pid,
pcode:this.pcode,
condition:this.condition
}
getAction(this.url,param).then(res=>{
if(res.success && res.result){
for(let i of res.result){
i.value = i.key
if(i.leaf==false){
i.isLeaf=false
}else if(i.leaf==true){
i.isLeaf=true
}
}
this.treeData = [...res.result]
}else{
console.log("树一级节点查询结果-else",res)
}
})
},
/** 数据回显*/
loadItemByCode(){
if(!this.value || this.value=="0"){
this.treeValue = []
}else{
getAction(this.view,{ids:this.value}).then(res=>{
console.log(124345)
console.log(124345,res)
if(res.success){
let values = this.value.split(',')
this.treeValue = res.result.map((item, index) => ({
key: values[index],
value: values[index],
label: item
}))
this.onLoadTriggleChange(res.result[0]);
}
})
}
},
onLoadTriggleChange(text){
//只有单选才会触发
if(!this.multiple && this.loadTriggleChange){
this.backValue(this.value,text)
}
},
backValue(value,label){
let obj = {}
if(this.back){
obj[this.back] = label
}
this.$emit('change', value, obj)
},
asyncLoadTreeData (treeNode) {
return new Promise((resolve) => {
if (treeNode.$vnode.children) {
resolve()
return
}
let pid = treeNode.$vnode.key
let param = {
pid:pid,
condition:this.condition
}
getAction(this.url,param).then(res=>{
if(res.success){
for(let i of res.result){
i.value = i.key
if(i.leaf==false){
i.isLeaf=false
}else if(i.leaf==true){
i.isLeaf=true
}
}
this.addChildren(pid,res.result,this.treeData)
this.treeData = [...this.treeData]
}
resolve()
})
})
},
addChildren(pid,children,treeArray){
if(treeArray && treeArray.length>0){
for(let item of treeArray){
if(item.key == pid){
if(!children || children.length==0){
item.isLeaf=true
}else{
item.children = children
}
break
}else{
this.addChildren(pid,children,item.children)
}
}
}
},
onChange(value){
if(!value){
this.$emit('change', '');
this.treeValue = ''
} else if (value instanceof Array) {
//this.$emit('change', value.map(item => item.value).join(','))
//this.treeValue = value
} else {
this.backValue(value.value,value.label)
this.treeValue = value
}
},
getCurrTreeData(){
return this.treeData
},
validateProp(){
let mycondition = this.condition
return new Promise((resolve,reject)=>{
if(!mycondition){
resolve();
}else{
try {
let test=JSON.parse(mycondition);
if(typeof test == 'object' && test){
resolve()
}else{
this.$message.error("组件JTreeSelect-condition传值有误需要一个json字符串!")
reject()
}
} catch(e) {
this.$message.error("组件JTreeSelect-condition传值有误需要一个json字符串!")
reject()
}
}
})
}
},
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
model: {
prop: 'value',
event: 'change'
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<a-checkbox-group :options="options" :value="checkboxArray" @change="onChange" />
<a-checkbox-group :options="options" :value="checkboxArray" v-bind="$attrs" @change="onChange" />
</template>
<script>

View File

@ -228,10 +228,11 @@
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.coderOptions)
// 编辑器赋值
this.coder.setValue(this.value || this.code)
if(this.value||this.code){
this.hasCode=true
this.coder.setValue(this.value || this.code)
}else{
this.coder.setValue('')
this.hasCode=false
}
// 支持双向绑定
@ -266,7 +267,13 @@
return this.code
},
setCodeContent(val){
this.coder.setValue(val)
setTimeout(()=>{
if(!val){
this.coder.setValue('')
}else{
this.coder.setValue(val)
}
},300)
},
// 获取当前语法类型
_getLanguage (language) {
@ -405,5 +412,7 @@
}
.CodeMirror-cursor{
height:18.4px !important;
}
</style>

View File

@ -18,9 +18,6 @@
value: {
required: false,
type: String,
default:()=>{
return '* * * * * ? *'
}
}
},
data(){

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver/theme'
import 'tinymce/plugins/image'
import 'tinymce/plugins/link'
import 'tinymce/plugins/media'
import 'tinymce/plugins/table'
import 'tinymce/plugins/lists'
@ -42,11 +43,12 @@
},
plugins: {
type: [String, Array],
default: 'lists image media table textcolor wordcount contextmenu fullscreen'
default: 'lists image link media table textcolor wordcount contextmenu fullscreen'
},
toolbar: {
type: [String, Array],
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat | fullscreen'
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists link unlink image media table | removeformat | fullscreen',
branding:false
}
},
data() {
@ -61,6 +63,7 @@
toolbar: this.toolbar,
branding: false,
menubar: false,
toolbar_drawer: false,
images_upload_handler: (blobInfo, success) => {
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
success(img)
@ -87,12 +90,9 @@
this.myValue = (newValue == null ? '' : newValue)
},
myValue(newValue) {
console.log(newValue)
if(this.triggerChange){
console.log(1)
this.$emit('change', newValue)
}else{
console.log(2)
this.$emit('input', newValue)
}
}

View File

@ -1,12 +1,13 @@
<template>
<div v-if="disabled" class="jeecg-form-container-disabled">
<div :class="disabled?'jeecg-form-container-disabled':''">
<fieldset disabled>
<slot name="detail"></slot>
</fieldset>
<slot name="edit"></slot>
<fieldset disabled>
<slot></slot>
</fieldset>
</div>
<div v-else>
<slot></slot>
</div>
</template>
<script>

View File

@ -5,6 +5,8 @@
</template>
<script>
import { getAction } from '@/api/manage'
export default {
name: 'JGraphicCode',
props: {
@ -59,6 +61,11 @@
contentHeight: {
type: Number,
default: 38
},
remote:{
type:Boolean,
default:false,
required:false
}
},
methods: {
@ -74,20 +81,21 @@
return 'rgb(' + r + ',' + g + ',' + b + ')'
},
drawPic () {
this.randomCode()
let canvas = document.getElementById('gc-canvas')
let ctx = canvas.getContext('2d')
ctx.textBaseline = 'bottom'
// 绘制背景
ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
// 绘制文字
for (let i = 0; i < this.code.length; i++) {
this.drawText(ctx, this.code[i], i)
}
this.drawLine(ctx)
this.drawDot(ctx)
this.$emit("success",this.code)
this.randomCode().then(()=>{
let canvas = document.getElementById('gc-canvas')
let ctx = canvas.getContext('2d')
ctx.textBaseline = 'bottom'
// 绘制背景
ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
// 绘制文字
for (let i = 0; i < this.code.length; i++) {
this.drawText(ctx, this.code[i], i)
}
this.drawLine(ctx)
this.drawDot(ctx)
this.$emit("success",this.code)
})
},
drawText (ctx, txt, i) {
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
@ -136,6 +144,31 @@
this.drawPic()
},
randomCode(){
return new Promise((resolve)=>{
if(this.remote==true){
getAction("/sys/getCheckCode").then(res=>{
console.log("aaaaa",res)
if(res.success){
this.checkKey = res.result.key
this.code = res.result.code
resolve();
}else{
this.$message.error("生成验证码错误,请联系系统管理员")
this.code = 'BUG'
resolve();
}
}).catch(()=>{
console.log("生成验证码连接服务器异常")
this.code = 'BUG'
resolve();
})
}else{
this.randomLocalCode();
resolve();
}
})
},
randomLocalCode(){
let random = ''
//去掉了I l i o O
let str = "QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm1234567890"
@ -144,6 +177,12 @@
random += str[index];
}
this.code = random
},
getLoginParam(){
return {
checkCode:this.code,
checkKey:this.checkKey
}
}
},
mounted () {
@ -151,7 +190,8 @@
},
data(){
return {
code:""
code:"",
checkKey:""
}
}

View File

@ -0,0 +1,95 @@
<template>
<a-input :placeholder="placeholder" :value="inputVal" @input="backValue"></a-input>
</template>
<script>
const JINPUT_QUERY_LIKE = 'like';
const JINPUT_QUERY_NE = 'ne';
const JINPUT_QUERY_GE = 'ge'; //大于等于
const JINPUT_QUERY_LE = 'le'; //小于等于
export default {
name: 'JInput',
props:{
value:{
type:String,
required:false
},
type:{
type:String,
required:false,
default:JINPUT_QUERY_LIKE
},
placeholder:{
type:String,
required:false,
default:''
}
},
watch:{
value:{
immediate:true,
handler:function(){
this.initVal();
}
}
},
model: {
prop: 'value',
event: 'change'
},
data(){
return {
inputVal:''
}
},
methods:{
initVal(){
if(!this.value){
this.inputVal = ''
}else{
let text = this.value
switch (this.type) {
case JINPUT_QUERY_LIKE:
text = text.substring(1,text.length-1);
break;
case JINPUT_QUERY_NE:
text = text.substring(1);
break;
case JINPUT_QUERY_GE:
text = text.substring(2);
break;
case JINPUT_QUERY_LE:
text = text.substring(2);
break;
default:
}
this.inputVal = text
}
},
backValue(e){
let text = e.target.value
switch (this.type) {
case JINPUT_QUERY_LIKE:
text = "*"+text+"*";
break;
case JINPUT_QUERY_NE:
text = "!"+text;
break;
case JINPUT_QUERY_GE:
text = ">="+text;
break;
case JINPUT_QUERY_LE:
text = "<="+text;
break;
default:
}
this.$emit("change",text)
}
}
}
</script>
<style scoped>
</style>

View File

@ -59,8 +59,13 @@
this.mouseMoveStata = false;
var width = e.clientX - this.beginClientX;
if(width<this.maxwidth){
document.getElementsByClassName('handler')[0].style.left = 0 + 'px';
document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px';
// ---- update-begin- author:sunjianlei --- date:20191009 --- for: 修复获取不到 handler 的时候报错 ----
let handler = document.getElementsByClassName('handler')[0]
if (handler) {
handler.style.left = 0 + 'px'
document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px'
}
// ---- update-end- author:sunjianlei --- date:20191009 --- for: 修复获取不到 handler 的时候报错 ----
}
} //mouseup事件
},

View File

@ -1,152 +1,466 @@
<template>
<div class="j-super-query-box">
<slot>
<a-tooltip v-if="superQueryFlag" title="已有高级查询条件生效">
<a-button type="primary" @click="visible=true">
<a-icon type="appstore" theme="twoTone" :spin="true"></a-icon>
<span>高级查询</span>
</a-button>
</a-tooltip>
<a-button v-else type="primary" icon="filter" @click="visible=true">高级查询</a-button>
</slot>
<a-modal
title="高级查询构造器"
:width="800"
:width="1000"
:visible="visible"
:confirmLoading="confirmLoading"
@cancel="handleCancel"
:mask="false"
wrapClassName="ant-modal-cust-warp"
class="j-super-query-modal"
style="top:5%;max-height: 95%;">
<template slot="footer">
<a-button @click="handleCancel"> </a-button>
<a-button @click="handleReset" style="float: left"> </a-button>
<a-button type="primary" @click="handleOk"> </a-button>
<div style="float: left">
<a-button :loading="loading" @click="handleReset">重置</a-button>
<a-button :loading="loading" @click="handleSave">保存查询条件</a-button>
</div>
<a-button :loading="loading" @click="handleCancel">关闭</a-button>
<a-button :loading="loading" type="primary" @click="handleOk">查询</a-button>
</template>
<a-spin :spinning="confirmLoading">
<a-form>
<div>
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">
<a-spin :spinning="loading">
<a-row>
<a-col :sm="24" :md="24-5">
<a-col :span="6">
<a-select placeholder="选择查询字段" v-model="item.field" @select="(val,option)=>handleSelected(option,item)">
<a-select-option v-for="(f,fIndex) in fieldList" :key=" 'field'+fIndex" :value="f.value" :data-type="f.type">{{ f.text }}</a-select-option>
<a-empty v-if="queryParamsModel.length === 0">
<div slot="description">
<span>没有任何查询条件</span>
<a-divider type="vertical"/>
<a @click="handleAdd">点击新增</a>
</div>
</a-empty>
<a-form v-else layout="inline">
<a-form-item label="过滤条件匹配" style="margin-bottom: 12px;">
<a-select v-model="selectValue" :getPopupContainer="node=>node.parentNode">
<a-select-option value="and">AND所有条件都要求匹配</a-select-option>
<a-select-option value="or">OR条件中的任意一个匹配</a-select-option>
</a-select>
</a-col>
</a-form-item>
<a-col :span="6">
<a-select placeholder="选择匹配规则" v-model="item.rule">
<a-select-option value="eq">等于</a-select-option>
<a-select-option value="ne">不等于</a-select-option>
<a-select-option value="gt">大于</a-select-option>
<a-select-option value="ge">大于等于</a-select-option>
<a-select-option value="lt">小于</a-select-option>
<a-select-option value="le">小于等于</a-select-option>
<a-select-option value="right_like">..开始</a-select-option>
<a-select-option value="left_like">..结尾</a-select-option>
<a-select-option value="like">包含</a-select-option>
<a-select-option value="in">...</a-select-option>
</a-select>
</a-col>
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">
<a-col :span="6">
<j-date v-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期"></j-date>
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss"></j-date>
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
<a-input v-else v-model="item.val" placeholder="请输入值" />
</a-col>
<a-col :span="8">
<a-tree-select
showSearch
v-model="item.field"
:treeData="fieldTreeData"
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="选择查询字段"
allowClear
treeDefaultExpandAll
:getPopupContainer="node=>node.parentNode"
style="width: 100%"
@select="(val,option)=>handleSelected(option,item)"
>
</a-tree-select>
</a-col>
<a-col :span="4">
<a-select placeholder="匹配规则" v-model="item.rule" :getPopupContainer="node=>node.parentNode">
<a-select-option value="eq">等于</a-select-option>
<a-select-option value="ne">不等于</a-select-option>
<a-select-option value="gt">大于</a-select-option>
<a-select-option value="ge">大于等于</a-select-option>
<a-select-option value="lt">小于</a-select-option>
<a-select-option value="le">小于等于</a-select-option>
<a-select-option value="right_like">以..开始</a-select-option>
<a-select-option value="left_like">以..结尾</a-select-option>
<a-select-option value="like">包含</a-select-option>
<a-select-option value="in">在...中</a-select-option>
</a-select>
</a-col>
<a-col :span="8">
<template v-if="item.dictCode">
<template v-if="item.type === 'table-dict'">
<j-popup
v-model="item.val"
:code="item.dictTable"
:field="item.dictCode"
:orgFields="item.dictCode"
:destFields="item.dictCode"
></j-popup>
</template>
<j-dict-select-tag v-else v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
</template>
<j-select-multi-user
v-else-if="item.type === 'select-user'"
v-model="item.val"
:buttons="false"
:multiple="false"
placeholder="请选择用户"
:returnKeys="['id', item.customReturnField || 'username']"
/>
<j-select-depart
v-else-if="item.type === 'select-depart'"
v-model="item.val"
:multi="false"
placeholder="请选择部门"
:customReturnField="item.customReturnField || 'id'"
/>
<a-select v-else-if="item.options instanceof Array" v-model="item.val" :options="item.options" allowClear placeholder="请选择"/>
<j-date v-else-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期" style="width: 100%"></j-date>
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></j-date>
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
<a-input v-else v-model="item.val" placeholder="请输入值"/>
</a-col>
<a-col :span="4">
<a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
<a-button @click="handleDel( index )" icon="minus"></a-button>
</a-col>
</a-row>
</a-form>
</a-col>
<a-col :sm="24" :md="5">
<!-- 查询记录 -->
<a-card class="j-super-query-history-card" :bordered="true">
<div slot="title">
保存的查询
</div>
<a-empty v-if="treeData.length === 0" class="j-super-query-history-empty" description="没有保存任何查询"/>
<a-tree
v-else
class="j-super-query-history-tree"
showIcon
:treeData="treeData"
@select="handleTreeSelect"
@rightClick="handleTreeRightClick"
>
</a-tree>
</a-card>
</a-col>
</a-row>
<a-col :span="6">
<a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
<a-button @click="handleDel( index )" icon="minus"></a-button>
</a-col>
</a-row>
</div>
</a-form>
</a-spin>
<a-modal title="请输入保存的名称" :visible="prompt.visible" @cancel="prompt.visible=false" @ok="handlePromptOk">
<a-input v-model="prompt.value"></a-input>
</a-modal>
</a-modal>
</div>
</template>
<script>
import ACol from 'ant-design-vue/es/grid/Col'
import JDate from '@/components/jeecg/JDate.vue';
import * as utils from '@/utils/util'
import JDate from '@/components/jeecg/JDate.vue'
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
export default {
name: 'JSuperQuery',
components: {
ACol,
JDate
},
data(){
return {
visible:false,
confirmLoading:false,
queryParamsModel:[{}]
}
},
props:{
/* fieldList:[{value:'',text:'',type:''}]
* type:date datetime int number string
components: { JDate, JSelectDepart, JSelectMultiUser },
props: {
/*
fieldList: [{
value:'',
text:'',
type:'',
dictCode:'' // 只要 dictCode 有值,无论 type 是什么,都显示为字典下拉框
}]
type:date datetime int number string
* */
fieldList:{
type:Array,
required:true
fieldList: {
type: Array,
required: true
},
/*
* 这个回调函数接收一个数组参数 即查询条件
* */
callback:{
type:String,
required:false,
default:'handleSuperQuery'
callback: {
type: String,
required: false,
default: 'handleSuperQuery'
},
// 当前是否在加载中
loading: {
type: Boolean,
default: false
},
// 保存查询条件的唯一 code通过该 code 区分
saveCode: {
type: String,
default: 'testSaveCode'
}
},
data() {
return {
fieldTreeData: [],
prompt: {
visible: false,
value: ''
},
visible: false,
queryParamsModel: [{}],
treeIcon: <a-icon type="file-text"/>,
treeData: [],
// 保存查询条件的前缀名
saveCodeBefore: 'JSuperQuerySaved_',
selectValue: 'and',
superQueryFlag: false
}
},
methods:{
show(){
if(!this.queryParamsModel ||this.queryParamsModel.length==0){
watch: {
// 当 saveCode 变化时,重新查询已保存的条件
saveCode: {
immediate: true,
handler(val) {
let list = this.$ls.get(this.saveCodeBefore + val)
if (list instanceof Array) {
this.treeData = list.map(item => {
item.icon = this.treeIcon
return item
})
}
}
},
fieldList: {
deep: true,
immediate: true,
handler(val) {
let mainData = [], subData = []
val.forEach(item => {
let data = { ...item }
data.label = data.label || data.text
let hasChildren = (data.children instanceof Array)
data.disabled = hasChildren
data.selectable = !hasChildren
if (hasChildren) {
data.children = data.children.map(item2 => {
let child = { ...item2 }
child.label = child.label || child.text
child.label = data.label + '-' + child.label
child.value = data.value + ',' + child.value
child.val = ''
return child
})
data.val = ''
subData.push(data)
} else {
mainData.push(data)
}
})
this.fieldTreeData = mainData.concat(subData)
}
}
},
methods: {
show() {
if (!this.queryParamsModel || this.queryParamsModel.length == 0) {
this.queryParamsModel = [{}]
}
this.visible = true;
this.visible = true
},
handleOk(){
console.log("---高级查询参数--->",this.queryParamsModel)
if(!this.isNullArray()){
this.$emit(this.callback, this.queryParamsModel)
}else{
this.$emit(this.callback)
handleOk() {
if (!this.isNullArray(this.queryParamsModel)) {
let event = {
matchType: this.selectValue,
params: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
}
console.log('---高级查询参数--->', event)
this.emitCallback(event.params, event.matchType)
} else {
this.emitCallback()
}
},
handleCancel(){
emitCallback(params, matchType) {
this.superQueryFlag = !!params
this.$emit(this.callback, params, matchType)
},
handleCancel() {
this.close()
},
close () {
this.$emit('close');
this.visible = false;
close() {
this.$emit('close')
this.visible = false
},
handleAdd () {
this.queryParamsModel.push({});
handleAdd() {
this.queryParamsModel.push({})
},
handleDel (index) {
handleDel(index) {
this.queryParamsModel.splice(index, 1)
},
handleSelected(node, item) {
let { type, options, dictCode, dictTable, customReturnField } = node.dataRef
item['type'] = type
item['options'] = options
item['dictCode'] = dictCode
item['dictTable'] = dictTable
item['customReturnField'] = customReturnField
this.$set(item, 'val', undefined)
},
handleReset() {
this.superQueryFlag = false
this.queryParamsModel = [{}]
this.emitCallback()
},
handleSave() {
let queryParams = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
if (this.isNullArray(queryParams)) {
this.$message.warning('空条件不能保存')
} else {
this.prompt.value = ''
this.prompt.visible = true
}
},
handlePromptOk() {
let { value } = this.prompt
// 判断有没有重名
let filterList = this.treeData.filter(i => i.title === value)
if (filterList.length > 0) {
this.$confirm({
content: `${value} 已存在,是否覆盖?`,
onOk: () => {
this.prompt.visible = false
filterList[0].records = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
this.saveToLocalStore()
this.$message.success('保存成功')
}
})
} else {
this.prompt.visible = false
this.treeData.push({
title: value,
icon: this.treeIcon,
records: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
})
this.saveToLocalStore()
this.$message.success('保存成功')
}
this.queryParamsModel.splice(index,1);
this.$message.warning("请关闭后重新打开")
},
handleSelected(option,item){
item['type'] = option.data.attrs['data-type']
handleTreeSelect(idx, event) {
if (event.selectedNodes[0]) {
this.queryParamsModel = utils.cloneObject(event.selectedNodes[0].data.props.records)
}
},
handleReset(){
this.queryParamsModel=[{}]
this.$emit(this.callback)
handleTreeRightClick(args) {
this.$confirm({
content: '是否删除当前查询?',
onOk: () => {
let { node: { eventKey } } = args
this.treeData.splice(Number.parseInt(eventKey.substring(2)), 1)
this.saveToLocalStore()
this.$message.success('删除成功')
},
})
},
isNullArray(){
// 将查询保存到 LocalStore 里
saveToLocalStore() {
this.$ls.set(this.saveCodeBefore + this.saveCode, this.treeData.map(item => {
return { title: item.title, records: item.records }
}))
},
isNullArray(array) {
//判断是不是空数组对象
if(!this.queryParamsModel || this.queryParamsModel.length==0){
if (!array || array.length === 0) {
return true
}
if(this.queryParamsModel.length==1){
let obj = this.queryParamsModel[0]
if(!obj.field || !obj.val || !obj.rule){
if (array.length === 1) {
let obj = array[0]
if (!obj.field || (obj.val == null || obj.val === '') || !obj.rule) {
return true
}
}
return false;
return false
},
// 去掉数组中的空对象
removeEmptyObject(array) {
for (let i = 0; i < array.length; i++) {
let item = array[i]
if (item == null || Object.keys(item).length <= 0) {
array.splice(i--, 1)
} else {
// 去掉特殊属性
delete item.options
}
}
return array
}
}
}
</script>
<style >
<style lang="scss" scoped>
.j-super-query-box {
display: inline-block;
}
.j-super-query-modal {
.j-super-query-history-card /deep/ {
.ant-card-body,
.ant-card-head-title {
padding: 0;
}
.ant-card-head {
padding: 4px 8px;
min-height: initial;
}
}
.j-super-query-history-empty /deep/ {
.ant-empty-image {
height: 80px;
line-height: 80px;
margin-bottom: 0;
}
img {
width: 80px;
height: 65px;
}
.ant-empty-description {
color: #afafaf;
margin: 8px 0;
}
}
.j-super-query-history-tree /deep/ {
.ant-tree-switcher {
display: none;
}
.ant-tree-node-content-wrapper {
width: 100%;
}
}
}
</style>

View File

@ -22,7 +22,7 @@
data(){
return {
treeData:[],
treeValue:"",
treeValue: null,
url_root:"/sys/category/loadTreeRoot",
url_children:"/sys/category/loadTreeChildren",
url_view:'/sys/category/loadOne',
@ -97,7 +97,7 @@
methods:{
loadViewInfo(){
if(!this.value || this.value=="0"){
this.treeValue = ""
this.treeValue = null
}else{
let param = {
field:this.field,

View File

@ -9,6 +9,7 @@
:loadData="asyncLoadTreeData"
:value="treeValue"
:treeData="treeData"
:multiple="multiple"
@change="onChange"
@search="onSearch">
</a-tree-select>
@ -45,7 +46,7 @@
},
pidValue:{
type: String,
default: '0',
default: '',
required: false
},
disabled:{
@ -57,11 +58,26 @@
type: String,
default: '',
required: false
},
condition:{
type:String,
default:'',
required:false
},
// 是否支持多选
multiple: {
type: Boolean,
default: false,
},
loadTriggleChange:{
type: Boolean,
default: false,
required:false
}
},
data () {
return {
treeValue:"",
treeValue: null,
treeData:[],
url:"/sys/dict/loadTreeData",
view:'/sys/dict/loadDictItem/',
@ -81,26 +97,36 @@
}
},
created(){
this.initDictInfo()
this.loadRoot()
this.loadItemByCode()
this.validateProp().then(()=>{
this.initDictInfo()
this.loadRoot()
this.loadItemByCode()
})
},
methods: {
loadItemByCode(){
if(!this.value || this.value=="0"){
this.treeValue = ""
this.treeValue = null
}else{
getAction(`${this.view}${this.dict}`,{key:this.value}).then(res=>{
if(res.success){
this.treeValue = {
key:this.value,
value:this.value,
label:res.result
}
let values = this.value.split(',')
this.treeValue = res.result.map((item, index) => ({
key: values[index],
value: values[index],
label: item
}))
this.onLoadTriggleChange(res.result[0]);
}
})
}
},
onLoadTriggleChange(text){
//只有单选才会触发
if(!this.multiple && this.loadTriggleChange){
this.$emit('change', this.value,text)
}
},
initDictInfo(){
let arr = this.dict.split(",")
this.tableName = arr[0]
@ -120,7 +146,8 @@
text:this.text,
code:this.code,
pidField:this.pidField,
hasChildField:this.hasChildField
hasChildField:this.hasChildField,
condition:this.condition
}
getAction(this.url,param).then(res=>{
if(res.success){
@ -162,7 +189,8 @@
text:this.text,
code:this.code,
pidField:this.pidField,
hasChildField:this.hasChildField
hasChildField:this.hasChildField,
condition:this.condition
}
getAction(this.url,param).then(res=>{
if(res.success && res.result){
@ -183,9 +211,12 @@
onChange(value){
if(!value){
this.$emit('change', '');
this.treeValue = ''
}else{
this.$emit('change', value.value);
this.treeValue = null
} else if (value instanceof Array) {
this.$emit('change', value.map(item => item.value).join(','))
this.treeValue = value
} else {
this.$emit('change', value.value,value.label)
this.treeValue = value
}
@ -195,6 +226,28 @@
},
getCurrTreeData(){
return this.treeData
},
validateProp(){
let mycondition = this.condition
return new Promise((resolve,reject)=>{
if(!mycondition){
resolve();
}else{
try {
let test=JSON.parse(mycondition);
console.log("aaaaasdsdd",typeof test)
if(typeof test == 'object' && test){
resolve()
}else{
this.$message.error("组件JTreeSelect-condition传值有误需要一个json字符串!")
reject()
}
} catch(e) {
this.$message.error("组件JTreeSelect-condition传值有误需要一个json字符串!")
reject()
}
}
})
}
},
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼

View File

@ -3,8 +3,11 @@
:rowKey="rowKey"
:columns="columns"
:dataSource="dataSource"
v-bind="tableProps"
@expand="handleExpand">
:expandedRowKeys="expandedRowKeys"
v-bind="tableAttrs"
v-on="$listeners"
@expand="handleExpand"
@expandedRowsChange="expandedRowKeys=$event">
<template v-for="(slotItem) of slots" :slot="slotItem" slot-scope="text, record, index">
<slot :name="slotItem" v-bind="{text,record,index}"></slot>
@ -30,8 +33,7 @@
},
queryParams: {
type: Object,
default: () => {
}
default: () => ({})
},
// 查询顶级时的值如果顶级为0则传0
topValue: {
@ -52,13 +54,23 @@
},
tableProps: {
type: Object,
default: () => {
}
default: () => ({})
},
/** 是否在创建组件的时候就查询数据 */
immediateRequest: {
type: Boolean,
default: true
},
condition:{
type:String,
default:'',
required:false
}
},
data() {
return {
dataSource: []
dataSource: [],
expandedRowKeys: []
}
},
computed: {
@ -77,6 +89,9 @@
}
}
return slots
},
tableAttrs() {
return Object.assign(this.$attrs, this.tableProps)
}
},
watch: {
@ -88,20 +103,44 @@
}
},
created() {
this.loadData()
if (this.immediateRequest) this.loadData()
},
methods: {
/** 加载数据*/
loadData(id = this.topValue, first = true, url = this.url) {
this.$emit('requestBefore', { first })
if (first) {
this.expandedRowKeys = []
}
let params = Object.assign({}, this.queryParams || {})
params[this.queryKey] = id
if(this.condition && this.condition.length>0){
params['condition'] = this.condition
}
return getAction(url, params).then(res => {
let dataSource = res.result.map(item => {
let list = []
if (res.result instanceof Array) {
list = res.result
} else if (res.result.records instanceof Array) {
list = res.result.records
} else {
throw '返回数据类型不识别'
}
let dataSource = list.map(item => {
// 判断是否标记了带有子级
if (item.hasChildren === true) {
// 查找第一个带有dataIndex的值的列
let firstColumn
for (let column of this.columns) {
firstColumn = column.dataIndex
if (firstColumn) break
}
// 定义默认展开时显示的loading子级实际子级数据只在展开时加载
let loadChild = { id: `${item.id}_loadChild`, name: 'loading...', isLoading: true }
let loadChild = { id: `${item.id}_loadChild`, [firstColumn]: 'loading...', isLoading: true }
item.children = [loadChild]
}
return item
@ -109,8 +148,9 @@
if (first) {
this.dataSource = dataSource
}
this.$emit('requestSuccess', { first, dataSource, res })
return Promise.resolve(dataSource)
})
}).finally(() => this.$emit('requestFinally', { first }))
},
/** 点击展开图标时触发 */

View File

@ -7,7 +7,8 @@
:data="{'isup':1,'bizPath':bizPath}"
:fileList="fileList"
:beforeUpload="beforeUpload"
@change="handleChange">
@change="handleChange"
:disabled="disabled">
<a-button>
<a-icon type="upload" />{{ text }}
</a-button>
@ -60,9 +61,16 @@
default:"temp"
},
value:{
type:String,
type:[String,Array],
required:false
},
// update-begin- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
disabled:{
type:Boolean,
required:false,
default: false
},
// update-end- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
//此属性被废弃了
triggerChange:{
type: Boolean,
@ -72,7 +80,11 @@
},
watch:{
value(val){
this.initFileList(val)
if (val instanceof Array) {
this.initFileList(val.join(','))
} else {
this.initFileList(val)
}
}
},
created(){

View File

@ -477,6 +477,7 @@ online用 实际开发请使用components/dict/JMultiSelectTag
| dict |string | ✔| 表名,显示字段名,存储字段名拼接的字符串 |
| pidField |string | ✔| 父ID的字段名 |
| pidValue |string | | 根节点父ID的值 默认'0' 不可以设置为空,如果想使用此组件而数据库根节点父ID为空请修改之 |
| multiple |boolean | |是否支持多选 |
使用示例
----

View File

@ -73,6 +73,7 @@
- `required` 是否必填,可选值为`true`or`false`
- `pattern` 正则表达式验证,只有成功匹配该正则的值才能成功通过验证
- `handler` 自定义函数校验,使用方法请见[示例五](#示例五)
- `message` 当验证未通过时显示的提示文本,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`
- 配置示例请看[示例二](#示例二)
@ -252,6 +253,19 @@ setValues([
}
])
```
### clearSelection
主动清空选择的行
- `参数:`
- `返回值:`
## 内置插槽
| 插槽名 | 说明 |
|--------------|------------------------------------------------------|
| buttonBefore | 在操作按钮的**前面**插入插槽,不受`actionButton`属性的影响 |
| buttonAfter | 在操作按钮的**后面**插入插槽,不受`actionButton`属性的影响 |
## ${...} 变量使用方式
@ -510,4 +524,54 @@ this.$refs.editableTable.getValues((error, values) => {
}
}
</script>
```
## 示例五
```js
// 该示例是自定义函数校验
columns: [
{
title: '字段名称',
key: 'dbFieldName',
type: FormTypes.input,
defaultValue: '',
validateRules: [
{
// 自定义函数校验 handler
handler(type, value, row, column, callback, target) {
// type 触发校验的类型input、change、blur
// value 当前校验的值
// callback(flag, message) 方法必须执行且只能执行一次
// flag = 是否通过了校验,不填写或者填写 null 代表不进行任何操作
// message = 提示的类型,默认使用配置的 message
// target 行编辑的实例对象
if (type === 'blur') {
if (value === 'abc') {
callback(false, '${title}不能是abc') // false = 未通过,可以跟自定义提示
return
}
let { values } = target.getValuesSync({ validate: false })
let count = 0
for (let val of values) {
if (val['dbFieldName'] === value) {
if (++count >= 2) {
callback(false, '${title}不能重复')
return
}
}
}
callback(true) // true = 通过验证
} else {
callback() // 不填写或者填写 null 代表不进行任何操作
}
},
message: '${title}默认提示'
}
]
},
]
```

View File

@ -17,7 +17,7 @@
</a-row>
<a-row>
<a-radio value="2">每隔
<a-input-number size="small" v-model="result.second.incrementIncrement" :min="1" :max="60"></a-input-number>
<a-input-number size="small" v-model="result.second.incrementIncrement" :min="1" :max="59"></a-input-number>
秒执行 从
<a-input-number size="small" v-model="result.second.incrementStart" :min="0" :max="59"></a-input-number>
秒开始
@ -31,7 +31,7 @@
</a-row>
<a-row>
<a-radio value="4">周期从
<a-input-number size="small" v-model="result.second.rangeStart" :min="1" :max="60"></a-input-number>
<a-input-number size="small" v-model="result.second.rangeStart" :min="1" :max="59"></a-input-number>
<a-input-number size="small" v-model="result.second.rangeEnd" :min="0" :max="59"></a-input-number>

View File

@ -0,0 +1,315 @@
<template>
<a-modal
centered
:title="name + '选择'"
:width="width"
:visible="visible"
@ok="handleOk"
@cancel="close"
cancelText="关闭">
<a-row :gutter="18">
<a-col :span="16">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="14">
<a-form-item :label="(queryParamText||name)">
<a-input v-model="queryParam[queryParamCode||valueKey]" :placeholder="'请输入' + (queryParamText||name)" @pressEnter="searchQuery"/>
</a-form-item>
</a-col>
<a-col :span="8">
<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>
<a-table
size="small"
bordered
:rowKey="rowKey"
:columns="innerColumns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:scroll="{ y: 240 }"
:rowSelection="{selectedRowKeys, onChange: onSelectChange, type: multiple ? 'checkbox':'radio'}"
:customRow="customRowFn"
@change="handleTableChange">
</a-table>
</a-col>
<a-col :span="8">
<a-card :title="'已选' + name" :bordered="false" :head-style="{padding:0}" :body-style="{padding:0}">
<a-table size="small" :rowKey="rowKey" bordered v-bind="selectedTable">
<span slot="action" slot-scope="text, record, index">
<a @click="handleDeleteSelected(record, index)">删除</a>
</span>
</a-table>
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
import { getAction } from '@/api/manage'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import { cloneObject, pushIfNotExist } from '@/utils/util'
export default {
name: 'JSelectBizComponentModal',
mixins: [JeecgListMixin],
props: {
value: {
type: Array,
default: () => []
},
visible: {
type: Boolean,
default: false
},
valueKey: {
type: String,
required: true
},
multiple: {
type: Boolean,
default: true
},
width: {
type: Number,
default: 900
},
name: {
type: String,
default: ''
},
listUrl: {
type: String,
required: true,
default: ''
},
// 根据 value 获取显示文本的地址,例如存的是 username可以通过该地址获取到 realname
valueUrl: {
type: String,
default: ''
},
displayKey: {
type: String,
default: null
},
columns: {
type: Array,
required: true,
default: () => []
},
// 查询条件Code
queryParamCode: {
type: String,
default: null
},
// 查询条件文字
queryParamText: {
type: String,
default: null
},
rowKey: {
type: String,
default: 'id'
},
},
data() {
return {
innerValue: [],
// 表头
innerColumns: this.columns,
// 已选择列表
selectedTable: {
pagination: false,
scroll: { y: 240 },
columns: [
{
...this.columns[0],
width: this.columns[0].widthRight || this.columns[0].width,
},
{ title: '操作', dataIndex: 'action', align: 'center', width: 60, scopedSlots: { customRender: 'action' }, }
],
dataSource: [],
},
url: { list: this.listUrl },
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 5,
pageSizeOptions: ['5', '10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
options: [],
dataSourceMap: {},
}
},
watch: {
value: {
deep: true,
immediate: true,
handler(val) {
this.innerValue = cloneObject(val)
this.selectedRowKeys = []
this.valueWatchHandler(val)
this.queryOptionsByValue(val)
}
},
dataSource: {
deep: true,
handler(val) {
this.emitOptions(val)
this.valueWatchHandler(this.innerValue)
}
},
selectedRowKeys: {
immediate: true,
deep: true,
handler(val) {
this.selectedTable.dataSource = val.map(key => {
for (let data of this.dataSource) {
if (data[this.rowKey] === key) {
pushIfNotExist(this.innerValue, data[this.valueKey])
return data
}
}
for (let data of this.selectedTable.dataSource) {
if (data[this.rowKey] === key) {
pushIfNotExist(this.innerValue, data[this.valueKey])
return data
}
}
console.warn('未找到选择的行信息key' + key)
return {}
})
},
}
},
methods: {
/** 关闭弹窗 */
close() {
this.$emit('update:visible', false)
},
valueWatchHandler(val) {
val.forEach(item => {
this.dataSource.concat(this.selectedTable.dataSource).forEach(data => {
if (data[this.valueKey] === item) {
pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
}
})
})
},
queryOptionsByValue(value) {
if (!value || value.length === 0) {
return
}
// 判断options是否存在value如果已存在数据就不再请求后台了
let notExist = false
for (let val of value) {
let find = false
for (let option of this.options) {
if (val === option.value) {
find = true
break
}
}
if (!find) {
notExist = true
break
}
}
if (!notExist) return
getAction(this.valueUrl || this.listUrl, {
// 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
[this.valueKey]: value.join(',') + ',',
pageNo: 1,
pageSize: value.length
}).then((res) => {
if (res.success) {
let dataSource = res.result
if (!(dataSource instanceof Array)) {
dataSource = res.result.records
}
this.emitOptions(dataSource, (data) => {
pushIfNotExist(this.innerValue, data[this.valueKey])
pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
})
}
})
},
emitOptions(dataSource, callback) {
dataSource.forEach(data => {
let key = data[this.valueKey]
this.dataSourceMap[key] = data
pushIfNotExist(this.options, { label: data[this.displayKey || this.valueKey], value: key }, 'value')
typeof callback === 'function' ? callback(data) : ''
})
this.$emit('options', this.options, this.dataSourceMap)
},
/** 完成选择 */
handleOk() {
let value = this.selectedTable.dataSource.map(data => data[this.valueKey])
this.$emit('input', value)
this.close()
},
/** 删除已选择的 */
handleDeleteSelected(record, index) {
this.selectedRowKeys.splice(this.selectedRowKeys.indexOf(record[this.rowKey]), 1)
this.selectedTable.dataSource.splice(index, 1)
},
customRowFn(record) {
return {
on: {
click: () => {
let key = record[this.rowKey]
if (!this.multiple) {
this.selectedRowKeys = [key]
this.selectedTable.dataSource = [record]
} else {
let index = this.selectedRowKeys.indexOf(key)
if (index === -1) {
this.selectedRowKeys.push(key)
this.selectedTable.dataSource.push(record)
} else {
this.handleDeleteSelected(record, index)
}
}
}
}
}
},
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -0,0 +1,36 @@
# JSelectBizComponent
Jeecg 选择组件的公共可复用组件
## 引用方式
```js
import JSelectBizComponent from '@/src/components/jeecgbiz/JSelectBizComponent'
export default {
components: { JSelectBizComponent }
}
```
## 参数
### 配置参数
| 参数名 | 类型 | 必填 | 默认值 | 备注 |
|-----------------------|---------|------|--------------|--------------------------------------------------------------------------------------|
| rowKey | String | | "id" | 唯一标识的字段名 |
| value(v-model) | String | | "" | 默认选择的数据,多个用半角逗号分割 |
| name | String | | "" | 显示名字,例如选择用户就填写"用户" |
| listUrl | String | 是 | | 数据请求地址,必须是封装了分页的地址 |
| valueUrl | String | | "" | 获取显示文本的地址,例如存的是 username可以通过该地址获取到 realname |
| displayKey | String | | null | 显示在标签上的字段 key ,不传则直接显示数据 |
| returnKeys | Array | | ['id', 'id'] | v-model 绑定的 keys是个数组默认使用第二项当配置了 `returnId=true` 就返回第一项 |
| returnId | Boolean | | false | 返回ID设为true后将返回配置的 `returnKeys` 中的第一项 |
| selectButtonText | String | | "选择" | 选择按钮的文字 |
| queryParamText | String | | null | 查询条件显示文字,不传则使用 `name` |
| columns | Array | 是 | | 列配置项与antd的table的配置完全一致。列的第一项会被配置成右侧已选择的列表上 |
| columns[0].widthRight | Array | | null | 仅列的第一项可以应用此配置,表示右侧已选择列表的宽度,建议 `70%`,不传则应用`width` |
| placeholder | String | | "请选择" | 占位符 |
| disabled | Boolean | | false | 是否禁用 |
| multiple | Boolean | | false | 是否可多选 |
| buttons | Boolean | | true | 是否显示"选择"按钮,如果不显示,可以直接点击文本框打开选择界面 |

View File

@ -0,0 +1,158 @@
<template>
<a-row class="j-select-biz-component-box" type="flex" :gutter="8">
<a-col class="left" :class="{'full': !buttons}">
<slot name="left">
<a-select
mode="multiple"
:placeholder="placeholder"
v-model="selectValue"
:options="selectOptions"
allowClear
:disabled="disabled"
:open="false"
style="width: 100%;"
@click.native="visible=(buttons?visible:true)"
/>
</slot>
</a-col>
<a-col v-if="buttons" class="right">
<a-button type="primary" icon="search" :disabled="disabled" @click="visible=true">{{selectButtonText}}</a-button>
</a-col>
<j-select-biz-component-modal
v-model="selectValue"
:visible.sync="visible"
v-bind="modalProps"
@options="handleOptions"
/>
</a-row>
</template>
<script>
import JSelectBizComponentModal from './JSelectBizComponentModal'
export default {
name: 'JSelectBizComponent',
components: { JSelectBizComponentModal },
props: {
value: {
type: String,
default: ''
},
/** 是否返回 id默认 false返回 code */
returnId: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
// 是否支持多选,默认 true
multiple: {
type: Boolean,
default: true
},
// 是否显示按钮,默认 true
buttons: {
type: Boolean,
default: true
},
// 显示的 Key
displayKey: {
type: String,
default: null
},
// 返回的 key
returnKeys: {
type: Array,
default: () => ['id', 'id']
},
// 选择按钮文字
selectButtonText: {
type: String,
default: '选择'
},
},
data() {
return {
selectValue: [],
selectOptions: [],
dataSourceMap: {},
visible: false
}
},
computed: {
valueKey() {
return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
},
modalProps() {
return Object.assign({
valueKey: this.valueKey,
multiple: this.multiple,
returnKeys: this.returnKeys,
displayKey: this.displayKey || this.valueKey
}, this.$attrs)
},
},
watch: {
value: {
immediate: true,
handler(val) {
if (val) {
this.selectValue = val.split(',')
} else {
this.selectValue = []
}
}
},
selectValue: {
deep: true,
handler(val) {
let rows = val.map(key => this.dataSourceMap[key])
this.$emit('select', rows)
let data = val.join(',')
this.$emit('input', data)
this.$emit('change', data)
}
}
},
methods: {
handleOptions(options, dataSourceMap) {
this.selectOptions = options
this.dataSourceMap = dataSourceMap
},
}
}
</script>
<style lang="scss" scoped>
.j-select-biz-component-box {
$width: 82px;
.left {
width: calc(100% - #{$width} - 8px);
}
.right {
width: #{$width};
}
.full {
width: 100%;
}
/deep/ {
.ant-select-search__field {
display: none !important;
}
}
}
</style>

View File

@ -11,7 +11,7 @@
:modal-width="modalWidth"
:multi="multi"
:rootOpened="rootOpened"
:depart-id="value"
:depart-id="departIds"
@ok="handleOK"
@initComp="initComp"/>
</div>
@ -48,6 +48,11 @@
type: Boolean,
required: false,
default: false
},
// 自定义返回字段,默认返回 id
customReturnField: {
type: String,
default: 'id'
}
},
data(){
@ -63,7 +68,9 @@
},
watch:{
value(val){
this.departIds = val
if (this.customReturnField === 'id') {
this.departIds = val
}
}
},
methods:{
@ -73,21 +80,17 @@
openModal(){
this.$refs.innerDepartSelectModal.show()
},
handleOK(rows,idstr){
console.log("当前选中部门",rows)
console.log("当前选中部门ID",idstr)
if(!rows){
handleOK(rows, idstr) {
let value = ''
if (!rows && rows.length <= 0) {
this.departNames = ''
this.departIds=''
}else{
let temp = ''
for(let item of rows){
temp+=','+item.departName
}
this.departNames = temp.substring(1)
this.departIds=idstr
this.departIds = ''
} else {
value = rows.map(row => row[this.customReturnField]).join(',')
this.departNames = rows.map(row => row['departName']).join(',')
this.departIds = idstr
}
this.$emit("change",this.departIds)
this.$emit("change", value)
},
getDepartNames(){
return this.departNames

View File

@ -1,65 +1,46 @@
<template>
<div style="width: 100%;">
<a-select
mode="multiple"
placeholder="Please select"
:value="nameList"
style="width: calc(100% - 178px);">
</a-select>
<span style="display: inline-block;width:170px;float: right;overflow: hidden;">
<a-button type="primary" @click="handleSelect" icon="search" style="width: 81px">选择</a-button>
<a-button type="primary" @click="selectReset" icon="reload" style="margin-left: 8px;width: 81px">清空</a-button>
</span>
<!-- 选择多个用户支持排序 -->
<j-select-multi-user-modal ref="selectModal" @selectFinished="selectOK"/>
</div>
<!-- 定义在这里的参数都是不可在外部覆盖的防止出现问题 -->
<j-select-biz-component
:value="value"
:listUrl="url.list"
:columns="columns"
v-on="$listeners"
v-bind="attrs"
/>
</template>
<script>
import JSelectMultiUserModal from './modal/JSelectMultiUserModal'
import JSelectBizComponent from './JSelectBizComponent'
export default {
name: 'JSelectMultiUser',
components:{ JSelectMultiUserModal },
props:{
value:{
type:String,
required:false
}
},
data(){
components: { JSelectBizComponent },
props: ['value'],
data() {
return {
selectList: [],
url: { list: '/sys/user/list' },
columns: [
{ title: '姓名', align: 'center', width: '20%', widthRight: '70%', dataIndex: 'realname' },
{ title: '账号', align: 'center', width: '20%', dataIndex: 'username' },
{ title: '电话', align: 'center', width: '23%', dataIndex: 'phone' },
{ title: '出生日期', align: 'center', width: '23%', dataIndex: 'birthday' }
],
// 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
default: {
name: '用户',
width: 1000,
displayKey: 'realname',
returnKeys: ['id', 'username'],
queryParamText: '账号',
}
}
},
computed: {
nameList: function () {
var names = [];
for (var a = 0; a < this.selectList.length; a++) {
names.push(this.selectList[a].name);
}
let nameStr = ''
if(names.length>0){
nameStr = names.join(",")
}
this.$emit("change",nameStr)
return names;
}
},
model: {
prop: 'value',
event: 'change'
},
methods:{
handleSelect: function () {
this.$refs.selectModal.add();
},
selectReset() {
this.selectList = [];
},
selectOK: function (data) {
this.selectList = data;
attrs() {
return Object.assign(this.default, this.$attrs)
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,37 @@
<template>
<j-select-biz-component :width="1000" v-bind="configs" v-on="$listeners"/>
</template>
<script>
import JSelectBizComponent from './JSelectBizComponent'
export default {
name: 'JSelectPosition',
components: { JSelectBizComponent },
props: ['value'],
data() {
return {
settings: {
name: '职务',
displayKey: 'name',
returnKeys: ['id', 'code'],
listUrl: '/sys/position/list',
queryParamCode: 'name',
queryParamText: '职务名称',
columns: [
{ title: '职务名称', dataIndex: 'name', align: 'center', width: '30%', widthRight: '70%' },
{ title: '职务编码', dataIndex: 'code', align: 'center', width: '35%' },
{ title: '职级', dataIndex: 'rank_dictText', align: 'center', width: '25%' }
]
}
}
},
computed: {
configs() {
return Object.assign({ value: this.value }, this.settings, this.$attrs)
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,38 @@
<template>
<j-select-biz-component
:value="value"
name="角色"
displayKey="roleName"
:returnKeys="returnKeys"
:listUrl="url.list"
:columns="columns"
queryParamText="角色编码"
v-on="$listeners"
v-bind="$attrs"
/>
</template>
<script>
import JSelectBizComponent from './JSelectBizComponent'
export default {
name: 'JSelectMultiUser',
components: { JSelectBizComponent },
props: ['value'],
data() {
return {
returnKeys: ['id', 'roleCode'],
url: { list: '/sys/role/list' },
columns: [
{ title: '角色名称', dataIndex: 'roleName', align: 'center', width: 120 },
{ title: '角色编码', dataIndex: 'roleCode', align: 'center', width: 120 }
]
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -1,51 +1,55 @@
<template>
<div>
<a-input-search
v-model="selectedDepUsers"
v-model="userNames"
placeholder="请先选择用户"
disabled
@search="onSearchDepUser">
<a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
</a-input-search>
<j-select-user-by-dep-modal
ref="selectModal"
:modal-width="modalWidth"
@ok="onSearchDepUserCallBack" />
<j-select-user-by-dep-modal ref="selectModal" :modal-width="modalWidth" :multi="multi" @ok="selectOK" :user-ids="value" @initComp="initComp"/>
</div>
</template>
<script>
import JSelectUserByDepModal from './modal/JSelectUserByDepModal'
export default {
name: 'JSelectUserByDep',
components: { JSelectUserByDepModal },
props:{
modalWidth:{
type:Number,
default:1250,
required:false
components: {JSelectUserByDepModal},
props: {
modalWidth: {
type: Number,
default: 1250,
required: false
},
value:{
type:String,
required:false
value: {
type: String,
required: false
},
disabled:{
disabled: {
type: Boolean,
required: false,
default: false
}
},
multi: {
type: Boolean,
default: true,
required: false
},
},
data() {
return {
selectedDepUsers:"",
userIds: "",
userNames: ""
}
},
mounted(){
this.selectedDepUsers = this.value
mounted() {
this.userIds = this.value
},
watch:{
value(val){
this.selectedDepUsers = val
watch: {
value(val) {
this.userIds = val
}
},
model: {
@ -53,14 +57,27 @@
event: 'change'
},
methods: {
//通过组织机构筛选选择用户
initComp(userNames) {
this.userNames = userNames
},
onSearchDepUser() {
this.$refs.selectModal.showModal()
this.onSearchDepUserCallBack('')
},
onSearchDepUserCallBack(selectedDepUsers) {
this.selectedDepUsers = selectedDepUsers
this.$emit("change",selectedDepUsers)
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.$emit("change", this.userIds)
}
}
}

View File

@ -63,7 +63,7 @@
handler() {
if (this.departId) {
this.checkedKeys = this.departId.split(",");
console.log('this.departId', this.departId)
// console.log('this.departId', this.departId)
} else {
this.checkedKeys = [];
}
@ -75,7 +75,6 @@
this.visible=true
this.checkedRows=[]
this.checkedKeys=[]
console.log("this.multi",this.multi)
},
loadDepart(){
queryDepartTreeList().then(res=>{
@ -133,39 +132,29 @@
},
onCheck (checkedKeys,info) {
if(!this.multi){
let arr = checkedKeys.checked.filter(item=>{
return this.checkedKeys.indexOf(item)<0
})
let arr = checkedKeys.checked.filter(item => this.checkedKeys.indexOf(item) < 0)
this.checkedKeys = [...arr]
this.checkedRows=[info.node.dataRef]
this.checkedRows = (this.checkedKeys.length === 0) ? [] : [info.node.dataRef]
}else{
this.checkedKeys = checkedKeys.checked
this.checkedRows.push(info.node.dataRef)
this.checkedRows = this.getCheckedRows(this.checkedKeys)
}
//this.$emit("input",this.checkedKeys.join(","))
//console.log(this.checkedKeys.join(","))
},
onSelect (selectedKeys,info) {
console.log(selectedKeys)
onSelect(selectedKeys,info) {
let keys = []
keys.push(selectedKeys[0])
if(!this.checkedKeys || this.checkedKeys.length==0 || !this.multi){
if(!this.checkedKeys || this.checkedKeys.length===0 || !this.multi){
this.checkedKeys = [...keys]
this.checkedRows=[info.node.dataRef]
}else{
let currKey = info.node.dataRef.key
if(this.checkedKeys.indexOf(currKey)>=0){
this.checkedKeys = this.checkedKeys.filter(item=>{
return item !=currKey
})
this.checkedRows=this.checkedRows.filter(item=>{
return item.key !=currKey
})
this.checkedKeys = this.checkedKeys.filter(item=> item !==currKey)
}else{
this.checkedRows.push(info.node.dataRef)
this.checkedKeys.push(...keys)
}
}
this.checkedRows = this.getCheckedRows(this.checkedKeys)
},
onExpand (expandedKeys) {
this.expandedKeys = expandedKeys
@ -215,6 +204,32 @@
})
},
// 根据 checkedKeys 获取 rows
getCheckedRows(checkedKeys) {
const forChildren = (list, key) => {
for (let item of list) {
if (item.id === key) {
return item
}
if (item.children instanceof Array) {
let value = forChildren(item.children, key)
if (value != null) {
return value
}
}
}
return null
}
let rows = []
for (let key of checkedKeys) {
let row = forChildren(this.treeData, key)
if (row != null) {
rows.push(row)
}
}
return rows
}
}
}

View File

@ -1,274 +0,0 @@
<template>
<a-modal
centered
:title="title"
:width="1000"
:visible="visible"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-row :gutter="18">
<a-col :span="16">
<a-card title="选择人员" :bordered="true">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="10">
<a-form-item label="姓名">
<a-input placeholder="请输入姓名" v-model="queryParam.name"></a-input>
</a-form-item>
</a-col>
<a-col :span="8" >
<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>
<!-- table区域-begin -->
<div>
<a-table
size="small"
bordered
rowKey="id"
:columns="columns1"
:dataSource="dataSource1"
:pagination="ipagination"
:loading="loading"
:scroll="{ y: 240 }"
:rowSelection="{selectedRowKeys: selectedRowKeys,onSelectAll:onSelectAll,onSelect:onSelect,onChange: onSelectChange}"
@change="handleTableChange">
</a-table>
</div>
<!-- table区域-end -->
</a-card>
</a-col>
<a-col :span="8">
<a-card title="用户选择" :bordered="true">
<!-- table区域-begin -->
<div>
<a-table
size="small"
bordered
rowKey="id"
:columns="columns2"
:dataSource="dataSource2"
:loading="loading"
:scroll="{ y: 240 }"
>
<span slot="action" slot-scope="text, record">
<a-button type="primary" size="small" @click="handleDelete(record)" icon="delete">删除</a-button>
</span>
</a-table>
</div>
<!-- table区域-end -->
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
import { filterObj } from '@/utils/util'
import { getAction } from '@/api/manage'
export default {
name: 'JSelectMultiUserModal',
data () {
return {
title: "用户列表",
names: [],
visible: false,
placement: 'right',
description: '人员管理页面',
// 查询条件
queryParam: {},
// 表头
columns1: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
width:50,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
{
title: '姓名',
align:"center",
width:113,
dataIndex: 'name'
},
{
title: '年龄',
align:"center",
width:100,
dataIndex: 'age'
},
{
title: '出生日期',
align:"center",
width:100,
dataIndex: 'birthday'
}
],
columns2: [
{
title: '用户账号',
align:"center",
width:100,
dataIndex: 'name'
},
{
title: '操作',
dataIndex: 'action',
align:"center",
width:100,
scopedSlots: { customRender: 'action' },
}
],
//数据集
dataSource1:[],
dataSource2:[],
// 分页参数
ipagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " " + total + ""
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter:{
column: 'createTime',
order: 'desc',
},
loading:false,
selectedRowKeys: [],
selectedRows: [],
url: {
list: "/test/jeecgDemo/list",
},
}
},
created() {
this.loadData();
},
methods: {
searchQuery(){
this.loadData(1);
},
searchReset(){
this.queryParam={};
this.loadData(1);
},
handleCancel() {
this.visible = false;
},
handleOk() {
this.$emit("selectFinished",this.dataSource2);
this.visible = false;
},
add() {
this.visible = true;
},
loadData (arg){
//加载数据 若传入参数1则加载第一页的内容
if(arg===1){
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list,params).then((res)=>{
if(res.success){
this.dataSource1 = res.result.records;
this.ipagination.total = res.result.total;
}
})
},
getQueryParams(){
var param = Object.assign({}, this.queryParam,this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField(){
//TODO 字段权限控制
},
onSelectAll (selected, selectedRows, changeRows) {
if(selected===true){
for(var a = 0;a<changeRows.length;a++){
this.dataSource2.push(changeRows[a]);
}
}else{
for(var b = 0;b<changeRows.length;b++){
this.dataSource2.splice(this.dataSource2.indexOf(changeRows[b]),1);
}
}
// console.log(selected, selectedRows, changeRows);
},
onSelect (record,selected) {
if(selected===true){
this.dataSource2.push(record);
}else{
var index = this.dataSource2.indexOf(record);
//console.log();
if(index >=0 ){
this.dataSource2.splice(this.dataSource2.indexOf(record),1);
}
}
},
onSelectChange (selectedRowKeys,selectedRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectedRows;
},
onClearSelected(){
this.selectedRowKeys = [];
this.selectionRows = [];
},
handleDelete: function(record){
this.dataSource2.splice(this.dataSource2.indexOf(record),1);
},
handleTableChange(pagination, filters, sorter){
//分页、排序、筛选变化时触发
console.log(sorter);
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.ipagination = pagination;
this.loadData();
}
}
}
</script>
<style lang="less" 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

@ -15,9 +15,9 @@
<!--组织机构-->
<a-directory-tree
selectable
:selectedKeys="selectedKeys"
:selectedKeys="selectedDepIds"
:checkStrictly="true"
@select="this.onSelect"
@select="onDepSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
/>
@ -42,7 +42,7 @@
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
@change="handleTableChange">
</a-table>
</a-card>
@ -52,16 +52,17 @@
</template>
<script>
import { filterObj } from '@/utils/util'
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
import {filterObj} from '@/utils/util'
import {queryDepartTreeList, getUserList, queryUserByDepId} from '@/api/api'
export default {
name: 'JSelectUserByDepModal',
components: {},
props:['modalWidth'],
props: ['modalWidth', 'multi', 'userIds'],
data() {
return {
queryParam: {
username:"",
username: "",
},
columns: [
{
@ -74,16 +75,11 @@
align: 'center',
dataIndex: 'realname'
},
{
title: '角色名称',
align: 'center',
dataIndex: 'roleName'
},
{
title: '性别',
align: 'center',
dataIndex: 'sex',
customRender: function(text) {
customRender: function (text) {
if (text === 1) {
return '男'
} else if (text === 2) {
@ -106,10 +102,9 @@
],
scrollTrigger: {},
dataSource: [],
selectedKeys: [],
userNameArr: [],
departName: '',
userRolesMap: {},
selectedRowKeys: [],
selectUserRows: [],
selectUserIds: [],
title: '根据部门选择用户',
ipagination: {
current: 1,
@ -126,53 +121,77 @@
column: 'createTime',
order: 'desc'
},
selectedRowKeys: [],
selectedRows: [],
selectedDepIds: [],
departTree: [],
visible: false,
form: this.$form.createForm(this)
}
},
computed: {
// 计算属性的 getter
getType: function () {
console.log("multi: ", this.multi);
return this.multi == true ? 'checkbox' : 'radio';
}
},
watch: {
userIds() {
this.initUserNames()
}
},
created() {
// 该方法触发屏幕自适应
this.resetScreenSize();
this.queryUserRoleMap();
this.loadData().then((res) => {
this.initUserNames();
})
},
methods: {
loadData(arg) {
initUserNames() {
let names = ''
console.log("props userIds: ", this.userIds)
if (this.userIds) {
let currUserIds = this.userIds
let userIdsArr = currUserIds.split(',');
for (let item of this.dataSource) {
if (userIdsArr.includes(item.username)) {
names += "," + item.realname
}
}
if (names) {
names = names.substring(1)
}
this.$emit("initComp", names)
}else{
// JSelectUserByDep组件bug issues/I16634
this.$emit("initComp", "")
}
},
async loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
let params = this.getQueryParams();//查询条件
getUserList(params).then((res) => {
await getUserList(params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.assignRoleName(this.dataSource);
this.ipagination.total = res.result.total;
}
})
},
queryUserRoleMap(){
queryUserRoleMap().then((res) => {
if (res.success) {
this.userRolesMap = res.result;
this.loadData();
}
})
},
// 触发屏幕自适应
resetScreenSize() {
let screenWidth = document.body.clientWidth;
if (screenWidth < 500) {
this.scrollTrigger = { x: 800 };
this.scrollTrigger = {x: 800};
} else {
this.scrollTrigger = {};
}
},
showModal() {
this.visible = true;
this.assignRoleName(this.dataSource);
this.queryDepartTree();
this.loadData();
this.form.resetFields();
},
getQueryParams() {
@ -191,13 +210,13 @@
},
searchReset(num) {
let that = this;
if(num !== 0){
if (num !== 0) {
that.queryParam = {};
that.loadData(1);
}
that.selectedRowKeys = [];
that.userNameArr = [];
that.selectedKeys = [];
that.selectUserIds = [];
that.selectedDepIds = [];
},
close() {
this.searchReset(0);
@ -214,27 +233,31 @@
},
handleSubmit() {
let that = this;
for (let i = 0, len = this.selectedRowKeys.length; i < len; i++) {
this.getUserNames(this.selectedRowKeys[i]);
}
that.$emit('ok', that.userNameArr.join(','));
this.getSelectUserRows();
console.log(that.selectUserRows)
that.$emit('ok', that.selectUserRows, that.selectUserIds);
that.searchReset(0)
that.close();
},
// 遍历匹配,获取用户真实姓名
getUserNames(rowId) {
//获取选择用户信息
getSelectUserRows(rowId) {
let dataSource = this.dataSource;
let userIds = "";
this.selectUserRows = [];
for (let i = 0, len = dataSource.length; i < len; i++) {
if (rowId === dataSource[i].id) {
this.userNameArr.push(dataSource[i].realname);
if (this.selectedRowKeys.includes(dataSource[i].id)) {
this.selectUserRows.push(dataSource[i]);
userIds = userIds + "," + dataSource[i].username
}
}
this.selectUserIds = userIds.substring(1);
},
// 点击树节点,筛选出对应的用户
onSelect(selectedKeys) {
if (selectedKeys[0] != null) {
this.queryUserByDepId(selectedKeys); // 调用方法根据选选择的id查询用户信息
if (this.selectedKeys[0] !== selectedKeys[0]) {
this.selectedKeys = [selectedKeys[0]];
onDepSelect(selectedDepIds) {
if (selectedDepIds[0] != null) {
this.initQueryUserByDepId(selectedDepIds); // 调用方法根据选选择的id查询用户信息
if (this.selectedDepIds[0] !== selectedDepIds[0]) {
this.selectedDepIds = [selectedDepIds[0]];
}
}
},
@ -246,26 +269,14 @@
this.loadData(1);
},
// 根据选择的id来查询用户信息
queryUserByDepId(selectedKeys) {
queryUserByDepId({ id: selectedKeys.toString() }).then((res) => {
initQueryUserByDepId(selectedDepIds) {
queryUserByDepId({id: selectedDepIds.toString()}).then((res) => {
if (res.success) {
this.dataSource = res.result;
this.ipagination.total = res.result.length;
this.assignRoleName(this.dataSource);
}
})
},
// 传入用户id,找到匹配的角色名称
queryUserRole(userId) {
let map = this.userRolesMap;
let roleName = [];
for (var key in map) {
if (userId === key) {
roleName.push(map[key]);
}
}
return roleName.join(',');
},
queryDepartTree() {
queryDepartTreeList().then((res) => {
if (res.success) {
@ -273,16 +284,6 @@
}
})
},
// 为角色名称赋值
assignRoleName(data) {
let userId = '';
let role = '';
for (let i = 0, length = data.length; i < length; i++) {
userId = this.dataSource[i].id;
role = this.queryUserRole(userId);
this.dataSource[i].roleName = role;
}
},
modalFormOk() {
this.loadData();
}

View File

@ -10,6 +10,7 @@
export default {
name: "IframePageContent",
inject:['closeCurrent'],
data () {
return {
url: "",
@ -36,7 +37,13 @@
console.log("------url------"+url)
if (url !== null && url !== undefined) {
this.url = url;
//window.open(this.url);
/*update_begin author:wuxianquan date:20190908 for:判断打开方式新窗口打开时this.$route.meta.internalOrExternal==true */
if(this.$route.meta.internalOrExternal != undefined && this.$route.meta.internalOrExternal==true){
this.closeCurrent();
window.open(this.url);
}
/*update_end author:wuxianquan date:20190908 for:判断打开方式新窗口打开时this.$route.meta.internalOrExternal==true */
}
}
}

View File

@ -1,6 +1,8 @@
<template>
<global-layout @dynamicRouterShow="dynamicRouterShow">
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect"/>
<!-- update-begin- author:sunjianlei --- date:20191009 --- for: 提升右键菜单的层级 -->
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" style="z-index: 9999;" @select="onMenuSelect"/>
<!-- update-end- author:sunjianlei --- date:20191009 --- for: 提升右键菜单的层级 -->
<a-tabs
@contextmenu.native="e => onContextmenu(e)"
v-if="multipage"
@ -10,6 +12,7 @@
:hide-add="true"
type="editable-card"
@change="changePage"
@tabClick="tabCallBack"
@edit="editPage">
<a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList">
<span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
@ -18,9 +21,11 @@
<div style="margin: 12px 12px 0;">
<transition name="page-toggle">
<keep-alive v-if="multipage">
<router-view/>
<router-view v-if="reloadFlag"/>
</keep-alive>
<router-view v-else/>
<template v-else>
<router-view v-if="reloadFlag"/>
</template>
</transition>
</div>
</global-layout>
@ -30,6 +35,7 @@
import GlobalLayout from '@/components/page/GlobalLayout'
import Contextmenu from '@/components/menu/Contextmenu'
import { mixin, mixinDevice } from '@/utils/mixin.js'
import { triggerWindowResizeEvent } from '@/utils/util'
const indexKey = '/dashboard/analysis'
@ -47,12 +53,21 @@
activePage: '',
menuVisible: false,
menuItemList: [
{ key: '4', icon: 'reload', text: '刷 新' },
{ key: '1', icon: 'arrow-left', text: '关闭左侧' },
{ key: '2', icon: 'arrow-right', text: '关闭右侧' },
{ key: '3', icon: 'close', text: '关闭其它' }
]
],
reloadFlag:true
}
},
/* update_begin author:wuxianquan date:20190828 for: 关闭当前tab页供子页面调用 ->望菜单能配置外链直接弹出新页面而不是嵌入iframe #428 */
provide(){
return{
closeCurrent:this.closeCurrent
}
},
/* update_end author:wuxianquan date:20190828 for: 关闭当前tab页供子页面调用->望菜单能配置外链直接弹出新页面而不是嵌入iframe #428 */
computed: {
multipage() {
//判断如果是手机模式,自动切换为单页面模式
@ -101,9 +116,11 @@
this.$router.push(Object.assign({},waitRouter));
},
'multipage': function(newVal) {
if (!newVal) {
this.linkList = [this.$route.fullPath]
this.pageList = [this.$route]
if(this.reloadFlag){
if (!newVal) {
this.linkList = [this.$route.fullPath]
this.pageList = [this.$route]
}
}
}
},
@ -111,6 +128,11 @@
changePage(key) {
this.activePage = key
},
tabCallBack() {
this.$nextTick(() => {
triggerWindowResizeEvent()
})
},
editPage(key, action) {
this[action](key)
},
@ -157,13 +179,21 @@
case '3':
this.closeOthers(pageKey)
break
case '4':
this.routeReload()
break
default:
break
}
},
/* update_begin author:wuxianquan date:20190828 for: 关闭当前tab页供子页面调用->望菜单能配置外链直接弹出新页面而不是嵌入iframe #428 */
closeCurrent(){
this.remove(this.activePage);
},
/* update_end author:wuxianquan date:20190828 for: 关闭当前tab页供子页面调用->望菜单能配置外链直接弹出新页面而不是嵌入iframe #428 */
closeOthers(pageKey) {
let index = this.linkList.indexOf(pageKey)
if (pageKey == indexKey) {
if (pageKey == indexKey || pageKey.indexOf('?ticke=')>=0) {
this.linkList = this.linkList.slice(index, index + 1)
this.pageList = this.pageList.slice(index, index + 1)
this.activePage = this.linkList[0]
@ -171,7 +201,7 @@
let indexContent = this.pageList.slice(0, 1)[0]
this.linkList = this.linkList.slice(index, index + 1)
this.pageList = this.pageList.slice(index, index + 1)
this.linkList.unshift(indexKey)
this.linkList.unshift(indexContent.fullPath)
this.pageList.unshift(indexContent)
this.activePage = this.linkList[1]
}
@ -185,7 +215,7 @@
let index = this.linkList.indexOf(pageKey)
this.linkList = this.linkList.slice(index)
this.pageList = this.pageList.slice(index)
this.linkList.unshift(indexKey)
this.linkList.unshift(indexContent.fullPath)
this.pageList.unshift(indexContent)
if (this.linkList.indexOf(this.activePage) < 0) {
this.activePage = this.linkList[0]
@ -207,13 +237,25 @@
let meta = Object.assign({},currRouter.meta,{title:title})
this.pageList.splice(keyIndex, 1, Object.assign({},currRouter,{meta:meta}))
}
}
},
//update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
//update-begin-author:taoyan date:20191008 for:路由刷新
routeReload(){
this.reloadFlag = false
let ToggleMultipage = "ToggleMultipage"
this.$store.dispatch(ToggleMultipage,false)
this.$nextTick(()=>{
this.$store.dispatch(ToggleMultipage,true)
this.reloadFlag = true
})
}
//update-end-author:taoyan date:20191008 for:路由刷新
}
}
</script>
<style lang="scss">
<style lang="less">
/*
* The following styles are auto-applied to elements with
@ -291,7 +333,7 @@
border-bottom: 1px solid transparent !important;
}
.ant-tabs-tab-active {
border-color: #1890ff !important;
border-color: @primary-color!important;
}
}

View File

@ -145,7 +145,7 @@
</style>
<!-- update_begin author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
<style lang="scss">
<style lang="less">
.ant-menu.ant-menu-root {
& > .ant-menu-item:first-child {
background-color: transparent;
@ -156,7 +156,7 @@
&.ant-menu-item-selected {
& > a, & > a:hover {
color: #1890ff;
color: @primary-color;
}
}
}

View File

@ -161,10 +161,10 @@
}
</script>
<style lang="scss" scoped>
<style lang="less" scoped>
/* update_begin author:scott date:20190220 for: 缩小首页布局顶部的高度*/
$height: 59px;
@height: 59px;
.layout {
@ -174,8 +174,8 @@
margin-left: 10px;
.ant-menu.ant-menu-horizontal {
height: $height;
line-height: $height;
height: @height;
line-height: @height;
}
}
.trigger {
@ -189,15 +189,15 @@
.header {
z-index: 2;
color: white;
height: $height;
background-color: #1890ff;
height: @height;
background-color: @primary-color;
transition: background 300ms;
/* dark 样式 */
&.dark {
color: #000000;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
background-color: white !important;
background-color: @primary-color;
}
}
@ -209,8 +209,8 @@
}
.ant-layout-header {
height: $height;
line-height: $height;
height: @height;
line-height: @height;
}
/* update_end author:scott date:20190220 for: 缩小首页布局顶部的高度*/

View File

@ -74,7 +74,9 @@
</a-layout-footer>
</a-layout>
<setting-drawer></setting-drawer>
<!-- update-start---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ---- -->
<!--<setting-drawer></setting-drawer>-->
<!-- update-end---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ---- -->
</a-layout>
</template>
@ -82,7 +84,11 @@
import SideMenu from '@/components/menu/SideMenu'
import GlobalHeader from '@/components/page/GlobalHeader'
import GlobalFooter from '@/components/page/GlobalFooter'
import SettingDrawer from '@/components/setting/SettingDrawer'
// update-start---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ------
// import SettingDrawer from '@/components/setting/SettingDrawer'
// 注释这个因为在个人设置模块已经加载了SettingDrawer页面
// update-end ---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ------
import { triggerWindowResizeEvent } from '@/utils/util'
import { mapState, mapActions } from 'vuex'
import { mixin, mixinDevice } from '@/utils/mixin.js'
@ -93,7 +99,11 @@
SideMenu,
GlobalHeader,
GlobalFooter,
SettingDrawer
// update-start---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ------
// // SettingDrawer
// 注释这个因为在个人设置模块已经加载了SettingDrawer页面
// update-end ---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ------
},
mixins: [mixin, mixinDevice],
data() {

View File

@ -31,7 +31,7 @@
<a-list>
<a-list-item :key="index" v-for="(record, index) in announcement1">
<div style="margin-left: 5%;width: 80%">
<p><a @click="showAnnouncement(record)">标题{{ record.titile }}</a></p>
<p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
</div>
<div style="text-align: right">
@ -49,7 +49,7 @@
<a-list>
<a-list-item :key="index" v-for="(record, index) in announcement2">
<div style="margin-left: 5%;width: 80%">
<p><a @click="showAnnouncement(record)">标题{{ record.titile }}</a></p>
<p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
</div>
<div style="text-align: right">
@ -80,6 +80,7 @@
import ShowAnnouncement from './ShowAnnouncement'
import store from '@/store/'
export default {
name: "HeaderNotice",
components: {
@ -96,11 +97,14 @@
hovered: false,
announcement1:[],
announcement2:[],
msg1Count:"3",
msg1Count:"0",
msg2Count:"0",
msg1Title:"通知(3)",
msg1Title:"通知(0)",
msg2Title:"",
stopTimer:false,
websock: null,
lockReconnect:false,
heartCheck:null,
}
},
computed:{
@ -112,6 +116,7 @@
this.loadData();
//this.timerFun();
this.initWebSocket();
this.heartCheckFun();
},
destroyed: function () { // 离开页面生命周期函数
this.websocketclose();
@ -186,35 +191,45 @@
// WebSocket与普通的请求所用协议有所不同ws等同于httpwss等同于https
var userId = store.getters.userInfo.id;
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
//console.log(url);
console.log(url);
this.websock = new WebSocket(url);
this.websock.onopen = this.websocketonopen;
this.websock.onerror = this.websocketonerror;
this.websock.onmessage = this.websocketonmessage;
this.websock.onclose = this.websocketclose;
this.websock.onopen = this.websocketOnopen;
this.websock.onerror = this.websocketOnerror;
this.websock.onmessage = this.websocketOnmessage;
this.websock.onclose = this.websocketOnclose;
},
websocketonopen: function () {
websocketOnopen: function () {
console.log("WebSocket连接成功");
//心跳检测重置
this.heartCheck.reset().start();
},
websocketonerror: function (e) {
websocketOnerror: function (e) {
console.log("WebSocket连接发生错误");
this.reconnect();
},
websocketonmessage: function (e) {
websocketOnmessage: function (e) {
console.log("-----接收消息-------",e.data);
var data = eval("(" + e.data + ")"); //解析对象
this.loadData();
//if(data.cmd == "topic"){
//系统通知
this.openNotification(data);
//}else if(data.cmd == "user"){
//用户消息
// this.openNotification(data);
//}
if(data.cmd == "topic"){
//系统通知
this.loadData();
}else if(data.cmd == "user"){
//用户消息
this.loadData();
}
//心跳检测重置
this.heartCheck.reset().start();
},
websocketclose: function (e) {
websocketOnclose: function (e) {
console.log("connection closed (" + e.code + ")");
this.reconnect();
},
websocketSend(text) { // 数据发送
try {
this.websock.send(text);
} catch (err) {
console.log("send failed (" + err.code + ")");
}
},
openNotification (data) {
@ -239,6 +254,45 @@
});
},
reconnect() {
var that = this;
if(that.lockReconnect) return;
that.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function () {
console.info("尝试重连...");
that.initWebSocket();
that.lockReconnect = false;
}, 5000);
},
heartCheckFun(){
var that = this;
//心跳检测,每20s心跳一次
that.heartCheck = {
timeout: 20000,
timeoutObj: null,
serverTimeoutObj: null,
reset: function(){
clearTimeout(this.timeoutObj);
//clearTimeout(this.serverTimeoutObj);
return this;
},
start: function(){
var self = this;
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
that.websocketSend("HeartBeat");
console.info("客户端发送心跳");
//self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
// that.websock.close();//如果onclose会执行reconnect我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
//}, self.timeout)
}, this.timeout)
}
}
},
showDetail(key,data){
this.$notification.close(key);
var id = data.msgId;

View File

@ -32,15 +32,15 @@
}
}
</script>
<style lang="scss" scoped>
<style lang="less" scoped>
/*缩小首页布 局顶部的高度*/
$height: 59px;
@height: 59px;
.sider {
box-shadow: none !important;
.logo {
height: $height !important;
line-height: $height !important;
height: @height !important;
line-height: @height !important;
box-shadow: none !important;
transition: background 300ms;
@ -53,7 +53,7 @@
}
&.light .logo {
background-color: #1890ff;
background-color: @primary-color;
}
}
</style>

View File

@ -1,5 +1,26 @@
<template>
<div class="user-wrapper" :class="theme">
<!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
<!-- update-begin author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 -->
<span class="action" @click="showClick">
<a-icon type="search"></a-icon>
</span>
<span v-show="shows" class="borders">
<a-select
class="search-input"
showSearch
:showArrow="false"
placeholder="搜索菜单"
optionFilterProp="children"
:filterOption="filterOption"
@change="searchMethods"
@blur="hiddenClick"
>
<a-select-option v-for="site in search " :value="site.id">{{site.meta.title}}</a-select-option>
</a-select>
</span>
<!-- update-end author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 -->
<!-- update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
<span class="action">
<a class="logout_title" target="_blank" href="http://jeecg-boot.mydoc.io">
<a-icon type="question-circle-o"></a-icon>
@ -66,12 +87,19 @@
import UserPassword from './UserPassword'
import SettingDrawer from "@/components/setting/SettingDrawer";
import DepartSelect from './DepartSelect'
import { mapActions, mapGetters } from 'vuex'
import { mapActions, mapGetters,mapState } from 'vuex'
import { mixinDevice } from '@/utils/mixin.js'
export default {
name: "UserMenu",
mixins: [mixinDevice],
data(){
return{
//菜单搜索
search:[],
shows:false
}
},
components: {
HeaderNotice,
UserPassword,
@ -85,7 +113,31 @@
default: 'dark'
}
},
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
created() {
let lists = []
console.log("permissionMenuList: ",this.permissionMenuList)
this.searchMenus(lists,this.permissionMenuList)
this.search=[...lists]
console.log(this.search)
},
computed: {
...mapState({
// 后台菜单
permissionMenuList: state => state.user.permissionList
})
},
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
methods: {
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
showClick(){
this.shows = !this.shows
},
hiddenClick(){
this.shows = false
},
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
...mapActions(["Logout"]),
...mapGetters(["nickname", "avatar","userInfo"]),
getAvatar(){
@ -122,11 +174,54 @@
},
systemSetting(){
this.$refs.settingDrawer.showDrawer()
},
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
searchMenus(arr,menus){
for(let i of menus){
if(!i.hidden && "layouts/RouteView"!==i.component){
arr.push(i)
}
if(i.children&& i.children.length>0){
this.searchMenus(arr,i.children)
}
}
},
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
searchMethods(value){
let jump = this.search.filter(item=>item.id==value)
this.$router.push({ path:jump[0].path})
}
/*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
}
}
</script>
<style lang="scss" scoped>
/* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
.user-wrapper .search-input {
width: 180px;
color: white;
/deep/ {
.ant-select-selection {
background-color: inherit;
border: 0;
border-bottom: 1px solid white;
}
.ant-select-selection__placeholder,
.ant-select-search__field__placeholder {
color: inherit;
}
}
}
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
</style>
<style scoped>
.logout_title {
color: inherit;

View File

@ -40,23 +40,23 @@ const updateTheme = primaryColor => {
return;
}
const hideMessage = message.loading('正在编译主题', 0);
console.info(`正在编译主题!`)
function buildIt() {
if (!window.less) {
// 正确的判定less是否已经加载less.modifyVars可用
if (!window.less || !window.less.modifyVars) {
return;
}
setTimeout(() => {
window.less
.modifyVars({
'@primary-color': primaryColor,
})
.then(() => {
hideMessage();
})
.catch(() => {
message.error('Failed to update theme');
hideMessage();
});
}, 200);
// less.modifyVars可用
window.less.modifyVars({
'@primary-color': primaryColor,
})
.then(() => {
hideMessage();
})
.catch(() => {
message.error('Failed to update theme');
hideMessage();
});
}
if (!lessNodesAppended) {
// insert less.js and color.less

View File

@ -323,6 +323,30 @@ export const constantRouterMap = [
]
},
// {
// path: '/',
// name: 'index',
// component: TabLayout,
// meta: {title: '首页'},
// redirect: '/dashboard/workplace',
// children: [
// {
// path: '/online',
// name: 'online',
// redirect: '/online',
// component: RouteView,
// meta: {title: '在线开发', icon: 'dashboard', permission: ['dashboard']},
// children: [
// {
// path: '/online/auto/:code',
// name: 'report',
// component: () => import('@/views/modules/online/cgreport/OnlCgreportAutoList')
// },
// ]
// },
// ]
// },
{
path: '/test',
component: BlankLayout,

View File

@ -22,7 +22,7 @@ export default {
fixSiderbar: false, // sticky siderbar
autoHideHeader: false, // auto hide header
colorWeak: false,
multipage: false, //默认多页签模式
multipage: true, //默认多页签模式
// vue-ls options
storageOptions: {
namespace: 'pro__', // key prefix

View File

@ -18,9 +18,8 @@ import VueApexCharts from 'vue-apexcharts'
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
import "@jeecg/antd-onine"
import '@jeecg/antd-onine/dist/OnlineForm.css'
import "@jeecg/antd-online-re"
import '@jeecg/antd-online-re/dist/OnlineForm.css'
import {
ACCESS_TOKEN,
@ -70,7 +69,7 @@ new Vue({
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,true))
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
},
render: h => h(App)
}).$mount('#app')

View File

@ -9,9 +9,6 @@ export const DisabledAuthFilterMixin = {
return {
}
},
created() {
},
methods:{
isDisabledAuth(code){

View File

@ -80,10 +80,11 @@ export const JEditableTableMixin = {
},
/** 查询某个tab的数据 */
requestSubTableData(url, params, tab) {
requestSubTableData(url, params, tab, success) {
tab.loading = true
getAction(url, params).then(res => {
tab.dataSource = res.result || []
typeof success === 'function' ? success(res) : ''
}).finally(() => {
tab.loading = false
})

View File

@ -51,9 +51,12 @@ export const JeecgListMixin = {
}
},
created() {
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
if(!this.disableMixinCreated){
console.log(' -- mixin created -- ')
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
}
},
methods:{
loadData(arg) {
@ -149,6 +152,7 @@ export const JeecgListMixin = {
title: "确认删除",
content: "是否删除选中数据?",
onOk: function () {
that.loading = true;
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) {
that.$message.success(res.message);
@ -157,6 +161,8 @@ export const JeecgListMixin = {
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.loading = false;
});
}
});
@ -250,9 +256,24 @@ export const JeecgListMixin = {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
if(info.file.response.success){
this.$message.success(`${info.file.name} 文件上传成功`);
this.loadData();
if (info.file.response.success) {
// this.$message.success(`${info.file.name} 文件上传成功`);
if (info.file.response.code === 201) {
let { message, result: { msg, fileUrl, fileName } } = info.file.response
let href = window._CONFIG['domianURL'] + fileUrl
this.$warning({
title: message,
content: (
<div>
<span>{msg}</span><br/>
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
</div>
)
})
} else {
this.$message.success(info.file.response.message || `${info.file.name} 文件上传成功`)
}
this.loadData()
} else {
this.$message.error(`${info.file.name} ${info.file.response.message}.`);
}

View File

@ -2,6 +2,16 @@ import Vue from 'vue'
import Router from 'vue-router'
import { constantRouterMap } from '@/config/router.config'
//update-begin-author:taoyan date:20191011 for:TASK #3214 【优化】访问online功能测试 浏览器控制台抛出异常
try {
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
} catch (e) {
}
//update-end-author:taoyan date:20191011 for:TASK #3214 【优化】访问online功能测试 浏览器控制台抛出异常
Vue.use(Router)
export default new Router({

View File

@ -7,6 +7,14 @@ const FormTypes = {
date: 'date',
datetime: 'datetime',
upload: 'upload',
file: 'file',
image: 'image',
popup:'popup',
list_multi:"list_multi",
sel_search:"sel_search",
radio:'radio',
checkbox_meta:"checkbox_meta",
slot: 'slot',
hidden: 'hidden'
}

View File

@ -0,0 +1,107 @@
/**
* LunarFullCalendar 公共 js
*
* @version 1.0.0
* @author sunjianlei
*
* */
import { getRefPromise } from '@/utils/JEditableTableUtil'
/* 日历的视图类型 */
const calendarViewType = {
month: 'month', // 月视图
basicWeek: 'basicWeek', // 基础周视图
basicDay: 'basicDay',// 基础天视图
agendaWeek: 'agendaWeek', // 议程周视图
agendaDay: 'agendaDay', // 议程天视图
}
/* 定义默认视图 */
const defaultView = calendarViewType.month
/* 定义日历默认配置 */
const defaultSettings = {
locale: 'zh-cn',
// 按钮文字
buttonText: {
today: '今天',
month: '月',
week: '周',
day: '日'
},
// 头部排列方式
header: {
left: 'prev,next, today',
center: 'title',
right: 'hide, custom, month,agendaWeek,agendaDay'
},
//点击今天日列表图
eventLimitClick: 'day',
// 隐藏超出的事件
eventLimit: true,
// 设置每周开始日期为周日
firstDay: 0,
// 默认显示视图
defaultView,
timeFormat: 'H:mm',
axisFormat: 'H:mm',
// agenda视图下是否显示all-day
allDaySlot: true,
// agenda视图下all-day的显示文本
allDayText: '全天',
// 时区默认本地的
timezone: 'local',
// 周视图和日视同的左侧时间显示
slotLabelFormat: 'HH:mm',
// 设置第二天阈值
nextDayThreshold: '00:00:00',
}
/** 提供了一些增强方法 */
const CalendarMixins = {
data() {
return {
calenderCurrentViewType: defaultView
}
},
methods: {
getCalendarConfigEventHandler() {
return {
// 处理 view changed 事件
viewRender: (view, element) => {
let { type } = view
let lastViewType = this.calenderCurrentViewType
this.calenderCurrentViewType = type
if (typeof this.handleViewRender === 'function') {
this.handleViewRender(type, view, element)
}
if (lastViewType !== this.calenderCurrentViewType && typeof this.handleViewChanged === 'function') {
this.handleViewChanged(type, view, element)
}
},
}
},
/** 获取 LunarFullCalendar 实例ref = baseCalendar */
getCalendar(fn) {
return getRefPromise(this, 'baseCalendar').then(fn)
},
calendarEmit(name, data) {
this.getCalendar(ref => ref.$emit(name, data))
},
/** 强制重新加载所有的事件(日程)*/
calendarReloadEvents() {
this.calendarEmit('reload-events')
}
}
}
export { defaultSettings, calendarViewType, CalendarMixins }

View File

@ -8,7 +8,7 @@ import { ACCESS_TOKEN } from "@/store/mutation-types"
// 创建 axios 实例
const service = axios.create({
baseURL: '/jeecg-boot', // api base_url
timeout: 6000 // 请求超时时间
timeout: 9000 // 请求超时时间
})
const err = (error) => {

View File

@ -1,3 +1,4 @@
import * as api from '@/api/api'
import { isURL } from '@/utils/validate'
export function timeFix() {
@ -125,7 +126,10 @@ function generateChildRouters (data) {
icon: item.meta.icon,
url:item.meta.url ,
permissionList:item.meta.permissionList,
keepAlive:item.meta.keepAlive
keepAlive:item.meta.keepAlive,
/*update_begin author:wuxianquan date:20190908 for:赋值 */
internalOrExternal:item.meta.internalOrExternal
/*update_end author:wuxianquan date:20190908 for:赋值 */
}
}
if(item.alwaysShow){
@ -251,4 +255,44 @@ export function cssExpand(css, id) {
}
// 应用新样式
document.head.appendChild(style)
}
/**
* 重复值验证工具方法
*
* 使用示例:
* { validator: (rule, value, callback) => validateDuplicateValue('sys_fill_rule', 'rule_code', value, this.model.id, callback) }
*
* @param tableName 被验证的表名
* @param fieldName 被验证的字段名
* @param fieldVal 被验证的值
* @param dataId 数据ID可空
* @param callback
*/
export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) {
let params = { tableName, fieldName, fieldVal, dataId }
api.duplicateCheck(params).then(res => {
res['success'] ? callback() : callback(res['message'])
}).catch(err => {
callback(err.message || err)
})
}
/**
* 如果值不存在就 push 进数组,反之不处理
* @param array 要操作的数据
* @param value 要添加的值
* @param key 可空,如果比较的是对象,可能存在地址不一样但值实际上是一样的情况,可以传此字段判断对象中唯一的字段,例如 id。不传则直接比较实际值
* @returns {boolean} 成功 push 返回 true不处理返回 false
*/
export function pushIfNotExist(array, value, key) {
for (let item of array) {
if (key && (item[key] === value[key])) {
return false
} else if (item === value) {
return false
}
}
array.push(value)
return true
}

View File

@ -1,269 +1,41 @@
<template>
<div class="page-header-index-wide">
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="总销售额" total="126,560">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<trend flag="up" style="margin-right: 16px;">
<span slot="term">周同比</span>
12%
</trend>
<trend flag="down">
<span slot="term">日同比</span>
11%
</trend>
</div>
<template slot="footer">日均销售额<span>¥ 234.56</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="访问量" :total="8846 | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area />
</div>
<template slot="footer">日访问量<span> {{ '1234' | NumberFormat }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="支付笔数" :total="6560 | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar :height="40" />
</div>
<template slot="footer">转化率 <span>60%</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="运营活动效果" total="78%">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-progress color="rgb(19, 194, 194)" :target="80" :percentage="78" :height="8" />
</div>
<template slot="footer">
<trend flag="down" style="margin-right: 16px;">
<span slot="term">同周比</span>
12%
</trend>
<trend flag="up">
<span slot="term">日环比</span>
80%
</trend>
</template>
</chart-card>
</a-col>
</a-row>
<a-card :loading="loading" :bordered="false" :body-style="{padding: '0'}">
<div class="salesCard">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrapper" slot="tabBarExtraContent">
<div class="extra-item">
<a>今日</a>
<a>本周</a>
<a>本月</a>
<a>本年</a>
</div>
<a-range-picker :style="{width: '256px'}" />
</div>
<a-tab-pane loading="true" tab="销售额" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额排行" :dataSource="barData"/>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList"/>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="访问量" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额趋势" :dataSource="barData"/>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList"/>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
</div>
</a-card>
<a-row>
<a-col :span="24">
<a-card :loading="loading" :bordered="false" title="最近一周访问次数统计" :style="{ marginTop: '24px' }">
<a-row>
<a-col :span="6">
<head-info title="今日访问IP数" :content="loginfo.todayIp"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="environment" style="font-size: 24px" />
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="今日访问次数" :content="loginfo.todayVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="team" style="font-size: 24px" />
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="访问总次数" :content="loginfo.totalVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="rise" style="font-size: 24px" />
</a-spin>
</a-col>
</a-row>
<line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid>
</a-card>
</a-col>
</a-row>
<div>
<index-chart v-if="indexStyle==1"></index-chart>
<index-bdc v-if="indexStyle==2"></index-bdc>
<index-task v-if="indexStyle==3"></index-task>
<div style="width: 100%;text-align: right;margin-top: 20px">
请选择首页样式
<a-radio-group v-model="indexStyle">
<a-radio :value="1">统计图表</a-radio>
<a-radio :value="2">统计图表2</a-radio>
<a-radio :value="3">任务表格</a-radio>
</a-radio-group>
</div>
</div>
</template>
<script>
import ChartCard from '@/components/ChartCard'
import ACol from "ant-design-vue/es/grid/Col"
import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
import MiniArea from '@/components/chart/MiniArea'
import MiniBar from '@/components/chart/MiniBar'
import MiniProgress from '@/components/chart/MiniProgress'
import RankList from '@/components/chart/RankList'
import Bar from '@/components/chart/Bar'
import LineChartMultid from '@/components/chart/LineChartMultid'
import HeadInfo from '@/components/tools/HeadInfo.vue'
import IndexChart from './IndexChart'
import IndexTask from "./IndexTask"
import IndexBdc from './IndexBdc'
import Trend from '@/components/Trend'
import { getLoginfo,getVisitInfo } from '@/api/api'
const rankList = []
for (let i = 0; i < 7; i++) {
rankList.push({
name: '白鹭岛 ' + (i+1) + ' 号店',
total: 1234.56 - i * 100
})
}
const barData = []
for (let i = 0; i < 12; i += 1) {
barData.push({
x: `${i + 1}月`,
y: Math.floor(Math.random() * 1000) + 200
})
}
export default {
name: "Analysis",
components: {
ATooltip,
ACol,
ChartCard,
MiniArea,
MiniBar,
MiniProgress,
RankList,
Bar,
Trend,
LineChartMultid,
HeadInfo
IndexChart,
IndexTask,
IndexBdc
},
data() {
return {
loading: true,
center: null,
rankList,
barData,
loginfo:{},
visitFields:['ip','visit'],
visitInfo:[],
indicator: <a-icon type="loading" style="font-size: 24px" spin />
indexStyle:1
}
},
created() {
setTimeout(() => {
this.loading = !this.loading
}, 1000)
this.initLogInfo();
},
methods: {
initLogInfo () {
getLoginfo(null).then((res)=>{
if(res.success){
Object.keys(res.result).forEach(key=>{
res.result[key] =res.result[key]+""
})
this.loginfo = res.result;
}
})
getVisitInfo().then(res=>{
if(res.success){
console.log("aaaaaa",res.result)
this.visitInfo = res.result;
}
})
},
}
}
</script>
<style lang="scss" scoped>
.circle-cust{
position: relative;
top: 28px;
left: -100%;
}
.extra-wrapper {
line-height: 55px;
padding-right: 24px;
.extra-item {
display: inline-block;
margin-right: 24px;
a {
margin-left: 24px;
}
}
}
/* 首页访问量统计 */
.head-info {
position: relative;
text-align: left;
padding: 0 32px 0 0;
min-width: 125px;
&.center {
text-align: center;
padding: 0 32px;
}
span {
color: rgba(0, 0, 0, .45);
display: inline-block;
font-size: .95rem;
line-height: 42px;
margin-bottom: 4px;
}
p {
line-height: 42px;
margin: 0;
a {
font-weight: 600;
font-size: 1rem;
}
}
}
</style>
</script>

View File

@ -0,0 +1,519 @@
<template>
<div class="page-header-index-wide">
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="受理量" :total="cardCount.sll | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area :datasource="chartData.sll" />
</div>
<template slot="footer">今日受理量:<span>{{ todaySll }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="办结量" :total="cardCount.bjl | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area :datasource="chartData.bjl"/>
</div>
<template slot="footer">今日办结量:<span>{{ todayBjl }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="用户受理量" :total="cardCount.isll | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar :datasource="chartData.isll" :height="50"/>
</div>
<template slot="footer">用户今日受理量:<span>{{ todayISll }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="用户办结量" :total="cardCount.ibjl | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar :datasource="chartData.ibjl" :height="50"/>
</div>
<template slot="footer">用户今日办结量:<span>{{ todayIBjl }}</span></template>
</chart-card>
</a-col>
</a-row>
<a-card :loading="loading" :bordered="false" :body-style="{padding: '0'}">
<div class="salesCard">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrapper" slot="tabBarExtraContent">
<div class="extra-item">
<a>今日</a>
<a>本周</a>
<a>本月</a>
<a>本年</a>
</div>
<a-range-picker :style="{width: '256px'}" />
</div>
<a-tab-pane loading="true" tab="受理监管" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<index-bar title="受理量统计" />
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="12" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="交互监管" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar-multid :sourceData="jhjgData" :fields="jhjgFields" title="平台与部门交互量统计"></bar-multid>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="12" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="存储监管" key="4">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<a-row>
<template v-if="diskInfo && diskInfo.length>0">
<a-col :span="12" v-for="(item,index) in diskInfo" :key=" 'diskInfo'+index ">
<dash-chart-demo :title="item.name" :datasource="item.restPPT"></dash-chart-demo>
</a-col>
</template>
</a-row>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="10" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
</div>
</a-card>
<a-row :gutter="12">
<a-card :loading="loading" :class="{ 'anty-list-cust':true }" :bordered="false" :style="{ marginTop: '24px' }">
<a-tabs v-model="indexBottomTab" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrapper" slot="tabBarExtraContent">
<a-radio-group v-model="indexRegisterType" @change="changeRegisterType">
<a-radio-button value="转移登记">转移登记</a-radio-button>
<a-radio-button value="抵押登记">抵押登记</a-radio-button>
<a-radio-button value="">所有</a-radio-button>
</a-radio-group>
</div>
<a-tab-pane loading="true" tab="业务流程限时监管" key="1">
<a-table :dataSource="dataSource1" size="default" rowKey="id" :columns="columns" :pagination="ipagination1" @change="tableChange1">
<template slot="flowRate" slot-scope="text, record, index">
<a-progress :strokeColor="getPercentColor(record.flowRate)" :format="getPercentFormat" :percent="getFlowRateNumber(record.flowRate)" style="width:80px" />
</template>
</a-table>
</a-tab-pane>
<a-tab-pane loading="true" tab="业务节点限时监管" key="2">
<a-table :dataSource="dataSource2" size="default" rowKey="id" :columns="columns2" :pagination="ipagination2" @change="tableChange2">
<template slot="flowRate" slot-scope="text, record, index">
<span style="color: red;">{{ record.flowRate }}小时</span>
</template>
</a-table>
</a-tab-pane>
</a-tabs>
</a-card>
</a-row>
</div>
</template>
<script>
import ACol from "ant-design-vue/es/grid/Col"
import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
import ChartCard from '@/components/ChartCard'
import MiniBar from '@/components/chart/MiniBar'
import MiniArea from '@/components/chart/MiniArea'
import IndexBar from '@/components/chart/IndexBar'
import BarMultid from '@/components/chart/BarMultid'
import DashChartDemo from '@/components/chart/DashChartDemo'
const jhjgData = [
{ type: '房管', '1月': 900, '2月': 1120, '3月': 1380, '4月': 1480, '5月': 1450, '6月': 1100, '7月':1300, '8月':900,'9月':1000 ,'10月':1200 ,'11月':600 ,'12月':900 },
{ type: '税务', '1月':1200, '2月': 1500, '3月': 1980, '4月': 2000, '5月': 1000, '6月': 600, '7月':900, '8月':1100,'9月':1300 ,'10月':2000 ,'11月':900 ,'12月':1100 },
{ type: '不动产', '1月':2000, '2月': 1430, '3月': 1300, '4月': 1400, '5月': 900, '6月': 500, '7月':600, '8月':1000,'9月':600 ,'10月':1000 ,'11月':1500 ,'12月':1200 }
]
const jhjgFields=[
'1月','2月','3月','4月','5月','6月',
'7月','8月','9月','10月','11月','12月'
]
const xljgData = [
{type:'一月',"房管":1.12,"税务":1.55,"不动产":1.2},
{type:'二月',"房管":1.65,"税务":1.32,"不动产":1.42},
{type:'三月',"房管":1.85,"税务":1.1,"不动产":1.5},
{type:'四月',"房管":1.33,"税务":1.63,"不动产":1.4},
{type:'五月',"房管":1.63,"税务":1.8,"不动产":1.7},
{type:'六月',"房管":1.85,"税务":1.98,"不动产":1.8},
{type:'七月',"房管":1.98,"税务":1.5,"不动产":1.76},
{type:'八月',"房管":1.48,"税务":1.2,"不动产":1.3},
{type:'九月',"房管":1.41,"税务":1.9,"不动产":1.6},
{type:'十月',"房管":1.1,"税务":1.1,"不动产":1.4},
{type:'十一月',"房管":1.85,"税务":1.6,"不动产":1.5},
{type:'十二月',"房管":1.5,"税务":1.4,"不动产":1.3}
]
const xljgFields=["房管","税务","不动产"]
const dataCol1 = [{
title: '业务号',
align:"center",
dataIndex: 'reBizCode'
},{
title: '业务类型',
align:"center",
dataIndex: 'type'
},{
title: '受理人',
align:"center",
dataIndex: 'acceptBy'
},{
title: '受理时间',
align:"center",
dataIndex: 'acceptDate'
},{
title: '当前节点',
align:"center",
dataIndex: 'curNode'
},{
title: '办理时长',
align:"center",
dataIndex: 'flowRate',
scopedSlots: { customRender: 'flowRate' }
}];
const dataSource1=[
{reBizCode:"1",type:"转移登记",acceptBy:'张三',acceptDate:"2019-01-22",curNode:"任务分派",flowRate:60},
{reBizCode:"2",type:"抵押登记",acceptBy:'李四',acceptDate:"2019-01-23",curNode:"领导审核",flowRate:30},
{reBizCode:"3",type:"转移登记",acceptBy:'王武',acceptDate:"2019-01-25",curNode:"任务处理",flowRate:20},
{reBizCode:"4",type:"转移登记",acceptBy:'赵楼',acceptDate:"2019-11-22",curNode:"部门审核",flowRate:80},
{reBizCode:"5",type:"转移登记",acceptBy:'钱就',acceptDate:"2019-12-12",curNode:"任务分派",flowRate:90},
{reBizCode:"6",type:"转移登记",acceptBy:'孙吧',acceptDate:"2019-03-06",curNode:"任务处理",flowRate:10},
{reBizCode:"7",type:"抵押登记",acceptBy:'周大',acceptDate:"2019-04-13",curNode:"任务分派",flowRate:100},
{reBizCode:"8",type:"抵押登记",acceptBy:'吴二',acceptDate:"2019-05-09",curNode:"任务上报",flowRate:50},
{reBizCode:"9",type:"抵押登记",acceptBy:'郑爽',acceptDate:"2019-07-12",curNode:"任务处理",flowRate:63},
{reBizCode:"20",type:"抵押登记",acceptBy:'林有',acceptDate:"2019-12-12",curNode:"任务打回",flowRate:59},
{reBizCode:"11",type:"转移登记",acceptBy:'码云',acceptDate:"2019-09-10",curNode:"任务签收",flowRate:87},
]
const dataCol2 = [{
title: '业务号',
align:"center",
dataIndex: 'reBizCode'
},{
title: '受理人',
align:"center",
dataIndex: 'acceptBy'
},{
title: '发起时间',
align:"center",
dataIndex: 'acceptDate'
},{
title: '当前节点',
align:"center",
dataIndex: 'curNode'
},{
title: '超时时间',
align:"center",
dataIndex: 'flowRate',
scopedSlots: { customRender: 'flowRate' }
}];
const dataSource2=[
{reBizCode:"A001",type:"转移登记",acceptBy:'张四',acceptDate:"2019-01-22",curNode:"任务分派",flowRate:12},
{reBizCode:"A002",type:"抵押登记",acceptBy:'李吧',acceptDate:"2019-01-23",curNode:"任务签收",flowRate:3},
{reBizCode:"A003",type:"转移登记",acceptBy:'王三',acceptDate:"2019-01-25",curNode:"任务处理",flowRate:24},
{reBizCode:"A004",type:"转移登记",acceptBy:'赵二',acceptDate:"2019-11-22",curNode:"部门审核",flowRate:10},
{reBizCode:"A005",type:"转移登记",acceptBy:'钱大',acceptDate:"2019-12-12",curNode:"任务签收",flowRate:8},
{reBizCode:"A006",type:"转移登记",acceptBy:'孙就',acceptDate:"2019-03-06",curNode:"任务处理",flowRate:10},
{reBizCode:"A007",type:"抵押登记",acceptBy:'周晕',acceptDate:"2019-04-13",curNode:"部门审核",flowRate:24},
{reBizCode:"A008",type:"抵押登记",acceptBy:'吴有',acceptDate:"2019-05-09",curNode:"部门审核",flowRate:30},
{reBizCode:"A009",type:"抵押登记",acceptBy:'郑武',acceptDate:"2019-07-12",curNode:"任务分派",flowRate:1},
{reBizCode:"A0010",type:"抵押登记",acceptBy:'林爽',acceptDate:"2019-12-12",curNode:"部门审核",flowRate:16},
{reBizCode:"A0011",type:"转移登记",acceptBy:'码楼',acceptDate:"2019-09-10",curNode:"部门审核",flowRate:7},
]
export default {
name: "IndexBdc",
components: {
ATooltip,
ACol,
ChartCard,
MiniArea,
MiniBar,
DashChartDemo,
BarMultid,
IndexBar
},
data() {
return {
loading: true,
cardCount:{
sll:100,
bjl:87,
isll:15,
ibjl:9
},
todaySll:60,
todayBjl:54,
todayISll:13,
todayIBjl:7,
chartData:{
sll:[],
bjl:[],
isll:[],
ibjl:[]
},
jhjgFields,
jhjgData,
xljgData,
xljgFields,
diskInfo:[
{name:"C盘",restPPT:7},
{name:"D盘",restPPT:5}
],
registerTypeList:[{
text:"业务受理"
},{
text:"业务管理"
},{
text:"文件管理"
},{
text:"信息查询"
}],
dataSource1:[],
dataSource2:[],
columns:dataCol1,
columns2:dataCol2,
ipagination1:{
current: 1,
pageSize: 5,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " " + total + ""
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
ipagination2:{
current: 1,
pageSize: 5,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " " + total + ""
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
indexRegisterType:"转移登记",
indexBottomTab:"1"
}
},
methods:{
goPage(){
this.$message.success("根据业务自行处理跳转页面!")
},
changeRegisterType(e){
this.indexRegisterType = e.target.value
if(this.indexBottomTab=="1"){
this.loadDataSource1()
}else{
this.loadDataSource2()
}
},
tableChange1(pagination){
this.ipagination1.current = pagination.current
this.ipagination1.pageSize = pagination.pageSize
this.queryTimeoutInfo()
},
tableChange2(pagination){
this.ipagination2.current = pagination.current
this.ipagination2.pageSize = pagination.pageSize
this.queryNodeTimeoutInfo()
},
getFlowRateNumber(value){
return Number(value)
},
getPercentFormat(value){
if(value==100){
return "超时"
}else{
return value+"%"
}
},
getPercentColor(value){
let p = Number(value)
if(p>=90 && p<100){
return 'rgb(244, 240, 89)'
}else if(p>=100){
return 'red'
}else{
return 'rgb(16, 142, 233)'
}
},
loadDataSource1(){
this.dataSource1 = dataSource1.filter(item=>{
if(!this.indexRegisterType){
return true
}
return item.type==this.indexRegisterType
})
},
loadDataSource2(){
this.dataSource2 = dataSource2.filter(item=>{
if(!this.indexRegisterType){
return true
}
return item.type==this.indexRegisterType
})
}
},
created() {
this.loadDataSource1()
this.loadDataSource2()
setTimeout(() => {
this.loading = !this.loading
}, 1000)
}
}
</script>
<style lang="scss" scoped>
.extra-wrapper {
line-height: 55px;
padding-right: 24px;
.extra-item {
display: inline-block;
margin-right: 24px;
a {
margin-left: 24px;
}
}
}
.item-group {
padding: 20px 0 8px 24px;
font-size: 0;
a {
color: rgba(0, 0, 0, 0.65);
display: inline-block;
font-size: 14px;
margin-bottom: 13px;
width: 25%;
}
}
.item-group {
.more-btn {
margin-bottom: 13px;
text-align: center;
}
}
.list-content-item {
color: rgba(0, 0, 0, .45);
display: inline-block;
vertical-align: middle;
font-size: 14px;
margin-left: 40px;
}
@media only screen and (min-width: 1600px) {
.list-content-item{
margin-left:60px;
}
}
@media only screen and (max-width: 1300px) {
.list-content-item{
margin-left:20px;
}
.width-hidden4{
display:none
}
}
.list-content-item{
span{line-height: 20px;}
}
.list-content-item{
p{margin-top: 4px;margin-bottom:0;line-height:22px;}
}
.anty-list-cust {
.ant-list-item-meta{flex: 0.3 !important;}
}
.anty-list-cust {
.ant-list-item-content{flex:1 !important; justify-content:flex-start !important;margin-left: 20px;}
}
</style>

View File

@ -0,0 +1,269 @@
<template>
<div class="page-header-index-wide">
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="总销售额" total="126,560">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<trend flag="up" style="margin-right: 16px;">
<span slot="term">周同比</span>
12%
</trend>
<trend flag="down">
<span slot="term">日同比</span>
11%
</trend>
</div>
<template slot="footer">日均销售额<span>¥ 234.56</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="访问量" :total="8846 | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area />
</div>
<template slot="footer">日访问量<span> {{ '1234' | NumberFormat }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="支付笔数" :total="6560 | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar :height="40" />
</div>
<template slot="footer">转化率 <span>60%</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="运营活动效果" total="78%">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-progress color="rgb(19, 194, 194)" :target="80" :percentage="78" :height="8" />
</div>
<template slot="footer">
<trend flag="down" style="margin-right: 16px;">
<span slot="term">同周比</span>
12%
</trend>
<trend flag="up">
<span slot="term">日环比</span>
80%
</trend>
</template>
</chart-card>
</a-col>
</a-row>
<a-card :loading="loading" :bordered="false" :body-style="{padding: '0'}">
<div class="salesCard">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrapper" slot="tabBarExtraContent">
<div class="extra-item">
<a>今日</a>
<a>本周</a>
<a>本月</a>
<a>本年</a>
</div>
<a-range-picker :style="{width: '256px'}" />
</div>
<a-tab-pane loading="true" tab="销售额" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额排行" :dataSource="barData"/>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList"/>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="访问量" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额趋势" :dataSource="barData"/>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList"/>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
</div>
</a-card>
<a-row>
<a-col :span="24">
<a-card :loading="loading" :bordered="false" title="最近一周访问次数统计" :style="{ marginTop: '24px' }">
<a-row>
<a-col :span="6">
<head-info title="今日访问IP数" :content="loginfo.todayIp"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="environment" style="font-size: 24px" />
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="今日访问次数" :content="loginfo.todayVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="team" style="font-size: 24px" />
</a-spin>
</a-col>
<a-col :span="6">
<head-info title="访问总次数" :content="loginfo.totalVisitCount"></head-info>
</a-col>
<a-col :span="2">
<a-spin class='circle-cust'>
<a-icon slot="indicator" type="rise" style="font-size: 24px" />
</a-spin>
</a-col>
</a-row>
<line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script>
import ChartCard from '@/components/ChartCard'
import ACol from "ant-design-vue/es/grid/Col"
import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
import MiniArea from '@/components/chart/MiniArea'
import MiniBar from '@/components/chart/MiniBar'
import MiniProgress from '@/components/chart/MiniProgress'
import RankList from '@/components/chart/RankList'
import Bar from '@/components/chart/Bar'
import LineChartMultid from '@/components/chart/LineChartMultid'
import HeadInfo from '@/components/tools/HeadInfo.vue'
import Trend from '@/components/Trend'
import { getLoginfo,getVisitInfo } from '@/api/api'
const rankList = []
for (let i = 0; i < 7; i++) {
rankList.push({
name: '白鹭岛 ' + (i+1) + ' 号店',
total: 1234.56 - i * 100
})
}
const barData = []
for (let i = 0; i < 12; i += 1) {
barData.push({
x: `${i + 1}月`,
y: Math.floor(Math.random() * 1000) + 200
})
}
export default {
name: "IndexChart",
components: {
ATooltip,
ACol,
ChartCard,
MiniArea,
MiniBar,
MiniProgress,
RankList,
Bar,
Trend,
LineChartMultid,
HeadInfo
},
data() {
return {
loading: true,
center: null,
rankList,
barData,
loginfo:{},
visitFields:['ip','visit'],
visitInfo:[],
indicator: <a-icon type="loading" style="font-size: 24px" spin />
}
},
created() {
setTimeout(() => {
this.loading = !this.loading
}, 1000)
this.initLogInfo();
},
methods: {
initLogInfo () {
getLoginfo(null).then((res)=>{
if(res.success){
Object.keys(res.result).forEach(key=>{
res.result[key] =res.result[key]+""
})
this.loginfo = res.result;
}
})
getVisitInfo().then(res=>{
if(res.success){
console.log("aaaaaa",res.result)
this.visitInfo = res.result;
}
})
},
}
}
</script>
<style lang="scss" scoped>
.circle-cust{
position: relative;
top: 28px;
left: -100%;
}
.extra-wrapper {
line-height: 55px;
padding-right: 24px;
.extra-item {
display: inline-block;
margin-right: 24px;
a {
margin-left: 24px;
}
}
}
/* 首页访问量统计 */
.head-info {
position: relative;
text-align: left;
padding: 0 32px 0 0;
min-width: 125px;
&.center {
text-align: center;
padding: 0 32px;
}
span {
color: rgba(0, 0, 0, .45);
display: inline-block;
font-size: .95rem;
line-height: 42px;
margin-bottom: 4px;
}
p {
line-height: 42px;
margin: 0;
a {
font-weight: 600;
font-size: 1rem;
}
}
}
</style>

View File

@ -0,0 +1,372 @@
<template>
<div class="index-container-ty">
<a-spin :spinning="loading">
<a-row type="flex" justify="start" :gutter="3">
<a-col :sm="24" :lg="12">
<a-card>
<div slot="title" class="index-md-title">
<img src="../../assets/daiban.png"/>
我的待办【{{ dataSource1.length }}】
</div>
<div slot="extra">
<a v-if="dataSource1 && dataSource1.length>0" slot="footer" @click="goPage">更多 <a-icon type="double-right" /></a>
</div>
<a-table
:class="'my-index-table tytable1'"
ref="table1"
size="small"
rowKey="id"
:columns="columns"
:dataSource="dataSource1"
:pagination="false">
<template slot="ellipsisText" slot-scope="text">
<j-ellipsis :value="text" :length="textMaxLength"></j-ellipsis>
</template>
<template slot="dayWarnning" slot-scope="text,record">
<a-icon type="bulb" theme="twoTone" style="font-size:22px" :twoToneColor="getTipColor(record)"/>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleData">办理</a>
</span>
</a-table>
</a-card>
</a-col>
<a-col :sm="24" :lg="12">
<a-card>
<div slot="title" class="index-md-title">
<img src="../../assets/zaiban.png"/>
我的在办【{{ dataSource2.length }}】
</div>
<div slot="extra">
<a v-if="dataSource2 && dataSource2.length>0" slot="footer" @click="goPage">更多 <a-icon type="double-right" /></a>
</div>
<a-table
:class="'my-index-table tytable2'"
ref="table2"
size="small"
rowKey="id"
:columns="columns"
:dataSource="dataSource2"
:pagination="false">
<template slot="ellipsisText" slot-scope="text">
<j-ellipsis :value="text" :length="textMaxLength"></j-ellipsis>
</template>
<template slot="dayWarnning" slot-scope="text,record">
<a-icon type="bulb" theme="twoTone" style="font-size:22px" :twoToneColor="getTipColor(record)"/>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleData">办理</a>
</span>
</a-table>
</a-card>
</a-col>
<a-col :span="24">
<div style="height: 5px;"></div>
</a-col>
<a-col :sm="24" :lg="12">
<a-card>
<div slot="title" class="index-md-title">
<img src="../../assets/guaz.png"/>
我的挂账【{{ dataSource4.length }}】
</div>
<a-table
:class="'my-index-table tytable4'"
ref="table4"
size="small"
rowKey="id"
:columns="columns"
:dataSource="dataSource4"
:pagination="false">
<template slot="ellipsisText" slot-scope="text">
<j-ellipsis :value="text" :length="textMaxLength"></j-ellipsis>
</template>
<template slot="dayWarnning" slot-scope="text,record">
<a-icon type="bulb" theme="twoTone" style="font-size:22px" :twoToneColor="getTipColor(record)"/>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleData">办理</a>
</span>
</a-table>
</a-card>
</a-col>
<a-col :sm="24" :lg="12">
<a-card>
<div slot="title" class="index-md-title">
<img src="../../assets/duban.png"/>
我的督办【{{ dataSource3.length }}】
</div>
<a-table
:class="'my-index-table tytable3'"
ref="table3"
size="small"
rowKey="id"
:columns="columns"
:dataSource="dataSource3"
:pagination="false">
<template slot="ellipsisText" slot-scope="text">
<j-ellipsis :value="text" :length="textMaxLength"></j-ellipsis>
</template>
<template slot="dayWarnning" slot-scope="text,record">
<a-icon type="bulb" theme="twoTone" style="font-size:22px" :twoToneColor="getTipColor(record)"/>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleData">办理</a>
</span>
</a-table>
</a-card>
</a-col>
</a-row>
</a-spin>
</div>
</template>
<script>
import noDataPng from '@/assets/nodata.png'
import JEllipsis from '@/components/jeecg/JEllipsis'
const tempSs1=[{
id:"001",
orderNo:"[1]1267102",
orderTitle:"药品出问题了",
restDay:1
},{
id:"002",
orderNo:"[4]5967102",
orderTitle:"吃了xxx医院的药病情越来越严重",
restDay:0
},{
id:"003",
orderNo:"[3]5988987",
orderTitle:"今天去超市买鸡蛋鸡蛋都是坏的",
restDay:7
},{
id:"004",
orderNo:"[2]5213491",
orderTitle:"xx宝实体店高价售卖xx",
restDay:5
},{
id:"005",
orderNo:"[1]1603491",
orderTitle:"以红利相诱答应退保后扣一年费用",
restDay:0
}]
const tempSs2=[{
id:"001",
orderTitle:"我要投诉这个大超市",
orderNo:"[1]10299456",
restDay:6
},{
id:"002",
orderTitle:"xxx医院乱开药方,售卖假药",
orderNo:"[2]20235691",
restDay:0
},{
id:"003",
orderTitle:"我想问问这家店是干啥的",
orderNo:"[3]495867322",
restDay:7
},{
id:"004",
orderTitle:"我要举报朝阳区奥森公园酒店",
orderNo:"[2]1193849",
restDay:3
},{
id:"005",
orderTitle:"我今天吃饭吃到一个石头子",
orderNo:"[4]56782344",
restDay:9
}]
//4-7天
const tip_green = "rgba(0, 255, 0, 1)"
//1-3天
const tip_yellow = "rgba(255, 255, 0, 1)"
//超期
const tip_red = "rgba(255, 0, 0, 1)"
export default {
name: "IndexTask",
components:{ JEllipsis },
data() {
return {
loading:false,
textMaxLength:8,
dataSource1:[],
dataSource2:[],
dataSource3:[],
dataSource4:[],
columns: [
{
title: '',
dataIndex: '',
key:'rowIndex',
width:50,
fixed:'left',
align:"center",
scopedSlots: {customRender: "dayWarnning"}
},
{
title:'剩余天数',
align:"center",
dataIndex: 'restDay',
width:80
},
{
title:'工单标题',
align:"center",
dataIndex: 'orderTitle',
scopedSlots: {customRender: "ellipsisText"}
},
{
title:'工单编号',
align:"center",
dataIndex: 'orderNo',
},
{
title: '操作',
dataIndex: 'action',
align:"center",
scopedSlots: { customRender: 'action' }
}
]
}
},
created() {
this.mock();
},
mounted(){
},
methods: {
getTipColor(rd){
let num = rd.restDay
if(num<=0){
return tip_red
}else if(num>=1 && num<4){
return tip_yellow
}else if(num>=4){
return tip_green
}
},
goPage(){
this.$message.success("请根据具体业务跳转页面")
//this.$router.push({ path: '/comp/mytask' })
},
mock(){
this.dataSource1=tempSs1
this.dataSource2=tempSs2
this.dataSource3=tempSs1
this.dataSource4=[]
this.ifNullDataSource(this.dataSource4,'.tytable4')
},
ifNullDataSource(ds,tb){
this.$nextTick(()=>{
if(!ds || ds.length==0){
var tmp = document.createElement('img');
tmp.src=noDataPng
tmp.width=300
let tbclass=`${tb} .ant-table-placeholder`
document.querySelector(tbclass).innerHTML=""
document.querySelector(tbclass).appendChild(tmp)
}
})
},
handleData(){
this.$message.success("办理完成")
}
}
}
</script>
<style>
.my-index-table{height:270px}
.my-index-table table{font-size: 14px !important;}
.index-container-ty .ant-card-head-title{padding-top: 6px;padding-bottom: 6px;}
.index-container-ty .ant-card-extra{padding:0}
.index-container-ty .ant-card-extra a{color:#fff}
.index-container-ty .ant-card-extra a:hover{color:#152ede}
.index-container-ty .ant-card-head-wrapper,.index-container-ty .ant-card-head{
line-height:24px;
min-height:24px;
/*background: #90aeff;*/
background: #7196fb;
}
.index-container-ty .ant-card-body{padding: 10px 12px 0px 12px}
/* .index-container-ty .ant-card-actions{background: #fff}
.index-container-ty .ant-card-actions li {margin:2px 0;}
.index-container-ty .ant-card-actions > li > span{width: 100%}*/
.index-container-ty .ant-table-footer{text-align: right;padding:6px 12px 6px 6px;background: #fff;border-top: 2px solid #f7f1f1;}
.index-md-title{
postion:relative;
padding-left:24px;
width: 100%;
color: #fff;
font-size: 21px;
font-family: cursive;
}
.index-md-title img{
position: absolute;
height:32px;
top: 2px;
left:14px;
}
.index-container-ty .ant-card-body{
/*border-left:1px solid #90aeff;
/*border-right:1px solid #90aeff;
border-bottom:1px solid #90aeff;*/
}
.index-container-ty .ant-table-thead > tr > th,
.index-container-ty .ant-table-tbody > tr > td{
border-bottom: 1px solid #90aeff;
}
.index-container-ty .ant-table-small > .ant-table-content > .ant-table-fixed-left > .ant-table-body-outer > .ant-table-body-inner > table > .ant-table-thead > tr > th,
.index-container-ty .ant-table-small > .ant-table-content > .ant-table-fixed-right > .ant-table-body-outer > .ant-table-body-inner > table > .ant-table-thead > tr > th{
border-bottom: 1px solid #90aeff;
}
.index-container-ty .ant-table-small > .ant-table-content > .ant-table-scroll > .ant-table-body > table > .ant-table-thead > tr > th{
border-bottom: 1px solid #90aeff;
}
.index-container-ty .ant-table-small{
border: 1px solid #90aeff;
}
.index-container-ty .ant-table-placeholder {
padding: 0
}
</style>

View File

@ -3,29 +3,39 @@
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="">
<a-input placeholder="请输入名称查询" v-model="queryParam.name"></a-input>
<a-form-item label="用户">
<j-input placeholder="请输入名称模糊查询" v-model="queryParam.name"></j-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="年龄">
<a-input placeholder="请输入名称查询" v-model="queryParam.age"></a-input>
<!-- <a-input placeholder="请输入名称查询" v-model="queryParam.age"></a-input>-->
<a-input placeholder="最小年龄" type="ge" v-model="queryParam.age_begin" style="width:calc(50% - 15px);"></a-input>
<span class="group-query-strig">~</span>
<a-input placeholder="最大年龄" type="le" v-model="queryParam.age_end" style="width:calc(50% - 15px);"></a-input>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8">
<a-form-item label="字典下拉">
<j-dict-select-tag v-model="queryParam.sex" placeholder="请选择用户名称" dictCode="sex"/>
<a-form-item label="生日">
<a-range-picker v-model="queryParam.birthdayRange"
format="YYYY-MM-DD"
:placeholder="['开始时间', '结束时间']"
@change="onBirthdayChange" />
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="字典表下拉">
<j-dict-select-tag v-model="queryParam.realname" placeholder="请选择用户" dictCode="sys_user,realname,id"/>
<a-form-item label="性别">
<j-dict-select-tag v-model="queryParam.sex" placeholder="请选择性别" dictCode="sex"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="选择用户">
<j-dict-select-tag v-model="queryParam.id" placeholder="请选择用户" dictCode="demo,name,id"/>
</a-form-item>
</a-col>
</template>
@ -37,7 +47,7 @@
</span>
<a-col :md="6" :sm="24">
<template v-if="superQueryFlag">
<!-- <template v-if="superQueryFlag">
<a-tooltip title="已有高级查询条件生效!">
<button :disabled="false" class="ant-btn ant-btn-primary" @click="superQuery">
<a-icon type="appstore" theme="twoTone" spin="true"></a-icon>
@ -46,6 +56,9 @@
</a-tooltip>
</template>
<a-button v-else type="primary" @click="superQuery" icon="filter">高级查询</a-button>
-->
<!-- 高级查询区域 -->
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
@ -157,18 +170,18 @@
<!-- 一对多表单区域 -->
<JeecgDemoTabsModal ref="jeecgDemoTabsModal" @ok="modalFormOk"></JeecgDemoTabsModal>
<!-- 高级查询区域 -->
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
</a-card>
</template>
<script>
import JeecgDemoModal from './modules/JeecgDemoModal'
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
import JInput from '@/components/jeecg/JInput.vue';
import JeecgDemoTabsModal from './modules/JeecgDemoTabsModal'
import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Vue from 'vue'
import { filterObj } from '@/utils/util';
//高级查询modal需要参数
const superQueryFieldList=[{
@ -191,6 +204,7 @@
JeecgDemoModal,
JSuperQuery,
JeecgDemoTabsModal,
JInput
},
data() {
return {
@ -278,6 +292,22 @@
}
},
methods: {
getQueryParams(){
console.log(this.queryParam.birthdayRange)
//高级查询器
let sqp = {}
if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams)
}
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
delete param.birthdayRange; //范围参数不传递后台
return filterObj(param);
},
initDictConfig() {
console.log("--我才是真的方法!--")
//初始化字典 - 性别
@ -295,6 +325,11 @@
jump() {
this.$router.push({path: '/jeecg/helloworld'})
},
onBirthdayChange: function (value, dateString) {
console.log(dateString[0],dateString[1]);
this.queryParam.birthday_begin=dateString[0];
this.queryParam.birthday_end=dateString[1];
},
//列设置更改事件
onColSettingsChange (checkedValues) {
var key = this.$route.name+":colsettings";

View File

@ -132,23 +132,32 @@
}
</script>
<style scoped>
/*update_begin author:scott date:20191203 for:打印机打印的字体模糊问题 */
* {
color: #000000!important;
-webkit-tap-highlight-color: #000000!important;
}
/*update_end author:scott date:20191203 for:打印机打印的字体模糊问题 */
.abcdefg .ant-card-body{
margin-left: 0%;
margin-right: 0%;
margin-bottom: 1%;
border:0px solid black;
min-width: 800px;
color:#000000!important;
}
.explain{
text-align: left;
margin-left: 50px;
color:#000000!important;
}
.explain .ant-input,.sign .ant-input{
font-weight:bolder;
text-align:center;
border-left-width:0px!important;
border-top-width:0px!important;;
border-right-width:0px!important;;
border-top-width:0px!important;
border-right-width:0px!important;
}
.explain div{
margin-bottom: 10px;

View File

@ -39,8 +39,8 @@
<!-- 部门选择控件 -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择部门">
<j-select-depart v-decorator="['departId']" :trigger-change="true"></j-select-depart>
<a-form-item label="选择部门 自定义返回值">
<j-select-depart v-decorator="['departId']" :trigger-change="true" customReturnField="departName"></j-select-depart>
</a-form-item>
</a-col>
<a-col :span="12">选中的部门ID(v-decorator):{{ getDepartIdValue() }}</a-col>
@ -55,26 +55,36 @@
<a-col :span="12">选中的部门ID(v-model):{{ departId }}</a-col>
</a-row>
<!-- 用户选择控件 -->
<!-- 通过部门选择用户控件 -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择用户">
<j-select-user-by-dep v-model="userRealName"></j-select-user-by-dep>
<j-select-user-by-dep v-model="userIds" :multi="true"></j-select-user-by-dep>
</a-form-item>
</a-col>
<a-col :span="12">选中的用户(v-model):{{ userRealName }}</a-col>
<a-col :span="12">选中的用户(v-model):{{ userIds }}</a-col>
</a-row>
<!-- 用户选择控件 -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择用户">
<j-select-multi-user v-model="multiUser"></j-select-multi-user>
<j-select-multi-user v-model="multiUser" ></j-select-multi-user>
</a-form-item>
</a-col>
<a-col :span="12">选中的用户(v-model):{{ multiUser }}</a-col>
</a-row>
<!-- 角色选择 -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="选择角色">
<j-select-role v-model="formData.selectRole"/>
</a-form-item>
</a-col>
<a-col :span="12">选中值:{{ formData.selectRole}}</a-col>
</a-row>
<!-- JCheckbox -->
<a-row :gutter="24">
<a-col :span="12">
@ -213,12 +223,42 @@
<a-col :span="12"></a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="下拉树选择">
<j-tree-select
v-model="formData.treeSelect"
placeholder="请选择菜单"
dict="sys_permission,name,id"
pidField="parent_id"
pidValue=""
/>
</a-form-item>
</a-col>
<a-col :spapn="12">选中的值(v-model){{ formData.treeSelect }}</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="下拉树多选">
<j-tree-select
v-model="formData.treeSelectMultiple"
placeholder="请选择菜单"
dict="sys_permission,name,id"
pidField="parent_id"
pidValue=""
multiple
/>
</a-form-item>
</a-col>
<a-col :spapn="12">选中的值(v-model){{ formData.treeSelectMultiple }}</a-col>
</a-row>
<!-- VueCron -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="cron表达式">
<j-cron ref="innerVueCron" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?'}]" @change="setCorn"></j-cron>
<!-- <j-cron ref="innerVueCron" v-model="cron" @change="setCorn"></j-cron>-->
<j-cron ref="innerVueCron" v-decorator="['cronExpression', { initialValue: '* * * * * ? *' }]" @change="setCorn"></j-cron>
</a-form-item>
</a-col>
</a-row>
@ -234,6 +274,7 @@
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
import JSelectUserByDep from '@/components/jeecgbiz/JSelectUserByDep'
import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
import JSelectRole from '@/components/jeecgbiz/JSelectRole'
import JCheckbox from '@/components/jeecg/JCheckbox'
import JCodeEditor from '@/components/jeecg/JCodeEditor'
import JDate from '@/components/jeecg/JDate'
@ -244,6 +285,8 @@
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
import JTreeDict from "../../components/jeecg/JTreeDict.vue";
import JCron from "@/components/jeecg/JCron.vue";
import JTreeSelect from '@/components/jeecg/JTreeSelect'
export default {
name: 'SelectDemo',
components: {
@ -252,20 +295,21 @@
JSelectDepart,
JSelectUserByDep,
JSelectMultiUser,
JSelectRole,
JCheckbox,
JCodeEditor,
JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple,
JCron
JCron, JTreeSelect
},
data() {
return {
selectList: [],
selectedDepUsers: '',
formData:{},
formData: {},
form: this.$form.createForm(this),
departId: '4f1765520d6346f9bd9c79e2479e5b12,57197590443c44f083d42ae24ef26a2c',
userRealName: '',
multiUser: '',
userIds: 'admin',
multiUser: 'admin,jeecg',
jcheckbox: {
values: 'spring,jeecgboot',
options: [
@ -368,7 +412,6 @@ sayHi('hello, world!')`
this.modal.fullScreen = mode
},
setCorn(data){
this.$nextTick(() => {
this.form.cronExpression = data;
})

View File

@ -224,7 +224,7 @@
getAction(this.url.customerListByMainId, {mainId: record.id}).then((res) => {
if (res.success) {
this.loading = false;
this.innerData = res.result;
this.innerData = res.result.records;
}
});
}

View File

@ -19,11 +19,11 @@
<a-cascader :options="areaOptions" @change="onChange" :showSearch="{filter}" placeholder="Please select" />
</a-form-item>
</a-col>
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-col :md="24" :sm="24">
<a-button type="primary" htmlType="submit">Submit</a-button>
</a-col>
</a-form-item>
<a-col :md="24" :sm="24">
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-button type="primary" htmlType="submit">Submit</a-button>
</a-form-item>
</a-col>
</a-form>
</a-card>
</template>
@ -68,4 +68,4 @@
})
}
}
</script>
</script>

View File

@ -62,6 +62,31 @@
{
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
message: '${title}必须以字母开头可包含数字下划线横杠'
},
{
unique: true,
message: '${title}不能重复'
},
{
handler(type, value, row, column, callback, target) {
// type 触发校验的类型input、change、blur
// value 当前校验的值
// callback(flag, message) 方法必须执行且只能执行一次
// flag = 是否通过了校验,不填写或者填写 null 代表不进行任何操作
// message = 提示的类型,默认使用配置的 message
// target 行编辑的实例对象
if (type === 'blur') {
if (value === 'abc') {
callback(false, '${title}不能是abc') // false = 未通过校验
} else {
callback(true) // true = 通过验证
}
} else {
callback(true) // 不填写或者填写 null 代表不进行任何操作
}
},
message: '${title}默认提示'
}
]
},

View File

@ -133,14 +133,19 @@
if (arg === 1) {
this.ipagination.current = 1;
}
//update-begin--Author:kangxiaolin Date:20190905 for[442]主子表分开维护,生成的代码子表的分页改为真实的分页--------------------
var params = this.getQueryParams();
getAction(this.url.list, {mainId: params.mainId}).then((res) => {
getAction(this.url.list, {orderId: params.mainId, pageNo : this.ipagination.current,
pageSize :this.ipagination.pageSize}).then((res) => {
if (res.success) {
this.dataSource = res.result;
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
} else {
this.dataSource = null;
}
})
//update-end--Author:kangxiaolin Date:20190905 for[442]主子表分开维护,生成的代码子表的分页改为真实的分页--------------------
},
getOrderMain(orderId) {
this.queryParam.mainId = orderId;

View File

@ -123,13 +123,17 @@
this.ipagination.current = 1;
}
var params = this.getQueryParams();
getAction(this.url.list, {mainId: params.mainId}).then((res) => {
//update-begin--Author:kangxiaolin Date:20190905 for[442]主子表分开维护,生成的代码子表的分页改为真实的分页--------------------
getAction(this.url.list, {orderId: params.mainId ,pageNo : this.ipagination.current,
pageSize :this.ipagination.pageSize}).then((res) => {
if (res.success) {
this.dataSource = res.result;
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
} else {
this.dataSource = null;
}
})
//update-end--Author:kangxiaolin Date:20190905 for[442]主子表分开维护,生成的代码子表的分页改为真实的分页--------------------
},
getOrderMain(orderId) {
this.queryParam.mainId = orderId;

View File

@ -27,7 +27,7 @@
:wrapperCol="wrapperCol"
label="航班时间"
hasFeedback>
<j-date v-decorator="['tickectDate',{trigger:'input',rules:[{ required: true,message: '请输入航班号!'}]}]"></j-date>
<j-date :trigger-change="true" v-decorator="['tickectDate',{rules:[{ required: true,message: '请输入航班号!'}]}]"></j-date>
</a-form-item>
<a-form-item
:labelCol="labelCol"

View File

@ -3,7 +3,7 @@
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="消息标题">

View File

@ -3,7 +3,7 @@
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
@ -179,6 +179,9 @@
if(text=='3') {
return "微信";
}
if(text=='4') {
return "系统";
}
}
},
{

View File

@ -10,50 +10,70 @@
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板CODE">
<a-input
:disabled="disable"
placeholder="请输入模板编码"
v-decorator="['templateCode', validatorRules.templateCode ]"
/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板标题">
<a-input
placeholder="请输入模板标题"
v-decorator="['templateName', validatorRules.templateName]"
/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板类型">
<j-dict-select-tag @change="handleChangeTemplateType" :triggerChange="true" dictCode="msgType" v-decorator="['templateType', validatorRules.templateType ]" placeholder="请选择模板类型">
</j-dict-select-tag>
</a-form-item>
<a-form-item
v-show="!useEditor"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容">
<a-textarea placeholder="请输入模板内容" v-decorator="['templateContent', validatorRules.templateContent ]" :autosize="{ minRows: 8, maxRows: 8 }" />
</a-form-item>
<a-form-item
v-show="useEditor"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容">
<j-editor v-model="templateEditorContent"></j-editor>
</a-form-item>
<a-row :gutter="{ xs: 8, sm: 16, md: 24, lg: 32 }">
<a-col :span="12">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板CODE"
style="margin-right: -35px"
>
<a-input
:disabled="disable"
placeholder="请输入模板编码"
v-decorator="['templateCode', validatorRules.templateCode ]"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板类型">
<j-dict-select-tag @change="handleChangeTemplateType" :triggerChange="true" dictCode="msgType" v-decorator="['templateType', validatorRules.templateType ]" placeholder="请选择模板类型">
</j-dict-select-tag>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="24" >
<a-col :span="24" pull="2">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板标题"
style="margin-left: -15px">
<a-input
placeholder="请输入模板标题"
v-decorator="['templateName', validatorRules.templateName]"
style="width: 122%"
/>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="24">
<a-col :span="24" pull="4">
<a-form-item
v-show="!useEditor"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容"
style="margin-left: 4px;width: 126%">
<a-textarea placeholder="请输入模板内容" v-decorator="['templateContent', validatorRules.templateContent ]" :autosize="{ minRows: 8, maxRows: 8 }"/>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="24">
<a-col :span="24" pull="4">
<a-form-item
v-show="useEditor"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容"
style="margin-left: 4px;width: 126%">
<j-editor v-model="templateEditorContent"></j-editor>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-spin>
@ -111,7 +131,7 @@
edit(record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.useEditor = (record.templateType==2)
this.useEditor = (record.templateType==2 || record.templateType==4)
if(this.useEditor){
this.templateEditorContent=record.templateContent
}else{
@ -191,7 +211,7 @@
},
handleChangeTemplateType(value){
//如果是邮件类型那么则改变模板内容是富文本编辑器
this.useEditor = value==2
this.useEditor = (value==2 || value==4)
}
}

View File

@ -0,0 +1,388 @@
<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.tableName"></a-input>
</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="doCgformButton" type="primary" icon="highlight" style="margin-left:8px">自定义按钮</a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS增强</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter" style="margin-left:8px">SQL增强</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java增强</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>
已选择
<a style="font-weight: 600">{{ selectedRowKeys.length }}</a>
<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">
<template 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 @click="goPageOnline(record)">功能测试</a>
</a-menu-item>
<a-menu-item>
<a @click="handleOnlineUrlShow(record)">配置地址</a>
</a-menu-item>
<a-menu-item>
<a @click="handleRemoveRecord(record.id)">移除</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="dbsync" slot-scope="text">
<span v-if="text==='Y'" style="color:limegreen">已同步</span>
<span v-if="text==='N'" style="color:red">未同步</span>
</template>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<onl-cgform-head-modal ref="modalForm" @ok="modalFormOk" :action-button="false"></onl-cgform-head-modal>
<!-- 提示online报表链接 -->
<a-modal
:title="onlineUrlTitle"
:visible="onlineUrlVisible"
@cancel="handleOnlineUrlClose">
<template slot="footer">
<a-button @click="handleOnlineUrlClose">关闭</a-button>
<a-button type="primary" class="copy-this-text" :data-clipboard-text="onlineUrl" @click="onCopyUrl">复制</a-button>
</template>
<p>{{ onlineUrl }}</p>
</a-modal>
<enhance-js ref="ehjs"></enhance-js>
<enhance-sql ref="ehsql"></enhance-sql>
<enhance-java ref="ehjava"></enhance-java>
<trans-db2-online ref="transd2o" @ok="transOk"></trans-db2-online>
<onl-cgform-button-list ref="btnList"></onl-cgform-button-list>
</a-card>
</template>
<script>
import { deleteAction, postAction,getAction } from '@/api/manage'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { filterObj } from '@/utils/util';
export default {
name: 'OnlCgformHeadList',
mixins: [JeecgListMixin],
components: {
},
data() {
return {
description: 'Online表单视图',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '视图表名',
align: 'center',
dataIndex: 'tableName'
},
{
title: '视图表描述',
align: 'center',
dataIndex: 'tableTxt'
},
{
title: '原表版本',
align: 'center',
dataIndex: 'tableVersion'
},
{
title: '视图版本',
align: 'center',
dataIndex: 'copyVersion'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
url: {
list: '/online/cgform/head/list',
delete: '/online/cgform/head/delete',
deleteBatch: '/online/cgform/head/deleteBatch',
removeRecord: '/online/cgform/head/removeRecord',
},
tableTypeDictOptions: [],
sexDictOptions: [],
syncModalVisible: false,
syncFormId: '',
synMethod: 'normal',
syncLoading: false,
onlineUrlTitle: '',
onlineUrlVisible: false,
onlineUrl: '',
selectedRowKeys: [],
selectedRows: [],
physicId:""
}
},
watch: {
'$route'() {
this.loadData()
}
},
methods: {
getQueryParams() {
//获取查询条件
var param = Object.assign({}, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
param.copyType = 1;
param.physicId = this.physicId;
return filterObj(param);
},
loadData(arg) {
if(!this.$route.params.code){
return false
}
this.physicId = this.$route.params.code
if(!this.url.list){
this.$message.error("请设置url.list属性!")
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
this.loading = true;
getAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
if(res.code===510){
this.$message.warning(res.message)
}
this.loading = false;
})
},
goPageOnline(rd) {
if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
}
},
handleOnlineUrlClose() {
this.onlineUrlTitle = ''
this.onlineUrlVisible = false
},
handleOnlineUrlShow(record) {
if(record.isTree=='Y'){
this.onlineUrl = `/online/cgformTreeList/${record.id}`
}else{
this.onlineUrl = `/online/cgformList/${record.id}`
}
this.onlineUrlVisible = true
this.onlineUrlTitle = '菜单链接[' + record.tableTxt + ']'
},
handleRemoveRecord(id) {
let that = this
this.$confirm({
title: '确认要移除此记录?',
onOk() {
deleteAction(that.url.removeRecord, { id: id }).then((res) => {
if (res.success) {
that.$message.success('移除成功')
that.loadData()
} else {
that.$message.warning(res.message)
}
})
},
onCancel() {
}
})
},
doEnhanceJs() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.ehjs.show(this.selectedRowKeys[0])
},
doEnhanceSql() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.ehsql.show(this.selectedRowKeys[0])
},
doEnhanceJava() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.ehjava.show(this.selectedRowKeys[0])
},
doCgformButton() {
if (!this.selectedRowKeys || this.selectedRowKeys.length != 1) {
this.$message.warning('请先选中一条记录')
return
}
this.$refs.btnList.show(this.selectedRowKeys[0])
//this.$router.push({ path: '/online/cgformButton/' + this.selectedRowKeys[0] })
},
importOnlineForm() {
this.$refs.transd2o.show()
},
transOk() {
this.loadData()
},
onSelectChange(keys, rows) {
this.selectedRowKeys = keys
this.selectedRows = rows
},
onCopyUrl(){
var clipboard = new Clipboard('.copy-this-text')
clipboard.on('success', () => {
clipboard.destroy()
this.$message.success('复制成功')
this.handleOnlineUrlClose()
})
clipboard.on('error', () => {
this.$message.error('该浏览器不支持自动复制')
clipboard.destroy()
})
},
showMyCopyInfo(id){
console.log("查看复制表单的信息",id)
},
copyConfig(id){
postAction(`${this.url.copyOnline}?code=${id}`).then(res=>{
if(res.success){
this.$message.success("复制成功")
this.loadData()
}else{
this.$message.error("复制失败>>"+res.message)
}
})
}
}
}
</script>
<style lang="less">
.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
}
.valid-error-cust{
.ant-select-selection{
border:2px solid #f5222d;
}
}
</style>

View File

@ -95,12 +95,22 @@
</a-menu-item>
</template>
<a-menu-item>
<a @click="copyConfig(record.id)">复制视图</a>
</a-menu-item>
<a-menu-item v-if="record.hascopy==1">
<a @click="showMyCopyInfo(record.id)">配置视图</a>
</a-menu-item>
<a-menu-item>
<a @click="handleRemoveRecord(record.id)">移除</a>
</a-menu-item>
<a-menu-item>
<a @click="handleDelete(record.id)">删除</a>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
@ -167,6 +177,7 @@
import JDictSelectTag from '../../../../components/dict/JDictSelectTag.vue'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { filterObj } from '@/utils/util';
export default {
name: 'OnlCgformHeadList',
@ -231,7 +242,8 @@
delete: '/online/cgform/head/delete',
deleteBatch: '/online/cgform/head/deleteBatch',
doDbSynch: '/online/cgform/api/doDbSynch/',
removeRecord: '/online/cgform/head/removeRecord'
removeRecord: '/online/cgform/head/removeRecord',
copyOnline: '/online/cgform/head/copyOnline'
},
tableTypeDictOptions: [],
sexDictOptions: [],
@ -253,7 +265,6 @@
this.tableTypeDictOptions = res.result
}
})
this.loadData()
},
methods: {
doDbSynch(id) {
@ -266,6 +277,15 @@
}
})
},
getQueryParams() {
//获取查询条件
var param = Object.assign({}, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
param.copyType = 0;
return filterObj(param);
},
handleCancleDbSync() {
this.syncModalVisible = false
},
@ -281,9 +301,18 @@
this.$message.warning(res.message)
}
})
setTimeout(()=>{
if(this.syncLoading){
this.syncModalVisible = false
this.syncLoading = false
this.$message.success("网络延迟,已自动刷新!")
this.loadData()
}
},10000)
},
openSyncModal(id) {
this.syncModalVisible = true
this.syncLoading = false
this.syncFormId = id
},
goPageOnline(rd) {
@ -391,7 +420,21 @@
this.$message.error('该浏览器不支持自动复制')
clipboard.destroy()
})
},
showMyCopyInfo(id){
this.$router.push({ path: '/online/copyform/' + id })
},
copyConfig(id){
postAction(`${this.url.copyOnline}?code=${id}`).then(res=>{
if(res.success){
this.$message.success("复制成功")
this.loadData()
}else{
this.$message.error("复制失败>>"+res.message)
}
})
}
}
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<a-card :bordered="false" style="height: 100%">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-form layout="inline" @keyup.enter.native="searchByquery">
<a-row :gutter="24" v-if="queryInfo && queryInfo.length>0">
<template v-for="(item,index) in queryInfo">
<template v-if=" item.hidden==='1' ">
@ -63,6 +63,15 @@
</a-button>
</template>
<!-- 高级查询 -->
<j-super-query
ref="superQuery"
:fieldList="superQuery.fieldList"
:saveCode="$route.fullPath"
:loading="table.loading"
style="margin-left: 8px;"
@handleSuperQuery="handleSuperQuery"/>
<a-button
v-if="buttonSwitch.batch_delete"
@click="handleDelBatch"
@ -89,8 +98,9 @@
:dataSource="table.dataSource"
:pagination="table.pagination"
:loading="table.loading"
:rowSelection="{selectedRowKeys:table.selectedRowKeys, onChange: handleChangeInTableSelect}"
:rowSelection="rowSelectionConfig"
@change="handleTableChange"
:scroll="table.scroll"
style="min-height: 300px">
<template slot="dateSlot" slot-scope="text">
@ -102,19 +112,19 @@
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" height="25px" alt="图片不存在" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="uploadFile(text)">
@click="downloadRowFile(text)">
下载
</a-button>
</template>
@ -143,6 +153,19 @@
<a href="javascript:;" @click="handleDetail(record)">详情</a>
</a-menu-item>
<template v-if="hasBpmStatus">
<template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null">
<a-menu-item>
<a href="javascript:;" @click="startProcess(record)">提交流程</a>
</a-menu-item>
<a-menu-item v-if="buttonSwitch.delete">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</template>
<template v-else>
<a-menu-item @click="handlePreviewPic(record)">审批进度</a-menu-item>
</template>
</template>
<template v-else>
<a-menu-item v-if="buttonSwitch.delete">
@ -165,7 +188,7 @@
</span>
</a-table>
<OnlCgformAutoModal @success="handleFormSuccess" ref="modal" :code="code"></OnlCgformAutoModal>
<onl-cgform-auto-modal @success="handleFormSuccess" ref="modal" :code="code" @schema="handleGetSchema" />
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
@ -179,11 +202,13 @@
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { filterObj } from '@/utils/util';
import JImportModal from '@/components/jeecg/JImportModal'
import JSuperQuery from '@comp/jeecg/JSuperQuery'
export default {
name: 'OnlCgFormAutoList',
components: {
JImportModal
JSuperQuery,
JImportModal,
},
data() {
return {
@ -197,6 +222,7 @@
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess",
},
flowCodePre:"onl_",
isorter:{
@ -210,12 +236,12 @@
cgButtonLinkList:[],
cgButtonList:[],
queryInfo:[],
queryParam:{
},
// 查询参数,多个页面的查询参数用 code 作为键来区分
queryParamsMap: {},
toggleSearchStatus:false,
table: {
loading: true,
scroll:{x:false},
// 表头
columns: [],
//数据集
@ -225,17 +251,20 @@
selectionRows: [],
// 分页参数
pagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
}
},
metaPagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
actionColumn:{
title: '操作',
dataIndex: 'action',
@ -256,6 +285,16 @@
export:true
},
hasBpmStatus:false,
checkboxFlag:false,
// 高级查询
superQuery: {
// 字段列表
fieldList: [],
// 查询参数
params: '',
// 查询条件拼接方式 'and' or 'or'
matchType: 'and'
}
}
},
created() {
@ -265,11 +304,32 @@
this.cgButtonJsHandler('mounted')
},
watch: {
'$route'() {
'$route.path'(newVal,oldVal) {
console.log('$route.path ',oldVal)
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initAutoList()
}
},
computed:{
rowSelectionConfig:function() {
if(!this.checkboxFlag){
return null
}
return {
fixed:true,
selectedRowKeys:this.table.selectedRowKeys,
onChange: this.handleChangeInTableSelect
}
},
queryParam: {
get() {
return this.queryParamsMap[this.code]
},
set(newVal) {
this.$set(this.queryParamsMap, this.code, newVal)
}
}
},
methods: {
hasBpmStatusFilter(){
var columnObjs = this.table.columns;
@ -283,6 +343,30 @@
this.hasBpmStatus = false;
}
},
startProcess: function(record){
var that = this;
this.$confirm({
title:"提示",
content:"确认提交流程吗?",
onOk: function(){
var param = {
flowCode:that.flowCodePre+that.currentTableName,
id:record.id,
formUrl:"modules/bpm/task/form/OnlineFormDetail",
formUrlMobile:"modules/bpm/task/form/OnlineFormDetail"
}
postAction(that.url.startProcess,param).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
},
initQueryInfo(){
getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{
console.log("--onlineList-获取查询条件配置",res);
@ -297,11 +381,32 @@
if(!this.$route.params.code){
return false
}
// 清空高级查询条件
this.superQuery.params = ''
if (this.$refs.superQuery) {
this.$refs.superQuery.handleReset()
}
this.table.loading = true
this.code = this.$route.params.code
if (!this.queryParam) {
this.queryParam = {}
}
getAction(`${this.url.getColumns}${this.code}`).then((res)=>{
console.log("--onlineList-加载动态列>>",res);
if(res.success){
if(res.result.checkboxFlag == 'Y'){
this.checkboxFlag = true
}else{
this.checkboxFlag = false
}
if(res.result.paginationFlag=='Y'){
this.table.pagination = {...this.metaPagination}
}else{
this.table.pagination = false
}
this.dictOptions = res.result.dictOptions
this.formTemplate = res.result.formTemplate
this.description = res.result.description
@ -313,11 +418,24 @@
for(let a=0;a<currColumns.length;a++){
if(currColumns[a].customRender){
let dictCode = currColumns[a].customRender;
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text);
let replaceFlag = '_replace_text_';
if(dictCode.startsWith(replaceFlag)){
let textFieldName = dictCode.replace(replaceFlag,'')
currColumns[a].customRender=(text,record)=>{
return record[textFieldName]
}
}else{
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text);
}
}
}
}
if(res.result.scrollFlag==1){
this.table.scroll = { x :'115%' }
}else{
this.table.scroll = { x :false }
}
currColumns.push(this.actionColumn);
this.table.columns = [...currColumns]
this.hasBpmStatusFilter();
@ -329,26 +447,52 @@
})
},
loadData(arg){
if(arg==1){
this.table.pagination.current=1
if(this.table.pagination){
if(arg==1){
this.table.pagination.current=1
}
this.table.loading = true
let params = this.getQueryParams();//查询条件
console.log("--onlineList-查询条件-->",params)
getAction(`${this.url.getData}${this.code}`,params).then((res)=>{
console.log("--onlineList-列表数据",res)
if(res.success){
let result = res.result;
if(Number(result.total)>0){
this.table.pagination.total = Number(result.total)
this.table.dataSource = result.records
}else{
this.table.pagination.total=0;
this.table.dataSource=[]
//this.$message.warning("查无数据")
}
}else{
this.$message.warning(res.message)
}
}).finally(() => {
this.table.loading = false
})
}else{
this.loadDataNoPage()
}
let params = this.getQueryParams();//查询条件
console.log("--onlineList-查询条件-->",params)
getAction(`${this.url.getData}${this.code}`,params).then((res)=>{
},
loadDataNoPage(){
this.table.loading = true
let param = this.getQueryParams()//查询条件
param['pageSize'] = -521;
getAction(`${this.url.getData}${this.code}`,filterObj(param)).then((res)=>{
console.log("--onlineList-列表数据",res)
if(res.success){
let result = res.result;
if(Number(result.total)>0){
this.table.pagination.total = Number(result.total)
this.table.dataSource = result.records
}else{
this.table.pagination.total=0;
this.table.dataSource=[]
//this.$message.warning("查无数据")
}
}else{
this.$message.warning(res.message)
}
}).finally(() => {
this.table.loading = false
})
},
@ -356,11 +500,14 @@
let param = Object.assign({}, this.queryParam,this.isorter);
param.pageNo = this.table.pagination.current;
param.pageSize = this.table.pagination.pageSize;
param.superQueryMatchType = this.superQuery.matchType
param.superQueryParams = encodeURIComponent(this.superQuery.params)
return filterObj(param);
},
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
this.selectedRowKeys = selectedRowKeys
},
handleTableChange(pagination, filters, sorter){
//TODO 筛选
@ -443,6 +590,49 @@
handleFormSuccess(){
this.loadData()
},
// 查询完 schema 后,生成高级查询的字段列表
handleGetSchema(schema) {
if (schema && schema.properties) {
let setField = (array, field) => {
let type = field.type || 'string'
type = (type === 'inputNumber' ? 'number' : type)
array.push({
type: type,
value: field.key,
text: field.title,
// 额外字典参数
dictCode: field.dictCode,
dictTable: field.dictTable,
dictText: field.dictText,
options: field.enum || field.options
})
}
let fieldList = []
for (let key in schema.properties) {
if (!schema.properties.hasOwnProperty(key)) {
continue
}
let field = schema.properties[key]
// tab = 子表
if (field.view === 'tab') {
let subTable = {
type: 'sub-table',
value: field.key,
text: field.describe,
children: []
}
for (let column of field.columns) {
setField(subTable.children, column)
}
fieldList.push(subTable)
} else {
field.key = key
setField(fieldList, field)
}
}
this.superQuery.fieldList = fieldList
}
},
onClearSelected(){
this.table.selectedRowKeys = []
this.table.selectionRows = []
@ -453,7 +643,7 @@
}
return window._CONFIG['imgDomainURL']+"/"+text
},
uploadFile(text){
downloadRowFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
@ -461,7 +651,7 @@
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['imgDomainURL']+"/"+text);//TODO 下载的方法
window.open(window._CONFIG['downloadUrl']+"/"+text);//TODO 下载的方法
},
handleDelBatch(){
if(this.table.selectedRowKeys.length<=0){
@ -595,7 +785,18 @@
})
}
}
},
// 高级查询
handleSuperQuery(params, matchType) {
if (!params || params.length === 0) {
this.superQuery.params = ''
} else {
this.superQuery.params = JSON.stringify(params)
}
this.superQuery.matchType = matchType
this.loadData()
},
}
}

View File

@ -66,28 +66,30 @@
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" height="25px" alt="图片不存在" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="uploadFile(text)">
@click="downloadRowFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<template v-if="buttonSwitch.update">
<template v-if="showOptButton('update',record)">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
</template>
<a-dropdown>
<a class="ant-dropdown-link">
更多 <a-icon type="down" />
@ -96,7 +98,16 @@
<a-menu-item >
<a @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item v-if="buttonSwitch.delete">
<a-menu-item v-if="showSubmitFlowButton(record)">
<a @click="startProcess(record)">提交流程</a>
</a-menu-item>
<template v-if="showViewFlowButton(record)">
<a-menu-item @click="handlePreviewPic(record)">审批进度</a-menu-item>
</template>
<a-menu-item v-if="showOptButton('delete',record)">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a>删除</a>
</a-popconfirm>
@ -120,6 +131,7 @@
<onl-cgform-auto-modal @success="handleFormSuccess" ref="modal" :code="code"></onl-cgform-auto-modal>
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
</div>
</a-card>
</template>
@ -171,7 +183,7 @@
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess",
startProcess: "/process/extActProcess/startMutilProcess"
},
isorter:{
column: 'create_time',
@ -209,7 +221,9 @@
import:true,
export:true
},
expandedRowKeys:[]
expandedRowKeys:[],
hasBpmStatus:false,
flowCodePre:"onl_",
}
},
@ -299,18 +313,27 @@
this.initButtonSwitch(res.result.hideColumns)
let currColumns = res.result.columns
let textFieldIndex = -1
let hasBpmStatus = false
for(let a=0;a<currColumns.length;a++){
currColumns[a].align = 'left'
//找到显示列
if(this.textField==currColumns[a].dataIndex){
textFieldIndex = a
}
//数据字典翻译
if(currColumns[a].customRender){
let dictCode = currColumns[a].customRender;
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text);
}
}
//判断是否有bpm_status
if(currColumns[a].dataIndex.toLowerCase()=='bpm_status'){
hasBpmStatus = true;
}
}
this.hasBpmStatus = hasBpmStatus;
if(textFieldIndex!=-1){
let textFieldColumn = currColumns.splice(textFieldIndex,1)
currColumns.unshift(textFieldColumn[0])
@ -461,7 +484,7 @@
}
return window._CONFIG['imgDomainURL']+"/"+text
},
uploadFile(text){
downloadRowFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
@ -469,7 +492,7 @@
if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(","))
}
window.open(window._CONFIG['domianURL'] + "/sys/common/download/"+text);
window.open(window._CONFIG['downloadUrl']+"/"+text);
},
/*-------数据格式化-end----------*/
@ -615,7 +638,59 @@
},
/*-------JS增强-end----------*/
showOptButton(opt,record){
//只有当按钮属性为false,或是按钮属性为true但是流程已提交时才隐藏
if(!this.buttonSwitch[opt]){
return false
}else{
if(this.hasBpmStatus){
if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){
return false
}
}
}
return true
},
showSubmitFlowButton(record){
if(this.hasBpmStatus){
if(record.bpm_status ==null || record.bpm_status =='' || record.bpm_status == '1'){
return true
}
}
return false
},
showViewFlowButton(record){
if(this.hasBpmStatus){
if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){
return true
}
}
return false
},
startProcess: function(record){
var that = this;
this.$confirm({
title:"提示",
content:"确认提交流程吗?",
onOk: function(){
var param = {
flowCode:that.flowCodePre+that.currentTableName,
id:record.id,
formUrl:"modules/bpm/task/form/OnlineFormDetail",
formUrlMobile:"modules/bpm/task/form/OnlineFormDetail"
}
postAction(that.url.startProcess,param).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
},
}
}
</script>

View File

@ -0,0 +1,256 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="6">
<a-form-item label="报表编码">
<a-input placeholder="请输入报表编码" v-model="queryParam.code"></a-input>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="报表名字">
<a-input placeholder="请输入报表名字" v-model="queryParam.name"></a-input>
</a-form-item>
</a-col>
<a-col :span="8">
<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>
已选择
<a style="font-weight: 600">
{{ selectedRowKeys.length }}
</a>
<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 @click="popReportURL(record.id)">
配置地址
</a-menu-item>
<a-menu-item>
<a @click="goPageOnline(record.id)">功能测试</a>
</a-menu-item>
<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 -->
<!-- 表单区域 -->
<onlCgreportHead-modal ref="modalForm" @ok="modalFormOk"></onlCgreportHead-modal>
<!-- 提示online报表链接 -->
<a-modal
title="报表访问链接"
:visible="visible"
@cancel="handleCancel">
<template slot="footer">
<a-button @click="handleCancel">关闭</a-button>
<a-button type="primary" class="copy-this-text" :data-clipboard-text="reportUrlText" @click="onCopyUrl">复制</a-button>
</template>
<p>{{ reportUrlText }}</p>
</a-modal>
</a-card>
</template>
<script>
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { getAction } from '@/api/manage'
export default {
name: 'OnlCgreportHeadList',
mixins: [JeecgListMixin],
components: {
Clipboard
},
data() {
return {
description: '在线报表配置管理页面',
visible:false,
reportUrlText:'',
// 表头
columns: [
{
title: '报表名称',
align: 'center',
dataIndex: 'name'
},
{
title: '编码',
align: 'center',
dataIndex: 'code'
},
{
title: '查询SQL',
align: 'center',
dataIndex: 'cgrSql'
},
{
title: '数据源',
align: 'center',
dataIndex: 'dbSource'
},
{
title: '创建时间',
align: 'center',
dataIndex: 'createTime'
},
{
title: '描述',
align: 'center',
dataIndex: 'content'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
url: {
list: '/online/cgreport/head/list',
delete: '/online/cgreport/head/delete',
deleteBatch: '/online/cgreport/head/deleteBatch',
getParamsInfo:'/online/cgreport/api/getParamsInfo/'
}
}
},
methods: {
initReportUrlText(id){
getAction(this.url.getParamsInfo+id).then((res) => {
let textUrl = ""
if (res.success) {
if(res.result && res.result.length>0){
for(let i of res.result){
textUrl+=i.paramName+"=${"+i.paramName+"}&"
}
}
} else {
this.$message.warning(res.message)
}
if(textUrl.length>0){
textUrl = textUrl.substring(0,textUrl.length-1)
this.reportUrlText = `/online/cgreport/${id}?${textUrl}`
}else{
this.reportUrlText = `/online/cgreport/${id}`
}
})
},
goPageOnline(id){
this.$router.push({path: '/online/cgreport/'+id})
},
popReportURL(id){
this.visible = true;
this.initReportUrlText(id)
},
handleCancel(){
this.visible = false
this.reportUrlText = '';
},
onCopyUrl(){
var clipboard = new Clipboard('.copy-this-text')
clipboard.on('success', () => {
clipboard.destroy()
this.$message.success('复制成功')
this.handleCancel()
})
clipboard.on('error', () => {
this.$message.error('该浏览器不支持自动复制')
clipboard.destroy()
})
}
}
}
</script>
<style lang="less" 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

@ -0,0 +1,293 @@
<template>
<a-card :bordered="false" style="height: 100%">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24" v-if="queryInfo && queryInfo.length>0">
<template v-for="(item,index) in queryInfo">
<template v-if=" item.hidden==='1' ">
<a-col v-if="item.view.indexOf('Date')>=0" :md="12" :sm="16" :key=" 'query'+index " v-show="toggleSearchStatus">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index " v-show="toggleSearchStatus">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
</template>
<template v-else>
<a-col v-if="item.view.indexOf('Date')>=0" :md="12" :sm="16" :key=" 'query'+index ">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
<a-col v-else :md="6" :sm="8" :key=" 'query'+index ">
<onl-cgreport-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></onl-cgreport-query-form-item>
</a-col>
</template>
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchByQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div class="table-operator" style="margin-bottom: 10px">
<a-button type="primary" icon="plus" @click="exportExcel">导出</a-button>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="table.columns"
:dataSource="table.dataSource"
:pagination="table.pagination"
:loading="table.loading"
:scroll="table.scroll"
:rowSelection="{fixed:true, selectedRowKeys: table.selectedRowKeys, onChange: handleChangeInTableSelect}"
@change="handleChangeInTable"
style="min-height: 300px"
>
</a-table>
</a-card>
</template>
<script>
import { getAction,downFile } from '@/api/manage'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import {filterObj} from '@/utils/util';
export default {
name: 'OnlCgreportAutoList',
components: {
},
data() {
return {
// 查询参数
queryInfo: [],
// 查询参数,多个页面的查询参数用 code 作为键来区分
queryParamsMap: {},
selfParam:{
},
sorter: {
column: '',
order: 'desc',
},
dictOptions: {},
toggleSearchStatus: false, // 高级搜索 展开/关闭
reportCode: '',
description: '在线报表功能测试页面',
url: {
getColumns: '/online/cgreport/api/getColumns/',
getData: '/online/cgreport/api/getData/',
getQueryInfo: '/online/cgreport/api/getQueryInfo/',
getParamsInfo:'/online/cgreport/api/getParamsInfo/'
},
table: {
loading: true,
// 表头
columns: [],
//数据集
dataSource: [],
// 选择器
selectedRowKeys: [],
selectionRows: [],
scroll: { x: false },
// 分页参数
pagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
}
},
cgreportHeadName:""
}
},
mounted() {
this.initParamsInfo()
this.initQueryInfo();
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initParamsInfo()
this.initQueryInfo();
}
},
computed: {
queryParam: {
get() {
return this.queryParamsMap[this.reportCode]
},
set(newVal) {
this.$set(this.queryParamsMap, this.reportCode, newVal)
}
}
},
methods: {
initParamsInfo(){
if(!this.$route.params.code){
return false
}
//获取报表ID
this.reportCode = this.$route.params.code;
if (!this.queryParam) {
this.queryParam = {}
}
this.selfParam={}
getAction(`${this.url.getParamsInfo}${this.$route.params.code}`).then((res) => {
if (res.success) {
if(res.result && res.result.length>0){
for(let i of res.result){
this.selfParam['self_'+i.paramName]=(!this.$route.query[i.paramName])?"":this.$route.query[i.paramName]
}
}
} else {
this.$message.warning(res.message)
}
this.loadData()
})
},
initQueryInfo() {
if(!this.$route.params.code){
return false
}
getAction(`${this.url.getQueryInfo}${this.$route.params.code}`).then((res) => {
console.log("获取查询条件", res);
if (res.success) {
this.queryInfo = res.result
} else {
this.$message.warning(res.message)
}
})
},
loadData(arg) {
if(!this.$route.params.code){
return false
}
if (arg == 1) {
this.table.pagination.current = 1
}
let params = this.getQueryParams();//查询条件
console.log(params)
console.log(' 动态报表 reportCode ' + this.reportCode);
this.table.loading = true
Promise.all([
getAction(`${this.url.getColumns}${this.reportCode}`),
getAction(`${this.url.getData}${this.reportCode}`, params)
]).then(results => {
let [{result: {columns,cgreportHeadName,dictOptions}}, {result: data}] = results
let columnWidth = 230
this.dictOptions = dictOptions
for(let a=0;a<columns.length;a++){
if(columns[a].customRender){
let field_name = columns[a].customRender;
columns[a].customRender=(text)=>{
if(!text){
return ''
}else{
return filterMultiDictText(this.dictOptions[field_name], text+"");
}
}
}
columns.width = columnWidth
}
this.table.scroll.x = columns.length * columnWidth
this.table.columns = [...columns]
this.cgreportHeadName = cgreportHeadName
if (data) {
this.table.pagination.total = Number(data.total)
this.table.dataSource = data.records
} else {
this.table.pagination.total = 0
this.table.dataSource = []
}
}).catch((e) => {
console.error(e)
this.$message.error('查询失败')
}).then(() => {
this.table.loading = false
})
},
getQueryParams() {
let param = Object.assign({}, this.queryParam, this.sorter,this.selfParam);
param.pageNo = this.table.pagination.current;
param.pageSize = this.table.pagination.pageSize;
return filterObj(param);
},
searchByQuery() {
this.loadData(1);
},
searchReset() {
this.queryParam = {}
this.loadData(1);
},
handleToggleSearch() {
this.toggleSearchStatus = !this.toggleSearchStatus;
},
exportExcel() {
let fileName = this.cgreportHeadName
downFile(`/online/cgreport/api/exportXls/${this.reportCode}`,this.queryParam).then((data)=>{
if (!data) {
this.$message.warning("文件下载失败")
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName+'.xls')
}else{
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName+'.xls')
document.body.appendChild(link)
link.click()
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
})
},
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
},
handleChangeInTable(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
if (Object.keys(sorter).length > 0) {
this.sorter.column = sorter.field
this.sorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
}
this.table.pagination = pagination
this.loadData()
}
}
}
</script>
<style scoped>
.div {
display: flex;
align-items: center;
height: 500px
}
</style>

View File

@ -0,0 +1,164 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="文件名称">
<a-input placeholder="请输入文件名称" v-model="queryParam.fileName"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="文件地址">
<a-input placeholder="请输入文件地址" v-model="queryParam.url"></a-input>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<!-- <a-button type="primary" icon="download" @click="handleExportXls('文件列表')">导出</a-button>-->
<a-upload
name="file"
:multiple="false"
:action="uploadAction"
:headers="tokenHeader"
:showUploadList="false"
:beforeUpload="beforeUpload"
@change="handleChange">
<a-button>
<a-icon type="upload"/>
文件上传
</a-button>
</a-upload>
</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> 已选择 <a
style="font-weight: 600">{{
selectedRowKeys.length }}</a>项
<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="ossDelete(record.id)">删除</a>
</span>
</a-table>
</div>
<!-- table区域-end -->
</a-card>
</template>
<script>
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
export default {
name: "OSSFileList",
mixins: [JeecgListMixin],
data() {
return {
description: '文件列表',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
customRender: function (t, r, index) {
return parseInt(index) + 1;
}
},
{
title: '文件名称',
align: "center",
dataIndex: 'fileName'
},
{
title: '文件地址',
align: "center",
dataIndex: 'url'
},
{
title: '操作',
dataIndex: 'action',
align: "center",
scopedSlots: {customRender: 'action'},
}
],
url: {
upload: "/oss/file/upload",
list: "/oss/file/list",
delete: "/oss/file/delete"
}
}
},
computed: {
uploadAction() {
return window._CONFIG['domianURL'] + this.url.upload;
}
},
methods: {
beforeUpload(file) {
var fileType = file.type;
if (fileType === 'image') {
if (fileType.indexOf('image') < 0) {
this.$message.warning('请上传图片');
return false;
}
} else if (fileType === 'file') {
if (fileType.indexOf('image') >= 0) {
this.$message.warning('请上传文件');
return false;
}
}
return true
},
handleChange(info) {
if (info.file.status === 'done') {
if (info.file.response.success) {
this.loadData()
this.$message.success(`${info.file.name} 上传成功!`);
} else {
this.$message.error(`${info.file.name} 上传失败.`);
}
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 上传失败.`);
}
},
ossDelete(id) {
var that = this;
that.$confirm({
title: "确认删除",
content: "是否删除选中文件?",
onOk: function () {
that.handleDelete(id)
}
});
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -0,0 +1,31 @@
<template>
<a-row type="flex" :gutter="16">
<a-col :md="5" :sm="24">
<address-list-left v-model="currentOrgCode"/>
</a-col>
<a-col :md="24-5" :sm="24">
<address-list-right v-model="currentOrgCode"/>
</a-col>
</a-row>
</template>
<script>
import AddressListLeft from './modules/AddressListLeft'
import AddressListRight from './modules/AddressListRight'
export default {
name: 'AddressList',
components: { AddressListLeft, AddressListRight },
data() {
return {
description: '通讯录页面',
currentOrgCode: ''
}
},
methods: {}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

View File

@ -2,7 +2,7 @@
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="表名">

View File

@ -37,7 +37,7 @@
:selectedKeys="selectedKeys"
:checkedKeys="checkedKeys"
:treeData="departTree"
:checkStrictly="true"
:checkStrictly="checkStrictly"
:expandedKeys="iExpandedKeys"
:autoExpandParent="autoExpandParent"
@expand="onExpand"/>
@ -53,6 +53,23 @@
</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-card :bordered="false">
@ -79,6 +96,28 @@
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"
@ -186,6 +225,10 @@
selectedKeys: [],
autoIncr: 1,
currSelected: {},
allTreeKeys:[],
checkStrictly: true,
form: this.$form.createForm(this),
labelCol: {
xs: {span: 24},
@ -202,6 +245,7 @@
validatorRules: {
departName: {rules: [{required: true, message: '请输入机构/部门名称!'}]},
orgCode: {rules: [{required: true, message: '请输入机构编码!'}]},
orgCategory: {rules: [{required: true, message: '请输入机构类型!'}]},
mobile: {rules: [{validator: this.validateMobile}]}
},
url: {
@ -211,6 +255,7 @@
exportXlsUrl: "sys/sysDepart/exportXls",
importExcelUrl: "sys/sysDepart/importExcel",
},
orgCategoryDisabled:false,
}
},
computed: {
@ -233,7 +278,8 @@
that.treeData.push(temp)
that.departTree.push(temp)
that.setThisExpandedKeys(temp)
console.log(temp.id)
that.getAllKeys(temp);
// console.log(temp.id)
}
this.loading = false
}
@ -338,7 +384,14 @@
onCheck(checkedKeys, info) {
console.log('onCheck', checkedKeys, info)
this.hiding = false
this.checkedKeys = checkedKeys.checked
//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)
@ -355,8 +408,13 @@
},
// 触发onSelect事件时,为部门树右侧的form表单赋值
setValuesToForm(record) {
if(record.orgCategory == '1'){
this.orgCategoryDisabled = true;
}else{
this.orgCategoryDisabled = false;
}
this.form.getFieldDecorator('fax', {initialValue: ''})
this.form.setFieldsValue(pick(record, 'departName', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
this.form.setFieldsValue(pick(record, 'departName','orgCategory', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'))
},
getCurrSelectedTitle() {
return !this.currSelected.title ? '' : this.currSelected.title
@ -459,6 +517,39 @@
}
}
},
// <!---- author:os_chengtgen -- date:20190827 -- for:切换父子勾选模式 =======------>
expandAll () {
this.iExpandedKeys = this.allTreeKeys
},
closeAll () {
this.iExpandedKeys = []
},
checkALL () {
this.checkStriccheckStrictlytly = false
this.checkedKeys = this.allTreeKeys
},
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
@ -516,4 +607,16 @@
.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

@ -9,8 +9,8 @@
<template>
<!--组织机构-->
<a-directory-tree
selectable
<a-tree
showLine
:selectedKeys="selectedKeys"
:checkStrictly="true"
@select="onSelect"

View File

@ -0,0 +1,125 @@
<template>
<a-modal
:width="modalWidth"
:style="modalStyle"
:visible="visible"
:maskClosable="false"
@cancel="handleCancel">
<template slot="footer">
<a-button @click="handleCancel">关闭</a-button>
</template>
<a-table
ref="table"
rowKey="id"
size="middle"
:columns="columns"
:loading="loading"
:dataSource="dataSource"
:pagination="false">
<span slot="action" slot-scope="text, record">
<a @click="handleBack(record.id)"><a-icon type="redo"/>字典取回</a>
<a-divider type="vertical"/>
<a @click="handleDelete(record.id)"><a-icon type="scissor"/>彻底删除</a>
</span>
</a-table>
</a-modal>
</template>
<script>
import { getAction,deleteAction,putAction } from '@/api/manage'
export default {
name: "DictDeleteList",
data () {
return {
modalWidth: '90%',
modalStyle: { 'top': '20px'},
title: '操作',
visible: false,
loading: false,
dataSource:[],
columns:[
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 120,
align: "center",
customRender: function (t, r, index) {
return parseInt(index) + 1;
}
},
{
title: '字典名称',
align: "left",
dataIndex: 'dictName'
},
{
title: '字典编号',
align: "left",
dataIndex: 'dictCode'
},
{
title: '描述',
align: "left",
dataIndex: 'description'
},
{
title: '操作',
dataIndex: 'action',
align: "center",
scopedSlots: {customRender: 'action'}
}
]
}
},
methods: {
handleCancel(){
this.visible = false
},
show(){
this.visible = true
this.loadData();
},
loadData(){
this.loading = true
getAction("/sys/dict/deleteList").then(res=>{
this.loading = false
if(res.success){
this.dataSource = res.result
}else{
this.$message.warning(res.message)
}
})
},
handleBack(id){
putAction("/sys/dict/back/"+id).then(res=>{
if(res.success){
this.$message.success(res.message)
this.loadData();
}else{
this.$message.warning(res.message)
}
})
},
handleDelete(id){
deleteAction("/sys/dict/deletePhysic/"+id).then(res=>{
if(res.success){
this.$message.success(res.message)
this.loadData();
}else{
this.$message.warning(res.message)
}
})
}
}
}
</script>
<style scoped>
</style>

View File

@ -16,7 +16,7 @@
}">
<div class="table-page-search-wrapper">
<a-form layout="inline" :form="form">
<a-form layout="inline" :form="form" @keyup.enter.native="searchQuery">
<a-row :gutter="10">
<a-col :md="8" :sm="12">
<a-form-item label="名称">

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