Compare commits

..

31 Commits

Author SHA1 Message Date
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
285 changed files with 14624 additions and 28691 deletions

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.2发布日期20191122
[![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.2-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配置表单、编码表单。同时实现了流程与表单的分离设计松耦合、并支持任务节点灵活配置既保证了公司流程的保密性又减少了开发人员的工作量。
@ -53,7 +56,7 @@ Jeecg-Boot快速开发平台可以应用在任何J2EE项目的开发中
交流互动
-----------------------------------
- QQ交流群 ①284271917、②769925425
- QQ交流群 ②769925425、①284271917
- 反馈问题: [反馈问题请按格式发Issues](https://github.com/zhangdaiscott/jeecg-boot/issues/new)

View File

@ -1,7 +1,7 @@
Ant Design Jeecg Vue
====
当前最新版本: 2.1.0发布日期20190826
当前最新版本: 2.1.2发布日期20191122
Overview
----

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.2",
"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": "2.1.2",
"@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",
@ -51,6 +51,7 @@
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.0.0-beta.11",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"node-sass": "^4.11.0",

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
}

View File

@ -31,6 +31,11 @@
type: Array,
default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.']
},
// 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}]
aliases:{
type: Array,
default: () => []
},
height: {
type: Number,
default: 254
@ -55,11 +60,22 @@
})
// bar 使用不了 - 和 / 所以替换下
return dv.rows.map(row => {
row.x = row.x.replace(/[-/]/g, '_')
let rows = dv.rows.map(row => {
if (typeof row.x === 'string') {
row.x = row.x.replace(/[-/]/g, '_')
}
return row
})
// 替换别名
rows.forEach(row => {
for (let item of this.aliases) {
if (item.field === row.type) {
row.type = item.alias
break
}
}
})
return rows
}
}
}

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

