mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
jeecg-boot 2.0 模块开发版本发布
This commit is contained in:
10
README.md
10
README.md
@ -1,7 +1,7 @@
|
|||||||
Jeecg-Boot 快速开发平台(前后端分离版本)
|
Jeecg-Boot 快速开发平台(前后端分离版本)
|
||||||
===============
|
===============
|
||||||
|
|
||||||
当前最新版本: 1.1(发布日期:20190415)
|
当前最新版本: 2.0.0(发布日期:20190520)
|
||||||
|
|
||||||
项目介绍:
|
项目介绍:
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@ -52,11 +52,11 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
|||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
#### 后端
|
#### 后端
|
||||||
- 基础框架:Spring Boot 2.0.3.RELEASE
|
- 基础框架:Spring Boot 2.1.3.RELEASE
|
||||||
|
|
||||||
- 持久层框架:Mybatis-plus_3.0.6
|
- 持久层框架:Mybatis-plus_3.0.6
|
||||||
|
|
||||||
- 安全框架:Apache Shiro 1.4.0-RC2,Jwt_3.4.1
|
- 安全框架:Apache Shiro 1.4.0,Jwt_3.7.0
|
||||||
|
|
||||||
- 数据库连接池:阿里巴巴Druid 1.1.10
|
- 数据库连接池:阿里巴巴Druid 1.1.10
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
|||||||
|
|
||||||
- 依赖管理:Maven
|
- 依赖管理:Maven
|
||||||
|
|
||||||
- 数据库:MySQL5.0 & Oracle 11g
|
- 数据库:MySQL5.0 & Oracle 11g & Sqlserver2005
|
||||||
|
|
||||||
- 缓存:Redis
|
- 缓存:Redis
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ Jeecg-Boot快速开发平台,可以应用在任何J2EE项目的开发中,尤
|
|||||||
- jdk8
|
- jdk8
|
||||||
- mysql
|
- mysql
|
||||||
- redis
|
- redis
|
||||||
- 数据库脚步:jeecg-boot\docs\jeecg-boot_1.1.0-20190415.sql
|
- 数据库脚步:jeecg-boot\docs\jeecg-boot-mysql.sql
|
||||||
- 默认登录账号: admin/123456
|
- 默认登录账号: admin/123456
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
ant-design-jeecg-vue/.eslintignore
Normal file
1
ant-design-jeecg-vue/.eslintignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
/src
|
||||||
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019 jeecg-boot
|
Copyright (c) 2019 DaiHao Zhang
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
Ant Design Jeecg Vue
|
Ant Design Jeecg Vue
|
||||||
====
|
====
|
||||||
|
|
||||||
当前最新版本: 1.1.0(发布日期:20190415)
|
当前最新版本: 2.0.0(发布日期:20190518)
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
----
|
----
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-antd-jeecg",
|
"name": "vue-antd-jeecg",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve --open",
|
"serve": "vue-cli-service serve --open",
|
||||||
@ -15,6 +15,8 @@
|
|||||||
"ant-design-vue": "^1.3.1",
|
"ant-design-vue": "^1.3.1",
|
||||||
"apexcharts": "^3.6.5",
|
"apexcharts": "^3.6.5",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
|
"clipboard": "^2.0.4",
|
||||||
|
"codemirror": "^5.46.0",
|
||||||
"dayjs": "^1.8.0",
|
"dayjs": "^1.8.0",
|
||||||
"enquire.js": "^2.1.6",
|
"enquire.js": "^2.1.6",
|
||||||
"js-cookie": "^2.2.0",
|
"js-cookie": "^2.2.0",
|
||||||
@ -29,10 +31,14 @@
|
|||||||
"vue-class-component": "^6.0.0",
|
"vue-class-component": "^6.0.0",
|
||||||
"vue-cropper": "^0.4.8",
|
"vue-cropper": "^0.4.8",
|
||||||
"vue-i18n": "^8.7.0",
|
"vue-i18n": "^8.7.0",
|
||||||
|
"vue-loader": "^15.7.0",
|
||||||
"vue-ls": "^3.2.0",
|
"vue-ls": "^3.2.0",
|
||||||
"vue-print-nb-jeecg": "^1.0.5",
|
"vue-photo-preview": "^1.1.3",
|
||||||
|
"vue-print-nb-jeecg": "^1.0.7",
|
||||||
"vue-property-decorator": "^7.3.0",
|
"vue-property-decorator": "^7.3.0",
|
||||||
"vue-router": "^3.0.1",
|
"vue-router": "^3.0.1",
|
||||||
|
"vue-splitpane": "^1.0.4",
|
||||||
|
"vuedraggable": "^2.20.0",
|
||||||
"vuex": "^3.0.1",
|
"vuex": "^3.0.1",
|
||||||
"vuex-class": "^0.3.1"
|
"vuex-class": "^0.3.1"
|
||||||
},
|
},
|
||||||
|
|||||||
1
ant-design-jeecg-vue/public/index.html
vendored
1
ant-design-jeecg-vue/public/index.html
vendored
@ -224,6 +224,7 @@
|
|||||||
window._CONFIG = {};
|
window._CONFIG = {};
|
||||||
window._CONFIG['domianURL'] = 'http://localhost:8080/jeecg-boot';
|
window._CONFIG['domianURL'] = 'http://localhost:8080/jeecg-boot';
|
||||||
window._CONFIG['imgDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/view';
|
window._CONFIG['imgDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/view';
|
||||||
|
window._CONFIG['pdfDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/pdf/pdfPreviewIframe';
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { getAction,deleteAction,putAction,postAction} from '@/api/manage'
|
|||||||
////图片预览请求地址
|
////图片预览请求地址
|
||||||
// const imgView = "http://localhost:8080/jeecg-boot/sys/common/view/";
|
// const imgView = "http://localhost:8080/jeecg-boot/sys/common/view/";
|
||||||
|
|
||||||
|
|
||||||
//角色管理
|
//角色管理
|
||||||
const addRole = (params)=>postAction("/sys/role/add",params);
|
const addRole = (params)=>postAction("/sys/role/add",params);
|
||||||
const editRole = (params)=>putAction("/sys/role/edit",params);
|
const editRole = (params)=>putAction("/sys/role/edit",params);
|
||||||
@ -39,7 +38,8 @@ const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",param
|
|||||||
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
|
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
|
||||||
const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params);
|
const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params);
|
||||||
const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params);
|
const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params);
|
||||||
const queryPermissionsByUser = (params)=>getAction("/sys/permission/queryByUser",params);
|
//const queryPermissionsByUser = (params)=>getAction("/sys/permission/queryByUser",params);
|
||||||
|
const queryPermissionsByUser = (params)=>getAction("/sys/permission/getUserPermissionByToken",params);
|
||||||
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
|
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
|
||||||
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
|
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
|
||||||
const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermissionRule",params);
|
const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermissionRule",params);
|
||||||
@ -130,7 +130,7 @@ export {
|
|||||||
queryUserByDepId,
|
queryUserByDepId,
|
||||||
queryUserRoleMap,
|
queryUserRoleMap,
|
||||||
duplicateCheck,
|
duplicateCheck,
|
||||||
queryTreeListForRole
|
queryTreeListForRole,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
/*列表上方操作按钮*/
|
/*列表上方操作按钮区域*/
|
||||||
.ant-card-body .table-operator {
|
.ant-card-body .table-operator {
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
/** Button按钮间距 */
|
||||||
|
.table-operator .ant-btn {
|
||||||
|
margin-right: 6px
|
||||||
|
}
|
||||||
/*列表td的padding设置 可以控制列表大小*/
|
/*列表td的padding设置 可以控制列表大小*/
|
||||||
.ant-table-tbody .ant-table-row td {
|
.ant-table-tbody .ant-table-row td {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
@ -26,4 +29,14 @@
|
|||||||
height: 90% !important;
|
height: 90% !important;
|
||||||
overflow-y: hidden
|
overflow-y: hidden
|
||||||
}
|
}
|
||||||
|
/*列表中有图片的加这个样式 参考用户管理*/
|
||||||
|
.anty-img-wrap {
|
||||||
|
height: 25px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.anty-img-wrap > img {
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
/*列表中范围查询样式*/
|
||||||
|
.query-group-cust{width: calc(50% - 10px)}
|
||||||
|
.query-group-split-cust:before{content:"~";width: 20px;display: inline-block;text-align: center}
|
||||||
BIN
ant-design-jeecg-vue/src/assets/pdf4.jpg
Normal file
BIN
ant-design-jeecg-vue/src/assets/pdf4.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
35
ant-design-jeecg-vue/src/components/bpm/DynamicComponent.vue
Normal file
35
ant-design-jeecg-vue/src/components/bpm/DynamicComponent.vue
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
<template>
|
||||||
|
<component ref="compModel" :is="comp" :formData="formData" v-if="comp" @ok="callBackOk" @close="callBackClose"></component>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'DynamicComponent',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
compName: this.path
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
comp: function () {
|
||||||
|
return () => import(`@/views/${this.compName}.vue`)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: ['path','formData'],
|
||||||
|
methods: {
|
||||||
|
add () {
|
||||||
|
this.$refs.compModel.add();
|
||||||
|
},
|
||||||
|
callBackClose () {
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
|
handleOk () {
|
||||||
|
this.$refs.compModel.handleOk();
|
||||||
|
},
|
||||||
|
callBackOk(){
|
||||||
|
this.$emit('ok');
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
72
ant-design-jeecg-vue/src/components/bpm/FormCommonModal.vue
Normal file
72
ant-design-jeecg-vue/src/components/bpm/FormCommonModal.vue
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:title="title"
|
||||||
|
:width="width"
|
||||||
|
:visible="visible"
|
||||||
|
:confirmLoading="confirmLoading"
|
||||||
|
@ok="handleOk"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
destroyOnClose
|
||||||
|
cancelText="关闭">
|
||||||
|
<a-spin :spinning="confirmLoading">
|
||||||
|
<dynamic-component ref="dynamiclink" :path="path" :formData="formData" @ok="callBackOk" @close="callBackClose"></dynamic-component>
|
||||||
|
</a-spin>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import DynamicComponent from "./DynamicComponent";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "FormCommonModal",
|
||||||
|
props: ['path'],
|
||||||
|
components: {
|
||||||
|
DynamicComponent
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"操作",
|
||||||
|
width:"80%",
|
||||||
|
visible: false,
|
||||||
|
confirmLoading: false,
|
||||||
|
formData:{},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
add () {
|
||||||
|
this.formData =[];
|
||||||
|
this.title = "新增";
|
||||||
|
this.visible = true;
|
||||||
|
this.$refs.dynamiclink.add();
|
||||||
|
},
|
||||||
|
edit (record) {
|
||||||
|
var data = {
|
||||||
|
dataId:record.id,
|
||||||
|
}
|
||||||
|
this.formData = data;
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
callBackClose () {
|
||||||
|
this.$emit('close');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleOk () {
|
||||||
|
this.$refs.dynamiclink.handleOk();
|
||||||
|
},
|
||||||
|
callBackOk(){
|
||||||
|
this.$emit('ok');
|
||||||
|
this.callBackClose();
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.callBackClose()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
120
ant-design-jeecg-vue/src/components/bpm/ProcNodeInfoModel.vue
Normal file
120
ant-design-jeecg-vue/src/components/bpm/ProcNodeInfoModel.vue
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:title="title"
|
||||||
|
:width="280"
|
||||||
|
:visible="visible"
|
||||||
|
:confirmLoading="confirmLoading"
|
||||||
|
:bodyStyle ="bodyStyle"
|
||||||
|
:mask = "false"
|
||||||
|
destroyOnClose
|
||||||
|
:footer="null"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
cancelText="关闭">
|
||||||
|
|
||||||
|
<a-spin :spinning="confirmLoading">
|
||||||
|
<div style="height: 300px;overflow: hidden;overflow-y: auto;overflow-x: auto;">
|
||||||
|
<template v-for="(item, key, index) in nodeInfos">
|
||||||
|
<table class="gridtable">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th width="90">任务名称</th>
|
||||||
|
<td width="150">{{ item.taskName}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="90">执行人</th>
|
||||||
|
<td width="150">{{ item.taskAssigneeId}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="90">开始时间</th>
|
||||||
|
<td width="150">{{ item.taskBeginTime }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="90">结束时间</th>
|
||||||
|
<td width="150">{{ item.taskEndTime }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="90">耗时</th>
|
||||||
|
<td width="150">{{ item.durationStr }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th width="90">意见</th>
|
||||||
|
<td width="150">{{ item.remarks }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { httpAction } from '@/api/manage'
|
||||||
|
import pick from 'lodash.pick'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ProcNodeInfoModel",
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"任务审批详情",
|
||||||
|
visible: false,
|
||||||
|
bodyStyle:{
|
||||||
|
padding: "0",
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
validatorRules:{
|
||||||
|
},
|
||||||
|
nodeInfos:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showInfo(record,taskId) {
|
||||||
|
this.nodeInfos = [];
|
||||||
|
for (var item of record) {
|
||||||
|
if(item.taskId == taskId){
|
||||||
|
this.nodeInfos.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.nodeInfos = [];
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.nodeInfos = [];
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
table.gridtable {
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-family: verdana,arial,sans-serif;
|
||||||
|
font-size:12px;
|
||||||
|
color:#333333;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
table.gridtable th {
|
||||||
|
border-width: 1px;
|
||||||
|
padding: 8px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #ddd;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
table.gridtable td {
|
||||||
|
border-width: 1px;
|
||||||
|
padding: 8px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #ddd;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
136
ant-design-jeecg-vue/src/components/bpm/ProcessInstPicModal.vue
Normal file
136
ant-design-jeecg-vue/src/components/bpm/ProcessInstPicModal.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:title="title"
|
||||||
|
:width="900"
|
||||||
|
:visible="visible"
|
||||||
|
:confirmLoading="confirmLoading"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
:bodyStyle="bodyStyle"
|
||||||
|
style="top: 50px;"
|
||||||
|
destroyOnClose
|
||||||
|
:footer="null"
|
||||||
|
cancelText="关闭">
|
||||||
|
|
||||||
|
<a-spin :spinning="confirmLoading">
|
||||||
|
<img :src="picUrl" alt="流程图" usemap="#planetmap"/>
|
||||||
|
<map name="planetmap">
|
||||||
|
<template v-for="(item, key, index) in nodePositionInfo.positionList">
|
||||||
|
<area shape="rect" :coords="item.coords" title="Venus" @mouseover="showNodeInfo(nodePositionInfo.hisTasks,item.id)">
|
||||||
|
</template>
|
||||||
|
</map>
|
||||||
|
</a-spin>
|
||||||
|
<proc-node-info-model ref="nodeInfoModel"></proc-node-info-model>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
import qs from 'qs';
|
||||||
|
import ProcNodeInfoModel from "./ProcNodeInfoModel.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {ProcNodeInfoModel},
|
||||||
|
name: "ProcessInstPicModal",
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"操作",
|
||||||
|
visible: false,
|
||||||
|
nodePositionInfo:{},
|
||||||
|
model: {},
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 5 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 16 },
|
||||||
|
},
|
||||||
|
bodyStyle:{
|
||||||
|
"overflow-y":"auto",
|
||||||
|
"overflow-x":"auto",
|
||||||
|
height:(window.innerHeight-280)+"px",
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
picUrl:"",
|
||||||
|
url: {
|
||||||
|
getProcessInfo: "/process/extActFlowData/getProcessInfo",
|
||||||
|
getNodePositionInfo:"/act/task/getNodePositionInfo",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
preview(flowCode,dataId){
|
||||||
|
this.visible = true;
|
||||||
|
var params = {
|
||||||
|
flowCode:flowCode,
|
||||||
|
dataId:dataId
|
||||||
|
};//查询条件
|
||||||
|
this.confirmLoading = true;
|
||||||
|
getAction(this.url.getProcessInfo,params).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
var processInstanceId = res.result.processInstanceId;
|
||||||
|
this.picUrl = this.getResourceURL(processInstanceId);
|
||||||
|
this.getNodePositionInfoData(processInstanceId);
|
||||||
|
console.log("---流程图----",this.picUrl)
|
||||||
|
}else{
|
||||||
|
this.$message.warning(res.message);
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
}).then(() => {
|
||||||
|
this.confirmLoading = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
close () {
|
||||||
|
this.$emit('close');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
// 获取静态资源访问地址
|
||||||
|
getResourceURL(processInstanceId) {
|
||||||
|
var params = qs.stringify({
|
||||||
|
//'token': Cookies.get('token'),
|
||||||
|
'_t': Date.parse(new Date())/1000,
|
||||||
|
'processInstanceId': processInstanceId
|
||||||
|
})
|
||||||
|
return `${window._CONFIG['domianURL']}/act/process/processPic?${params}`
|
||||||
|
},
|
||||||
|
// 获取静态资源访问地址
|
||||||
|
getResourceURL(processInstanceId) {
|
||||||
|
var params = qs.stringify({
|
||||||
|
//'token': Cookies.get('token'),
|
||||||
|
'_t': Date.parse(new Date())/1000,
|
||||||
|
'processInstanceId': processInstanceId
|
||||||
|
})
|
||||||
|
return `${window._CONFIG['domianURL']}/act/process/processPic?${params}`
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询坐标信息数据
|
||||||
|
getNodePositionInfoData(processInstanceId) {
|
||||||
|
var params = {processInstanceId:processInstanceId};//查询条件
|
||||||
|
getAction(this.url.getNodePositionInfo,params).then(res => {
|
||||||
|
if (res.success) {
|
||||||
|
this.nodePositionInfo = res.result
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
}).then(() => {
|
||||||
|
})
|
||||||
|
},
|
||||||
|
showNodeInfo(data,taskId){
|
||||||
|
this.$refs.nodeInfoModel.close();
|
||||||
|
this.$refs.nodeInfoModel.showInfo(data,taskId);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ padding: '0 0 32px 32px' }">
|
<div :style="{ padding: '0' }">
|
||||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||||
|
|
||||||
<v-chart ref="chart" :forceFit="true" :height="height" :data="dataSource" :scale="scale">
|
<v-chart ref="chart" :forceFit="true" :height="height" :data="dataSource" :scale="scale">
|
||||||
<v-tooltip/>
|
<v-tooltip :shared="false"/>
|
||||||
<v-axis/>
|
<v-axis/>
|
||||||
<v-line position="x*y" :size="lineSize"/>
|
<v-line position="x*y" :size="lineSize" :color="lineColor"/>
|
||||||
<v-area position="x*y"/>
|
<v-area position="x*y" :color="color"/>
|
||||||
</v-chart>
|
</v-chart>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -38,6 +38,16 @@
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'y'
|
default: 'y'
|
||||||
},
|
},
|
||||||
|
// Y轴最小值
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// Y轴最大值
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
// 图表高度
|
// 图表高度
|
||||||
height: {
|
height: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -47,13 +57,23 @@
|
|||||||
lineSize: {
|
lineSize: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 2
|
default: 2
|
||||||
|
},
|
||||||
|
// 面积的颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 线的颜色
|
||||||
|
lineColor: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
scale() {
|
scale() {
|
||||||
return [
|
return [
|
||||||
{ dataKey: 'x', title: this.x, alias: this.x },
|
{ dataKey: 'x', title: this.x, alias: this.x },
|
||||||
{ dataKey: 'y', title: this.y, alias: this.y }
|
{ dataKey: 'y', title: this.y, alias: this.y, min: this.min, max: this.max }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ padding: '0 0 32px 32px' }">
|
<div :style="{ padding: '0 0 32px 32px' }">
|
||||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||||
<v-chart :forceFit="true" :height="height" :data="dataSource" :padding="padding">
|
<v-chart :forceFit="true" :height="height" :data="dataSource" :scale="scale" :padding="padding">
|
||||||
<v-tooltip/>
|
<v-tooltip/>
|
||||||
<v-axis/>
|
<v-axis/>
|
||||||
<v-bar position="x*y"/>
|
<v-bar position="x*y"/>
|
||||||
@ -19,6 +19,10 @@
|
|||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
yaxisText: {
|
||||||
|
type: String,
|
||||||
|
default: 'y'
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
@ -31,6 +35,14 @@
|
|||||||
data() {
|
data() {
|
||||||
return { padding: ['auto', 'auto', '40', '50'] }
|
return { padding: ['auto', 'auto', '40', '50'] }
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
scale() {
|
||||||
|
return [{
|
||||||
|
dataKey: 'y',
|
||||||
|
alias: this.yaxisText
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
triggerWindowResizeEvent()
|
triggerWindowResizeEvent()
|
||||||
}
|
}
|
||||||
|
|||||||
57
ant-design-jeecg-vue/src/components/chart/BarAndLine.vue
Normal file
57
ant-design-jeecg-vue/src/components/chart/BarAndLine.vue
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<template>
|
||||||
|
<div :style="{ padding: '0 0 32px 32px' }">
|
||||||
|
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||||
|
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
|
||||||
|
<v-tooltip/>
|
||||||
|
<v-legend/>
|
||||||
|
<v-axis/>
|
||||||
|
<v-bar position="type*bar"/>
|
||||||
|
<v-line position="type*line" color="#2fc25b" :size="3"/>
|
||||||
|
</v-chart>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'BarMultid',
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
dataSource: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [
|
||||||
|
{ type: '10:10', bar: 2, line: 2 },
|
||||||
|
{ type: '10:15', bar: 6, line: 3 },
|
||||||
|
{ type: '10:20', bar: 2, line: 5 },
|
||||||
|
{ type: '10:25', bar: 9, line: 1 },
|
||||||
|
{ type: '10:30', bar: 2, line: 3 },
|
||||||
|
{ type: '10:35', bar: 2, line: 1 },
|
||||||
|
{ type: '10:40', bar: 1, line: 2 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 400
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
scale: [{
|
||||||
|
dataKey: 'bar',
|
||||||
|
min: 0
|
||||||
|
}, {
|
||||||
|
dataKey: 'line',
|
||||||
|
min: 0
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
data() {
|
||||||
|
return this.dataSource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ padding: '0 0 32px 32px' }">
|
<div :style="{ padding: '0 0 32px 32px' }">
|
||||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||||
<v-chart :forceFit="true" :height="height" :data="data" :padding="['auto', 'auto', '40', '50']">
|
<v-chart :forceFit="true" :height="height" :data="data">
|
||||||
<v-tooltip />
|
<v-tooltip />
|
||||||
<v-axis />
|
<v-axis />
|
||||||
<v-legend />
|
<v-legend />
|
||||||
@ -13,11 +13,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { DataSet } from '@antv/data-set'
|
import { DataSet } from '@antv/data-set'
|
||||||
|
|
||||||
const sourceDataConst = [
|
|
||||||
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
|
|
||||||
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }
|
|
||||||
];
|
|
||||||
const fieldsConst = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.'];
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BarMultid',
|
name: 'BarMultid',
|
||||||
props: {
|
props: {
|
||||||
@ -26,12 +21,15 @@
|
|||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
dataSource:{
|
dataSource:{
|
||||||
type:Array,
|
type: Array,
|
||||||
default:()=>[]
|
default: () => [
|
||||||
|
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
|
||||||
|
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
fields:{
|
fields:{
|
||||||
type:Array,
|
type: Array,
|
||||||
default:()=>[]
|
default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.']
|
||||||
},
|
},
|
||||||
height: {
|
height: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -40,35 +38,28 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data:"",
|
|
||||||
adjust: [{
|
adjust: [{
|
||||||
type: 'dodge',
|
type: 'dodge',
|
||||||
marginRatio: 1 / 32,
|
marginRatio: 1 / 32
|
||||||
}],
|
}]
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'dataSource': function () {
|
|
||||||
this.drawChart();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted(){
|
computed: {
|
||||||
this.drawChart()
|
data() {
|
||||||
},
|
const dv = new DataSet.View().source(this.dataSource)
|
||||||
methods:{
|
|
||||||
drawChart(){
|
|
||||||
let temp = sourceDataConst;
|
|
||||||
if(this.dataSource && this.dataSource.length>0){
|
|
||||||
temp = this.dataSource
|
|
||||||
}
|
|
||||||
const dv = new DataSet.View().source(temp);
|
|
||||||
dv.transform({
|
dv.transform({
|
||||||
type: 'fold',
|
type: 'fold',
|
||||||
fields:(!this.fields||this.fields.length==0)?fieldsConst:this.fields,
|
fields: this.fields,
|
||||||
key: 'x',
|
key: 'x',
|
||||||
value: 'y',
|
value: 'y'
|
||||||
});
|
})
|
||||||
this.data=dv.rows;
|
|
||||||
|
// bar 使用不了 - 和 / 所以替换下
|
||||||
|
return dv.rows.map(row => {
|
||||||
|
row.x = row.x.replace(/[-/]/g, '_')
|
||||||
|
return row
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ padding: '0 0 32px 32px' }">
|
<div :style="{ padding: '0 0 32px 32px' }">
|
||||||
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
|
<v-chart :forceFit="true" :height="350" :data="chartData" :scale="scale">
|
||||||
<v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord>
|
<v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord>
|
||||||
<v-axis
|
<v-axis
|
||||||
dataKey="value"
|
dataKey="value"
|
||||||
@ -45,7 +45,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {registerShape} from 'viser-vue';
|
import { registerShape } from 'viser-vue';
|
||||||
|
|
||||||
registerShape('point', 'pointer', {
|
registerShape('point', 'pointer', {
|
||||||
draw(cfg, container) {
|
draw(cfg, container) {
|
||||||
@ -87,67 +87,64 @@
|
|||||||
nice: false,
|
nice: false,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const sourceData = [
|
const data = [
|
||||||
{value: 6.7},
|
{ value: 7.0 },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DashChartDemo",
|
name:"DashChartDemo",
|
||||||
props: {
|
props:{
|
||||||
value: {
|
datasource:{
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 6.7
|
default:7
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: Number,
|
|
||||||
default: 254
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created(){
|
||||||
if (!this.value) {
|
if(!this.datasource){
|
||||||
this.data = sourceData;
|
this.chartData = data;
|
||||||
} else {
|
}else{
|
||||||
this.data = [
|
this.chartData = [
|
||||||
{value: this.value},
|
{ value: this.datasource },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
this.getData()
|
this.getChartData()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'value': function (val) {
|
'datasource': function (val) {
|
||||||
this.data = [
|
this.chartData = [
|
||||||
{value: val},
|
{ value: val},
|
||||||
];
|
];
|
||||||
this.getData();
|
this.getChartData();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods:{
|
||||||
getData() {
|
getChartData(){
|
||||||
if (this.data && this.data.length > 0) {
|
if(this.chartData && this.chartData.length>0){
|
||||||
this.abcd = this.data[0].value * 10
|
this.abcd = this.chartData[0].value * 10
|
||||||
} else {
|
}else{
|
||||||
this.abcd = 70
|
this.abcd = 70
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getHtmlGuideHtml() {
|
getHtmlGuideHtml(){
|
||||||
return '<div style="width: 300px;text-align: center;">\n' +
|
return '<div style="width: 300px;text-align: center;">\n' +
|
||||||
'<p style="font-size: 14px;color: #545454;margin: 0;">' + this.title + '</p>\n' +
|
'<p style="font-size: 14px;color: #545454;margin: 0;">'+this.title+'</p>\n' +
|
||||||
'<p style="font-size: 36px;color: #545454;margin: 0;">' + this.abcd + '%</p>\n' +
|
'<p style="font-size: 36px;color: #545454;margin: 0;">'+this.abcd+'%</p>\n' +
|
||||||
'</div>'
|
'</div>'
|
||||||
},
|
},
|
||||||
getArcGuide2End() {
|
getArcGuide2End(){
|
||||||
return [this.data[0].value, 0.945]
|
return [this.chartData[0].value, 0.945]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data: [],
|
chartData:[],
|
||||||
|
height: 400,
|
||||||
scale: scale,
|
scale: scale,
|
||||||
abcd: 70,
|
abcd:70,
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
offset: -16,
|
offset: -16,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ padding: '0 0 32px 32px' }">
|
<div :style="{ padding: '0 0 32px 32px' }">
|
||||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||||
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :padding="['auto', 'auto', '40', '50']">
|
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale">
|
||||||
<v-tooltip />
|
<v-tooltip/>
|
||||||
<v-axis />
|
<v-axis/>
|
||||||
<v-legend />
|
<v-legend/>
|
||||||
<v-line position="type*y" color="x" />
|
<v-line position="type*y" color="x"/>
|
||||||
<v-point position="type*y" color="x" :size="4" :v-style="style" :shape="'circle'" />
|
<v-point position="type*y" color="x" :size="4" :v-style="style" :shape="'circle'"/>
|
||||||
</v-chart>
|
</v-chart>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -14,23 +14,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { DataSet } from '@antv/data-set'
|
import { DataSet } from '@antv/data-set'
|
||||||
|
|
||||||
const sourceDataConst = [
|
|
||||||
{ type: 'Jan', jeecg: 7.0, jeebt: 3.9 },
|
|
||||||
{ type: 'Feb', jeecg: 6.9, jeebt: 4.2 },
|
|
||||||
{ type: 'Mar', jeecg: 9.5, jeebt: 5.7 },
|
|
||||||
{ type: 'Apr', jeecg: 14.5, jeebt: 8.5 },
|
|
||||||
{ type: 'May', jeecg: 18.4, jeebt: 11.9 },
|
|
||||||
{ type: 'Jun', jeecg: 21.5, jeebt: 15.2 },
|
|
||||||
{ type: 'Jul', jeecg: 25.2, jeebt: 17.0 },
|
|
||||||
{ type: 'Aug', jeecg: 26.5, jeebt: 16.6 },
|
|
||||||
{ type: 'Sep', jeecg: 23.3, jeebt: 14.2 },
|
|
||||||
{ type: 'Oct', jeecg: 18.3, jeebt: 10.3 },
|
|
||||||
{ type: 'Nov', jeecg: 13.9, jeebt: 6.6 },
|
|
||||||
{ type: 'Dec', jeecg: 9.6, jeebt: 4.8 }
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LineChartMultid',
|
name: 'LineChartMultid',
|
||||||
props: {
|
props: {
|
||||||
@ -38,58 +21,52 @@
|
|||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
dataSource:{
|
dataSource: {
|
||||||
type:Array,
|
type: Array,
|
||||||
default:()=>[]
|
default: () => [
|
||||||
|
{ type: 'Jan', jeecg: 7.0, jeebt: 3.9 },
|
||||||
|
{ type: 'Feb', jeecg: 6.9, jeebt: 4.2 },
|
||||||
|
{ type: 'Mar', jeecg: 9.5, jeebt: 5.7 },
|
||||||
|
{ type: 'Apr', jeecg: 14.5, jeebt: 8.5 },
|
||||||
|
{ type: 'May', jeecg: 18.4, jeebt: 11.9 },
|
||||||
|
{ type: 'Jun', jeecg: 21.5, jeebt: 15.2 },
|
||||||
|
{ type: 'Jul', jeecg: 25.2, jeebt: 17.0 },
|
||||||
|
{ type: 'Aug', jeecg: 26.5, jeebt: 16.6 },
|
||||||
|
{ type: 'Sep', jeecg: 23.3, jeebt: 14.2 },
|
||||||
|
{ type: 'Oct', jeecg: 18.3, jeebt: 10.3 },
|
||||||
|
{ type: 'Nov', jeecg: 13.9, jeebt: 6.6 },
|
||||||
|
{ type: 'Dec', jeecg: 9.6, jeebt: 4.8 }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
fields:{
|
fields: {
|
||||||
type:Array,
|
type: Array,
|
||||||
default: () => ['jeecg', 'jeebt']
|
default: () => ['jeecg', 'jeebt']
|
||||||
},
|
},
|
||||||
height:{
|
height: {
|
||||||
type:Number,
|
type: Number,
|
||||||
default:254
|
default: 254
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data:"",
|
|
||||||
scale: [{
|
scale: [{
|
||||||
dataKey: 'x',
|
dataKey: 'x',
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 1
|
max: 1
|
||||||
}],
|
}],
|
||||||
style: { stroke: '#fff', lineWidth: 1 },
|
style: { stroke: '#fff', lineWidth: 1 }
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'dataSource': function () {
|
|
||||||
this.drawChart();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted(){
|
computed: {
|
||||||
this.drawChart()
|
data() {
|
||||||
},
|
const dv = new DataSet.View().source(this.dataSource)
|
||||||
methods:{
|
|
||||||
drawChart(){
|
|
||||||
let temp = sourceDataConst;
|
|
||||||
if (this.dataSource && this.dataSource.length > 0) {
|
|
||||||
temp = this.dataSource.map(item => {
|
|
||||||
// 为了防止直接修改源数据导致报错
|
|
||||||
let obj = Object.assign({}, item)
|
|
||||||
obj.type = obj.x
|
|
||||||
return obj
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const dv = new DataSet.View().source(temp);
|
|
||||||
dv.transform({
|
dv.transform({
|
||||||
type: 'fold',
|
type: 'fold',
|
||||||
fields: this.fields,
|
fields: this.fields,
|
||||||
key: 'x',
|
key: 'x',
|
||||||
value: 'y',
|
value: 'y'
|
||||||
});
|
})
|
||||||
|
return dv.rows
|
||||||
this.data=dv.rows;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,20 +11,6 @@
|
|||||||
<script>
|
<script>
|
||||||
const DataSet = require('@antv/data-set')
|
const DataSet = require('@antv/data-set')
|
||||||
|
|
||||||
const sourceData = [
|
|
||||||
{ item: '事例一', percent: 40 },
|
|
||||||
{ item: '事例二', percent: 21 },
|
|
||||||
{ item: '事例三', percent: 17 },
|
|
||||||
{ item: '事例四', percent: 13 },
|
|
||||||
{ item: '事例五', percent: 9 }
|
|
||||||
]
|
|
||||||
|
|
||||||
const scale = [{
|
|
||||||
dataKey: 'percent',
|
|
||||||
min: 0,
|
|
||||||
formatter: '.0%'
|
|
||||||
}]
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
@ -37,37 +23,22 @@
|
|||||||
},
|
},
|
||||||
dataSource: {
|
dataSource: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => [
|
||||||
}
|
{ item: '示例一', count: 40 },
|
||||||
},
|
{ item: '示例二', count: 21 },
|
||||||
created() {
|
{ item: '示例三', count: 17 },
|
||||||
this.change()
|
{ item: '示例四', count: 13 },
|
||||||
},
|
{ item: '示例五', count: 9 }
|
||||||
watch: {
|
]
|
||||||
'dataSource': function() {
|
|
||||||
this.change()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
change() {
|
|
||||||
if (this.dataSource.length === 0) {
|
|
||||||
this.data = sourceData
|
|
||||||
} else {
|
|
||||||
const dv = new DataSet.View().source(this.dataSource)
|
|
||||||
dv.transform({
|
|
||||||
type: 'percent',
|
|
||||||
field: 'count',
|
|
||||||
dimension: 'item',
|
|
||||||
as: 'percent'
|
|
||||||
})
|
|
||||||
this.data = dv.rows
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data: '',
|
scale: [{
|
||||||
scale,
|
dataKey: 'percent',
|
||||||
|
min: 0,
|
||||||
|
formatter: '.0%'
|
||||||
|
}],
|
||||||
pieStyle: {
|
pieStyle: {
|
||||||
stroke: '#fff',
|
stroke: '#fff',
|
||||||
lineWidth: 1
|
lineWidth: 1
|
||||||
@ -78,6 +49,19 @@
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
data() {
|
||||||
|
let dv = new DataSet.View().source(this.dataSource)
|
||||||
|
// 计算数据百分比
|
||||||
|
dv.transform({
|
||||||
|
type: 'percent',
|
||||||
|
field: 'count',
|
||||||
|
dimension: 'item',
|
||||||
|
as: 'percent'
|
||||||
|
})
|
||||||
|
return dv.rows
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -35,6 +35,45 @@ import Bar from '@/components/chart/Bar'
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### 代码示例
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<bar title="柱状图" :dataSource="dataSource" :height="420"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Bar from '@/components/chart/Bar'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ChartDemo',
|
||||||
|
components: {
|
||||||
|
Bar
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dataSource: [
|
||||||
|
{
|
||||||
|
"x": "1月",
|
||||||
|
"y": 320
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "2月",
|
||||||
|
"y": 457
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "3月",
|
||||||
|
"y": 182
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
|
```
|
||||||
|
|
||||||
## 多列柱状图
|
## 多列柱状图
|
||||||
|
|
||||||
##### 引用方式
|
##### 引用方式
|
||||||
|
|||||||
@ -1,7 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-select :placeholder="placeholder" :value="value" @change="handleInput">
|
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="value" :disabled="disabled">
|
||||||
|
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
|
||||||
|
<a-select v-else-if="tagType=='select'" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput">
|
||||||
<a-select-option value="">请选择</a-select-option>
|
<a-select-option value="">请选择</a-select-option>
|
||||||
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-select-option>
|
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
|
||||||
|
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
|
||||||
|
{{ item.text || item.label }}
|
||||||
|
</span>
|
||||||
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -14,15 +22,23 @@
|
|||||||
dictCode: String,
|
dictCode: String,
|
||||||
placeholder: String,
|
placeholder: String,
|
||||||
triggerChange: Boolean,
|
triggerChange: Boolean,
|
||||||
value: String,// 1.接收一个 value prop
|
disabled: Boolean,
|
||||||
|
value: String,
|
||||||
|
type: String
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dictOptions: [],
|
dictOptions: [],
|
||||||
|
tagType:""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
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();
|
||||||
},
|
},
|
||||||
@ -36,13 +52,25 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleInput(val) {
|
handleInput(e) {
|
||||||
|
let val;
|
||||||
|
if(this.tagType=="radio"){
|
||||||
|
val = e.target.value
|
||||||
|
}else{
|
||||||
|
val = e
|
||||||
|
}
|
||||||
console.log(val);
|
console.log(val);
|
||||||
if(this.triggerChange){
|
if(this.triggerChange){
|
||||||
this.$emit('change', val);
|
this.$emit('change', val);
|
||||||
}else{
|
}else{
|
||||||
this.$emit('input', val);
|
this.$emit('input', val);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setCurrentDictOptions(dictOptions){
|
||||||
|
this.dictOptions = dictOptions
|
||||||
|
},
|
||||||
|
getCurrentDictOptions(){
|
||||||
|
return this.dictOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
ant-design-jeecg-vue/src/components/dict/JMultiSelectTag.vue
Normal file
92
ant-design-jeecg-vue/src/components/dict/JMultiSelectTag.vue
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<template>
|
||||||
|
<a-checkbox-group v-if="tagType=='checkbox'" @change="onChange" :value="arrayValue" :disabled="disabled">
|
||||||
|
<a-checkbox v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text || item.label }}</a-checkbox>
|
||||||
|
</a-checkbox-group>
|
||||||
|
|
||||||
|
<a-select
|
||||||
|
v-else-if="tagType=='select'"
|
||||||
|
:value="arrayValue"
|
||||||
|
@change="onChange"
|
||||||
|
:disabled="disabled"
|
||||||
|
mode="multiple"
|
||||||
|
:placeholder="placeholder">
|
||||||
|
<a-select-option
|
||||||
|
v-for="(item,index) in dictOptions"
|
||||||
|
:key="index"
|
||||||
|
:value="item.value">
|
||||||
|
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
|
||||||
|
{{ item.text || item.label }}
|
||||||
|
</span>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ajaxGetDictItems} from '@/api/api'
|
||||||
|
export default {
|
||||||
|
name: 'JMultiSelectTag',
|
||||||
|
props: {
|
||||||
|
dictCode: String,
|
||||||
|
placeholder: String,
|
||||||
|
triggerChange: Boolean,
|
||||||
|
disabled: Boolean,
|
||||||
|
value: String,
|
||||||
|
type: String,
|
||||||
|
options:Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dictOptions: [],
|
||||||
|
tagType:"",
|
||||||
|
arrayValue:!this.value?[]:this.value.split(",")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if(!this.type || this.type==="list_multi"){
|
||||||
|
this.tagType = "select"
|
||||||
|
}else{
|
||||||
|
this.tagType = this.type
|
||||||
|
}
|
||||||
|
//获取字典数据
|
||||||
|
this.initDictData();
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
value (val) {
|
||||||
|
if(!val){
|
||||||
|
this.arrayValue = []
|
||||||
|
}else{
|
||||||
|
this.arrayValue = this.value.split(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initDictData() {
|
||||||
|
if(this.options && this.options.length>0){
|
||||||
|
this.dictOptions = [...this.options]
|
||||||
|
}else{
|
||||||
|
//根据字典Code, 初始化字典数组
|
||||||
|
ajaxGetDictItems(this.dictCode, null).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
this.dictOptions = res.result;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onChange (selectedValue) {
|
||||||
|
if(this.triggerChange){
|
||||||
|
this.$emit('change', selectedValue.join(","));
|
||||||
|
}else{
|
||||||
|
this.$emit('input', selectedValue.join(","));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setCurrentDictOptions(dictOptions){
|
||||||
|
this.dictOptions = dictOptions
|
||||||
|
},
|
||||||
|
getCurrentDictOptions(){
|
||||||
|
return this.dictOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
170
ant-design-jeecg-vue/src/components/dict/JSearchSelectTag.vue
Normal file
170
ant-design-jeecg-vue/src/components/dict/JSearchSelectTag.vue
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<a-select
|
||||||
|
v-if="async"
|
||||||
|
showSearch
|
||||||
|
labelInValue
|
||||||
|
@search="loadData"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
v-model="selectedAsyncValue"
|
||||||
|
style="width: 100%"
|
||||||
|
:filterOption="false"
|
||||||
|
@change="handleAsyncChange"
|
||||||
|
: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>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<a-select
|
||||||
|
v-else
|
||||||
|
showSearch
|
||||||
|
:placeholder="placeholder"
|
||||||
|
optionFilterProp="children"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="handleChange"
|
||||||
|
:filterOption="filterOption"
|
||||||
|
v-model="selectedValue"
|
||||||
|
: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>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ajaxGetDictItems } from '@/api/api'
|
||||||
|
import debounce from 'lodash/debounce';
|
||||||
|
import { getAction } from '../../api/manage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JSearchSelectTag',
|
||||||
|
props:{
|
||||||
|
triggerChange: Boolean,
|
||||||
|
disabled: Boolean,
|
||||||
|
value: String,
|
||||||
|
dictCode: String,
|
||||||
|
dictOptions: Array,
|
||||||
|
async: Boolean,
|
||||||
|
placeholder:{
|
||||||
|
type:String,
|
||||||
|
default:"请选择",
|
||||||
|
required:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
this.loadData = debounce(this.loadData, 800);//消抖
|
||||||
|
this.lastLoad = 0;
|
||||||
|
return {
|
||||||
|
loading:false,
|
||||||
|
selectedValue:[],
|
||||||
|
selectedAsyncValue:[],
|
||||||
|
options: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.initDictData();
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
"value":{
|
||||||
|
immediate:true,
|
||||||
|
handler(val){
|
||||||
|
if(!val){
|
||||||
|
this.selectedValue=[]
|
||||||
|
this.selectedAsyncValue=[]
|
||||||
|
}else{
|
||||||
|
this.initSelectValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
initSelectValue(){
|
||||||
|
if(this.async){
|
||||||
|
if(!this.selectedAsyncValue || !this.selectedAsyncValue.key || this.selectedAsyncValue.key!=this.value){
|
||||||
|
console.log("这才请求后台")
|
||||||
|
getAction(`/sys/dict/loadDictItem/${this.dictCode}`,{key:this.value}).then(res=>{
|
||||||
|
if(res.success){
|
||||||
|
let obj = {
|
||||||
|
key:this.value,
|
||||||
|
label:res.result
|
||||||
|
}
|
||||||
|
this.selectedAsyncValue = {...obj}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
this.selectedValue = this.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadData(value){
|
||||||
|
console.log("数据加载",value)
|
||||||
|
this.lastLoad +=1
|
||||||
|
const currentLoad = this.lastLoad
|
||||||
|
this.options = []
|
||||||
|
this.loading=true
|
||||||
|
// 字典code格式:table,text,code
|
||||||
|
getAction(`/sys/dict/loadDict/${this.dictCode}`,{keyword:value}).then(res=>{
|
||||||
|
this.loading=false
|
||||||
|
if(res.success){
|
||||||
|
if(currentLoad!=this.lastLoad){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.options = res.result
|
||||||
|
console.log("我是第一个",res)
|
||||||
|
}else{
|
||||||
|
this.$message.warning(res.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
initDictData(){
|
||||||
|
if(!this.async){
|
||||||
|
//如果字典项集合有数据
|
||||||
|
if(this.dictOptions && this.dictOptions.length>0){
|
||||||
|
this.options = [...this.dictOptions]
|
||||||
|
}else{
|
||||||
|
//根据字典Code, 初始化字典数组
|
||||||
|
ajaxGetDictItems(this.dictCode, null).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
this.options = res.result;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterOption(input, option) {
|
||||||
|
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
},
|
||||||
|
handleChange (selectedValue) {
|
||||||
|
console.log("selectedValue",selectedValue)
|
||||||
|
this.selectedValue = selectedValue
|
||||||
|
this.callback()
|
||||||
|
},
|
||||||
|
handleAsyncChange(selectedObj){
|
||||||
|
this.selectedAsyncValue = selectedObj
|
||||||
|
this.selectedValue = selectedObj.key
|
||||||
|
this.callback()
|
||||||
|
},
|
||||||
|
callback(){
|
||||||
|
if(this.triggerChange){
|
||||||
|
this.$emit('change', this.selectedValue);
|
||||||
|
}else{
|
||||||
|
this.$emit('input', this.selectedValue);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setCurrentDictOptions(dictOptions){
|
||||||
|
this.options = dictOptions
|
||||||
|
},
|
||||||
|
getCurrentDictOptions(){
|
||||||
|
return this.options
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -15,6 +15,7 @@
|
|||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
/*label value*/
|
||||||
options:{
|
options:{
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
409
ant-design-jeecg-vue/src/components/jeecg/JCodeEditor.vue
Normal file
409
ant-design-jeecg-vue/src/components/jeecg/JCodeEditor.vue
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<template>
|
||||||
|
<div v-bind="fullScreenParentProps">
|
||||||
|
<a-icon v-if="fullScreen" class="full-screen-icon" type="fullscreen" @click="()=>fullCoder=!fullCoder"/>
|
||||||
|
|
||||||
|
<div class="code-editor-cust full-screen-child">
|
||||||
|
<textarea ref="textarea"></textarea>
|
||||||
|
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden':hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||||
|
<template v-if="languageChange">
|
||||||
|
<a-select v-model="mode" size="small" class="code-mode-select" @change="changeMode" placeholder="请选择主题">
|
||||||
|
<a-select-option
|
||||||
|
v-for="mode in modes"
|
||||||
|
:key="mode.value"
|
||||||
|
:value="mode.value">
|
||||||
|
{{ mode.label }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/ecmascript-6">
|
||||||
|
// 引入全局实例
|
||||||
|
import _CodeMirror from 'codemirror'
|
||||||
|
|
||||||
|
// 核心样式
|
||||||
|
import 'codemirror/lib/codemirror.css'
|
||||||
|
// 引入主题后还需要在 options 中指定主题才会生效 darcula gruvbox-dark hopscotch monokai
|
||||||
|
import 'codemirror/theme/panda-syntax.css'
|
||||||
|
//提示css
|
||||||
|
import "codemirror/addon/hint/show-hint.css";
|
||||||
|
|
||||||
|
// 需要引入具体的语法高亮库才会有对应的语法高亮效果
|
||||||
|
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
|
||||||
|
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入
|
||||||
|
import 'codemirror/mode/javascript/javascript.js'
|
||||||
|
import 'codemirror/mode/css/css.js'
|
||||||
|
import 'codemirror/mode/xml/xml.js'
|
||||||
|
import 'codemirror/mode/clike/clike.js'
|
||||||
|
import 'codemirror/mode/markdown/markdown.js'
|
||||||
|
import 'codemirror/mode/python/python.js'
|
||||||
|
import 'codemirror/mode/r/r.js'
|
||||||
|
import 'codemirror/mode/shell/shell.js'
|
||||||
|
import 'codemirror/mode/sql/sql.js'
|
||||||
|
import 'codemirror/mode/swift/swift.js'
|
||||||
|
import 'codemirror/mode/vue/vue.js'
|
||||||
|
|
||||||
|
// 尝试获取全局实例
|
||||||
|
const CodeMirror = window.CodeMirror || _CodeMirror
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JCodeEditor',
|
||||||
|
props: {
|
||||||
|
// 外部传入的内容,用于实现双向绑定
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 外部传入的语法类型
|
||||||
|
language: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
languageChange:{
|
||||||
|
type: Boolean,
|
||||||
|
default:false,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// 显示行号
|
||||||
|
lineNumbers: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否显示全屏按钮
|
||||||
|
fullScreen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 全屏以后的z-index
|
||||||
|
zIndex: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
// 内部真实的内容
|
||||||
|
code: '',
|
||||||
|
hasCode:false,
|
||||||
|
// 默认的语法类型
|
||||||
|
mode: 'javascript',
|
||||||
|
// 编辑器实例
|
||||||
|
coder: null,
|
||||||
|
// 默认配置
|
||||||
|
options: {
|
||||||
|
// 缩进格式
|
||||||
|
tabSize: 2,
|
||||||
|
// 主题,对应主题库 JS 需要提前引入
|
||||||
|
theme: 'panda-syntax',
|
||||||
|
line: true,
|
||||||
|
// extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
|
||||||
|
hintOptions: {
|
||||||
|
tables: {
|
||||||
|
users: ['name', 'score', 'birthDate'],
|
||||||
|
countries: ['name', 'population', 'size']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 支持切换的语法高亮类型,对应 JS 已经提前引入
|
||||||
|
// 使用的是 MIME-TYPE ,不过作为前缀的 text/ 在后面指定时写死了
|
||||||
|
modes: [{
|
||||||
|
value: 'css',
|
||||||
|
label: 'CSS'
|
||||||
|
}, {
|
||||||
|
value: 'javascript',
|
||||||
|
label: 'Javascript'
|
||||||
|
}, {
|
||||||
|
value: 'html',
|
||||||
|
label: 'XML/HTML'
|
||||||
|
}, {
|
||||||
|
value: 'x-java',
|
||||||
|
label: 'Java'
|
||||||
|
}, {
|
||||||
|
value: 'x-objectivec',
|
||||||
|
label: 'Objective-C'
|
||||||
|
}, {
|
||||||
|
value: 'x-python',
|
||||||
|
label: 'Python'
|
||||||
|
}, {
|
||||||
|
value: 'x-rsrc',
|
||||||
|
label: 'R'
|
||||||
|
}, {
|
||||||
|
value: 'x-sh',
|
||||||
|
label: 'Shell'
|
||||||
|
}, {
|
||||||
|
value: 'x-sql',
|
||||||
|
label: 'SQL'
|
||||||
|
}, {
|
||||||
|
value: 'x-swift',
|
||||||
|
label: 'Swift'
|
||||||
|
}, {
|
||||||
|
value: 'x-vue',
|
||||||
|
label: 'Vue'
|
||||||
|
}, {
|
||||||
|
value: 'markdown',
|
||||||
|
label: 'Markdown'
|
||||||
|
}],
|
||||||
|
// code 编辑器 是否全屏
|
||||||
|
fullCoder: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// value: {
|
||||||
|
// immediate: false,
|
||||||
|
// handler(value) {
|
||||||
|
// this._getCoder().then(() => {
|
||||||
|
// this.coder.setValue(value)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
language: {
|
||||||
|
immediate: true,
|
||||||
|
handler(language) {
|
||||||
|
this._getCoder().then(() => {
|
||||||
|
// 尝试从父容器获取语法类型
|
||||||
|
if (language) {
|
||||||
|
// 获取具体的语法类型对象
|
||||||
|
let modeObj = this._getLanguage(language)
|
||||||
|
|
||||||
|
// 判断父容器传入的语法是否被支持
|
||||||
|
if (modeObj) {
|
||||||
|
this.mode = modeObj.label
|
||||||
|
this.coder.setOption('mode', `text/${modeObj.value}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
placeholderShow() {
|
||||||
|
if (this.placeholder == null) {
|
||||||
|
return `请在此输入${this.language}代码`
|
||||||
|
} else {
|
||||||
|
return this.placeholder
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nullTipStyle(){
|
||||||
|
if (this.lineNumbers) {
|
||||||
|
return { left: '36px' }
|
||||||
|
} else {
|
||||||
|
return { left: '12px' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// coder 配置
|
||||||
|
coderOptions() {
|
||||||
|
return {
|
||||||
|
tabSize: this.options.tabSize,
|
||||||
|
theme: this.options.theme,
|
||||||
|
lineNumbers: this.lineNumbers,
|
||||||
|
line: true,
|
||||||
|
hintOptions: this.options.hintOptions
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fullScreenParentProps(){
|
||||||
|
let props = {
|
||||||
|
class: ['full-screen-parent', this.fullCoder ? 'full-screen' : ''],
|
||||||
|
style: {}
|
||||||
|
}
|
||||||
|
if (this.fullCoder) {
|
||||||
|
props.style['z-index'] = this.zIndex
|
||||||
|
}
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
// 初始化
|
||||||
|
this._initialize()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化
|
||||||
|
_initialize () {
|
||||||
|
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
|
||||||
|
this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.coderOptions)
|
||||||
|
// 编辑器赋值
|
||||||
|
this.coder.setValue(this.value || this.code)
|
||||||
|
if(this.value||this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
// 支持双向绑定
|
||||||
|
this.coder.on('change', (coder) => {
|
||||||
|
this.code = coder.getValue()
|
||||||
|
if(this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
if (this.$emit) {
|
||||||
|
this.$emit('input', this.code)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.coder.on('focus', () => {
|
||||||
|
this.hasCode=true
|
||||||
|
})
|
||||||
|
this.coder.on('blur', () => {
|
||||||
|
if(this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/* this.coder.on('cursorActivity',()=>{
|
||||||
|
this.coder.showHint()
|
||||||
|
})*/
|
||||||
|
|
||||||
|
},
|
||||||
|
getCodeContent(){
|
||||||
|
return this.code
|
||||||
|
},
|
||||||
|
setCodeContent(val){
|
||||||
|
this.coder.setValue(val)
|
||||||
|
},
|
||||||
|
// 获取当前语法类型
|
||||||
|
_getLanguage (language) {
|
||||||
|
// 在支持的语法类型列表中寻找传入的语法类型
|
||||||
|
return this.modes.find((mode) => {
|
||||||
|
// 所有的值都忽略大小写,方便比较
|
||||||
|
let currentLanguage = language.toLowerCase()
|
||||||
|
let currentLabel = mode.label.toLowerCase()
|
||||||
|
let currentValue = mode.value.toLowerCase()
|
||||||
|
|
||||||
|
// 由于真实值可能不规范,例如 java 的真实值是 x-java ,所以讲 value 和 label 同时和传入语法进行比较
|
||||||
|
return currentLabel === currentLanguage || currentValue === currentLanguage
|
||||||
|
})
|
||||||
|
},
|
||||||
|
_getCoder() {
|
||||||
|
let _this = this
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
(function get() {
|
||||||
|
if (_this.coder) {
|
||||||
|
resolve(_this.coder)
|
||||||
|
} else {
|
||||||
|
setTimeout(get, 10)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 更改模式
|
||||||
|
changeMode (val) {
|
||||||
|
// 修改编辑器的语法配置
|
||||||
|
this.coder.setOption('mode', `text/${val}`)
|
||||||
|
|
||||||
|
// 获取修改后的语法
|
||||||
|
let label = this._getLanguage(val).label.toLowerCase()
|
||||||
|
|
||||||
|
// 允许父容器通过以下函数监听当前的语法值
|
||||||
|
this.$emit('language-change', label)
|
||||||
|
},
|
||||||
|
nullTipClick(){
|
||||||
|
this.coder.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.code-editor-cust{
|
||||||
|
flex-grow:1;
|
||||||
|
display:flex;
|
||||||
|
position:relative;
|
||||||
|
height:100%;
|
||||||
|
.CodeMirror{
|
||||||
|
flex-grow:1;
|
||||||
|
z-index:1;
|
||||||
|
.CodeMirror-code{
|
||||||
|
line-height:19px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.code-mode-select{
|
||||||
|
position:absolute;
|
||||||
|
z-index:2;
|
||||||
|
right:10px;
|
||||||
|
top:10px;
|
||||||
|
max-width:130px;
|
||||||
|
}
|
||||||
|
.CodeMirror{
|
||||||
|
height: auto;
|
||||||
|
min-height:100%;
|
||||||
|
}
|
||||||
|
.null-tip{
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 36px;
|
||||||
|
z-index: 10;
|
||||||
|
color: #ffffffc9;
|
||||||
|
line-height: initial;
|
||||||
|
}
|
||||||
|
.null-tip-hidden{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 全屏样式 */
|
||||||
|
.full-screen-parent {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.full-screen-icon {
|
||||||
|
opacity: 0;
|
||||||
|
color: black;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 24px;
|
||||||
|
background-color: white;
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
right: 2px;
|
||||||
|
z-index: 9;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.full-screen-icon {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.88);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.full-screen {
|
||||||
|
position: fixed;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
height: calc(100% - 20px);
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
|
||||||
|
.full-screen-icon {
|
||||||
|
top: 12px;
|
||||||
|
right: 12px;
|
||||||
|
}
|
||||||
|
.full-screen-child {
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-screen-child {
|
||||||
|
min-height: 120px;
|
||||||
|
max-height: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -6,6 +6,7 @@
|
|||||||
:value="momVal"
|
:value="momVal"
|
||||||
:showTime="showTime"
|
:showTime="showTime"
|
||||||
:format="dateFormat"
|
:format="dateFormat"
|
||||||
|
:getCalendarContainer="getCalendarContainer"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -41,6 +42,10 @@
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
getCalendarContainer: {
|
||||||
|
type: Function,
|
||||||
|
default: () => document.body
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,11 @@
|
|||||||
type: String,
|
type: String,
|
||||||
required:false
|
required:false
|
||||||
},
|
},
|
||||||
|
triggerChange:{
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -82,7 +87,13 @@
|
|||||||
},
|
},
|
||||||
myValue(newValue) {
|
myValue(newValue) {
|
||||||
console.log(newValue)
|
console.log(newValue)
|
||||||
this.$emit('input', newValue)
|
if(this.triggerChange){
|
||||||
|
console.log(1)
|
||||||
|
this.$emit('change', newValue)
|
||||||
|
}else{
|
||||||
|
console.log(2)
|
||||||
|
this.$emit('input', newValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
163
ant-design-jeecg-vue/src/components/jeecg/JGraphicCode.vue
Normal file
163
ant-design-jeecg-vue/src/components/jeecg/JGraphicCode.vue
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<template>
|
||||||
|
<div class="gc-canvas" @click="reloadPic">
|
||||||
|
<canvas id="gc-canvas" :width="contentWidth" :height="contentHeight"></canvas>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'JGraphicCode',
|
||||||
|
props: {
|
||||||
|
length:{
|
||||||
|
type: Number,
|
||||||
|
default: 4
|
||||||
|
},
|
||||||
|
fontSizeMin: {
|
||||||
|
type: Number,
|
||||||
|
default: 20
|
||||||
|
},
|
||||||
|
fontSizeMax: {
|
||||||
|
type: Number,
|
||||||
|
default: 45
|
||||||
|
},
|
||||||
|
backgroundColorMin: {
|
||||||
|
type: Number,
|
||||||
|
default: 180
|
||||||
|
},
|
||||||
|
backgroundColorMax: {
|
||||||
|
type: Number,
|
||||||
|
default: 240
|
||||||
|
},
|
||||||
|
colorMin: {
|
||||||
|
type: Number,
|
||||||
|
default: 50
|
||||||
|
},
|
||||||
|
colorMax: {
|
||||||
|
type: Number,
|
||||||
|
default: 160
|
||||||
|
},
|
||||||
|
lineColorMin: {
|
||||||
|
type: Number,
|
||||||
|
default: 40
|
||||||
|
},
|
||||||
|
lineColorMax: {
|
||||||
|
type: Number,
|
||||||
|
default: 180
|
||||||
|
},
|
||||||
|
dotColorMin: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
dotColorMax: {
|
||||||
|
type: Number,
|
||||||
|
default: 255
|
||||||
|
},
|
||||||
|
contentWidth: {
|
||||||
|
type: Number,
|
||||||
|
default:136
|
||||||
|
},
|
||||||
|
contentHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 38
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 生成一个随机数
|
||||||
|
randomNum (min, max) {
|
||||||
|
return Math.floor(Math.random() * (max - min) + min)
|
||||||
|
},
|
||||||
|
// 生成一个随机的颜色
|
||||||
|
randomColor (min, max) {
|
||||||
|
let r = this.randomNum(min, max)
|
||||||
|
let g = this.randomNum(min, max)
|
||||||
|
let b = this.randomNum(min, max)
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
drawText (ctx, txt, i) {
|
||||||
|
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
|
||||||
|
let fontSize = this.randomNum(this.fontSizeMin, this.fontSizeMax)
|
||||||
|
ctx.font = fontSize + 'px SimHei'
|
||||||
|
let padding = 10;
|
||||||
|
let offset = (this.contentWidth-40)/(this.code.length-1)
|
||||||
|
let x=padding;
|
||||||
|
if(i>0){
|
||||||
|
x = padding+(i*offset)
|
||||||
|
}
|
||||||
|
//let x = (i + 1) * (this.contentWidth / (this.code.length + 1))
|
||||||
|
let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
|
||||||
|
if(fontSize>40){
|
||||||
|
y=40
|
||||||
|
}
|
||||||
|
var deg = this.randomNum(-10,10)
|
||||||
|
// 修改坐标原点和旋转角度
|
||||||
|
ctx.translate(x, y)
|
||||||
|
ctx.rotate(deg * Math.PI / 180)
|
||||||
|
ctx.fillText(txt, 0, 0)
|
||||||
|
// 恢复坐标原点和旋转角度
|
||||||
|
ctx.rotate(-deg * Math.PI / 180)
|
||||||
|
ctx.translate(-x, -y)
|
||||||
|
},
|
||||||
|
drawLine (ctx) {
|
||||||
|
// 绘制干扰线
|
||||||
|
for (let i = 0; i <1; i++) {
|
||||||
|
ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
|
||||||
|
ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drawDot (ctx) {
|
||||||
|
// 绘制干扰点
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
ctx.fillStyle = this.randomColor(0, 255)
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
|
||||||
|
ctx.fill()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reloadPic(){
|
||||||
|
this.drawPic()
|
||||||
|
},
|
||||||
|
randomCode(){
|
||||||
|
let random = ''
|
||||||
|
//去掉了I l i o O
|
||||||
|
let str = "QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm1234567890"
|
||||||
|
for(let i = 0; i < this.length; i++) {
|
||||||
|
let index = Math.floor(Math.random()*57);
|
||||||
|
random += str[index];
|
||||||
|
}
|
||||||
|
this.code = random
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.drawPic()
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
code:""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -4,7 +4,7 @@
|
|||||||
v-for="(item,index) in options"
|
v-for="(item,index) in options"
|
||||||
:key="index"
|
:key="index"
|
||||||
:value="item.value">
|
:value="item.value">
|
||||||
{{ item.text }}
|
{{ item.text || item.label }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
111
ant-design-jeecg-vue/src/components/jeecg/JSlider.vue
Normal file
111
ant-design-jeecg-vue/src/components/jeecg/JSlider.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div class="drag" ref="dragDiv">
|
||||||
|
<div class="drag_bg"></div>
|
||||||
|
<div class="drag_text">{{confirmWords}}</div>
|
||||||
|
<div ref="moveDiv" @mousedown="mousedownFn($event)" :class="{'handler_ok_bg':confirmSuccess}" class="handler handler_bg" style="border: 0.5px solid #fff;height: 34px;position: absolute;top: 0px;left: 0px;"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name:"JSlider",
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
beginClientX:0, /*距离屏幕左端距离*/
|
||||||
|
mouseMoveStata:false, /*触发拖动状态 判断*/
|
||||||
|
maxwidth:'', /*拖动最大宽度,依据滑块宽度算出来的*/
|
||||||
|
confirmWords:'拖动滑块验证', /*滑块文字*/
|
||||||
|
confirmSuccess:false /*验证成功判断*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
isSuccess(){
|
||||||
|
return this.confirmSuccess
|
||||||
|
},
|
||||||
|
mousedownFn:function (e) {
|
||||||
|
if(!this.confirmSuccess){
|
||||||
|
e.preventDefault && e.preventDefault(); //阻止文字选中等 浏览器默认事件
|
||||||
|
this.mouseMoveStata = true;
|
||||||
|
this.beginClientX = e.clientX;
|
||||||
|
}
|
||||||
|
}, //mousedoen 事件
|
||||||
|
successFunction(){
|
||||||
|
this.confirmSuccess = true
|
||||||
|
this.confirmWords = '验证通过';
|
||||||
|
if(window.addEventListener){
|
||||||
|
document.getElementsByTagName('html')[0].removeEventListener('mousemove',this.mouseMoveFn);
|
||||||
|
document.getElementsByTagName('html')[0].removeEventListener('mouseup',this.moseUpFn);
|
||||||
|
}else {
|
||||||
|
document.getElementsByTagName('html')[0].removeEventListener('mouseup',()=>{});
|
||||||
|
}
|
||||||
|
document.getElementsByClassName('drag_text')[0].style.color = '#fff'
|
||||||
|
document.getElementsByClassName('handler')[0].style.left = this.maxwidth + 'px';
|
||||||
|
document.getElementsByClassName('drag_bg')[0].style.width = this.maxwidth + 'px';
|
||||||
|
|
||||||
|
this.$emit("onSuccess",true)
|
||||||
|
}, //验证成功函数
|
||||||
|
mouseMoveFn(e){
|
||||||
|
if(this.mouseMoveStata){
|
||||||
|
let width = e.clientX - this.beginClientX;
|
||||||
|
if(width>0 && width<=this.maxwidth){
|
||||||
|
document.getElementsByClassName('handler')[0].style.left = width + 'px';
|
||||||
|
document.getElementsByClassName('drag_bg')[0].style.width = width + 'px';
|
||||||
|
}else if(width>this.maxwidth){
|
||||||
|
this.successFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, //mousemove事件
|
||||||
|
moseUpFn(e){
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
} //mouseup事件
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
this.maxwidth = this.$refs.dragDiv.clientWidth - this.$refs.moveDiv.clientWidth;
|
||||||
|
document.getElementsByTagName('html')[0].addEventListener('mousemove',this.mouseMoveFn);
|
||||||
|
document.getElementsByTagName('html')[0].addEventListener('mouseup',this.moseUpFn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.drag{
|
||||||
|
position: relative;
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
width: 100%;
|
||||||
|
height: 34px;
|
||||||
|
line-height: 34px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.handler{
|
||||||
|
width: 40px;
|
||||||
|
height: 32px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
.handler_bg{
|
||||||
|
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;
|
||||||
|
}
|
||||||
|
.handler_ok_bg{
|
||||||
|
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;
|
||||||
|
}
|
||||||
|
.drag_bg{
|
||||||
|
background-color: #7ac23c;
|
||||||
|
height: 34px;
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
.drag_text{
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
width: 100%;text-align: center;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-o-user-select:none;
|
||||||
|
-ms-user-select:none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
96
ant-design-jeecg-vue/src/components/jeecg/JTreeTable.vue
Normal file
96
ant-design-jeecg-vue/src/components/jeecg/JTreeTable.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<a-table
|
||||||
|
:rowKey="rowKey"
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="dataSource"
|
||||||
|
v-bind="tableProps"
|
||||||
|
@expand="handleExpand"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JTreeTable',
|
||||||
|
props: {
|
||||||
|
rowKey: {
|
||||||
|
type: String,
|
||||||
|
default: 'id'
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
childrenUrl: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
tableProps: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dataSource: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
getChildrenUrl() {
|
||||||
|
if (this.childrenUrl) {
|
||||||
|
return this.childrenUrl
|
||||||
|
} else {
|
||||||
|
return this.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
/** 加载数据*/
|
||||||
|
loadData(id = '0', first = true, url = this.url) {
|
||||||
|
return getAction(url, { id }).then(res => {
|
||||||
|
let dataSource = res.result.map(item => {
|
||||||
|
// 判断是否标记了带有子级
|
||||||
|
if (item.hasChildren === true) {
|
||||||
|
// 定义默认展开时显示的loading子级,实际子级数据只在展开时加载
|
||||||
|
let loadChild = { id: `${item.id}_loadChild`, name: 'loading...', isLoading: true }
|
||||||
|
item.children = [loadChild]
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
if (first) {
|
||||||
|
this.dataSource = dataSource
|
||||||
|
}
|
||||||
|
return Promise.resolve(dataSource)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 点击展开图标时触发 */
|
||||||
|
handleExpand(expanded, record) {
|
||||||
|
// 判断是否是展开状态
|
||||||
|
if (expanded) {
|
||||||
|
// 判断子级的首个项的标记是否是“正在加载中”,如果是就加载数据
|
||||||
|
if (record.children[0].isLoading === true) {
|
||||||
|
this.loadData(record.id, false, this.getChildrenUrl).then(dataSource => {
|
||||||
|
// 处理好的数据可直接赋值给children
|
||||||
|
record.children = dataSource
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
172
ant-design-jeecg-vue/src/components/jeecg/JUpload.vue
Normal file
172
ant-design-jeecg-vue/src/components/jeecg/JUpload.vue
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<template>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
:multiple="true"
|
||||||
|
:action="uploadAction"
|
||||||
|
:headers="headers"
|
||||||
|
:data="{'isup':1,'bizPath':bizPath}"
|
||||||
|
:fileList="fileList"
|
||||||
|
:beforeUpload="beforeUpload"
|
||||||
|
@change="handleChange">
|
||||||
|
<a-button>
|
||||||
|
<a-icon type="upload" />{{ text }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||||
|
|
||||||
|
const FILE_TYPE_ALL = "all"
|
||||||
|
const FILE_TYPE_IMG = "image"
|
||||||
|
const FILE_TYPE_TXT = "file"
|
||||||
|
const uidGenerator=()=>{
|
||||||
|
return '-'+parseInt(Math.random()*10000+1,10);
|
||||||
|
}
|
||||||
|
const getFileName=(path)=>{
|
||||||
|
if(path.lastIndexOf("\\")>=0){
|
||||||
|
let reg=new RegExp("\\\\","g");
|
||||||
|
path = path.replace(reg,"/");
|
||||||
|
}
|
||||||
|
return path.substring(path.lastIndexOf("/")+1);
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'JUpload',
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
|
||||||
|
urlDownload:window._CONFIG['domianURL'] + "/sys/common/download/",
|
||||||
|
headers:{},
|
||||||
|
fileList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
text:{
|
||||||
|
type:String,
|
||||||
|
required:false,
|
||||||
|
default:"点击上传"
|
||||||
|
},
|
||||||
|
fileType:{
|
||||||
|
type:String,
|
||||||
|
required:false,
|
||||||
|
default:FILE_TYPE_ALL
|
||||||
|
},
|
||||||
|
/*这个属性用于控制文件上传的业务路径*/
|
||||||
|
bizPath:{
|
||||||
|
type:String,
|
||||||
|
required:false,
|
||||||
|
default:"temp"
|
||||||
|
},
|
||||||
|
value:{
|
||||||
|
type:String,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
triggerChange:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
value(val){
|
||||||
|
this.initFileList(val)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
const token = Vue.ls.get(ACCESS_TOKEN);
|
||||||
|
this.headers = {"X-Access-Token":token}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods:{
|
||||||
|
initFileList(paths){
|
||||||
|
if(!paths || paths.length==0){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
let fileList = [];
|
||||||
|
let arr = paths.split(",")
|
||||||
|
for(var a=0;a<arr.length;a++){
|
||||||
|
fileList.push({
|
||||||
|
uid:uidGenerator(),
|
||||||
|
name:getFileName(arr[a]),
|
||||||
|
status: 'done',
|
||||||
|
url: this.urlDownload+arr[a],
|
||||||
|
response:{
|
||||||
|
status:"history",
|
||||||
|
message:arr[a]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.fileList = fileList
|
||||||
|
},
|
||||||
|
handlePathChange(){
|
||||||
|
let uploadFiles = this.fileList
|
||||||
|
let path = ''
|
||||||
|
if(!uploadFiles || uploadFiles.length==0){
|
||||||
|
path = ''
|
||||||
|
}
|
||||||
|
let arr = [];
|
||||||
|
|
||||||
|
for(var a=0;a<uploadFiles.length;a++){
|
||||||
|
arr.push(uploadFiles[a].response.message)
|
||||||
|
}
|
||||||
|
if(arr.length>0){
|
||||||
|
path = arr.join(",")
|
||||||
|
}
|
||||||
|
if(this.triggerChange){
|
||||||
|
this.$emit('change', path);
|
||||||
|
}else{
|
||||||
|
this.$emit('input', path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeUpload(file){
|
||||||
|
var fileType = file.type;
|
||||||
|
if(fileType===FILE_TYPE_IMG){
|
||||||
|
if(fileType.indexOf('image')<0){
|
||||||
|
this.$message.warning('请上传图片');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else if(fileType===FILE_TYPE_TXT){
|
||||||
|
if(fileType.indexOf('image')>=0){
|
||||||
|
this.$message.warning('请上传文件');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO 扩展功能验证文件大小
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
handleChange(info) {
|
||||||
|
console.log("--文件列表改变--")
|
||||||
|
let fileList = info.fileList
|
||||||
|
if(info.file.status==='done'){
|
||||||
|
if(info.file.response.success){
|
||||||
|
fileList = fileList.map((file) => {
|
||||||
|
if (file.response) {
|
||||||
|
file.url = this.urlDownload+file.response.message;
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.$message.success(`${info.file.name} 上传成功!`);
|
||||||
|
}else if (info.file.status === 'error') {
|
||||||
|
this.$message.error(`${info.file.name} 上传失败.`);
|
||||||
|
}else if(info.file.status === 'removed'){
|
||||||
|
this.handleDelete(info.file)
|
||||||
|
}
|
||||||
|
this.fileList = fileList
|
||||||
|
if(info.file.status==='done' || info.file.status === 'removed'){
|
||||||
|
this.handlePathChange()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleDelete(file){
|
||||||
|
//如有需要新增 删除逻辑
|
||||||
|
console.log(file)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -196,3 +196,87 @@ this.$refs.superQueryModal.show();
|
|||||||
modaltoggleFlag:true,
|
modaltoggleFlag:true,
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# <a-select/> 下拉选项滚动错位的解决方法
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
|
||||||
|
当使用了 `a-modal` 或其他带有滚动条的组件时,使用`a-select`组件并打开下拉框时滚动滚动条,就会导致错位的问题产生。
|
||||||
|
|
||||||
|
## 解决方法
|
||||||
|
|
||||||
|
大多数情况下,在 `a-select` 上添加一个 `getPopupContainer` 属性,值为`node => node.parentNode`即可解决。
|
||||||
|
但是如果遇到 `a-select` 标签层级过深的情况,可能仍然会显示异常,只需要多加几个`.parentNode` (例:node => node.parentNode.parentNode.parentNode)多尝试几次直到解决问题即可。
|
||||||
|
|
||||||
|
### 代码示例
|
||||||
|
|
||||||
|
```html
|
||||||
|
<a-select
|
||||||
|
placeholder="请选择展示模板"
|
||||||
|
:options="dicts.displayTemplate"
|
||||||
|
:getPopupContainer="node => node.parentNode"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
# JAsyncTreeList 异步数列表组件使用说明
|
||||||
|
|
||||||
|
## 引入组件
|
||||||
|
|
||||||
|
```js
|
||||||
|
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||||
|
export default {
|
||||||
|
components: { JTreeTable }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 所需参数
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|-------------|--------|-----|------------------------------------------------------------|
|
||||||
|
| rowKey | String | 非必填 | 表格行 key 的取值,默认为"id" |
|
||||||
|
| columns | Array | 必填 | 表格列的配置描述,具体见Antd官方文档 |
|
||||||
|
| url | String | 必填 | 数据查询url |
|
||||||
|
| childrenUrl | String | 非必填 | 查询子级时的url,若不填则使用url参数查询子级 |
|
||||||
|
| tableProps | Object | 非必填 | 自定义给内部table绑定的props |
|
||||||
|
|
||||||
|
## 代码示例
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<j-tree-table :url="url" :columns="columns" :tableProps="tableProps"/>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AsyncTreeTable',
|
||||||
|
components: { JTreeTable },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
url: '/api/asynTreeList',
|
||||||
|
columns: [
|
||||||
|
{ title: '菜单名称', dataIndex: 'name' },
|
||||||
|
{ title: '组件', dataIndex: 'component' },
|
||||||
|
{ title: '排序', dataIndex: 'orderNum' }
|
||||||
|
],
|
||||||
|
selectedRowKeys: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tableProps() {
|
||||||
|
let _this = this
|
||||||
|
return {
|
||||||
|
// 列表项是否可选择
|
||||||
|
// 配置项见:https://vue.ant.design/components/table-cn/#rowSelection
|
||||||
|
rowSelection: {
|
||||||
|
selectedRowKeys: _this.selectedRowKeys,
|
||||||
|
onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
@ -15,16 +15,16 @@
|
|||||||
|
|
||||||
### columns 参数详解
|
### columns 参数详解
|
||||||
|
|
||||||
| 参数 | 类型 | 必填 | 说明 |
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|---------------|--------|----|----------------------------------------------------------------------|
|
|---------------|--------|----|---------------------------------------------------------------------------------|
|
||||||
| title | string | ✔️ | 表格列头显示的问题 |
|
| title | string | ✔️ | 表格列头显示的问题 |
|
||||||
| key | string | ✔️ | 列数据在数据项中对应的 key,必须是唯一的 |
|
| key | string | ✔️ | 列数据在数据项中对应的 key,必须是唯一的 |
|
||||||
| type | string | ✔️ | 表单的类型,可以通过`JEditableTableUtil.FormTypes`赋值 |
|
| type | string | ✔️ | 表单的类型,可以通过`JEditableTableUtil.FormTypes`赋值 |
|
||||||
| width | string | | 列的宽度,可以是百分比,也可以是`px`或其他单位,建议设置为百分比,且每一列的宽度加起来不应超过100%,否则可能会不能达到预期的效果。留空会自动计算百分比 |
|
| width | string | | 列的宽度,可以是百分比,也可以是`px`或其他单位,建议设置为百分比,且每一列的宽度加起来不应超过100%,否则可能会不能达到预期的效果。留空会自动计算百分比 |
|
||||||
| placeholder | string | | 表单预期值的提示信息,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`) |
|
| placeholder | string | | 表单预期值的提示信息,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`) |
|
||||||
| defaultValue | string | | 默认值,在新增一行时生效 |
|
| defaultValue | string | | 默认值,在新增一行时生效 |
|
||||||
| validateRules | array | | 表单验证规则,配置方式见[validateRules 配置规则](#validaterules-配置规则) |
|
| validateRules | array | | 表单验证规则,配置方式见[validateRules 配置规则](#validaterules-配置规则) |
|
||||||
| props | object | | 设置添加给表单元素的自定义属性,例如:`props:{title: 'show title'}` |
|
| props | object | | 设置添加给表单元素的自定义属性,例如:`props:{title: 'show title'}` |
|
||||||
|
|
||||||
#### 当 type=checkbox 时所需的参数
|
#### 当 type=checkbox 时所需的参数
|
||||||
|
|
||||||
@ -41,10 +41,25 @@
|
|||||||
|
|
||||||
##### options 所需参数
|
##### options 所需参数
|
||||||
|
|
||||||
| 参数 | 类型 | 必填 | 说明 |
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|-------|--------|----|------|
|
|-----------|------------|----|-----------------------------------------------|
|
||||||
| title | string | ✔️ | 显示标题 |
|
| text | string | ✔️ | 显示标题 |
|
||||||
| value | string | ✔️ | 真实值 |
|
| value | string | ✔️ | 真实值 |
|
||||||
|
| ~~title~~ | ~~string~~ | | ~~显示标题(已废弃,若同时填写了 title 和 text 那么优先使用 text)~~ |
|
||||||
|
|
||||||
|
#### 当 type=upload 时所需的参数
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|--------------|---------|----|------------------------------------------------|
|
||||||
|
| action | string | ✔️ | 上传文件路径 |
|
||||||
|
| token | boolean | | 上传的时候是否传递token |
|
||||||
|
| responseName | string | ✔️ | 若要从上传成功后从response中取出返回的文件名,那么这里填后台返回的包含文件名的字段名 |
|
||||||
|
|
||||||
|
#### 当 type=slot 时所需的参数
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|--------------|---------|----|------------------------------------------------|
|
||||||
|
| slot | string | ✔️ | slot的名称 |
|
||||||
|
|
||||||
### validateRules 配置规则
|
### validateRules 配置规则
|
||||||
|
|
||||||
@ -128,18 +143,53 @@
|
|||||||
|----------|----------|----|-----------------------------------------------------------------------------------------------|
|
|----------|----------|----|-----------------------------------------------------------------------------------------------|
|
||||||
| callback | function | ✔️ | 获取值的回调方法,会传入`error`和`values`两个参数。`error`:未通过验证的数量,当等于`0`时代表验证通过;`values`:获取的值(即使未通过验证该字段也有数据) |
|
| callback | function | ✔️ | 获取值的回调方法,会传入`error`和`values`两个参数。`error`:未通过验证的数量,当等于`0`时代表验证通过;`values`:获取的值(即使未通过验证该字段也有数据) |
|
||||||
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
||||||
|
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||||
|
|
||||||
- `返回值:` 无
|
- `返回值:` 无
|
||||||
|
|
||||||
|
|
||||||
|
### getValuesSync
|
||||||
|
|
||||||
|
`getValues`的同步版,会直接将获取到的数据返回
|
||||||
|
|
||||||
|
- `参数:`
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|---------|--------|----|-------------|
|
||||||
|
| options | object | | 选项,详见下方所需参数 |
|
||||||
|
|
||||||
|
- - `options` 所需参数
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|----------|---------|----|--------------------------------------------------------------------|
|
||||||
|
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
||||||
|
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||||
|
|
||||||
|
- `返回值:` object
|
||||||
|
- `error` 未通过验证的数量,当等于`0`时代表验证通过
|
||||||
|
- `values` 获取的值(即使未通过验证该字段也有数据)
|
||||||
|
|
||||||
|
- `使用示例`
|
||||||
|
|
||||||
|
```js
|
||||||
|
let { error, values } = this.$refs.editableTable.getValuesSync({ validate: true, rowIds: ['rowId1', 'rowId2'] })
|
||||||
|
if (error === 0) {
|
||||||
|
console.log('表单验证通过,数据:', values);
|
||||||
|
} else {
|
||||||
|
console.log('未通过表单验证,数据:', values);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### getValuesPromise
|
### getValuesPromise
|
||||||
|
|
||||||
`getValues`的promise版,会在`resolve`中传入获取到的值,会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
|
`getValues`的promise版,会在`resolve`中传入获取到的值,会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
|
||||||
|
|
||||||
- `参数:`
|
- `参数:`
|
||||||
|
|
||||||
| 参数名 | 类型 | 必填 | 说明 |
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|----------|---------|----|---------------------------|
|
|----------|---------|----|--------------------------------------------------------------------|
|
||||||
| validate | boolean | | 同`getValues`的`validate`参数 |
|
| validate | boolean | | 同`getValues`的`validate`参数 |
|
||||||
|
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||||
|
|
||||||
- `返回值:` Promise
|
- `返回值:` Promise
|
||||||
|
|
||||||
@ -219,6 +269,8 @@ setValues([
|
|||||||
- `select` 显示选择器(下拉框)
|
- `select` 显示选择器(下拉框)
|
||||||
- `date` 日期选择器
|
- `date` 日期选择器
|
||||||
- `datetime` 日期时间选择器
|
- `datetime` 日期时间选择器
|
||||||
|
- `upload` 上传组件(文件域)
|
||||||
|
- `slot` 自定义插槽
|
||||||
|
|
||||||
### VALIDATE_NO_PASSED
|
### VALIDATE_NO_PASSED
|
||||||
|
|
||||||
@ -284,7 +336,7 @@ validateTables(cases).then((all) => {
|
|||||||
### 为什么使用了ATab组件后,切换选项卡会导致白屏或滚动条位置会归零?
|
### 为什么使用了ATab组件后,切换选项卡会导致白屏或滚动条位置会归零?
|
||||||
|
|
||||||
在ATab组件中确实会导致滚动条位置归零,且不会触发`onscroll`方法,所以无法动态加载行,导致白屏的问题出现。
|
在ATab组件中确实会导致滚动条位置归零,且不会触发`onscroll`方法,所以无法动态加载行,导致白屏的问题出现。
|
||||||
解决方法是在ATab组件的`onChange`事件触发时执行`resetScrollTop()`即可,但是需要注意的是:代码主动改变ATab的`activeKey`不会触发`onChange`事件,还需要你手动调用下
|
解决方法是在ATab组件的`onChange`事件触发时执行实例提供的`resetScrollTop()`方法即可,但是需要注意的是:代码主动改变ATab的`activeKey`不会触发`onChange`事件,还需要你手动调用下。
|
||||||
|
|
||||||
- `示例`
|
- `示例`
|
||||||
|
|
||||||
@ -322,7 +374,11 @@ methods: {
|
|||||||
/*--- 忽略部分代码片段 ---*/
|
/*--- 忽略部分代码片段 ---*/
|
||||||
```
|
```
|
||||||
|
|
||||||
----
|
### slot(自定义插槽)如何使用?
|
||||||
|
|
||||||
|
代码示例请看:[示例四(slot)](#示例四(slot))
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
## 示例一
|
## 示例一
|
||||||
|
|
||||||
@ -393,4 +449,57 @@ this.$refs.editableTable.getValues((error, values) => {
|
|||||||
this.$message.error('验证未通过')
|
this.$message.error('验证未通过')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## 示例四(slot)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<j-editable-table :columns="columns" :dataSource="dataSource">
|
||||||
|
<!-- 定义插槽 -->
|
||||||
|
<!-- 这种定义插槽的写法是vue推荐的新版写法(https://cn.vuejs.org/v2/guide/components-slots.html#具名插槽),旧版已被废弃的写法不再支持 -->
|
||||||
|
<!-- 若webstorm这样写报错,请看这篇文章:https://blog.csdn.net/lxq_9532/article/details/81870651 -->
|
||||||
|
<template v-slot:action="props">
|
||||||
|
<a @click="handleDelete(props)">删除</a>
|
||||||
|
</template>
|
||||||
|
</j-editable-table>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||||
|
import JEditableTable from '@/components/jeecg/JEditableTable'
|
||||||
|
export default {
|
||||||
|
components: { JEditableTable },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
columns: [
|
||||||
|
// ...
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: '8%',
|
||||||
|
type: FormTypes.slot, // 定义该列为 自定义插值列
|
||||||
|
slot: 'action' // slot 的名称,对应 v-slot 冒号后面和等号前面的内容
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/* a 标签的点击事件,删除当前选中的行 */
|
||||||
|
handleDelete(props) {
|
||||||
|
// 参数解释
|
||||||
|
// props.text :当前值,可能是defaultValue定义的值,也可能是从dataSource中取出的值
|
||||||
|
// props.rowId :当前选中行的id,如果是新增行则是临时id
|
||||||
|
// props.column :当前操作的列
|
||||||
|
// props.getValue :这是一个function,执行后可以获取当前行的所有值(禁止在template中使用)
|
||||||
|
// 例:const value = props.getValue()
|
||||||
|
// props.target :触发当前事件的实例,可直接调用该实例内的方法(禁止在template中使用)
|
||||||
|
// 例:target.add()
|
||||||
|
|
||||||
|
// 使用实例:删除当前操作的行
|
||||||
|
let { rowId, target } = props
|
||||||
|
target.removeRows(rowId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
@ -29,7 +29,7 @@
|
|||||||
用户账号:
|
用户账号:
|
||||||
<a-input-search
|
<a-input-search
|
||||||
:style="{width:'150px',marginBottom:'15px'}"
|
:style="{width:'150px',marginBottom:'15px'}"
|
||||||
placeholder="请输入用户名搜索"
|
placeholder="请输入用户账号"
|
||||||
v-model="queryParam.username"
|
v-model="queryParam.username"
|
||||||
@search="onSearch"
|
@search="onSearch"
|
||||||
></a-input-search>
|
></a-input-search>
|
||||||
@ -194,13 +194,13 @@
|
|||||||
},
|
},
|
||||||
searchReset(num) {
|
searchReset(num) {
|
||||||
let that = this;
|
let that = this;
|
||||||
|
if(num !== 0){
|
||||||
|
that.queryParam = {};
|
||||||
|
that.loadData(1);
|
||||||
|
}
|
||||||
that.selectedRowKeys = [];
|
that.selectedRowKeys = [];
|
||||||
that.userNameArr = [];
|
that.userNameArr = [];
|
||||||
that.queryParam = {};
|
|
||||||
that.selectedKeys = [];
|
that.selectedKeys = [];
|
||||||
if(num !== 0){
|
|
||||||
that.loadData();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.searchReset(0);
|
this.searchReset(0);
|
||||||
|
|||||||
125
ant-design-jeecg-vue/src/components/jeecgbiz/JSelectDepart.vue
Normal file
125
ant-design-jeecg-vue/src/components/jeecgbiz/JSelectDepart.vue
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<div class="components-input-demo-presuffix">
|
||||||
|
<!---->
|
||||||
|
<a-input @click="openModal" placeholder="请点击选择部门" v-model="departNames" readOnly :disabled="disabled">
|
||||||
|
<a-icon slot="prefix" type="cluster" title="部门选择控件"/>
|
||||||
|
<a-icon v-if="departIds" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||||
|
</a-input>
|
||||||
|
|
||||||
|
<j-select-depart-modal
|
||||||
|
ref="innerDepartSelectModal"
|
||||||
|
:modal-width="modalWidth"
|
||||||
|
:multi="multi"
|
||||||
|
:rootOpened="rootOpened"
|
||||||
|
:depart-id="value"
|
||||||
|
@ok="handleOK"
|
||||||
|
@initComp="initComp"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JSelectDepartModal from './modal/JSelectDepartModal'
|
||||||
|
export default {
|
||||||
|
name: 'JSelectDepart',
|
||||||
|
components:{
|
||||||
|
JSelectDepartModal
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
modalWidth:{
|
||||||
|
type:Number,
|
||||||
|
default:500,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
multi:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
rootOpened:{
|
||||||
|
type:Boolean,
|
||||||
|
default:true,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
value:{
|
||||||
|
type:String,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
triggerChange:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
disabled:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
visible:false,
|
||||||
|
confirmLoading:false,
|
||||||
|
departNames:"",
|
||||||
|
departIds:''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
this.departIds = this.value
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
value(val){
|
||||||
|
this.departIds = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
initComp(departNames){
|
||||||
|
this.departNames = departNames
|
||||||
|
},
|
||||||
|
openModal(){
|
||||||
|
this.$refs.innerDepartSelectModal.show()
|
||||||
|
},
|
||||||
|
handleOK(rows,idstr){
|
||||||
|
console.log("当前选中部门",rows)
|
||||||
|
console.log("当前选中部门ID",idstr)
|
||||||
|
if(!rows){
|
||||||
|
this.departNames = ''
|
||||||
|
this.departIds=''
|
||||||
|
}else{
|
||||||
|
let temp = ''
|
||||||
|
for(let item of rows){
|
||||||
|
temp+=','+item.departName
|
||||||
|
}
|
||||||
|
this.departNames = temp.substring(1)
|
||||||
|
this.departIds=idstr
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.triggerChange){
|
||||||
|
this.$emit("change",this.departIds)
|
||||||
|
}else{
|
||||||
|
this.$emit("input",this.departIds)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDepartNames(){
|
||||||
|
return this.departNames
|
||||||
|
},
|
||||||
|
handleEmpty(){
|
||||||
|
this.handleOK('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.components-input-demo-presuffix .anticon-close-circle {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #ccc;
|
||||||
|
transition: color 0.3s;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.components-input-demo-presuffix .anticon-close-circle:hover {
|
||||||
|
color: #f5222d;
|
||||||
|
}
|
||||||
|
.components-input-demo-presuffix .anticon-close-circle:active {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div style="width: 100%;">
|
||||||
|
<a-select
|
||||||
|
mode="multiple"
|
||||||
|
placeholder="Please select"
|
||||||
|
:value="nameList"
|
||||||
|
style="width: calc(100% - 178px);">
|
||||||
|
</a-select>
|
||||||
|
<span style="display: inline-block;width:170px;float: right;overflow: hidden;">
|
||||||
|
<a-button type="primary" @click="handleSelect" icon="search" style="width: 81px">选择</a-button>
|
||||||
|
<a-button type="primary" @click="selectReset" icon="reload" style="margin-left: 8px;width: 81px">清空</a-button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 选择多个用户支持排序 -->
|
||||||
|
<j-select-multi-user-modal ref="selectModal" @selectFinished="selectOK"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JSelectMultiUserModal from './modal/JSelectMultiUserModal'
|
||||||
|
export default {
|
||||||
|
name: 'JSelectMultiUser',
|
||||||
|
components:{ JSelectMultiUserModal },
|
||||||
|
props:{
|
||||||
|
value:{
|
||||||
|
type:String,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
triggerChange:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
selectList: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
nameList: function () {
|
||||||
|
var names = [];
|
||||||
|
for (var a = 0; a < this.selectList.length; a++) {
|
||||||
|
names.push(this.selectList[a].name);
|
||||||
|
}
|
||||||
|
let nameStr = ''
|
||||||
|
if(names.length>0){
|
||||||
|
nameStr = names.join(",")
|
||||||
|
}
|
||||||
|
if(this.triggerChange){
|
||||||
|
this.$emit("change",nameStr)
|
||||||
|
}else{
|
||||||
|
this.$emit("input",nameStr)
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
handleSelect: function () {
|
||||||
|
this.$refs.selectModal.add();
|
||||||
|
},
|
||||||
|
selectReset() {
|
||||||
|
this.selectList = [];
|
||||||
|
},
|
||||||
|
selectOK: function (data) {
|
||||||
|
this.selectList = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
cancelText="关闭">
|
cancelText="关闭">
|
||||||
<a-row :gutter="18">
|
<a-row :gutter="18">
|
||||||
<a-col :span="16">
|
<a-col :span="16">
|
||||||
<a-card title="选择人员" :bordered=true>
|
<a-card title="选择人员" :bordered="true">
|
||||||
<!-- 查询区域 -->
|
<!-- 查询区域 -->
|
||||||
<div class="table-page-search-wrapper">
|
<div class="table-page-search-wrapper">
|
||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
@ -51,7 +51,7 @@
|
|||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-card title="用户选择" :bordered=true>
|
<a-card title="用户选择" :bordered="true">
|
||||||
<!-- table区域-begin -->
|
<!-- table区域-begin -->
|
||||||
<div>
|
<div>
|
||||||
<a-table
|
<a-table
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-input-search
|
||||||
|
v-model="selectedDepUsers"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JSelectUserByDepModal from './modal/JSelectUserByDepModal'
|
||||||
|
export default {
|
||||||
|
name: 'JSelectUserByDep',
|
||||||
|
components: { JSelectUserByDepModal },
|
||||||
|
props:{
|
||||||
|
modalWidth:{
|
||||||
|
type:Number,
|
||||||
|
default:1250,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
value:{
|
||||||
|
type:String,
|
||||||
|
required:false
|
||||||
|
},
|
||||||
|
triggerChange:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
disabled:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedDepUsers:"",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
this.selectedDepUsers = this.value
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
value(val){
|
||||||
|
this.selectedDepUsers = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//通过组织机构筛选选择用户
|
||||||
|
onSearchDepUser() {
|
||||||
|
this.$refs.selectModal.showModal()
|
||||||
|
this.onSearchDepUserCallBack('')
|
||||||
|
},
|
||||||
|
onSearchDepUserCallBack(selectedDepUsers) {
|
||||||
|
this.selectedDepUsers = selectedDepUsers
|
||||||
|
if(this.triggerChange){
|
||||||
|
this.$emit("change",selectedDepUsers)
|
||||||
|
}else{
|
||||||
|
this.$emit("input",selectedDepUsers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -1,308 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
:width="modalWidth"
|
|
||||||
:visible="visible"
|
|
||||||
:title="title"
|
|
||||||
@ok="handleSubmit"
|
|
||||||
@cancel="close"
|
|
||||||
cancelText="关闭"
|
|
||||||
style="margin-top: -70px"
|
|
||||||
wrapClassName="ant-modal-cust-warp"
|
|
||||||
>
|
|
||||||
<a-row :gutter="10" style="background-color: #ececec; padding: 10px; margin: -10px">
|
|
||||||
<a-col :md="6" :sm="24">
|
|
||||||
<a-card :bordered="false">
|
|
||||||
<!--组织机构-->
|
|
||||||
<a-directory-tree
|
|
||||||
selectable
|
|
||||||
:selectedKeys="selectedKeys"
|
|
||||||
:checkStrictly="true"
|
|
||||||
@select="this.onSelect"
|
|
||||||
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
|
|
||||||
:treeData="departTree"
|
|
||||||
/>
|
|
||||||
</a-card>
|
|
||||||
</a-col>
|
|
||||||
<a-col :md="18" :sm="24">
|
|
||||||
<a-card :bordered="false">
|
|
||||||
用户账号:
|
|
||||||
<a-input-search
|
|
||||||
:style="{width:'150px',marginBottom:'15px'}"
|
|
||||||
placeholder=""
|
|
||||||
v-model="queryParam.username"
|
|
||||||
@search="onSearch"
|
|
||||||
/>
|
|
||||||
<a-button @click="searchReset" style="margin-left: 10px" icon="redo">重置</a-button>
|
|
||||||
<!--用户列表-->
|
|
||||||
<a-table
|
|
||||||
ref="table"
|
|
||||||
:scroll="scrollTrigger"
|
|
||||||
size="middle"
|
|
||||||
rowKey="id"
|
|
||||||
:columns="columns"
|
|
||||||
:dataSource="dataSource"
|
|
||||||
:pagination="ipagination"
|
|
||||||
style="background-color: white"
|
|
||||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
|
||||||
@change="handleTableChange">
|
|
||||||
</a-table>
|
|
||||||
</a-card>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { filterObj } from '@/utils/util'
|
|
||||||
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'SearchUserByDepModal',
|
|
||||||
components: {
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
queryParam: {},
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
title: '用户账号',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'username'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '真实姓名',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'realname'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '角色名称',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'roleName'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '性别',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'sex',
|
|
||||||
customRender: function(text) {
|
|
||||||
if (text === 1) {
|
|
||||||
return '男'
|
|
||||||
} else if (text === 2) {
|
|
||||||
return '女'
|
|
||||||
} else {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '手机号码',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'phone'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '邮箱',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'email'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
scrollTrigger:{},
|
|
||||||
dataSource: [],
|
|
||||||
selectedKeys: [],
|
|
||||||
userNames: [],
|
|
||||||
departName: '',
|
|
||||||
userRolesMap: {},
|
|
||||||
title: '',
|
|
||||||
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'
|
|
||||||
},
|
|
||||||
selectedRowKeys: [],
|
|
||||||
selectedRows: [],
|
|
||||||
userData: [],
|
|
||||||
modalWidth: 1250,
|
|
||||||
departTree: [],
|
|
||||||
visible: false,
|
|
||||||
form: this.$form.createForm(this),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 该方法触发屏幕自适应
|
|
||||||
this.resetScreenSize();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadData(arg) {
|
|
||||||
if (arg === 1) {
|
|
||||||
this.ipagination.current = 1;
|
|
||||||
}
|
|
||||||
let params = this.getQueryParams();//查询条件
|
|
||||||
getUserList(params).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.dataSource = res.result.records;
|
|
||||||
this.assignRoleName(this.dataSource);
|
|
||||||
this.userData = res.result.records;
|
|
||||||
this.ipagination.total = res.result.total;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
queryUserRoleMap().then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.userRolesMap = res.result;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 触发屏幕自适应
|
|
||||||
resetScreenSize(){
|
|
||||||
let screenWidth = document.body.clientWidth;
|
|
||||||
if(screenWidth < 500){
|
|
||||||
this.scrollTrigger = {x : 800};
|
|
||||||
}else{
|
|
||||||
this.scrollTrigger = {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showModal() {
|
|
||||||
this.visible = true;
|
|
||||||
this.assignRoleName(this.dataSource);
|
|
||||||
this.queryDepartTree();
|
|
||||||
this.form.resetFields();
|
|
||||||
this.loadData(1);
|
|
||||||
},
|
|
||||||
getQueryParams() {
|
|
||||||
let 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() {
|
|
||||||
let str = 'id,';
|
|
||||||
for (let a = 0; a < this.columns.length; a++) {
|
|
||||||
str += ',' + this.columns[a].dataIndex;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
searchReset(num) {
|
|
||||||
let that = this;
|
|
||||||
if(num !== 0){
|
|
||||||
that.loadData(1);
|
|
||||||
}
|
|
||||||
that.selectedRowKeys = [];
|
|
||||||
that.userNames = [];
|
|
||||||
that.queryParam = {};
|
|
||||||
that.selectedKeys = [];
|
|
||||||
that.userNames = [];
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.$emit('close');
|
|
||||||
this.searchReset(0);
|
|
||||||
this.visible = false;
|
|
||||||
},
|
|
||||||
handleTableChange(pagination, filters, 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();
|
|
||||||
},
|
|
||||||
handleSubmit() {
|
|
||||||
const that = this;
|
|
||||||
for (let i = 0, len = this.selectedRowKeys.length; i < len; i++) {
|
|
||||||
this.getUserNames(this.selectedRowKeys[i]);
|
|
||||||
}
|
|
||||||
that.$emit('ok', that.userNames.join(','));
|
|
||||||
that.close();
|
|
||||||
},
|
|
||||||
// 遍历匹配,获取用户真实姓名
|
|
||||||
getUserNames(rowId) {
|
|
||||||
let dataSource = this.dataSource;
|
|
||||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
|
||||||
if (rowId === dataSource[i].id) {
|
|
||||||
this.userNames.push(dataSource[i].realname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 点击树节点,筛选出对应的用户
|
|
||||||
onSelect(selectedKeys) {
|
|
||||||
if (selectedKeys[0] != null) {
|
|
||||||
this.queryUser(selectedKeys) // 调用方法根据选选择的id查询用户信息
|
|
||||||
if (this.selectedKeys[0] !== selectedKeys[0]) {
|
|
||||||
this.selectedKeys = [selectedKeys[0]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelectChange(selectedRowKeys, selectionRows) {
|
|
||||||
this.selectedRowKeys = selectedRowKeys;
|
|
||||||
this.selectionRows = selectionRows;
|
|
||||||
},
|
|
||||||
onSearch() {
|
|
||||||
this.loadData(1);
|
|
||||||
},
|
|
||||||
// 根据选择的id来查询用户信息
|
|
||||||
queryUser(selectedKeys) {
|
|
||||||
queryUserByDepId({ id: selectedKeys.toString() }).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.ipagination.total = res.result.length;
|
|
||||||
this.dataSource = res.result;
|
|
||||||
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) {
|
|
||||||
this.departTree = res.result;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 为角色名称赋值
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.ant-table-tbody .ant-table-row td {
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#components-layout-demo-custom-trigger .trigger {
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 64px;
|
|
||||||
padding: 0 24px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color .3s;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -0,0 +1,216 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
title="选择部门"
|
||||||
|
:width="modalWidth"
|
||||||
|
:visible="visible"
|
||||||
|
:confirmLoading="confirmLoading"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
cancelText="关闭">
|
||||||
|
<a-spin tip="Loading..." :spinning="false">
|
||||||
|
<a-input-search style="margin-bottom: 1px" placeholder="请输入部门名称按回车进行搜索" @search="onSearch" />
|
||||||
|
<a-tree
|
||||||
|
checkable
|
||||||
|
:treeData="treeData"
|
||||||
|
:checkStrictly="true"
|
||||||
|
@check="onCheck"
|
||||||
|
@select="onSelect"
|
||||||
|
@expand="onExpand"
|
||||||
|
:autoExpandParent="autoExpandParent"
|
||||||
|
:expandedKeys="expandedKeys"
|
||||||
|
:checkedKeys="checkedKeys">
|
||||||
|
|
||||||
|
<template slot="title" slot-scope="{title}">
|
||||||
|
<span v-if="title.indexOf(searchValue) > -1">
|
||||||
|
{{title.substr(0, title.indexOf(searchValue))}}
|
||||||
|
<span style="color: #f50">{{searchValue}}</span>
|
||||||
|
{{title.substr(title.indexOf(searchValue) + searchValue.length)}}
|
||||||
|
</span>
|
||||||
|
<span v-else>{{title}}</span>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
|
||||||
|
</a-spin>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { queryDepartTreeList } from '@/api/api'
|
||||||
|
export default {
|
||||||
|
name: 'JSelectDepartModal',
|
||||||
|
props:['modalWidth','multi','rootOpened','departId'],
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
visible:false,
|
||||||
|
confirmLoading:false,
|
||||||
|
treeData:[],
|
||||||
|
autoExpandParent:true,
|
||||||
|
expandedKeys:[],
|
||||||
|
dataList:[],
|
||||||
|
checkedKeys:[],
|
||||||
|
checkedRows:[],
|
||||||
|
searchValue:""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.loadDepart();
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
departId(){
|
||||||
|
this.initDepartComponent()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
show(){
|
||||||
|
this.visible=true
|
||||||
|
this.checkedRows=[]
|
||||||
|
this.checkedKeys=[]
|
||||||
|
console.log("this.multi",this.multi)
|
||||||
|
},
|
||||||
|
loadDepart(){
|
||||||
|
queryDepartTreeList().then(res=>{
|
||||||
|
if(res.success){
|
||||||
|
let arr = [...res.result]
|
||||||
|
this.reWriterWithSlot(arr)
|
||||||
|
this.treeData = arr
|
||||||
|
this.initDepartComponent()
|
||||||
|
if(this.rootOpened){
|
||||||
|
this.initExpandedKeys(res.result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
initDepartComponent(){
|
||||||
|
let names = ''
|
||||||
|
if(this.departId){
|
||||||
|
let currDepartId = this.departId
|
||||||
|
for(let item of this.dataList){
|
||||||
|
if(currDepartId.indexOf(item.key)>=0){
|
||||||
|
names+=","+item.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(names){
|
||||||
|
names = names.substring(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$emit("initComp",names)
|
||||||
|
},
|
||||||
|
reWriterWithSlot(arr){
|
||||||
|
for(let item of arr){
|
||||||
|
if(item.children && item.children.length>0){
|
||||||
|
this.reWriterWithSlot(item.children)
|
||||||
|
let temp = Object.assign({},item)
|
||||||
|
temp.children = {}
|
||||||
|
this.dataList.push(temp)
|
||||||
|
}else{
|
||||||
|
this.dataList.push(item)
|
||||||
|
item.scopedSlots={ title: 'title' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initExpandedKeys(arr){
|
||||||
|
if(arr && arr.length>0){
|
||||||
|
let keys = []
|
||||||
|
for(let item of arr){
|
||||||
|
if(item.children && item.children.length>0){
|
||||||
|
keys.push(item.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.expandedKeys=[...keys]
|
||||||
|
}else{
|
||||||
|
this.expandedKeys=[]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCheck (checkedKeys,info) {
|
||||||
|
if(!this.multi){
|
||||||
|
let arr = checkedKeys.checked.filter(item=>{
|
||||||
|
return this.checkedKeys.indexOf(item)<0
|
||||||
|
})
|
||||||
|
this.checkedKeys = [...arr]
|
||||||
|
this.checkedRows=[info.node.dataRef]
|
||||||
|
}else{
|
||||||
|
this.checkedKeys = checkedKeys.checked
|
||||||
|
this.checkedRows.push(info.node.dataRef)
|
||||||
|
}
|
||||||
|
//this.$emit("input",this.checkedKeys.join(","))
|
||||||
|
//console.log(this.checkedKeys.join(","))
|
||||||
|
},
|
||||||
|
onSelect (selectedKeys,info) {
|
||||||
|
console.log(selectedKeys)
|
||||||
|
let keys = []
|
||||||
|
keys.push(selectedKeys[0])
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
this.checkedRows.push(info.node.dataRef)
|
||||||
|
this.checkedKeys.push(...keys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onExpand (expandedKeys) {
|
||||||
|
this.expandedKeys = expandedKeys
|
||||||
|
this.autoExpandParent = false
|
||||||
|
},
|
||||||
|
handleSubmit(){
|
||||||
|
if(!this.checkedKeys || this.checkedKeys.length==0){
|
||||||
|
this.$emit("ok",'')
|
||||||
|
}else{
|
||||||
|
this.$emit("ok",this.checkedRows,this.checkedKeys.join(","))
|
||||||
|
}
|
||||||
|
this.handleClear()
|
||||||
|
},
|
||||||
|
handleCancel(){
|
||||||
|
this.handleClear()
|
||||||
|
},
|
||||||
|
handleClear(){
|
||||||
|
this.visible=false
|
||||||
|
this.checkedKeys=[]
|
||||||
|
},
|
||||||
|
getParentKey(currKey,treeData){
|
||||||
|
let parentKey
|
||||||
|
for (let i = 0; i < treeData.length; i++) {
|
||||||
|
const node = treeData[i]
|
||||||
|
if (node.children) {
|
||||||
|
if (node.children.some(item => item.key === currKey)) {
|
||||||
|
parentKey = node.key
|
||||||
|
} else if (this.getParentKey(currKey, node.children)) {
|
||||||
|
parentKey = this.getParentKey(currKey, node.children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parentKey
|
||||||
|
},
|
||||||
|
onSearch(value){
|
||||||
|
const expandedKeys = this.dataList.map((item) => {
|
||||||
|
if (item.title.indexOf(value) > -1) {
|
||||||
|
return this.getParentKey(item.key,this.treeData)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}).filter((item, i, self) => item && self.indexOf(item) === i)
|
||||||
|
|
||||||
|
Object.assign(this, {
|
||||||
|
expandedKeys,
|
||||||
|
searchValue: value,
|
||||||
|
autoExpandParent: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -0,0 +1,274 @@
|
|||||||
|
<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>
|
||||||
@ -1,5 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<a-modal
|
<a-modal
|
||||||
:width="modalWidth"
|
:width="modalWidth"
|
||||||
:visible="visible"
|
:visible="visible"
|
||||||
@ -29,11 +28,11 @@
|
|||||||
用户账号:
|
用户账号:
|
||||||
<a-input-search
|
<a-input-search
|
||||||
:style="{width:'150px',marginBottom:'15px'}"
|
:style="{width:'150px',marginBottom:'15px'}"
|
||||||
placeholder="请输入用户名搜索"
|
placeholder="请输入用户账号"
|
||||||
v-model="queryParam.username"
|
v-model="queryParam.username"
|
||||||
@search="onSearch"
|
@search="onSearch"
|
||||||
/>
|
></a-input-search>
|
||||||
<a-button @click="searchReset" style="margin-left: 20px" icon="redo">重置</a-button>
|
<a-button @click="searchReset(1)" style="margin-left: 20px" icon="redo">重置</a-button>
|
||||||
<!--用户列表-->
|
<!--用户列表-->
|
||||||
<a-table
|
<a-table
|
||||||
ref="table"
|
ref="table"
|
||||||
@ -50,19 +49,20 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { filterObj } from '@/utils/util'
|
import { filterObj } from '@/utils/util'
|
||||||
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
|
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JSearchUserByDepModal',
|
name: 'JSelectUserByDepModal',
|
||||||
components: {},
|
components: {},
|
||||||
|
props:['modalWidth'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
queryParam: {},
|
queryParam: {
|
||||||
|
username:"",
|
||||||
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
title: '用户账号',
|
title: '用户账号',
|
||||||
@ -106,12 +106,11 @@
|
|||||||
],
|
],
|
||||||
scrollTrigger: {},
|
scrollTrigger: {},
|
||||||
dataSource: [],
|
dataSource: [],
|
||||||
userDataSource:[],
|
|
||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
userNameArr: [],
|
userNameArr: [],
|
||||||
departName: '',
|
departName: '',
|
||||||
userRolesMap: {},
|
userRolesMap: {},
|
||||||
title: '',
|
title: '根据部门选择用户',
|
||||||
ipagination: {
|
ipagination: {
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@ -129,7 +128,6 @@
|
|||||||
},
|
},
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
modalWidth: 1250,
|
|
||||||
departTree: [],
|
departTree: [],
|
||||||
visible: false,
|
visible: false,
|
||||||
form: this.$form.createForm(this)
|
form: this.$form.createForm(this)
|
||||||
@ -149,7 +147,6 @@
|
|||||||
getUserList(params).then((res) => {
|
getUserList(params).then((res) => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
this.dataSource = res.result.records;
|
this.dataSource = res.result.records;
|
||||||
this.userDataSource = res.result.records;
|
|
||||||
this.assignRoleName(this.dataSource);
|
this.assignRoleName(this.dataSource);
|
||||||
this.ipagination.total = res.result.total;
|
this.ipagination.total = res.result.total;
|
||||||
}
|
}
|
||||||
@ -194,12 +191,12 @@
|
|||||||
},
|
},
|
||||||
searchReset(num) {
|
searchReset(num) {
|
||||||
let that = this;
|
let that = this;
|
||||||
if (num !== 0) {
|
if(num !== 0){
|
||||||
that.dataSource = that.userDataSource;
|
that.queryParam = {};
|
||||||
|
that.loadData(1);
|
||||||
}
|
}
|
||||||
that.selectedRowKeys = [];
|
that.selectedRowKeys = [];
|
||||||
that.userNameArr = [];
|
that.userNameArr = [];
|
||||||
that.queryParam = {};
|
|
||||||
that.selectedKeys = [];
|
that.selectedKeys = [];
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<iframe :id="id" :src="url" frameborder="0" width="100%" height="800px" scrolling="auto" style="background-color: #fff;"></iframe>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PageLayout from '../page/PageLayout'
|
||||||
|
import RouteView from './RouteView'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "IframePageContent",
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
url: "",
|
||||||
|
id:""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.goUrl()
|
||||||
|
},
|
||||||
|
updated () {
|
||||||
|
this.goUrl()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(to, from) {
|
||||||
|
this.goUrl();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
goUrl () {
|
||||||
|
let url = this.$route.meta.url
|
||||||
|
let id = this.$route.path
|
||||||
|
this.id = id
|
||||||
|
//url = "http://www.baidu.com"
|
||||||
|
console.log("------url------"+url)
|
||||||
|
if (url !== null && url !== undefined) {
|
||||||
|
this.url = url;
|
||||||
|
//window.open(this.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<global-layout>
|
<global-layout @dynamicRouterShow="dynamicRouterShow">
|
||||||
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect"/>
|
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect"/>
|
||||||
<a-tabs
|
<a-tabs
|
||||||
@contextmenu.native="e => onContextmenu(e)"
|
@contextmenu.native="e => onContextmenu(e)"
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
|
<span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<div style="margin: 24px 24px 0;">
|
<div style="margin: 12px 12px 0;">
|
||||||
<transition name="page-toggle">
|
<transition name="page-toggle">
|
||||||
<keep-alive v-if="multipage">
|
<keep-alive v-if="multipage">
|
||||||
<router-view/>
|
<router-view/>
|
||||||
@ -30,7 +30,6 @@
|
|||||||
import GlobalLayout from '@/components/page/GlobalLayout'
|
import GlobalLayout from '@/components/page/GlobalLayout'
|
||||||
import Contextmenu from '@/components/menu/Contextmenu'
|
import Contextmenu from '@/components/menu/Contextmenu'
|
||||||
import { mixin, mixinDevice } from '@/utils/mixin.js'
|
import { mixin, mixinDevice } from '@/utils/mixin.js'
|
||||||
import { topNavScrollToSelectItem } from '@/utils/util'
|
|
||||||
|
|
||||||
const indexKey = '/dashboard/analysis'
|
const indexKey = '/dashboard/analysis'
|
||||||
|
|
||||||
@ -86,23 +85,20 @@
|
|||||||
this.activePage = newRoute.fullPath
|
this.activePage = newRoute.fullPath
|
||||||
if (!this.multipage) {
|
if (!this.multipage) {
|
||||||
this.linkList = [newRoute.fullPath]
|
this.linkList = [newRoute.fullPath]
|
||||||
this.pageList = [newRoute]
|
this.pageList = [Object.assign({},newRoute)]
|
||||||
} else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
|
} else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
|
||||||
this.linkList.push(newRoute.fullPath)
|
this.linkList.push(newRoute.fullPath)
|
||||||
this.pageList.push(newRoute)
|
this.pageList.push(Object.assign({},newRoute))
|
||||||
} else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
|
} else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
|
||||||
let oldIndex = this.linkList.indexOf(newRoute.fullPath)
|
let oldIndex = this.linkList.indexOf(newRoute.fullPath)
|
||||||
this.pageList.splice(oldIndex, 1, newRoute)
|
let oldPositionRoute = this.pageList[oldIndex]
|
||||||
|
this.pageList.splice(oldIndex, 1, Object.assign({},newRoute,{meta:oldPositionRoute.meta}))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'activePage': function(key) {
|
'activePage': function(key) {
|
||||||
let index = this.linkList.lastIndexOf(key)
|
let index = this.linkList.lastIndexOf(key)
|
||||||
var waitRouter = this.pageList[index]
|
let waitRouter = this.pageList[index]
|
||||||
this.$router.push({
|
this.$router.push(Object.assign({},waitRouter));
|
||||||
path: waitRouter.path,
|
|
||||||
name: waitRouter.name,
|
|
||||||
params: waitRouter.params
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
'multipage': function(newVal) {
|
'multipage': function(newVal) {
|
||||||
if (!newVal) {
|
if (!newVal) {
|
||||||
@ -114,12 +110,6 @@
|
|||||||
methods: {
|
methods: {
|
||||||
changePage(key) {
|
changePage(key) {
|
||||||
this.activePage = key
|
this.activePage = key
|
||||||
// 只有当前模式是顶部菜单时才执行定位
|
|
||||||
if (this.layoutMode === 'topmenu') {
|
|
||||||
setTimeout(() => {
|
|
||||||
topNavScrollToSelectItem(document)
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
editPage(key, action) {
|
editPage(key, action) {
|
||||||
this[action](key)
|
this[action](key)
|
||||||
@ -208,7 +198,17 @@
|
|||||||
if (this.linkList.indexOf(this.activePage < 0)) {
|
if (this.linkList.indexOf(this.activePage < 0)) {
|
||||||
this.activePage = this.linkList[this.linkList.length - 1]
|
this.activePage = this.linkList[this.linkList.length - 1]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
//update-begin-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
|
||||||
|
dynamicRouterShow(key,title){
|
||||||
|
let keyIndex = this.linkList.indexOf(key)
|
||||||
|
if(keyIndex>=0){
|
||||||
|
let currRouter = this.pageList[keyIndex]
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
:class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null ]"
|
:class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null ]"
|
||||||
width="200px"
|
width="200px"
|
||||||
:collapsible="collapsible"
|
:collapsible="collapsible"
|
||||||
v-model="collapsed"
|
v-model="collapsed"
|
||||||
:trigger="null">
|
:trigger="null">
|
||||||
<logo />
|
<logo />
|
||||||
<s-menu
|
<s-menu
|
||||||
@ -12,7 +12,8 @@
|
|||||||
:theme="theme"
|
:theme="theme"
|
||||||
@select="onSelect"
|
@select="onSelect"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
style="padding: 0;"></s-menu>
|
:style="smenuStyle">
|
||||||
|
</s-menu>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@ -53,10 +54,92 @@
|
|||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed:{
|
||||||
|
smenuStyle() {
|
||||||
|
let style = { 'padding': '0' }
|
||||||
|
if (this.fixSiderbar) {
|
||||||
|
style['height'] = 'calc(100% - 59px)'
|
||||||
|
style['overflow'] = 'auto'
|
||||||
|
style['overflow-x'] = 'hidden'
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSelect (obj) {
|
onSelect (obj) {
|
||||||
this.$emit('menuSelect', obj)
|
this.$emit('menuSelect', obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
/* update_begin author:sunjianlei date:20190509 for: 修改侧边导航栏滚动条的样式 */
|
||||||
|
.sider {
|
||||||
|
$scrollBarSize: 10px;
|
||||||
|
|
||||||
|
ul.ant-menu {
|
||||||
|
|
||||||
|
/* 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: $scrollBarSize;
|
||||||
|
height: $scrollBarSize;
|
||||||
|
background-color: transparent;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .-o-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 兼容IE */
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
-ms-scroll-chaining: chained;
|
||||||
|
-ms-content-zooming: zoom;
|
||||||
|
-ms-scroll-rails: none;
|
||||||
|
-ms-content-zoom-limit-min: 100%;
|
||||||
|
-ms-content-zoom-limit-max: 500%;
|
||||||
|
-ms-scroll-snap-type: proximity;
|
||||||
|
-ms-scroll-snap-points-x: snapList(100%, 200%, 300%, 400%, 500%);
|
||||||
|
|
||||||
|
/* 定义滚动条轨道 */
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 定义滑块 */
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: $scrollBarSize;
|
||||||
|
background-color: #eee;
|
||||||
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #bbbbbb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 暗色系滚动条样式 */
|
||||||
|
&.dark ul.ant-menu {
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #666666;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #808080;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update_end author:sunjianlei date:20190509 for: 修改侧边导航栏滚动条的样式 */
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -34,149 +34,155 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
rootSubmenuKeys: (vm) => {
|
rootSubmenuKeys: vm => {
|
||||||
let keys = []
|
const keys = []
|
||||||
vm.menu.forEach(item => keys.push(item.path))
|
vm.menu.forEach(item => keys.push(item.path))
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
mounted () {
|
||||||
this.updateMenu()
|
this.updateMenu()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
collapsed (val) {
|
collapsed (val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.cachedOpenKeys = this.openKeys
|
this.cachedOpenKeys = this.openKeys.concat()
|
||||||
this.openKeys = []
|
this.openKeys = []
|
||||||
} else {
|
} else {
|
||||||
this.openKeys = this.cachedOpenKeys
|
this.openKeys = this.cachedOpenKeys
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'$route': function () {
|
$route: function () {
|
||||||
this.updateMenu()
|
this.updateMenu()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
renderIcon: function (h, icon) {
|
// select menu item
|
||||||
return icon === 'none' || icon === undefined ? null
|
|
||||||
: h(Icon, { props: { type: icon !== undefined ? icon : '' } })
|
|
||||||
},
|
|
||||||
renderMenuItem: function (h, menu, pIndex, index) {
|
|
||||||
// 判断是否带参数路由URL,是的话,采用path跳转方式
|
|
||||||
if(menu.route && menu.route === '0'){
|
|
||||||
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
|
|
||||||
[
|
|
||||||
h(
|
|
||||||
'router-link',
|
|
||||||
//--update-begin----author:scott---date:20190320------for:改造菜单路由跳转规则,原来是跳转到组件,现在改造成跳转URL(为了支持参数URL菜单)------
|
|
||||||
{ attrs: { to: { path: menu.path } } },
|
|
||||||
//--update-end----author:scott---date:20190320------for:改造菜单路由跳转规则,原来是跳转到组件,现在改造成跳转URL(为了支持参数URL菜单)------
|
|
||||||
[
|
|
||||||
this.renderIcon(h, menu.meta.icon),
|
|
||||||
h('span', [ menu.meta.title ])
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}else{
|
|
||||||
// 默认采用组件跳转方式
|
|
||||||
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
|
|
||||||
[
|
|
||||||
h(
|
|
||||||
'router-link',
|
|
||||||
{ attrs: { to: { name: menu.name } } },
|
|
||||||
[
|
|
||||||
this.renderIcon(h, menu.meta.icon),
|
|
||||||
h('span', [ menu.meta.title ])
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
renderSubMenu: function (h, menu, pIndex, index) {
|
|
||||||
const this2_ = this;
|
|
||||||
let subItem = [ h('span',
|
|
||||||
{ slot: 'title' },
|
|
||||||
[
|
|
||||||
this.renderIcon(h, menu.meta.icon),
|
|
||||||
h('span', [ menu.meta.title ])
|
|
||||||
]
|
|
||||||
) ]
|
|
||||||
let itemArr = []
|
|
||||||
let pIndex_ = pIndex + '_' + index
|
|
||||||
if (!menu.alwaysShow) {
|
|
||||||
menu.children.forEach(function (item, i) {
|
|
||||||
itemArr.push(this2_.renderItem(h, item, pIndex_, i))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return h(
|
|
||||||
SubMenu,
|
|
||||||
{ key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index },
|
|
||||||
subItem.concat(itemArr)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
renderItem: function (h, menu, pIndex, index) {
|
|
||||||
if (!menu.hidden) {
|
|
||||||
return menu.children && !menu.alwaysShow ? this.renderSubMenu(h, menu, pIndex, index) : this.renderMenuItem(h, menu, pIndex, index)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
renderMenu: function (h, menuTree) {
|
|
||||||
const this2_ = this
|
|
||||||
let menuArr = []
|
|
||||||
menuTree.forEach(function (menu, i) {
|
|
||||||
if (!menu.hidden) {
|
|
||||||
menuArr.push(this2_.renderItem(h, menu, '0', i))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return menuArr
|
|
||||||
},
|
|
||||||
onOpenChange (openKeys) {
|
onOpenChange (openKeys) {
|
||||||
const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1)
|
|
||||||
if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
|
// 在水平模式下时执行,并且不再执行后续
|
||||||
|
if (this.mode === 'horizontal') {
|
||||||
|
this.openKeys = openKeys
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 非水平模式时
|
||||||
|
const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
|
||||||
|
if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
|
||||||
this.openKeys = openKeys
|
this.openKeys = openKeys
|
||||||
} else {
|
} else {
|
||||||
this.openKeys = latestOpenKey ? [ latestOpenKey ] : []
|
this.openKeys = latestOpenKey ? [latestOpenKey] : []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateMenu () {
|
updateMenu () {
|
||||||
let routes = this.$route.matched.concat()
|
const routes = this.$route.matched.concat()
|
||||||
if (routes.length >= 4 && this.$route.meta.hidden) {
|
const { hidden } = this.$route.meta
|
||||||
|
if (routes.length >= 3 && hidden) {
|
||||||
routes.pop()
|
routes.pop()
|
||||||
this.selectedKeys = [ routes[2].path ]
|
this.selectedKeys = [routes[routes.length - 1].path]
|
||||||
} else {
|
} else {
|
||||||
this.selectedKeys = [ routes.pop().path ]
|
this.selectedKeys = [routes.pop().path]
|
||||||
}
|
}
|
||||||
|
const openKeys = []
|
||||||
let openKeys = []
|
|
||||||
if (this.mode === 'inline') {
|
if (this.mode === 'inline') {
|
||||||
routes.forEach((item) => {
|
routes.forEach(item => {
|
||||||
openKeys.push(item.path)
|
openKeys.push(item.path)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//update-begin-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
|
||||||
|
if(!this.selectedKeys || this.selectedKeys[0].indexOf(":")<0){
|
||||||
|
this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
|
||||||
|
}
|
||||||
|
//update-end-author:taoyan date:20190510 for:online表单菜单点击展开的一级目录不对
|
||||||
|
},
|
||||||
|
|
||||||
this.collapsed ? this.cachedOpenKeys = openKeys : this.openKeys = openKeys
|
// render
|
||||||
|
renderItem (menu) {
|
||||||
|
if (!menu.hidden) {
|
||||||
|
return menu.children && !menu.hideChildrenInMenu ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
renderMenuItem (menu) {
|
||||||
|
const target = menu.meta.target || null
|
||||||
|
const tag = target && 'a' || 'router-link'
|
||||||
|
let props = { to: { name: menu.name } }
|
||||||
|
if(menu.route && menu.route === '0'){
|
||||||
|
props = { to: { path: menu.path } }
|
||||||
|
}
|
||||||
|
|
||||||
|
const attrs = { href: menu.path, target: menu.meta.target }
|
||||||
|
|
||||||
|
if (menu.children && menu.hideChildrenInMenu) {
|
||||||
|
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
|
||||||
|
// 都给子菜单增加一个 hidden 属性
|
||||||
|
// 用来给刷新页面时, selectedKeys 做控制用
|
||||||
|
menu.children.forEach(item => {
|
||||||
|
item.meta = Object.assign(item.meta, { hidden: true })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Item {...{ key: menu.path }}>
|
||||||
|
<tag {...{ props, attrs }}>
|
||||||
|
{this.renderIcon(menu.meta.icon)}
|
||||||
|
<span>{menu.meta.title}</span>
|
||||||
|
</tag>
|
||||||
|
</Item>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
renderSubMenu (menu) {
|
||||||
|
const itemArr = []
|
||||||
|
if (!menu.hideChildrenInMenu) {
|
||||||
|
menu.children.forEach(item => itemArr.push(this.renderItem(item)))
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<SubMenu {...{ key: menu.path }}>
|
||||||
|
<span slot="title">
|
||||||
|
{this.renderIcon(menu.meta.icon)}
|
||||||
|
<span>{menu.meta.title}</span>
|
||||||
|
</span>
|
||||||
|
{itemArr}
|
||||||
|
</SubMenu>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
renderIcon (icon) {
|
||||||
|
if (icon === 'none' || icon === undefined) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const props = {}
|
||||||
|
typeof (icon) === 'object' ? props.component = icon : props.type = icon
|
||||||
|
return (
|
||||||
|
<Icon {... { props } }/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render (h) {
|
|
||||||
return h(
|
render () {
|
||||||
Menu,
|
const { mode, theme, menu } = this
|
||||||
{
|
const props = {
|
||||||
props: {
|
mode: mode,
|
||||||
theme: this.$props.theme,
|
theme: theme,
|
||||||
mode: this.$props.mode,
|
openKeys: this.openKeys
|
||||||
openKeys: this.openKeys,
|
}
|
||||||
selectedKeys: this.selectedKeys
|
const on = {
|
||||||
},
|
select: obj => {
|
||||||
on: {
|
this.selectedKeys = obj.selectedKeys
|
||||||
openChange: this.onOpenChange,
|
this.$emit('select', obj)
|
||||||
select: (obj) => {
|
},
|
||||||
this.selectedKeys = obj.selectedKeys
|
openChange: this.onOpenChange
|
||||||
this.$emit('select', obj)
|
}
|
||||||
}
|
|
||||||
}
|
const menuTree = menu.map(item => {
|
||||||
}, this.renderMenu(h, this.menu)
|
if (item.hidden) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.renderItem(item)
|
||||||
|
})
|
||||||
|
// {...{ props, on: on }}
|
||||||
|
return (
|
||||||
|
<Menu vModel={this.selectedKeys} {...{ props, on: on }}>
|
||||||
|
{menuTree}
|
||||||
|
</Menu>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,13 +27,11 @@
|
|||||||
<div class="header-index-wide">
|
<div class="header-index-wide">
|
||||||
<div class="header-index-left" :style="topMenuStyle.headerIndexLeft">
|
<div class="header-index-left" :style="topMenuStyle.headerIndexLeft">
|
||||||
<logo class="top-nav-header" :show-title="device !== 'mobile'" :style="topMenuStyle.topNavHeader"/>
|
<logo class="top-nav-header" :show-title="device !== 'mobile'" :style="topMenuStyle.topNavHeader"/>
|
||||||
<div v-if="device !== 'mobile'" id="top-nav-scroll-view" :style="topMenuStyle.scrollView">
|
<div v-if="device !== 'mobile'" :style="topMenuStyle.topSmenuStyle">
|
||||||
<div id="top-nav-scroll-width" :style="topMenuStyle.scrollWidth">
|
<s-menu
|
||||||
<s-menu
|
mode="horizontal"
|
||||||
mode="horizontal"
|
:menu="menus"
|
||||||
:menu="menus"
|
:theme="theme"></s-menu>
|
||||||
:theme="theme"></s-menu>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<a-icon
|
<a-icon
|
||||||
v-else
|
v-else
|
||||||
@ -54,7 +52,6 @@
|
|||||||
import Logo from '../tools/Logo'
|
import Logo from '../tools/Logo'
|
||||||
|
|
||||||
import { mixin } from '@/utils/mixin.js'
|
import { mixin } from '@/utils/mixin.js'
|
||||||
import { topNavScrollToSelectItem } from '@/utils/util'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GlobalHeader',
|
name: 'GlobalHeader',
|
||||||
@ -93,19 +90,12 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
headerBarFixed: false,
|
headerBarFixed: false,
|
||||||
//update-begin--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
|
//update-begin--author:sunjianlei---date:20190508------for: 顶部导航栏过长时显示更多按钮-----
|
||||||
topMenuStyle: {
|
topMenuStyle: {
|
||||||
headerIndexLeft: {},
|
headerIndexLeft: {},
|
||||||
topNavHeader: {},
|
topNavHeader: {},
|
||||||
headerIndexRight: {},
|
headerIndexRight: {},
|
||||||
scrollView: {
|
topSmenuStyle: {}
|
||||||
'overflow-x': 'auto',
|
|
||||||
'overflow-y': 'hidden'
|
|
||||||
},
|
|
||||||
scrollWidth: {
|
|
||||||
// 设置这么宽是为了让顶部菜单首次加载时充分展开,方便计算真实宽度
|
|
||||||
'width': '10000px'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -119,19 +109,18 @@
|
|||||||
/** 监听导航栏模式变化 */
|
/** 监听导航栏模式变化 */
|
||||||
mode(newVal) {
|
mode(newVal) {
|
||||||
if (newVal === 'topmenu') {
|
if (newVal === 'topmenu') {
|
||||||
this.calcTopMenuScrollWidth()
|
this.buildTopMenuStyle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//update-end--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
|
//update-end--author:sunjianlei---date:20190508------for: 顶部导航栏过长时显示更多按钮-----
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('scroll', this.handleScroll)
|
window.addEventListener('scroll', this.handleScroll)
|
||||||
//update-begin--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
|
//update-begin--author:sunjianlei---date:20190508------for: 顶部导航栏过长时显示更多按钮-----
|
||||||
if (this.mode === 'topmenu') {
|
if (this.mode === 'topmenu') {
|
||||||
this.buildTopMenuStyle()
|
this.buildTopMenuStyle()
|
||||||
this.calcTopMenuScrollWidth()
|
|
||||||
}
|
}
|
||||||
//update-end--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
|
//update-end--author:sunjianlei---date:20190508------for: 顶部导航栏过长时显示更多按钮-----
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
@ -149,67 +138,25 @@
|
|||||||
toggle() {
|
toggle() {
|
||||||
this.$emit('toggle')
|
this.$emit('toggle')
|
||||||
},
|
},
|
||||||
//update-begin--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
|
//update-begin--author:sunjianlei---date:20190508------for: 顶部导航栏过长时显示更多按钮-----
|
||||||
buildTopMenuStyle() {
|
buildTopMenuStyle() {
|
||||||
if (this.mode === 'topmenu') {
|
if (this.mode === 'topmenu') {
|
||||||
if (this.device === 'mobile') {
|
if (this.device === 'mobile') {
|
||||||
// 手机端需要清空样式,否则显示会错乱
|
// 手机端需要清空样式,否则显示会错乱
|
||||||
this.topMenuStyle.topNavHeader = {}
|
this.topMenuStyle.topNavHeader = {}
|
||||||
|
this.topMenuStyle.topSmenuStyle = {}
|
||||||
this.topMenuStyle.headerIndexRight = {}
|
this.topMenuStyle.headerIndexRight = {}
|
||||||
this.topMenuStyle.headerIndexLeft = {}
|
this.topMenuStyle.headerIndexLeft = {}
|
||||||
} else {
|
} else {
|
||||||
let rightWidth = '360px'
|
let rightWidth = '360px'
|
||||||
this.topMenuStyle.topNavHeader = { 'min-width': '165px' }
|
this.topMenuStyle.topNavHeader = { 'min-width': '165px' }
|
||||||
|
this.topMenuStyle.topSmenuStyle = { 'width': 'calc(100% - 165px)' }
|
||||||
this.topMenuStyle.headerIndexRight = { 'min-width': rightWidth }
|
this.topMenuStyle.headerIndexRight = { 'min-width': rightWidth }
|
||||||
this.topMenuStyle.headerIndexLeft = { 'width': `calc(100% - ${rightWidth})` }
|
this.topMenuStyle.headerIndexLeft = { 'width': `calc(100% - ${rightWidth})` }
|
||||||
// 由于首次从mobile设备下切换到desktop设备没有初始化TopMenuScrollWidth,所以这里需要计算一下
|
|
||||||
if (this.topMenuStyle.scrollWidth['width'] === '10000px') {
|
|
||||||
this.calcTopMenuScrollWidth()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/** 计算滚动条的宽度 */
|
|
||||||
calcTopMenuScrollWidth() {
|
|
||||||
// 非顶部菜单时不计算宽度
|
|
||||||
if (this.mode !== 'topmenu') return
|
|
||||||
let count = 0
|
|
||||||
let timer = setInterval(() => {
|
|
||||||
count++
|
|
||||||
let scrollWidth = document.getElementById('top-nav-scroll-width')
|
|
||||||
if (scrollWidth == null) {
|
|
||||||
clearInterval(timer)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let menu = scrollWidth.getElementsByClassName('ant-menu')[0]
|
|
||||||
if (menu) {
|
|
||||||
let widthCount = 0
|
|
||||||
let menuItems = menu.getElementsByTagName('li')
|
|
||||||
for (let item of menuItems) {
|
|
||||||
if (item.className.indexOf('ant-menu-overflowed-submenu') === -1) {
|
|
||||||
widthCount += item.offsetWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 由于首次从侧边菜单模式下切换到顶部菜单模式下没有buildTopMenuStyle,所以这里需要build一下
|
|
||||||
if (this.topMenuStyle.scrollWidth['width'] === '10000px') {
|
|
||||||
// 防止递归调用
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.buildTopMenuStyle()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.topMenuStyle.scrollWidth['width'] = `${widthCount + 10}px`
|
|
||||||
// 将滚动条位置滚动到当前选中的菜单处
|
|
||||||
if (count === 1) {
|
|
||||||
topNavScrollToSelectItem(document)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 校准数据三次再关闭定时器
|
|
||||||
if (count === 3) {
|
|
||||||
clearInterval(timer)
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
}
|
}
|
||||||
//update-end--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
|
//update-begin--author:sunjianlei---date:20190508------for: 顶部导航栏过长时显示更多按钮-----
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -268,52 +215,4 @@
|
|||||||
|
|
||||||
/* update_end author:scott date:20190220 for: 缩小首页布局顶部的高度*/
|
/* update_end author:scott date:20190220 for: 缩小首页布局顶部的高度*/
|
||||||
|
|
||||||
/* update_begin author:sunjianlei date:20190408 for: 修改顶部导航栏滚动条的样式 */
|
|
||||||
#top-nav-scroll-view {
|
|
||||||
$scrollBarSize: 8px;
|
|
||||||
|
|
||||||
/* 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: $scrollBarSize;
|
|
||||||
height: $scrollBarSize;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 定义滚动条轨道 */
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 定义滑块 */
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: $scrollBarSize;
|
|
||||||
background-color: #eee;
|
|
||||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #dddddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #bbbbbb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 暗色系滚动条样式 */
|
|
||||||
.dark #top-nav-scroll-view {
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #666666;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #808080;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #999999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update_end author:sunjianlei date:20190408 for: 修改顶部导航栏滚动条的样式 */
|
|
||||||
</style>
|
</style>
|
||||||
@ -24,6 +24,7 @@
|
|||||||
v-else
|
v-else
|
||||||
mode="inline"
|
mode="inline"
|
||||||
:menus="menus"
|
:menus="menus"
|
||||||
|
@menuSelect="myMenuSelect"
|
||||||
:theme="navTheme"
|
:theme="navTheme"
|
||||||
:collapsed="collapsed"
|
:collapsed="collapsed"
|
||||||
:collapsible="true"></side-menu>
|
:collapsible="true"></side-menu>
|
||||||
@ -98,6 +99,7 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
|
activeMenu:{},
|
||||||
menus: []
|
menus: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -136,9 +138,26 @@
|
|||||||
if (!this.isDesktop()) {
|
if (!this.isDesktop()) {
|
||||||
this.collapsed = false
|
this.collapsed = false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
//update-begin-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
|
||||||
|
myMenuSelect(value){
|
||||||
|
//此处触发动态路由被点击事件
|
||||||
|
this.findMenuBykey(this.menus,value.key)
|
||||||
|
this.$emit("dynamicRouterShow",value.key,this.activeMenu.meta.title)
|
||||||
|
},
|
||||||
|
findMenuBykey(menus,key){
|
||||||
|
for(let i of menus){
|
||||||
|
if(i.path==key){
|
||||||
|
this.activeMenu = {...i}
|
||||||
|
}else if(i.children && i.children.length>0){
|
||||||
|
this.findMenuBykey(i.children,key)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -114,7 +114,7 @@
|
|||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
<a-list-item >
|
<a-list-item >
|
||||||
<a-switch slot="actions" size="small" :disabled="(layoutMode === 'topmenu')" :defaultChecked="fixSiderbar" @change="handleFixSiderbar" />
|
<a-switch slot="actions" size="small" :disabled="(layoutMode === 'topmenu')" :checked="dataFixSiderbar" @change="handleFixSiderbar" />
|
||||||
<a-list-item-meta>
|
<a-list-item-meta>
|
||||||
<div slot="title" :style="{ textDecoration: layoutMode === 'topmenu' ? 'line-through' : 'unset' }">固定侧边菜单</div>
|
<div slot="title" :style="{ textDecoration: layoutMode === 'topmenu' ? 'line-through' : 'unset' }">固定侧边菜单</div>
|
||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
@ -179,7 +179,8 @@
|
|||||||
return {
|
return {
|
||||||
visible: true,
|
visible: true,
|
||||||
colorList,
|
colorList,
|
||||||
}
|
dataFixSiderbar: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
||||||
@ -244,9 +245,9 @@
|
|||||||
},
|
},
|
||||||
handleFixSiderbar (fixed) {
|
handleFixSiderbar (fixed) {
|
||||||
if (this.layoutMode === 'topmenu') {
|
if (this.layoutMode === 'topmenu') {
|
||||||
this.$store.dispatch('ToggleFixSiderbar', false)
|
fixed = false
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
this.dataFixSiderbar = fixed
|
||||||
this.$store.dispatch('ToggleFixSiderbar', fixed)
|
this.$store.dispatch('ToggleFixSiderbar', fixed)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,19 +5,20 @@
|
|||||||
:autoAdjustOverflow="true"
|
:autoAdjustOverflow="true"
|
||||||
:arrowPointAtCenter="true"
|
:arrowPointAtCenter="true"
|
||||||
overlayClassName="header-notice-wrapper"
|
overlayClassName="header-notice-wrapper"
|
||||||
|
@visibleChange="handleHoverChange"
|
||||||
:overlayStyle="{ width: '300px', top: '50px' }">
|
:overlayStyle="{ width: '300px', top: '50px' }">
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<a-spin :spinning="loadding">
|
<a-spin :spinning="loadding">
|
||||||
<a-tabs>
|
<a-tabs>
|
||||||
<a-tab-pane tab="通知" key="1">
|
<a-tab-pane :tab="msg1Title" key="1">
|
||||||
<a-list>
|
<!--<a-list>
|
||||||
<a-list-item>
|
<a-list-item>
|
||||||
<a-list-item-meta title="你收到了 14 份新周报" description="一年前">
|
<a-list-item-meta title="你收到了 14 份新周报" description="一年前">
|
||||||
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/>
|
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/>
|
||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
<a-list-item>
|
<a-list-item>
|
||||||
<a-list-item-meta title="你推荐的 曲妮妮 已通过第三轮面试" description="一年前">
|
<a-list-item-meta title="你推荐的 IT大牛 已通过第三轮面试" description="一年前">
|
||||||
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png"/>
|
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png"/>
|
||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
@ -26,34 +27,107 @@
|
|||||||
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png"/>
|
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png"/>
|
||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
|
</a-list>-->
|
||||||
|
<a-list>
|
||||||
|
<a-list-item :key="index" v-for="(record, index) in announcement1">
|
||||||
|
<div style="margin-left: 5%;width: 80%">
|
||||||
|
<p><a @click="showAnnouncement(record)">标题:{{ record.titile }}</a></p>
|
||||||
|
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag>
|
||||||
|
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag>
|
||||||
|
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
<div style="margin-top: 5px;text-align: center">
|
||||||
|
<a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button>
|
||||||
|
</div>
|
||||||
</a-list>
|
</a-list>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane tab="消息" key="2">
|
<a-tab-pane :tab="msg2Title" key="2">
|
||||||
123
|
<a-list>
|
||||||
</a-tab-pane>
|
<a-list-item :key="index" v-for="(record, index) in announcement2">
|
||||||
<a-tab-pane tab="待办" key="3">
|
<div style="margin-left: 5%;width: 80%">
|
||||||
123
|
<p><a @click="showAnnouncement(record)">标题:{{ record.titile }}</a></p>
|
||||||
|
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag>
|
||||||
|
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag>
|
||||||
|
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
<div style="margin-top: 5px;text-align: center">
|
||||||
|
<a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button>
|
||||||
|
</div>
|
||||||
|
</a-list>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
<span @click="fetchNotice" class="header-notice">
|
<span @click="fetchNotice" class="header-notice">
|
||||||
<a-badge count="12">
|
<a-badge :count="msgTotal">
|
||||||
<a-icon style="font-size: 16px; padding: 4px" type="bell" />
|
<a-icon style="font-size: 16px; padding: 4px" type="bell" />
|
||||||
</a-badge>
|
</a-badge>
|
||||||
</span>
|
</span>
|
||||||
|
<show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { getAction,putAction } from '@/api/manage'
|
||||||
|
import ShowAnnouncement from './ShowAnnouncement'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "HeaderNotice",
|
name: "HeaderNotice",
|
||||||
|
components: {
|
||||||
|
ShowAnnouncement,
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
loadding: false
|
loadding: false,
|
||||||
|
url:{
|
||||||
|
listCementByUser:"/sys/annountCement/listByUser",
|
||||||
|
editCementSend:"/system/sysAnnouncementSend/editByAnntIdAndUserId",
|
||||||
|
},
|
||||||
|
hovered: false,
|
||||||
|
announcement1:[],
|
||||||
|
announcement2:[],
|
||||||
|
msg1Count:"3",
|
||||||
|
msg2Count:"0",
|
||||||
|
msg1Title:"通知(3)",
|
||||||
|
msg2Title:"",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed:{
|
||||||
|
msgTotal () {
|
||||||
|
return parseInt(this.msg1Count)+parseInt(this.msg2Count);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadData();
|
||||||
|
this.timer();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
timer() {
|
||||||
|
return setInterval(()=>{
|
||||||
|
this.loadData()
|
||||||
|
},60000)
|
||||||
|
},
|
||||||
|
loadData (){
|
||||||
|
// 获取系统消息
|
||||||
|
getAction(this.url.listCementByUser).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
this.announcement1 = res.result.anntMsgList;
|
||||||
|
this.msg1Count = res.result.anntMsgTotal;
|
||||||
|
this.msg1Title = "通知("+res.result.anntMsgTotal+")";
|
||||||
|
this.announcement2 = res.result.sysMsgList;
|
||||||
|
this.msg2Count = res.result.sysMsgTotal;
|
||||||
|
this.msg2Title = "系统消息("+res.result.sysMsgTotal+")";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
fetchNotice () {
|
fetchNotice () {
|
||||||
if (this.loadding) {
|
if (this.loadding) {
|
||||||
this.loadding = false
|
this.loadding = false
|
||||||
@ -62,8 +136,30 @@
|
|||||||
this.loadding = true
|
this.loadding = true
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loadding = false
|
this.loadding = false
|
||||||
}, 2000)
|
}, 200)
|
||||||
}
|
},
|
||||||
|
showAnnouncement(record){
|
||||||
|
putAction(this.url.editCementSend,{anntId:record.id}).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.hovered = false;
|
||||||
|
this.$refs.ShowAnnouncement.detail(record);
|
||||||
|
},
|
||||||
|
toMyAnnouncement(){
|
||||||
|
|
||||||
|
this.$router.push({
|
||||||
|
path: '/isps/userAnnouncement',
|
||||||
|
name: 'isps-userAnnouncement'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
modalFormOk(){
|
||||||
|
},
|
||||||
|
handleHoverChange (visible) {
|
||||||
|
this.hovered = visible;
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:title="title"
|
||||||
|
:width="600"
|
||||||
|
:visible="visible"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
:okButtonProps="okButtonProps"
|
||||||
|
cancelText="关闭">
|
||||||
|
|
||||||
|
<div class="message">
|
||||||
|
<div class="title">{{ record.titile }}</div>
|
||||||
|
<div class="createBy">发布人:{{ record.sender }}</div>
|
||||||
|
<div class="sendTime">发布时间:{{ record.sendTime }}</div>
|
||||||
|
<a-divider />
|
||||||
|
<p v-html="record.msgContent"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SysAnnouncementModal",
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"通知消息",
|
||||||
|
record: {},
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 5 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 16 },
|
||||||
|
},
|
||||||
|
visible: false,
|
||||||
|
okButtonProps:{
|
||||||
|
style: {
|
||||||
|
display:"none"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
detail (record) {
|
||||||
|
this.visible = true;
|
||||||
|
this.record = record;
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.message{
|
||||||
|
width: 90%;
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-right: 5%;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
width: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.createBy {
|
||||||
|
width: 50%;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 5%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.sendTime{
|
||||||
|
width: 50%;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 5%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.message .ant-divider .ant-divider-horizontal .ant-divider-with-text-right{
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: lighter!important;
|
||||||
|
}
|
||||||
|
.message p{
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.message .ant-divider-horizontal{
|
||||||
|
margin-top: 40px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="user-wrapper" :class="theme">
|
<div class="user-wrapper" :class="theme">
|
||||||
<span class="action">
|
<span class="action">
|
||||||
<a-icon type="question-circle-o"></a-icon>
|
<a class="logout_title" target="_blank" href="http://jeecg-boot.mydoc.io">
|
||||||
|
<a-icon type="question-circle-o"></a-icon>
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<header-notice class="action"/>
|
<header-notice class="action"/>
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
@ -17,11 +19,15 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="1">
|
<a-menu-item key="1">
|
||||||
<router-link :to="{ name: 'account-settings' }">
|
<router-link :to="{ name: 'account-settings-base' }">
|
||||||
<a-icon type="setting"/>
|
<a-icon type="setting"/>
|
||||||
<span>账户设置</span>
|
<span>账户设置</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
<a-menu-item key="2" @click="updatePassword">
|
||||||
|
<a-icon type="setting"/>
|
||||||
|
<span>密码修改</span>
|
||||||
|
</a-menu-item>
|
||||||
<!-- <a-menu-item key="2" disabled>
|
<!-- <a-menu-item key="2" disabled>
|
||||||
<a-icon type="setting"/>
|
<a-icon type="setting"/>
|
||||||
<span>测试</span>
|
<span>测试</span>
|
||||||
@ -41,18 +47,22 @@
|
|||||||
<span v-if="isDesktop()"> 退出登录</span>
|
<span v-if="isDesktop()"> 退出登录</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
<user-password ref="userPassword"></user-password>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HeaderNotice from './HeaderNotice'
|
import HeaderNotice from './HeaderNotice'
|
||||||
|
import UserPassword from './UserPassword'
|
||||||
import { mapActions, mapGetters } from 'vuex'
|
import { mapActions, mapGetters } from 'vuex'
|
||||||
import { mixinDevice } from '@/utils/mixin.js'
|
import { mixinDevice } from '@/utils/mixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "UserMenu",
|
name: "UserMenu",
|
||||||
mixins: [mixinDevice],
|
mixins: [mixinDevice],
|
||||||
components: {
|
components: {
|
||||||
HeaderNotice
|
HeaderNotice,
|
||||||
|
UserPassword
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
theme: {
|
theme: {
|
||||||
@ -63,7 +73,7 @@
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["Logout"]),
|
...mapActions(["Logout"]),
|
||||||
...mapGetters(["nickname", "avatar"]),
|
...mapGetters(["nickname", "avatar","userInfo"]),
|
||||||
getAvatar(){
|
getAvatar(){
|
||||||
console.log('url = '+ window._CONFIG['imgDomainURL']+"/"+this.avatar())
|
console.log('url = '+ window._CONFIG['imgDomainURL']+"/"+this.avatar())
|
||||||
return window._CONFIG['imgDomainURL']+"/"+this.avatar()
|
return window._CONFIG['imgDomainURL']+"/"+this.avatar()
|
||||||
@ -89,6 +99,10 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updatePassword(){
|
||||||
|
let username = this.userInfo().username
|
||||||
|
this.$refs.userPassword.show(username)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
157
ant-design-jeecg-vue/src/components/tools/UserPassword.vue
Normal file
157
ant-design-jeecg-vue/src/components/tools/UserPassword.vue
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:title="title"
|
||||||
|
:width="modalWidth"
|
||||||
|
:visible="visible"
|
||||||
|
: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 type="password" placeholder="请输入旧密码" v-decorator="[ 'oldpassword', validatorRules.oldpassword]" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="新密码">
|
||||||
|
<a-input type="password" placeholder="请输入新密码" v-decorator="[ 'password', validatorRules.password]" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="确认新密码">
|
||||||
|
<a-input type="password" @blur="handleConfirmBlur" placeholder="请确认新密码" v-decorator="[ 'confirmpassword', validatorRules.confirmpassword]"/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
</a-form>
|
||||||
|
</a-spin>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { putAction } from '@/api/manage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UserPassword",
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"修改密码",
|
||||||
|
modalWidth:800,
|
||||||
|
visible: false,
|
||||||
|
confirmLoading: false,
|
||||||
|
validatorRules:{
|
||||||
|
oldpassword:{
|
||||||
|
rules: [{
|
||||||
|
required: true, message: '请输入旧密码!',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
password:{
|
||||||
|
rules: [{
|
||||||
|
required: true, message: '请输入新密码!',
|
||||||
|
}, {
|
||||||
|
validator: this.validateToNextPassword,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
confirmpassword:{
|
||||||
|
rules: [{
|
||||||
|
required: true, message: '请确认新密码!',
|
||||||
|
}, {
|
||||||
|
validator: this.compareToFirstPassword,
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirmDirty:false,
|
||||||
|
labelCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 5 },
|
||||||
|
},
|
||||||
|
wrapperCol: {
|
||||||
|
xs: { span: 24 },
|
||||||
|
sm: { span: 16 },
|
||||||
|
},
|
||||||
|
|
||||||
|
form:this.$form.createForm(this),
|
||||||
|
url: "sys/user/updatePassword",
|
||||||
|
username:"",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
show(uname){
|
||||||
|
if(!uname){
|
||||||
|
this.$message.warning("当前系统无登陆用户!");
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
this.username = uname
|
||||||
|
this.form.resetFields();
|
||||||
|
this.visible = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
close () {
|
||||||
|
this.$emit('close');
|
||||||
|
this.visible = false;
|
||||||
|
this.disableSubmit = false;
|
||||||
|
this.selectedRole = [];
|
||||||
|
},
|
||||||
|
handleOk () {
|
||||||
|
const that = this;
|
||||||
|
// 触发表单验证
|
||||||
|
this.form.validateFields((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
that.confirmLoading = true;
|
||||||
|
let params = Object.assign({username:this.username},values)
|
||||||
|
console.log("修改密码提交数据",params)
|
||||||
|
putAction(this.url,params).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
console.log(res)
|
||||||
|
that.$message.success(res.message);
|
||||||
|
that.close();
|
||||||
|
}else{
|
||||||
|
that.$message.warning(res.message);
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
that.confirmLoading = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
validateToNextPassword (rule, value, callback) {
|
||||||
|
const form = this.form;
|
||||||
|
if (value && this.confirmDirty) {
|
||||||
|
form.validateFields(['confirm'], { force: true })
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
compareToFirstPassword (rule, value, callback) {
|
||||||
|
const form = this.form;
|
||||||
|
if (value && value !== form.getFieldValue('password')) {
|
||||||
|
callback('两次输入的密码不一样!');
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleConfirmBlur (e) {
|
||||||
|
const value = e.target.value
|
||||||
|
this.confirmDirty = this.confirmDirty || !!value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
@ -13,366 +13,61 @@ export const asyncRouterMap = [
|
|||||||
meta: { title: '首页' },
|
meta: { title: '首页' },
|
||||||
redirect: '/dashboard/workplace',
|
redirect: '/dashboard/workplace',
|
||||||
children: [
|
children: [
|
||||||
|
// // account
|
||||||
|
|
||||||
// //系统监控
|
|
||||||
// {
|
// {
|
||||||
// path: '/sysmonitor',
|
// path: '/account',
|
||||||
// name: 'sysmonitor',
|
|
||||||
// redirect: '/sysmonitor',
|
|
||||||
// component: RouteView,
|
// component: RouteView,
|
||||||
// meta: { title: '系统监控', icon: 'dashboard', permission: [ 'dashboard' ] },
|
// name: 'account',
|
||||||
|
// meta: { title: '个人页', icon: 'user', keepAlive: true, permission: [ 'user' ] },
|
||||||
// children: [
|
// children: [
|
||||||
// {
|
// {
|
||||||
// path: '/sys/dataLog-list',
|
// path: '/account/center',
|
||||||
// name: 'DataLogList',
|
// name: 'center',
|
||||||
// component: () => import('@/views/system/DataLogList'),
|
// component: () => import('@/views/account/center/Index'),
|
||||||
// meta: { title: '数据日志', permission: [ 'dashboard' ] }
|
// meta: { title: '个人中心', keepAlive: true, permission: [ 'user' ] }
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// path: 'http://localhost:8080/jeecg-boot/druid/',
|
// path: '/account/settings',
|
||||||
// name: 'druid',
|
// name: 'settings',
|
||||||
// component: () => import('@/views/jeecg/tablist/JeecgOrderDMainList'),
|
// component: () => import('@/views/account/settings/Index'),
|
||||||
// meta: { title: 'SQL监控', permission: [ 'dashboard' ] }
|
// meta: { title: '个人设置', hideHeader: true, keepAlive: true, permission: [ 'user' ] },
|
||||||
// },
|
// redirect: '/account/settings/base',
|
||||||
// {
|
// alwaysShow: true,
|
||||||
// path: '/isystem/QuartzJobList',
|
// children: [
|
||||||
// name: 'QuartzJobList',
|
// {
|
||||||
// component: () => import('@/views/system/QuartzJobList'),
|
// path: '/account/settings/base',
|
||||||
// meta: { title: '定时任务', permission: [ 'dashboard' ] }
|
// name: 'BaseSettings',
|
||||||
|
// component: () => import('@/views/account/settings/BaseSetting'),
|
||||||
|
// meta: { title: '基本设置', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/account/settings/security',
|
||||||
|
// name: 'SecuritySettings',
|
||||||
|
// component: () => import('@/views/account/settings/Security'),
|
||||||
|
// meta: { title: '安全设置', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/account/settings/custom',
|
||||||
|
// name: 'CustomSettings',
|
||||||
|
// component: () => import('@/views/account/settings/Custom'),
|
||||||
|
// meta: { title: '个性化设置', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/account/settings/binding',
|
||||||
|
// name: 'BindingSettings',
|
||||||
|
// component: () => import('@/views/account/settings/Binding'),
|
||||||
|
// meta: { title: '账户绑定', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/account/settings/notification',
|
||||||
|
// name: 'NotificationSettings',
|
||||||
|
// component: () => import('@/views/account/settings/Notification'),
|
||||||
|
// meta: { title: '新消息通知', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
// },
|
// },
|
||||||
// ]
|
// ]
|
||||||
// },
|
// }
|
||||||
//
|
|
||||||
//
|
|
||||||
// //jeecg demo
|
|
||||||
// {
|
|
||||||
// path: '/jeecg',
|
|
||||||
// name: 'jeecg',
|
|
||||||
// redirect: '/jeecg',
|
|
||||||
// component: RouteView,
|
|
||||||
// meta: { title: 'JEECG案例', icon: 'dashboard', permission: [ 'dashboard' ] },
|
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// path: '/jeecg/JeecgDemoList',
|
|
||||||
// name: 'DemoList',
|
|
||||||
// component: () => import('@/views/jeecg/JeecgDemoList'),
|
|
||||||
// meta: { title: '单表模型示例', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/jeecg/tablist/JeecgOrderDMainList',
|
|
||||||
// name: 'JeecgOrderDMainList',
|
|
||||||
// component: () => import('@/views/jeecg/tablist/JeecgOrderDMainList'),
|
|
||||||
// meta: { title: '一对多Tab示例', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/jeecg/FlowTest',
|
|
||||||
// name: 'FlowTest',
|
|
||||||
// component: () => import('@/views/jeecg/FlowTest'),
|
|
||||||
// meta: { title: '数据回执模拟', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/jeecg/PrintDemo',
|
|
||||||
// name: 'PrintDemo',
|
|
||||||
// component: () => import('@/views/jeecg/PrintDemo'),
|
|
||||||
// meta: { title: '打印测试', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/jeecg/JeecgOrderMainList',
|
|
||||||
// name: 'JeecgOrderMainList',
|
|
||||||
// component: () => import('@/views/jeecg/JeecgOrderMainList'),
|
|
||||||
// meta: { title: '一对多示例', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'http://www.baidu.com',
|
|
||||||
// name: 'baidu',
|
|
||||||
// component: () => import('@/components/layouts/IframePageView'),
|
|
||||||
// meta: { title: '百度', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: 'http://localhost:8080/jeecg-boot/auto/cgform/list',
|
|
||||||
// name: 'cgformtest',
|
|
||||||
// component: () => import('@/components/layouts/IframePageView'),
|
|
||||||
// meta: { title: 'online表单测试', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/jeecg/helloworld',
|
|
||||||
// name: 'helloworld',
|
|
||||||
// hidden : true,
|
|
||||||
// component: () => import('@/views/jeecg/helloworld'),
|
|
||||||
// meta: { title: 'helloworld', permission: [ 'dashboard' ] }
|
|
||||||
// },
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
|
|
||||||
// dashboard
|
|
||||||
{
|
|
||||||
path: '/dashboard',
|
|
||||||
name: 'dashboard',
|
|
||||||
redirect: '/dashboard/workplace',
|
|
||||||
component: RouteView,
|
|
||||||
meta: { title: '仪表盘', icon: 'dashboard', permission: [ 'dashboard' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/dashboard/analysis',
|
|
||||||
name: 'Analysis',
|
|
||||||
component: () => import('@/views/dashboard/Analysis'),
|
|
||||||
meta: { title: '分析页', permission: [ 'dashboard' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/dashboard/monitor',
|
|
||||||
name: 'Monitor',
|
|
||||||
hidden: true,
|
|
||||||
component: () => import('@/views/dashboard/Monitor'),
|
|
||||||
meta: { title: '监控页', permission: [ 'dashboard' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/dashboard/workplace',
|
|
||||||
name: 'Workplace',
|
|
||||||
component: () => import('@/views/dashboard/Workplace'),
|
|
||||||
meta: { title: '工作台', permission: [ 'dashboard' ] }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// forms
|
|
||||||
{
|
|
||||||
path: '/form',
|
|
||||||
redirect: '/form/basic-form',
|
|
||||||
component: PageView,
|
|
||||||
meta: { title: '表单页', icon: 'form', permission: [ 'form' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/form/base-form',
|
|
||||||
name: 'BaseForm',
|
|
||||||
component: () => import('@/views/form/BasicForm'),
|
|
||||||
meta: { title: '基础表单', permission: [ 'form' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/form/step-form',
|
|
||||||
name: 'StepForm',
|
|
||||||
component: () => import('@/views/form/stepForm/StepForm'),
|
|
||||||
meta: { title: '分步表单', permission: [ 'form' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/form/advanced-form',
|
|
||||||
name: 'AdvanceForm',
|
|
||||||
component: () => import('@/views/form/advancedForm/AdvancedForm'),
|
|
||||||
meta: { title: '高级表单', permission: [ 'form' ] }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// list
|
|
||||||
{
|
|
||||||
path: '/list',
|
|
||||||
name: 'list',
|
|
||||||
component: PageView,
|
|
||||||
redirect: '/list/query-list',
|
|
||||||
meta: { title: '列表页', icon: 'table', permission: [ 'table' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/list/query-list',
|
|
||||||
name: 'QueryList',
|
|
||||||
component: () => import('@/views/list/TableList'),
|
|
||||||
meta: { title: '查询表格', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/edit-table',
|
|
||||||
name: 'EditList',
|
|
||||||
component: () => import('@/views/list/TableInnerEditList'),
|
|
||||||
meta: { title: '内联编辑表格', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/user-list',
|
|
||||||
name: 'UserList',
|
|
||||||
component: () => import('@/views/list/UserList'),
|
|
||||||
meta: { title: '用户列表', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/role-list',
|
|
||||||
name: 'RoleList',
|
|
||||||
component: () => import('@/views/list/RoleList'),
|
|
||||||
meta: { title: '角色列表', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/permission-list',
|
|
||||||
name: 'PermissionList',
|
|
||||||
component: () => import('@/views/list/PermissionList'),
|
|
||||||
meta: { title: '权限列表', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/basic-list',
|
|
||||||
name: 'BasicList',
|
|
||||||
component: () => import('@/views/list/StandardList'),
|
|
||||||
meta: { title: '标准列表', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/card',
|
|
||||||
name: 'CardList',
|
|
||||||
component: () => import('@/views/list/CardList'),
|
|
||||||
meta: { title: '卡片列表', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/search',
|
|
||||||
name: 'SearchList',
|
|
||||||
component: () => import('@/views/list/search/SearchLayout'),
|
|
||||||
redirect: '/list/search/article',
|
|
||||||
meta: { title: '搜索列表', permission: [ 'table' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/list/search/article',
|
|
||||||
name: 'SearchArticles',
|
|
||||||
component: () => import('../views/list/TableList'),
|
|
||||||
meta: { title: '搜索列表(文章)', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/search/project',
|
|
||||||
name: 'SearchProjects',
|
|
||||||
component: () => import('../views/list/TableList'),
|
|
||||||
meta: { title: '搜索列表(项目)', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/list/search/application',
|
|
||||||
name: 'SearchApplications',
|
|
||||||
component: () => import('../views/list/TableList'),
|
|
||||||
meta: { title: '搜索列表(应用)', permission: [ 'table' ] }
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// profile
|
|
||||||
{
|
|
||||||
path: '/profile',
|
|
||||||
name: 'profile',
|
|
||||||
component: RouteView,
|
|
||||||
redirect: '/profile/basic',
|
|
||||||
meta: { title: '详情页', icon: 'profile', permission: [ 'profile' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/profile/basic',
|
|
||||||
name: 'ProfileBasic',
|
|
||||||
component: () => import('@/views/profile/basic/Index'),
|
|
||||||
meta: { title: '基础详情页', permission: [ 'profile' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/profile/advanced',
|
|
||||||
name: 'ProfileAdvanced',
|
|
||||||
component: () => import('@/views/profile/advanced/Advanced'),
|
|
||||||
meta: { title: '高级详情页', permission: [ 'profile' ] }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// result
|
|
||||||
{
|
|
||||||
path: '/result',
|
|
||||||
name: 'result',
|
|
||||||
component: PageView,
|
|
||||||
redirect: '/result/success',
|
|
||||||
meta: { title: '结果页', icon: 'check-circle-o', permission: [ 'result' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/result/success',
|
|
||||||
name: 'ResultSuccess',
|
|
||||||
component: () => import(/* webpackChunkName: "result" */ '@/views/result/Success'),
|
|
||||||
meta: { title: '成功', hiddenHeaderContent: true, permission: [ 'result' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/result/fail',
|
|
||||||
name: 'ResultFail',
|
|
||||||
component: () => import(/* webpackChunkName: "result" */ '@/views/result/Error'),
|
|
||||||
meta: { title: '失败', hiddenHeaderContent: true, permission: [ 'result' ] }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Exception
|
|
||||||
{
|
|
||||||
path: '/exception',
|
|
||||||
name: 'exception',
|
|
||||||
component: RouteView,
|
|
||||||
redirect: '/exception/403',
|
|
||||||
meta: { title: '异常页', icon: 'warning', permission: [ 'exception' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/exception/403',
|
|
||||||
name: 'Exception403',
|
|
||||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/403'),
|
|
||||||
meta: { title: '403', permission: [ 'exception' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/exception/404',
|
|
||||||
name: 'Exception404',
|
|
||||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404'),
|
|
||||||
meta: { title: '404', permission: [ 'exception' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/exception/500',
|
|
||||||
name: 'Exception500',
|
|
||||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/500'),
|
|
||||||
meta: { title: '500', permission: [ 'exception' ] }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// account
|
|
||||||
{
|
|
||||||
path: '/account',
|
|
||||||
component: RouteView,
|
|
||||||
name: 'account',
|
|
||||||
meta: { title: '个人页', icon: 'user', keepAlive: true, permission: [ 'user' ] },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/account/center',
|
|
||||||
name: 'center',
|
|
||||||
component: () => import('@/views/account/center/Index'),
|
|
||||||
meta: { title: '个人中心', keepAlive: true, permission: [ 'user' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/account/settings',
|
|
||||||
name: 'settings',
|
|
||||||
component: () => import('@/views/account/settings/Index'),
|
|
||||||
meta: { title: '个人设置', hideHeader: true, keepAlive: true, permission: [ 'user' ] },
|
|
||||||
redirect: '/account/settings/base',
|
|
||||||
alwaysShow: true,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/account/settings/base',
|
|
||||||
name: 'BaseSettings',
|
|
||||||
component: () => import('@/views/account/settings/BaseSetting'),
|
|
||||||
meta: { title: '基本设置', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/account/settings/security',
|
|
||||||
name: 'SecuritySettings',
|
|
||||||
component: () => import('@/views/account/settings/Security'),
|
|
||||||
meta: { title: '安全设置', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/account/settings/custom',
|
|
||||||
name: 'CustomSettings',
|
|
||||||
component: () => import('@/views/account/settings/Custom'),
|
|
||||||
meta: { title: '个性化设置', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/account/settings/binding',
|
|
||||||
name: 'BindingSettings',
|
|
||||||
component: () => import('@/views/account/settings/Binding'),
|
|
||||||
meta: { title: '账户绑定', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/account/settings/notification',
|
|
||||||
name: 'NotificationSettings',
|
|
||||||
component: () => import('@/views/account/settings/Notification'),
|
|
||||||
meta: { title: '新消息通知', hidden: true, keepAlive: true, permission: [ 'user' ] }
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -449,5 +144,4 @@ export const constantRouterMap = [
|
|||||||
path: '/404',
|
path: '/404',
|
||||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
|
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -16,6 +16,9 @@ import Print from 'vue-print-nb-jeecg'
|
|||||||
/*import '@babel/polyfill'*/
|
/*import '@babel/polyfill'*/
|
||||||
import VueApexCharts from 'vue-apexcharts'
|
import VueApexCharts from 'vue-apexcharts'
|
||||||
|
|
||||||
|
import preview from 'vue-photo-preview'
|
||||||
|
import 'vue-photo-preview/dist/skin.css'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ACCESS_TOKEN,
|
ACCESS_TOKEN,
|
||||||
DEFAULT_COLOR,
|
DEFAULT_COLOR,
|
||||||
@ -26,12 +29,14 @@ import {
|
|||||||
DEFAULT_FIXED_HEADER,
|
DEFAULT_FIXED_HEADER,
|
||||||
DEFAULT_FIXED_HEADER_HIDDEN,
|
DEFAULT_FIXED_HEADER_HIDDEN,
|
||||||
DEFAULT_FIXED_SIDEMENU,
|
DEFAULT_FIXED_SIDEMENU,
|
||||||
DEFAULT_CONTENT_WIDTH_TYPE
|
DEFAULT_CONTENT_WIDTH_TYPE,
|
||||||
|
DEFAULT_MULTI_PAGE
|
||||||
} from "@/store/mutation-types"
|
} from "@/store/mutation-types"
|
||||||
import config from '@/defaultSettings'
|
import config from '@/defaultSettings'
|
||||||
|
|
||||||
import JDictSelectTag from './components/dict/index.js'
|
import JDictSelectTag from './components/dict/index.js'
|
||||||
import hasPermission from '@/utils/hasPermission'
|
import hasPermission from '@/utils/hasPermission'
|
||||||
|
import vueBus from '@/utils/vueBus';
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
Vue.use(Storage, config.storageOptions)
|
Vue.use(Storage, config.storageOptions)
|
||||||
@ -43,6 +48,8 @@ Vue.use(JDictSelectTag)
|
|||||||
Vue.use(Print)
|
Vue.use(Print)
|
||||||
Vue.use(VueApexCharts)
|
Vue.use(VueApexCharts)
|
||||||
Vue.component('apexchart', VueApexCharts)
|
Vue.component('apexchart', VueApexCharts)
|
||||||
|
Vue.use(preview)
|
||||||
|
Vue.use(vueBus);
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
@ -58,6 +65,7 @@ new Vue({
|
|||||||
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
|
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
|
||||||
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
|
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
|
||||||
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
|
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
|
||||||
|
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,true))
|
||||||
},
|
},
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount('#app')
|
}).$mount('#app')
|
||||||
|
|||||||
22
ant-design-jeecg-vue/src/mixins/DisabledAuthFilterMixin.js
Normal file
22
ant-design-jeecg-vue/src/mixins/DisabledAuthFilterMixin.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { disabledAuthFilter } from "@/utils/authFilter"
|
||||||
|
|
||||||
|
export const DisabledAuthFilterMixin = {
|
||||||
|
props: ['formData'],
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
disabledAuth(code){
|
||||||
|
return disabledAuthFilter(code,this.formData);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ import JEditableTable from '@/components/jeecg/JEditableTable'
|
|||||||
import { VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables } from '@/utils/JEditableTableUtil'
|
import { VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables } from '@/utils/JEditableTableUtil'
|
||||||
import { httpAction, getAction } from '@/api/manage'
|
import { httpAction, getAction } from '@/api/manage'
|
||||||
|
|
||||||
export const JEditableTableOneToManyMixin = {
|
export const JEditableTableMixin = {
|
||||||
components: {
|
components: {
|
||||||
JEditableTable
|
JEditableTable
|
||||||
},
|
},
|
||||||
@ -48,6 +48,7 @@ export const JEditableTableOneToManyMixin = {
|
|||||||
|
|
||||||
/** 当点击新增按钮时调用此方法 */
|
/** 当点击新增按钮时调用此方法 */
|
||||||
add() {
|
add() {
|
||||||
|
if (typeof this.addBefore === 'function') this.addBefore()
|
||||||
// 默认新增空数据
|
// 默认新增空数据
|
||||||
let rowNum = this.addDefaultRowNum
|
let rowNum = this.addDefaultRowNum
|
||||||
if (typeof rowNum !== 'number') {
|
if (typeof rowNum !== 'number') {
|
||||||
@ -57,7 +58,7 @@ export const JEditableTableOneToManyMixin = {
|
|||||||
this.eachAllTable((item) => {
|
this.eachAllTable((item) => {
|
||||||
item.add(rowNum)
|
item.add(rowNum)
|
||||||
})
|
})
|
||||||
|
if (typeof this.addAfter === 'function') this.addAfter(this.model)
|
||||||
this.edit({})
|
this.edit({})
|
||||||
},
|
},
|
||||||
/** 当点击了编辑(修改)按钮时调用此方法 */
|
/** 当点击了编辑(修改)按钮时调用此方法 */
|
||||||
@ -4,11 +4,16 @@
|
|||||||
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
|
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
|
||||||
*/
|
*/
|
||||||
import { filterObj } from '@/utils/util';
|
import { filterObj } from '@/utils/util';
|
||||||
import { deleteAction, getAction } from '@/api/manage'
|
import { deleteAction, getAction,downFile } from '@/api/manage'
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||||
|
|
||||||
export const JeecgListMixin = {
|
export const JeecgListMixin = {
|
||||||
data(){
|
data(){
|
||||||
return {
|
return {
|
||||||
/* 查询条件 */
|
//token header
|
||||||
|
tokenHeader: {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)},
|
||||||
|
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
|
||||||
queryParam: {},
|
queryParam: {},
|
||||||
/* 数据源 */
|
/* 数据源 */
|
||||||
dataSource:[],
|
dataSource:[],
|
||||||
@ -42,7 +47,7 @@ export const JeecgListMixin = {
|
|||||||
/* 高级查询条件生效状态 */
|
/* 高级查询条件生效状态 */
|
||||||
superQueryFlag:false,
|
superQueryFlag:false,
|
||||||
/* 高级查询条件 */
|
/* 高级查询条件 */
|
||||||
superQueryParams:"",
|
superQueryParams:""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -61,11 +66,13 @@ export const JeecgListMixin = {
|
|||||||
this.ipagination.current = 1;
|
this.ipagination.current = 1;
|
||||||
}
|
}
|
||||||
var params = this.getQueryParams();//查询条件
|
var params = this.getQueryParams();//查询条件
|
||||||
|
this.loading = true;
|
||||||
getAction(this.url.list, params).then((res) => {
|
getAction(this.url.list, params).then((res) => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
this.dataSource = res.result.records;
|
this.dataSource = res.result.records;
|
||||||
this.ipagination.total = res.result.total;
|
this.ipagination.total = res.result.total;
|
||||||
}
|
}
|
||||||
|
this.loading = false;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
initDictConfig(){
|
initDictConfig(){
|
||||||
@ -198,23 +205,74 @@ export const JeecgListMixin = {
|
|||||||
this.$refs.modalForm.disableSubmit = true;
|
this.$refs.modalForm.disableSubmit = true;
|
||||||
},
|
},
|
||||||
/* 导出 */
|
/* 导出 */
|
||||||
handleExportXls(){
|
handleExportXls2(){
|
||||||
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
|
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
|
||||||
let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
|
let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
},
|
},
|
||||||
|
handleExportXls(fileName){
|
||||||
|
if(!fileName || typeof fileName != "string"){
|
||||||
|
fileName = "导出文件"
|
||||||
|
}
|
||||||
|
let param = {...this.queryParam};
|
||||||
|
if(this.selectedRowKeys && this.selectedRowKeys.length>0){
|
||||||
|
param['selections'] = this.selectedRowKeys.join(",")
|
||||||
|
}
|
||||||
|
console.log("导出参数",param)
|
||||||
|
downFile(this.url.exportXlsUrl,param).then((data)=>{
|
||||||
|
if (!data) {
|
||||||
|
this.$message.warning("文件下载失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
||||||
|
window.navigator.msSaveBlob(new Blob([data]), fileName+'.xls')
|
||||||
|
}else{
|
||||||
|
let url = window.URL.createObjectURL(new Blob([data]))
|
||||||
|
let link = document.createElement('a')
|
||||||
|
link.style.display = 'none'
|
||||||
|
link.href = url
|
||||||
|
link.setAttribute('download', fileName+'.xls')
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link); //下载完成移除元素
|
||||||
|
window.URL.revokeObjectURL(url); //释放掉blob对象
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
/* 导入 */
|
/* 导入 */
|
||||||
handleImportExcel(info){
|
handleImportExcel(info){
|
||||||
if (info.file.status !== 'uploading') {
|
if (info.file.status !== 'uploading') {
|
||||||
console.log(info.file, info.fileList);
|
console.log(info.file, info.fileList);
|
||||||
}
|
}
|
||||||
if (info.file.status === 'done') {
|
if (info.file.status === 'done') {
|
||||||
this.$message.success(`${info.file.name} 文件上传成功`);
|
if(info.file.response.success){
|
||||||
this.loadData();
|
this.$message.success(`${info.file.name} 文件上传成功`);
|
||||||
|
this.loadData();
|
||||||
|
} else {
|
||||||
|
this.$message.error(`${info.file.name} ${info.file.response.message}.`);
|
||||||
|
}
|
||||||
} else if (info.file.status === 'error') {
|
} else if (info.file.status === 'error') {
|
||||||
this.$message.error(`${info.file.name} 文件上传失败.`);
|
this.$message.error(`文件上传失败: ${info.file.msg} `);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/* 图片预览 */
|
||||||
|
getImgView(text){
|
||||||
|
if(text && text.indexOf(",")>0){
|
||||||
|
text = text.substring(0,text.indexOf(","))
|
||||||
|
}
|
||||||
|
return window._CONFIG['imgDomainURL']+"/"+text
|
||||||
|
},
|
||||||
|
/* 文件下载 */
|
||||||
|
uploadFile(text){
|
||||||
|
if(!text){
|
||||||
|
this.$message.warning("未知的文件")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(text.indexOf(",")>0){
|
||||||
|
text = text.substring(0,text.indexOf(","))
|
||||||
|
}
|
||||||
|
window.open(window._CONFIG['domianURL'] + "/sys/common/download/"+text);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ router.beforeEach((to, from, next) => {
|
|||||||
} else {
|
} else {
|
||||||
if (store.getters.permissionList.length === 0) {
|
if (store.getters.permissionList.length === 0) {
|
||||||
store.dispatch('GetPermissionList').then(res => {
|
store.dispatch('GetPermissionList').then(res => {
|
||||||
const menuData = res.result;
|
const menuData = res.result.menu;
|
||||||
console.log(res.message)
|
console.log(res.message)
|
||||||
if (menuData === null || menuData === "" || menuData === undefined) {
|
if (menuData === null || menuData === "" || menuData === undefined) {
|
||||||
return;
|
return;
|
||||||
@ -45,10 +45,10 @@ router.beforeEach((to, from, next) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notification.error({
|
/* notification.error({
|
||||||
message: '系统提示',
|
message: '系统提示',
|
||||||
description: '请求用户信息失败,请重试!'
|
description: '请求用户信息失败,请重试!'
|
||||||
})
|
})*/
|
||||||
store.dispatch('Logout').then(() => {
|
store.dispatch('Logout').then(() => {
|
||||||
next({ path: '/user/login', query: { redirect: to.fullPath } })
|
next({ path: '/user/login', query: { redirect: to.fullPath } })
|
||||||
})
|
})
|
||||||
|
|||||||
@ -8,7 +8,8 @@ import {
|
|||||||
DEFAULT_FIXED_HEADER,
|
DEFAULT_FIXED_HEADER,
|
||||||
DEFAULT_FIXED_SIDEMENU,
|
DEFAULT_FIXED_SIDEMENU,
|
||||||
DEFAULT_FIXED_HEADER_HIDDEN,
|
DEFAULT_FIXED_HEADER_HIDDEN,
|
||||||
DEFAULT_CONTENT_WIDTH_TYPE
|
DEFAULT_CONTENT_WIDTH_TYPE,
|
||||||
|
DEFAULT_MULTI_PAGE
|
||||||
} from "@/store/mutation-types"
|
} from "@/store/mutation-types"
|
||||||
|
|
||||||
const app = {
|
const app = {
|
||||||
@ -75,6 +76,7 @@ const app = {
|
|||||||
state.weak = flag
|
state.weak = flag
|
||||||
},
|
},
|
||||||
SET_MULTI_PAGE (state, multipageFlag) {
|
SET_MULTI_PAGE (state, multipageFlag) {
|
||||||
|
Vue.ls.set(DEFAULT_MULTI_PAGE, multipageFlag)
|
||||||
state.multipage = multipageFlag
|
state.multipage = multipageFlag
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { login, logout } from "@/api/login"
|
import { login, logout } from "@/api/login"
|
||||||
import { ACCESS_TOKEN, USER_NAME,USER_INFO } from "@/store/mutation-types"
|
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
|
||||||
import { welcome } from "@/utils/util"
|
import { welcome } from "@/utils/util"
|
||||||
import { queryPermissionsByUser } from '@/api/api'
|
import { queryPermissionsByUser } from '@/api/api'
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ const user = {
|
|||||||
commit('SET_INFO', userInfo)
|
commit('SET_INFO', userInfo)
|
||||||
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
|
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
|
||||||
commit('SET_AVATAR', userInfo.avatar)
|
commit('SET_AVATAR', userInfo.avatar)
|
||||||
resolve()
|
resolve(response)
|
||||||
}else{
|
}else{
|
||||||
reject(response)
|
reject(response)
|
||||||
}
|
}
|
||||||
@ -63,10 +63,15 @@ const user = {
|
|||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
GetPermissionList({ commit }) {
|
GetPermissionList({ commit }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let username = Vue.ls.get(USER_NAME);
|
let v_token = Vue.ls.get(ACCESS_TOKEN);
|
||||||
let params = {username:username};
|
let params = {token:v_token};
|
||||||
queryPermissionsByUser(params).then(response => {
|
queryPermissionsByUser(params).then(response => {
|
||||||
const menuData = response.result;
|
const menuData = response.result.menu;
|
||||||
|
const authData = response.result.auth;
|
||||||
|
const allAuthData = response.result.allAuth;
|
||||||
|
//Vue.ls.set(USER_AUTH,authData);
|
||||||
|
sessionStorage.setItem(USER_AUTH,JSON.stringify(authData));
|
||||||
|
sessionStorage.setItem(SYS_BUTTON_AUTH,JSON.stringify(allAuthData));
|
||||||
if (menuData && menuData.length > 0) {
|
if (menuData && menuData.length > 0) {
|
||||||
commit('SET_PERMISSIONLIST', menuData)
|
commit('SET_PERMISSIONLIST', menuData)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -8,8 +8,11 @@ export const DEFAULT_FIXED_HEADER = 'DEFAULT_FIXED_HEADER'
|
|||||||
export const DEFAULT_FIXED_SIDEMENU= 'DEFAULT_FIXED_SIDEMENU'
|
export const DEFAULT_FIXED_SIDEMENU= 'DEFAULT_FIXED_SIDEMENU'
|
||||||
export const DEFAULT_FIXED_HEADER_HIDDEN = 'DEFAULT_FIXED_HEADER_HIDDEN'
|
export const DEFAULT_FIXED_HEADER_HIDDEN = 'DEFAULT_FIXED_HEADER_HIDDEN'
|
||||||
export const DEFAULT_CONTENT_WIDTH_TYPE = 'DEFAULT_CONTENT_WIDTH_TYPE'
|
export const DEFAULT_CONTENT_WIDTH_TYPE = 'DEFAULT_CONTENT_WIDTH_TYPE'
|
||||||
|
export const DEFAULT_MULTI_PAGE = 'DEFAULT_MULTI_PAGE'
|
||||||
export const USER_NAME = 'Login_Username'
|
export const USER_NAME = 'Login_Username'
|
||||||
export const USER_INFO = 'Login_Userinfo'
|
export const USER_INFO = 'Login_Userinfo'
|
||||||
|
export const USER_AUTH = 'LOGIN_USER_BUTTON_AUTH'
|
||||||
|
export const SYS_BUTTON_AUTH = 'SYS_BUTTON_AUTH'
|
||||||
|
|
||||||
export const CONTENT_WIDTH_TYPE = {
|
export const CONTENT_WIDTH_TYPE = {
|
||||||
Fluid: 'Fluid',
|
Fluid: 'Fluid',
|
||||||
|
|||||||
@ -5,7 +5,9 @@ const FormTypes = {
|
|||||||
checkbox: 'checkbox',
|
checkbox: 'checkbox',
|
||||||
select: 'select',
|
select: 'select',
|
||||||
date: 'date',
|
date: 'date',
|
||||||
datetime: 'datetime'
|
datetime: 'datetime',
|
||||||
|
upload: 'upload',
|
||||||
|
slot: 'slot'
|
||||||
}
|
}
|
||||||
const VALIDATE_NO_PASSED = Symbol()
|
const VALIDATE_NO_PASSED = Symbol()
|
||||||
export { FormTypes, VALIDATE_NO_PASSED }
|
export { FormTypes, VALIDATE_NO_PASSED }
|
||||||
|
|||||||
112
ant-design-jeecg-vue/src/utils/authFilter.js
Normal file
112
ant-design-jeecg-vue/src/utils/authFilter.js
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
|
||||||
|
import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
|
||||||
|
|
||||||
|
export function disabledAuthFilter(code,formData) {
|
||||||
|
if(nodeDisabledAuth(code,formData)){
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return globalDisabledAuth(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function nodeDisabledAuth(code,formData){
|
||||||
|
console.log("页面权限禁用--NODE--开始");
|
||||||
|
var permissionList = [];
|
||||||
|
try {
|
||||||
|
var obj = formData;
|
||||||
|
//console.log("页面权限禁用--NODE--开始",obj);
|
||||||
|
if (obj) {
|
||||||
|
let bpmList = obj.permissionList;
|
||||||
|
for (var bpm of bpmList) {
|
||||||
|
if(bpm.type == '2') {
|
||||||
|
permissionList.push(bpm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
//console.log("页面权限异常----", e);
|
||||||
|
}
|
||||||
|
if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let permissions = [];
|
||||||
|
for (var item of permissionList) {
|
||||||
|
if(item.type == '2') {
|
||||||
|
permissions.push(item.action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log("页面权限----"+code);
|
||||||
|
if (!permissions.includes(code)) {
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
for (var item2 of permissionList) {
|
||||||
|
if(code === item2.action){
|
||||||
|
console.log("页面权限禁用--NODE--生效");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function globalDisabledAuth(code){
|
||||||
|
console.log("页面禁用权限--Global--开始");
|
||||||
|
|
||||||
|
var permissionList = [];
|
||||||
|
var allPermissionList = [];
|
||||||
|
|
||||||
|
//let authList = Vue.ls.get(USER_AUTH);
|
||||||
|
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
|
||||||
|
for (var auth of authList) {
|
||||||
|
if(auth.type == '2') {
|
||||||
|
permissionList.push(auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
|
||||||
|
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
|
||||||
|
for (var gauth of allAuthList) {
|
||||||
|
if(gauth.type == '2') {
|
||||||
|
allPermissionList.push(gauth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//设置全局配置是否有命中
|
||||||
|
var gFlag = false;//禁用命中
|
||||||
|
var invalidFlag = false;//无效命中
|
||||||
|
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
|
||||||
|
for (var itemG of allPermissionList) {
|
||||||
|
if(code === itemG.action){
|
||||||
|
if(itemG.status == '0'){
|
||||||
|
invalidFlag = true;
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
gFlag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(invalidFlag){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) {
|
||||||
|
return gFlag;
|
||||||
|
}
|
||||||
|
let permissions = [];
|
||||||
|
for (var item of permissionList) {
|
||||||
|
if(item.type == '2') {
|
||||||
|
permissions.push(item.action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log("页面禁用权限----"+code);
|
||||||
|
if (!permissions.includes(code)) {
|
||||||
|
return gFlag;
|
||||||
|
}else{
|
||||||
|
for (var item2 of permissionList) {
|
||||||
|
if(code === item2.action){
|
||||||
|
console.log("页面权限解除禁用--Global--生效");
|
||||||
|
gFlag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gFlag;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,27 +1,116 @@
|
|||||||
|
import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
|
||||||
|
|
||||||
const hasPermission = {
|
const hasPermission = {
|
||||||
install (Vue, options) {
|
install (Vue, options) {
|
||||||
console.log(options);
|
console.log(options);
|
||||||
Vue.directive('has', {
|
Vue.directive('has', {
|
||||||
inserted: (el, binding, vnode)=>{
|
inserted: (el, binding, vnode)=>{
|
||||||
console.log("页面权限----",el);
|
console.log("页面权限控制----");
|
||||||
let permissionList = vnode.context.$route.meta.permissionList;
|
//节点权限处理,如果命中则不进行全局权限处理
|
||||||
if (permissionList === null || permissionList === "" || permissionList === undefined) {
|
if(!filterNodePermission(el, binding, vnode)){
|
||||||
el.parentNode.removeChild(el)
|
filterGlobalPermission(el, binding, vnode);
|
||||||
return
|
}
|
||||||
}
|
|
||||||
let permissions = [];
|
|
||||||
for (var item of permissionList) {
|
|
||||||
permissions.push(item.action);
|
|
||||||
}
|
|
||||||
//console.log("页面权限----"+permissions);
|
|
||||||
//console.log("页面权限----"+binding.value);
|
|
||||||
if (!permissions.includes(binding.value)) {
|
|
||||||
//if(el.parentNode)
|
|
||||||
el.parentNode.removeChild(el)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局权限控制
|
||||||
|
*/
|
||||||
|
export function filterNodePermission(el, binding, vnode) {
|
||||||
|
console.log("页面权限--NODE--");
|
||||||
|
|
||||||
|
var permissionList = [];
|
||||||
|
try {
|
||||||
|
var obj = vnode.context.$props.formData;
|
||||||
|
if (obj) {
|
||||||
|
let bpmList = obj.permissionList;
|
||||||
|
for (var bpm of bpmList) {
|
||||||
|
if(bpm.type != '2') {
|
||||||
|
permissionList.push(bpm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
//console.log("页面权限异常----", e);
|
||||||
|
}
|
||||||
|
if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) {
|
||||||
|
//el.parentNode.removeChild(el)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let permissions = [];
|
||||||
|
for (var item of permissionList) {
|
||||||
|
if(item.type != '2') {
|
||||||
|
permissions.push(item.action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log("页面权限----"+permissions);
|
||||||
|
//console.log("页面权限----"+binding.value);
|
||||||
|
if (!permissions.includes(binding.value)) {
|
||||||
|
//el.parentNode.removeChild(el)
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
for (var item2 of permissionList) {
|
||||||
|
if(binding.value === item2.action){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局权限控制
|
||||||
|
*/
|
||||||
|
export function filterGlobalPermission(el, binding, vnode) {
|
||||||
|
console.log("页面权限--Global--");
|
||||||
|
|
||||||
|
var permissionList = [];
|
||||||
|
var allPermissionList = [];
|
||||||
|
|
||||||
|
//let authList = Vue.ls.get(USER_AUTH);
|
||||||
|
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
|
||||||
|
for (var auth of authList) {
|
||||||
|
if(auth.type != '2') {
|
||||||
|
permissionList.push(auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log("页面权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
|
||||||
|
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
|
||||||
|
for (var gauth of allAuthList) {
|
||||||
|
if(gauth.type != '2') {
|
||||||
|
allPermissionList.push(gauth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//设置全局配置是否有命中
|
||||||
|
var invalidFlag = false;//无效命中
|
||||||
|
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
|
||||||
|
for (var itemG of allPermissionList) {
|
||||||
|
if(binding.value === itemG.action){
|
||||||
|
if(itemG.status == '0'){
|
||||||
|
invalidFlag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(invalidFlag){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) {
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let permissions = [];
|
||||||
|
for (var item of permissionList) {
|
||||||
|
if(item.type != '2'){
|
||||||
|
permissions.push(item.action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!permissions.includes(binding.value)) {
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default hasPermission;
|
export default hasPermission;
|
||||||
|
|||||||
@ -136,8 +136,8 @@ function generateChildRouters (data) {
|
|||||||
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置,判断是否路由菜单字段,动态选择是否生成路由(为了支持参数URL菜单)------
|
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置,判断是否路由菜单字段,动态选择是否生成路由(为了支持参数URL菜单)------
|
||||||
//判断是否生成路由
|
//判断是否生成路由
|
||||||
if(item.route && item.route === '0'){
|
if(item.route && item.route === '0'){
|
||||||
console.log(' 不生成路由 item.route: '+item.route);
|
//console.log(' 不生成路由 item.route: '+item.route);
|
||||||
console.log(' 不生成路由 item.path: '+item.path);
|
//console.log(' 不生成路由 item.path: '+item.path);
|
||||||
}else{
|
}else{
|
||||||
routers.push(menu);
|
routers.push(menu);
|
||||||
}
|
}
|
||||||
@ -157,12 +157,30 @@ export function cloneObject(obj) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 随机生成数字
|
* 随机生成数字
|
||||||
* @param min 最小值
|
*
|
||||||
* @param max 最大值
|
* 示例:生成长度为 12 的随机数:randomNumber(12)
|
||||||
|
* 示例:生成 3~23 之间的随机数:randomNumber(3, 23)
|
||||||
|
*
|
||||||
|
* @param1 最小值 | 长度
|
||||||
|
* @param2 最大值
|
||||||
* @return int 生成后的数字
|
* @return int 生成后的数字
|
||||||
*/
|
*/
|
||||||
export function randomNumber(min, max) {
|
export function randomNumber() {
|
||||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
// 生成 最小值 到 最大值 区间的随机数
|
||||||
|
const random = (min, max) => {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||||
|
}
|
||||||
|
if (arguments.length === 1) {
|
||||||
|
let [length] = arguments
|
||||||
|
// 生成指定长度的随机数字,首位一定不是 0
|
||||||
|
let nums = [...Array(length).keys()].map((i) => (i > 0 ? random(0, 9) : random(1, 9)))
|
||||||
|
return parseInt(nums.join(''))
|
||||||
|
} else if (arguments.length >= 2) {
|
||||||
|
let [min, max] = arguments
|
||||||
|
return random(min, max)
|
||||||
|
} else {
|
||||||
|
return Number.NaN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,35 +210,12 @@ export function randomUUID() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【顶部导航栏模式】
|
* 下划线转驼峰
|
||||||
* @date 2019-04-08
|
* @param string
|
||||||
* 顶部导航栏滚动条位置滚动到选中的菜单处
|
* @returns {*}
|
||||||
* @param doc document 对象
|
|
||||||
*/
|
*/
|
||||||
export function topNavScrollToSelectItem(doc) {
|
export function underLine2CamelCase(string){
|
||||||
let scrollWidth = doc.getElementById('top-nav-scroll-width')
|
return string.replace( /_([a-z])/g, function( all, letter ) {
|
||||||
if (scrollWidth == null) return
|
return letter.toUpperCase();
|
||||||
let menu = scrollWidth.getElementsByClassName('ant-menu')[0]
|
});
|
||||||
if (menu) {
|
|
||||||
let menuItems = menu.getElementsByTagName('li')
|
|
||||||
for (let item of menuItems) {
|
|
||||||
let index1 = item.className.indexOf('ant-menu-item-selected') !== -1
|
|
||||||
let index2 = item.className.indexOf('ant-menu-submenu-selected') !== -1
|
|
||||||
if (index1 || index2) {
|
|
||||||
// scrollLeft = 选中项left - 选中项width - (第一个隐藏的div的宽度)
|
|
||||||
let scrollLeft = (item.offsetLeft - item.offsetWidth - (index1 ? 100 : 60))
|
|
||||||
let scrollView = doc.getElementById('top-nav-scroll-view')
|
|
||||||
// scrollTo() 方法存在兼容性问题
|
|
||||||
if (typeof scrollView.scrollTo === 'function') {
|
|
||||||
scrollView.scrollTo({
|
|
||||||
left: scrollLeft,
|
|
||||||
behavior: 'smooth'
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
scrollView.scrollLeft = scrollLeft
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
5
ant-design-jeecg-vue/src/utils/vueBus.js
Normal file
5
ant-design-jeecg-vue/src/utils/vueBus.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import Bus from 'vue';
|
||||||
|
let install = function (Vue) {
|
||||||
|
Vue.prototype.$bus = new Bus()
|
||||||
|
}
|
||||||
|
export default { install };
|
||||||
119
ant-design-jeecg-vue/src/views/jeecg/ImagPreview.vue
Normal file
119
ant-design-jeecg-vue/src/views/jeecg/ImagPreview.vue
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<a-col :span="18">
|
||||||
|
<a-spin tip="Loading..." :spinning="spinning">
|
||||||
|
<div>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="18">
|
||||||
|
<p>
|
||||||
|
<a-divider orientation="left">组一</a-divider>
|
||||||
|
</p>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="6"></a-col>
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<a-col :span="12">
|
||||||
|
<template>
|
||||||
|
<div v-for="(fileDetail,index) in dataSource[0].fileDetails" :key="index">
|
||||||
|
<div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
|
||||||
|
<div
|
||||||
|
style="width: 100%;height: 100%;position: relative;padding: 8px;border: 1px solid #d9d9d9;border-radius: 4px;">
|
||||||
|
<img style="width: 100%;" :src="fileDetail.imgUrl" :preview="dataSource[0].key">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="18">
|
||||||
|
<p>
|
||||||
|
<a-divider orientation="left">组二</a-divider>
|
||||||
|
</p>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="6"></a-col>
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<a-col :span="12">
|
||||||
|
<template>
|
||||||
|
<div v-for="(fileDetail,index) in dataSource[1].fileDetails" :key="index">
|
||||||
|
<div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
|
||||||
|
<div
|
||||||
|
style="width: 100%;height: 100%;position: relative;padding: 8px;border: 1px solid #d9d9d9;border-radius: 4px;">
|
||||||
|
<img style="width: 100%;" :src="fileDetail.imgUrl" :preview="dataSource[1].key">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
<p></p>
|
||||||
|
</a-col>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import ARow from 'ant-design-vue/es/grid/Row'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ImagPreview',
|
||||||
|
components: {
|
||||||
|
ARow
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: '电子档补扫页面',
|
||||||
|
spinning:false,
|
||||||
|
//数据集
|
||||||
|
dataSource: [{
|
||||||
|
key:0,
|
||||||
|
fileDetails:[
|
||||||
|
{
|
||||||
|
imgUrl:"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imgUrl:"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imgUrl:"https://ss0.bdstatic.com/6Ox1bjeh1BF3odCf/it/u=3660968530,985748925&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=5e64af964be378c6c2a3b0acc65dfe24"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},{
|
||||||
|
key:1,
|
||||||
|
fileDetails:[
|
||||||
|
{
|
||||||
|
imgUrl:"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imgUrl:"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&fm=27&gp=0.jpg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
url: {
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.table-operator {
|
||||||
|
margin-bottom: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clName .ant-tree li span.ant-tree-switcher, .ant-tree li span.ant-tree-iconEle {
|
||||||
|
width: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clName .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
|
||||||
|
background-color: #1890FF !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
75
ant-design-jeecg-vue/src/views/jeecg/ImgDragSort.vue
Normal file
75
ant-design-jeecg-vue/src/views/jeecg/ImgDragSort.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<a-card>
|
||||||
|
<draggable @end="end" :options="{animation: 300}" v-model="dataSource" style="display: inline-block">
|
||||||
|
<template v-for="(data,index) in dataSource">
|
||||||
|
<div style="float: left;width:150px;height:150px;margin-right: 10px;margin: 0 8px 8px 0;" :key="index">
|
||||||
|
<div style="width: 100%;height: 100%;position: relative;padding: 8px;border: 1px solid #d9d9d9;border-radius: 4px;">
|
||||||
|
<img style="width: 100%;" :src="data.filePath" preview="index">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<a-button @click="sureChange" type="primary" style="margin-top: 115px">确定</a-button>
|
||||||
|
</draggable>
|
||||||
|
<br/>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="12">
|
||||||
|
<p>拖拽前json数据:</p>
|
||||||
|
<textarea rows="25" style="width: 780px">{{ oldDateSource }}</textarea>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<p>拖拽后json数据:</p>
|
||||||
|
<textarea rows="25" style="width: 780px">{{ newDateSource }}</textarea>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import draggable from 'vuedraggable'
|
||||||
|
import ARow from 'ant-design-vue/es/grid/Row'
|
||||||
|
import ACol from 'ant-design-vue/es/grid/Col'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ImgDragSort',
|
||||||
|
components:{
|
||||||
|
ACol,
|
||||||
|
ARow,
|
||||||
|
draggable
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: '图片拖拽排序',
|
||||||
|
spinning: false,
|
||||||
|
//数据集
|
||||||
|
dataSource: [
|
||||||
|
{id:'000',sort: 0,filePath: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg'},
|
||||||
|
{id:'111',sort: 1,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg'},
|
||||||
|
{id:'222',sort: 2,filePath: 'https://ss0.bdstatic.com/6Ox1bjeh1BF3odCf/it/u=3660968530,985748925&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=5e64af964be378c6c2a3b0acc65dfe24'},
|
||||||
|
{id:'333',sort: 3,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg'},
|
||||||
|
{id:'444',sort: 4,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&fm=27&gp=0.jpg'}
|
||||||
|
],
|
||||||
|
oldDateSource:[],
|
||||||
|
newDateSource:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.oldDateSource = this.dataSource;
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
end: function (evt) {
|
||||||
|
console.log("拖动前的位置"+evt.oldIndex);
|
||||||
|
console.log("拖动后的位置"+evt.newIndex);
|
||||||
|
},
|
||||||
|
sureChange(){
|
||||||
|
for(var i=0;i<this.dataSource.length;i++){
|
||||||
|
this.dataSource[i].sort = i;
|
||||||
|
}
|
||||||
|
this.newDateSource = this.dataSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
147
ant-design-jeecg-vue/src/views/jeecg/ImgTurnPage.vue
Normal file
147
ant-design-jeecg-vue/src/views/jeecg/ImgTurnPage.vue
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<a-card title="树形结构图片翻页查看" style="min-width: 800px;overflow-x:auto ">
|
||||||
|
<a-row>
|
||||||
|
<!-- 左侧文件树 -->
|
||||||
|
<a-col :span="5">
|
||||||
|
<a-tree
|
||||||
|
showLine
|
||||||
|
:treeData="treeData"
|
||||||
|
:expandedKeys="[expandedKeys[0]]"
|
||||||
|
:selectedKeys="selectedKeys"
|
||||||
|
:style="{'height':'500px','border-right':'2px solid #c1c1c1','overflow-y':'auto'}"
|
||||||
|
@expand="onExpand"
|
||||||
|
@select="this.onSelect"
|
||||||
|
>
|
||||||
|
</a-tree>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<!--右侧缩略图-->
|
||||||
|
<a-col :span="19">
|
||||||
|
<a-row style="margin-top: 10px">
|
||||||
|
<a-col :span="24" style="padding-left: 2%;margin-bottom: 10px">
|
||||||
|
<a-button @click="prev" type="primary"><a-icon type="left" />上一页</a-button>
|
||||||
|
<a-button @click="next" type="primary" style="margin-left: 8px">下一页<a-icon type="right" /></a-button>
|
||||||
|
<span style="margin-left: 15%;font-weight: bolder">{{ navName }}</span>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="24" style="padding-left: 2%;">
|
||||||
|
<img :src="imgUrl" preview>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ImgTurnPage',
|
||||||
|
components:{
|
||||||
|
draggable
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: '图片翻页',
|
||||||
|
//数据集
|
||||||
|
treeData: [{
|
||||||
|
title: '第一页',
|
||||||
|
key: '0-0',
|
||||||
|
children: [{
|
||||||
|
title: '1页',
|
||||||
|
key: '0-0-0',
|
||||||
|
imgUrl:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg'
|
||||||
|
}, {
|
||||||
|
title: '2页',
|
||||||
|
key: '0-0-1',
|
||||||
|
imgUrl:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg'
|
||||||
|
}]
|
||||||
|
},{
|
||||||
|
title: '第二页',
|
||||||
|
key: '0-1',
|
||||||
|
children: [{
|
||||||
|
title: '1页',
|
||||||
|
key: '0-1-0',
|
||||||
|
imgUrl:'https://ss0.bdstatic.com/6Ox1bjeh1BF3odCf/it/u=3660968530,985748925&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=5e64af964be378c6c2a3b0acc65dfe24'
|
||||||
|
}, {
|
||||||
|
title: '2页',
|
||||||
|
key: '0-1-1',
|
||||||
|
imgUrl:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg'
|
||||||
|
}]
|
||||||
|
},{
|
||||||
|
title: '第三页',
|
||||||
|
key: '0-2',
|
||||||
|
children: [{
|
||||||
|
title: '1页',
|
||||||
|
key: '0-2-0',
|
||||||
|
imgUrl:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&fm=27&gp=0.jpg'
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
selectedKeys:[],
|
||||||
|
expandedKeys:[],
|
||||||
|
sort:0,
|
||||||
|
imgUrl:'',
|
||||||
|
navName:'',
|
||||||
|
imgList:[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.getImgList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getImgList(){
|
||||||
|
var count = 0;
|
||||||
|
for(var i=0;i<this.treeData.length;i++){
|
||||||
|
for(var j=0;j<this.treeData[i].children.length;j++){
|
||||||
|
this.imgList.push({key:this.treeData[i].children[j].key,pkey:this.treeData[i].key,sort:count++,
|
||||||
|
imgUrl:this.treeData[i].children[j].imgUrl,navName:this.treeData[i].title+"/"+this.treeData[i].children[j].title})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setValue(this.imgList[this.sort]);
|
||||||
|
},
|
||||||
|
onSelect (selectedKeys, info) {
|
||||||
|
for(var i=0;i<this.imgList.length;i++){
|
||||||
|
if(this.imgList[i].key === selectedKeys[0]){
|
||||||
|
this.sort = this.imgList[i].sort;
|
||||||
|
this.setValue(this.imgList[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onExpand (expandedKeys) {
|
||||||
|
this.expandedKeys = [];
|
||||||
|
if(expandedKeys !== null && expandedKeys !== ''){
|
||||||
|
this.expandedKeys[0] = expandedKeys[1];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
prev(){
|
||||||
|
if(this.sort === 0){
|
||||||
|
this.sort = this.imgList.length-1;
|
||||||
|
}else{
|
||||||
|
this.sort = this.sort - 1;
|
||||||
|
}
|
||||||
|
this.setValue(this.imgList[this.sort]);
|
||||||
|
},
|
||||||
|
next(){
|
||||||
|
if(this.sort === this.imgList.length-1){
|
||||||
|
this.sort = 0;
|
||||||
|
}else{
|
||||||
|
this.sort = this.sort + 1;
|
||||||
|
}
|
||||||
|
this.setValue(this.imgList[this.sort]);
|
||||||
|
},
|
||||||
|
// 设置受控节点值
|
||||||
|
setValue(value){
|
||||||
|
this.selectedKeys = [];
|
||||||
|
this.imgUrl = value.imgUrl;
|
||||||
|
this.selectedKeys[0] = value.key;
|
||||||
|
this.expandedKeys[0] = value.pkey;
|
||||||
|
this.navName = value.navName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -1,43 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<a-input-search
|
|
||||||
v-model="this.selectedUserNames"
|
|
||||||
placeholder="请先选择用户"
|
|
||||||
disabled
|
|
||||||
@search="onSearch"
|
|
||||||
size="large">
|
|
||||||
<a-button slot="enterButton">选择用户</a-button>
|
|
||||||
</a-input-search>
|
|
||||||
|
|
||||||
<j-search-user-by-dep-modal ref="JSearchUserByDepModal" @ok="modalFormOk"></j-search-user-by-dep-modal>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import JSearchUserByDepModal from '@/components/jeecgbiz/JSearchUserByDepModal'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'JSearchUserByDepList',
|
|
||||||
components: {
|
|
||||||
JSearchUserByDepModal,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedUserNames: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onSearch() {
|
|
||||||
this.$refs.JSearchUserByDepModal.showModal();
|
|
||||||
this.selectedUserNames = '';
|
|
||||||
this.$refs.JSearchUserByDepModal.title = '根据部门查询用户';
|
|
||||||
},
|
|
||||||
modalFormOk(selectedValue) {
|
|
||||||
this.selectedUserNames = selectedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -61,8 +61,8 @@
|
|||||||
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
||||||
<a-button type="primary" icon="plus" @click="jump">创建单据</a-button>
|
<a-button type="primary" icon="plus" @click="jump">创建单据</a-button>
|
||||||
<a-button type="primary" icon="plus" @click="onetomany">一对多</a-button>
|
<a-button type="primary" icon="plus" @click="onetomany">一对多</a-button>
|
||||||
<a-button type="primary" icon="download" @click="exportXls">导出</a-button>
|
<a-button type="primary" icon="download" @click="handleExportXls('demo')">导出</a-button>
|
||||||
<a-upload name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl" @change="handleImportExcel">
|
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
|
||||||
<a-button type="primary" icon="import">导入</a-button>
|
<a-button type="primary" icon="import">导入</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||||
@ -231,28 +231,12 @@
|
|||||||
list: "/test/jeecgDemo/list",
|
list: "/test/jeecgDemo/list",
|
||||||
delete: "/test/jeecgDemo/delete",
|
delete: "/test/jeecgDemo/delete",
|
||||||
deleteBatch: "/test/jeecgDemo/deleteBatch",
|
deleteBatch: "/test/jeecgDemo/deleteBatch",
|
||||||
|
exportXlsUrl: "/test/jeecgDemo/exportXls"
|
||||||
},
|
},
|
||||||
fieldList:superQueryFieldList
|
fieldList:superQueryFieldList
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
exportXls(){
|
|
||||||
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
|
|
||||||
console.log('paramsStr: ' + paramsStr)
|
|
||||||
let url = `${window._CONFIG['domianURL']}/test/jeecgDemo/exportXls?paramsStr=${paramsStr}`;
|
|
||||||
window.location.href = url;
|
|
||||||
},
|
|
||||||
handleImportExcel(info){
|
|
||||||
if (info.file.status !== 'uploading') {
|
|
||||||
console.log(info.file, info.fileList);
|
|
||||||
}
|
|
||||||
if (info.file.status === 'done') {
|
|
||||||
this.$message.success(`${info.file.name} 文件上传成功`);
|
|
||||||
this.loadData();
|
|
||||||
} else if (info.file.status === 'error') {
|
|
||||||
this.$message.error(`${info.file.name} 文件上传失败.`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initDictConfig() {
|
initDictConfig() {
|
||||||
console.log("--我才是真的方法!--")
|
console.log("--我才是真的方法!--")
|
||||||
//初始化字典 - 性别
|
//初始化字典 - 性别
|
||||||
|
|||||||
@ -23,18 +23,23 @@
|
|||||||
:rowSelection="true"
|
:rowSelection="true"
|
||||||
:actionButton="true"
|
:actionButton="true"
|
||||||
style="margin-top: 8px;"
|
style="margin-top: 8px;"
|
||||||
@selectRowChange="handleSelectRowChange"/>
|
@selectRowChange="handleSelectRowChange">
|
||||||
|
|
||||||
|
<template v-slot:action="props">
|
||||||
|
<a @click="handleDelete(props)">{{ props.text }}</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</j-editable-table>
|
||||||
|
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
import JEditableTable from '@/components/jeecg/JEditableTable'
|
import JEditableTable from '@/components/jeecg/JEditableTable'
|
||||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||||
import { randomUUID, randomString, randomNumber } from '@/utils/util'
|
import { randomUUID, randomNumber } from '@/utils/util'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JeecgEditableTableExample',
|
name: 'JeecgEditableTableExample',
|
||||||
@ -48,7 +53,8 @@
|
|||||||
{
|
{
|
||||||
title: '字段名称',
|
title: '字段名称',
|
||||||
key: 'dbFieldName',
|
key: 'dbFieldName',
|
||||||
width: '19%',
|
// width: '19%',
|
||||||
|
width: '300px',
|
||||||
type: FormTypes.input,
|
type: FormTypes.input,
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
placeholder: '请输入${title}',
|
placeholder: '请输入${title}',
|
||||||
@ -64,18 +70,21 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '字段备注',
|
title: '文件域',
|
||||||
key: 'dbFieldTxt',
|
key: 'upload',
|
||||||
width: '19%',
|
type: FormTypes.upload,
|
||||||
type: FormTypes.input,
|
// width: '19%',
|
||||||
defaultValue: '',
|
width: '300px',
|
||||||
placeholder: '请输入${title}',
|
placeholder: '点击上传',
|
||||||
validateRules: [{ required: true, message: '请输入${title}' }]
|
token: true,
|
||||||
|
responseName: 'message',
|
||||||
|
action: window._CONFIG['domianURL'] + '/sys/common/upload'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '字段类型',
|
title: '字段类型',
|
||||||
key: 'dbFieldType',
|
key: 'dbFieldType',
|
||||||
width: '18%',
|
// width: '18%',
|
||||||
|
width: '300px',
|
||||||
type: FormTypes.select,
|
type: FormTypes.select,
|
||||||
options: [ // 下拉选项
|
options: [ // 下拉选项
|
||||||
{ title: 'String', value: 'string' },
|
{ title: 'String', value: 'string' },
|
||||||
@ -86,32 +95,61 @@
|
|||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
placeholder: '请选择${title}',
|
placeholder: '请选择${title}',
|
||||||
validateRules: [{ required: true, message: '请选择${title}' }]
|
validateRules: [{ required: true, message: '请选择${title}' }]
|
||||||
|
}, {
|
||||||
|
title: '多选测试',
|
||||||
|
key: 'multipleSelect',
|
||||||
|
// width: '18%',
|
||||||
|
width: '300px',
|
||||||
|
type: FormTypes.select,
|
||||||
|
props: { 'mode': 'multiple' }, // 支持多选
|
||||||
|
options: [
|
||||||
|
{ title: 'String', value: 'string' },
|
||||||
|
{ title: 'Integer', value: 'int' },
|
||||||
|
{ title: 'Double', value: 'double' },
|
||||||
|
{ title: 'Boolean', value: 'boolean' }
|
||||||
|
],
|
||||||
|
defaultValue: ['int', 'boolean'], // 多个默认项
|
||||||
|
// defaultValue: 'string,double,int', // 也可使用这种方式
|
||||||
|
placeholder: '这里可以多选',
|
||||||
|
validateRules: [{ required: true, message: '请选择${title}' }]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '字段长度',
|
title: '字段长度',
|
||||||
key: 'dbLength',
|
key: 'dbLength',
|
||||||
width: '8%',
|
// width: '8%',
|
||||||
|
width: '100px',
|
||||||
type: FormTypes.inputNumber,
|
type: FormTypes.inputNumber,
|
||||||
defaultValue: 32,
|
defaultValue: 32,
|
||||||
placeholder: '${title}',
|
placeholder: '${title}',
|
||||||
validateRules: [{ required: true, message: '请输入${title}' }]
|
validateRules: [{ required: true, message: '请输入${title}' }]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '默认值',
|
title: '日期',
|
||||||
key: 'dbDefaultVal',
|
key: 'datetime',
|
||||||
width: '22%',
|
// width: '22%',
|
||||||
type: FormTypes.input,
|
width: '320px',
|
||||||
defaultValue: '',
|
type: FormTypes.datetime,
|
||||||
placeholder: '请输入${title}',
|
defaultValue: '2019-4-30 14:52:22',
|
||||||
validateRules: [{ required: true, message: '请输入${title}' }]
|
placeholder: '请选择${title}',
|
||||||
|
validateRules: [{ required: true, message: '请选择${title}' }]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '可以为空',
|
title: '可以为空',
|
||||||
key: 'isNull',
|
key: 'isNull',
|
||||||
width: '8%',
|
// width: '8%',
|
||||||
|
width: '100px',
|
||||||
type: FormTypes.checkbox,
|
type: FormTypes.checkbox,
|
||||||
customValue: ['Y', 'N'], // true ,false
|
customValue: ['Y', 'N'], // true ,false
|
||||||
defaultChecked: false
|
defaultChecked: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
// width: '8%',
|
||||||
|
width: '100px',
|
||||||
|
type: FormTypes.slot,
|
||||||
|
slot: 'action',
|
||||||
|
defaultValue:"删除"
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
@ -161,26 +199,44 @@
|
|||||||
randomData(size, loading = false) {
|
randomData(size, loading = false) {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
setTimeout(() => {
|
|
||||||
this.loading = false
|
|
||||||
}, 3000)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let randomDatetime = () => {
|
||||||
|
let time = parseInt(randomNumber(1000, 9999999999999))
|
||||||
|
return moment(new Date(time)).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
|
||||||
|
let begin = Date.now()
|
||||||
let values = []
|
let values = []
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
values.push({
|
values.push({
|
||||||
id: randomUUID(),
|
id: randomUUID(),
|
||||||
dbFieldName: `name_${i + 1}`,
|
dbFieldName: `name_${i + 1}`,
|
||||||
dbFieldTxt: randomString(10),
|
// dbFieldTxt: randomString(10),
|
||||||
|
multipleSelect: ['string', ['int', 'double', 'boolean'][randomNumber(0, 2)]],
|
||||||
dbFieldType: ['string', 'int', 'double', 'boolean'][randomNumber(0, 3)],
|
dbFieldType: ['string', 'int', 'double', 'boolean'][randomNumber(0, 3)],
|
||||||
dbLength: randomNumber(0, 233),
|
dbLength: randomNumber(0, 233),
|
||||||
dbDefaultVal: randomString(8),
|
datetime: randomDatetime(),
|
||||||
isNull: ['Y', 'N'][randomNumber(0, 1)]
|
isNull: ['Y', 'N'][randomNumber(0, 1)]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.dataSource = values
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.dataSource = values
|
||||||
|
let end = Date.now()
|
||||||
|
let diff = end - begin
|
||||||
|
|
||||||
|
if (loading && diff < size) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false
|
||||||
|
}, size - diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
handleDelete(props) {
|
||||||
|
let { rowId, target } = props
|
||||||
|
target.removeRows(rowId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,8 +34,8 @@
|
|||||||
<!-- 操作按钮区域 -->
|
<!-- 操作按钮区域 -->
|
||||||
<div class="table-operator">
|
<div class="table-operator">
|
||||||
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
||||||
<a-button type="primary" icon="download" @click="exportXls">导出</a-button>
|
<a-button type="primary" icon="download" @click="handleExportXls('一对多示例')">导出</a-button>
|
||||||
<a-upload name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl" @change="handleImportExcel">
|
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
|
||||||
<a-button type="primary" icon="import">导入</a-button>
|
<a-button type="primary" icon="import">导入</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
|
|
||||||
@ -163,27 +163,11 @@
|
|||||||
list: "/test/jeecgOrderMain/list",
|
list: "/test/jeecgOrderMain/list",
|
||||||
delete: "/test/jeecgOrderMain/delete",
|
delete: "/test/jeecgOrderMain/delete",
|
||||||
deleteBatch: "/test/jeecgOrderMain/deleteBatch",
|
deleteBatch: "/test/jeecgOrderMain/deleteBatch",
|
||||||
|
exportXlsUrl: "/test/jeecgOrderMain/exportXls",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
exportXls(){
|
|
||||||
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
|
|
||||||
console.log('paramsStr: ' + paramsStr)
|
|
||||||
let url = `${window._CONFIG['domianURL']}/test/jeecgOrderMain/exportXls?paramsStr=${paramsStr}`;
|
|
||||||
window.location.href = url;
|
|
||||||
},
|
|
||||||
handleImportExcel(info){
|
|
||||||
if (info.file.status !== 'uploading') {
|
|
||||||
console.log(info.file, info.fileList);
|
|
||||||
}
|
|
||||||
if (info.file.status === 'done') {
|
|
||||||
this.$message.success(`${info.file.name} 文件上传成功`);
|
|
||||||
this.loadData();
|
|
||||||
} else if (info.file.status === 'error') {
|
|
||||||
this.$message.error(`${info.file.name} 文件上传失败.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
122
ant-design-jeecg-vue/src/views/jeecg/JeecgPdfView.vue
Normal file
122
ant-design-jeecg-vue/src/views/jeecg/JeecgPdfView.vue
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- 左侧文件树 -->
|
||||||
|
<a-col :span="4" class="clName">
|
||||||
|
<a-tree
|
||||||
|
:treeData="treeData"
|
||||||
|
:defaultExpandAll="defaultExpandAll"
|
||||||
|
@select="this.onSelect"
|
||||||
|
style="height: 500px;overflow-y: auto;"
|
||||||
|
>
|
||||||
|
</a-tree>
|
||||||
|
</a-col>
|
||||||
|
<!-- 中间面板 -->
|
||||||
|
<a-col :span="2"/>
|
||||||
|
<!--右侧缩略图-->
|
||||||
|
<a-col :span="18">
|
||||||
|
<a-spin tip="Loading..." :spinning="spinning">
|
||||||
|
<div v-for="(file, key) in dataSource" :key="key">
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="24"><p><a-divider orientation="left">{{ file.fileName }}</a-divider></p></a-col>
|
||||||
|
<!-- 预览区域 -->
|
||||||
|
<a-col :span="24">
|
||||||
|
<template v-if="file.filePdfPath">
|
||||||
|
<div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
|
||||||
|
<div style="width: 100%;height: 100%;position: relative;padding: 8px;" @click="pdfPreview(file.title)">
|
||||||
|
<img style="width: 100%;" src="~@/assets/pdf4.jpg">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
(暂无材料,点击右侧"选择文件"或"扫描上传"上传文件)
|
||||||
|
</template>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</a-col>
|
||||||
|
<pdf-preview-modal ref="pdfmodal"></pdf-preview-modal >
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||||
|
import Vue from 'vue'
|
||||||
|
import PdfPreviewModal from './modules/PdfPreviewModal'
|
||||||
|
const mockdata=[{
|
||||||
|
"id": "1",
|
||||||
|
"key": "1",
|
||||||
|
"title": "实例.pdf",
|
||||||
|
"fileCode": "shili",
|
||||||
|
"fileName": "实例",
|
||||||
|
"filePdfPath": "实例"
|
||||||
|
}]
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "JeecgPdfView",
|
||||||
|
components:{
|
||||||
|
PdfPreviewModal
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
description: 'PDF预览页面',
|
||||||
|
// 文件类型集
|
||||||
|
treeData:[{
|
||||||
|
title: '所有PDF电子档',
|
||||||
|
key: '0-0',
|
||||||
|
children: mockdata }],
|
||||||
|
// 文件数据集
|
||||||
|
dataSource: mockdata,
|
||||||
|
allData:mockdata,
|
||||||
|
// 上传文件集
|
||||||
|
defaultExpandAll: true,
|
||||||
|
// 加载中
|
||||||
|
spinning:false,
|
||||||
|
url: {
|
||||||
|
pdfList: "/api/pdfList",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
//this.loadData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadData (){
|
||||||
|
this.spinning = false;
|
||||||
|
getAction(this.url.pdfList).then((res)=>{
|
||||||
|
if(res.length>0){
|
||||||
|
this.allData = res;
|
||||||
|
this.dataSource = res;
|
||||||
|
this.treeData[0].children = res;
|
||||||
|
}
|
||||||
|
this.spinning = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
pdfPreview:function(title){
|
||||||
|
const token = Vue.ls.get(ACCESS_TOKEN);
|
||||||
|
this.headers = {"X-Access-Token":token}
|
||||||
|
this.$refs.pdfmodal.previewFiles(title,token);
|
||||||
|
},
|
||||||
|
// 选择文件类型
|
||||||
|
onSelect (selectedKeys, info) {
|
||||||
|
this.dataSource = [];
|
||||||
|
if(selectedKeys[0] === undefined || selectedKeys[0] === '0-0'){
|
||||||
|
this.dataSource = this.allData;
|
||||||
|
}else{
|
||||||
|
this.dataSource.push(info.node._props.dataRef);
|
||||||
|
}
|
||||||
|
console.log("SELECT-->dataSource",this.dataSource );
|
||||||
|
},
|
||||||
|
// model回调
|
||||||
|
modalFormOk () {
|
||||||
|
this.loadData();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.clName .ant-tree li span.ant-tree-switcher, .ant-tree li span.ant-tree-iconEle{width:10px}
|
||||||
|
</style>
|
||||||
49
ant-design-jeecg-vue/src/views/jeecg/JeecgTreeTable.vue
Normal file
49
ant-design-jeecg-vue/src/views/jeecg/JeecgTreeTable.vue
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<j-tree-table :url="url" :columns="columns" :tableProps="tableProps"/>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JeecgTreeTable',
|
||||||
|
components: { JTreeTable },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
url: '/api/asynTreeList',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '菜单名称',
|
||||||
|
dataIndex: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '组件',
|
||||||
|
dataIndex: 'component'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排序',
|
||||||
|
dataIndex: 'orderNum'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
selectedRowKeys: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tableProps() {
|
||||||
|
let _this = this
|
||||||
|
return {
|
||||||
|
// 列表项是否可选择
|
||||||
|
// https://vue.ant.design/components/table-cn/#rowSelection
|
||||||
|
rowSelection: {
|
||||||
|
selectedRowKeys: _this.selectedRowKeys,
|
||||||
|
onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
250
ant-design-jeecg-vue/src/views/jeecg/JoaDemoList.vue
Normal file
250
ant-design-jeecg-vue/src/views/jeecg/JoaDemoList.vue
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
|
||||||
|
<!-- 查询区域 -->
|
||||||
|
<div class="table-page-search-wrapper">
|
||||||
|
<a-form layout="inline">
|
||||||
|
<a-row :gutter="24">
|
||||||
|
|
||||||
|
<a-col :md="6" :sm="8" class="1">
|
||||||
|
<a-form-item label="请假人">
|
||||||
|
<a-input placeholder="请输入请假人" v-model="queryParam.name"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="6" :sm="8" class="1">
|
||||||
|
<a-form-item label="请假天数">
|
||||||
|
<a-input placeholder="请输入请假天数" v-model="queryParam.days"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<template v-if="toggleSearchStatus">
|
||||||
|
<a-col :md="6" :sm="8">
|
||||||
|
<a-form-item label="开始时间">
|
||||||
|
<a-input placeholder="请输入开始时间" v-model="queryParam.beginDate"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="6" :sm="8">
|
||||||
|
<a-form-item label="请假结束时间">
|
||||||
|
<a-input placeholder="请输入请假结束时间" v-model="queryParam.endDate"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="6" :sm="8">
|
||||||
|
<a-form-item label="请假原因">
|
||||||
|
<a-input placeholder="请输入请假原因" v-model="queryParam.reason"></a-input>
|
||||||
|
</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" :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">
|
||||||
|
<template v-if="record.bpmStatus === '1'">
|
||||||
|
<a @click="handleEdit(record)">编辑</a>
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click="startProcess(record)">提交流程</a>
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
</template>
|
||||||
|
<a-dropdown>
|
||||||
|
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
|
||||||
|
<a-menu slot="overlay">
|
||||||
|
<a-menu-item v-if="record.bpmStatus === '1'">
|
||||||
|
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
|
||||||
|
<a>删除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item v-else @click="handlePreviewPic(record)">审批进度</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</a-dropdown>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
<!-- table区域-end -->
|
||||||
|
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<form-common-modal ref="modalForm" :path="path" @ok="modalFormOk"></form-common-modal>
|
||||||
|
<!-- 审批流程 -->
|
||||||
|
<process-inst-pic-modal ref="processInstPicModal"></process-inst-pic-modal>
|
||||||
|
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { postAction } from '@/api/manage'
|
||||||
|
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||||
|
import JDate from '@/components/jeecg/JDate.vue'
|
||||||
|
import FormCommonModal from "@/components/bpm/FormCommonModal";
|
||||||
|
import ProcessInstPicModal from "@/components/bpm/ProcessInstPicModal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "JoaDemoList",
|
||||||
|
mixins:[JeecgListMixin],
|
||||||
|
components: {
|
||||||
|
FormCommonModal,
|
||||||
|
ProcessInstPicModal,
|
||||||
|
JDate
|
||||||
|
},
|
||||||
|
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: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请假天数',
|
||||||
|
align:"center",
|
||||||
|
dataIndex: 'days'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '开始时间',
|
||||||
|
align:"center",
|
||||||
|
dataIndex: 'beginDate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '结束时间',
|
||||||
|
align:"center",
|
||||||
|
dataIndex: 'endDate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请假原因',
|
||||||
|
align:"center",
|
||||||
|
dataIndex: 'reason'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '流程状态',
|
||||||
|
align:"center",
|
||||||
|
dataIndex: 'bpmStatus',
|
||||||
|
customRender:function (text) {
|
||||||
|
if(text=='1'){
|
||||||
|
return "待提交";
|
||||||
|
}else if(text=='2'){
|
||||||
|
return "处理中";
|
||||||
|
}else if(text=='3'){
|
||||||
|
return "已完成";
|
||||||
|
}else if(text=='4'){
|
||||||
|
return "已作废";
|
||||||
|
}else{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
align:"center",
|
||||||
|
scopedSlots: { customRender: 'action' },
|
||||||
|
}
|
||||||
|
],
|
||||||
|
flowCode:"dev_joa_demo_001",
|
||||||
|
path:"jeecg/modules/JoaDemoForm",
|
||||||
|
url: {
|
||||||
|
list: "/test/joaDemo/list",
|
||||||
|
delete: "/test/joaDemo/delete",
|
||||||
|
deleteBatch: "/test/joaDemo/deleteBatch",
|
||||||
|
exportXlsUrl: "test/joaDemo/exportXls",
|
||||||
|
importExcelUrl: "test/joaDemo/importExcel",
|
||||||
|
startProcess: "/process/extActProcess/startMutilProcess",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
importExcelUrl: function(){
|
||||||
|
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
startProcess: function(record){
|
||||||
|
var that = this;
|
||||||
|
this.$confirm({
|
||||||
|
title:"提示",
|
||||||
|
content:"确认提交流程吗?",
|
||||||
|
onOk: function(){
|
||||||
|
var param = {
|
||||||
|
flowCode:that.flowCode,
|
||||||
|
id:record.id,
|
||||||
|
formUrl:that.path,
|
||||||
|
formUrlMobile:that.path
|
||||||
|
}
|
||||||
|
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.flowCode;
|
||||||
|
var dataId = record.id;
|
||||||
|
this.$refs.processInstPicModal.preview(flowCode,dataId);
|
||||||
|
this.$refs.processInstPicModal.title="流程图";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
@import '~@assets/less/common.less'
|
||||||
|
</style>
|
||||||
285
ant-design-jeecg-vue/src/views/jeecg/RowspanTable.vue
Normal file
285
ant-design-jeecg-vue/src/views/jeecg/RowspanTable.vue
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- table区域-begin -->
|
||||||
|
<a-table
|
||||||
|
ref="table"
|
||||||
|
size="default"
|
||||||
|
bordered
|
||||||
|
rowKey="id"
|
||||||
|
:columns="columns"
|
||||||
|
:pagination="false"
|
||||||
|
:dataSource="dataSource">
|
||||||
|
|
||||||
|
</a-table>
|
||||||
|
<!-- table区域-end -->
|
||||||
|
|
||||||
|
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "RowspanTable",
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: '存放位置设置表管理页面',
|
||||||
|
levelNum:{},
|
||||||
|
gridNum:0,
|
||||||
|
boxNum:0,
|
||||||
|
cabinetNo:"",
|
||||||
|
// 表头
|
||||||
|
columns: [ {
|
||||||
|
title: '分组一',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'cabinetNo',
|
||||||
|
customRender: (value, row, index) => {
|
||||||
|
const obj = {
|
||||||
|
children: value,
|
||||||
|
attrs: {},
|
||||||
|
};
|
||||||
|
if(index===0){
|
||||||
|
obj.attrs.rowSpan = this.dataSource.length;
|
||||||
|
}else{
|
||||||
|
obj.attrs.rowSpan = 0;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '分组二',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'levelNo',
|
||||||
|
customRender: (value, row, index) => {
|
||||||
|
const obj = {
|
||||||
|
children: value,
|
||||||
|
attrs: {},
|
||||||
|
};
|
||||||
|
//当前列跨行的条数
|
||||||
|
var a = parseInt(this.levelNum);
|
||||||
|
var b = parseInt(this.gridNum)*parseInt(this.boxNum);
|
||||||
|
console.log(a);
|
||||||
|
for(var c=0;c<=a;c++){
|
||||||
|
if(index === (c*b)){
|
||||||
|
console.log(1);
|
||||||
|
console.log(c*b);
|
||||||
|
obj.attrs.rowSpan = b;
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
obj.attrs.rowSpan = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '分组三',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'gridNo',
|
||||||
|
customRender: (value, row, index) => {
|
||||||
|
const obj = {
|
||||||
|
children: value,
|
||||||
|
attrs: {},
|
||||||
|
};
|
||||||
|
var a = parseInt(this.levelNum)*parseInt(this.gridNum);
|
||||||
|
var b = parseInt(this.boxNum);
|
||||||
|
for(var c=0;c<=a;c++){
|
||||||
|
if(index === (c*b)){
|
||||||
|
obj.attrs.rowSpan = b;
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
obj.attrs.rowSpan = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
title: '字段一',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'boxNo'
|
||||||
|
}, {
|
||||||
|
title: '字段二',
|
||||||
|
align: 'center',
|
||||||
|
dataIndex: 'storedNum'
|
||||||
|
}, {
|
||||||
|
title: '字段三',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'maxNum'
|
||||||
|
},],
|
||||||
|
//数据集
|
||||||
|
dataSource: [{
|
||||||
|
"id": "cb1dfd12cbeca3f8ba121439ee7e2411",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "1",
|
||||||
|
"gridNo": "1",
|
||||||
|
"boxNo": "1",
|
||||||
|
"storedNum": 2,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 2,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "1",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-02"
|
||||||
|
}, {
|
||||||
|
"id": "f903d50d02904b14175dccf2a7948777",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "1",
|
||||||
|
"gridNo": "1",
|
||||||
|
"boxNo": "2",
|
||||||
|
"storedNum": 2,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 2,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "1",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-02"
|
||||||
|
}, {
|
||||||
|
"id": "4f04c0ca4202535d678871b07e706cf6",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "1",
|
||||||
|
"gridNo": "2",
|
||||||
|
"boxNo": "1",
|
||||||
|
"storedNum": 2,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 2,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "1",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-02"
|
||||||
|
}, {
|
||||||
|
"id": "d0c91dabedfc03efad0126e50ea72e80",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "1",
|
||||||
|
"gridNo": "2",
|
||||||
|
"boxNo": "2",
|
||||||
|
"storedNum": 2,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 2,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "1",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-08"
|
||||||
|
}, {
|
||||||
|
"id": "1e8bfcbe4352afbab8878f9fd368e007",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "2",
|
||||||
|
"gridNo": "1",
|
||||||
|
"boxNo": "1",
|
||||||
|
"storedNum": 1,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 1,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "0",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-08"
|
||||||
|
}, {
|
||||||
|
"id": "d76087d8d3ebc7a59d43458588f26941",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "2",
|
||||||
|
"gridNo": "1",
|
||||||
|
"boxNo": "2",
|
||||||
|
"storedNum": 0,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 0,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "0",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-02"
|
||||||
|
}, {
|
||||||
|
"id": "7bf7754f12e1bf95edcd501cc6b85e62",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "2",
|
||||||
|
"gridNo": "2",
|
||||||
|
"boxNo": "1",
|
||||||
|
"storedNum": 0,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 0,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "0",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-02"
|
||||||
|
}, {
|
||||||
|
"id": "9cd08d733657d5b286bec870f12f6ecf",
|
||||||
|
"attributeId": "e62831f314e1390edbd884e9d9e6aca6",
|
||||||
|
"cabinetNo": "1",
|
||||||
|
"levelNo": "2",
|
||||||
|
"gridNo": "2",
|
||||||
|
"boxNo": "2",
|
||||||
|
"storedNum": 0,
|
||||||
|
"maxNum": 2,
|
||||||
|
"unitNum": 0,
|
||||||
|
"assignStatus": "1",
|
||||||
|
"storageStatus": "0",
|
||||||
|
"remark": null,
|
||||||
|
"createBy": "admin",
|
||||||
|
"createTime": "2019-04-02",
|
||||||
|
"updateBy": "admin",
|
||||||
|
"updateTime": "2019-04-02"
|
||||||
|
}],
|
||||||
|
isorter: {
|
||||||
|
column: 'createTime',
|
||||||
|
order: 'desc',
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadData(){
|
||||||
|
this.levelNum=4;
|
||||||
|
this.gridNum = 2;
|
||||||
|
this.boxNum = 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.ant-card-body .table-operator{
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.ant-table-tbody .ant-table-row td{
|
||||||
|
padding-top:15px;
|
||||||
|
padding-bottom:15px;
|
||||||
|
}
|
||||||
|
.anty-row-operator button{margin: 0 5px}
|
||||||
|
.ant-btn-danger{background-color: #ffffff}
|
||||||
|
|
||||||
|
.ant-modal-cust-warp{height: 100%}
|
||||||
|
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}
|
||||||
|
.ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden}
|
||||||
|
</style>
|
||||||
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<a-input-search
|
|
||||||
v-model="this.selectedUserNames"
|
|
||||||
placeholder="请先选择用户"
|
|
||||||
disabled
|
|
||||||
@search="onSearch"
|
|
||||||
size="large">
|
|
||||||
<a-button slot="enterButton">选择用户</a-button>
|
|
||||||
</a-input-search>
|
|
||||||
|
|
||||||
<j-search-user-by-dep ref="JSearchUserByDep" @ok="modalFormOk"></j-search-user-by-dep>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import JSearchUserByDep from '@/components/jeecgbiz/JSearchUserByDep'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'SearchUserByDepList',
|
|
||||||
components: {
|
|
||||||
JSearchUserByDep,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedUserNames: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onSearch() {
|
|
||||||
this.$refs.JSearchUserByDep.showModal();
|
|
||||||
this.selectedUserNames = '';
|
|
||||||
this.$refs.JSearchUserByDep.title = '根据部门查询用户';
|
|
||||||
},
|
|
||||||
modalFormOk(selectedValue) {
|
|
||||||
this.selectedUserNames = selectedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<a-card :bordered="false" style="height:100%">
|
<a-card :bordered="false" style="height:100%">
|
||||||
|
|
||||||
<div class="table-page-search-wrapper">
|
<div class="table-page-search-wrapper">
|
||||||
<a-form layout="inline">
|
<a-form layout="inline" :form="form">
|
||||||
<!-- 选择多个用户,可排序 -->
|
<!-- 选择多个用户,可排序 -->
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<a-select
|
<a-select
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
placeholder="Please select"
|
placeholder="Please select"
|
||||||
:value=nameList
|
:value="nameList"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
</a-select>
|
</a-select>
|
||||||
@ -41,63 +41,325 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
|
<!-- 通过部门筛选,选择人 -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="性别">
|
||||||
|
<j-dict-select-tag title="性别" dictCode="sex" disabled/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- 部门选择控件 -->
|
||||||
|
<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>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">选中的部门ID(v-decorator):{{ getDepartIdValue() }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="选择部门">
|
||||||
|
<j-select-depart v-model="departId"></j-select-depart>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<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>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">选中的用户(v-model):{{ userRealName }}</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>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">选中的用户(v-model):{{ multiUser }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JCheckbox -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="多选组合">
|
||||||
|
<j-checkbox
|
||||||
|
v-model="jcheckbox.values"
|
||||||
|
:options="jcheckbox.options"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">多选组合(v-model):{{ jcheckbox.values }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JCodeEditor -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="代码输入框" style="min-height: 120px">
|
||||||
|
<j-code-editor
|
||||||
|
language="javascript"
|
||||||
|
v-model="jcodedditor.value"
|
||||||
|
:fullScreen="true"
|
||||||
|
style="min-height: 100px"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">代码输入框(v-model):{{ jcodedditor.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JDate -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="日期选择框">
|
||||||
|
<j-date v-model="jdate.value" :showTime="true" dateFormat="YYYY-MM-DD HH:mm:ss"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">日期选择框(v-model):{{ jdate.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JEditor -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="富文本编辑器" style="min-height: 300px">
|
||||||
|
<j-editor v-model="jeditor.value"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">富文本编辑器(v-model):{{ jeditor.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JEllipsis -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="过长剪切">
|
||||||
|
<j-ellipsis :value="jellipsis.value" :length="30"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">过长剪切:{{ jellipsis.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JGraphicCode -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="验证码">
|
||||||
|
<j-graphic-code @success="generateCode"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">验证码:{{ jgraphicCode.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JSlider -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="滑块验证码">
|
||||||
|
<j-slider @onSuccess="handleJSliderSuccess"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">滑块验证码验证通过:{{ jslider.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JSelectMultiple -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="多选下拉框">
|
||||||
|
<j-select-multiple v-model="jselectMultiple.value" :options="jselectMultiple.options"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">多选下拉框(v-model):{{ jselectMultiple.value }}</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<!-- JSelectMultiple -->
|
||||||
|
<a-row :gutter="24">
|
||||||
|
<a-col>
|
||||||
|
|
||||||
|
<a-form-item label="最大化弹窗">
|
||||||
|
<a-button @click="()=>modal.visible=true">最大化弹窗</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
:visible="modal.visible"
|
||||||
|
:width="modal.width"
|
||||||
|
:style="modal.style"
|
||||||
|
@ok="()=>modal.visible=false"
|
||||||
|
@cancel="()=>modal.visible=false">
|
||||||
|
|
||||||
|
<template slot="title">
|
||||||
|
<div style="width: 100%;height:20px;padding-right:32px;">
|
||||||
|
<div style="float: left;">{{ modal.title }}</div>
|
||||||
|
<div style="float: right;">
|
||||||
|
<a-button
|
||||||
|
icon="fullscreen"
|
||||||
|
style="width:56px;height:100%;border:0"
|
||||||
|
@click="handleClickToggleFullScreen"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-for="(i,k) of 30">
|
||||||
|
<p :key="k">这是主体内容,高度是自适应的</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 选择多个用户支持排序 -->
|
<!-- 选择多个用户支持排序 -->
|
||||||
<select-multiple-user-modal ref="selectDemoModal" @selectFinished="selectOK"></select-multiple-user-modal>
|
<j-select-multiple-user ref="selectDemoModal" @selectFinished="selectOK"></j-select-multiple-user>
|
||||||
<!-- 通过部门筛选,选择人 -->
|
<!-- 通过部门筛选,选择人 -->
|
||||||
<search-user-by-dep-modal ref="SearchUserByDepModal" @ok="onSearchDepUserCallBack"></search-user-by-dep-modal>
|
<j-search-user-by-dep ref="JSearchUserByDep" @ok="onSearchDepUserCallBack"></j-search-user-by-dep>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SelectMultipleUserModal from '@/components/jeecgbiz/SelectMultipleUserModal'
|
import JSelectMultipleUser from '@/components/jeecgbiz/JSelectMultipleUser'
|
||||||
import SearchUserByDepModal from '@/components/jeecgbiz/SearchUserByDepModal'
|
import JSearchUserByDep from '@/components/jeecgbiz/JSearchUserByDep'
|
||||||
|
import JDictSelectTag from '../../components/dict/JDictSelectTag.vue'
|
||||||
|
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
|
||||||
|
import JSelectUserByDep from '@/components/jeecgbiz/JSelectUserByDep'
|
||||||
|
import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
|
||||||
|
import JCheckbox from '@/components/jeecg/JCheckbox'
|
||||||
|
import JCodeEditor from '@/components/jeecg/JCodeEditor'
|
||||||
|
import JDate from '@/components/jeecg/JDate'
|
||||||
|
import JEditor from '@/components/jeecg/JEditor'
|
||||||
|
import JEllipsis from '@/components/jeecg/JEllipsis'
|
||||||
|
import JGraphicCode from '@/components/jeecg/JGraphicCode'
|
||||||
|
import JSlider from '@/components/jeecg/JSlider'
|
||||||
|
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "SelectDemo",
|
name: 'SelectDemo',
|
||||||
components: {
|
components: {
|
||||||
SelectMultipleUserModal,
|
JDictSelectTag,
|
||||||
SearchUserByDepModal
|
JSelectMultipleUser,
|
||||||
|
JSearchUserByDep,
|
||||||
|
JSelectDepart,
|
||||||
|
JSelectUserByDep,
|
||||||
|
JSelectMultiUser,
|
||||||
|
JCheckbox,
|
||||||
|
JCodeEditor,
|
||||||
|
JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectList: [],
|
selectList: [],
|
||||||
selectedDepUsers: ''
|
selectedDepUsers: '',
|
||||||
|
form: this.$form.createForm(this),
|
||||||
|
departId: '4f1765520d6346f9bd9c79e2479e5b12,57197590443c44f083d42ae24ef26a2c',
|
||||||
|
userRealName: '',
|
||||||
|
multiUser: '',
|
||||||
|
jcheckbox: {
|
||||||
|
values: 'spring,jeecgboot',
|
||||||
|
options: [
|
||||||
|
{ label: 'Jeecg', value: 'jeecg' },
|
||||||
|
{ label: 'Jeecg-Boot', value: 'jeecgboot' },
|
||||||
|
{ label: 'Spring', value: 'spring', disabled: true },
|
||||||
|
{ label: 'MyBaits', value: 'mybatis' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
jcodedditor: {
|
||||||
|
value: `function sayHi(word) {
|
||||||
|
alert(word)
|
||||||
|
}
|
||||||
|
sayHi('hello, world!')`
|
||||||
|
},
|
||||||
|
jdate: {
|
||||||
|
value: '2019-5-10 15:33:06'
|
||||||
|
},
|
||||||
|
jeditor: {
|
||||||
|
value: '<h2 style="text-align: center;">富文本编辑器</h2> <p>这里是富文本编辑器。</p>'
|
||||||
|
},
|
||||||
|
jellipsis: {
|
||||||
|
value: '这是一串很长很长的文字段落。这是一串很长很长的文字段落。这是一串很长很长的文字段落。这是一串很长很长的文字段落。'
|
||||||
|
},
|
||||||
|
jgraphicCode: {
|
||||||
|
value: ''
|
||||||
|
},
|
||||||
|
jslider: {
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
jselectMultiple: {
|
||||||
|
options: [
|
||||||
|
{ text: '字符串', value: 'String' },
|
||||||
|
{ text: '整数型', value: 'Integer' },
|
||||||
|
{ text: '浮点型', value: 'Double' },
|
||||||
|
{ text: '布尔型', value: 'Boolean' }
|
||||||
|
],
|
||||||
|
value: 'Integer,Boolean'
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
title: '这里是标题',
|
||||||
|
visible: false,
|
||||||
|
width: '100%',
|
||||||
|
style: { top: '20px' },
|
||||||
|
fullScreen: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
nameList: function () {
|
nameList: function() {
|
||||||
var names = [];
|
|
||||||
|
var names = []
|
||||||
for (var a = 0; a < this.selectList.length; a++) {
|
for (var a = 0; a < this.selectList.length; a++) {
|
||||||
names.push(this.selectList[a].name);
|
names.push(this.selectList[a].name)
|
||||||
}
|
}
|
||||||
return names;
|
return names
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleChange() {
|
handleChange() {
|
||||||
},
|
},
|
||||||
selectOK: function (data) {
|
getDepartIdValue() {
|
||||||
this.selectList = data;
|
return this.form.getFieldValue('departId')
|
||||||
},
|
},
|
||||||
handleSelect: function () {
|
selectOK: function(data) {
|
||||||
this.$refs.selectDemoModal.add();
|
this.selectList = data
|
||||||
|
},
|
||||||
|
handleSelect: function() {
|
||||||
|
this.$refs.selectDemoModal.add()
|
||||||
},
|
},
|
||||||
selectReset() {
|
selectReset() {
|
||||||
this.selectList = [];
|
this.selectList = []
|
||||||
},
|
},
|
||||||
//通过组织机构筛选选择用户
|
//通过组织机构筛选选择用户
|
||||||
onSearchDepUser() {
|
onSearchDepUser() {
|
||||||
this.$refs.SearchUserByDepModal.showModal()
|
this.$refs.JSearchUserByDep.showModal()
|
||||||
this.selectedDepUsers = ''
|
this.selectedDepUsers = ''
|
||||||
this.$refs.SearchUserByDepModal.selectedKeys = []
|
this.$refs.JSearchUserByDep.title = '根据部门查询用户'
|
||||||
this.$refs.SearchUserByDepModal.title = '根据部门查询用户'
|
|
||||||
},
|
},
|
||||||
onSearchDepUserCallBack(selectedDepUsers) {
|
onSearchDepUserCallBack(selectedDepUsers) {
|
||||||
this.selectedDepUsers = selectedDepUsers
|
this.selectedDepUsers = selectedDepUsers
|
||||||
|
},
|
||||||
|
generateCode(value) {
|
||||||
|
this.jgraphicCode.value = value.toLowerCase()
|
||||||
|
},
|
||||||
|
handleJSliderSuccess(value) {
|
||||||
|
this.jslider.value = value
|
||||||
|
},
|
||||||
|
/** 切换全屏显示 */
|
||||||
|
handleClickToggleFullScreen() {
|
||||||
|
let mode = !this.modal.fullScreen
|
||||||
|
if (mode) {
|
||||||
|
this.modal.width = '100%'
|
||||||
|
this.modal.style.top = '20px'
|
||||||
|
} else {
|
||||||
|
this.modal.width = '1200px'
|
||||||
|
this.modal.style.top = '50px'
|
||||||
|
}
|
||||||
|
this.modal.fullScreen = mode
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
32
ant-design-jeecg-vue/src/views/jeecg/SplitPanel.vue
Normal file
32
ant-design-jeecg-vue/src/views/jeecg/SplitPanel.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<a-card>
|
||||||
|
<a-button @click="splitPane" type="primary" icon="desktop">点我分屏</a-button>
|
||||||
|
|
||||||
|
<split-panel-modal ref="splitPanelModal"></split-panel-modal>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SplitPanelModal from './modules/SplitPanelModal'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SplitPanel',
|
||||||
|
components:{
|
||||||
|
SplitPanelModal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: '分屏',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
splitPane(){
|
||||||
|
this.$refs.splitPanelModal.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -237,10 +237,6 @@
|
|||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-layout-content {
|
|
||||||
margin: 12px 16px 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-tbody .ant-table-row td {
|
.ant-table-tbody .ant-table-row td {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
|
|||||||
160
ant-design-jeecg-vue/src/views/jeecg/modules/JoaDemoForm.vue
Normal file
160
ant-design-jeecg-vue/src/views/jeecg/modules/JoaDemoForm.vue
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<a-form :form="form">
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="请假人">
|
||||||
|
<a-input placeholder="请输入请假人" v-decorator="['name', {}]" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="请假天数">
|
||||||
|
<a-input-number v-decorator="[ 'days', {}]" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="开始时间">
|
||||||
|
<a-date-picker showTime format='YYYY-MM-DD' v-decorator="[ 'beginDate', {}]" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="请假结束时间">
|
||||||
|
<a-date-picker showTime format='YYYY-MM-DD' v-decorator="[ 'endDate', {}]" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="请假原因">
|
||||||
|
<a-input placeholder="请输入请假原因" v-decorator="['reason', {}]" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { httpAction,getAction } from '@/api/manage'
|
||||||
|
import moment from "moment"
|
||||||
|
import pick from 'lodash.pick'
|
||||||
|
import JDate from '@/components/jeecg/JDate.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "JoaDemoModal",
|
||||||
|
components: { JDate },
|
||||||
|
props: ['formData'],
|
||||||
|
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:{
|
||||||
|
name:{},
|
||||||
|
days:{},
|
||||||
|
beginDate:{},
|
||||||
|
endDate:{},
|
||||||
|
reason:{},
|
||||||
|
bpmStatus:{},
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
queryById: "/test/joaDemo/queryById",
|
||||||
|
add: "/test/joaDemo/add",
|
||||||
|
edit: "/test/joaDemo/edit",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
console.log("form start");
|
||||||
|
console.log("formdata",this.formData);
|
||||||
|
if(this.formData.dataId){
|
||||||
|
var params = {id:this.formData.dataId};//查询条件
|
||||||
|
getAction(this.url.queryById,params).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
console.log("获取表单数据",res);
|
||||||
|
this.edit (res.result);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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,'name','days','reason','bpmStatus'))
|
||||||
|
//时间格式化
|
||||||
|
this.form.setFieldsValue({beginDate:this.model.beginDate?moment(this.model.beginDate):null})
|
||||||
|
this.form.setFieldsValue({endDate:this.model.endDate?moment(this.model.endDate):null})
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
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);
|
||||||
|
//时间格式化
|
||||||
|
formData.beginDate = formData.beginDate?formData.beginDate.format('YYYY-MM-DD HH:mm:ss'):null;
|
||||||
|
formData.endDate = formData.endDate?formData.endDate.format('YYYY-MM-DD HH:mm:ss'):null;
|
||||||
|
|
||||||
|
console.log(formData)
|
||||||
|
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 scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<div style="display: none">
|
||||||
|
<iframe
|
||||||
|
:id="id"
|
||||||
|
:src="url"
|
||||||
|
frameborder="0"
|
||||||
|
width="100%"
|
||||||
|
height="550px"
|
||||||
|
scrolling="auto">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PdfPreviewModal",
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
url: window._CONFIG['pdfDomainURL'],
|
||||||
|
id:"pdfPreviewIframe",
|
||||||
|
headers:{}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
const token = Vue.ls.get(ACCESS_TOKEN);
|
||||||
|
this.headers = {"X-Access-Token":token}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
window.addEventListener('message', this.handleScanFileMessage);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleScanFileMessage (event) {
|
||||||
|
// 根据上面制定的结构来解析iframe内部发回来的数据
|
||||||
|
const data = event.data;
|
||||||
|
console.log(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
previewFiles (title,token) {
|
||||||
|
var iframe = document.getElementById("pdfPreviewIframe");
|
||||||
|
var json = {"title":title,"token":token};
|
||||||
|
iframe.contentWindow.postMessage(json, "*");
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
27
ant-design-jeecg-vue/src/views/jeecg/modules/SplitPanelA.vue
Normal file
27
ant-design-jeecg-vue/src/views/jeecg/modules/SplitPanelA.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<a-card style="min-width: 500px;overflow-x: auto">
|
||||||
|
<p>我是左侧页面</p>
|
||||||
|
<img-turn-page></img-turn-page>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ImgTurnPage from '../ImgTurnPage'
|
||||||
|
export default {
|
||||||
|
name: "SplitPanelAModal",
|
||||||
|
components:{
|
||||||
|
ImgTurnPage
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
27
ant-design-jeecg-vue/src/views/jeecg/modules/SplitPanelB.vue
Normal file
27
ant-design-jeecg-vue/src/views/jeecg/modules/SplitPanelB.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<a-card style="min-width: 500px;overflow-x: auto">
|
||||||
|
<p>我是右侧页面</p>
|
||||||
|
<img-turn-page></img-turn-page>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ImgTurnPage from '../ImgTurnPage'
|
||||||
|
export default {
|
||||||
|
name: "SplitPanelAModal",
|
||||||
|
components:{
|
||||||
|
ImgTurnPage
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
title="分屏"
|
||||||
|
:width="modalWidth"
|
||||||
|
:visible="visible"
|
||||||
|
:bodyStyle="bodyStyle"
|
||||||
|
style="top: 0px;"
|
||||||
|
@ok="handleOk"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
cancelText="关闭">
|
||||||
|
|
||||||
|
<split-pane :min-percent='20' :default-percent='50' split="vertical">
|
||||||
|
<template slot="paneL">
|
||||||
|
<split-panel-a></split-panel-a>
|
||||||
|
</template>
|
||||||
|
<template slot="paneR">
|
||||||
|
<split-panel-b></split-panel-b>
|
||||||
|
</template>
|
||||||
|
</split-pane>
|
||||||
|
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import splitPane from 'vue-splitpane'
|
||||||
|
import SplitPanelA from './SplitPanelA'
|
||||||
|
import SplitPanelB from './SplitPanelB'
|
||||||
|
export default {
|
||||||
|
name: "SplitPanelModal",
|
||||||
|
components:{
|
||||||
|
splitPane,
|
||||||
|
SplitPanelA,
|
||||||
|
SplitPanelB
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
bodyStyle:{
|
||||||
|
padding: "0",
|
||||||
|
height:(window.innerHeight-150)+"px"
|
||||||
|
},
|
||||||
|
modalWidth:800,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.modalWidth = window.innerWidth-0;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
show () {
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
handleOk(){
|
||||||
|
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="14">
|
<a-col :span="14">
|
||||||
<a-form v-if="barType === 'month'" layout="inline" style="margin-top: -4px">
|
<a-form v-if="barType === 'month' && false" layout="inline" style="margin-top: -4px">
|
||||||
<a-form-item label="月份区间">
|
<a-form-item label="月份区间">
|
||||||
<a-range-picker
|
<a-range-picker
|
||||||
:placeholder="['开始月份', '结束月份']"
|
:placeholder="['开始月份', '结束月份']"
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<a-button style="margin-top: 2px;margin-left: 8px" type="primary" icon="reload" @click="searchReset">重置</a-button>
|
<a-button style="margin-top: 2px;margin-left: 8px" type="primary" icon="reload" @click="searchReset">重置</a-button>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-col>
|
</a-col>
|
||||||
<bar class="statistic" title="档案统计" :dataSource="countSource"/>
|
<bar class="statistic" title="档案统计" :dataSource="countSource" :height="400"/>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
|
||||||
@ -40,7 +40,7 @@
|
|||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="14">
|
<a-col :span="14">
|
||||||
<a-form v-if="pieType === 'month'" layout="inline" style="margin-top: -4px">
|
<a-form v-if="pieType === 'month' && false" layout="inline" style="margin-top: -4px">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-form-item label="月份区间">
|
<a-form-item label="月份区间">
|
||||||
<a-range-picker
|
<a-range-picker
|
||||||
@ -55,7 +55,7 @@
|
|||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-col>
|
</a-col>
|
||||||
<pie class="statistic" title="档案统计" :dataSource="countSource"/>
|
<pie class="statistic" title="档案统计" :dataSource="countSource" :height="450"/>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
|||||||
@ -63,6 +63,10 @@
|
|||||||
<a-tab-pane tab="Liquid" key="14">
|
<a-tab-pane tab="Liquid" key="14">
|
||||||
<liquid :height="height"/>
|
<liquid :height="height"/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
<!-- BarAndLine -->
|
||||||
|
<a-tab-pane tab="BarAndLine" key="15">
|
||||||
|
<bar-and-line :height="height"/>
|
||||||
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
@ -82,13 +86,14 @@
|
|||||||
import RankList from '@/components/chart/RankList'
|
import RankList from '@/components/chart/RankList'
|
||||||
import TransferBar from '@/components/chart/TransferBar'
|
import TransferBar from '@/components/chart/TransferBar'
|
||||||
import Trend from '@/components/chart/Trend'
|
import Trend from '@/components/chart/Trend'
|
||||||
|
import BarAndLine from '@/components/chart/BarAndLine'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ViserChartDemo',
|
name: 'ViserChartDemo',
|
||||||
components: {
|
components: {
|
||||||
Bar, MiniBar, BarMultid, AreaChartTy, LineChartMultid,
|
Bar, MiniBar, BarMultid, AreaChartTy, LineChartMultid,
|
||||||
Pie, Radar, DashChartDemo, MiniProgress, RankList,
|
Pie, Radar, DashChartDemo, MiniProgress, RankList,
|
||||||
TransferBar, Trend, Liquid, MiniArea
|
TransferBar, Trend, Liquid, MiniArea, BarAndLine
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -6,13 +6,13 @@
|
|||||||
<a-form layout="inline">
|
<a-form layout="inline">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :md="6" :sm="8">
|
<a-col :md="6" :sm="8">
|
||||||
<a-form-item label="推送标题">
|
<a-form-item label="消息标题">
|
||||||
<a-input placeholder="请输入推送标题" v-model="queryParam.esTitle"></a-input>
|
<a-input placeholder="请输入消息标题" v-model="queryParam.esTitle"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :md="6" :sm="8">
|
<a-col :md="6" :sm="8">
|
||||||
<a-form-item label="推送内容">
|
<a-form-item label="发送内容">
|
||||||
<a-input placeholder="请输入推送内容" v-model="queryParam.esContent"></a-input>
|
<a-input placeholder="请输入发送内容" v-model="queryParam.esContent"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<template v-if="toggleSearchStatus">
|
<template v-if="toggleSearchStatus">
|
||||||
@ -40,8 +40,8 @@
|
|||||||
<!-- 操作按钮区域 -->
|
<!-- 操作按钮区域 -->
|
||||||
<div class="table-operator">
|
<div class="table-operator">
|
||||||
<a-button @click="handleAdd" v-show="show" type="primary" icon="plus">新增</a-button>
|
<a-button @click="handleAdd" v-show="show" type="primary" icon="plus">新增</a-button>
|
||||||
<a-button type="primary" v-show="show" icon="download" @click="handleExportXls">导出</a-button>
|
<a-button type="primary" v-show="show" icon="download" @click="handleExportXls('消息')">导出</a-button>
|
||||||
<a-upload v-show="show" name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl"
|
<a-upload v-show="show" name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl"
|
||||||
@change="handleImportExcel">
|
@change="handleImportExcel">
|
||||||
<a-button type="primary" icon="import">导入</a-button>
|
<a-button type="primary" icon="import">导入</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
@ -84,14 +84,13 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span slot="action" slot-scope="text, record">
|
<span slot="action" slot-scope="text, record">
|
||||||
<a v-show="show" @click="handleEdit(record)">编辑</a>
|
<a href="javascript:;" @click="handleDetail(record)">详情</a>
|
||||||
|
|
||||||
<a-divider type="vertical"/>
|
<a-divider type="vertical"/>
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
<a class="ant-dropdown-link">更多<a-icon type="down"/></a>
|
<a class="ant-dropdown-link">更多<a-icon type="down"/></a>
|
||||||
<a-menu slot="overlay">
|
<a-menu slot="overlay">
|
||||||
<a-menu-item>
|
<a-menu-item v-show="show">
|
||||||
<a href="javascript:;" @click="handleDetail(record)">详情</a>
|
<a @click="handleEdit(record)">编辑</a>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item>
|
<a-menu-item>
|
||||||
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
|
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
|
||||||
@ -163,19 +162,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发送状态',
|
title: '发送状态',
|
||||||
align: "center",
|
align: 'center',
|
||||||
dataIndex: 'esSendStatus',
|
dataIndex: 'esSendStatus_dictText'
|
||||||
customRender: function (text) {
|
|
||||||
if(text=='0') {
|
|
||||||
return "未发送";
|
|
||||||
}
|
|
||||||
if(text=='1') {
|
|
||||||
return "发送成功";
|
|
||||||
}
|
|
||||||
if(text=='2') {
|
|
||||||
return "发送失败";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发送时间',
|
title: '发送时间',
|
||||||
@ -184,19 +172,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发送方式',
|
title: '发送方式',
|
||||||
align: "center",
|
align: 'center',
|
||||||
dataIndex: 'esType',
|
dataIndex: 'esType_dictText'
|
||||||
customRender: function (text) {
|
|
||||||
if(text=='1') {
|
|
||||||
return "短信";
|
|
||||||
}
|
|
||||||
if(text=='2') {
|
|
||||||
return "邮件";
|
|
||||||
}
|
|
||||||
if(text=='3') {
|
|
||||||
return "微信";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
|
|||||||
@ -46,8 +46,8 @@
|
|||||||
<!-- 操作按钮区域 -->
|
<!-- 操作按钮区域 -->
|
||||||
<div class="table-operator">
|
<div class="table-operator">
|
||||||
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
|
||||||
<a-button type="primary" icon="download" @click="handleExportXls">导出</a-button>
|
<a-button type="primary" icon="download" @click="handleExportXls('消息模板')">导出</a-button>
|
||||||
<a-upload name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl"
|
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl"
|
||||||
@change="handleImportExcel">
|
@change="handleImportExcel">
|
||||||
<a-button type="primary" icon="import">导入</a-button>
|
<a-button type="primary" icon="import">导入</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
|
|||||||
@ -107,6 +107,7 @@
|
|||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
form: this.$form.createForm(this),
|
form: this.$form.createForm(this),
|
||||||
validatorRules: {},
|
validatorRules: {},
|
||||||
|
disableSubmit: true,
|
||||||
url: {
|
url: {
|
||||||
add: "/message/sysMessage/add",
|
add: "/message/sysMessage/add",
|
||||||
edit: "/message/sysMessage/edit",
|
edit: "/message/sysMessage/edit",
|
||||||
|
|||||||
@ -17,7 +17,8 @@
|
|||||||
label="模板CODE">
|
label="模板CODE">
|
||||||
<a-input
|
<a-input
|
||||||
:disabled="disable"
|
:disabled="disable"
|
||||||
v-decorator="['templateCode', {} ]"
|
placeholder="请输入模板编码"
|
||||||
|
v-decorator="['templateCode', validatorRules.templateCode ]"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
@ -29,23 +30,31 @@
|
|||||||
v-decorator="['templateName', validatorRules.templateName]"
|
v-decorator="['templateName', validatorRules.templateName]"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
|
||||||
:labelCol="labelCol"
|
|
||||||
:wrapperCol="wrapperCol"
|
|
||||||
label="模板内容">
|
|
||||||
<a-textarea
|
|
||||||
placeholder="请输入模板内容"
|
|
||||||
v-decorator="['templateContent', validatorRules.templateContent ]"
|
|
||||||
:autosize="{ minRows: 8, maxRows: 8 }"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:labelCol="labelCol"
|
:labelCol="labelCol"
|
||||||
:wrapperCol="wrapperCol"
|
:wrapperCol="wrapperCol"
|
||||||
label="模板类型">
|
label="模板类型">
|
||||||
<j-dict-select-tag :triggerChange="true" dictCode="msgType" v-decorator="['templateType', validatorRules.templateType ]" placeholder="请选择模板类型">
|
<j-dict-select-tag @change="handleChangeTemplateType" :triggerChange="true" dictCode="msgType" v-decorator="['templateType', validatorRules.templateType ]" placeholder="请选择模板类型">
|
||||||
</j-dict-select-tag>
|
</j-dict-select-tag>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
v-show="!useEditor"
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="模板内容">
|
||||||
|
<a-textarea placeholder="请输入模板内容" v-decorator="['templateContent', validatorRules.templateContent ]" :autosize="{ minRows: 8, maxRows: 8 }" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
v-show="useEditor"
|
||||||
|
:labelCol="labelCol"
|
||||||
|
:wrapperCol="wrapperCol"
|
||||||
|
label="模板内容">
|
||||||
|
<j-editor v-model="templateEditorContent"></j-editor>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@ -54,9 +63,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import {httpAction} from '@/api/manage'
|
import {httpAction} from '@/api/manage'
|
||||||
import pick from 'lodash.pick'
|
import pick from 'lodash.pick'
|
||||||
|
import { duplicateCheck } from '@/api/api'
|
||||||
|
import JEditor from '@/components/jeecg/JEditor'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "SysMessageTemplateModal",
|
name: "SysMessageTemplateModal",
|
||||||
|
components:{
|
||||||
|
JEditor
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: "操作",
|
title: "操作",
|
||||||
@ -74,14 +88,17 @@
|
|||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
form: this.$form.createForm(this),
|
form: this.$form.createForm(this),
|
||||||
validatorRules: {
|
validatorRules: {
|
||||||
templateName: {rules: [{required: true, message: '请输入模板标题!'}]},
|
templateCode: {rules: [{required: true, message: '请输入模板CODE!' },{validator: this.validateTemplateCode}]},
|
||||||
templateContent: {rules: [{required: true, message: '请输入模板内容!'}]},
|
templateName: {rules: [{required: true, message: '请输入模板标题!'}]},
|
||||||
templateType: {rules: [{required: true, message: '请输入模板类型!'}]},
|
templateContent: {rules: []},
|
||||||
|
templateType: {rules: [{required: true, message: '请输入模板类型!'}]},
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
add: "/message/sysMessageTemplate/add",
|
add: "/message/sysMessageTemplate/add",
|
||||||
edit: "/message/sysMessageTemplate/edit",
|
edit: "/message/sysMessageTemplate/edit",
|
||||||
},
|
},
|
||||||
|
useEditor:false,
|
||||||
|
templateEditorContent:""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -94,12 +111,20 @@
|
|||||||
edit(record) {
|
edit(record) {
|
||||||
this.form.resetFields();
|
this.form.resetFields();
|
||||||
this.model = Object.assign({}, record);
|
this.model = Object.assign({}, record);
|
||||||
|
this.useEditor = (record.templateType==2)
|
||||||
|
if(this.useEditor){
|
||||||
|
this.templateEditorContent=record.templateContent
|
||||||
|
}else{
|
||||||
|
this.templateEditorContent=''
|
||||||
|
}
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.form.setFieldsValue(pick(this.model, 'templateCode', 'templateContent', 'templateName', 'templateTestJson', 'templateType'))
|
if(this.useEditor){
|
||||||
//时间格式化
|
this.form.setFieldsValue(pick(this.model, 'templateCode', 'templateName', 'templateTestJson', 'templateType'))
|
||||||
|
}else{
|
||||||
|
this.form.setFieldsValue(pick(this.model, 'templateCode', 'templateContent', 'templateName', 'templateTestJson', 'templateType'))
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$emit('close');
|
this.$emit('close');
|
||||||
@ -125,6 +150,9 @@
|
|||||||
let formData = Object.assign(this.model, values);
|
let formData = Object.assign(this.model, values);
|
||||||
//时间格式化
|
//时间格式化
|
||||||
|
|
||||||
|
if(this.useEditor){
|
||||||
|
formData.templateContent=this.templateEditorContent
|
||||||
|
}
|
||||||
console.log(formData)
|
console.log(formData)
|
||||||
httpAction(httpurl, formData, method).then((res) => {
|
httpAction(httpurl, formData, method).then((res) => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
@ -142,10 +170,29 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
validateTemplateCode(rule, value, callback){
|
||||||
|
var params = {
|
||||||
|
tableName: "sys_sms_template",
|
||||||
|
fieldName: "template_code",
|
||||||
|
fieldVal: value,
|
||||||
|
dataId: this.model.id
|
||||||
|
}
|
||||||
|
duplicateCheck(params).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
callback();
|
||||||
|
}else{
|
||||||
|
callback(res.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.close()
|
this.close()
|
||||||
},
|
},
|
||||||
|
handleChangeTemplateType(value){
|
||||||
|
//如果是邮件类型那么则改变模板内容是富文本编辑器
|
||||||
|
this.useEditor = value==2
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<a-card title="磁盘监控">
|
||||||
|
<a-row>
|
||||||
|
<template v-if="diskInfo && diskInfo.length>0">
|
||||||
|
<a-col :span="8" v-for="(item,index) in diskInfo" :key=" 'diskInfo'+index ">
|
||||||
|
<dash-chart-demo :title="item.name" :datasource="item.restPPT"></dash-chart-demo>
|
||||||
|
</a-col>
|
||||||
|
</template>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
import DashChartDemo from '@/components/chart/DashChartDemo'
|
||||||
|
import ARow from 'ant-design-vue/es/grid/Row'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DiskMonitoring',
|
||||||
|
components:{
|
||||||
|
ARow,
|
||||||
|
DashChartDemo,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: '磁盘监控',
|
||||||
|
//数据集
|
||||||
|
diskInfo:[],
|
||||||
|
url:{
|
||||||
|
queryDiskInfo:'actuator/redis/queryDiskInfo',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
getAction(this.url.queryDiskInfo).then((res)=>{
|
||||||
|
if(res.success){
|
||||||
|
for(var i=0;i<res.result.length;i++){
|
||||||
|
res.result[i].restPPT = res.result[i].restPPT/10;
|
||||||
|
}
|
||||||
|
this.diskInfo = res.result;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
148
ant-design-jeecg-vue/src/views/modules/monitor/HttpTrace.vue
Normal file
148
ant-design-jeecg-vue/src/views/modules/monitor/HttpTrace.vue
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<template>
|
||||||
|
<a-skeleton active :loading="loading" :paragraph="{rows: 17}">
|
||||||
|
<a-card :bordered="false" class="card-area">
|
||||||
|
|
||||||
|
<a-alert type="info" :showIcon="true">
|
||||||
|
<div slot="message">
|
||||||
|
共追踪到 {{ dataSource.length }} 条近期HTTP请求记录
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click="handleClickUpdate">立即刷新</a>
|
||||||
|
</div>
|
||||||
|
</a-alert>
|
||||||
|
|
||||||
|
<!-- 表格区域 -->
|
||||||
|
<a-table
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="dataSource"
|
||||||
|
:pagination="pagination"
|
||||||
|
:loading="tableLoading"
|
||||||
|
:scroll="{ x: 900 }"
|
||||||
|
style="margin-top: 20px;"
|
||||||
|
@change="handleTableChange">
|
||||||
|
|
||||||
|
<template slot="timeTaken" slot-scope="text">
|
||||||
|
<a-tag v-if="text < 500" color="green">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else-if="text < 1000" color="cyan">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else-if="text < 1500" color="orange">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else color="red">{{ text }} ms</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="responseStatus" slot-scope="text">
|
||||||
|
<a-tag v-if="text < 200" color="pink">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else-if="text < 201" color="green">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else-if="text < 399" color="cyan">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else-if="text < 403" color="orange">{{ text }} ms</a-tag>
|
||||||
|
<a-tag v-else-if="text < 501" color="red">{{ text }} ms</a-tag>
|
||||||
|
<span v-else>{{ text }} ms</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="requestMethod" slot-scope="text">
|
||||||
|
<a-tag v-if="text === 'GET'" color="#87d068">{{ text }}</a-tag>
|
||||||
|
<a-tag v-else-if="text === 'POST'" color="#2db7f5">{{ text }}</a-tag>
|
||||||
|
<a-tag v-else-if="text === 'PUT'" color="#ffba5a">{{ text }}</a-tag>
|
||||||
|
<a-tag v-else-if="text === 'DELETE'" color="#f50">{{ text }}</a-tag>
|
||||||
|
<span v-else>{{ text }} ms</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</a-table>
|
||||||
|
|
||||||
|
</a-card>
|
||||||
|
</a-skeleton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import moment from 'moment'
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
|
||||||
|
moment.locale('zh-cn')
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
advanced: false,
|
||||||
|
dataSource: [],
|
||||||
|
pagination: {
|
||||||
|
defaultPageSize: 10,
|
||||||
|
defaultCurrent: 1,
|
||||||
|
pageSizeOptions: ['10', '20', '30', '40', '100'],
|
||||||
|
showQuickJumper: true,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showTotal: (total, range) => `显示 ${range[0]} ~ ${range[1]} 条记录,共 ${total} 条记录`
|
||||||
|
},
|
||||||
|
loading: true,
|
||||||
|
tableLoading: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
columns() {
|
||||||
|
return [{
|
||||||
|
title: '请求时间',
|
||||||
|
dataIndex: 'timestamp',
|
||||||
|
customRender(text) {
|
||||||
|
return moment(text).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
title: '请求方法',
|
||||||
|
dataIndex: 'request.method',
|
||||||
|
scopedSlots: { customRender: 'requestMethod' },
|
||||||
|
filters: [
|
||||||
|
{ text: 'GET', value: 'GET' },
|
||||||
|
{ text: 'POST', value: 'POST' },
|
||||||
|
{ text: 'PUT', value: 'PUT' },
|
||||||
|
{ text: 'DELETE', value: 'DELETE' }
|
||||||
|
],
|
||||||
|
filterMultiple: true,
|
||||||
|
onFilter: (value, record) => record.request.method.includes(value)
|
||||||
|
}, {
|
||||||
|
title: '请求URL',
|
||||||
|
dataIndex: 'request.uri',
|
||||||
|
customRender(text) {
|
||||||
|
return text.split('?')[0]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
title: '响应状态',
|
||||||
|
dataIndex: 'response.status',
|
||||||
|
scopedSlots: { customRender: 'responseStatus' }
|
||||||
|
}, {
|
||||||
|
title: '请求耗时',
|
||||||
|
dataIndex: 'timeTaken',
|
||||||
|
scopedSlots: { customRender: 'timeTaken' }
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetch()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
handleClickUpdate() {
|
||||||
|
this.fetch()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTableChange() {
|
||||||
|
this.fetch()
|
||||||
|
},
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
this.tableLoading = true
|
||||||
|
getAction('actuator/httptrace').then((data) => {
|
||||||
|
let filterData = []
|
||||||
|
for (let d of data.traces) {
|
||||||
|
if (d.request.method !== 'OPTIONS' && d.request.uri.indexOf('httptrace') === -1) {
|
||||||
|
filterData.push(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dataSource = filterData
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error('获取HTTP信息失败')
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
this.tableLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style></style>
|
||||||
169
ant-design-jeecg-vue/src/views/modules/monitor/JvmInfo.vue
Normal file
169
ant-design-jeecg-vue/src/views/modules/monitor/JvmInfo.vue
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<template>
|
||||||
|
<a-skeleton active :loading="loading" :paragraph="{rows: 17}">
|
||||||
|
<a-card :bordered="false">
|
||||||
|
|
||||||
|
<a-alert type="info" :showIcon="true">
|
||||||
|
<div slot="message">
|
||||||
|
上次更新时间:{{ this.time }}
|
||||||
|
<a-divider type="vertical"/>
|
||||||
|
<a @click="handleClickUpdate">立即更新</a>
|
||||||
|
</div>
|
||||||
|
</a-alert>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
rowKey="id"
|
||||||
|
size="middle"
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="dataSource"
|
||||||
|
:pagination="false"
|
||||||
|
:loading="tableLoading"
|
||||||
|
style="margin-top: 20px;">
|
||||||
|
|
||||||
|
<template slot="param" slot-scope="text, record">
|
||||||
|
<a-tag :color="textInfo[record.param].color">{{ text }}</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="text" slot-scope="text, record">
|
||||||
|
{{ textInfo[record.param].text }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="value" slot-scope="text, record">
|
||||||
|
{{ text }} {{ textInfo[record.param].unit }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
</a-skeleton>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import moment from 'moment'
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
|
||||||
|
moment.locale('zh-cn')
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
time: '',
|
||||||
|
loading: true,
|
||||||
|
tableLoading: true,
|
||||||
|
columns: [{
|
||||||
|
title: '参数',
|
||||||
|
width: '30%',
|
||||||
|
dataIndex: 'param',
|
||||||
|
scopedSlots: { customRender: 'param' }
|
||||||
|
}, {
|
||||||
|
title: '描述',
|
||||||
|
width: '40%',
|
||||||
|
dataIndex: 'text',
|
||||||
|
scopedSlots: { customRender: 'text' }
|
||||||
|
}, {
|
||||||
|
title: '当前值',
|
||||||
|
width: '30%',
|
||||||
|
dataIndex: 'value',
|
||||||
|
scopedSlots: { customRender: 'value' }
|
||||||
|
}],
|
||||||
|
dataSource: [],
|
||||||
|
// 列表通过 textInfo 渲染出颜色、描述和单位
|
||||||
|
textInfo: {
|
||||||
|
'jvm.memory.max': { color: 'purple', text: 'JVM 最大内存', unit: 'MB' },
|
||||||
|
'jvm.memory.committed': { color: 'purple', text: 'JVM 可用内存', unit: 'MB' },
|
||||||
|
'jvm.memory.used': { color: 'purple', text: 'JVM 已用内存', unit: 'MB' },
|
||||||
|
'jvm.buffer.memory.used': { color: 'cyan', text: 'JVM 缓冲区已用内存', unit: 'MB' },
|
||||||
|
'jvm.buffer.count': { color: 'cyan', text: '当前缓冲区数量', unit: '个' },
|
||||||
|
'jvm.threads.daemon': { color: 'green', text: 'JVM 守护线程数量', unit: '个' },
|
||||||
|
'jvm.threads.live': { color: 'green', text: 'JVM 当前活跃线程数量', unit: '个' },
|
||||||
|
'jvm.threads.peak': { color: 'green', text: 'JVM 峰值线程数量', unit: '个' },
|
||||||
|
'jvm.classes.loaded': { color: 'orange', text: 'JVM 已加载 Class 数量', unit: '个' },
|
||||||
|
'jvm.classes.unloaded': { color: 'orange', text: 'JVM 未加载 Class 数量', unit: '个' },
|
||||||
|
'jvm.gc.memory.allocated': { color: 'pink', text: 'GC 时, 年轻代分配的内存空间', unit: 'MB' },
|
||||||
|
'jvm.gc.memory.promoted': { color: 'pink', text: 'GC 时, 老年代分配的内存空间', unit: 'MB' },
|
||||||
|
'jvm.gc.max.data.size': { color: 'pink', text: 'GC 时, 老年代的最大内存空间', unit: 'MB' },
|
||||||
|
'jvm.gc.live.data.size': { color: 'pink', text: 'FullGC 时, 老年代的内存空间', unit: 'MB' },
|
||||||
|
'jvm.gc.pause.count': { color: 'blue', text: '系统启动以来GC 次数', unit: '次' },
|
||||||
|
'jvm.gc.pause.totalTime': { color: 'blue', text: '系统启动以来GC 总耗时', unit: '秒' }
|
||||||
|
},
|
||||||
|
// 当一条记录中需要取出多条数据的时候需要配置该字段
|
||||||
|
moreInfo: {
|
||||||
|
'jvm.gc.pause': ['.count', '.totalTime']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadTomcatInfo()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
handleClickUpdate() {
|
||||||
|
this.loadTomcatInfo()
|
||||||
|
},
|
||||||
|
|
||||||
|
loadTomcatInfo() {
|
||||||
|
this.tableLoading = true
|
||||||
|
this.time = moment().format('YYYY年MM月DD日 HH时mm分ss秒')
|
||||||
|
Promise.all([
|
||||||
|
getAction('actuator/metrics/jvm.memory.max'),
|
||||||
|
getAction('actuator/metrics/jvm.memory.committed'),
|
||||||
|
getAction('actuator/metrics/jvm.memory.used'),
|
||||||
|
getAction('actuator/metrics/jvm.buffer.memory.used'),
|
||||||
|
getAction('actuator/metrics/jvm.buffer.count'),
|
||||||
|
getAction('actuator/metrics/jvm.threads.daemon'),
|
||||||
|
getAction('actuator/metrics/jvm.threads.live'),
|
||||||
|
getAction('actuator/metrics/jvm.threads.peak'),
|
||||||
|
getAction('actuator/metrics/jvm.classes.loaded'),
|
||||||
|
getAction('actuator/metrics/jvm.classes.unloaded'),
|
||||||
|
getAction('actuator/metrics/jvm.gc.memory.allocated'),
|
||||||
|
getAction('actuator/metrics/jvm.gc.memory.promoted'),
|
||||||
|
getAction('actuator/metrics/jvm.gc.max.data.size'),
|
||||||
|
getAction('actuator/metrics/jvm.gc.live.data.size'),
|
||||||
|
getAction('actuator/metrics/jvm.gc.pause')
|
||||||
|
]).then((res) => {
|
||||||
|
|
||||||
|
let info = []
|
||||||
|
res.forEach((value, id) => {
|
||||||
|
let more = this.moreInfo[value.name]
|
||||||
|
if (!(more instanceof Array)) {
|
||||||
|
more = ['']
|
||||||
|
}
|
||||||
|
more.forEach((item, idx) => {
|
||||||
|
let param = value.name + item
|
||||||
|
let val = value.measurements[idx].value
|
||||||
|
|
||||||
|
if (param === 'jvm.memory.max'
|
||||||
|
|| param === 'jvm.memory.committed'
|
||||||
|
|| param === 'jvm.memory.used'
|
||||||
|
|| param === 'jvm.buffer.memory.used'
|
||||||
|
|| param === 'jvm.gc.memory.allocated'
|
||||||
|
|| param === 'jvm.gc.memory.promoted'
|
||||||
|
|| param === 'jvm.gc.max.data.size'
|
||||||
|
|| param === 'jvm.gc.live.data.size'
|
||||||
|
) {
|
||||||
|
val = this.convert(val, Number)
|
||||||
|
}
|
||||||
|
info.push({ id: param + id, param, text: 'false value', value: val })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.dataSource = info
|
||||||
|
|
||||||
|
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error('获取JVM信息失败')
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
this.tableLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
convert(value, type) {
|
||||||
|
if (type === Number) {
|
||||||
|
return Number(value / 1048576).toFixed(3)
|
||||||
|
} else if (type === Date) {
|
||||||
|
return moment(value * 1000).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style></style>
|
||||||
177
ant-design-jeecg-vue/src/views/modules/monitor/RedisInfo.vue
Normal file
177
ant-design-jeecg-vue/src/views/modules/monitor/RedisInfo.vue
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
<template>
|
||||||
|
<a-skeleton active :loading="loading" :paragraph="{rows: 17}">
|
||||||
|
<a-card>
|
||||||
|
<!-- Radis 信息实时监控 -->
|
||||||
|
<a-row :gutter="8">
|
||||||
|
<a-col :sm="24" :xl="12">
|
||||||
|
<area-chart-ty v-bind="memory"/>
|
||||||
|
</a-col>
|
||||||
|
<a-col :sm="24" :xl="12">
|
||||||
|
<area-chart-ty v-bind="key"/>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<h3>Redis 详细信息</h3>
|
||||||
|
<a-table
|
||||||
|
:loading="tableLoading"
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="redisInfo"
|
||||||
|
:pagination="false"/>
|
||||||
|
|
||||||
|
</a-card>
|
||||||
|
</a-skeleton>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import moment from 'moment'
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
import AreaChartTy from '@/components/chart/AreaChartTy'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'RedisInfo',
|
||||||
|
components: {
|
||||||
|
AreaChartTy
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: true,
|
||||||
|
tableLoading: true,
|
||||||
|
timer: null,
|
||||||
|
millisec: 3000,
|
||||||
|
key: {
|
||||||
|
title: 'Radis Key 实时数量(个)',
|
||||||
|
dataSource: [],
|
||||||
|
y: '数量(个)',
|
||||||
|
height: 340,
|
||||||
|
max: 100,
|
||||||
|
color: '#FF6987',
|
||||||
|
lineSize: 8,
|
||||||
|
lineColor: '#DC143C'
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
title: 'Radis 内存实时占用情况(KB)',
|
||||||
|
dataSource: [],
|
||||||
|
y: '内存(KB)',
|
||||||
|
max: 3000,
|
||||||
|
height: 340,
|
||||||
|
lineSize: 8
|
||||||
|
},
|
||||||
|
redisInfo: [],
|
||||||
|
columns: [{
|
||||||
|
title: 'Key',
|
||||||
|
align: 'center',
|
||||||
|
dataIndex: 'key'
|
||||||
|
}, {
|
||||||
|
title: 'Description',
|
||||||
|
align: 'left',
|
||||||
|
dataIndex: 'description'
|
||||||
|
}, {
|
||||||
|
title: 'Value',
|
||||||
|
align: 'center',
|
||||||
|
dataIndex: 'value'
|
||||||
|
}],
|
||||||
|
url: {
|
||||||
|
keysSize: '/actuator/redis/keysSize',
|
||||||
|
memoryInfo: '/actuator/redis/memoryInfo',
|
||||||
|
info: '/actuator/redis/info'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// '$route'(to, from) {
|
||||||
|
// console.log(to, from)
|
||||||
|
// let path = '/monitor/redis/info'
|
||||||
|
// if (to.path === path) this.openTimer(), console.log('to')
|
||||||
|
// if (from.path === path) this.closeTimer(), console.log('from'),
|
||||||
|
// this.$destroy()
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.openTimer()
|
||||||
|
this.loadRedisInfo()
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loadData()
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.closeTimer()//, console.log('beforeDestroy')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
/** 开启定时器 */
|
||||||
|
openTimer() {
|
||||||
|
this.loadData()
|
||||||
|
this.closeTimer()
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
if (this.$route.path === '/monitor/redis/info') {
|
||||||
|
this.loadData()
|
||||||
|
}
|
||||||
|
}, this.millisec)
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 关闭定时器 */
|
||||||
|
closeTimer() {
|
||||||
|
if (this.timer) clearInterval(this.timer)
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 查询数据 */
|
||||||
|
loadData() {
|
||||||
|
Promise.all([
|
||||||
|
getAction(this.url.keysSize),
|
||||||
|
getAction(this.url.memoryInfo)
|
||||||
|
]).then((res) => {
|
||||||
|
let time = moment().format('hh:mm:ss')
|
||||||
|
|
||||||
|
let [{ dbSize: currentSize }, memoryInfo] = res
|
||||||
|
let currentMemory = memoryInfo.used_memory / 1000
|
||||||
|
|
||||||
|
// push 数据
|
||||||
|
this.key.dataSource.push({ x: time, y: currentSize })
|
||||||
|
this.memory.dataSource.push({ x: time, y: currentMemory })
|
||||||
|
// 最大长度为6
|
||||||
|
if (this.key.dataSource.length > 6) {
|
||||||
|
this.key.dataSource.splice(0, 1)
|
||||||
|
this.memory.dataSource.splice(0, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算最大值阈值
|
||||||
|
let maxKey = this.getMaxValue(this.key.dataSource, 'y')
|
||||||
|
this.key.max = Math.floor(maxKey) + 10
|
||||||
|
let maxMemory = this.getMaxValue(this.memory.dataSource, 'y')
|
||||||
|
this.memory.max = Math.floor(maxMemory) + 100
|
||||||
|
|
||||||
|
}).catch((e) => {
|
||||||
|
console.error(e)
|
||||||
|
this.closeTimer()
|
||||||
|
this.$message.error('获取 Redis 信息失败')
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getMaxValue(dataSource, f) {
|
||||||
|
let maxValue = null
|
||||||
|
dataSource.forEach(item => {
|
||||||
|
let value = Number.parseInt(item[f])
|
||||||
|
if (maxValue == null) {
|
||||||
|
maxValue = value
|
||||||
|
} else if (value > maxValue) {
|
||||||
|
maxValue = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return maxValue
|
||||||
|
},
|
||||||
|
|
||||||
|
loadRedisInfo() {
|
||||||
|
this.tableLoading = true
|
||||||
|
getAction(this.url.info).then((res) => {
|
||||||
|
this.redisInfo = res.result
|
||||||
|
}).finally(() => {
|
||||||
|
this.tableLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style></style>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user