@ -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(){

View File

@ -1,25 +1,36 @@
<!-- JEditableTable -->
<!-- @version 1.4.4 -->
<!-- @version 1.5.0 -->
<!-- @author sjlei -->
<template>
<a-spin :spinning="loading">
<!-- 操作按钮 -->
<div v-if="actionButton" class="action-button">
<a-button type="primary" icon="plus" @click="handleClickAdd">新增</a-button>
<span class="gap"></span>
<template v-if="selectedRowIds.length>0">
<a-popconfirm
:title="`确定要删除这 ${selectedRowIds.length} 项吗?`"
@confirm="handleConfirmDelete">
<a-button type="primary" icon="minus">删除</a-button>
</a-popconfirm>
<template v-if="showClearSelectButton">
<a-row type="flex">
<a-col>
<slot name="buttonBefore" :target="getVM()"/>
</a-col>
<a-col>
<!-- 操作按钮 -->
<div v-if="actionButton" class="action-button">
<a-button type="primary" icon="plus" @click="handleClickAdd">新增</a-button>
<span class="gap"></span>
<a-button icon="delete" @click="handleClickClearSelect">清空选择</a-button>
</template>
</template>
</div>
<template v-if="selectedRowIds.length>0">
<a-popconfirm
:title="`确定要删除这 ${selectedRowIds.length} 项吗?`"
@confirm="handleConfirmDelete">
<a-button type="primary" icon="minus">删除</a-button>
<span class="gap"></span>
</a-popconfirm>
<template v-if="showClearSelectButton">
<a-button icon="delete" @click="handleClickClearSelection">清空选择</a-button>
<span class="gap"></span>
</template>
</template>
</div>
</a-col>
<a-col>
<slot name="buttonAfter" :target="getVM()"/>
</a-col>
</a-row>
<div :id="`${caseId}inputTable`" class="input-table">
<!-- 渲染表头 -->
@ -65,7 +76,8 @@
<div v-if="rows.length===0" class="tr-nodata">
<span>暂无数据</span>
</div>
<draggable v-model="rows" handle=".td-ds-icons" @end="handleDragMoveEnd">
<!-- v-model="rows"-->
<draggable :value="rows" handle=".td-ds-icons" @end="handleDragMoveEnd">
<!-- 动态生成tr -->
<template v-for="(row,rowIndex) in rows">
@ -128,6 +140,7 @@
v-bind="buildProps(row,col)"
:data-input-number="col.type === formTypes.inputNumber"
:placeholder="replaceProps(col, col.placeholder)"
@blur="(e)=>{handleBlurCommono(e.target,rowIndex,row,col)}"
@input="(e)=>{handleInputCommono(e.target,rowIndex,row,col)}"
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}"/>
@ -168,6 +181,7 @@
:options="col.options"
:getPopupContainer="getParentContainer"
:placeholder="replaceProps(col, col.placeholder)"
:filterOption="(i,o)=>handleSelectFilterOption(i,o,col)"
@change="(v)=>handleChangeSelectCommon(v,id,row,col)"
@search="(v)=>handleSearchSelect(v,id,row,col)"
@blur="(v)=>handleBlurSearch(v,id,row,col)"
@ -262,6 +276,230 @@
</div>
<!-- update-begin-author:taoyan date:0827 forpopup -->
<template v-else-if="col.type === formTypes.popup">
<a-tooltip
:key="i"
:id="id"
placement="top"
:title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true">
<span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<j-popup
:id="id"
:key="i"
v-bind="buildProps(row,col)"
:placeholder="replaceProps(col, col.placeholder)"
style="width: 100%;"
:value="getPopupValue(id)"
:field="col.key"
:org-fields="col.orgFieldse"
:dest-fields="col.destFields"
:code="col.popupCode"
@input="(value,others)=>popupCallback(value,others,id,row,col,rowIndex)"/>
</span>
</a-tooltip>
</template>
<!-- update-end-author:taoyan date:0827 forpopup -->
<!-- update-beign-author:taoyan date:0827 for文件/图片逻辑新增 -->
<div v-else-if="col.type === formTypes.file" :key="i">
<template v-if="uploadValues[id] != null" v-for="(file,fileKey) of [(uploadValues[id]||{})]">
<a-input
:key="fileKey"
:readOnly="true"
:value="file.name"
>
<template slot="addonBefore" style="width: 30px">
<a-tooltip v-if="file.status==='uploading'" :title="`上传中(${Math.floor(file.percent)}%)`">
<a-icon type="loading"/>
</a-tooltip>
<a-tooltip v-else-if="file.status==='done'" title="上传完成">
<a-icon type="check-circle" style="color:#00DB00;"/>
</a-tooltip>
<a-tooltip v-else title="上传失败">
<a-icon type="exclamation-circle" style="color:red;"/>
</a-tooltip>
</template>
<template slot="addonAfter" style="width: 30px">
<a-tooltip title="删除并重新上传">
<a-icon
v-if="file.status!=='uploading'"
type="close-circle"
style="cursor: pointer;"
@click="()=>handleClickDelFile(id)"/>
</a-tooltip>
</template>
</a-input>
</template>
<div :hidden="uploadValues[id] != null">
<a-upload
name="file"
:data="{'isup':1}"
:multiple="false"
:action="getUploadAction(col.action)"
:headers="uploadGetHeaders(row,col)"
:showUploadList="false"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
>
<a-button icon="upload">{{ col.placeholder }}</a-button>
</a-upload>
</div>
</div>
<div v-else-if="col.type === formTypes.image" :key="i">
<template v-if="uploadValues[id] != null" v-for="(file,fileKey) of [(uploadValues[id]||{})]">
<div :key="fileKey" style="position: relative;">
<img :src="getCellImageView(id)" style="height:32px;max-width:100px !important;" alt="无图片"/>
<template slot="addonBefore" style="width: 30px">
<a-tooltip v-if="file.status==='uploading'" :title="`上传中(${Math.floor(file.percent)}%)`">
<a-icon type="loading"/>
</a-tooltip>
<a-tooltip v-else-if="file.status==='done'" title="上传完成">
<a-icon type="check-circle" style="color:#00DB00;"/>
</a-tooltip>
<a-tooltip v-else title="上传失败">
<a-icon type="exclamation-circle" style="color:red;"/>
</a-tooltip>
</template>
<template style="width: 30px">
<a-tooltip title="删除并重新上传" style="margin-left:5px">
<a-icon
v-if="file.status!=='uploading'"
type="close-circle"
style="cursor: pointer;"
@click="()=>handleClickDelFile(id)"/>
</a-tooltip>
</template>
</div>
</template>
<div :hidden="uploadValues[id] != null">
<a-upload
name="file"
:data="{'isup':1}"
:multiple="false"
:action="getUploadAction(col.action)"
:headers="uploadGetHeaders(row,col)"
:showUploadList="false"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
>
<a-button icon="upload">请上传图片</a-button>
</a-upload>
</div>
</div>
<!-- update-end-author:taoyan date:0827 for图片逻辑新增 -->
<!-- radio-begin -->
<template v-else-if="col.type === formTypes.radio">
<a-tooltip
:key="i"
:id="id"
placement="top"
:title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true">
<span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<a-radio-group
:id="id"
:key="i"
v-bind="buildProps(row,col)"
:value="radioValues[id]"
@change="(e)=>handleRadioChange(e.target.value,id,row,col)">
<a-radio v-for="(item, key) in col.options" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group>
</span>
</a-tooltip>
</template>
<!-- radio-end -->
<!-- select多选 -begin -->
<template v-else-if="col.type === formTypes.list_multi">
<a-tooltip
:key="i"
:id="id"
placement="top"
:title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true">
<span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<a-select
:id="id"
:key="i"
mode="multiple"
:maxTagCount="1"
v-bind="buildProps(row,col)"
style="width: 100%;"
:value="multiSelectValues[id]"
:options="col.options"
:getPopupContainer="getParentContainer"
:placeholder="replaceProps(col, col.placeholder)"
@change="(v)=>handleMultiSelectChange(v,id,row,col)"
allowClear>
</a-select>
</span>
</a-tooltip>
</template>
<!-- select多选 -end -->
<!-- select搜索 -begin -->
<template v-else-if="col.type === formTypes.sel_search">
<a-tooltip
:key="i"
:id="id"
placement="top"
:title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true">
<span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<a-select
:id="id"
:key="i"
showSearch
optionFilterProp="children"
:filterOption="filterOption"
v-bind="buildProps(row,col)"
style="width: 100%;"
:value="searchSelectValues[id]"
:options="col.options"
:getPopupContainer="getParentContainer"
:placeholder="replaceProps(col, col.placeholder)"
@change="(v)=>handleSearchSelectChange(v,id,row,col)"
allowClear>
</a-select>
</span>
</a-tooltip>
</template>
<!-- select搜索 -end -->
<div v-else-if="col.type === formTypes.slot" :key="i">
<slot
:name="(col.slot || col.slotName) || col.key"
@ -270,12 +508,14 @@
:column="col"
:rowId="removeCaseId(row.id)"
:getValue="()=>_getValueForSlot(row.id)"
:caseId="caseId"
:allValues="_getAllValuesForSlot()"
:target="getVM()"
/>
</div>
<!-- else (normal) -->
<span v-else :key="i">{{ inputValues[rowIndex][col.key] }}</span>
<span v-else :key="i" v-bind="buildProps(row,col)">{{ inputValues[rowIndex][col.key] }}</span>
</template>
</div>
</div>
@ -299,6 +539,7 @@
import JDate from '@/components/jeecg/JDate'
import { initDictOptions } from '@/components/dict/JDictSelectUtil'
// 行高,需要在实例加载完成前用到
let rowHeight = 61
@ -397,6 +638,13 @@
jdateValues: {},
// file 信息
uploadValues: {},
//popup信息
popupValues:{},
radioValues:{},
metaCheckboxValues:{},
multiSelectValues:{},
searchSelectValues:{},
// 绑定左侧选择框已选择的id
selectedRowIds: [],
// 存储被删除行的id
@ -410,17 +658,6 @@
created() {
// 当前显示的tr
this.visibleTrEls = []
// 用来存储input表单的值
// 数组里的每项都是一个对象对象里每个key都是input的rowKey值就是input的值其中有个id的字段来区分
// 示例:
// [{
// id: "_jet-4sp0iu-15541771111770"
// dbDefaultVal: "aaa",
// dbFieldName: "bbb",
// dbFieldTxt: "ccc",
// dbLength: 32
// }]
this.inputValues = []
this.disabledRowIds = (this.disabledRowIds || [])
},
// 计算属性
@ -480,6 +717,20 @@
},
// 侦听器
watch: {
rows:{
immediate:true,
handler(val,old) {
// val.forEach(item => {
// for (let inputValue of this.inputValues) {
// if (inputValue.id === item.id) {
// item['dbFieldName'] = inputValue['dbFieldName']
// break
// }
// }
// })
// console.log('watch.rows:', cloneObject({ val, old }))
}
},
dataSource: {
immediate: true,
handler: function (newValue) {
@ -489,6 +740,12 @@
let checkboxValues = {}
let selectValues = {}
let jdateValues = {}
let uploadValues = {}
let popupValues={}
let radioValues = {}
let multiSelectValues = {}
let searchSelectValues = {}
// 禁用行的id
let disabledRowIds = (this.disabledRowIds || [])
newValue.forEach((data, newValueIndex) => {
@ -531,6 +788,27 @@
value[column.key] = sourceValue
}
} else if (column.type === FormTypes.popup) {
popupValues[inputId] = sourceValue
} else if (column.type === FormTypes.radio) {
radioValues[inputId] = sourceValue
} else if (column.type === FormTypes.sel_search) {
searchSelectValues[inputId] = sourceValue
} else if (column.type === FormTypes.list_multi) {
if(sourceValue.length>0){
multiSelectValues[inputId] = sourceValue.split(",")
}else{
multiSelectValues[inputId] = []
}
} else if (column.type === FormTypes.file || column.type === FormTypes.image) {
if(sourceValue){
let fileName = sourceValue.substring(sourceValue.lastIndexOf("/")+1)
uploadValues[inputId] = {
name: fileName,
status: 'done',
path:sourceValue
}
}
} else {
value[column.key] = sourceValue
}
@ -539,15 +817,18 @@
for (let columnKey in this.disabledRows) {
// 判断是否有该属性
if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) {
// row[columnKey] =
if (disabled !== true) {
disabled = this.disabledRows[columnKey] === data[columnKey]
let temp = this.disabledRows[columnKey]
// 禁用规则可以是一个数组
if (temp instanceof Array) {
disabled = temp.includes(data[columnKey])
} else {
disabled = (temp === data[columnKey])
}
if (disabled) {
disabledRowIds.push(row.id)
}
}
}
}
})
@ -559,6 +840,11 @@
this.selectValues = selectValues
this.jdateValues = jdateValues
this.rows = rows
this.uploadValues = uploadValues
this.popupValues = popupValues
this.radioValues = radioValues
this.multiSelectValues = multiSelectValues
this.searchSelectValues = searchSelectValues
// 更新form表单的值
this.$nextTick(() => {
@ -571,15 +857,15 @@
immediate: true,
handler(columns) {
columns.forEach(column => {
if (column.type === FormTypes.select) {
if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) {
// 兼容 旧版本 options
if (column.options instanceof Array) {
column.options = column.options.map(item => {
if (item) {
return {
...item,
text: item.text || item.title,
title: item.text || item.title,
value: item.value
title: item.text || item.title
}
}
return {}
@ -594,7 +880,7 @@
},
// 当selectRowIds改变时触发事件
selectedRowIds(newValue) {
this.$emit('selectRowChange', cloneObject(newValue))
this.$emit('selectRowChange', cloneObject(newValue).map(i => this.removeCaseId(i)))
}
},
mounted() {
@ -632,16 +918,31 @@
/** 初始化列表 */
initialize() {
// inputValues用来存储input表单的值
// 数组里的每项都是一个对象对象里每个key都是input的rowKey值就是input的值其中有个id的字段来区分
// 示例:
// [{
// id: "_jet-4sp0iu-15541771111770"
// dbDefaultVal: "aaa",
// dbFieldName: "bbb",
// dbFieldTxt: "ccc",
// dbLength: 32
// }]
this.inputValues = []
this.visibleTrEls = []
this.rows = []
this.deleteIds = []
this.inputValues = []
this.selectValues = {}
this.checkboxValues = {}
this.jdateValues = {}
this.selectedRowIds = []
this.tooltips = {}
this.notPassedIds = []
this.uploadValues=[]
this.popupValues=[]
this.radioValues=[]
this.multiSelectValues = []
this.searchSelectValues = []
this.scrollTop = 0
this.$nextTick(() => {
this.el.tbody.scrollTop = 0
@ -796,16 +1097,17 @@
}
this.rows = rows
let rowValue = this.getValuesSync({
validate: false,
rowIds: [this.removeCaseId(row.id)]
}).values[0]
this.$nextTick(() => {
this.updateFormValues()
})
// 触发add事件
this.$emit('added', {
row: (() => {
let r = Object.assign({}, row)
r.id = this.removeCaseId(r.id)
return r
})(),
row: rowValue,
target: this
})
// 设置滚动条位置
@ -921,12 +1223,34 @@
} else if (column.type === FormTypes.upload) {
value[column.key] = cloneObject(this.uploadValues[inputId] || null)
} else if (column.type === FormTypes.image || column.type === FormTypes.file) {
let currUploadObj = cloneObject(this.uploadValues[inputId] || null)
if(currUploadObj){
value[column.key] = currUploadObj['path'] || null
}
} else if (column.type === FormTypes.popup) {
if(!value[column.key]){
value[column.key] = this.popupValues[inputId] || null
}
} else if (column.type === FormTypes.radio) {
value[column.key] = this.radioValues[inputId]
}else if (column.type === FormTypes.sel_search) {
value[column.key] = this.searchSelectValues[inputId]
}else if (column.type === FormTypes.list_multi) {
if(!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length==0){
value[column.key] = ''
}else{
value[column.key] = this.multiSelectValues[inputId].join(",")
}
}
// 检查表单验证
if (validate === true) {
let results = this.validateOneInput(value[column.key], value, column, notPassedIds, false)
let results = this.validateOneInput(value[column.key], value, column, notPassedIds, false, 'getValues')
tooltips[inputId] = results[0]
if (tooltips[inputId].visible) {
if (tooltips[inputId].passed === false) {
error++
// if (error++ === 0) {
// let element = document.getElementById(inputId)
@ -946,8 +1270,10 @@
}
this.tooltips = tooltips
this.notPassedIds = notPassedIds
if (validate === true) {
this.tooltips = tooltips
this.notPassedIds = notPassedIds
}
return { error, values }
},
@ -994,6 +1320,19 @@
_getValueForSlot(rowId) {
return this.getValuesSync({ rowIds: [rowId] }).values[0]
},
_getAllValuesForSlot() {
return cloneObject({
inputValues: this.inputValues,
selectValues: this.selectValues,
checkboxValues: this.checkboxValues,
jdateValues: this.jdateValues,
uploadValues: this.uploadValues,
popupValues: this.popupValues,
radioValues: this.radioValues,
multiSelectValues: this.multiSelectValues,
searchSelectValues: this.searchSelectValues,
})
},
/** 设置某行某列的值 */
setValues(values) {
@ -1052,42 +1391,78 @@
// },
/** 验证单个表单 */
validateOneInput(value, row, column, notPassedIds, update = false) {
validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') {
let tooltips = Object.assign({}, this.tooltips)
// let notPassedIds = cloneObject(this.notPassedIds)
let inputId = column.key + row.id
let [passed, message] = this.validateValue(column.validateRules, value)
tooltips[inputId] = tooltips[inputId] ? tooltips[inputId] : {}
tooltips[inputId].visible = !passed
let index = notPassedIds.indexOf(inputId)
let borderColor = null, boxShadow = null
if (!passed) {
tooltips[inputId].title = this.replaceProps(column, message)
borderColor = 'red'
boxShadow = `0 0 0 2px rgba(255, 0, 0, 0.2)`
if (index === -1) notPassedIds.push(inputId)
} else {
if (index !== -1) notPassedIds.splice(index, 1)
let [passed, message] = this.validateValue(column.validateRules, value)
const nextThen = res => {
let [passed, message] = res
if (passed == null) {
// debugger
}
if (passed == null && tooltips[inputId].visible != null) {
return
}
passed = passed == null ? true : passed
tooltips[inputId].visible = !passed
tooltips[inputId].passed = passed
let index = notPassedIds.indexOf(inputId)
let borderColor = null, boxShadow = null
if (!passed) {
tooltips[inputId].title = this.replaceProps(column, message)
borderColor = 'red'
boxShadow = `0 0 0 2px rgba(255, 0, 0, 0.2)`
if (index === -1) notPassedIds.push(inputId)
} else {
if (index !== -1) notPassedIds.splice(index, 1)
}
let element = document.getElementById(inputId)
if (element != null) {
// select 在 .ant-select-selection 上设置 border-color
if (column.type === FormTypes.select) {
element = element.getElementsByClassName('ant-select-selection')[0]
}
// jdate 在 input 上设置 border-color
if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
element = element.getElementsByTagName('input')[0]
}
element.style.borderColor = borderColor
element.style.boxShadow = boxShadow
}
// 是否更新到data
if (update) {
this.tooltips = tooltips
this.notPassedIds = notPassedIds
}
}
let element = document.getElementById(inputId)
if (element != null) {
// select 在 .ant-select-selection 上设置 border-color
if (column.type === FormTypes.select) {
element = element.getElementsByClassName('ant-select-selection')[0]
}
// jdate 在 input 上设置 border-color
if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
element = element.getElementsByTagName('input')[0]
}
element.style.borderColor = borderColor
element.style.boxShadow = boxShadow
}
// 是否更新到data
if (update) {
this.tooltips = tooltips
this.notPassedIds = notPassedIds
if (typeof passed === 'function') {
let executed = false
passed(validType, value, row, column, (flag, msg) => {
if (executed) return
executed = true
if (typeof msg === 'string') {
message = msg
}
if (flag == null) {
nextThen([null, message])
}else if (typeof flag === 'boolean' && flag) {
nextThen([true, message])
} else {
nextThen([false, message])
}
}, this)
} else {
nextThen([passed, message])
}
return [tooltips[inputId], notPassedIds]
},
/** 通过规则验证值是否正确 */
@ -1130,6 +1505,8 @@
}
}
if (!flag) passed = new RegExp(rule.pattern).test(value)
} else if (typeof rule.handler === 'function') {
return [rule.handler, rule.message]
}
// 如果没有通过验证,则跳出循环。如果通过了验证,则继续验证下一条规则
if (!passed) {
@ -1221,12 +1598,22 @@
handleConfirmDelete() {
this.removeSelectedRows()
},
handleClickClearSelect() {
handleClickClearSelection() {
this.clearSelection()
},
clearSelection() {
this.selectedRowIds = []
},
/** 用于搜索下拉框中的内容 */
handleSelectFilterOption(input, option, column) {
if (column.allowSearch === true) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
return true
},
/** select 搜索时的事件用于动态添加options */
handleSearchSelect(value, id, row, col) {
if (col.allowInput === true) {
if (col.allowSearch !== true && col.allowInput === true) {
// 是否找到了对应的项,找不到则添加这一项
let flag = false
for (let option of col.options) {
@ -1267,20 +1654,14 @@
/** 拖动结束交换inputValue中的值 */
handleDragMoveEnd(event) {
let { oldIndex, newIndex } = event
let { oldIndex, newIndex, item: { dataset: { idx: dataIdx } } } = event
let values = this.inputValues
// 存储旧数据,并删除旧项目
let temp = values[oldIndex]
values.splice(oldIndex, 1)
// 向新项目里添加旧数据
values.splice(newIndex, 0, temp)
// 由于动态显示隐藏行导致index有误差需要算出真实的index
let diff = Number.parseInt(dataIdx) - oldIndex
oldIndex += diff
newIndex += diff
values.forEach((item, index) => {
item[this.dragSortKey] = (index + 1)
})
this.forceUpdateFormValues()
this.rowResort(oldIndex, newIndex)
// 触发已拖动事件
this.$emit('dragged', {
@ -1290,13 +1671,32 @@
})
},
/** 行重新排序 */
rowResort(oldIndex, newIndex) {
const sort = (array) => {
// 存储旧数据,并删除旧项目
let temp = array[oldIndex]
array.splice(oldIndex, 1)
// 向新项目里添加旧数据
array.splice(newIndex, 0, temp)
}
sort(this.rows)
sort(this.inputValues)
// 重置排序字段
this.inputValues.forEach((val, idx) => val[this.dragSortKey] = (idx + 1))
this.forceUpdateFormValues()
},
/* --- common function begin --- */
/** 鼠标移入 */
handleMouseoverCommono(row, column) {
let inputId = column.key + row.id
if (this.notPassedIds.indexOf(inputId) !== -1) {
this.showOrHideTooltip(inputId, true)
this.showOrHideTooltip(inputId, true, true)
}
},
/** 鼠标移出 */
@ -1325,13 +1725,18 @@
// 存储输入的值
this.inputValues[index][column.key] = value
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true)
this.validateOneInput(value, row, column, this.notPassedIds, true, 'input')
// 触发valueChange 事件
if (change) {
this.elemValueChange(type, row, column, value)
}
},
handleBlurCommono(target, index, row, column) {
let { value } = target
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'blur')
},
handleChangeCheckboxCommon(event, row, column) {
let { id, checked } = event.target
this.checkboxValues = this.bindValuesChange(checked, id, 'checkboxValues')
@ -1342,14 +1747,14 @@
handleChangeSelectCommon(value, id, row, column) {
this.selectValues = this.bindValuesChange(value, id, 'selectValues')
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true)
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange(FormTypes.select, row, column, value)
},
handleChangeJDateCommon(value, id, row, column, showTime) {
this.jdateValues = this.bindValuesChange(value, id, 'jdateValues')
this.validateOneInput(value, row, column, this.notPassedIds, true)
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
if (showTime) {
@ -1370,6 +1775,9 @@
if (column.responseName && file.response) {
value['responseName'] = file.response[column.responseName]
}
if(file.status =='done'){
value['path'] = file.response[column.responseName]
}
this.uploadValues = this.bindValuesChange(value, id, 'uploadValues')
},
/** 记录用到数据绑定的组件的值 */
@ -1380,11 +1788,16 @@
},
/** 显示或隐藏tooltip */
showOrHideTooltip(inputId, show) {
let tooltips = Object.assign({}, this.tooltips)
tooltips[inputId] = tooltips[inputId] ? tooltips[inputId] : {}
tooltips[inputId].visible = show
this.tooltips = tooltips
showOrHideTooltip(inputId, show, force = false) {
if (!this.tooltips[inputId] && !force) {
return
}
let tooltip = this.tooltips[inputId] || {}
if (tooltip.visible !== show) {
tooltip.visible = show
this.$set(this.tooltips, inputId, tooltip)
}
},
/** value 触发valueChange事件 */
@ -1502,12 +1915,14 @@
},
/** view辅助方法构建 td style */
buildTdStyle(col) {
const isEmptyWidth = (column) => (column.type === FormTypes.hidden || column.width === '0px' || column.width === '0' || column.width === 0)
let style = {}
// 计算宽度
if (col.width) {
style['width'] = col.width
} else if (this.columns) {
style['width'] = `${(100 - 4 * 2) / this.columns.length}%`
style['width'] = `${(100 - 4 * 2) / (this.columns.filter(column => !isEmptyWidth(column))).length}%`
} else {
style['width'] = '120px'
}
@ -1519,6 +1934,10 @@
style['padding-left'] = '0'
style['padding-right'] = '0'
}
if (isEmptyWidth(col)) {
style['padding-left'] = '0'
style['padding-right'] = '0'
}
return style
},
/** view辅助方法构造props */
@ -1533,12 +1952,12 @@
}
}
// 判断select是否允许输入
if (col.type === FormTypes.select && col.allowInput === true) {
if (col.type === FormTypes.select && (col.allowInput === true || col.allowSearch === true)) {
props['showSearch'] = true
}
// 判断是否是禁用的列
props['disabled'] = !!col['disabled']
props['disabled'] = (typeof col['disabled'] === 'boolean' ? col['disabled'] : props['disabled'])
// 判断是否为禁用的行
if (props['disabled'] !== true) {
@ -1559,7 +1978,69 @@
headers['X-Access-Token'] = this.accessToken
}
return headers
}
},
/** 上传请求地址 */
getUploadAction(value){
if(!value){
return window._CONFIG['domianURL']+"/sys/common/upload"
}else{
return value
}
},
/** 预览图片地址 */
getCellImageView(id){
let currUploadObj = this.uploadValues[id] || null
if(currUploadObj && currUploadObj['path']){
return window._CONFIG['domianURL']+"/sys/common/view/"+currUploadObj['path']
}else{
return ''
}
},
/** popup回调 */
popupCallback(value,others,id,row,column,index){
// 存储输入的值
this.popupValues[id]=value
if(others){
Object.keys(others).map((key)=>{
this.inputValues[index][key] = others[key]
})
}
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange("input", row, column, value)
// 更新form表单的值
this.$nextTick(() => {
this.forceUpdateFormValues()
})
},
/** popup输入框回显 */
getPopupValue(id){
return this.popupValues[id]
},
handleRadioChange(value, id, row, column) {
this.radioValues = this.bindValuesChange(value, id, 'radioValues')
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange(FormTypes.radio, row, column, value)
},
handleMultiSelectChange(value, id, row, column) {
this.multiSelectValues = this.bindValuesChange(value, id, 'multiSelectValues')
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange(FormTypes.list_multi, row, column, value)
},
handleSearchSelectChange(value, id, row, column) {
this.searchSelectValues = this.bindValuesChange(value, id, 'searchSelectValues')
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
this.elemValueChange(FormTypes.sel_search, row, column, value)
},
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
}
}

View File

@ -61,6 +61,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 +88,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,404 @@
<template>
<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">
<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-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-idx="fIndex">{{ f.text }}</a-select-option>
</a-select>
</a-col>
<a-col :span="4">
<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-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'"
/>
<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>
</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 {
prompt: {
visible: false,
value: ''
},
visible: false,
queryParamsModel: [{}],
treeIcon: <a-icon type="file-text"/>,
treeData: [],
// 保存查询条件的前缀名
saveCodeBefore: 'JSuperQuerySaved_',
selectValue: 'and',
}
},
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
})
}
}
}
},
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{
handleOk() {
console.log('---高级查询参数--->', this.queryParamsModel)
if (!this.isNullArray(this.queryParamsModel)) {
let event = {
matchType: this.selectValue,
params: this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
}
this.$emit(this.callback, event.params, event.matchType)
} else {
this.$emit(this.callback)
}
},
handleCancel(){
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(option, item) {
let index = option.data.attrs['data-idx']
this.queryParamsModel.splice(index,1);
this.$message.warning("请关闭后重新打开")
let { type, dictCode, dictTable, customReturnField } = this.fieldList[index]
item['type'] = type
item['dictCode'] = dictCode
item['dictTable'] = dictTable
item['customReturnField'] = customReturnField
this.$set(item, 'val', '')
},
handleSelected(option,item){
item['type'] = option.data.attrs['data-type']
},
handleReset(){
this.queryParamsModel=[{}]
handleReset() {
this.queryParamsModel = [{}]
this.$emit(this.callback)
},
isNullArray(){
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('保存成功')
}
},
handleTreeSelect(idx, event) {
if (event.selectedNodes[0]) {
this.queryParamsModel = utils.cloneObject(event.selectedNodes[0].data.props.records)
}
},
handleTreeRightClick(args) {
this.$confirm({
content: '是否删除当前查询?',
onOk: () => {
let { node: { eventKey } } = args
this.treeData.splice(Number.parseInt(eventKey.substring(2)), 1)
this.saveToLocalStore()
this.$message.success('删除成功')
},
})
},
// 将查询保存到 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 || !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)
}
}
return array
}
}
}
</script>
<style >
<style lang="scss" scoped>
.j-super-query-modal {
/deep/ {
}
.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

@ -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,6 +58,21 @@
type: String,
default: '',
required: false
},
condition:{
type:String,
default:'',
required:false
},
// 是否支持多选
multiple: {
type: Boolean,
default: false,
},
loadTriggleChange:{
type: Boolean,
default: false,
required:false
}
},
data () {
@ -81,9 +97,11 @@
}
},
created(){
this.initDictInfo()
this.loadRoot()
this.loadItemByCode()
this.validateProp().then(()=>{
this.initDictInfo()
this.loadRoot()
this.loadItemByCode()
})
},
methods: {
loadItemByCode(){
@ -92,15 +110,23 @@
}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){
@ -184,8 +212,11 @@
if(!value){
this.$emit('change', '');
this.treeValue = ''
}else{
this.$emit('change', value.value);
} 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>
@ -63,6 +64,13 @@
type:String,
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,

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,206 @@
<template>
<a-modal
centered
:title="name + '选择'"
:width="900"
: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 :placeholder="'请输入' + (queryParamText||name)" v-model="queryParam[valueKey]"></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>
<a-table
size="small"
bordered
rowKey="id"
:columns="columns"
: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 rowKey="id" size="small" 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 { JeecgListMixin } from '@/mixins/JeecgListMixin'
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
},
name: {
type: String,
default: ''
},
listUrl: {
type: String,
required: true,
default: ''
},
displayKey: {
type: String,
default: null
},
propColumns: {
type: Array,
default: () => []
},
// 查询条件文字
queryParamText: {
type: String,
default: null
},
},
data() {
return {
// 表头
columns: this.propColumns,
// 已选择列表
selectedTable: {
pagination: false,
scroll: { y: 240 },
columns: [
this.propColumns[0],
{ title: '操作', dataIndex: 'action', align: 'center', width: 60, scopedSlots: { customRender: 'action' }, }
],
dataSource: [],
},
url: { list: this.listUrl }
}
},
watch: {
value: {
immediate: true,
handler(val) {
this.valueWatchHandler(val)
}
},
dataSource: {
deep: true,
handler(val) {
let options = val.map(data => ({ label: data[this.displayKey || this.valueKey], value: data[this.valueKey] }))
this.$emit('ok', options)
this.valueWatchHandler(this.value)
}
},
selectionRows: {
immediate: true,
deep: true,
handler(val) {
this.selectedTable.dataSource = val
},
},
},
methods: {
/** 关闭弹窗 */
close() {
this.$emit('update:visible', false)
},
valueWatchHandler(val) {
let dataSource = []
let selectedRowKeys = []
val.forEach(item => {
this.dataSource.forEach(data => {
if (data[this.valueKey] === item) {
dataSource.push(data)
selectedRowKeys.push(data.id)
}
})
})
this.selectedTable.dataSource = dataSource
this.selectedRowKeys = selectedRowKeys
},
/** 完成选择 */
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.id), 1)
this.selectedTable.dataSource.splice(index, 1)
},
customRowFn(record) {
if (!this.multiple) {
return {
on: {
click: () => {
this.selectedRowKeys = [record.id]
this.selectedTable.dataSource = [record]
}
}
}
}
return {}
},
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -0,0 +1,26 @@
# JSelectBizComponent
Jeecg 选择组件的公共可复用组件
## 引用方式
```js
import JSelectBizComponent from '@/src/components/jeecgbiz/JSelectBizComponent'
export default {
components: { JSelectBizComponent }
}
```
## 参数
### 配置参数
- `name`:`String` 显示名字,例如选择部门就填写'部门'
- `listUrl`:`String` 数据请求地址,必须是封装了分页的地址
- `displayKey`:`String` 显示在标签上的字段 key
- `returnKeys`:`Array` v-model 绑定的 keys是个数组默认使用第二项当配置了 `returnId=true` 就返回第一项
- `returnId`:`Boolean` 返回ID设为true后将返回配置的 `returnKeys` 中的第一项
- `selectButtonText`:`String` 选择按钮的文字
- `queryParamText`:`String` 查询条件显示文字
- `columns`:`Array` 列配置项与a-table的列配置项相同会将第一项配置成已选择的列表

View File

@ -0,0 +1,167 @@
<template>
<a-row class="j-select-biz-component-box" type="flex" :gutter="8">
<a-col class="left" :class="{'full': !buttons}">
<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)"
/>
</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"
:name="name" :listUrl="listUrl" :returnKeys="returnKeys" :displayKey="displayKey"
:propColumns="columns" :queryParamText="queryParamText" :multiple="multiple"
:visible.sync="visible"
:valueKey="valueKey"
@ok="selectOptions=$event"
/>
</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
},
/* 可复用属性 */
// 被选择的名字,例如选择部门就填写'部门'
name: {
type: String,
default: ''
},
// list 接口地址
listUrl: {
type: String,
required: true,
default: ''
},
// 显示的 Key
displayKey: {
type: String,
default: null
},
// 返回的 key
returnKeys: {
type: Array,
default: () => ['id', 'id']
},
// 选择按钮文字
selectButtonText: {
type: String,
default: '选择'
},
// 查询条件文字
queryParamText: {
type: String,
default: null
},
// columns
columns: {
type: Array,
default: () => []
}
},
data() {
return {
selectValue: [],
selectOptions: [],
visible: false
}
},
computed: {
valueKey() {
return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
}
},
watch: {
value: {
immediate: true,
handler(val) {
if (val) {
this.selectValue = val.split(',')
} else {
this.selectValue = []
}
}
},
selectValue: {
deep: true,
handler(val) {
const data = val.join(',')
this.$emit('input', data)
this.$emit('change', data)
}
}
},
methods: {}
}
</script>
<style lang="scss">
.j-select-biz-component-box {
.ant-select-search__field {
display: none !important;
}
}
</style>
<style lang="scss" scoped>
.j-select-biz-component-box {
$width: 82px;
.left {
width: calc(100% - #{$width} - 8px);
}
.right {
width: #{$width};
}
.full {
width: 100%;
}
}
</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,49 @@
<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-biz-component
:value="value"
<!-- 选择多个用户支持排序 -->
<j-select-multi-user-modal ref="selectModal" @selectFinished="selectOK"/>
</div>
name="用户"
displayKey="realname"
:listUrl="url.list"
:columns="columns"
queryParamText="账号"
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: 100, dataIndex: 'realname' },
{ title: '账号', align: 'center', width: 100, dataIndex: 'username' },
{ title: '电话', align: 'center', width: 100, dataIndex: 'phone' },
{ title: '出生日期', align: 'center', width: 100, dataIndex: 'birthday' }
]
}
},
computed: {
nameList: function () {
var names = [];
for (var a = 0; a < this.selectList.length; a++) {
names.push(this.selectList[a].name);
watch: {
$attrs: {
deep: true,
immediate: true,
handler(val) {
if (!val.returnKeys) {
val.returnKeys = ['id', 'username']
}
}
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;
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,36 @@
<template>
<j-select-biz-component 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',
queryParamText: '职务编码',
columns: [
{ title: '职务名称', dataIndex: 'name', align: 'center', width: 100 },
{ title: '职务编码', dataIndex: 'code', align: 'center', width: 100 },
{ title: '职级', dataIndex: 'rank_dictText', align: 'center', width: 100 }
]
}
}
},
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: [
{
@ -83,7 +84,7 @@
title: '性别',
align: 'center',
dataIndex: 'sex',
customRender: function(text) {
customRender: function (text) {
if (text === 1) {
return '男'
} else if (text === 2) {
@ -106,10 +107,9 @@
],
scrollTrigger: {},
dataSource: [],
selectedKeys: [],
userNameArr: [],
departName: '',
userRolesMap: {},
selectedRowKeys: [],
selectUserRows: [],
selectUserIds: [],
title: '根据部门选择用户',
ipagination: {
current: 1,
@ -126,53 +126,74 @@
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)
}
},
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 +212,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 +235,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 +271,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 +286,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,8 +237,20 @@
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>

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

@ -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();
@ -195,26 +200,38 @@
},
websocketonopen: function () {
console.log("WebSocket连接成功");
//心跳检测重置
this.heartCheck.reset().start();
},
websocketonerror: function (e) {
console.log("WebSocket连接发生错误");
this.reconnect();
},
websocketonmessage: function (e) {
console.log("-----接收消息-------",e.data);
//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();
},
websocketsend(text) { // 数据发送
try {
this.websock.send(text);
} catch (err) {
console.log("send failed (" + err.code + ")");
}
},
websocketclose: function (e) {
console.log("connection closed (" + e.code + ")");
this.reconnect();
},
openNotification (data) {
@ -239,6 +256,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

@ -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

@ -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"
import '@jeecg/antd-online/dist/OnlineForm.css'
import {
ACCESS_TOKEN,

View File

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

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

@ -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,25 @@ 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)
})
}

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>
@ -165,10 +175,12 @@
<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 +203,7 @@
JeecgDemoModal,
JSuperQuery,
JeecgDemoTabsModal,
JInput
},
data() {
return {
@ -278,6 +291,15 @@
}
},
methods: {
getQueryParams(){
console.log(this.queryParam.birthdayRange)
var param = Object.assign({}, this.queryParam,this.isorter);
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 +317,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

@ -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

@ -62,6 +62,39 @@
{
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
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') {
let { values } = target.getValuesSync({ validate: false })
if (value === 'abc') {
callback(false, '${title}不能是abc') // false = 未验证
return
}
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

@ -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">

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>
@ -168,6 +178,8 @@
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { filterObj } from '@/utils/util';
export default {
name: 'OnlCgformHeadList',
mixins: [JeecgListMixin],
@ -231,7 +243,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 +266,6 @@
this.tableTypeDictOptions = res.result
}
})
this.loadData()
},
methods: {
doDbSynch(id) {
@ -266,6 +278,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 +302,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 +421,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

@ -89,8 +89,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 +103,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 +144,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,10 +179,11 @@
</span>
</a-table>
<OnlCgformAutoModal @success="handleFormSuccess" ref="modal" :code="code"></OnlCgformAutoModal>
<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>
@ -183,7 +198,7 @@
export default {
name: 'OnlCgFormAutoList',
components: {
JImportModal
JImportModal,
},
data() {
return {
@ -197,6 +212,7 @@
optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess",
},
flowCodePre:"onl_",
isorter:{
@ -216,6 +232,7 @@
toggleSearchStatus:false,
table: {
loading: true,
scroll:{x:false},
// 表头
columns: [],
//数据集
@ -225,17 +242,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 +276,7 @@
export:true
},
hasBpmStatus:false,
checkboxFlag:false
}
},
created() {
@ -270,6 +291,18 @@
this.initAutoList()
}
},
computed:{
rowSelectionConfig:function() {
if(!this.checkboxFlag){
return null
}
return {
fixed:true,
selectedRowKeys:this.table.selectedRowKeys,
onChange: this.handleChangeInTableSelect
}
}
},
methods: {
hasBpmStatusFilter(){
var columnObjs = this.table.columns;
@ -283,6 +316,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);
@ -302,6 +359,18 @@
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 +382,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,22 +411,44 @@
})
},
loadData(arg){
if(arg==1){
this.table.pagination.current=1
if(this.table.pagination){
if(arg==1){
this.table.pagination.current=1
}
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)
}
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(){
let param = Object.assign({}, this.queryParam,this.isorter);
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)
@ -361,6 +465,7 @@
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
this.selectedRowKeys = selectedRowKeys
},
handleTableChange(pagination, filters, sorter){
//TODO 筛选
@ -453,7 +558,7 @@
}
return window._CONFIG['imgDomainURL']+"/"+text
},
uploadFile(text){
downloadRowFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
@ -461,7 +566,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){

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,8 @@
<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>
<process-inst-pic-modal ref="processInstPicModal"></process-inst-pic-modal>
</div>
</a-card>
</template>
@ -134,7 +147,7 @@
export default {
name: 'OnlCgformTreeList',
components: {
JImportModal
JImportModal,
},
data() {
return {
@ -171,7 +184,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 +222,9 @@
import:true,
export:true
},
expandedRowKeys:[]
expandedRowKeys:[],
hasBpmStatus:false,
flowCodePre:"onl_",
}
},
@ -299,18 +314,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 +485,7 @@
}
return window._CONFIG['imgDomainURL']+"/"+text
},
uploadFile(text){
downloadRowFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
@ -469,7 +493,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,6 +639,65 @@
},
/*-------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);
}
});
}
});
},
handlePreviewPic: function(record){
var flowCode = this.flowCodePre+this.currentTableName;
var dataId = record.id;
this.$refs.processInstPicModal.preview(flowCode,dataId);
this.$refs.processInstPicModal.title="流程图";
}
}
}

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="名称">

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="12">
<a-col :md="7" :sm="8">
<a-form-item label="字典名称" :labelCol="{span: 6}" :wrapperCol="{span: 14, offset: 1}">
@ -30,6 +30,8 @@
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-button type="primary" icon="hdd" @click="openDeleteList">回收站</a-button>
</div>
<a-table
@ -58,6 +60,7 @@
</div>
<dict-modal ref="modalForm" @ok="modalFormOk"></dict-modal> <!-- 字典类型 -->
<dict-item-list ref="dictItemList"></dict-item-list>
<dict-delete-list ref="dictDeleteList"></dict-delete-list>
</a-card>
</template>
@ -66,11 +69,12 @@
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import DictModal from './modules/DictModal'
import DictItemList from './DictItemList'
import DictDeleteList from './DictDeleteList'
export default {
name: "DictList",
mixins:[JeecgListMixin],
components: {DictModal, DictItemList},
components: {DictModal, DictItemList,DictDeleteList},
data() {
return {
description: '这是数据字典页面',
@ -161,6 +165,10 @@
that.queryParam.dictCode = "";
that.loadData(this.ipagination.current);
},
openDeleteList(){
this.$refs.dictDeleteList.show()
}
},
watch: {
openKeys(val) {

View File

@ -10,7 +10,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">

View File

@ -0,0 +1,198 @@
<template>
<a-card :bordered="false">
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button
@click="batchDel"
v-if="selectedRowKeys.length > 0"
ghost
type="primary"
icon="delete">批量删除
</a-button>
</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>已选择&nbsp;<a style="font-weight: 600">{{
selectedRowKeys.length }}</a>项&nbsp;&nbsp;
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
:columns="columns"
size="middle"
:pagination="false"
:dataSource="dataSource"
:loading="loading"
@expand="expandSubmenu"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
更多 <a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item>
<a href="javascript:;" @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;" @click="handleAddSub(record)">添加子菜单</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;" @click="handleDataRule(record)">数据规则</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>
<!-- 字符串超长截取省略号显示 -->
<span slot="url" slot-scope="text">
<j-ellipsis :value="text" :length="25"/>
</span>
<!-- 字符串超长截取省略号显示-->
<span slot="component" slot-scope="text">
<j-ellipsis :value="text"/>
</span>
</a-table>
</div>
<!-- table区域-end -->
<permission-modal ref="modalForm" @ok="modalFormOk"></permission-modal>
<permission-data-rule-list ref="PermissionDataRuleList" @ok="modalFormOk"></permission-data-rule-list>
</a-card>
</template>
<script>
import PermissionModal from './modules/PermissionModal'
import { getSystemMenuList,getSystemSubmenu } from '@/api/api'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import PermissionDataRuleList from './PermissionDataRuleList'
import JEllipsis from '@/components/jeecg/JEllipsis'
const columns = [
{
title: '菜单名称',
dataIndex: 'name',
key: 'name'
}, {
title: '菜单类型',
dataIndex: 'menuType',
key: 'menuType',
customRender: function(text) {
if (text == 0) {
return '菜单'
} else if (text == 1) {
return '菜单'
} else if (text == 2) {
return '按钮/权限'
} else {
return text
}
}
},/*{
title: '权限编码',
dataIndex: 'perms',
key: 'permissionCode',
},*/{
title: 'icon',
dataIndex: 'icon',
key: 'icon'
},
{
title: '组件',
dataIndex: 'component',
key: 'component',
scopedSlots: { customRender: 'component' }
},
{
title: '路径',
dataIndex: 'url',
key: 'url',
scopedSlots: { customRender: 'url' }
},
{
title: '排序',
dataIndex: 'sortNo',
key: 'sortNo'
},
{
title: '操作',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
align: 'center',
width: 150
}
]
export default {
name: 'PermissionList',
mixins: [JeecgListMixin],
components: {
PermissionDataRuleList,
PermissionModal,
JEllipsis
},
data() {
return {
description: '这是菜单管理页面',
// 表头
columns: columns,
loading: false,
url: {
list: '/sys/permission/list',
delete: '/sys/permission/delete',
deleteBatch: '/sys/permission/deleteBatch'
}
}
},
methods: {
loadData() {
this.dataSource = []
getSystemMenuList().then((res) => {
if (res.success) {
console.log(res.result)
this.dataSource = res.result
}
})
},
expandSubmenu(expanded, record){
if(expanded){
getSystemSubmenu({parentId:record.id}).then((res) => {
if (res.success) {
record.children = res.result
}
})
}
},
// 打开数据规则编辑
handleDataRule(record) {
this.$refs.PermissionDataRuleList.edit(record)
},
handleAddSub(record) {
this.$refs.modalForm.title = "添加子菜单";
this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -14,7 +14,7 @@
background: '#fff',
}">
<div class="table-page-search-wrapper">
<a-form>
<a-form @keyup.enter.native="searchQuery">
<a-row :gutter="12">
<a-col :md="8" :sm="8">
<a-form-item label="规则名称" :labelCol="{span: 8}" :wrapperCol="{span: 14, offset: 1}">
@ -118,6 +118,10 @@
},
methods: {
loadData() {
//20190908 scott for: 首次进入菜单列表的时候,不加载权限列表
if(!this.permId){
return
}
let that = this
this.dataSource = []
var params = this.getQueryParams()//查询条件

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="10">

View File

@ -4,7 +4,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="名称" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">

View File

@ -5,7 +5,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="12" :sm="12">
<a-form-item label="角色名称" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">

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 :span="6">
@ -89,6 +89,9 @@
<a>撤销</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a @click="handleDetail(record)">查看</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>

View File

@ -0,0 +1,187 @@
<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.ruleName"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="规则Code">
<a-input placeholder="请输入规则Code" v-model="queryParam.ruleCode"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="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-button type="primary" icon="download" @click="handleExportXls('填值规则')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-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 -->
<a-alert type="info" showIcon style="margin-bottom: 16px;">
<template slot="message">
<span>已选择</span>
<a style="font-weight: 600;padding: 0 4px;">{{ selectedRowKeys.length }}</a>
<span>项</span>
<template v-if="selectedRowKeys.length>0">
<a-divider type="vertical"/>
<a @click="onClearSelected">清空</a>
</template>
</template>
</a-alert>
<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="handleTest(record)">
功能测试
</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>
<!-- table区域-end -->
<!-- 表单区域 -->
<sys-fill-rule-modal ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
import SysFillRuleModal from './modules/SysFillRuleModal'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
name: 'SysFillRuleList',
mixins: [JeecgListMixin],
components: { SysFillRuleModal },
data() {
return {
description: '填值规则管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: (t, r, index) => 1 + index
},
{
title: '规则名称',
align: 'center',
dataIndex: 'ruleName'
},
{
title: '规则Code',
align: 'center',
dataIndex: 'ruleCode'
},
{
title: '规则实现类',
align: 'center',
dataIndex: 'ruleClass'
},
{
title: '规则参数',
align: 'center',
dataIndex: 'ruleParams'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' },
}
],
url: {
list: '/sys/fillRule/list',
test: '/sys/fillRule/testFillRule',
delete: '/sys/fillRule/delete',
deleteBatch: '/sys/fillRule/deleteBatch',
exportXlsUrl: '/sys/fillRule/exportXls',
importExcelUrl: '/sys/fillRule/importExcel',
},
}
},
computed: {
importExcelUrl() {
return `${window._CONFIG['domianURL']}${this.url.importExcelUrl}`
}
},
methods: {
handleTest(record) {
let closeLoading = this.$message.loading('生成中...', 0)
getAction(this.url.test, {
ruleCode: record.ruleCode
}).then(res => {
if (res.success) {
this.$info({
title: '填值规则功能测试',
content: '生成结果:' + res.result
})
} else {
this.$message.warn(res.message)
}
}).finally(() => {
closeLoading()
})
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -0,0 +1,178 @@
<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.code"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="职务名称">
<a-input placeholder="请输入职务名称" v-model="queryParam.name"></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.postRank" placeholder="请选择职级" dictCode="position_rank"/>
</a-form-item>
</a-col>
</template>
<a-col :md="6" :sm="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>
<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">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('职务表')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-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>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<sysPosition-modal ref="modalForm" @ok="modalFormOk"></sysPosition-modal>
</a-card>
</template>
<script>
import SysPositionModal from './modules/SysPositionModal'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import JDictSelectTag from '@/components/dict/JDictSelectTag'
export default {
name: 'SysPositionList',
mixins: [JeecgListMixin],
components: {
SysPositionModal,
JDictSelectTag
},
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: 'code'
},
{
title: '职务名称',
align: 'center',
dataIndex: 'name'
},
{
title: '职级',
align: 'center',
dataIndex: 'postRank_dictText'
},
// {
// title: '公司id',
// align: 'center',
// dataIndex: 'companyId'
// },
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' },
}
],
url: {
list: '/sys/position/list',
delete: '/sys/position/delete',
deleteBatch: '/sys/position/deleteBatch',
exportXlsUrl: '/sys/position/exportXls',
importExcelUrl: '/sys/position/importExcel',
},
}
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
}
}
}
</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 :span="6">
@ -132,11 +132,7 @@
loading:false,
}
},
created() {
this.loadData();
},
methods: {
handleDetail: function(record){
this.$refs.sysAnnouncementModal.detail(record);
this.$refs.sysAnnouncementModal.title="查看";

View File

@ -3,12 +3,13 @@
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @submit.prevent="searchQuery">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="12">
<a-form-item label="账号">
<a-input placeholder="请输入账号查询" v-model="queryParam.username"></a-input>
<!--<a-input placeholder="请输入账号查询" v-model="queryParam.username"></a-input>-->
<j-input placeholder="输入账号模糊查询" v-model="queryParam.username"></j-input>
</a-form-item>
</a-col>
@ -41,7 +42,7 @@
<a-select v-model="queryParam.status" placeholder="请选择用户状态查询">
<a-select-option value="">请选择用户状态</a-select-option>
<a-select-option value="1">正常</a-select-option>
<a-select-option value="2">冻</a-select-option>
<a-select-option value="2">冻</a-select-option>
</a-select>
</a-form-item>
</a-col>
@ -64,7 +65,7 @@
<!-- 操作按钮区域 -->
<div class="table-operator" style="border-top: 5px">
<a-button @click="handleAdd" v-has="'user:add'" type="primary" icon="plus">添加用户</a-button>
<a-button @click="handleAdd" type="primary" icon="plus" v-has="'user:add'">添加用户</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('用户信息')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
@ -117,9 +118,9 @@
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)" v-has="'user:edit'">编辑</a>
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" v-has="'user:edit'"/>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
@ -180,6 +181,7 @@
import {frozenBatch} from '@/api/api'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import SysUserAgentModal from "./modules/SysUserAgentModal";
import JInput from '@/components/jeecg/JInput'
export default {
name: "UserList",
@ -187,7 +189,8 @@
components: {
SysUserAgentModal,
UserModal,
PasswordModal
PasswordModal,
JInput
},
data() {
return {
@ -369,4 +372,4 @@
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>
</style>

View File

@ -0,0 +1,98 @@
<template>
<a-card :loading="cardLoading" :bordered="false" style="height: 100%;">
<a-spin :spinning="loading">
<a-input-search @search="handleSearch" style="width:100%;margin-top: 10px" placeholder="输入组织机构名称进行查询..."/>
<a-tree
showLine
checkStrictly
:expandedKeys.sync="expandedKeys"
:selectedKeys="selectedKeys"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="treeDataSource"
@select="handleTreeSelect"
/>
</a-spin>
</a-card>
</template>
<script>
import { queryDepartTreeList, searchByKeywords } from '@/api/api'
export default {
name: 'AddressListLeft',
props: ['value'],
data() {
return {
cardLoading: true,
loading: false,
treeDataSource: [],
selectedKeys: [],
expandedKeys: []
}
},
created() {
this.queryTreeData()
},
methods: {
queryTreeData(keyword) {
this.commonRequestThen(queryDepartTreeList({
departName: keyword ? keyword : undefined
}))
},
handleSearch(value) {
if (value) {
this.commonRequestThen(searchByKeywords({ keyWord: value }))
} else {
this.queryTreeData()
}
},
handleTreeSelect(selectedKeys, event) {
if (selectedKeys.length > 0 && this.selectedKeys[0] !== selectedKeys[0]) {
this.selectedKeys = [selectedKeys[0]]
let orgCode = event.node.dataRef.orgCode
this.emitInput(orgCode)
}
},
emitInput(orgCode) {
this.$emit('input', orgCode)
},
commonRequestThen(promise) {
this.loading = true
promise.then(res => {
if (res.success) {
this.treeDataSource = res.result
// 默认选中第一条数据、默认展开所有第一级
if (res.result.length > 0) {
this.expandedKeys = []
res.result.forEach((item, index) => {
if (index === 0) {
this.selectedKeys = [item.id]
this.emitInput(item.orgCode)
}
this.expandedKeys.push(item.id)
})
}
} else {
this.$message.warn('组织机构查询失败' + res.message)
console.error('组织机构查询失败:', res)
}
}).finally(() => {
this.loading = false
this.cardLoading = false
})
},
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,198 @@
<template>
<a-card class="j-address-list-right-card-box" :loading="cardLoading" :bordered="false">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="10">
<a-col :md="6" :sm="12">
<a-form-item label="姓名" style="margin-left:8px">
<a-input placeholder="请输入姓名查询" v-model="queryParam.realname"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="12">
<a-form-item label="工号" style="margin-left:8px">
<a-input placeholder="请输入工号查询" v-model="queryParam.workNo"></a-input>
</a-form-item>
</a-col>
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24">
<a-button type="primary" @click="searchQuery" icon="search" style="margin-left: 18px">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</a-col>
</span>
</a-row>
</a-form>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="userId"
:pagination="ipagination"
:columns="columns"
:dataSource="dataSource"
:loading="loading"
@change="handleTableChange">
</a-table>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
name: 'AddressListRight',
mixins: [JeecgListMixin],
components: {},
props: ['value'],
data() {
return {
description: '用户信息',
cardLoading: true,
positionInfo: {},
columns: [
{
title: '#',
key: 'rowIndex',
dataIndex: '',
width: 60,
align: 'center',
customRender: (t, r, i) => parseInt(i) + 1
},
{
title: '部门',
width: '20%',
align: 'center',
dataIndex: 'departName'
},
{
title: '姓名',
width: '15%',
align: 'center',
dataIndex: 'realname'
},
{
title: '工号',
width: '15%',
align: 'center',
dataIndex: 'workNo'
},
{
title: '职务',
width: '15%',
align: 'center',
dataIndex: 'post',
customRender: (text) => (text || '').split(',').map(t => this.positionInfo[t] ? this.positionInfo[t] : t).join(',')
},
{
title: '座机',
width: '15%',
align: 'center',
dataIndex: 'telephone'
},
// {
// title: '手机号',
// width: '12%',
// align: 'center',
// dataIndex: 'phone'
// },
{
title: '公司邮箱',
width: '15%',
align: 'center',
dataIndex: 'email'
}
],
url: {
list: '/sys/user/queryByOrgCodeForAddressList',
listByPosition: '/sys/position/list'
}
}
},
watch: {
value: {
immediate: true,
handler(orgCode) {
this.dataSource = []
this.loadData(1, orgCode)
}
},
},
created() {
this.queryPositionInfo()
},
methods: {
loadData(pageNum, orgCode) {
if (!orgCode) {
return
}
//加载数据 若传入参数1则加载第一页的内容
if (pageNum === 1) {
this.ipagination.current = 1
}
this.loading = true
getAction(this.url.list, {
orgCode,
...this.getQueryParams()
}).then((res) => {
if (res.success) {
this.dataSource = res.result.records
this.ipagination.total = res.result.total
}
}).finally(() => {
this.loading = false
this.cardLoading = false
})
},
searchQuery() {
this.loadData(1, this.value)
},
searchReset() {
this.queryParam = {}
this.loadData(1, this.value)
},
handleTableChange(pagination, filters, sorter) {
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc'
}
this.ipagination = pagination
this.loadData(null, this.value)
},
// 查询职务信息
queryPositionInfo() {
getAction(this.url.listByPosition, { pageSize: 99999 }).then(res => {
if (res.success) {
let positionInfo = {}
res.result.records.forEach(record => {
positionInfo[record['code']] = record['name']
})
this.positionInfo = positionInfo
}
})
}
}
}
</script>
<style>
.j-address-list-right-card-box .ant-table-placeholder {
min-height: 46px;
}
</style>
<style scoped>
.j-address-list-right-card-box {
height: 100%;
min-height: 300px;
}
</style>

View File

@ -30,6 +30,28 @@
:disabled="condition">
</a-tree-select>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
<template v-if="seen">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
</a-radio-group>
</template>
<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"
@ -107,6 +129,7 @@
url: {
add: "/sys/sysDepart/add",
},
dictDisabled:true,
}
},
created () {
@ -128,8 +151,10 @@
add (depart) {
if(depart){
this.seen = false;
this.dictDisabled = false;
}else{
this.seen = true;
this.dictDisabled = true;
}
this.edit(depart);
},
@ -139,8 +164,13 @@
this.visible = true;
this.loadTreeData();
this.model.parentId = record!=null?record.toString():null;
if(this.seen){
this.model.orgCategory = '1';
}else{
this.model.orgCategory = '2';
}
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,'departName','departNameEn','departNameAbbr','departOrder','description','orgType','orgCode','mobile','fax','address','memo','status','delFlag'))
this.form.setFieldsValue(pick(this.model,'orgCategory','departName','departNameEn','departNameAbbr','departOrder','description','orgType','orgCode','mobile','fax','address','memo','status','delFlag'))
});
},
close () {

View File

@ -23,6 +23,22 @@
label="机构编码">
<a-input style="border:0px;" placeholder="" v-decorator="['orgCode', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="机构类型">
<a-radio-group :disabled="true" v-decorator="['orgCategory',{}]" placeholder="请选择机构类型">
<a-radio value="1">
公司
</a-radio>
<a-radio value="2">
部门
</a-radio>
<a-radio value="3">
岗位
</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
@ -98,7 +114,7 @@
console.log("record:");
console.log(record);
this.$nextTick(() => {
this.form.setFieldsValue(pick(record, 'departName', 'parentId', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'));
this.form.setFieldsValue(pick(record, 'orgCategory','departName', 'parentId', 'orgCode', 'departOrder', 'mobile', 'fax', 'address', 'memo'));
});
},
clearForm() {

View File

@ -148,6 +148,16 @@
<a-switch checkedChildren="" unCheckedChildren="" v-model="alwaysShow"/>
</a-form-item>
<!--update_begin author:wuxianquan date:20190908 for:增加组件外链打开方式可选 -->
<a-form-item
v-show="show"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="打开方式">
<a-switch checkedChildren="外部" unCheckedChildren="内部" v-model="internalOrExternal"/>
</a-form-item>
<!--update_end author:wuxianquan date:20190908 for:增加组件外链打开方式可选 -->
</a-form>
@ -186,6 +196,9 @@
alwaysShow:false,//表单元素-聚合路由
menuHidden:false,//表单元素-隐藏路由
routeSwitch:true, //是否路由菜单
/*update_begin author:wuxianquan date:20190908 for:定义变量,初始值代表内部打开*/
internalOrExternal:false,//菜单打开方式
/*update_end author:wuxianquan date:20190908 for:定义变量,初始值代表内部打开*/
isKeepalive:true, //是否缓存路由
show:true,//根据菜单类型,动态显示隐藏表单元素
menuLabel:'菜单名称',
@ -213,7 +226,7 @@
component:{rules: [{ required: this.show, message: '请输入前端组件!' }]},
url:{rules: [{ required: this.show, message: '请输入菜单路径!' }]},
permsType:{rules: [{ required: true, message: '请输入授权策略!' }]},
sortNo:{initialValue:1.0,rules: [{validator: this.validateNumber}]},
sortNo:{initialValue:1.0},
}
}
},
@ -254,13 +267,20 @@
if(record.route!=null){
this.routeSwitch = record.route?true:false;
}
if(record.keepAlive!=null){
this.isKeepalive = record.keepAlive?true:false;
}else{
this.isKeepalive = false; // 升级兼容 如果没有后台没有传过来、或者是新建默认为false
}
/*update_begin author:wuxianquan date:20190908 for:编辑初始化数据*/
if(record.internalOrExternal!=null){
this.internalOrExternal = record.internalOrExternal?true:false;
}else{
this.internalOrExternal = false;
}
/*update_end author:wuxianquan date:20190908 for:编辑初始化数据*/
//console.log('record.menuType', record.menuType);
@ -295,6 +315,10 @@
this.model.hidden = this.menuHidden;
this.model.route = this.routeSwitch;
this.model.keepAlive = this.isKeepalive;
/*update_begin author:wuxianquan date:20190908 for:获取值*/
this.model.internalOrExternal = this.internalOrExternal;
/*update_end author:wuxianquan date:20190908 for:获取值*/
let formData = Object.assign(this.model, values);
if ((formData.menuType == 1 || formData.menuType == 2) && !formData.parentId) {
that.validateStatus = 'error';

View File

@ -28,7 +28,8 @@
<!-- <a-icon type="share-alt" />-->
<!-- 在线cron表达式生成-->
<!-- </a>-->
<j-cron ref="innerVueCron" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?',rules: [{ required: true, message: '请输入cron表达式!' }]}]" @change="setCorn"></j-cron>
<!-- <j-cron ref="innerVueCron" v-decorator="['cronExpression', {'initialValue':'0/1 * * * * ?',rules: [{ required: true, message: '请输入cron表达式!' }]}]" @change="setCorn"></j-cron>-->
<j-cron ref="innerVueCron" v-decorator="['cronExpression', { initialValue: '* * * * * ? *' }]" @change="setCorn"></j-cron>
</a-form-item>
<a-form-item
:labelCol="labelCol"
@ -61,9 +62,9 @@
<script>
import { httpAction } from '@/api/manage'
import JCron from "@/components/jeecg/JCron.vue";
import JCron from "@/components/jeecg/JCron";
import pick from 'lodash.pick'
import moment from "moment"
// import moment from "moment"
export default {
name: "QuartzJobModal",
@ -109,6 +110,8 @@
this.edit({});
},
edit (record) {
let that = this;
that.form.resetFields();
this.model = Object.assign({},record);
console.log(this.model)
this.visible = true;
@ -127,10 +130,10 @@
this.form.validateFields((err, values) => {
console.log('values',values)
if (!err) {
// if (typeof values.cronExpression == "undefined" || Object.keys(values.cronExpression).length==0 ) {
// this.$message.warning('请输入cron表达式!');
// return false;
// }
if (typeof values.cronExpression == "undefined" || Object.keys(values.cronExpression).length==0 ) {
this.$message.warning('请输入cron表达式!');
return false;
}
that.confirmLoading = true;
let httpurl = '';
@ -171,9 +174,9 @@
})
// console.log(Object.keys(data).length==0);
// if (Object.keys(data).length==0) {
// this.$message.warning('请输入cron表达式!');
// }
if (Object.keys(data).length==0) {
this.$message.warning('请输入cron表达式!');
}
},
validateCron(rule, value, callback){
if(!value){

View File

@ -66,17 +66,17 @@
</a-row>
</a-form>
</div>
<!-- update-begin author:kangxiaolin date:20190921 for:系统发送通知 用户多选失败 #513 -->
<a-table
ref="table"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,onSelect:onSelect}"
@change="handleTableChange"
>
<!-- update-end author:kangxiaolin date:20190921 for:系统发送通知 用户多选失败 #513 -->
</a-table>
</a-modal>
</template>
@ -178,7 +178,13 @@
if(!selectUser){
this.selectionRows=[]
}else{
this.selectionRows = selectUser;
var that=this;
that.selectionRows=[];
selectUser.forEach(function(record,index){
console.log(record)
that.selectionRows.push({id: that.selectedRowKeys[index],realname:record})
})
// this.selectionRows = selectUser;
}
},
loadData (arg){
@ -211,11 +217,23 @@
}
return str;
},
onSelectChange (selectedRowKeys,selectionRows) {
//--update-begin----author:kangxiaolin---date:20190921------for:系统发送通知 用户多选失败 #513----
onSelectChange (selectedRowKeys) {
this.selectedRowKeys = selectedRowKeys;
console.log(this.selectedRowKeys);
this.selectionRows = selectionRows;
},
onSelect(record, selected){
if(selected == true ){
this.selectionRows.push(record);
}else {
this.selectionRows.forEach(function(item,index,arr){
if(item.id == record.id) {
arr.splice(index, 1);
}
})
}
//--update-end----author:kangxiaolin---date:20190921------for:系统发送通知 用户多选失败 #513----
},
searchReset(){
let that = this;
Object.keys(that.queryParam).forEach(function(key){

View File

@ -17,7 +17,8 @@
placeholder="请选择父级节点"
v-decorator="['pid', validatorRules.pid]"
dict="sys_category,name,id"
pidField="pid">
pidField="pid"
pidValue="0">
</j-tree-select>
</a-form-item>
@ -25,9 +26,16 @@
<a-input v-decorator="[ 'name', validatorRules.name]" placeholder="请输入类型名称"></a-input>
</a-form-item>
<a-form-item label="类型编码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<!--<a-form-item label="类型编码" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input v-decorator="[ 'code', validatorRules.code]" placeholder="请输入类型编码"></a-input>
</a-form-item>
</a-form-item>-->
<!--<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol">
<span style="font-size: 12px;color:red" slot="label">编码规则()</span>
<span style="font-size: 12px;color:red">
编码值前缀需和父节点保持一致,比如父级节点编码是A01则当前编码必须以A01开头
</span>
</a-form-item>-->
</a-form>
@ -37,7 +45,7 @@
<script>
import { httpAction } from '@/api/manage'
import { httpAction,getAction } from '@/api/manage'
import pick from 'lodash.pick'
import JTreeSelect from '@/components/jeecg/JTreeSelect'
@ -64,13 +72,20 @@
confirmLoading: false,
validatorRules:{
pid:{},
name:{},
code:{},
code:{
rules: [{
required: true, message: '请输入类型编码!'
},{
validator: this.validateMyCode
}]
},
pid:{},
name:{}
},
url: {
add: "/sys/category/add",
edit: "/sys/category/edit",
checkCode:"/sys/category/checkCode"
},
expandedRowKeys:[],
pidField:"pid"
@ -154,7 +169,20 @@
}
}
}
}
},
validateMyCode(rule, value, callback){
let params = {
pid: this.form.getFieldValue('pid'),
code: value
}
getAction(this.url.checkCode,params).then((res) => {
if (res.success) {
callback()
} else {
callback(res.message)
}
})
},
}

View File

@ -0,0 +1,158 @@
<template>
<a-modal
:title="title"
:width="800"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="规则名称">
<a-input placeholder="请输入规则名称" v-decorator="['ruleName', validatorRules.ruleName]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="规则Code">
<a-input placeholder="请输入规则Code" :disabled="disabledCode" v-decorator="['ruleCode', validatorRules.ruleCode]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="规则实现类">
<a-input placeholder="请输入规则实现类" v-decorator="['ruleClass', validatorRules.ruleClass]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="规则参数">
<a-textarea placeholder="请输入规则参数" :rows="5" v-decorator="['ruleParams', validatorRules.ruleParams]"/>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import pick from 'lodash.pick'
import { httpAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
export default {
name: 'SysFillRuleModal',
components: {},
data() {
return {
title: '操作',
visible: false,
model: {},
labelCol: { xs: { span: 24 }, sm: { span: 5 } },
wrapperCol: { xs: { span: 24 }, sm: { span: 16 } },
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
ruleName: { rules: [{ required: true, message: '规则名称不能为空' }] },
ruleCode: {
rules: [
{ required: true, message: '规则Code不能为空' },
{ validator: (rule, value, callback) => validateDuplicateValue('sys_fill_rule', 'rule_code', value, this.model.id, callback) }
]
},
ruleClass: { rules: [{ required: true, message: '规则实现类不能为空' }] },
ruleParams: {
rules: [{
validator: (rule, value, callback) => {
try {
let json = JSON.parse(value)
if (json instanceof Array) {
callback('只能传递JSON对象不能传递JSON数组')
} else if (json instanceof Object) {
callback()
} else {
callback('请输入JSON字符串')
}
} catch {
callback('请输入JSON字符串')
}
}
}]
},
},
url: {
add: '/sys/fillRule/add',
edit: '/sys/fillRule/edit',
},
}
},
computed: {
disabledCode() {
return !!this.model.id
}
},
created() {
},
methods: {
add() {
this.edit({})
},
edit(record) {
this.form.resetFields()
this.model = Object.assign({}, record)
this.visible = true
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'ruleName', 'ruleCode', 'ruleClass', 'ruleParams'))
})
},
close() {
this.$emit('close')
this.visible = false
},
handleOk() {
const that = this
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true
let httpUrl = this.url.add, method = 'post'
if (this.model.id) {
httpUrl = this.url.edit
method = 'put'
}
let formData = Object.assign(this.model, values)
httpAction(httpUrl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message)
that.$emit('ok')
} else {
that.$message.warning(res.message)
}
}).finally(() => {
that.confirmLoading = false
that.close()
})
}
})
},
handleCancel() {
this.close()
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -0,0 +1,180 @@
<template>
<a-modal
:title="title"
:width="800"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="职务编码">
<a-input placeholder="请输入职务编码" v-decorator="['code', validatorRules.code]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="职务名称">
<a-input placeholder="请输入职务名称" v-decorator="['name', validatorRules.name]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="职级"
>
<j-dict-select-tag
placeholder="请选择职级"
:triggerChange="true"
dictCode="position_rank"
v-decorator="['postRank', validatorRules.postRank]"
/>
</a-form-item>
<!--<a-form-item-->
<!-- :labelCol="labelCol"-->
<!-- :wrapperCol="wrapperCol"-->
<!-- label="公司id">-->
<!-- <a-input placeholder="请输入公司id" v-decorator="['companyId', {}]"/>-->
<!--</a-form-item>-->
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import pick from 'lodash.pick'
import { httpAction } from '@/api/manage'
import { duplicateCheck } from '@/api/api'
import JDictSelectTag from '@/components/dict/JDictSelectTag'
let validatorCodeTimer = null
export default {
name: 'SysPositionModal',
components: { JDictSelectTag },
data() {
return {
title: '操作',
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
code: {
rules: [
{ required: true, message: '请输入职务编码' },
{
validator: (rule, value, callback) => {
// 函数消抖的简单实现,防止一段时间内发送多次请求
if (validatorCodeTimer) {
// 停止上次开启的定时器
clearTimeout(validatorCodeTimer)
}
validatorCodeTimer = setTimeout(() => {
duplicateCheck({
tableName: 'sys_position',
fieldName: 'code',
fieldVal: value,
dataId: this.model.id
}).then((res) => {
if (res.success) {
callback()
} else {
callback(res.message)
}
}).catch(console.error)
}, 300)
}
}
]
},
name: { rules: [{ required: true, message: '请输入职务名称' }] },
postRank: { rules: [{ required: true, message: '请选择职级' }] },
},
url: {
add: '/sys/position/add',
edit: '/sys/position/edit',
},
}
},
created() {
},
methods: {
add() {
this.edit({})
},
edit(record) {
this.form.resetFields()
this.model = Object.assign({}, record)
this.visible = true
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,
'code',
'name',
'postRank',
// 'companyId'
))
})
},
close() {
this.$emit('close')
this.visible = false
},
handleOk() {
const that = this
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true
let httpurl = ''
let method = ''
if (!this.model.id) {
httpurl += this.url.add
method = 'post'
} else {
httpurl += this.url.edit
method = 'put'
}
let formData = Object.assign(this.model, values)
httpAction(httpurl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message)
that.$emit('ok')
} else {
that.$message.warning(res.message)
}
}).finally(() => {
that.confirmLoading = false
that.close()
})
}
})
},
handleCancel() {
this.close()
},
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -40,6 +40,14 @@
<a-input placeholder="请输入用户名称" v-decorator="[ 'realname', validatorRules.realname]" />
</a-form-item>
<a-form-item label="工号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入工号" v-decorator="[ 'workNo', validatorRules.workNo]" />
</a-form-item>
<a-form-item label="职务" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-select-position placeholder="请选择职务" :multiple="false" v-decorator="['post', {}]"/>
</a-form-item>
<a-form-item label="角色分配" :labelCol="labelCol" :wrapperCol="wrapperCol" v-show="!roleDisabled" >
<a-select
mode="multiple"
@ -104,6 +112,10 @@
<a-input placeholder="请输入手机号码" :disabled="isDisabledAuth('user:form:phone')" v-decorator="[ 'phone', validatorRules.phone]" />
</a-form-item>
<a-form-item label="座机" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入座机" v-decorator="[ 'telephone', validatorRules.telephone]"/>
</a-form-item>
<a-form-item label="工作流引擎" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-dict-select-tag v-decorator="['activitiSync', {}]" placeholder="请选择是否同步工作流引擎" :type="'radio'" :triggerChange="true" dictCode="activiti_sync"/>
</a-form-item>
@ -127,6 +139,7 @@
import Vue from 'vue'
// 引入搜索部门弹出框的组件
import departWindow from './DepartWindow'
import JSelectPosition from '@/components/jeecgbiz/JSelectPosition'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import { getAction } from '@/api/manage'
import {addUser,editUser,queryUserRole,queryall } from '@/api/api'
@ -134,9 +147,10 @@
import {duplicateCheck } from '@/api/api'
export default {
name: "RoleModal",
name: "UserModal",
components: {
departWindow,
JSelectPosition
},
data () {
return {
@ -185,8 +199,19 @@
validator: this.validateEmail
}],
},
roles:{}
roles:{},
// sex:{initialValue:((!this.model.sex)?"": (this.model.sex+""))}
workNo: {
rules: [
{ required: true, message: '请输入工号' },
{ validator: this.validateWorkNo }
]
},
telephone: {
rules: [
{ pattern: /^0\d{2,3}-[1-9]\d{6,7}$/, message: '请输入正确的座机号码' },
]
}
},
title:"操作",
visible: false,
@ -282,7 +307,7 @@
that.visible = true;
that.model = Object.assign({}, record);
that.$nextTick(() => {
that.form.setFieldsValue(pick(this.model,'username','sex','realname','email','phone','activitiSync'))
that.form.setFieldsValue(pick(this.model,'username','sex','realname','email','phone','activitiSync','workNo','telephone','post'))
});
// 调用查询用户对应的部门信息的方法
that.checkedDepartKeys = [];
@ -389,7 +414,10 @@
if(!value){
callback()
}else{
if(new RegExp(/^1[3|4|5|7|8][0-9]\d{8}$/).test(value)){
//update-begin--Author:kangxiaolin Date:20190826 for[05] 手机号不支持199号码段--------------------
if(new RegExp(/^1[3|4|5|7|8|9][0-9]\d{8}$/).test(value)){
//update-end--Author:kangxiaolin Date:20190826 for[05] 手机号不支持199号码段--------------------
var params = {
tableName: 'sys_user',
fieldName: 'phone',
@ -447,6 +475,21 @@
}
})
},
validateWorkNo(rule, value, callback){
var params = {
tableName: 'sys_user',
fieldName: 'work_no',
fieldVal: value,
dataId: this.userId
};
duplicateCheck(params).then((res) => {
if (res.success) {
callback()
} else {
callback("工号已存在!")
}
})
},
handleConfirmBlur (e) {
const value = e.target.value;
this.confirmDirty = this.confirmDirty || !!value

View File

@ -18,6 +18,7 @@
:treeData="treeData"
@expand="onExpand"
@select="onTreeNodeSelect"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeysss"
:checkStrictly="checkStrictly">
<span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
@ -74,11 +75,15 @@
title:"角色权限配置",
visible: false,
loading: false,
selectedKeys:[]
}
},
methods: {
onTreeNodeSelect(id){
this.$refs.datarule.show(id[0],this.roleId)
if(id && id.length>0){
this.selectedKeys = id
}
this.$refs.datarule.show(this.selectedKeys[0],this.roleId)
},
onCheck (o) {
if(this.checkStrictly){

View File

@ -42,7 +42,7 @@
</a-form-item>
</a-col>
<a-col :span="10">
<j-graphic-code @success="generateCode" style="float: right"></j-graphic-code>
<j-graphic-code @success="generateCode" ref="jgraphicCodeRef" style="float: right" remote></j-graphic-code>
</a-col>
</a-row>
@ -84,13 +84,13 @@
</a-tabs>
<a-form-item>
<a-checkbox v-model="formLogin.rememberMe">自动登陆</a-checkbox>
<!-- <router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">
<a-checkbox v-decorator="['rememberMe', {initialValue: true, valuePropName: 'checked'}]" >自动登陆</a-checkbox>
<router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">
忘记密码
</router-link>
<router-link :to="{ name: 'register'}" class="forge-password" style="float: right;margin-right: 10px" >
注册账户
</router-link>-->
</router-link>
</a-form-item>
<a-form-item style="margin-top:24px">
@ -201,13 +201,6 @@
time: 60,
smsSendBtn: false,
},
formLogin: {
username: "",
password: "",
captcha: "",
mobile: "",
rememberMe: true
},
validatorRules:{
username:{rules: [{ required: true, message: '请输入用户名!',validator: 'click'}]},
password:{rules: [{ required: true, message: '请输入密码!',validator: 'click'}]},
@ -251,20 +244,22 @@
},
handleSubmit () {
let that = this
let loginParams = {
remember_me: that.formLogin.rememberMe
};
let loginParams = {};
that.loginBtn = true;
// 使用账户密码登陆
if (that.customActiveKey === 'tab1') {
that.form.validateFields([ 'username', 'password','inputCode' ], { force: true }, (err, values) => {
that.form.validateFields([ 'username', 'password','inputCode', 'rememberMe' ], { force: true }, (err, values) => {
if (!err) {
loginParams.username = values.username
// update-begin- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题
//loginParams.password = md5(values.password)
//loginParams.password = encryption(values.password,that.encryptedString.key,that.encryptedString.iv)
loginParams.password = values.password
loginParams.remember_me = values.rememberMe
// update-begin- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题
let checkParams = this.$refs.jgraphicCodeRef.getLoginParam()
loginParams.captcha = checkParams.checkCode
loginParams.checkKey = checkParams.checkKey
that.Login(loginParams).then((res) => {
this.departConfirm(res)
@ -279,10 +274,11 @@
})
// 使用手机号登陆
} else {
that.form.validateFields([ 'mobile', 'captcha' ], { force: true }, (err, values) => {
that.form.validateFields([ 'mobile', 'captcha', 'rememberMe' ], { force: true }, (err, values) => {
if (!err) {
loginParams.mobile = values.mobile
loginParams.captcha = values.captcha
loginParams.remember_me = values.rememberMe
that.PhoneLogin(loginParams).then((res) => {
console.log(res.result);
this.departConfirm(res)

View File

@ -13,14 +13,9 @@ module.exports = {
*/
// 如果你不需要生产环境的 source map可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
/*
pages: {
index: {
entry: 'src/main.js',
chunks: ['chunk-vendors', 'chunk-common', 'index']
}
},
*/
//打包app时放开该配置
//publicPath:'./',
configureWebpack: config => {
//生产环境取消 console.log
if (process.env.NODE_ENV === 'production') {
@ -36,6 +31,7 @@ module.exports = {
.set('@views', resolve('src/views'))
.set('@layout', resolve('src/layout'))
.set('@static', resolve('src/static'))
.set('@mobile', resolve('src/modules/mobile'))
},
css: {

File diff suppressed because it is too large Load Diff

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