Jeecg-Boot 2.1.4 版本发布 | 重构较大,较多新功能

pull/1067/merge
zhangdaiscott 2020-02-24 02:44:53 +08:00
parent 06847cd801
commit 4a4f236772
269 changed files with 15734 additions and 24855 deletions

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "vue-antd-jeecg", "name": "vue-antd-jeecg",
"version": "2.1.3", "version": "2.1.4",
"private": true, "private": true,
"scripts": { "scripts": {
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ", "pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
@ -10,7 +10,7 @@
}, },
"dependencies": { "dependencies": {
"@antv/data-set": "^0.10.2", "@antv/data-set": "^0.10.2",
"@jeecg/antd-online-re": "2.1.3", "@jeecg/antd-online-214": "^2.1.4",
"@tinymce/tinymce-vue": "^2.0.0", "@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "^1.4.0", "ant-design-vue": "^1.4.0",
"apexcharts": "^3.6.5", "apexcharts": "^3.6.5",
@ -24,7 +24,7 @@
"lodash.pick": "^4.4.0", "lodash.pick": "^4.4.0",
"md5": "^2.2.1", "md5": "^2.2.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"tinymce": "^5.0.2", "tinymce": "^5.1.4",
"viser-vue": "^2.4.4", "viser-vue": "^2.4.4",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-apexcharts": "^1.3.2", "vue-apexcharts": "^1.3.2",
@ -51,12 +51,12 @@
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0", "eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.0.0-beta.11",
"less": "^3.9.0", "less": "^3.9.0",
"less-loader": "^4.1.0", "less-loader": "^4.1.0",
"node-sass": "^4.11.0", "node-sass": "^4.11.0",
"sass-loader": "^7.0.1", "sass-loader": "^7.0.1",
"vue-template-compiler": "^2.6.10", "vue-template-compiler": "^2.6.10"
"html-webpack-plugin": "^4.0.0-beta.11"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,

View File

@ -5,9 +5,9 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Jeecg-Boot </title> <title>Jeecg-Boot </title>
<link rel="icon" href="<%= BASE_URL %>logo.png"> <link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="https://cdn.bootcss.com/babel-polyfill/7.6.0/polyfill.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.js"></script>
<style> <style>
html, html,
body, body,
@ -244,8 +244,8 @@
window._CONFIG = {}; window._CONFIG = {};
window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot'; window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot';
window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas'; window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas';
window._CONFIG['imgDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/view'; window._CONFIG['onlinePreviewDomainURL'] = 'http://fileview.jeecg.com/onlinePreview'
window._CONFIG['downloadUrl'] = window._CONFIG['domianURL'] + '/sys/common/download'; window._CONFIG['staticDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/static';
window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe'; window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe';
</script> </script>
</head> </head>

View File

@ -25,7 +25,7 @@ const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
//验证用户是否存在 //验证用户是否存在
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params); const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
//改变密码 //改变密码
const changPassword = (params)=>putAction("/sys/user/changPassword",params); const changePassword = (params)=>putAction("/sys/user/changePassword",params);
//权限管理 //权限管理
const addPermission= (params)=>postAction("/sys/permission/add",params); const addPermission= (params)=>postAction("/sys/permission/add",params);
@ -34,6 +34,7 @@ const getPermissionList = (params)=>getAction("/sys/permission/list",params);
/*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */ /*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params); const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params); const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params)
/*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */ /*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
// const deletePermission = (params)=>deleteAction("/sys/permission/delete",params); // const deletePermission = (params)=>deleteAction("/sys/permission/delete",params);
@ -56,6 +57,14 @@ const queryParentName = (params)=>getAction("/sys/sysDepart/queryParentName",p
const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params); const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params);
const deleteByDepartId = (params)=>deleteAction("/sys/sysDepart/delete",params); const deleteByDepartId = (params)=>deleteAction("/sys/sysDepart/delete",params);
//二级部门管理
const queryDepartPermission = (params)=>getAction("/sys/permission/queryDepartPermission",params);
const saveDepartPermission = (params)=>postAction("/sys/permission/saveDepartPermission",params);
const queryTreeListForDeptRole = (params)=>getAction("/sys/sysDepartPermission/queryTreeListForDeptRole",params);
const queryDeptRolePermission = (params)=>getAction("/sys/sysDepartPermission/queryDeptRolePermission",params);
const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/saveDeptRolePermission",params);
const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params);
//日志管理 //日志管理
//const getLogList = (params)=>getAction("/sys/log/list",params); //const getLogList = (params)=>getAction("/sys/log/list",params);
const deleteLog = (params)=>deleteAction("/sys/log/delete",params); const deleteLog = (params)=>deleteAction("/sys/log/delete",params);
@ -94,6 +103,7 @@ const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params); const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
// 加载分类字典 // 加载分类字典
const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params); const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params);
const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params)
export { export {
// imgView, // imgView,
@ -108,7 +118,7 @@ export {
queryall, queryall,
frozenBatch, frozenBatch,
checkOnlyUser, checkOnlyUser,
changPassword, changePassword,
getPermissionList, getPermissionList,
addPermission, addPermission,
editPermission, editPermission,
@ -142,7 +152,15 @@ export {
queryTreeListForRole, queryTreeListForRole,
getSystemMenuList, getSystemMenuList,
getSystemSubmenu, getSystemSubmenu,
loadCategoryData getSystemSubmenuBatch,
loadCategoryData,
checkRuleByCode,
queryDepartPermission,
saveDepartPermission,
queryTreeListForDeptRole,
queryDeptRolePermission,
saveDeptRolePermission,
queryMyDepartTreeList
} }

View File

@ -112,3 +112,17 @@ export function downFile(url,parameter){
}) })
} }
/**
* 访
* @param avatar
* @param imgerver
* @param str
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar,imgerver,subStr) {
if(avatar && avatar.indexOf(subStr) != -1 ){
return avatar;
}else{
return imgerver + "/" + avatar;
}
}

View File

@ -5,7 +5,7 @@
} }
/** Button按钮间距 */ /** Button按钮间距 */
.table-operator .ant-btn { .table-operator .ant-btn {
margin-right: 6px margin: 8px 8px 0 0;
} }
/*列表td的padding设置 可以控制列表大小*/ /*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td { .ant-table-tbody .ant-table-row td {

View File

@ -1,7 +1,7 @@
<template> <template>
<div :style="{ padding: '0 50px 32px 0' }"> <div :style="{ padding: '0 50px 32px 0' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding"> <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding" :onClick="handleClick">
<v-tooltip/> <v-tooltip/>
<v-legend/> <v-legend/>
<v-axis/> <v-axis/>
@ -12,9 +12,11 @@
</template> </template>
<script> <script>
import { ChartEventMixins } from './mixins/ChartMixins'
export default { export default {
name: 'BarMultid', name: 'BarAndLine',
mixins: [ChartEventMixins],
props: { props: {
title: { title: {
type: String, type: String,

View File

@ -1,71 +1,83 @@
<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="254" :data="chartData" :padding="['auto', 'auto', '40', '50']"> <v-chart :data="data" :height="height" :force-fit="true" :onClick="handleClick">
<v-tooltip /> <v-tooltip/>
<v-axis /> <v-axis/>
<v-legend /> <v-legend/>
<v-bar position="x*y" color="type" :adjust="adjust" /> <v-bar position="x*y" color="type" :adjust="adjust"/>
</v-chart> </v-chart>
</div> </div>
</template> </template>
<script> <script>
import { DataSet } from '@antv/data-set' import { DataSet } from '@antv/data-set'
import { ChartEventMixins } from './mixins/ChartMixins'
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',
mixins: [ChartEventMixins],
props: { props: {
title: { title: {
type: String, type: String,
default: '' default: ''
}, },
sourceData:{ 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.']
},
// 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}]
aliases: {
type: Array,
default: () => []
},
height: {
type: Number,
default: 254
} }
}, },
data() { data() {
return { return {
chartData:"",
height: 400,
adjust: [{ adjust: [{
type: 'dodge', type: 'dodge',
marginRatio: 1 / 32, marginRatio: 1 / 32
}], }]
};
},
watch: {
'sourceData': function () {
this.drawChart();
} }
}, },
mounted(){ computed: {
this.drawChart() data() {
}, const dv = new DataSet.View().source(this.dataSource)
methods:{
drawChart(){
let temp = sourceDataConst;
if(this.sourceData && this.sourceData.length>0){
temp = this.sourceData
}
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.chartData=dv.rows;
// bar 使用不了 - 和 / 所以替换下
let rows = dv.rows.map(row => {
if (typeof row.x === 'string') {
row.x = row.x.replace(/[-/]/g, '_')
}
return row
})
// 替换别名
rows.forEach(row => {
for (let item of this.aliases) {
if (item.field === row.type) {
row.type = item.alias
break
}
}
})
return rows
} }
} }
} }

View File

@ -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 :force-fit="true" :height="height" :data="data" :scale="scale"> <v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick">
<v-tooltip/> <v-tooltip/>
<v-axis/> <v-axis/>
<v-legend/> <v-legend/>
@ -13,9 +13,11 @@
<script> <script>
import { DataSet } from '@antv/data-set' import { DataSet } from '@antv/data-set'
import { ChartEventMixins } from './mixins/ChartMixins'
export default { export default {
name: 'LineChartMultid', name: 'LineChartMultid',
mixins: [ChartEventMixins],
props: { props: {
title: { title: {
type: String, type: String,

View File

@ -1,5 +1,5 @@
<template> <template>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale"> <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick">
<v-tooltip :showTitle="false" dataKey="item*percent"/> <v-tooltip :showTitle="false" dataKey="item*percent"/>
<v-axis/> <v-axis/>
<v-legend dataKey="item"/> <v-legend dataKey="item"/>
@ -10,8 +10,11 @@
<script> <script>
const DataSet = require('@antv/data-set') const DataSet = require('@antv/data-set')
import { ChartEventMixins } from './mixins/ChartMixins'
export default { export default {
name: 'Pie',
mixins: [ChartEventMixins],
props: { props: {
title: { title: {
type: String, type: String,

View File

@ -0,0 +1,10 @@
export const ChartEventMixins = {
methods: {
handleClick(event, chart) {
this.handleEvent('click', event, chart)
},
handleEvent(eventName, event, chart) {
this.$emit(eventName, event, chart)
},
}
}

View File

@ -1,10 +1,10 @@
<template> <template>
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="value" :disabled="disabled"> <a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="getValueSting" :disabled="disabled">
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio> <a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group> </a-radio-group>
<a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="value" @change="handleInput"> <a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput">
<a-select-option value=""></a-select-option> <a-select-option :value="undefined"></a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value"> <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 "> <span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
{{ item.text || item.label }} {{ item.text || item.label }}
@ -23,7 +23,7 @@
placeholder: String, placeholder: String,
triggerChange: Boolean, triggerChange: Boolean,
disabled: Boolean, disabled: Boolean,
value: String, value: [String, Number],
type: String type: String
}, },
data() { data() {
@ -50,6 +50,11 @@
//获取字典数据 //获取字典数据
// this.initDictData(); // this.initDictData();
}, },
computed: {
getValueSting(){
return this.value ? this.value.toString() : null;
},
},
methods: { methods: {
initDictData() { initDictData() {
//根据字典Code, 初始化字典数组 //根据字典Code, 初始化字典数组

View File

@ -47,10 +47,20 @@ export function filterDictText(dictOptions, text) {
* @return String * @return String
*/ */
export function filterMultiDictText(dictOptions, text) { export function filterMultiDictText(dictOptions, text) {
//js “!text” 认为0为空所以做提前处理
if(text === 0 || text === '0'){
for (let dictItem of dictOptions) {
if (text == dictItem.value) {
return dictItem.text
}
}
}
if(!text || !dictOptions || dictOptions.length==0){ if(!text || !dictOptions || dictOptions.length==0){
return "" return ""
} }
let re = ""; let re = "";
text = text.toString()
let arr = text.split(",") let arr = text.split(",")
dictOptions.forEach(function (option) { dictOptions.forEach(function (option) {
for(let i=0;i<arr.length;i++){ for(let i=0;i<arr.length;i++){

View File

@ -32,6 +32,8 @@
</a-col> </a-col>
</a-row> </a-row>
<slot name="actionButtonAfter" :target="getVM()"/>
<div :id="`${caseId}inputTable`" class="input-table"> <div :id="`${caseId}inputTable`" class="input-table">
<!-- --> <!-- -->
<div class="thead" ref="thead"> <div class="thead" ref="thead">
@ -142,7 +144,9 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<input <input
:id="id" :id="id"
@ -175,7 +179,9 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@ -211,7 +217,9 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@ -278,19 +286,33 @@
</template> </template>
<div :hidden="uploadValues[id] != null"> <div :hidden="uploadValues[id] != null">
<a-tooltip
<a-upload :key="i"
name="file" :id="id"
:data="{'isup':1}" placement="top"
:multiple="false" :title="(tooltips[id] || {}).title"
:action="col.action" :visible="(tooltips[id] || {}).visible || false"
:headers="uploadGetHeaders(row,col)" :autoAdjustOverflow="true"
:showUploadList="false" :getPopupContainer="getParentContainer"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
> >
<a-button icon="upload">{{ col.placeholder }}</a-button>
</a-upload> <span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<a-upload
name="file"
:data="{'isup':1}"
:multiple="false"
:action="col.action"
:headers="uploadGetHeaders(row,col)"
:showUploadList="false"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
>
<a-button icon="upload">{{ col.placeholder }}</a-button>
</a-upload>
</span>
</a-tooltip>
</div> </div>
</div> </div>
@ -303,7 +325,10 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}"> @mouseout="()=>{handleMouseoutCommono(row,col)}">
@ -359,19 +384,33 @@
</template> </template>
<div :hidden="uploadValues[id] != null"> <div :hidden="uploadValues[id] != null">
<a-tooltip
<a-upload :key="i"
name="file" :id="id"
:data="{'isup':1}" placement="top"
:multiple="false" :title="(tooltips[id] || {}).title"
:action="getUploadAction(col.action)" :visible="(tooltips[id] || {}).visible || false"
:headers="uploadGetHeaders(row,col)" :autoAdjustOverflow="true"
:showUploadList="false" :getPopupContainer="getParentContainer"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
> >
<a-button icon="upload">{{ col.placeholder }}</a-button>
</a-upload> <span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<a-upload
name="file"
:data="{'isup':1}"
:multiple="false"
:action="getUploadAction(col.action)"
:headers="uploadGetHeaders(row,col)"
:showUploadList="false"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
>
<a-button icon="upload">{{ col.placeholder }}</a-button>
</a-upload>
</span>
</a-tooltip>
</div> </div>
</div> </div>
@ -406,19 +445,33 @@
</template> </template>
<div :hidden="uploadValues[id] != null"> <div :hidden="uploadValues[id] != null">
<a-tooltip
<a-upload :key="i"
name="file" :id="id"
:data="{'isup':1}" placement="top"
:multiple="false" :title="(tooltips[id] || {}).title"
:action="getUploadAction(col.action)" :visible="(tooltips[id] || {}).visible || false"
:headers="uploadGetHeaders(row,col)" :autoAdjustOverflow="true"
:showUploadList="false" :getPopupContainer="getParentContainer"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
> >
<a-button icon="upload"></a-button>
</a-upload> <span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<a-upload
name="file"
:data="{'isup':1}"
:multiple="false"
:action="getUploadAction(col.action)"
:headers="uploadGetHeaders(row,col)"
:showUploadList="false"
v-bind="buildProps(row,col)"
@change="(v)=>handleChangeUpload(v,id,row,col)"
>
<a-button icon="upload"></a-button>
</a-upload>
</span>
</a-tooltip>
</div> </div>
</div> </div>
@ -433,7 +486,10 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}"> @mouseout="()=>{handleMouseoutCommono(row,col)}">
@ -459,7 +515,9 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@ -492,7 +550,9 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@ -526,7 +586,9 @@
placement="top" placement="top"
:title="(tooltips[id] || {}).title" :title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false" :visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true"> :autoAdjustOverflow="true"
:getPopupContainer="getParentContainer"
>
<span <span
@mouseover="()=>{handleMouseoverCommono(row,col)}" @mouseover="()=>{handleMouseoverCommono(row,col)}"
@ -693,6 +755,7 @@
} }
}, },
created() { created() {
this.inputValues = []
// 当前显示的tr // 当前显示的tr
this.visibleTrEls = [] this.visibleTrEls = []
this.disabledRowIds = (this.disabledRowIds || []) this.disabledRowIds = (this.disabledRowIds || [])
@ -771,149 +834,155 @@
dataSource: { dataSource: {
immediate: true, immediate: true,
handler: function (newValue) { handler: function (newValue) {
this.initialize() // 兼容IE
this.getElementPromise('tbody').then(() => {
let rows = [] this.initialize()
let checkboxValues = {}
let selectValues = {}
let jdateValues = {}
let slotValues = {}
let uploadValues = {}
let popupValues = {}
let radioValues = {}
let multiSelectValues = {}
let searchSelectValues = {}
// 禁用行的id let rows = []
let disabledRowIds = (this.disabledRowIds || []) let checkboxValues = {}
newValue.forEach((data, newValueIndex) => { let selectValues = {}
// 判断源数据是否带有id let jdateValues = {}
if (data.id == null || data.id === '') { let slotValues = {}
data.id = this.removeCaseId(this.generateId() + newValueIndex) let uploadValues = {}
} let popupValues = {}
let radioValues = {}
let multiSelectValues = {}
let searchSelectValues = {}
let value = { id: this.caseId + data.id } // 禁用行的id
let row = { id: value.id } let disabledRowIds = (this.disabledRowIds || [])
let disabled = false newValue.forEach((data, newValueIndex) => {
this.columns.forEach(column => { // 判断源数据是否带有id
let inputId = column.key + value.id if (data.id == null || data.id === '') {
let sourceValue = (data[column.key] == null ? '' : data[column.key]).toString() data.id = this.removeCaseId(this.generateId() + newValueIndex)
if (column.type === FormTypes.checkbox) {
// 判断是否设定了customValue自定义值
if (column.customValue instanceof Array) {
let customValue = (column.customValue[0] || '').toString()
checkboxValues[inputId] = (sourceValue === customValue)
} else {
checkboxValues[inputId] = sourceValue
}
} else if (column.type === FormTypes.select) {
if (sourceValue) {
// 判断是否是多选
selectValues[inputId] = (column.props || {})['mode'] === 'multiple' ? sourceValue.split(',') : sourceValue
} else {
selectValues[inputId] = undefined
}
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
jdateValues[inputId] = sourceValue
} else if (column.type === FormTypes.slot) {
if (sourceValue !== 0 && !sourceValue) {
slotValues[inputId] = column.defaultValue
} else {
slotValues[inputId] = sourceValue
}
} else if (column.type === FormTypes.popup) {
popupValues[inputId] = sourceValue
} else if (column.type === FormTypes.radio) {
radioValues[inputId] = sourceValue
} else if (column.type === FormTypes.sel_search) {
searchSelectValues[inputId] = sourceValue
} else if (column.type === FormTypes.list_multi) {
if (sourceValue.length > 0) {
multiSelectValues[inputId] = sourceValue.split(',')
} else {
multiSelectValues[inputId] = []
}
} else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
if (sourceValue) {
let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1)
uploadValues[inputId] = {
name: fileName,
status: 'done',
path: sourceValue
}
}
} else {
value[column.key] = sourceValue
} }
// 解析disabledRows let value = { id: this.caseId + data.id }
for (let columnKey in this.disabledRows) { let row = { id: value.id }
// 判断是否有该属性 let disabled = false
if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) { this.columns.forEach(column => {
if (disabled !== true) { let inputId = column.key + value.id
let temp = this.disabledRows[columnKey] let sourceValue = (data[column.key] == null ? '' : data[column.key]).toString()
// 禁用规则可以是一个数组 if (column.type === FormTypes.checkbox) {
if (temp instanceof Array) {
disabled = temp.includes(data[columnKey]) // 判断是否设定了customValue自定义值
} else { if (column.customValue instanceof Array) {
disabled = (temp === data[columnKey]) let customValue = (column.customValue[0] || '').toString()
checkboxValues[inputId] = (sourceValue === customValue)
} else {
checkboxValues[inputId] = sourceValue
}
} else if (column.type === FormTypes.select) {
if (sourceValue) {
// 判断是否是多选
selectValues[inputId] = (column.props || {})['mode'] === 'multiple' ? sourceValue.split(',') : sourceValue
} else {
selectValues[inputId] = undefined
}
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
jdateValues[inputId] = sourceValue
} else if (column.type === FormTypes.slot) {
if (sourceValue !== 0 && !sourceValue) {
slotValues[inputId] = column.defaultValue
} else {
slotValues[inputId] = sourceValue
}
} else if (column.type === FormTypes.popup) {
popupValues[inputId] = sourceValue
} else if (column.type === FormTypes.radio) {
radioValues[inputId] = sourceValue
} else if (column.type === FormTypes.sel_search) {
searchSelectValues[inputId] = sourceValue
} else if (column.type === FormTypes.list_multi) {
if (sourceValue.length > 0) {
multiSelectValues[inputId] = sourceValue.split(',')
} else {
multiSelectValues[inputId] = []
}
} else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
if (sourceValue) {
let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1)
uploadValues[inputId] = {
name: fileName,
status: 'done',
path: sourceValue
} }
if (disabled) { }
disabledRowIds.push(row.id) } else {
value[column.key] = sourceValue
}
// 解析disabledRows
for (let columnKey in this.disabledRows) {
// 判断是否有该属性
if (this.disabledRows.hasOwnProperty(columnKey) && data.hasOwnProperty(columnKey)) {
if (disabled !== true) {
let temp = this.disabledRows[columnKey]
// 禁用规则可以是一个数组
if (temp instanceof Array) {
disabled = temp.includes(data[columnKey])
} else {
disabled = (temp === data[columnKey])
}
if (disabled) {
disabledRowIds.push(row.id)
}
} }
} }
} }
} })
this.inputValues.push(value)
rows.push(row)
}) })
this.inputValues.push(value) this.disabledRowIds = disabledRowIds
rows.push(row) this.checkboxValues = checkboxValues
}) this.selectValues = selectValues
this.disabledRowIds = disabledRowIds this.jdateValues = jdateValues
this.checkboxValues = checkboxValues this.slotValues = slotValues
this.selectValues = selectValues this.rows = rows
this.jdateValues = jdateValues this.uploadValues = uploadValues
this.slotValues = slotValues this.popupValues = popupValues
this.rows = rows this.radioValues = radioValues
this.uploadValues = uploadValues this.multiSelectValues = multiSelectValues
this.popupValues = popupValues this.searchSelectValues = searchSelectValues
this.radioValues = radioValues
this.multiSelectValues = multiSelectValues
this.searchSelectValues = searchSelectValues
// 更新form表单的值 // 更新form表单的值
this.$nextTick(() => { this.$nextTick(() => {
this.updateFormValues() this.updateFormValues()
})
}) })
} }
}, },
columns: { columns: {
immediate: true, immediate: true,
handler(columns) { handler(columns) {
columns.forEach(column => { // 兼容IE
if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) { this.getElementPromise('tbody').then(() => {
// 兼容 旧版本 options columns.forEach(column => {
if (column.options instanceof Array) { if (column.type === FormTypes.select || column.type === FormTypes.list_multi || column.type === FormTypes.sel_search) {
column.options = column.options.map(item => { // 兼容 旧版本 options
if (item) { if (column.options instanceof Array) {
return { column.options = column.options.map(item => {
...item, if (item) {
text: item.text || item.title, return {
title: item.text || item.title ...item,
text: item.text || item.title,
title: item.text || item.title
}
} }
} return {}
return {} })
}) }
if (column.dictCode) {
this._loadDictConcatToOptions(column)
}
} }
if (column.dictCode) { })
this._loadDictConcatToOptions(column)
}
}
}) })
} }
}, },
@ -923,19 +992,12 @@
} }
}, },
mounted() { mounted() {
// 获取document element对象
let elements = {};
['inputTable', 'tbody'].forEach(id => {
elements[id] = document.getElementById(this.caseId + id)
})
this.el = elements
let vm = this let vm = this
/** 监听滚动条事件 */ /** 监听滚动条事件 */
this.el.inputTable.onscroll = function (event) { this.getElement('inputTable').onscroll = function (event) {
vm.syncScrollBar(event.target.scrollLeft) vm.syncScrollBar(event.target.scrollLeft)
} }
this.el.tbody.onscroll = function (event) { this.getElement('tbody').onscroll = function (event) {
// vm.recalcTrHiddenItem(event.target.scrollTop) // vm.recalcTrHiddenItem(event.target.scrollTop)
} }
@ -955,6 +1017,25 @@
}, },
methods: { methods: {
getElement(id, noCaseId = false) {
if (!this.el[id]) {
this.el[id] = document.getElementById((noCaseId ? '' : this.caseId) + id)
}
return this.el[id]
},
getElementPromise(id, noCaseId = false) {
return new Promise((resolve) => {
let timer = setInterval(() => {
let element = this.getElement(id, noCaseId)
if (element) {
clearInterval(timer)
resolve(element)
}
}, 10)
})
},
/** 初始化列表 */ /** 初始化列表 */
initialize() { initialize() {
// inputValues用来存储input表单的值 // inputValues用来存储input表单的值
@ -985,14 +1066,14 @@
this.searchSelectValues = [] this.searchSelectValues = []
this.scrollTop = 0 this.scrollTop = 0
this.$nextTick(() => { this.$nextTick(() => {
this.el.tbody.scrollTop = 0 this.getElement('tbody').scrollTop = 0
}) })
}, },
/** 同步滚动条状态 */ /** 同步滚动条状态 */
syncScrollBar(scrollLeft) { syncScrollBar(scrollLeft) {
// this.style.tbody.left = `${scrollLeft}px` // this.style.tbody.left = `${scrollLeft}px`
// this.el.tbody.scrollLeft = scrollLeft // this.getElement('tbody').scrollLeft = scrollLeft
}, },
/** 重置滚动条位置,参数留空则滚动到上次记录的位置 */ /** 重置滚动条位置,参数留空则滚动到上次记录的位置 */
resetScrollTop(top) { resetScrollTop(top) {
@ -1157,7 +1238,7 @@
target: this target: this
}) })
// 设置滚动条位置 // 设置滚动条位置
let tbody = this.el.tbody let tbody = this.getElement('tbody')
let offsetHeight = tbody.offsetHeight let offsetHeight = tbody.offsetHeight
let realScrollTop = tbody.scrollTop + offsetHeight let realScrollTop = tbody.scrollTop + offsetHeight
if (forceScrollToBottom === false) { if (forceScrollToBottom === false) {
@ -1245,13 +1326,14 @@
return true return true
}, },
/** 获取表格表单里的值(步版) */ /** 获取表格表单里的值(步版) */
getValuesSync(options = {}) { getValuesAsync(options = {}, callback) {
let { validate, rowIds } = options let { validate, rowIds } = options
if (typeof validate !== 'boolean') validate = true if (typeof validate !== 'boolean') validate = true
if (!(rowIds instanceof Array)) rowIds = null if (!(rowIds instanceof Array)) rowIds = null
// console.log('options:', { validate, rowIds }) // console.log('options:', { validate, rowIds })
let asyncCount = 0
let error = 0 let error = 0
let inputValues = cloneObject(this.inputValues) let inputValues = cloneObject(this.inputValues)
let tooltips = Object.assign({}, this.tooltips) let tooltips = Object.assign({}, this.tooltips)
@ -1314,7 +1396,7 @@
} else if (column.type === FormTypes.sel_search) { } else if (column.type === FormTypes.sel_search) {
value[column.key] = this.searchSelectValues[inputId] value[column.key] = this.searchSelectValues[inputId]
} else if (column.type === FormTypes.list_multi) { } else if (column.type === FormTypes.list_multi) {
if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length == 0) { if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length === 0) {
value[column.key] = '' value[column.key] = ''
} else { } else {
value[column.key] = this.multiSelectValues[inputId].join(',') value[column.key] = this.multiSelectValues[inputId].join(',')
@ -1326,20 +1408,27 @@
// 检查表单验证 // 检查表单验证
if (validate === true) { if (validate === true) {
let results = this.validateOneInput(value[column.key], value, column, notPassedIds, false, 'getValues') const handleValidateOneInput = (results) => {
tooltips[inputId] = results[0] tooltips[inputId] = results[0]
if (tooltips[inputId].passed === false) { if (tooltips[inputId].passed === false) {
error++ error++
// if (error++ === 0) { // if (error++ === 0) {
// let element = document.getElementById(inputId) // let element = document.getElementById(inputId)
// while (element.className !== 'tr') { // while (element.className !== 'tr') {
// element = element.parentElement // element = element.parentElement
// } // }
// this.jumpToId(inputId, element) // this.jumpToId(inputId, element)
// } // }
}
tooltips[inputId].visible = false
notPassedIds = results[1]
} }
tooltips[inputId].visible = false asyncCount++
notPassedIds = results[1] let results = this.validateOneInputAsync(value[column.key], value, column, notPassedIds, false, 'getValues', (results) => {
handleValidateOneInput(results)
asyncCount--
})
handleValidateOneInput(results)
} }
}) })
// 将caseId去除 // 将caseId去除
@ -1352,25 +1441,42 @@
this.tooltips = tooltips this.tooltips = tooltips
this.notPassedIds = notPassedIds this.notPassedIds = notPassedIds
} }
const timer = setInterval(() => {
if (asyncCount === 0) {
clearInterval(timer)
if (typeof callback === 'function') {
callback({ error, values })
}
}
}, 50)
return { error, values } return { error, values }
}, },
/** 获取表格表单里的值(同步版) */
getValuesSync(options = {}) {
return this.getValuesAsync(options)
},
/** 获取表格表单里的值 */ /** 获取表格表单里的值 */
getValues(callback, validate = true, rowIds) { getValues(callback, validate = true, rowIds) {
let result = this.getValuesSync({ validate, rowIds }) this.getValuesAsync({ validate, rowIds }, ({ error, values }) => {
if (typeof callback === 'function') { if (typeof callback === 'function') {
callback(result.error, result.values) callback(error, values)
} }
})
}, },
/** getValues的Promise版 */ /** getValues的Promise版 */
getValuesPromise(validate = true, rowIds) { getValuesPromise(validate = true, rowIds) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let { error, values } = this.getValuesSync({ validate, rowIds }) this.getValuesAsync({ validate, rowIds }, ({ error, values }) => {
if (error === 0) { if (error === 0) {
resolve(values) resolve(values)
} else { } else {
reject(VALIDATE_NO_PASSED) reject(VALIDATE_NO_PASSED)
} }
})
}) })
}, },
/** 获取被删除项的id */ /** 获取被删除项的id */
@ -1468,14 +1574,24 @@
// element = document.getElementById(id) // element = document.getElementById(id)
// } // }
// if (element != null) { // if (element != null) {
// console.log(this.el.tbody.scrollTop, element.offsetTop) // console.log(this.getElement('tbody').scrollTop, element.offsetTop)
// this.el.tbody.scrollTop = element.offsetTop // this.getElement('tbody').scrollTop = element.offsetTop
// console.log(this.el.tbody.scrollTop, element.offsetTop) // console.log(this.getElement('tbody').scrollTop, element.offsetTop)
// } // }
// }, // },
/** 验证单个表单 */ /**
validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') { *
*
* @param value
* @param row
* @param column
* @param notPassedIds id
* @param update vue
* @param validType inputblur
* @param callback
*/
validateOneInputAsync(value, row, column, notPassedIds, update = false, validType = 'input', callback) {
let tooltips = Object.assign({}, this.tooltips) let tooltips = Object.assign({}, this.tooltips)
// let notPassedIds = cloneObject(this.notPassedIds) // let notPassedIds = cloneObject(this.notPassedIds)
let inputId = column.key + row.id let inputId = column.key + row.id
@ -1515,6 +1631,10 @@
if (column.type === FormTypes.date || column.type === FormTypes.datetime) { if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
element = element.getElementsByTagName('input')[0] element = element.getElementsByTagName('input')[0]
} }
// upload 在 .ant-upload .ant-btn 上设置 border-color
if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
element = element.getElementsByClassName('ant-upload')[0].getElementsByClassName('ant-btn')[0]
}
element.style.borderColor = borderColor element.style.borderColor = borderColor
element.style.boxShadow = boxShadow element.style.boxShadow = boxShadow
if (element.tagName === 'SPAN') { if (element.tagName === 'SPAN') {
@ -1527,6 +1647,10 @@
this.notPassedIds = notPassedIds this.notPassedIds = notPassedIds
} }
if (typeof callback === 'function') {
callback([tooltips[inputId], notPassedIds])
}
} }
if (typeof passed === 'function') { if (typeof passed === 'function') {
@ -1547,9 +1671,13 @@
nextThen([passed, message]) nextThen([passed, message])
} }
return [tooltips[inputId], notPassedIds] return [tooltips[inputId], notPassedIds]
}, },
/** 验证单个表单 */
validateOneInput(value, row, column, notPassedIds, update = false, validType = 'input') {
return this.validateOneInputAsync(value, row, column, notPassedIds, update, validType)
},
/** 通过规则验证值是否正确 */ /** 通过规则验证值是否正确 */
validateValue(column, value) { validateValue(column, value) {
let rules = column.validateRules let rules = column.validateRules
@ -1620,7 +1748,7 @@
/** 动态更新表单的值 */ /** 动态更新表单的值 */
updateFormValues() { updateFormValues() {
let trs = this.el.tbody.getElementsByClassName('tr') let trs = this.getElement('tbody').getElementsByClassName('tr')
let trEls = [] let trEls = []
for (let tr of trs) { for (let tr of trs) {
trEls.push(tr) trEls.push(tr)
@ -1959,7 +2087,7 @@
handleClickDownloadFile(id) { handleClickDownloadFile(id) {
let { path } = this.uploadValues[id] || {} let { path } = this.uploadValues[id] || {}
if (path) { if (path) {
let url = window._CONFIG['downloadUrl'] + '/' + path let url = window._CONFIG['staticDomainURL'] + '/' + path
window.open(url) window.open(url)
} }
}, },
@ -2130,7 +2258,7 @@
getCellImageView(id) { getCellImageView(id) {
let currUploadObj = this.uploadValues[id] || null let currUploadObj = this.uploadValues[id] || null
if (currUploadObj && currUploadObj['path']) { if (currUploadObj && currUploadObj['path']) {
return window._CONFIG['domianURL'] + '/sys/common/view/' + currUploadObj['path'] return window._CONFIG['staticDomainURL'] + '/' + currUploadObj['path']
} else { } else {
return '' return ''
} }
@ -2340,7 +2468,7 @@
.td { .td {
/*flex: 1;*/ /*flex: 1;*/
padding: 14px 0 14px @spacing; padding: 14px @spacing 14px 0;
justify-content: center; justify-content: center;
&:last-child { &:last-child {

View File

@ -150,7 +150,7 @@
console.log("aaaaa",res) console.log("aaaaa",res)
if(res.success){ if(res.success){
this.checkKey = res.result.key this.checkKey = res.result.key
this.code = res.result.code this.code = window.atob(res.result.code)
resolve(); resolve();
}else{ }else{
this.$message.error("生成验证码错误,请联系系统管理员") this.$message.error("生成验证码错误,请联系系统管理员")

View File

@ -0,0 +1,202 @@
<template>
<a-upload
name="file"
listType="picture-card"
:multiple="isMultiple"
:action="uploadAction"
:headers="headers"
:data="{biz:bizPath}"
:fileList="fileList"
:beforeUpload="beforeUpload"
:disabled="disabled"
:isMultiple="isMultiple"
:showUploadList="isMultiple"
@change="handleChange"
@preview="handlePreview">
<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="height:104px;max-width:300px"/>
<div v-else >
<a-icon :type="uploadLoading ? 'loading' : 'plus'" />
<div class="ant-upload-text">{{ text }}</div>
</div>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
<img alt="example" style="width: 100%" :src="previewImage"/>
</a-modal>
</a-upload>
</template>
<script>
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import { getFileAccessHttpUrl } from '@/api/manage'
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: 'JImageUpload',
data(){
return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlView:window._CONFIG['staticDomainURL'],
uploadLoading:false,
picUrl:false,
headers:{},
fileList: [],
previewImage:"",
previewVisible: false,
}
},
props:{
text:{
type:String,
required:false,
default:"上传"
},
/*这个属性用于控制文件上传的业务路径*/
bizPath:{
type:String,
required:false,
default:"temp"
},
value:{
type:[String,Array],
required:false
},
disabled:{
type:Boolean,
required:false,
default: false
},
isMultiple:{
type:Boolean,
required:false,
default: false
}
},
watch:{
value(val){
if (val instanceof Array) {
this.initFileList(val.join(','))
} else {
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){
this.fileList = [];
return;
}
this.picUrl = true;
let fileList = [];
let arr = paths.split(",")
for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlView,"http");
fileList.push({
uid: uidGenerator(),
name: getFileName(arr[a]),
status: 'done',
url: url,
response:{
status:"history",
message:arr[a]
}
})
}
this.fileList = fileList
},
beforeUpload: function(file){
var fileType = file.type;
if(fileType.indexOf('image')<0){
this.$message.warning('');
return false;
}
},
handleChange(info) {
this.picUrl = false;
let fileList = info.fileList
if(info.file.status==='done'){
if(info.file.response.success){
this.picUrl = true;
fileList = fileList.map((file) => {
if (file.response) {
file.url = 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()
}
},
// 预览
handlePreview (file) {
this.previewImage = file.url || file.thumbUrl
this.previewVisible = true
},
getAvatarView(){
if(this.fileList.length>0){
let url = this.fileList[0].url
return getFileAccessHttpUrl(url,this.urlView,"http")
}
},
handlePathChange(){
let uploadFiles = this.fileList
let path = ''
if(!uploadFiles || uploadFiles.length==0){
path = ''
}
let arr = [];
if(!this.isMultiple){
arr.push(uploadFiles[uploadFiles.length-1].response.message)
}else{
for(var a=0;a<uploadFiles.length;a++){
arr.push(uploadFiles[a].response.message)
}
}
if(arr.length>0){
path = arr.join(",")
}
this.$emit('change', path);
},
handleDelete(file){
//如有需要新增 删除逻辑
console.log(file)
},
handleCancel() {
this.close();
this.previewVisible = false;
},
close () {
},
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
</style>

View File

@ -42,6 +42,11 @@
type: String, type: String,
default: '', default: '',
required: false required: false
},
biz:{
type: String,
default: '',
required: false
} }
}, },
data(){ data(){
@ -49,7 +54,8 @@
visible:false, visible:false,
uploading:false, uploading:false,
fileList:[], fileList:[],
uploadAction:'' uploadAction:'',
foreignKeys:''
} }
}, },
watch: { watch: {
@ -67,10 +73,11 @@
handleClose(){ handleClose(){
this.visible=false this.visible=false
}, },
show(){ show(arg){
this.fileList = [] this.fileList = []
this.uploading = false this.uploading = false
this.visible = true this.visible = true
this.foreignKeys = arg;
}, },
handleRemove(file) { handleRemove(file) {
const index = this.fileList.indexOf(file); const index = this.fileList.indexOf(file);
@ -85,6 +92,12 @@
handleImport() { handleImport() {
const { fileList } = this; const { fileList } = this;
const formData = new FormData(); const formData = new FormData();
if(this.biz){
formData.append('isSingleTableImport',this.biz);
}
if(this.foreignKeys && this.foreignKeys.length>0){
formData.append('foreignKeys',this.foreignKeys);
}
fileList.forEach((file) => { fileList.forEach((file) => {
formData.append('files[]', file); formData.append('files[]', file);
}); });

View File

@ -0,0 +1,209 @@
<template>
<a-modal
ref="modal"
class="j-modal-box"
:class="{'fullscreen':innerFullscreen,'no-title':isNoTitle,'no-footer':isNoFooter,}"
:visible="visible"
v-bind="_attrs"
v-on="$listeners"
@ok="handleOk"
@cancel="handleCancel"
>
<slot></slot>
<template v-if="!isNoTitle" slot="title">
<a-row class="j-modal-title-row" type="flex">
<a-col class="left">
<slot name="title">{{ title }}</slot>
</a-col>
<a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
<a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/>
</a-col>
</a-row>
</template>
<!-- scopedSlots -->
<template v-for="slotName of scopedSlotsKeys" :slot="slotName">
<slot :name="slotName"></slot>
</template>
<!-- slots -->
<template v-for="slotName of slotsKeys" v-slot:[slotName]>
<slot :name="slotName"></slot>
</template>
</a-modal>
</template>
<script>
import ACol from 'ant-design-vue/es/grid/Col'
export default {
name: 'JModal',
components: { ACol },
props: {
title: String,
// 可使用 .sync 修饰符
visible: Boolean,
// 是否在弹出时禁止 body 滚动
lockScroll: {
type: Boolean,
default: true
},
// 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
fullscreen: {
type: Boolean,
default: true
},
// 是否允许切换全屏(允许后右上角会出现一个按钮)
switchFullscreen: {
type: Boolean,
default: false
},
},
data() {
return {
// 内部使用的 slots ,不再处理
usedSlots: ['title'],
// 缓存 body 的 overflow
bodyOverflowCache: '',
innerFullscreen: this.fullscreen,
fullscreenButtonIcon: 'fullscreen-exit',
}
},
computed: {
// 一些未处理的参数或特殊处理的参数绑定到 a-modal 上
_attrs() {
let attrs = { ...this.$attrs }
// 如果全屏就将宽度设为 100%
if (this.innerFullscreen) {
attrs['width'] = '100%'
}
return attrs
},
isNoTitle() {
return !this.title && !this.allSlotsKeys.includes('title')
},
isNoFooter() {
return this._attrs['footer'] === null
},
slotsKeys() {
return Object.keys(this.$slots).filter(key => !this.usedSlots.includes(key))
},
scopedSlotsKeys() {
return Object.keys(this.$scopedSlots).filter(key => !this.usedSlots.includes(key))
},
allSlotsKeys() {
return this.slotsKeys.concat(this.scopedSlotsKeys)
},
// 是否锁定body滚动
lockBodyScroll() {
return this.lockScroll || this.innerFullscreen
}
},
watch: {
visible() {
if (this.visible) {
this.innerFullscreen = this.fullscreen
}
if (this.lockBodyScroll) {
if (this.visible) {
this.bodyOverflowCache = document.body.style.overflow
document.body.style.overflow = 'hidden'
} else {
document.body.style.overflow = this.bodyOverflowCache
}
}
},
innerFullscreen(val) {
this.$emit('update:fullscreen', val)
},
},
methods: {
close() {
this.$emit('update:visible', false)
},
handleOk() {
this.close()
},
handleCancel() {
this.close()
},
toggleFullscreen() {
if (this.innerFullscreen) {
this.fullscreenButtonIcon = 'fullscreen'
} else {
this.fullscreenButtonIcon = 'fullscreen-exit'
}
this.innerFullscreen = !this.innerFullscreen
},
}
}
</script>
<style lang="scss">
.j-modal-box {
&.fullscreen {
top: 0;
left: 0;
padding: 0;
height: 100vh;
& .ant-modal-content {
height: 100vh;
border-radius: 0;
& .ant-modal-body {
/* title 和 footer 各占 55px */
height: calc(100% - 55px - 55px);
overflow: auto;
}
}
&.no-title, &.no-footer {
.ant-modal-body {
height: calc(100% - 55px);
}
}
&.no-title.no-footer {
.ant-modal-body {
height: 100%;
}
}
}
.j-modal-title-row {
.left {
width: calc(100% - 56px - 56px);
}
.right {
width: 56px;
.ant-modal-close {
right: 56px;
color: rgba(0, 0, 0, 0.45);
&:hover {
color: rgba(0, 0, 0, 0.75);
}
}
}
}
/deep/ {
}
}
</style>

View File

@ -1,15 +1,22 @@
<template> <template>
<div class="j-super-query-box"> <div class="j-super-query-box">
<slot> <div @click="visible=true">
<a-tooltip v-if="superQueryFlag" title="已有高级查询条件生效"> <slot>
<a-button type="primary" @click="visible=true"> <a-tooltip v-if="superQueryFlag" :mouseLeaveDelay="0.2">
<a-icon type="appstore" theme="twoTone" :spin="true"></a-icon> <template slot="title">
<span></span> <span></span>
</a-button> <a-divider type="vertical"/>
</a-tooltip> <a @click="handleReset"></a>
<a-button v-else type="primary" icon="filter" @click="visible=true"></a-button> </template>
</slot> <a-button type="primary">
<a-icon type="appstore" theme="twoTone" :spin="true"></a-icon>
<span></span>
</a-button>
</a-tooltip>
<a-button v-else type="primary" icon="filter" @click="visible=true"></a-button>
</slot>
</div>
<a-modal <a-modal
title="高级查询构造器" title="高级查询构造器"

View File

@ -4,11 +4,12 @@
:multiple="true" :multiple="true"
:action="uploadAction" :action="uploadAction"
:headers="headers" :headers="headers"
:data="{'isup':1,'bizPath':bizPath}" :data="{'biz':bizPath}"
:fileList="fileList" :fileList="fileList"
:beforeUpload="beforeUpload" :beforeUpload="beforeUpload"
@change="handleChange" @change="handleChange"
:disabled="disabled"> :disabled="disabled"
:returnUrl="returnUrl">
<a-button> <a-button>
<a-icon type="upload" />{{ text }} <a-icon type="upload" />{{ text }}
</a-button> </a-button>
@ -19,6 +20,7 @@
import Vue from 'vue' import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types" import { ACCESS_TOKEN } from "@/store/mutation-types"
import { getFileAccessHttpUrl } from '@/api/manage';
const FILE_TYPE_ALL = "all" const FILE_TYPE_ALL = "all"
const FILE_TYPE_IMG = "image" const FILE_TYPE_IMG = "image"
@ -38,9 +40,10 @@
data(){ data(){
return { return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload", uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlDownload:window._CONFIG['domianURL'] + "/sys/common/download/", urlDownload:window._CONFIG['staticDomainURL'],
headers:{}, headers:{},
fileList: [] fileList: [],
newFileList: [],
} }
}, },
props:{ props:{
@ -77,11 +80,25 @@
required: false, required: false,
default: false default: false
}, },
/**
* update -- author:lvdandan -- date:20190219 -- for:Juploadurl
* trueurl
* falsefileName filePath fileSize
*/
returnUrl:{
type:Boolean,
required:false,
default: true
},
}, },
watch:{ watch:{
value(val){ value(val){
if (val instanceof Array) { if (val instanceof Array) {
this.initFileList(val.join(',')) if(this.returnUrl){
this.initFileList(val.join(','))
}else{
this.initFileListArr(val);
}
} else { } else {
this.initFileList(val) this.initFileList(val)
} }
@ -93,6 +110,26 @@
}, },
methods:{ methods:{
initFileListArr(val){
if(!val || val.length==0){
this.fileList = [];
return;
}
let fileList = [];
for(var a=0;a<val.length;a++){
fileList.push({
uid:uidGenerator(),
name:val[a].fileName,
status: 'done',
url: val[a].filePath,
response:{
status:"history",
message:val[a].filePath
}
})
}
this.fileList = fileList
},
initFileList(paths){ initFileList(paths){
if(!paths || paths.length==0){ if(!paths || paths.length==0){
//return []; //return [];
@ -104,11 +141,12 @@
let fileList = []; let fileList = [];
let arr = paths.split(",") let arr = paths.split(",")
for(var a=0;a<arr.length;a++){ for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlDownload,"http");
fileList.push({ fileList.push({
uid:uidGenerator(), uid:uidGenerator(),
name:getFileName(arr[a]), name:getFileName(arr[a]),
status: 'done', status: 'done',
url: this.urlDownload+arr[a], url: url,
response:{ response:{
status:"history", status:"history",
message:arr[a] message:arr[a]
@ -156,12 +194,13 @@
if(info.file.response.success){ if(info.file.response.success){
fileList = fileList.map((file) => { fileList = fileList.map((file) => {
if (file.response) { if (file.response) {
file.url = this.urlDownload+file.response.message; let reUrl = file.response.message;
file.url = getFileAccessHttpUrl(reUrl,this.urlDownload,"http");
} }
return file; return file;
}); });
} }
this.$message.success(`${info.file.name} !`); //this.$message.success(`${info.file.name} 上传成功!`);
}else if (info.file.status === 'error') { }else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} .`); this.$message.error(`${info.file.name} .`);
}else if(info.file.status === 'removed'){ }else if(info.file.status === 'removed'){
@ -169,7 +208,26 @@
} }
this.fileList = fileList this.fileList = fileList
if(info.file.status==='done' || info.file.status === 'removed'){ if(info.file.status==='done' || info.file.status === 'removed'){
this.handlePathChange() //returnUrl为true时仅返回文件路径
if(this.returnUrl){
this.handlePathChange()
}else{
//returnUrl为false时返回文件名称、文件路径及文件大小
fileList = fileList.filter((file) => {
if (file.response) {
return file.response.success === true;
}
return false;
}).map((file) => {
var fileJson = {
fileName:file.name,
filePath:file.url,
fileSize:file.size
};
this.newFileList.push(fileJson);
this.$emit('change', this.newFileList);
});
}
} }
}, },
handleDelete(file){ handleDelete(file){

View File

@ -1,5 +1,9 @@
import T from './JFormContainer.vue' import JModal from './JModal'
let install = function (Vue) { import JFormContainer from './JFormContainer.vue'
Vue.component('JFormContainer',T);
} export default {
export default { install }; install(Vue) {
Vue.component('JFormContainer', JFormContainer)
Vue.component(JModal.name, JModal)
}
}

View File

@ -17,9 +17,11 @@
selectable selectable
:selectedKeys="selectedDepIds" :selectedKeys="selectedDepIds"
:checkStrictly="true" :checkStrictly="true"
@select="onDepSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}" :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree" :treeData="departTree"
:expandAction="false"
:expandedKeys.sync="expandedKeys"
@select="onDepSelect"
/> />
</a-card> </a-card>
</a-col> </a-col>
@ -28,7 +30,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>
@ -43,6 +45,7 @@
:dataSource="dataSource" :dataSource="dataSource"
:pagination="ipagination" :pagination="ipagination"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}" :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
:loading="loading"
@change="handleTableChange"> @change="handleTableChange">
</a-table> </a-table>
</a-card> </a-card>
@ -71,7 +74,7 @@
dataIndex: 'username' dataIndex: 'username'
}, },
{ {
title: '', title: '',
align: 'center', align: 'center',
dataIndex: 'realname' dataIndex: 'realname'
}, },
@ -90,14 +93,14 @@
} }
}, },
{ {
title: '', title: '',
align: 'center', align: 'center',
dataIndex: 'phone' dataIndex: 'phone'
}, },
{ {
title: '', title: '',
align: 'center', align: 'center',
dataIndex: 'email' dataIndex: 'orgCode'
} }
], ],
scrollTrigger: {}, scrollTrigger: {},
@ -124,60 +127,74 @@
selectedDepIds: [], selectedDepIds: [],
departTree: [], departTree: [],
visible: false, visible: false,
form: this.$form.createForm(this) form: this.$form.createForm(this),
loading: false,
expandedKeys: [],
} }
}, },
computed: { computed: {
// 计算属性的 getter // 计算属性的 getter
getType: function () { getType: function () {
console.log("multi: ", this.multi);
return this.multi == true ? 'checkbox' : 'radio'; return this.multi == true ? 'checkbox' : 'radio';
} }
}, },
watch: { watch: {
userIds() { userIds: {
this.initUserNames() immediate: true,
} handler() {
this.initUserNames()
}
},
}, },
created() { created() {
// 该方法触发屏幕自适应 // 该方法触发屏幕自适应
this.resetScreenSize(); this.resetScreenSize();
this.loadData().then((res) => { this.loadData()
this.initUserNames();
})
}, },
methods: { methods: {
initUserNames() { initUserNames() {
let names = ''
console.log("props userIds: ", this.userIds)
if (this.userIds) { if (this.userIds) {
let currUserIds = this.userIds // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
let userIdsArr = currUserIds.split(','); let values = this.userIds.split(',') + ','
for (let item of this.dataSource) { getUserList({
if (userIdsArr.includes(item.username)) { username: values,
names += "," + item.realname pageNo: 1,
pageSize: values.length
}).then((res) => {
if (res.success) {
let selectedRowKeys = []
let realNames = []
res.result.records.forEach(user => {
realNames.push(user['realname'])
selectedRowKeys.push(user['id'])
})
this.selectedRowKeys = selectedRowKeys
this.$emit('initComp', realNames.join(','))
} }
} })
if (names) { } else {
names = names.substring(1)
}
this.$emit("initComp", names)
}else{
// JSelectUserByDep组件bug issues/I16634 // JSelectUserByDep组件bug issues/I16634
this.$emit("initComp", "") this.$emit('initComp', '')
} }
}, },
async loadData(arg) { async loadData(arg) {
if (arg === 1) { if (arg === 1) {
this.ipagination.current = 1; this.ipagination.current = 1;
} }
let params = this.getQueryParams();//查询条件 if (this.selectedDepIds && this.selectedDepIds.length > 0) {
await getUserList(params).then((res) => { await this.initQueryUserByDepId(this.selectedDepIds)
if (res.success) { } else {
this.dataSource = res.result.records; this.loading = true
this.ipagination.total = res.result.total; let params = this.getQueryParams()//查询条件
} await getUserList(params).then((res) => {
}) if (res.success) {
this.dataSource = res.result.records
this.ipagination.total = res.result.total
}
}).finally(() => {
this.loading = false
})
}
}, },
// 触发屏幕自适应 // 触发屏幕自适应
resetScreenSize() { resetScreenSize() {
@ -191,6 +208,7 @@
showModal() { showModal() {
this.visible = true; this.visible = true;
this.queryDepartTree(); this.queryDepartTree();
this.initUserNames()
this.loadData(); this.loadData();
this.form.resetFields(); this.form.resetFields();
}, },
@ -234,7 +252,6 @@
handleSubmit() { handleSubmit() {
let that = this; let that = this;
this.getSelectUserRows(); this.getSelectUserRows();
console.log(that.selectUserRows)
that.$emit('ok', that.selectUserRows, that.selectUserIds); that.$emit('ok', that.selectUserRows, that.selectUserIds);
that.searchReset(0) that.searchReset(0)
that.close(); that.close();
@ -270,17 +287,22 @@
}, },
// 根据选择的id来查询用户信息 // 根据选择的id来查询用户信息
initQueryUserByDepId(selectedDepIds) { initQueryUserByDepId(selectedDepIds) {
queryUserByDepId({id: selectedDepIds.toString()}).then((res) => { this.loading = true
return queryUserByDepId({id: selectedDepIds.toString()}).then((res) => {
if (res.success) { if (res.success) {
this.dataSource = res.result; this.dataSource = res.result;
this.ipagination.total = res.result.length; this.ipagination.total = res.result.length;
} }
}).finally(() => {
this.loading = false
}) })
}, },
queryDepartTree() { queryDepartTree() {
queryDepartTreeList().then((res) => { queryDepartTreeList().then((res) => {
if (res.success) { if (res.success) {
this.departTree = res.result; this.departTree = res.result;
// 默认展开父节点
this.expandedKeys = this.departTree.map(item => item.id)
} }
}) })
}, },

View File

@ -46,7 +46,7 @@
width: 200 width: 200
}, },
{ {
title: '', title: '',
align: "center", align: "center",
dataIndex: 'realname', dataIndex: 'realname',
}, },

View File

@ -5,6 +5,8 @@
</template> </template>
<script> <script>
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import PageLayout from '../page/PageLayout' import PageLayout from '../page/PageLayout'
import RouteView from './RouteView' import RouteView from './RouteView'
@ -40,6 +42,12 @@
/*update_begin author:wuxianquan date:20190908 for:判断打开方式新窗口打开时this.$route.meta.internalOrExternal==true */ /*update_begin author:wuxianquan date:20190908 for:判断打开方式新窗口打开时this.$route.meta.internalOrExternal==true */
if(this.$route.meta.internalOrExternal != undefined && this.$route.meta.internalOrExternal==true){ if(this.$route.meta.internalOrExternal != undefined && this.$route.meta.internalOrExternal==true){
this.closeCurrent(); this.closeCurrent();
//外部url加入token
let tokenStr = "${token}";
if(url.indexOf(tokenStr)!=-1){
let token = Vue.ls.get(ACCESS_TOKEN);
this.url = url.replace(tokenStr,token);
}
window.open(this.url); window.open(this.url);
} }
/*update_end author:wuxianquan date:20190908 for:判断打开方式新窗口打开时this.$route.meta.internalOrExternal==true */ /*update_end author:wuxianquan date:20190908 for:判断打开方式新窗口打开时this.$route.meta.internalOrExternal==true */

View File

@ -80,30 +80,41 @@
}, },
created() { created() {
if (this.$route.path != indexKey) { if (this.$route.path != indexKey) {
this.pageList.push({ this.addIndexToFirst()
name: 'dashboard-analysis',
path: indexKey,
fullPath: indexKey,
meta: {
icon: 'dashboard',
title: ''
}
})
this.linkList.push(indexKey)
} }
// update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
let storeKey = 'route:title:' + this.$route.fullPath
let routeTitle = this.$ls.get(storeKey)
if (routeTitle) {
this.$route.meta.title = routeTitle
}
// update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
this.pageList.push(this.$route) this.pageList.push(this.$route)
this.linkList.push(this.$route.fullPath) this.linkList.push(this.$route.fullPath)
this.activePage = this.$route.fullPath this.activePage = this.$route.fullPath
}, },
watch: { watch: {
'$route': function(newRoute) { '$route': function(newRoute) {
//console.log("新的路由",newRoute)
this.activePage = newRoute.fullPath this.activePage = newRoute.fullPath
if (!this.multipage) { if (!this.multipage) {
this.linkList = [newRoute.fullPath] this.linkList = [newRoute.fullPath]
this.pageList = [Object.assign({},newRoute)] this.pageList = [Object.assign({},newRoute)]
} else if (this.linkList.indexOf(newRoute.fullPath) < 0) { // update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
} else if(indexKey==newRoute.fullPath) {
//首页时 判断是否缓存 没有缓存 刷新之
if (newRoute.meta.keepAlive === false) {
this.routeReload()
}
// update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
}else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
this.linkList.push(newRoute.fullPath) this.linkList.push(newRoute.fullPath)
this.pageList.push(Object.assign({},newRoute)) this.pageList.push(Object.assign({},newRoute))
// update-begin-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍
if (newRoute.meta.keepAlive) {
this.routeReload()
}
// update-end-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍
} 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)
let oldPositionRoute = this.pageList[oldIndex] let oldPositionRoute = this.pageList[oldIndex]
@ -114,6 +125,7 @@
let index = this.linkList.lastIndexOf(key) let index = this.linkList.lastIndexOf(key)
let waitRouter = this.pageList[index] let waitRouter = this.pageList[index]
this.$router.push(Object.assign({},waitRouter)); this.$router.push(Object.assign({},waitRouter));
this.changeTitle(waitRouter.meta.title)
}, },
'multipage': function(newVal) { 'multipage': function(newVal) {
if(this.reloadFlag){ if(this.reloadFlag){
@ -122,9 +134,44 @@
this.pageList = [this.$route] this.pageList = [this.$route]
} }
} }
} },
// update-begin-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
device() {
if (this.multipage && this.linkList.indexOf(indexKey) === -1) {
this.addIndexToFirst()
}
},
// update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
}, },
methods: { methods: {
// update-begin-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
// 将首页添加到第一位
addIndexToFirst() {
this.pageList.splice(0, 0, {
name: 'dashboard-analysis',
path: indexKey,
fullPath: indexKey,
meta: {
icon: 'dashboard',
title: ''
}
})
this.linkList.splice(0, 0, indexKey)
},
// update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
// update-begin-author:sunjianlei date:20200120 for: 动态更改页面标题
changeTitle(title) {
let projectTitle = "Jeecg-Boot 企业级快速开发平台"
// 首页特殊处理
if (this.$route.path === indexKey) {
document.title = projectTitle
} else {
document.title = title + ' · ' + projectTitle
}
},
// update-end-author:sunjianlei date:20200120 for: 动态更改页面标题
changePage(key) { changePage(key) {
this.activePage = key this.activePage = key
}, },
@ -236,6 +283,9 @@
let currRouter = this.pageList[keyIndex] let currRouter = this.pageList[keyIndex]
let meta = Object.assign({},currRouter.meta,{title:title}) let meta = Object.assign({},currRouter.meta,{title:title})
this.pageList.splice(keyIndex, 1, Object.assign({},currRouter,{meta:meta})) this.pageList.splice(keyIndex, 1, Object.assign({},currRouter,{meta:meta}))
if (key === this.activePage) {
this.changeTitle(title)
}
} }
}, },
//update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title //update-end-author:taoyan date:20190430 for:动态路由title显示配置的菜单title而不是其对应路由的title

View File

@ -17,12 +17,12 @@
<div class="footer"> <div class="footer">
<div class="links"> <div class="links">
<a href="http://jeecg-boot.mydoc.io" target="_blank"></a> <a href="http://doc.jeecg.com" target="_blank"></a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"></a> <a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"></a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"></a> <a href="https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE" target="_blank"></a>
</div> </div>
<div class="copyright"> <div class="copyright">
Copyright &copy; 2019 <a href="http://www.jeecg.org" target="_blank">JEECG</a> Copyright &copy; 2019 <a href="http://www.jeecg.com" target="_blank">JEECG</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="footer"> <div class="footer">
<div class="links"> <div class="links">
<a href="http://www.jeecg.org" target="_blank">JEECG </a> <a href="http://www.jeecg.com" target="_blank">JEECG </a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"> <a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">
<a-icon type="github"/> <a-icon type="github"/>
</a> </a>

View File

@ -197,7 +197,7 @@
&.dark { &.dark {
color: #000000; color: #000000;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
background-color: @primary-color; background-color: white !important;
} }
} }

View File

@ -154,6 +154,10 @@
//此处触发动态路由被点击事件 //此处触发动态路由被点击事件
this.findMenuBykey(this.menus,value.key) this.findMenuBykey(this.menus,value.key)
this.$emit("dynamicRouterShow",value.key,this.activeMenu.meta.title) this.$emit("dynamicRouterShow",value.key,this.activeMenu.meta.title)
// update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
let storeKey = 'route:title:' + this.activeMenu.path
this.$ls.set(storeKey, this.activeMenu.meta.title)
// update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
}, },
findMenuBykey(menus,key){ findMenuBykey(menus,key){
for(let i of menus){ for(let i of menus){
@ -337,6 +341,10 @@
font-size: 16px; font-size: 16px;
padding: 4px; padding: 4px;
} }
.anticon {
color: white;
}
} }
} }
@ -349,6 +357,10 @@
&:hover { &:hover {
background: rgba(0, 0, 0, 0.05); background: rgba(0, 0, 0, 0.05);
} }
.anticon {
color: black;
}
} }
} }
} }

View File

@ -0,0 +1,36 @@
<template>
<component
:is="comp"
:formData="formData"
ref="compModel"
v-if="comp">
</component>
</template>
<script>
export default {
name: 'DynamicNotice',
data () {
return {
compName: this.path
}
},
computed: {
comp: function () {
if(!this.path){
return null;
}
return () => import(`@/views/${this.path}.vue`)
}
},
props: ['path','formData'],
methods: {
detail () {
setTimeout(() => {
if(this.path){
this.$refs.compModel.view(this.formData);
}
}, 200)
},
}
}
</script>

View File

@ -72,6 +72,7 @@
</a-badge> </a-badge>
</span> </span>
<show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement> <show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement>
<dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData"/>
</a-popover> </a-popover>
</template> </template>
@ -79,11 +80,13 @@
import { getAction,putAction } from '@/api/manage' import { getAction,putAction } from '@/api/manage'
import ShowAnnouncement from './ShowAnnouncement' import ShowAnnouncement from './ShowAnnouncement'
import store from '@/store/' import store from '@/store/'
import DynamicNotice from './DynamicNotice'
export default { export default {
name: "HeaderNotice", name: "HeaderNotice",
components: { components: {
DynamicNotice,
ShowAnnouncement, ShowAnnouncement,
}, },
data () { data () {
@ -105,6 +108,8 @@
websock: null, websock: null,
lockReconnect:false, lockReconnect:false,
heartCheck:null, heartCheck:null,
formData:{},
openPath:''
} }
}, },
computed:{ computed:{
@ -172,7 +177,13 @@
} }
}); });
this.hovered = false; this.hovered = false;
this.$refs.ShowAnnouncement.detail(record); if(record.openType==='component'){
this.openPath = record.openPage;
this.formData = {id:record.busId};
this.$refs.showDynamNotice.detail(record.openPage);
}else{
this.$refs.ShowAnnouncement.detail(record);
}
}, },
toMyAnnouncement(){ toMyAnnouncement(){

View File

@ -5,11 +5,14 @@
:visible="visible" :visible="visible"
:bodyStyle ="bodyStyle" :bodyStyle ="bodyStyle"
@cancel="handleCancel" @cancel="handleCancel"
destroyOnClose destroyOnClose>
:footer="null">
<template slot="title"> <template slot="title">
<a-button icon="fullscreen" class="custom-btn" @click="handleClickToggleFullScreen"/> <a-button icon="fullscreen" class="custom-btn" @click="handleClickToggleFullScreen"/>
</template> </template>
<template slot="footer">
<a-button key="back" @click="handleCancel"></a-button>
<a-button v-if="record.openType==='url'&&record.readFlag!=='1'" type="primary" @click="toHandle"></a-button>
</template>
<a-card class="daily-article" :loading="loading"> <a-card class="daily-article" :loading="loading">
<a-card-meta <a-card-meta
:title="record.titile" :title="record.titile"
@ -74,7 +77,14 @@
this.modelStyle.style.top = '50px' this.modelStyle.style.top = '50px'
} }
this.modelStyle.fullScreen = mode this.modelStyle.fullScreen = mode
} },
toHandle(){
if(this.record.openType==='url'&&this.record.readFlag!== '1'){
this.visible = false;
//链接跳转
this.$router.push({path: this.record.openPage})
}
},
} }
} }
</script> </script>

View File

@ -5,7 +5,8 @@
<span class="action" @click="showClick"> <span class="action" @click="showClick">
<a-icon type="search"></a-icon> <a-icon type="search"></a-icon>
</span> </span>
<span v-show="shows" class="borders"> <!-- update-begin author:sunjianlei date:20200219 for: -->
<component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false">
<a-select <a-select
class="search-input" class="search-input"
showSearch showSearch
@ -13,16 +14,20 @@
placeholder="搜索菜单" placeholder="搜索菜单"
optionFilterProp="children" optionFilterProp="children"
:filterOption="filterOption" :filterOption="filterOption"
:open="isMobile()?true:null"
:getPopupContainer="(node) => node.parentNode"
:style="isMobile()?{width: '100%',marginBottom:'50px'}:{}"
@change="searchMethods" @change="searchMethods"
@blur="hiddenClick" @blur="hiddenClick"
> >
<a-select-option v-for="site in search " :value="site.id">{{site.meta.title}}</a-select-option> <a-select-option v-for="site in searchMenuOptions" :value="site.id">{{site.meta.title}}</a-select-option>
</a-select> </a-select>
</span> </component>
<!-- update-end author:sunjianlei date:20191@20 for: --> <!-- update-end author:sunjianlei date:20200219 for: -->
<!-- update-end author:sunjianlei date:20191220 for: -->
<!-- update_end author:zhaoxin date:20191129 for: --> <!-- update_end author:zhaoxin date:20191129 for: -->
<span class="action"> <span class="action">
<a class="logout_title" target="_blank" href="http://jeecg-boot.mydoc.io"> <a class="logout_title" target="_blank" href="http://doc.jeecg.com">
<a-icon type="question-circle-o"></a-icon> <a-icon type="question-circle-o"></a-icon>
</a> </a>
</span> </span>
@ -95,9 +100,11 @@
mixins: [mixinDevice], mixins: [mixinDevice],
data(){ data(){
return{ return{
//菜单搜索 // update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
search:[], searchMenuOptions:[],
shows:false searchMenuComp: 'span',
searchMenuVisible: false,
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
} }
}, },
components: { components: {
@ -116,10 +123,8 @@
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
created() { created() {
let lists = [] let lists = []
console.log("permissionMenuList: ",this.permissionMenuList)
this.searchMenus(lists,this.permissionMenuList) this.searchMenus(lists,this.permissionMenuList)
this.search=[...lists] this.searchMenuOptions=[...lists]
console.log(this.search)
}, },
computed: { computed: {
...mapState({ ...mapState({
@ -129,10 +134,21 @@
}) })
}, },
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ /* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
watch: {
// update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
device: {
immediate: true,
handler() {
this.searchMenuVisible = false
this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span'
},
},
// update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
},
methods: { methods: {
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
showClick(){ showClick() {
this.shows = !this.shows this.searchMenuVisible = true
}, },
hiddenClick(){ hiddenClick(){
this.shows = false this.shows = false
@ -141,8 +157,8 @@
...mapActions(["Logout"]), ...mapActions(["Logout"]),
...mapGetters(["nickname", "avatar","userInfo"]), ...mapGetters(["nickname", "avatar","userInfo"]),
getAvatar(){ getAvatar(){
console.log('url = '+ window._CONFIG['imgDomainURL']+"/"+this.avatar()) console.log('url = '+ window._CONFIG['staticDomainURL']+"/"+this.avatar())
return window._CONFIG['imgDomainURL']+"/"+this.avatar() return window._CONFIG['staticDomainURL']+"/"+this.avatar()
}, },
handleLogout() { handleLogout() {
const that = this const that = this
@ -189,10 +205,17 @@
filterOption(input, option) { filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0 return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}, },
searchMethods(value){ // update_begin author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
let jump = this.search.filter(item=>item.id==value) searchMethods(value) {
this.$router.push({ path:jump[0].path}) let route = this.searchMenuOptions.filter(item => item.id === value)[0]
if (route.meta.internalOrExternal === true || route.component.includes('layouts/IframePageView')) {
window.open(route.meta.url, '_blank')
} else {
this.$router.push({ path: route.path })
}
this.searchMenuVisible = false
} }
// update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
/*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ /*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
} }
} }
@ -203,7 +226,7 @@
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ /* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
.user-wrapper .search-input { .user-wrapper .search-input {
width: 180px; width: 180px;
color: white; color: inherit;
/deep/ { /deep/ {
.ant-select-selection { .ant-select-selection {

View File

@ -18,8 +18,8 @@ import VueApexCharts from 'vue-apexcharts'
import preview from 'vue-photo-preview' import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css' import 'vue-photo-preview/dist/skin.css'
import "@jeecg/antd-online-re" import "@jeecg/antd-online-214"
import '@jeecg/antd-online-re/dist/OnlineForm.css' import '@jeecg/antd-online-214/dist/OnlineForm.css'
import { import {
ACCESS_TOKEN, ACCESS_TOKEN,

View File

@ -236,9 +236,9 @@ export const JeecgListMixin = {
return return
} }
if (typeof window.navigator.msSaveBlob !== 'undefined') { if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName+'.xls') window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
}else{ }else{
let url = window.URL.createObjectURL(new Blob([data])) let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
let link = document.createElement('a') let link = document.createElement('a')
link.style.display = 'none' link.style.display = 'none'
link.href = url link.href = url
@ -286,7 +286,7 @@ export const JeecgListMixin = {
if(text && text.indexOf(",")>0){ if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
return window._CONFIG['imgDomainURL']+"/"+text return window._CONFIG['staticDomainURL']+"/"+text
}, },
/* 文件下载 */ /* 文件下载 */
uploadFile(text){ uploadFile(text){
@ -297,7 +297,7 @@ export const JeecgListMixin = {
if(text.indexOf(",")>0){ if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
window.open(window._CONFIG['domianURL'] + "/sys/common/download/"+text); window.open(window._CONFIG['staticDomainURL']+ "/"+text);
}, },
} }

View File

@ -0,0 +1,78 @@
export const HrefJump = {
data() {
return {
fieldHrefSlots: [],
hrefComponent: {
model: {
title: '',
width: '100%',
visible: false,
destroyOnClose: true,
style: {
top: 0,
left: 0,
height: '100%',
margin: 0,
padding: 0
},
bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' },
// 隐藏掉取消按钮
cancelButtonProps: { style: { display: 'none' } },
afterClose: () => {
// 恢复body的滚动
document.body.style.overflow = null
}
},
on: {
ok: () => this.hrefComponent.model.visible = false,
cancel: () => this.hrefComponent.model.visible = false
},
is: null,
params: {},
}
}
},
methods: {
//支持链接href跳转
handleClickFieldHref(field, record) {
let href = field.href
let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?/
let compPattern = /\.vue(\?.*)?$/
if (typeof href === 'string') {
href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2])
if (urlPattern.test(href)) {
window.open(href, '_blank')
} else if (compPattern.test(href)) {
this.openHrefCompModal(href)
} else {
this.$router.push(href)
}
}
},
openHrefCompModal(href) {
// 解析 href 参数
let index = href.indexOf('?')
let path = href
if (index !== -1) {
path = href.substring(0, index)
let paramString = href.substring(index + 1, href.length)
let paramArray = paramString.split('&')
let params = {}
paramArray.forEach(paramObject => {
let paramItem = paramObject.split('=')
params[paramItem[0]] = paramItem[1]
})
this.hrefComponent.params = params
} else {
this.hrefComponent.params = {}
}
this.hrefComponent.model.visible = true
this.hrefComponent.model.title = '@/views/' + path
this.hrefComponent.is = () => import('@/views/' + (path.startsWith('/')?path.slice(1):path))
// 禁止body滚动防止滚动穿透
setTimeout(() => {
document.body.style.overflow = 'hidden'
}, 300)
},
}
}

View File

@ -120,6 +120,19 @@ const user = {
sessionStorage.setItem(USER_AUTH,JSON.stringify(authData)); sessionStorage.setItem(USER_AUTH,JSON.stringify(authData));
sessionStorage.setItem(SYS_BUTTON_AUTH,JSON.stringify(allAuthData)); sessionStorage.setItem(SYS_BUTTON_AUTH,JSON.stringify(allAuthData));
if (menuData && menuData.length > 0) { if (menuData && menuData.length > 0) {
//update--begin--autor:qinfeng-----date:20200109------forJEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------
menuData.forEach((item, index) => {
if (item["children"]) {
let hasChildrenMenu = item["children"].filter((i) => {
return !i.hidden || i.hidden == false
})
if (hasChildrenMenu == null || hasChildrenMenu.length == 0) {
item["hidden"] = true
}
}
})
console.log(" menu show json ", menuData)
//update--end--autor:qinfeng-----date:20200109------forJEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------
commit('SET_PERMISSIONLIST', menuData) commit('SET_PERMISSIONLIST', menuData)
} else { } else {
reject('getPermissionList: permissions must be a non-null array !') reject('getPermissionList: permissions must be a non-null array !')

View File

@ -1,4 +1,3 @@
import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types" import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
export function disabledAuthFilter(code,formData) { export function disabledAuthFilter(code,formData) {
@ -10,27 +9,30 @@ export function disabledAuthFilter(code,formData) {
} }
function nodeDisabledAuth(code,formData){ function nodeDisabledAuth(code,formData){
console.log("页面权限禁用--NODE--开始"); let permissionList = [];
var permissionList = [];
try { try {
var obj = formData;
//console.log("页面权限禁用--NODE--开始",obj); //console.log("页面权限禁用--NODE--开始",obj);
if (obj) { if (formData) {
let bpmList = obj.permissionList; let bpmList = formData.permissionList;
for (var bpm of bpmList) { permissionList = bpmList.filter(item=>item.type=='2')
if(bpm.type == '2') { // for (let bpm of bpmList) {
permissionList.push(bpm); // if(bpm.type == '2') {
} // permissionList.push(bpm);
} // }
// }
}else{
return false;
} }
} catch (e) { } catch (e) {
//console.log("页面权限异常----", e); //console.log("页面权限异常----", e);
} }
if (permissionList === null || permissionList === "" || permissionList === undefined||permissionList.length<=0) { if (permissionList.length == 0) {
return false; return false;
} }
console.log("流程节点页面权限禁用--NODE--开始");
let permissions = []; let permissions = [];
for (var item of permissionList) { for (let item of permissionList) {
if(item.type == '2') { if(item.type == '2') {
permissions.push(item.action); permissions.push(item.action);
} }
@ -39,9 +41,9 @@ function nodeDisabledAuth(code,formData){
if (!permissions.includes(code)) { if (!permissions.includes(code)) {
return false; return false;
}else{ }else{
for (var item2 of permissionList) { for (let item2 of permissionList) {
if(code === item2.action){ if(code === item2.action){
console.log("页面权限禁用--NODE--生效"); console.log("流程节点页面权限禁用--NODE--生效");
return true; return true;
} }
} }
@ -50,21 +52,21 @@ function nodeDisabledAuth(code,formData){
} }
function globalDisabledAuth(code){ function globalDisabledAuth(code){
console.log("页面禁用权限--Global--开始"); //console.log("全局页面禁用权限--Global--开始");
var permissionList = []; var permissionList = [];
var allPermissionList = []; var allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH); //let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
for (var auth of authList) { for (let auth of authList) {
if(auth.type == '2') { if(auth.type == '2') {
permissionList.push(auth); permissionList.push(auth);
} }
} }
//console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH)); //console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]"); let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
for (var gauth of allAuthList) { for (let gauth of allAuthList) {
if(gauth.type == '2') { if(gauth.type == '2') {
allPermissionList.push(gauth); allPermissionList.push(gauth);
} }
@ -73,7 +75,7 @@ function globalDisabledAuth(code){
var gFlag = false;//禁用命中 var gFlag = false;//禁用命中
var invalidFlag = false;//无效命中 var invalidFlag = false;//无效命中
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){ if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
for (var itemG of allPermissionList) { for (let itemG of allPermissionList) {
if(code === itemG.action){ if(code === itemG.action){
if(itemG.status == '0'){ if(itemG.status == '0'){
invalidFlag = true; invalidFlag = true;
@ -92,7 +94,7 @@ function globalDisabledAuth(code){
return gFlag; return gFlag;
} }
let permissions = []; let permissions = [];
for (var item of permissionList) { for (let item of permissionList) {
if(item.type == '2') { if(item.type == '2') {
permissions.push(item.action); permissions.push(item.action);
} }
@ -101,9 +103,9 @@ function globalDisabledAuth(code){
if (!permissions.includes(code)) { if (!permissions.includes(code)) {
return gFlag; return gFlag;
}else{ }else{
for (var item2 of permissionList) { for (let item2 of permissionList) {
if(code === item2.action){ if(code === item2.action){
console.log("页面权限解除禁用--Global--生效"); console.log("全局页面权限解除禁用--Global--生效");
gFlag = false; gFlag = false;
} }
} }
@ -134,12 +136,12 @@ function hasColoum(item,authList){
//权限无效时不做控制,有效时控制,只能控制 显示不显示 //权限无效时不做控制,有效时控制,只能控制 显示不显示
//根据授权码前缀获取未授权的列信息 //根据授权码前缀获取未授权的列信息
function getNoAuthCols(pre){ function getNoAuthCols(pre){
var permissionList = []; let permissionList = [];
var allPermissionList = []; let allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH); //let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
for (var auth of authList) { for (let auth of authList) {
//显示策略,有效状态 //显示策略,有效状态
if(auth.type == '1'&&startWith(auth.action,pre)) { if(auth.type == '1'&&startWith(auth.action,pre)) {
permissionList.push(substrPre(auth.action,pre)); permissionList.push(substrPre(auth.action,pre));
@ -147,7 +149,7 @@ function getNoAuthCols(pre){
} }
//console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH)); //console.log("页面禁用权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]"); let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
for (var gauth of allAuthList) { for (let gauth of allAuthList) {
//显示策略,有效状态 //显示策略,有效状态
if(gauth.type == '1'&&gauth.status == '1'&&startWith(gauth.action,pre)) { if(gauth.type == '1'&&gauth.status == '1'&&startWith(gauth.action,pre)) {
allPermissionList.push(substrPre(gauth.action,pre)); allPermissionList.push(substrPre(gauth.action,pre));

View File

@ -38,7 +38,7 @@ const getUploadFileList=(paths)=>{
uid:uidGenerator(), uid:uidGenerator(),
name:getFileName(arr[a]), name:getFileName(arr[a]),
status: 'done', status: 'done',
url: window._CONFIG['domianURL']+"/sys/common/view/"+arr[a], url: window._CONFIG['staticDomainURL']+"/"+arr[a],
response:{ response:{
status:"history", status:"history",
message:arr[a] message:arr[a]

View File

@ -2,35 +2,37 @@ 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("页面权限控制----"); //console.log("页面权限控制----");
console.time()
//节点权限处理,如果命中则不进行全局权限处理 //节点权限处理,如果命中则不进行全局权限处理
if(!filterNodePermission(el, binding, vnode)){ if(!filterNodePermission(el, binding, vnode)){
filterGlobalPermission(el, binding, vnode); filterGlobalPermission(el, binding, vnode);
} }
console.timeEnd() //计时结束并输出时长
} }
}); });
} }
}; };
/** /**
* *
*/ */
export function filterNodePermission(el, binding, vnode) { export function filterNodePermission(el, binding, vnode) {
console.log("页面权限--NODE--"); let permissionList = [];
var permissionList = [];
try { try {
var obj = vnode.context.$props.formData; let obj = vnode.context.$props.formData;
if (obj) { if (obj) {
let bpmList = obj.permissionList; let bpmList = obj.permissionList;
for (var bpm of bpmList) { for (let bpm of bpmList) {
if(bpm.type != '2') { if(bpm.type != '2') {
permissionList.push(bpm); permissionList.push(bpm);
} }
} }
}else{
return false;
} }
} catch (e) { } catch (e) {
//console.log("页面权限异常----", e); //console.log("页面权限异常----", e);
@ -39,8 +41,10 @@ export function filterNodePermission(el, binding, vnode) {
//el.parentNode.removeChild(el) //el.parentNode.removeChild(el)
return false; return false;
} }
console.log("流程节点页面权限--NODE--");
let permissions = []; let permissions = [];
for (var item of permissionList) { for (let item of permissionList) {
if(item.type != '2') { if(item.type != '2') {
permissions.push(item.action); permissions.push(item.action);
} }
@ -51,7 +55,7 @@ export function filterNodePermission(el, binding, vnode) {
//el.parentNode.removeChild(el) //el.parentNode.removeChild(el)
return false; return false;
}else{ }else{
for (var item2 of permissionList) { for (let item2 of permissionList) {
if(binding.value === item2.action){ if(binding.value === item2.action){
return true; return true;
} }
@ -64,29 +68,29 @@ export function filterNodePermission(el, binding, vnode) {
* *
*/ */
export function filterGlobalPermission(el, binding, vnode) { export function filterGlobalPermission(el, binding, vnode) {
console.log("页面权限--Global--"); console.log("全局页面权限--Global--");
var permissionList = []; let permissionList = [];
var allPermissionList = []; let allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH); //let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
for (var auth of authList) { for (let auth of authList) {
if(auth.type != '2') { if(auth.type != '2') {
permissionList.push(auth); permissionList.push(auth);
} }
} }
//console.log("页面权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH)); //console.log("页面权限--Global--",sessionStorage.getItem(SYS_BUTTON_AUTH));
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]"); let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
for (var gauth of allAuthList) { for (let gauth of allAuthList) {
if(gauth.type != '2') { if(gauth.type != '2') {
allPermissionList.push(gauth); allPermissionList.push(gauth);
} }
} }
//设置全局配置是否有命中 //设置全局配置是否有命中
var invalidFlag = false;//无效命中 let invalidFlag = false;//无效命中
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){ if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
for (var itemG of allPermissionList) { for (let itemG of allPermissionList) {
if(binding.value === itemG.action){ if(binding.value === itemG.action){
if(itemG.status == '0'){ if(itemG.status == '0'){
invalidFlag = true; invalidFlag = true;
@ -103,7 +107,7 @@ export function filterGlobalPermission(el, binding, vnode) {
return; return;
} }
let permissions = []; let permissions = [];
for (var item of permissionList) { for (let item of permissionList) {
if(item.type != '2'){ if(item.type != '2'){
permissions.push(item.action); permissions.push(item.action);
} }

View File

@ -5,9 +5,16 @@ import { VueAxios } from './axios'
import {Modal, notification} from 'ant-design-vue' import {Modal, notification} from 'ant-design-vue'
import { ACCESS_TOKEN } from "@/store/mutation-types" import { ACCESS_TOKEN } from "@/store/mutation-types"
//自动设置后台服务 baseURL (也可以手工指定写死项目名字)
let baseDomain = window._CONFIG['domianURL'];
let baseProject = baseDomain.substring(baseDomain.lastIndexOf("/"));
console.log("baseDomain= ",baseDomain)
console.log("baseProject= ",baseProject)
// 创建 axios 实例 // 创建 axios 实例
const service = axios.create({ const service = axios.create({
baseURL: '/jeecg-boot', // api base_url //baseURL: '/jeecg-boot',
baseURL: baseProject, // api base_url
timeout: 9000 // 请求超时时间 timeout: 9000 // 请求超时时间
}) })

View File

@ -257,6 +257,62 @@ export function cssExpand(css, id) {
document.head.appendChild(style) document.head.appendChild(style)
} }
/** 用于js增强事件运行JS代码可以传参 */
// options 所需参数:
// 参数名 类型 说明
// vm VueComponent vue实例
// event Object event对象
// jsCode String 待执行的js代码
// errorMessage String 执行出错后的提示(控制台)
export function jsExpand(options = {}) {
// 绑定到window上的keyName
let windowKeyName = 'J_CLICK_EVENT_OPTIONS'
if (typeof window[windowKeyName] != 'object') {
window[windowKeyName] = {}
}
// 随机生成JS增强的执行id防止冲突
let id = randomString(16, 'qwertyuioplkjhgfdsazxcvbnm'.toUpperCase())
// 封装按钮点击事件
let code = `
(function (o_${id}) {
try {
(function (globalEvent, vm) {
${options.jsCode}
})(o_${id}.event, o_${id}.vm)
} catch (e) {
o_${id}.error(e)
}
o_${id}.done()
})(window['${windowKeyName}']['EVENT_${id}'])
`
// 创建script标签
const script = document.createElement('script')
// 将需要传递的参数挂载到window对象上
window[windowKeyName]['EVENT_' + id] = {
vm: options.vm,
event: options.event,
// 当执行完成时,无论如何都会调用的回调事件
done() {
// 执行完后删除新增的 script 标签不会撤销执行结果(已产生的结果不会被撤销)
script.outerHTML = ''
delete window[windowKeyName]['EVENT_' + id]
},
// 当js运行出错的时候调用的事件
error(e) {
console.group(`${options.errorMessage || 'JS'}${new Date()}`)
console.error(e)
console.groupEnd()
}
}
// 将事件挂载到document中
script.innerHTML = code
document.body.appendChild(script)
}
/** /**
* *
* *
@ -270,12 +326,39 @@ export function cssExpand(css, id) {
* @param callback * @param callback
*/ */
export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) { export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) {
let params = { tableName, fieldName, fieldVal, dataId } if (fieldVal) {
api.duplicateCheck(params).then(res => { let params = { tableName, fieldName, fieldVal, dataId }
res['success'] ? callback() : callback(res['message']) api.duplicateCheck(params).then(res => {
}).catch(err => { res['success'] ? callback() : callback(res['message'])
callback(err.message || err) }).catch(err => {
}) callback(err.message || err)
})
} else {
callback()
}
}
/**
* code
*
* 使
* { validator: (rule, value, callback) => validateCheckRule('common', value, callback) }
*
* @param ruleCode code
* @param value
* @param callback
*/
export function validateCheckRule(ruleCode, value, callback) {
if (ruleCode && value) {
value = encodeURIComponent(value)
api.checkRuleByCode({ ruleCode, value }).then(res => {
res['success'] ? callback() : callback(res['message'])
}).catch(err => {
callback(err.message || err)
})
} else {
callback()
}
} }
/** /**
@ -295,4 +378,40 @@ export function pushIfNotExist(array, value, key) {
} }
array.push(value) array.push(value)
return true return true
}
/**
*
* @type {symbol}
*/
export const succeedSymbol = Symbol()
/**
*
* @type {symbol}
*/
export const failedSymbol = Symbol()
/**
* 使 promise resolvePromisePromise
* Promise.all
*
* @param promise PromisePromise
* @returns {Promise<any>}
*/
export function alwaysResolve(promise) {
return new Promise((resolve, reject) => {
let p = promise
if (typeof promise === 'function') {
p = promise()
}
if (p instanceof Promise) {
p.then(data => {
resolve({ type: succeedSymbol, data })
}).catch(error => {
resolve({ type: failedSymbol, error })
})
} else {
reject('alwaysResolve: PromisePromise')
}
})
} }

View File

@ -133,7 +133,7 @@
methods: { methods: {
...mapGetters(["nickname", "avatar"]), ...mapGetters(["nickname", "avatar"]),
getAvatar(){ getAvatar(){
return window._CONFIG['imgDomainURL']+"/"+this.avatar(); return window._CONFIG['staticDomainURL']+"/"+this.avatar();
}, },
getTeams() { getTeams() {
this.$http.get('/api/workplace/teams') this.$http.get('/api/workplace/teams')

View File

@ -20,14 +20,14 @@
</chart-card> </chart-card>
</a-col> </a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }"> <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="访问量" :total="8846 | NumberFormat"> <chart-card :loading="loading" title="订单量" :total="8846 | NumberFormat">
<a-tooltip title="指标说明" slot="action"> <a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" /> <a-icon type="info-circle-o" />
</a-tooltip> </a-tooltip>
<div> <div>
<mini-area /> <mini-area />
</div> </div>
<template slot="footer">访<span> {{ '1234' | NumberFormat }}</span></template> <template slot="footer"><span> {{ '1234' | NumberFormat }}</span></template>
</chart-card> </chart-card>
</a-col> </a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }"> <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
@ -85,7 +85,7 @@
</a-col> </a-col>
</a-row> </a-row>
</a-tab-pane> </a-tab-pane>
<a-tab-pane tab="访问量" key="2"> <a-tab-pane tab="销售趋势" key="2">
<a-row> <a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24"> <a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额趋势" :dataSource="barData"/> <bar title="销售额趋势" :dataSource="barData"/>
@ -101,10 +101,10 @@
<a-row> <a-row>
<a-col :span="24"> <a-col :span="24">
<a-card :loading="loading" :bordered="false" title="最近一周访问次数统计" :style="{ marginTop: '24px' }"> <a-card :loading="loading" :bordered="false" title="最近一周访问统计" :style="{ marginTop: '24px' }">
<a-row> <a-row>
<a-col :span="6"> <a-col :span="6">
<head-info title="今日访问IP" :content="loginfo.todayIp"></head-info> <head-info title="今日IP" :content="loginfo.todayIp"></head-info>
</a-col> </a-col>
<a-col :span="2"> <a-col :span="2">
<a-spin class='circle-cust'> <a-spin class='circle-cust'>
@ -112,7 +112,7 @@
</a-spin> </a-spin>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<head-info title="今日访问次数" :content="loginfo.todayVisitCount"></head-info> <head-info title="今日访问" :content="loginfo.todayVisitCount"></head-info>
</a-col> </a-col>
<a-col :span="2"> <a-col :span="2">
<a-spin class='circle-cust'> <a-spin class='circle-cust'>
@ -120,7 +120,7 @@
</a-spin> </a-spin>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<head-info title="访问总次数" :content="loginfo.totalVisitCount"></head-info> <head-info title="总访问量" :content="loginfo.totalVisitCount"></head-info>
</a-col> </a-col>
<a-col :span="2"> <a-col :span="2">
<a-spin class='circle-cust'> <a-spin class='circle-cust'>

View File

@ -185,7 +185,7 @@
}, },
created() { created() {
this.user = this.userInfo this.user = this.userInfo
this.avatar = window._CONFIG['imgDomainURL'] +"/"+ this.userInfo.avatar this.avatar = window._CONFIG['staticDomainURL'] +"/"+ this.userInfo.avatar
console.log('this.avatar :'+ this.avatar) console.log('this.avatar :'+ this.avatar)
getRoleList().then(res => { getRoleList().then(res => {

View File

@ -9,7 +9,7 @@
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="12"> <a-col :span="12">
<a-form-item label="性别"> <a-form-item label="性别">
<j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex"/> <j-dict-select-tag v-model="formData.sex" title="性别" dictCode="sex" placeholder="请选择性别"/>
<!-- <j-dict-select-tag title="性别" dictCode="sex" disabled/>--> <!-- <j-dict-select-tag title="性别" dictCode="sex" disabled/>-->
</a-form-item> </a-form-item>
</a-col> </a-col>
@ -176,34 +176,28 @@
<a-row :gutter="24"> <a-row :gutter="24">
<a-col> <a-col>
<a-form-item label="最大化弹窗"> <a-form-item label="JModal弹窗">
<a-button @click="()=>modal.visible=true"></a-button> <a-button style="margin-right: 8px;" @click="()=>modal.visible=true">JModal</a-button>
<span style="margin-right: 8px;"><a-switch v-model="modal.fullscreen"/></span>
<span style="margin-right: 8px;"><a-switch v-model="modal.switchFullscreen"/></span>
<span>Body<a-switch v-model="modal.lockScroll"/></span>
</a-form-item> </a-form-item>
<a-modal <j-modal
:visible="modal.visible" :visible.sync="modal.visible"
:width="modal.width" :width="1200"
:style="modal.style" :title="modal.title"
@ok="()=>modal.visible=false" :lockScroll="modal.lockScroll"
@cancel="()=>modal.visible=false"> :fullscreen.sync="modal.fullscreen"
:switchFullscreen="modal.switchFullscreen"
<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"> <template v-for="(i,k) of 30">
<p :key="k"></p> <p :key="k"></p>
</template> </template>
</a-modal> </j-modal>
</a-col> </a-col>
</a-row> </a-row>
@ -217,10 +211,10 @@
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="12"> <a-col :span="12">
<a-form-item label="树字典"> <a-form-item label="树字典">
<j-tree-dict parentCode="B01" /> <j-tree-dict v-model="formData.treeDict" placeholder="请选择树字典" parentCode="A01" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"></a-col> <a-col :span="12">(v-model){{ formData.treeDict }}</a-col>
</a-row> </a-row>
<a-row :gutter="24"> <a-row :gutter="24">
@ -262,6 +256,45 @@
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="高级查询">
<j-super-query :fieldList="superQuery.fieldList" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="高级查询(自定义按钮)">
<j-super-query :fieldList="superQuery.fieldList">
<!-- -->
<a-button type="primary" ghost icon="clock-circle"></a-button>
</j-super-query>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="图片上传">
<j-image-upload v-model="imgList"></j-image-upload>
</a-form-item>
</a-col>
<a-col :spapn="12">(v-model){{ imgList }}</a-col>
</a-row>
<a-row :gutter="24" style="margin-top: 65px;margin-bottom:50px;">
<a-col :span="12">
<a-form-item label="文件上传">
<j-upload v-model="fileList"></j-upload>
</a-form-item>
</a-col>
<a-col :spapn="12">
(v-model)
<j-ellipsis :value="fileList" :length="30" v-if="fileList.length>0"/>
</a-col>
</a-row>
</a-form> </a-form>
</div> </div>
@ -286,10 +319,15 @@
import JTreeDict from "../../components/jeecg/JTreeDict.vue"; import JTreeDict from "../../components/jeecg/JTreeDict.vue";
import JCron from "@/components/jeecg/JCron.vue"; import JCron from "@/components/jeecg/JCron.vue";
import JTreeSelect from '@/components/jeecg/JTreeSelect' import JTreeSelect from '@/components/jeecg/JTreeSelect'
import JSuperQuery from '@/components/jeecg/JSuperQuery'
import JUpload from '@/components/jeecg/JUpload'
import JImageUpload from '@/components/jeecg/JImageUpload'
export default { export default {
name: 'SelectDemo', name: 'SelectDemo',
components: { components: {
JImageUpload,
JUpload,
JTreeDict, JTreeDict,
JDictSelectTag, JDictSelectTag,
JSelectDepart, JSelectDepart,
@ -299,7 +337,7 @@
JCheckbox, JCheckbox,
JCodeEditor, JCodeEditor,
JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple, JDate, JEditor, JEllipsis, JGraphicCode, JSlider, JSelectMultiple,
JCron, JTreeSelect JCron, JTreeSelect, JSuperQuery
}, },
data() { data() {
return { return {
@ -352,11 +390,20 @@ sayHi('hello, world!')`
modal: { modal: {
title: '', title: '',
visible: false, visible: false,
width: '100%', lockScroll: true,
style: { top: '20px' }, fullscreen: true,
fullScreen: true switchFullscreen: true,
}, },
cron: '', cron: '',
superQuery: {
fieldList: [
{ type: 'input', value: 'name', text: '', },
{ type: 'select', value: 'sex', text: '', dictCode: 'sex' },
{ type: 'number', value: 'age', text: '', }
]
},
fileList:[],
imgList:[],
} }
}, },
computed: { computed: {
@ -399,18 +446,6 @@ sayHi('hello, world!')`
handleJSliderSuccess(value) { handleJSliderSuccess(value) {
this.jslider.value = 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
},
setCorn(data){ setCorn(data){
this.$nextTick(() => { this.$nextTick(() => {
this.form.cronExpression = data; this.form.cronExpression = data;

View File

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

View File

@ -35,12 +35,13 @@
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="sex"> label="性别">
<a-select v-decorator="['sex', {}]" placeholder="请选择性别"> <!-- <a-select v-decorator="['sex', {}]" placeholder="请选择性别">
<a-select-option value=""></a-select-option> <a-select-option value=""></a-select-option>
<a-select-option value="1"></a-select-option> <a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option> <a-select-option value="2"></a-select-option>
</a-select> </a-select>-->
<j-dict-select-tag type="radio" v-decorator="['sex', {}]" :trigger-change="true" dictCode="sex"/>
</a-form-item> </a-form-item>
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"

View File

@ -2,7 +2,7 @@
<a-card :bordered="false"> <a-card :bordered="false">
<a-tabs defaultActiveKey="1" @change="callback"> <a-tabs defaultActiveKey="1" @change="callback">
<a-tab-pane tab="柱状图" key="1"> <a-tab-pane tab="柱状图" key="1">
<a-row :gutter="24"> <a-row>
<a-col :span="10"> <a-col :span="10">
<a-radio-group :value="barType" @change="statisticst"> <a-radio-group :value="barType" @change="statisticst">
<a-radio-button value="year"></a-radio-button> <a-radio-button value="year"></a-radio-button>

View File

@ -43,24 +43,7 @@
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="身份证扫描件" label="身份证扫描件"
hasFeedback> hasFeedback>
<a-upload <j-image-upload text="上传" v-model="fileList" :isMultiple="true"></j-image-upload>
:action="uploadAction"
listType="picture-card"
:headers="headers"
:fileList="fileList"
@change="handleChange"
@preview="handlePreview"
>
<a-button>
<a-icon type="upload"/>
upload
</a-button>
</a-upload>
<a-modal :visible="previewVisible" :footer="null" @cancel="handlePicCancel">
<img alt="example" style="width: 100%" :src="previewImage"/>
</a-modal>
<br/>
</a-form-item> </a-form-item>
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
@ -88,11 +71,11 @@
import pick from 'lodash.pick' import pick from 'lodash.pick'
import Vue from 'vue' import Vue from 'vue'
import {ACCESS_TOKEN} from "@/store/mutation-types" import {ACCESS_TOKEN} from "@/store/mutation-types"
import JImageUpload from '../../../../components/jeecg/JImageUpload'
import { getUploadFileList,getFilePaths } from '@/utils/commonUploadFile.js'
export default { export default {
name: "JeecgOrderCustomerModal", name: "JeecgOrderCustomerModal",
components: { JImageUpload },
data() { data() {
return { return {
title: "操作", title: "操作",
@ -177,7 +160,7 @@
add: "/test/order/addCustomer", add: "/test/order/addCustomer",
edit: "/test/order/editCustomer", edit: "/test/order/editCustomer",
fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload", fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload",
imgerver: window._CONFIG['domianURL'] + "/sys/common/view", imgerver: window._CONFIG['staticDomainURL'],
getOrderCustomerList: "/test/order/listOrderCustomerByMainId", getOrderCustomerList: "/test/order/listOrderCustomerByMainId",
}, },
validatorRules: { validatorRules: {
@ -222,8 +205,6 @@
this.form.resetFields(); this.form.resetFields();
this.orderId = record.orderId; this.orderId = record.orderId;
let currFileList = getUploadFileList(record.idcardPic)
this.fileList = [...currFileList]
this.model = Object.assign({}, record); this.model = Object.assign({}, record);
if (record.id) { if (record.id) {
this.hiding = false; this.hiding = false;
@ -232,6 +213,9 @@
this.$nextTick(() => { this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'id', 'name', 'sex', 'idcard','telphone', 'orderId', 'createBy', 'createTime', 'updateBy', 'updateTime')) this.form.setFieldsValue(pick(this.model, 'id', 'name', 'sex', 'idcard','telphone', 'orderId', 'createBy', 'createTime', 'updateBy', 'updateTime'))
}); });
setTimeout(() => {
this.fileList = record.idcardPic
}, 5)
} else { } else {
this.addStatus = false; this.addStatus = false;
this.editStatus = true; this.editStatus = true;
@ -262,7 +246,7 @@
let formData = Object.assign(this.model, values); let formData = Object.assign(this.model, values);
console.log(formData); console.log(formData);
formData.orderId = this.orderId; formData.orderId = this.orderId;
formData.idcardPic = getFilePaths(this.fileList) formData.idcardPic = this.fileList;
httpAction(httpurl, formData, method).then((res) => { httpAction(httpurl, formData, method).then((res) => {
if (res.success) { if (res.success) {
that.$message.success(res.message); that.$message.success(res.message);

View File

@ -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="24"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="表名"> <a-form-item label="表名">
<a-input placeholder="请输入表名" v-model="queryParam.tableName"></a-input> <a-input placeholder="请输入表名" v-model="queryParam.tableName"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :md="6" :sm="24"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> <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="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button> <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
@ -25,10 +25,10 @@
<!-- --> <!-- -->
<div class="table-operator"> <div class="table-operator">
<a-button @click="doCgformButton" type="primary" icon="highlight" style="margin-left:8px"></a-button> <a-button @click="doCgformButton" type="primary" icon="highlight"></a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS</a-button> <a-button @click="doEnhanceJs" type="primary" icon="strikethrough">JS</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter" style="margin-left:8px">SQL</a-button> <a-button @click="doEnhanceSql" type="primary" icon="filter">SQL</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java</a-button> <a-button @click="doEnhanceJava" type="primary" icon="tool">Java</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0"> <a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay"> <a-menu slot="overlay">
@ -37,7 +37,7 @@
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
<a-button style="margin-left: 8px"> <a-button>
<a-icon type="down"/> <a-icon type="down"/>
</a-button> </a-button>
</a-dropdown> </a-dropdown>
@ -348,6 +348,9 @@
} }
} }
</script> </script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style lang="less"> <style lang="less">
.ant-card-body .table-operator { .ant-card-body .table-operator {
margin-bottom: 18px; margin-bottom: 18px;

View File

@ -6,18 +6,22 @@
<a-form layout="inline"> <a-form layout="inline">
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :md="6" :sm="24"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="表名"> <a-form-item label="表名">
<a-input placeholder="请输入表名" v-model="queryParam.tableName"></a-input> <a-input placeholder="请输入表名" v-model="queryParam.tableName"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :md="6" :sm="24"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="表类型"> <a-form-item label="表类型">
<j-dict-select-tag dictCode="cgform_table_type" v-model="queryParam.tableType"/> <j-dict-select-tag dictCode="cgform_table_type" v-model="queryParam.tableType"/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-col :md="6" :sm="24"> <a-form-item label="表描述">
<a-input placeholder="请输入表描述" v-model="queryParam.tableTxt"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> <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="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button> <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
@ -31,12 +35,12 @@
<!-- --> <!-- -->
<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 @click="doCgformButton" type="primary" icon="highlight" style="margin-left:8px"></a-button> <a-button @click="doCgformButton" type="primary" icon="highlight"></a-button>
<a-button @click="doEnhanceJs" type="primary" icon="strikethrough" style="margin-left:8px">JS</a-button> <a-button @click="doEnhanceJs" type="primary" icon="strikethrough">JS</a-button>
<a-button @click="doEnhanceSql" type="primary" icon="filter" v-has="'online:sql'" style="margin-left:8px">SQL</a-button> <a-button @click="doEnhanceSql" type="primary" icon="filter">SQL</a-button>
<a-button @click="doEnhanceJava" type="primary" icon="tool" style="margin-left:8px">Java</a-button> <a-button @click="doEnhanceJava" type="primary" icon="tool">Java</a-button>
<a-button @click="importOnlineForm" type="primary" icon="database" style="margin-left:8px"></a-button> <a-button @click="importOnlineForm" type="primary" icon="database"></a-button>
<a-button @click="goGenerateCode" v-has="'online:goGenerateCode'" type="primary" icon="database" style="margin-left:8px"></a-button> <a-button @click="goGenerateCode" type="primary" icon="database"></a-button>
<a-dropdown v-if="selectedRowKeys.length > 0"> <a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay"> <a-menu slot="overlay">
@ -45,7 +49,7 @@
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
<a-button style="margin-left: 8px"> <a-button>
<a-icon type="down"/> <a-icon type="down"/>
</a-button> </a-button>
</a-dropdown> </a-dropdown>
@ -204,8 +208,12 @@
title: '', title: '',
align: 'center', align: 'center',
dataIndex: 'tableType', dataIndex: 'tableType',
customRender: (text) => { customRender: (text, record) => {
return filterDictText(this.tableTypeDictOptions, `${text}`) let tbTypeText = filterDictText(this.tableTypeDictOptions, `${text}`)
if(record.isTree === 'Y'){
tbTypeText+='()'
}
return tbTypeText;
} }
}, },
{ {
@ -316,10 +324,14 @@
this.syncFormId = id this.syncFormId = id
}, },
goPageOnline(rd) { goPageOnline(rd) {
if(rd.isTree=='Y'){ if(rd.themeTemplate === 'erp'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id }) this.$router.push({ path: '/online/cgformErpList/' + rd.id })
}else{ }else{
this.$router.push({ path: '/online/cgformList/' + rd.id }) if(rd.isTree=='Y'){
this.$router.push({ path: '/online/cgformTreeList/' + rd.id })
}else{
this.$router.push({ path: '/online/cgformList/' + rd.id })
}
} }
}, },
handleOnlineUrlClose() { handleOnlineUrlClose() {
@ -438,6 +450,9 @@
} }
} }
</script> </script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style lang="less"> <style lang="less">
.ant-card-body .table-operator { .ant-card-body .table-operator {
margin-bottom: 18px; margin-bottom: 18px;

View File

@ -40,16 +40,15 @@
<!-- --> <!-- -->
<div class="table-operator"> <div class="table-operator">
<a-button v-if="buttonSwitch.add" @click="handleAdd" type="primary" icon="plus"></a-button> <a-button v-if="buttonSwitch.add" @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload" style="margin-left:8px"></a-button> <a-button v-if="buttonSwitch.import" @click="handleImportXls" type="primary" icon="upload"></a-button>
<a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download" style="margin-left:8px"></a-button> <a-button v-if="buttonSwitch.export" @click="handleExportXls" type="primary" icon="download"></a-button>
<template v-if="cgButtonList && cgButtonList.length>0" v-for="(item,index) in cgButtonList"> <template v-if="cgButtonList && cgButtonList.length>0" v-for="(item,index) in cgButtonList">
<a-button <a-button
v-if=" item.optType=='js' " v-if=" item.optType=='js' "
:key=" 'cgbtn'+index " :key=" 'cgbtn'+index "
@click="cgButtonJsHandler(item.buttonCode)" @click="cgButtonJsHandler(item.buttonCode)"
type="primary" type="primary"
:icon="item.buttonIcon" :icon="item.buttonIcon">
style="margin-left:8px">
{{ item.buttonName }} {{ item.buttonName }}
</a-button> </a-button>
<a-button <a-button
@ -57,8 +56,7 @@
:key=" 'cgbtn'+index " :key=" 'cgbtn'+index "
@click="cgButtonActionHandler(item.buttonCode)" @click="cgButtonActionHandler(item.buttonCode)"
type="primary" type="primary"
:icon="item.buttonIcon" :icon="item.buttonIcon">
style="margin-left:8px">
{{ item.buttonName }} {{ item.buttonName }}
</a-button> </a-button>
</template> </template>
@ -69,13 +67,11 @@
:fieldList="superQuery.fieldList" :fieldList="superQuery.fieldList"
:saveCode="$route.fullPath" :saveCode="$route.fullPath"
:loading="table.loading" :loading="table.loading"
style="margin-left: 8px;"
@handleSuperQuery="handleSuperQuery"/> @handleSuperQuery="handleSuperQuery"/>
<a-button <a-button
v-if="buttonSwitch.batch_delete" v-if="buttonSwitch.batch_delete"
@click="handleDelBatch" @click="handleDelBatch"
style="margin-left:8px"
v-show="table.selectedRowKeys.length > 0" v-show="table.selectedRowKeys.length > 0"
ghost ghost
type="primary" type="primary"
@ -103,6 +99,16 @@
:scroll="table.scroll" :scroll="table.scroll"
style="min-height: 300px"> style="min-height: 300px">
<!-- href -->
<template
v-for="field of fieldHrefSlots"
:slot="field.slotName"
slot-scope="text, record"
>
<a @click="handleClickFieldHref(field,record)">{{ text }}</a>
</template>
<template slot="dateSlot" slot-scope="text"> <template slot="dateSlot" slot-scope="text">
<span>{{ getFormatDate(text) }}</span> <span>{{ getFormatDate(text) }}</span>
</template> </template>
@ -149,23 +155,17 @@
<a-icon type="down" /> <a-icon type="down" />
</a> </a>
<a-menu slot="overlay"> <a-menu slot="overlay">
<a-menu-item > <a-menu-item v-if="buttonSwitch.detail">
<a href="javascript:;" @click="handleDetail(record)"></a> <a href="javascript:;" @click="handleDetail(record)"></a>
</a-menu-item> </a-menu-item>
<template v-if="hasBpmStatus"> <template v-if="hasBpmStatus">
<template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null"> <template v-if="record.bpm_status == '1'||record.bpm_status == ''|| record.bpm_status == null">
<a-menu-item>
<a href="javascript:;" @click="startProcess(record)"></a>
</a-menu-item>
<a-menu-item v-if="buttonSwitch.delete"> <a-menu-item v-if="buttonSwitch.delete">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)"> <a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a></a> <a></a>
</a-popconfirm> </a-popconfirm>
</a-menu-item> </a-menu-item>
</template> </template>
<template v-else>
<a-menu-item @click="handlePreviewPic(record)"></a-menu-item>
</template>
</template> </template>
<template v-else> <template v-else>
<a-menu-item v-if="buttonSwitch.delete"> <a-menu-item v-if="buttonSwitch.delete">
@ -175,7 +175,7 @@
</a-menu-item> </a-menu-item>
</template> </template>
<template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList"> <template v-if="cgButtonLinkList && cgButtonLinkList.length>0" v-for="(btnItem,btnIndex) in cgButtonLinkList">
<a-menu-item :key=" 'cgbtnLink'+btnIndex "> <a-menu-item :key=" 'cgbtnLink'+btnIndex " v-if="showLinkButton(btnItem,record)">
<a href="javascript:void(0);" @click="cgButtonLinkHandler(record,btnItem.buttonCode,btnItem.optType)"> <a href="javascript:void(0);" @click="cgButtonLinkHandler(record,btnItem.buttonCode,btnItem.optType)">
<a-icon v-if="btnItem.buttonIcon" :type="btnItem.buttonIcon" /> <a-icon v-if="btnItem.buttonIcon" :type="btnItem.buttonIcon" />
{{ btnItem.buttonName }} {{ btnItem.buttonName }}
@ -192,20 +192,27 @@
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal> <j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
<!-- Href -->
<a-modal v-bind="hrefComponent.model" v-on="hrefComponent.on">
<component :is="hrefComponent.is" v-bind="hrefComponent.params"/>
</a-modal>
</div> </div>
</a-card> </a-card>
</template> </template>
<script> <script>
import { HrefJump } from '@/mixins/OnlAutoListMixin'
import { postAction,getAction,deleteAction,downFile } from '@/api/manage' import { postAction,getAction,deleteAction,downFile } from '@/api/manage'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil' import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { filterObj } from '@/utils/util'; import { cloneObject, filterObj } from '@/utils/util'
import JImportModal from '@/components/jeecg/JImportModal' import JImportModal from '@/components/jeecg/JImportModal'
import JSuperQuery from '@comp/jeecg/JSuperQuery' import JSuperQuery from '@comp/jeecg/JSuperQuery'
export default { export default {
name: 'OnlCgFormAutoList', name: 'OnlCgFormAutoList',
mixins: [HrefJump],
components: { components: {
JSuperQuery, JSuperQuery,
JImportModal, JImportModal,
@ -222,7 +229,6 @@
optPre:"/online/cgform/api/form/", optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/', exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton', buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess",
}, },
flowCodePre:"onl_", flowCodePre:"onl_",
isorter:{ isorter:{
@ -282,7 +288,8 @@
delete:true, delete:true,
batch_delete:true, batch_delete:true,
import:true, import:true,
export:true export:true,
detail:true
}, },
hasBpmStatus:false, hasBpmStatus:false,
checkboxFlag:false, checkboxFlag:false,
@ -304,8 +311,7 @@
this.cgButtonJsHandler('mounted') this.cgButtonJsHandler('mounted')
}, },
watch: { watch: {
'$route.path'(newVal,oldVal) { '$route'() {
console.log('$route.path ',oldVal)
// 刷新参数放到这里去触发,就可以刷新相同界面了 // 刷新参数放到这里去触发,就可以刷新相同界面了
this.initAutoList() this.initAutoList()
} }
@ -343,30 +349,6 @@
this.hasBpmStatus = false; this.hasBpmStatus = false;
} }
}, },
startProcess: function(record){
var that = this;
this.$confirm({
title:"提示",
content:"确认提交流程吗?",
onOk: function(){
var param = {
flowCode:that.flowCodePre+that.currentTableName,
id:record.id,
formUrl:"modules/bpm/task/form/OnlineFormDetail",
formUrlMobile:"modules/bpm/task/form/OnlineFormDetail"
}
postAction(that.url.startProcess,param).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
},
initQueryInfo(){ initQueryInfo(){
getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{ getAction(`${this.url.getQueryInfo}${this.code}`).then((res)=>{
console.log("--onlineList-获取查询条件配置",res); console.log("--onlineList-获取查询条件配置",res);
@ -407,6 +389,7 @@
this.table.pagination = false this.table.pagination = false
} }
this.fieldHrefSlots = res.result.fieldHrefSlots
this.dictOptions = res.result.dictOptions this.dictOptions = res.result.dictOptions
this.formTemplate = res.result.formTemplate this.formTemplate = res.result.formTemplate
this.description = res.result.description this.description = res.result.description
@ -441,6 +424,8 @@
this.hasBpmStatusFilter(); this.hasBpmStatusFilter();
this.loadData(); this.loadData();
this.initQueryInfo(); this.initQueryInfo();
//加载新路由清空checkbox选中
this.table.selectedRowKeys = [];
}else{ }else{
this.$message.warning(res.message) this.$message.warning(res.message)
} }
@ -569,6 +554,10 @@
this.cgButtonLinkHandler(record,"beforeEdit","js") this.cgButtonLinkHandler(record,"beforeEdit","js")
this.$refs.modal.edit(this.formTemplate,record.id); this.$refs.modal.edit(this.formTemplate,record.id);
}, },
showLinkButton(item,record){
let btn = new ButtonExpHandler(item.exp,record);
return btn.show;
},
handleDetail(record){ handleDetail(record){
this.$refs.modal.detail(this.formTemplate,record.id); this.$refs.modal.detail(this.formTemplate,record.id);
}, },
@ -604,7 +593,8 @@
dictCode: field.dictCode, dictCode: field.dictCode,
dictTable: field.dictTable, dictTable: field.dictTable,
dictText: field.dictText, dictText: field.dictText,
options: field.enum || field.options options: field.enum || field.options,
order: field.order,
}) })
} }
let fieldList = [] let fieldList = []
@ -630,6 +620,17 @@
setField(fieldList, field) setField(fieldList, field)
} }
} }
// 冒泡排序
for (let i = 0; i < fieldList.length; i++) {
for (let j = i + 1; j < fieldList.length; j++) {
let temp1 = fieldList[i]
let temp2 = fieldList[j]
if (temp1.order > temp2.order) {
fieldList[i] = temp2
fieldList[j] = temp1
}
}
}
this.superQuery.fieldList = fieldList this.superQuery.fieldList = fieldList
} }
}, },
@ -641,7 +642,7 @@
if(text && text.indexOf(",")>0){ if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
return window._CONFIG['imgDomainURL']+"/"+text return window._CONFIG['staticDomainURL']+"/"+text
}, },
downloadRowFile(text){ downloadRowFile(text){
if(!text){ if(!text){
@ -651,7 +652,7 @@
if(text.indexOf(",")>0){ if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
window.open(window._CONFIG['downloadUrl']+"/"+text);//TODO 下载的方法 window.open(window._CONFIG['staticDomainURL']+"/"+text);//TODO 下载的方法
}, },
handleDelBatch(){ handleDelBatch(){
if(this.table.selectedRowKeys.length<=0){ if(this.table.selectedRowKeys.length<=0){
@ -777,13 +778,15 @@
} }
}, },
initButtonSwitch(hideColumns){ initButtonSwitch(hideColumns){
Object.keys(this.buttonSwitch).forEach(key=>{
this.buttonSwitch[key]=true
})
if(hideColumns && hideColumns.length>0){ if(hideColumns && hideColumns.length>0){
Object.keys(this.buttonSwitch).forEach(key=>{ Object.keys(this.buttonSwitch).forEach(key=>{
if(hideColumns.indexOf(key)>=0){ if(hideColumns.indexOf(key)>=0){
this.buttonSwitch[key]=false this.buttonSwitch[key]=false
} }
}) })
} }
}, },
@ -801,6 +804,9 @@
} }
} }
</script> </script>
<style scoped>
@import '~@assets/less/common.less';
</style>
<style> <style>
.ant-card-body .table-operator{ .ant-card-body .table-operator{
margin-bottom: 18px; margin-bottom: 18px;

View File

@ -98,15 +98,6 @@
<a-menu-item > <a-menu-item >
<a @click="handleDetail(record)"></a> <a @click="handleDetail(record)"></a>
</a-menu-item> </a-menu-item>
<a-menu-item v-if="showSubmitFlowButton(record)">
<a @click="startProcess(record)"></a>
</a-menu-item>
<template v-if="showViewFlowButton(record)">
<a-menu-item @click="handlePreviewPic(record)"></a-menu-item>
</template>
<a-menu-item v-if="showOptButton('delete',record)"> <a-menu-item v-if="showOptButton('delete',record)">
<a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)"> <a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteOne(record)">
<a></a> <a></a>
@ -146,7 +137,7 @@
export default { export default {
name: 'OnlCgformTreeList', name: 'OnlCgformTreeList',
components: { components: {
JImportModal JImportModal,
}, },
data() { data() {
return { return {
@ -183,7 +174,6 @@
optPre:"/online/cgform/api/form/", optPre:"/online/cgform/api/form/",
exportXls:'/online/cgform/api/exportXls/', exportXls:'/online/cgform/api/exportXls/',
buttonAction:'/online/cgform/api/doButton', buttonAction:'/online/cgform/api/doButton',
startProcess: "/process/extActProcess/startMutilProcess"
}, },
isorter:{ isorter:{
column: 'create_time', column: 'create_time',
@ -482,7 +472,7 @@
if(text && text.indexOf(",")>0){ if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
return window._CONFIG['imgDomainURL']+"/"+text return window._CONFIG['staticDomainURL']+"/"+text
}, },
downloadRowFile(text){ downloadRowFile(text){
if(!text){ if(!text){
@ -492,7 +482,7 @@
if(text.indexOf(",")>0){ if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
window.open(window._CONFIG['downloadUrl']+"/"+text); window.open(window._CONFIG['staticDomainURL']+"/"+text);
}, },
/*-------数据格式化-end----------*/ /*-------数据格式化-end----------*/
@ -651,14 +641,6 @@
} }
return true return true
}, },
showSubmitFlowButton(record){
if(this.hasBpmStatus){
if(record.bpm_status ==null || record.bpm_status =='' || record.bpm_status == '1'){
return true
}
}
return false
},
showViewFlowButton(record){ showViewFlowButton(record){
if(this.hasBpmStatus){ if(this.hasBpmStatus){
if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){ if(record.bpm_status !=null && record.bpm_status !='' && record.bpm_status != '1'){
@ -691,6 +673,7 @@
} }
}); });
}, },
} }
} }
</script> </script>

View File

@ -0,0 +1,111 @@
<template>
<a-card :bordered="false" style="height: 100%">
<online-common-list
:ref="'onl_'+mainModel.currentTableName"
:code="code"
:model="mainModel"
@seleted="onSelected">
</online-common-list>
<a-tabs defaultActiveKey="0">
<a-tab-pane v-for="(item,index) in subList" :tab="item.description" :key="index+''" :forceRender="true" >
<online-common-list
:ref="item.currentTableName"
:code="item.code"
:model="item"
:main="selectedRow">
</online-common-list>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
name: 'OnlCgformErpList',
components:{
},
data(){
return {
code:'',
url: {
getColumns: '/online/cgform/api/getErpColumns/',
},
mainModel:{},
subList:[],
mainId:'',
selectedRow:{}
}
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initColumnConfig()
}
},
created() {
this.initColumnConfig();
},
methods:{
getSubIndex(index){
return index+1 + ''
},
getSubRef(item){
let ref = item.currentTableName
console.log("ref string",ref)
return ref;
},
initColumnConfig(){
if(!this.$route.params.code){
return false
}
this.code = this.$route.params.code
getAction(`${this.url.getColumns}${this.code}`).then((res)=>{
console.log("erp表单配置",res)
if(res.success){
this.mainModel = res.result.main
this.subList = res.result.subList
this.$nextTick(()=>{
this.$refs['onl_'+this.mainModel.currentTableName].initListByModel();
if(this.subList && this.subList.length>0){
for(let item of this.subList){
this.$refs[item.currentTableName][0].initListByModel();
}
}
});
}
})
},
onSelected(row){
console.log("onSelected",row)
this.selectedRow = row;
}
}
}
</script>
<style>
.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}
.anty-img-wrap{height:25px;position: relative;}
.anty-img-wrap > img{max-height:100%;}
.ant-modal-cust-warp{height: 100%}
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}
.ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden}
</style>

View File

@ -109,6 +109,7 @@ export function getMasterTableInitialData() {
// table2 // table2
isShowForm: '0', isShowForm: '0',
isShowList: '0', isShowList: '0',
isReadOnly: '1',
fieldShowType: 'text', fieldShowType: 'text',
fieldLength: '120', fieldLength: '120',
queryMode: 'single', queryMode: 'single',

View File

@ -31,7 +31,21 @@
@change="handleChange"> @change="handleChange">
<a-button> <a-button>
<a-icon type="upload"/> <a-icon type="upload"/>
OSS
</a-button>
</a-upload>
<a-upload
name="file"
:multiple="false"
:action="minioUploadAction"
:headers="tokenHeader"
:showUploadList="false"
:beforeUpload="beforeUpload"
@change="handleChange">
<a-button>
<a-icon type="upload"/>
MINIO
</a-button> </a-button>
</a-upload> </a-upload>
</div> </div>
@ -58,7 +72,9 @@
@change="handleTableChange"> @change="handleTableChange">
<span slot="action" slot-scope="text, record"> <span slot="action" slot-scope="text, record">
<a @click="ossDelete(record.id)"></a> <a @click="handlePreview(record)"></a>
<a-divider type="vertical"/>
<a @click="ossDelete(record.id)"></a>
</span> </span>
</a-table> </a-table>
@ -108,14 +124,18 @@
url: { url: {
upload: "/oss/file/upload", upload: "/oss/file/upload",
list: "/oss/file/list", list: "/oss/file/list",
delete: "/oss/file/delete" delete: "/oss/file/delete",
minioUpload: "/sys/upload/uploadMinio"
} }
} }
}, },
computed: { computed: {
uploadAction() { uploadAction() {
return window._CONFIG['domianURL'] + this.url.upload; return window._CONFIG['domianURL'] + this.url.upload;
} },
minioUploadAction() {
return window._CONFIG['domianURL'] + this.url.minioUpload;
},
}, },
methods: { methods: {
beforeUpload(file) { beforeUpload(file) {
@ -139,10 +159,10 @@
this.loadData() this.loadData()
this.$message.success(`${info.file.name} !`); this.$message.success(`${info.file.name} !`);
} else { } else {
this.$message.error(`${info.file.name} .`); this.$message.error(`${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.response.message}`);
} }
}, },
ossDelete(id) { ossDelete(id) {
@ -154,11 +174,17 @@
that.handleDelete(id) that.handleDelete(id)
} }
}); });
},
handlePreview(record) {
if (record && record.url) {
let url = window._CONFIG['onlinePreviewDomainURL'] + '?url=' + encodeURIComponent(record.url)
window.open(url, '_blank')
}
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
@import '~@assets/less/common.less' @import '~@assets/less/common.less';
</style> </style>

View File

@ -17,8 +17,7 @@
<div style="background: #fff;padding-left:16px;height: 100%; margin-top: 5px"> <div style="background: #fff;padding-left:16px;height: 100%; margin-top: 5px">
<a-alert type="info" :showIcon="true"> <a-alert type="info" :showIcon="true">
<div slot="message"> <div slot="message">
<span v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</span>
<a v-if="this.currSelected.title">{{ getCurrSelectedTitle() }}</a>
<a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected"></a> <a v-if="this.currSelected.title" style="margin-left: 10px" @click="onClearSelected"></a>
</div> </div>
</a-alert> </a-alert>
@ -72,82 +71,90 @@
<!---- author:os_chengtgen -- date:20190827 -- for: =======------> <!---- author:os_chengtgen -- date:20190827 -- for: =======------>
</a-col> </a-col>
<a-col :md="12" :sm="24"> <a-col :md="12" :sm="24">
<a-card :bordered="false"> <a-tabs defaultActiveKey="1">
<a-form :form="form"> <a-tab-pane tab="基本信息" key="1" >
<a-form-item <a-card :bordered="false">
:labelCol="labelCol" <a-form :form="form">
:wrapperCol="wrapperCol" <a-form-item
label="机构名称"> :labelCol="labelCol"
<a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/> :wrapperCol="wrapperCol"
</a-form-item> label="机构名称">
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门"> <a-input placeholder="请输入机构/部门名称" v-decorator="['departName', validatorRules.departName ]"/>
<a-tree-select </a-form-item>
style="width:100%" <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级部门">
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}" <a-tree-select
:treeData="treeData" style="width:100%"
:disabled="disable" :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
v-model="model.parentId" :treeData="treeData"
placeholder="无"> :disabled="disable"
</a-tree-select> v-model="model.parentId"
</a-form-item> placeholder="无">
<a-form-item </a-tree-select>
:labelCol="labelCol" </a-form-item>
:wrapperCol="wrapperCol" <a-form-item
label="机构编码"> :labelCol="labelCol"
<a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/> :wrapperCol="wrapperCol"
</a-form-item> label="机构编码">
<a-form-item <a-input disabled placeholder="请输入机构编码" v-decorator="['orgCode', validatorRules.orgCode ]"/>
:labelCol="labelCol" </a-form-item>
:wrapperCol="wrapperCol" <a-form-item
label="机构类型"> :labelCol="labelCol"
<template v-if="orgCategoryDisabled"> :wrapperCol="wrapperCol"
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型"> label="机构类型">
<a-radio value="1"> <template v-if="orgCategoryDisabled">
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
</a-radio> <a-radio value="1">
</a-radio-group>
</template> </a-radio>
<template v-else> </a-radio-group>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型"> </template>
<a-radio value="2"> <template v-else>
<a-radio-group v-decorator="['orgCategory',validatorRules.orgCategory]" placeholder="请选择机构类型">
</a-radio> <a-radio value="2">
<a-radio value="3">
</a-radio>
</a-radio> <a-radio value="3">
</a-radio-group>
</template> </a-radio>
</a-form-item> </a-radio-group>
<a-form-item </template>
:labelCol="labelCol" </a-form-item>
:wrapperCol="wrapperCol" <a-form-item
label="排序"> :labelCol="labelCol"
<a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/> :wrapperCol="wrapperCol"
</a-form-item> label="排序">
<a-form-item <a-input-number v-decorator="[ 'departOrder',{'initialValue':0}]"/>
:labelCol="labelCol" </a-form-item>
:wrapperCol="wrapperCol" <a-form-item
label="手机号"> :labelCol="labelCol"
<a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/> :wrapperCol="wrapperCol"
</a-form-item> label="手机号">
<a-form-item <a-input placeholder="请输入手机号" v-decorator="['mobile', {'initialValue':''}]"/>
:labelCol="labelCol" </a-form-item>
:wrapperCol="wrapperCol" <a-form-item
label="地址"> :labelCol="labelCol"
<a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/> :wrapperCol="wrapperCol"
</a-form-item> label="地址">
<a-form-item <a-input placeholder="请输入地址" v-decorator="['address', {'initialValue':''}]"/>
:labelCol="labelCol" </a-form-item>
:wrapperCol="wrapperCol" <a-form-item
label="备注"> :labelCol="labelCol"
<a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/> :wrapperCol="wrapperCol"
</a-form-item> label="备注">
</a-form> <a-textarea placeholder="请输入备注" v-decorator="['memo', {'initialValue':''}]"/>
<div class="anty-form-btn"> </a-form-item>
<a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync"></a-button> </a-form>
<a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form"></a-button> <div class="anty-form-btn">
</div> <a-button @click="emptyCurrForm" type="default" htmlType="button" icon="sync"></a-button>
</a-card> <a-button @click="submitCurrForm" type="primary" htmlType="button" icon="form"></a-button>
</div>
</a-card>
</a-tab-pane>
<a-tab-pane tab="部门权限" key="2" forceRender>
<depart-auth-modal ref="departAuth"/>
</a-tab-pane>
</a-tabs>
</a-col> </a-col>
<depart-modal ref="departModal" @ok="loadTree"></depart-modal> <depart-modal ref="departModal" @ok="loadTree"></depart-modal>
</a-row> </a-row>
@ -158,6 +165,7 @@
import {queryDepartTreeList, searchByKeywords, deleteByDepartId} from '@/api/api' import {queryDepartTreeList, searchByKeywords, deleteByDepartId} from '@/api/api'
import {httpAction, deleteAction} from '@/api/manage' import {httpAction, deleteAction} from '@/api/manage'
import {JeecgListMixin} from '@/mixins/JeecgListMixin' import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import DepartAuthModal from './modules/DepartAuthModal'
// 表头 // 表头
const columns = [ const columns = [
{ {
@ -201,6 +209,7 @@
name: 'DepartList', name: 'DepartList',
mixins: [JeecgListMixin], mixins: [JeecgListMixin],
components: { components: {
DepartAuthModal,
DepartModal DepartModal
}, },
data() { data() {
@ -403,7 +412,7 @@
this.selectedKeys = [record.key] this.selectedKeys = [record.key]
this.model.parentId = record.parentId this.model.parentId = record.parentId
this.setValuesToForm(record) this.setValuesToForm(record)
this.$refs.departAuth.show(record.id);
}, },
// 触发onSelect事件时,为部门树右侧的form表单赋值 // 触发onSelect事件时,为部门树右侧的form表单赋值
@ -425,6 +434,7 @@
this.currSelected = {} this.currSelected = {}
this.form.resetFields() this.form.resetFields()
this.selectedKeys = [] this.selectedKeys = []
this.$refs.departAuth.departId = ''
}, },
handleNodeTypeChange(val) { handleNodeTypeChange(val) {
this.currSelected.nodeType = val this.currSelected.nodeType = val

View File

@ -6,7 +6,7 @@
<a-input-search @search="onSearch" style="width:100%;margin-top: 10px" placeholder="请输入部门名称"/> <a-input-search @search="onSearch" style="width:100%;margin-top: 10px" placeholder="请输入部门名称"/>
<!-- --> <!-- -->
<template> <template v-if="userIdentity === '2' && departTree.length>0">
<!----> <!---->
<a-tree <a-tree
@ -16,10 +16,14 @@
@select="onSelect" @select="onSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}" :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree" :treeData="departTree"
:autoExpandParent="autoExpandParent"
/> />
</template> </template>
<div style="margin-top: 24px;" v-else-if="userIdentity === '2' && departTree.length==0">
<h3><span></span></h3>
</div>
<div style="margin-top: 24px;" v-else><h3></h3></div>
</div> </div>
</a-card> </a-card>
</a-col> </a-col>
@ -30,7 +34,10 @@
<Dept-Base-Info ref="DeptBaseInfo"></Dept-Base-Info> <Dept-Base-Info ref="DeptBaseInfo"></Dept-Base-Info>
</a-tab-pane> </a-tab-pane>
<a-tab-pane tab="用户信息" key="2"> <a-tab-pane tab="用户信息" key="2">
<Dept-User-Info ref="DeptUserInfo"></Dept-User-Info> <Dept-User-Info ref="DeptUserInfo" @clearSelectedDepartKeys="clearSelectedDepartKeys"></Dept-User-Info>
</a-tab-pane>
<a-tab-pane tab="部门角色" key="3" forceRender>
<dept-role-info ref="DeptRoleInfo" @clearSelectedDepartKeys="clearSelectedDepartKeys"/>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-card> </a-card>
@ -40,13 +47,15 @@
<script> <script>
import DeptBaseInfo from './modules/DeptBaseInfo' import DeptBaseInfo from './modules/DeptBaseInfo'
import DeptUserInfo from './modules/DeptUserInfo' import DeptUserInfo from './modules/DeptUserInfo'
import {queryDepartTreeList, searchByKeywords} from '@/api/api' import {queryMyDepartTreeList, searchByKeywords} from '@/api/api'
import {JeecgListMixin} from '@/mixins/JeecgListMixin' import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import DeptRoleInfo from './modules/DeptRoleInfo'
export default { export default {
name: 'DepartUserList', name: 'DepartUserList',
mixins: [JeecgListMixin], mixins: [JeecgListMixin],
components: { components: {
DeptRoleInfo,
DeptBaseInfo, DeptBaseInfo,
DeptUserInfo, DeptUserInfo,
}, },
@ -85,6 +94,7 @@
nodes: [], nodes: [],
edges: [] edges: []
}, },
userIdentity:"",
} }
}, },
methods: { methods: {
@ -94,12 +104,19 @@
loadData() { loadData() {
this.refresh(); this.refresh();
}, },
clearSelectedDepartKeys() {
this.checkedKeys = [];
this.selectedKeys = [];
this.currentDeptId = '';
this.$refs.DeptUserInfo.currentDeptId='';
this.$refs.DeptRoleInfo.currentDeptId='';
},
loadTree() { loadTree() {
var that = this var that = this
that.treeData = [] that.treeData = []
that.departTree = [] that.departTree = []
queryDepartTreeList().then((res) => { queryMyDepartTreeList().then((res) => {
if (res.success) { if (res.success && res.result ) {
for (let i = 0; i < res.result.length; i++) { for (let i = 0; i < res.result.length; i++) {
let temp = res.result[i] let temp = res.result[i]
that.treeData.push(temp) that.treeData.push(temp)
@ -109,6 +126,7 @@
} }
this.loading = false this.loading = false
} }
that.userIdentity = res.message
}) })
}, },
setThisExpandedKeys(node) { setThisExpandedKeys(node) {
@ -161,6 +179,7 @@
this.$refs.DeptBaseInfo.open(record); this.$refs.DeptBaseInfo.open(record);
this.$refs.DeptUserInfo.open(record); this.$refs.DeptUserInfo.open(record);
this.$refs.DeptRoleInfo.open(record);
// } // }
// else { // else {
// this.checkedKeys = []; // this.checkedKeys = [];
@ -180,6 +199,8 @@
this.$refs.DeptBaseInfo.open(record); this.$refs.DeptBaseInfo.open(record);
this.$refs.DeptUserInfo.onClearSelected(); this.$refs.DeptUserInfo.onClearSelected();
this.$refs.DeptUserInfo.open(record); this.$refs.DeptUserInfo.open(record);
this.$refs.DeptRoleInfo.onClearSelected();
this.$refs.DeptRoleInfo.open(record);
}, },
}, },
created() { created() {

View File

@ -30,6 +30,7 @@
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :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-button type="primary" icon="sync" @click="refleshCache()"></a-button>
<a-button type="primary" icon="hdd" @click="openDeleteList"></a-button> <a-button type="primary" icon="hdd" @click="openDeleteList"></a-button>
</div> </div>
@ -70,6 +71,7 @@
import DictModal from './modules/DictModal' import DictModal from './modules/DictModal'
import DictItemList from './DictItemList' import DictItemList from './DictItemList'
import DictDeleteList from './DictDeleteList' import DictDeleteList from './DictDeleteList'
import { getAction } from '@/api/manage'
export default { export default {
name: "DictList", name: "DictList",
@ -132,6 +134,7 @@
delete: "/sys/dict/delete", delete: "/sys/dict/delete",
exportXlsUrl: "sys/dict/exportXls", exportXlsUrl: "sys/dict/exportXls",
importExcelUrl: "sys/dict/importExcel", importExcelUrl: "sys/dict/importExcel",
refleshCache: "sys/dict/refleshCache",
}, },
} }
}, },
@ -165,9 +168,18 @@
that.queryParam.dictCode = ""; that.queryParam.dictCode = "";
that.loadData(this.ipagination.current); that.loadData(this.ipagination.current);
}, },
openDeleteList(){ openDeleteList(){
this.$refs.dictDeleteList.show() this.$refs.dictDeleteList.show()
},
refleshCache(){
getAction(this.url.refleshCache).then((res) => {
if (res.success) {
this.$message.success("刷新缓存完成!");
}
}).catch(e=>{
this.$message.warn("刷新缓存失败!");
console.log("刷新失败",e)
})
} }
}, },
watch: { watch: {

View File

@ -29,7 +29,9 @@
:dataSource="dataSource" :dataSource="dataSource"
:loading="loading" :loading="loading"
@expand="expandSubmenu" @expand="expandSubmenu"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"> :expandedRowKeys="expandedRowKeys"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@expandedRowsChange="handleExpandedRowsChange">
<span slot="action" slot-scope="text, record"> <span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a> <a @click="handleEdit(record)"></a>
@ -79,7 +81,7 @@
<script> <script>
import PermissionModal from './modules/PermissionModal' import PermissionModal from './modules/PermissionModal'
import { getSystemMenuList,getSystemSubmenu } from '@/api/api' import { getSystemMenuList, getSystemSubmenu, getSystemSubmenuBatch } from '@/api/api'
import { JeecgListMixin } from '@/mixins/JeecgListMixin' import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import PermissionDataRuleList from './PermissionDataRuleList' import PermissionDataRuleList from './PermissionDataRuleList'
import JEllipsis from '@/components/jeecg/JEllipsis' import JEllipsis from '@/components/jeecg/JEllipsis'
@ -140,7 +142,7 @@
] ]
export default { export default {
name: 'PermissionList', name: 'PermissionListAsync',
mixins: [JeecgListMixin], mixins: [JeecgListMixin],
components: { components: {
PermissionDataRuleList, PermissionDataRuleList,
@ -153,6 +155,8 @@
// 表头 // 表头
columns: columns, columns: columns,
loading: false, loading: false,
// 展开的行,受控属性
expandedRowKeys: [],
url: { url: {
list: '/sys/permission/list', list: '/sys/permission/list',
delete: '/sys/permission/delete', delete: '/sys/permission/delete',
@ -162,23 +166,45 @@
}, },
methods: { methods: {
loadData() { loadData() {
this.dataSource = [] this.loading = true
getSystemMenuList().then((res) => { getSystemMenuList().then((res) => {
if (res.success) { if (res.success) {
console.log(res.result)
this.dataSource = res.result this.dataSource = res.result
return this.loadDataByExpandedRows(this.dataSource)
} }
}).finally(()=>{
this.loading = false
}) })
}, },
expandSubmenu(expanded, record){ expandSubmenu(expanded, record){
if(expanded){ if (expanded && (!record.children || record.children.length === 0)) {
getSystemSubmenu({parentId:record.id}).then((res) => { getSystemSubmenu({parentId:record.id}).then((res) => {
if (res.success) { if (res.success) {
record.children = res.result record.children = res.result
} }
}) })
} }
},
// 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
loadDataByExpandedRows(dataList) {
if (this.expandedRowKeys.length > 0) {
return getSystemSubmenuBatch({ parentIds: this.expandedRowKeys.join(',') }).then((res) => {
if (res.success) {
let childrenMap = res.result
let fn = (list) => {
list.forEach(data => {
if (this.expandedRowKeys.includes(data.id)) {
data.children = childrenMap[data.id]
fn(data.children)
}
})
}
fn(dataList)
}
})
} else {
return Promise.resolve()
}
}, },
// 打开数据规则编辑 // 打开数据规则编辑
handleDataRule(record) { handleDataRule(record) {
@ -189,10 +215,13 @@
this.$refs.modalForm.localMenuType = 1; this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false; this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id}); this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
} },
handleExpandedRowsChange(expandedRows) {
this.expandedRowKeys = expandedRows
},
} }
} }
</script> </script>
<style scoped> <style scoped>
@import '~@assets/less/common.less' @import '~@assets/less/common.less';
</style> </style>

View File

@ -28,7 +28,9 @@
:pagination="false" :pagination="false"
:dataSource="dataSource" :dataSource="dataSource"
:loading="loading" :loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"> :expandedRowKeys="expandedRowKeys"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@expandedRowsChange="handleExpandedRowsChange">
<span slot="action" slot-scope="text, record"> <span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a> <a @click="handleEdit(record)"></a>
@ -152,6 +154,8 @@
// 表头 // 表头
columns: columns, columns: columns,
loading: false, loading: false,
// 展开的行,受控属性
expandedRowKeys: [],
url: { url: {
list: '/sys/permission/list', list: '/sys/permission/list',
delete: '/sys/permission/delete', delete: '/sys/permission/delete',
@ -178,10 +182,13 @@
this.$refs.modalForm.localMenuType = 1; this.$refs.modalForm.localMenuType = 1;
this.$refs.modalForm.disableSubmit = false; this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id}); this.$refs.modalForm.edit({status:'1',permsType:'1',route:true,'parentId':record.id});
} },
handleExpandedRowsChange(expandedRows) {
this.expandedRowKeys = expandedRows
},
} }
} }
</script> </script>
<style scoped> <style scoped>
@import '~@assets/less/common.less' @import '~@assets/less/common.less';
</style> </style>

View File

@ -67,8 +67,8 @@
<span slot="action" slot-scope="text, record"> <span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a> <a @click="handleEdit(record)"></a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-dropdown> <a-dropdown>
<a class="ant-dropdown-link"> <a class="ant-dropdown-link">
<a-icon type="down" /> <a-icon type="down" />

View File

@ -60,26 +60,27 @@
:rowSelection="{selectedRowKeys: selectedRowKeys1, onChange: onSelectChange1, type:'radio'}" :rowSelection="{selectedRowKeys: selectedRowKeys1, onChange: onSelectChange1, type:'radio'}"
@change="handleTableChange"> @change="handleTableChange">
<span slot="action" slot-scope="text, record"> <span slot="action" slot-scope="text, record">
<a @click="handleOpen(record)"></a> <a @click="handleOpen(record)"></a>
<a-divider type="vertical"/> <a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link"> <a-dropdown>
<a-icon type="down"/> <a class="ant-dropdown-link">
</a> <a-icon type="down"/>
<a-menu slot="overlay"> </a>
<a-menu-item> <a-menu slot="overlay">
<a @click="handlePerssion(record.id)"></a> <a-menu-item>
</a-menu-item> <a @click="handlePerssion(record.id)"></a>
<a-menu-item> </a-menu-item>
<a @click="handleEdit(record)"></a> <a-menu-item>
</a-menu-item> <a @click="handleEdit(record)"></a>
<a-menu-item> </a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)"> <a-menu-item>
<a></a> <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete1(record.id)">
</a-popconfirm> <a></a>
</a-menu-item> </a-popconfirm>
</a-menu> </a-menu-item>
</a-dropdown> </a-menu>
</a-dropdown>
</span> </span>
</a-table> </a-table>
</div> </div>
@ -530,7 +531,7 @@
}, },
handlePerssion(roleId){ handlePerssion(roleId){
this.$refs.modalUserRole.show(roleId); this.$refs.modalUserRole.show(roleId);
} },
} }
} }
</script> </script>

View File

@ -0,0 +1,178 @@
<template>
<a-card :bordered="false">
<!-- -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="规则名称">
<a-input placeholder="请输入规则名称" v-model="queryParam.ruleName"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="规则Code">
<a-input placeholder="请输入规则Code" v-model="queryParam.ruleCode"/>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '' : '' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button type="primary" icon="download" @click="handleExportXls('编码校验规则')"></a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import"></a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table-begin -->
<a-alert type="info" showIcon style="margin-bottom: 16px;">
<template slot="message">
<span></span>
<a style="font-weight: 600;padding: 0 4px;">{{ selectedRowKeys.length }}</a>
<span></span>
<template v-if="selectedRowKeys.length>0">
<a-divider type="vertical"/>
<a @click="onClearSelected"></a>
</template>
</template>
</a-alert>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<template slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a @click="handleTest(record)"></a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
<span></span>
<a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="handleDelete(record.id)"></a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
</a-table>
<!-- table-end -->
<!-- -->
<sys-check-rule-modal ref="modalForm" @ok="modalFormOk"/>
<sys-check-rule-test-modal ref="testModal"/>
</a-card>
</template>
<script>
import JEllipsis from '@/components/jeecg/JEllipsis'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import SysCheckRuleModal from './modules/SysCheckRuleModal'
import SysCheckRuleTestModal from './modules/SysCheckRuleTestModal'
export default {
name: 'SysCheckRuleList',
mixins: [JeecgListMixin],
components: { SysCheckRuleModal, SysCheckRuleTestModal, JEllipsis },
data() {
return {
description: '',
// 表头
columns: [
{
title: '#',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: (t, r, i) => i + 1
},
{
title: '',
align: 'center',
dataIndex: 'ruleName'
},
{
title: 'Code',
align: 'center',
dataIndex: 'ruleCode'
},
{
title: '',
align: 'center',
dataIndex: 'ruleDescription',
customRender: (t) => (<j-ellipsis value={t} length={48}/>)
},
{
title: '',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' },
}
],
url: {
list: '/sys/checkRule/list',
delete: '/sys/checkRule/delete',
deleteBatch: '/sys/checkRule/deleteBatch',
exportXlsUrl: 'sys/checkRule/exportXls',
importExcelUrl: 'sys/checkRule/importExcel',
},
}
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
}
},
methods: {
handleTest(record) {
this.$refs.testModal.open(record.ruleCode)
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

View File

@ -0,0 +1,194 @@
<template>
<a-card :bordered="false">
<!-- -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="数据源名称">
<a-input placeholder="请输入数据源名称" v-model="queryParam.name"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="数据库类型">
<j-dict-select-tag v-model="queryParam.dbType" placeholder="请选择数据库类型" dict-code="database_type"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button type="primary" icon="download" @click="handleExportXls('多数据源管理')"></a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import"></a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table-begin -->
<div>
<a-alert type="info" showIcon style="margin-bottom: 16px;">
<template slot="message">
<span></span>
<a style="font-weight: 600;padding: 0 4px;">{{ selectedRowKeys.length }}</a>
<span></span>
<a style="margin-left: 24px" @click="onClearSelected"></a>
</template>
</a-alert>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link"> <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a></a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table-end -->
<!-- -->
<sys-data-source-modal ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import JEllipsis from '@/components/jeecg/JEllipsis'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import SysDataSourceModal from './modules/SysDataSourceModal'
export default {
name: 'SysDataSourceList',
mixins: [JeecgListMixin],
components: { JEllipsis, SysDataSourceModal },
data() {
let ellipsis = (v, l = 20) => (<j-ellipsis value={v} length={l}/>)
return {
description: '',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: (t, r, index) => index + 1
},
{
title: '',
align: 'center',
dataIndex: 'name'
},
{
title: '',
align: 'center',
dataIndex: 'code'
},
{
title: '',
align: 'center',
dataIndex: 'remark',
customRender: (t) => ellipsis(t)
},
{
title: '',
align: 'center',
dataIndex: 'dbType_dictText'
},
{
title: '',
align: 'center',
dataIndex: 'dbDriver',
customRender: (t) => ellipsis(t)
},
{
title: '',
align: 'center',
dataIndex: 'dbUrl',
customRender: (t) => ellipsis(t)
},
{
title: '',
align: 'center',
dataIndex: 'dbName'
},
{
title: '',
align: 'center',
dataIndex: 'dbUsername'
},
{
title: '',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' },
}
],
url: {
list: '/sys/dataSource/list',
delete: '/sys/dataSource/delete',
deleteBatch: '/sys/dataSource/deleteBatch',
exportXlsUrl: 'sys/dataSource/exportXls',
importExcelUrl: 'sys/dataSource/importExcel',
},
}
},
computed: {
importExcelUrl() {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
}
},
methods: {}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

View File

@ -46,6 +46,7 @@
</span> </span>
</a-table> </a-table>
<show-announcement ref="ShowAnnouncement"></show-announcement> <show-announcement ref="ShowAnnouncement"></show-announcement>
<dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData"/>
</a-card> </a-card>
</template> </template>
@ -54,11 +55,13 @@
import { getAction,putAction } from '@/api/manage' import { getAction,putAction } from '@/api/manage'
import ShowAnnouncement from '@/components/tools/ShowAnnouncement' import ShowAnnouncement from '@/components/tools/ShowAnnouncement'
import {JeecgListMixin} from '@/mixins/JeecgListMixin' import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import DynamicNotice from '../../components/tools/DynamicNotice'
export default { export default {
name: "UserAnnouncementList", name: "UserAnnouncementList",
mixins: [JeecgListMixin], mixins: [JeecgListMixin],
components: { components: {
DynamicNotice,
ShowAnnouncement ShowAnnouncement
}, },
data () { data () {
@ -130,6 +133,7 @@
readAllMsg:"sys/sysAnnouncementSend/readAll", readAllMsg:"sys/sysAnnouncementSend/readAll",
}, },
loading:false, loading:false,
openPath:''
} }
}, },
methods: { methods: {
@ -143,7 +147,13 @@
this.loadData(); this.loadData();
} }
}); });
this.$refs.ShowAnnouncement.detail(record); if(record.openType==='component'){
this.openPath = record.openPage;
this.formData = {id:record.busId};
this.$refs.showDynamNotice.detail();
}else{
this.$refs.ShowAnnouncement.detail(record);
}
}, },
readAll(){ readAll(){
var that = this; var that = this;

View File

@ -66,10 +66,12 @@
<!-- --> <!-- -->
<div class="table-operator" style="border-top: 5px"> <div class="table-operator" style="border-top: 5px">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button> <a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button @click="handleSyncUser" v-has="'user:syncbpm'" 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" :headers="tokenHeader" :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-button type="primary" icon="hdd" @click="recycleBinVisible=true"></a-button>
<a-dropdown v-if="selectedRowKeys.length > 0"> <a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay" @click="handleMenuClick"> <a-menu slot="overlay" @click="handleMenuClick">
<a-menu-item key="1"> <a-menu-item key="1">
@ -171,17 +173,22 @@
<password-modal ref="passwordmodal" @ok="passwordModalOk"></password-modal> <password-modal ref="passwordmodal" @ok="passwordModalOk"></password-modal>
<sys-user-agent-modal ref="sysUserAgentModal"></sys-user-agent-modal> <sys-user-agent-modal ref="sysUserAgentModal"></sys-user-agent-modal>
<!-- -->
<user-recycle-bin-modal :visible.sync="recycleBinVisible" @ok="modalFormOk"/>
</a-card> </a-card>
</template> </template>
<script> <script>
import UserModal from './modules/UserModal' import UserModal from './modules/UserModal'
import PasswordModal from './modules/PasswordModal' import PasswordModal from './modules/PasswordModal'
import {putAction} from '@/api/manage'; import {putAction,getFileAccessHttpUrl} from '@/api/manage';
import {frozenBatch} from '@/api/api' import {frozenBatch} from '@/api/api'
import {JeecgListMixin} from '@/mixins/JeecgListMixin' import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import SysUserAgentModal from "./modules/SysUserAgentModal"; import SysUserAgentModal from "./modules/SysUserAgentModal";
import JInput from '@/components/jeecg/JInput' import JInput from '@/components/jeecg/JInput'
import UserRecycleBinModal from './modules/UserRecycleBinModal'
export default { export default {
name: "UserList", name: "UserList",
@ -190,12 +197,14 @@
SysUserAgentModal, SysUserAgentModal,
UserModal, UserModal,
PasswordModal, PasswordModal,
JInput JInput,
UserRecycleBinModal
}, },
data() { data() {
return { return {
description: '', description: '',
queryParam: {}, queryParam: {},
recycleBinVisible: false,
columns: [ columns: [
/*{ /*{
title: '#', title: '#',
@ -214,7 +223,7 @@
width: 120 width: 120
}, },
{ {
title: '', title: '',
align: "center", align: "center",
width: 100, width: 100,
dataIndex: 'realname', dataIndex: 'realname',
@ -237,7 +246,7 @@
{ {
title: '', title: '',
align: "center", align: "center",
width: 180, width: 100,
dataIndex: 'birthday' dataIndex: 'birthday'
}, },
{ {
@ -247,9 +256,10 @@
dataIndex: 'phone' dataIndex: 'phone'
}, },
{ {
title: '', title: '',
align: "center", align: "center",
dataIndex: 'email' width: 180,
dataIndex: 'orgCode'
}, },
{ {
title: '', title: '',
@ -257,13 +267,6 @@
width: 80, width: 80,
dataIndex: 'status_dictText' dataIndex: 'status_dictText'
}, },
/* {
title: '',
align: "center",
width: 150,
dataIndex: 'createTime',
sorter: true
},*/
{ {
title: '', title: '',
dataIndex: 'action', dataIndex: 'action',
@ -274,7 +277,7 @@
], ],
url: { url: {
imgerver: window._CONFIG['domianURL'] + "/sys/common/view", imgerver: window._CONFIG['staticDomainURL'],
syncUser: "/process/extActProcess/doSyncUser", syncUser: "/process/extActProcess/doSyncUser",
list: "/sys/user/list", list: "/sys/user/list",
delete: "/sys/user/delete", delete: "/sys/user/delete",
@ -291,7 +294,7 @@
}, },
methods: { methods: {
getAvatarView: function (avatar) { getAvatarView: function (avatar) {
return this.url.imgerver + "/" + avatar; return getFileAccessHttpUrl(avatar,this.url.imgerver,"http")
}, },
batchFrozen: function (status) { batchFrozen: function (status) {
@ -363,6 +366,8 @@
this.$refs.sysUserAgentModal.agentSettings(username); this.$refs.sysUserAgentModal.agentSettings(username);
this.$refs.sysUserAgentModal.title = "用户代理人设置"; this.$refs.sysUserAgentModal.title = "用户代理人设置";
}, },
handleSyncUser() {
},
passwordModalOk() { passwordModalOk() {
//TODO 密码修改完成 不需要刷新页面可以把datasource中的数据更新一下 //TODO 密码修改完成 不需要刷新页面可以把datasource中的数据更新一下
} }
@ -372,4 +377,4 @@
</script> </script>
<style scoped> <style scoped>
@import '~@assets/less/common.less' @import '~@assets/less/common.less'
</style> </style>

View File

@ -1,7 +1,7 @@
<template> <template>
<a-card :loading="cardLoading" :bordered="false" style="height: 100%;"> <a-card :loading="cardLoading" :bordered="false" style="height: 100%;">
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<a-input-search @search="handleSearch" style="width:100%;margin-top: 10px" placeholder="输入组织机构名称进行查询..."/> <a-input-search @search="handleSearch" style="width:100%;margin-top: 10px" placeholder="输入机构名称查询..." allowClear enterButton />
<a-tree <a-tree
showLine showLine
@ -67,20 +67,21 @@
promise.then(res => { promise.then(res => {
if (res.success) { if (res.success) {
this.treeDataSource = res.result this.treeDataSource = res.result
// update-begin- --- author:wangshuai ------ date:20200102 ---- for:去除默认选中第一条数据、默认展开所有第一级
// 默认选中第一条数据、默认展开所有第一级 // 默认选中第一条数据、默认展开所有第一级
if (res.result.length > 0) { // if (res.result.length > 0) {
this.expandedKeys = [] // this.expandedKeys = []
res.result.forEach((item, index) => { // res.result.forEach((item, index) => {
if (index === 0) { // if (index === 0) {
this.selectedKeys = [item.id] // this.selectedKeys = [item.id]
this.emitInput(item.orgCode) // this.emitInput(item.orgCode)
} // }
this.expandedKeys.push(item.id) // this.expandedKeys.push(item.id)
}) // })
} // }
// update-end- --- author:wangshuai ------ date:20200102 ---- for:去除默认选中第一条数据、默认展开所有第一级
} else { } else {
this.$message.warn('' + res.message) this.$message.warn(res.message)
console.error(':', res) console.error(':', res)
} }
}).finally(() => { }).finally(() => {

View File

@ -65,12 +65,6 @@
align: 'center', align: 'center',
customRender: (t, r, i) => parseInt(i) + 1 customRender: (t, r, i) => parseInt(i) + 1
}, },
{
title: '',
width: '20%',
align: 'center',
dataIndex: 'departName'
},
{ {
title: '', title: '',
width: '15%', width: '15%',
@ -83,6 +77,12 @@
align: 'center', align: 'center',
dataIndex: 'workNo' dataIndex: 'workNo'
}, },
{
title: '',
width: '20%',
align: 'center',
dataIndex: 'departName'
},
{ {
title: '', title: '',
width: '15%', width: '15%',
@ -91,7 +91,7 @@
customRender: (text) => (text || '').split(',').map(t => this.positionInfo[t] ? this.positionInfo[t] : t).join(',') customRender: (text) => (text || '').split(',').map(t => this.positionInfo[t] ? this.positionInfo[t] : t).join(',')
}, },
{ {
title: '', title: '',
width: '15%', width: '15%',
align: 'center', align: 'center',
dataIndex: 'telephone' dataIndex: 'telephone'
@ -130,14 +130,26 @@
methods: { methods: {
loadData(pageNum, orgCode) { loadData(pageNum, orgCode) {
if (!orgCode) {
return
}
//加载数据 若传入参数1则加载第一页的内容
if (pageNum === 1) {
this.ipagination.current = 1
}
this.loading = true this.loading = true
if (pageNum === 1) {
this.ipagination.current = 1
}
// update-begin- --- author:wangshuai ------ date:20200102 ---- for:传过来的部门编码为空全查
if (!orgCode) {
getAction(this.url.list, {
...this.getQueryParams()
}).then((res) => {
if (res.success) {
this.dataSource = res.result.records
this.ipagination.total = res.result.total
}
}).finally(() => {
this.loading = false
this.cardLoading = false
})
// update-end- --- author:wangshuai ------ date:20200102 ---- for:传过来的部门编码为空全查
}else{
//加载数据 若传入参数1则加载第一页的内容
getAction(this.url.list, { getAction(this.url.list, {
orgCode, orgCode,
...this.getQueryParams() ...this.getQueryParams()
@ -150,6 +162,7 @@
this.loading = false this.loading = false
this.cardLoading = false this.cardLoading = false
}) })
}
}, },
searchQuery() { searchQuery() {

View File

@ -0,0 +1,184 @@
<template>
<a-card :bordered="false">
<template v-if="this.departId">
<a-form>
<a-form-item label=''>
<a-tree
checkable
@check="onCheck"
:checkedKeys="checkedKeys"
:treeData="treeData"
@expand="onExpand"
@select="onTreeNodeSelect"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeysss"
:checkStrictly="checkStrictly"
style="height:500px;overflow: auto;">
<span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
{{ slotTitle }}
<a-icon v-if="ruleFlag" type="align-left" style="margin-left:5px;color: red;"></a-icon>
</span>
</a-tree>
</a-form-item>
</a-form>
<div class="anty-form-btn">
<a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
<a-menu slot="overlay">
<!-- Tree使checkStrictlyfalse
<a-menu-item key="1" @click="switchCheckStrictly(1)"></a-menu-item>
<a-menu-item key="2" @click="switchCheckStrictly(2)"></a-menu-item>
-->
<a-menu-item key="3" @click="checkALL"></a-menu-item>
<a-menu-item key="4" @click="cancelCheckALL"></a-menu-item>
<a-menu-item key="5" @click="expandAll"></a-menu-item>
<a-menu-item key="6" @click="closeAll"></a-menu-item>
</a-menu>
<a-button>
<a-icon type="up" />
</a-button>
</a-dropdown>
<a-button style="float: right" @click="handleSubmit" type="primary" htmlType="button" icon="form"></a-button>
</div>
</template>
<div v-else style="height:330px;"><h3>!</h3></div>
<depart-datarule-modal ref="datarule"/>
</a-card>
</template>
<script>
import {queryTreeListForRole,queryDepartPermission,saveDepartPermission} from '@/api/api'
import DepartDataruleModal from './DepartDataruleModal'
export default {
name: 'DepartAuthModal',
components: { DepartDataruleModal },
data(){
return {
departId:"",
treeData: [],
defaultCheckedKeys:[],
checkedKeys:[],
halfCheckedKeys:[],
expandedKeysss:[],
allTreeKeys:[],
autoExpandParent: true,
checkStrictly: false,
title:"部门权限配置",
visible: false,
loading: false,
selectedKeys:[]
}
},
methods: {
onTreeNodeSelect(id){
if(id && id.length>0){
this.selectedKeys = id
}
this.$refs.datarule.show(this.selectedKeys[0],this.departId)
},
onCheck (checkedKeys, { halfCheckedKeys }) {
// 保存选中的和半选中的,后面保存的时候合并提交
this.checkedKeys = checkedKeys
this.halfCheckedKeys = halfCheckedKeys
},
show(departId){
this.departId=departId
this.loadData();
},
close () {
this.reset()
this.$emit('close');
this.visible = false;
},
onExpand(expandedKeys){
this.expandedKeysss = expandedKeys;
this.autoExpandParent = false
},
reset () {
this.expandedKeysss = []
this.checkedKeys = []
this.defaultCheckedKeys = []
this.loading = false
},
expandAll () {
this.expandedKeysss = this.allTreeKeys
},
closeAll () {
this.expandedKeysss = []
},
checkALL () {
this.checkedKeys = this.allTreeKeys
},
cancelCheckALL () {
this.checkedKeys = []
},
handleCancel () {
this.close()
},
handleSubmit() {
let that = this;
if(!that.departId){
this.$message.warning('!')
}
let checkedKeys = [...that.checkedKeys, ...that.halfCheckedKeys]
const permissionIds = checkedKeys.join(",")
let params = {
departId:that.departId,
permissionIds,
lastpermissionIds:that.defaultCheckedKeys.join(","),
};
that.loading = true;
saveDepartPermission(params).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loading = false;
that.loadData();
}else {
that.$message.error(res.message);
that.loading = false;
}
})
},
convertTreeListToKeyLeafPairs(treeList, keyLeafPair = []) {
for(const {key, isLeaf, children} of treeList) {
keyLeafPair.push({key, isLeaf})
if(children && children.length > 0) {
this.convertTreeListToKeyLeafPairs(children, keyLeafPair)
}
}
return keyLeafPair;
},
emptyCurrForm() {
this.form.resetFields()
},
loadData(){
queryTreeListForRole().then((res) => {
this.treeData = res.result.treeList
this.allTreeKeys = res.result.ids
const keyLeafPairs = this.convertTreeListToKeyLeafPairs(this.treeData)
queryDepartPermission({departId:this.departId}).then((res)=>{
// 过滤出 leaf node 即可,即选中的
// Tree组件中checkStrictly默认为false的时候选中子节点父节点会自动设置选中或半选中
// 保存 checkedKeys 以及 halfCheckedKeys 以便于未做任何操作时提交表单数据
const checkedKeys = [...res.result].filter(key => {
const keyLeafPair = keyLeafPairs.filter(item => item.key === key)[0]
return keyLeafPair && keyLeafPair.isLeaf
})
const halfCheckedKeys = [...res.result].filter(key => {
const keyLeafPair = keyLeafPairs.filter(item => item.key === key)[0]
return keyLeafPair && !keyLeafPair.isLeaf
})
this.checkedKeys = [...checkedKeys];
this.halfCheckedKeys = [...halfCheckedKeys]
this.defaultCheckedKeys = [...halfCheckedKeys, ...checkedKeys];
this.expandedKeysss = this.allTreeKeys;
})
})
}
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,116 @@
<template>
<a-drawer
title="数据规则/按钮权限配置"
width="365"
:closable="false"
@close="onClose"
:visible="visible"
>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="数据规则" key="1">
<a-checkbox-group v-model="dataruleChecked" v-if="dataruleList.length>0">
<a-row>
<a-col :span="24" v-for="(item,index) in dataruleList" :key=" 'dr'+index ">
<a-checkbox :value="item.id">{{ item.ruleName }}</a-checkbox>
</a-col>
<a-col :span="24">
<div style="width: 100%;margin-top: 15px">
<a-button @click="saveDataruleForRole" type="primary" size="small" icon="save"></a-button>
</div>
</a-col>
</a-row>
</a-checkbox-group>
<div v-else><h3>!</h3></div>
</a-tab-pane>
</a-tabs>
</a-drawer>
</template>
<script>
import ARow from 'ant-design-vue/es/grid/Row'
import ACol from 'ant-design-vue/es/grid/Col'
import { getAction,postAction } from '@/api/manage'
export default {
name: 'DepartDataruleModal',
components: { ACol, ARow },
data(){
return {
functionId:'',
departId:'',
visible:false,
tabList: [{
key: '1',
tab: '',
}, {
key: '2',
tab: '',
}],
activeTabKey: '1',
url:{
datarule:"/sys/sysDepartPermission/datarule",
},
dataruleList:[],
dataruleChecked:[]
}
},
methods:{
loadData(){
getAction(`${this.url.datarule}/${this.functionId}/${this.departId}`).then(res=>{
if(res.success){
this.dataruleList = res.result.datarule
let drChecked = res.result.drChecked
if(drChecked){
this.dataruleChecked = drChecked.split(",")
}
}
})
},
saveDataruleForRole(){
if(!this.dataruleChecked || this.dataruleChecked.length==0){
this.$message.warning("请注意,现未勾选任何数据权限!")
}
let params = {
permissionId:this.functionId,
departId:this.departId,
dataRuleIds:this.dataruleChecked.join(",")
}
postAction(this.url.datarule,params).then(res=>{
if(res.success){
this.$message.success(res.message)
}else{
this.$message.error(res.message)
}
})
},
show(functionId,departId){
this.onReset()
this.functionId = functionId
this.departId = departId
this.visible=true
this.loadData()
},
onClose(){
this.visible=false
this.onReset()
},
onTabChange (key) {
this.activeTabKey = key
},
onReset(){
this.functionId=''
this.departId=''
this.dataruleList=[]
this.dataruleChecked=[]
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,217 @@
<template>
<a-drawer
:title="title"
:maskClosable="true"
width=650
placement="right"
:closable="true"
@close="close"
:visible="visible"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;">
<a-form>
<a-form-item label=''>
<a-tree
v-if="treeData.length>0"
checkable
@check="onCheck"
:checkedKeys="checkedKeys"
:treeData="treeData"
@expand="onExpand"
@select="onTreeNodeSelect"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeysss"
:checkStrictly="checkStrictly">
<span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
{{ slotTitle }}<a-icon v-if="ruleFlag" type="align-left" style="margin-left:5px;color: red;"></a-icon>
</span>
</a-tree>
<div v-else><h3>!</h3></div>
</a-form-item>
</a-form>
<div class="drawer-bootom-button">
<a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
<a-menu slot="overlay">
<a-menu-item key="3" @click="checkALL"></a-menu-item>
<a-menu-item key="4" @click="cancelCheckALL"></a-menu-item>
<a-menu-item key="5" @click="expandAll"></a-menu-item>
<a-menu-item key="6" @click="closeAll"></a-menu-item>
</a-menu>
<a-button>
<a-icon type="up" />
</a-button>
</a-dropdown>
<a-popconfirm title="确定放弃编辑?" @confirm="close" okText="确定" cancelText="取消">
<a-button style="margin-right: .8rem"></a-button>
</a-popconfirm>
<a-button @click="handleSubmit(false)" type="primary" :loading="loading" ghost style="margin-right: 0.8rem"></a-button>
<a-button @click="handleSubmit(true)" type="primary" :loading="loading"></a-button>
</div>
<dept-role-datarule-modal ref="datarule"></dept-role-datarule-modal>
</a-drawer>
</template>
<script>
import {queryTreeListForDeptRole,queryDeptRolePermission,saveDeptRolePermission} from '@/api/api'
import RoleDataruleModal from './RoleDataruleModal.vue'
import DeptRoleDataruleModal from './DeptRoleDataruleModal'
export default {
name: "DeptRoleAuthModal",
components:{
DeptRoleDataruleModal,
RoleDataruleModal
},
data(){
return {
departId:"",
roleId:"",
treeData: [],
defaultCheckedKeys:[],
checkedKeys:[],
halfCheckedKeys:[],
expandedKeysss:[],
allTreeKeys:[],
autoExpandParent: true,
checkStrictly: false,
title:"部门角色权限配置",
visible: false,
loading: false,
selectedKeys:[]
}
},
methods: {
onTreeNodeSelect(id){
if(id && id.length>0){
this.selectedKeys = id
}
this.$refs.datarule.show(this.selectedKeys[0],this.departId,this.roleId)
},
onCheck (checkedKeys, { halfCheckedKeys }) {
// 保存选中的和半选中的,后面保存的时候合并提交
this.checkedKeys = checkedKeys
this.halfCheckedKeys = halfCheckedKeys
},
show(roleId,departId){
this.departId = departId
this.roleId=roleId
this.visible = true;
},
close () {
this.reset()
this.$emit('close');
this.visible = false;
},
onExpand(expandedKeys){
this.expandedKeysss = expandedKeys;
this.autoExpandParent = false
},
reset () {
this.expandedKeysss = []
this.checkedKeys = []
this.defaultCheckedKeys = []
this.loading = false
},
expandAll () {
this.expandedKeysss = this.allTreeKeys
},
closeAll () {
this.expandedKeysss = []
},
checkALL () {
this.checkedKeys = this.allTreeKeys
},
cancelCheckALL () {
this.checkedKeys = []
},
handleCancel () {
this.close()
},
handleSubmit(exit) {
let that = this;
let checkedKeys = [...that.checkedKeys, ...that.halfCheckedKeys]
const permissionIds = checkedKeys.join(",")
let params = {
roleId:that.roleId,
permissionIds,
lastpermissionIds:that.defaultCheckedKeys.join(","),
};
that.loading = true;
console.log("请求参数:",params);
saveDeptRolePermission(params).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loading = false;
if (exit) {
that.close()
}
}else {
that.$message.error(res.message);
that.loading = false;
if (exit) {
that.close()
}
}
this.loadData();
})
},
convertTreeListToKeyLeafPairs(treeList, keyLeafPair = []) {
for(const {key, isLeaf, children} of treeList) {
keyLeafPair.push({key, isLeaf})
if(children && children.length > 0) {
this.convertTreeListToKeyLeafPairs(children, keyLeafPair)
}
}
return keyLeafPair;
},
loadData(){
queryTreeListForDeptRole({departId:this.departId}).then((res) => {
this.treeData = res.result.treeList
this.allTreeKeys = res.result.ids
const keyLeafPairs = this.convertTreeListToKeyLeafPairs(this.treeData)
queryDeptRolePermission({roleId:this.roleId}).then((res)=>{
// 过滤出 leaf node 即可,即选中的
// Tree组件中checkStrictly默认为false的时候选中子节点父节点会自动设置选中或半选中
// 保存 checkedKeys 以及 halfCheckedKeys 以便于未做任何操作时提交表单数据
const checkedKeys = [...res.result].filter(key => {
const keyLeafPair = keyLeafPairs.filter(item => item.key === key)[0]
return keyLeafPair && keyLeafPair.isLeaf
})
const halfCheckedKeys = [...res.result].filter(key => {
const keyLeafPair = keyLeafPairs.filter(item => item.key === key)[0]
return keyLeafPair && !keyLeafPair.isLeaf
})
this.checkedKeys = [...checkedKeys];
this.halfCheckedKeys = [...halfCheckedKeys]
this.defaultCheckedKeys = [...halfCheckedKeys, ...checkedKeys];
this.expandedKeysss = this.allTreeKeys;
})
})
}
},
watch: {
visible () {
if (this.visible ) {
this.loadData();
}
}
}
}
</script>
<style lang="scss" scoped>
.drawer-bootom-button {
position: absolute;
bottom: 0;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

View File

@ -0,0 +1,122 @@
<template>
<a-drawer
title="数据规则/按钮权限配置"
width="365"
:closable="false"
@close="onClose"
:visible="visible"
>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="数据规则" key="1">
<a-checkbox-group v-model="dataruleChecked" v-if="dataruleList.length>0">
<a-row>
<a-col :span="24" v-for="(item,index) in dataruleList" :key=" 'dr'+index ">
<a-checkbox :value="item.id">{{ item.ruleName }}</a-checkbox>
</a-col>
<a-col :span="24">
<div style="width: 100%;margin-top: 15px">
<a-button @click="saveDataruleForRole" type="primary" size="small" icon="save"></a-button>
</div>
</a-col>
</a-row>
</a-checkbox-group>
<div v-else><h3>!</h3></div>
</a-tab-pane>
<!--<a-tab-pane tab="按钮权限" key="2">!!!</a-tab-pane>-->
</a-tabs>
</a-drawer>
</template>
<script>
import ARow from 'ant-design-vue/es/grid/Row'
import ACol from 'ant-design-vue/es/grid/Col'
import { getAction,postAction } from '@/api/manage'
export default {
name: 'DeptRoleDataruleModal',
components: { ACol, ARow },
data(){
return {
departId:'',
functionId:'',
roleId:'',
visible:false,
tabList: [{
key: '1',
tab: '',
}, {
key: '2',
tab: '',
}],
activeTabKey: '1',
url:{
datarule:"/sys/sysDepartRole/datarule",
},
dataruleList:[],
dataruleChecked:[]
}
},
methods:{
loadData(){
getAction(`${this.url.datarule}/${this.functionId}/${this.departId}/${this.roleId}`).then(res=>{
console.log(res)
if(res.success){
this.dataruleList = res.result.datarule
let drChecked = res.result.drChecked
if(drChecked){
this.dataruleChecked = drChecked.split(",")
}
}
})
},
saveDataruleForRole(){
if(!this.dataruleChecked || this.dataruleChecked.length==0){
this.$message.warning("请注意,现未勾选任何数据权限!")
}
let params = {
permissionId:this.functionId,
roleId:this.roleId,
dataRuleIds:this.dataruleChecked.join(",")
}
console.log("保存数据权限",params)
postAction(this.url.datarule,params).then(res=>{
if(res.success){
this.$message.success(res.message)
}else{
this.$message.error(res.message)
}
})
},
show(functionId,departId,roleId){
this.onReset()
this.departId = departId
this.functionId = functionId
this.roleId = roleId
this.visible=true
this.loadData()
},
onClose(){
this.visible=false
this.onReset()
},
onTabChange (key) {
this.activeTabKey = key
},
onReset(){
this.functionId=''
this.roleId=''
this.dataruleList=[]
this.dataruleChecked=[]
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,196 @@
<template>
<a-card :bordered="false">
<!-- -->
<div class="table-page-search-wrapper">
<!-- -->
<a-form layout="inline">
<a-row :gutter="10">
<a-col :md="10" :sm="12">
<a-form-item label="部门角色名称" style="margin-left:8px">
<a-input placeholder="请输入部门角色" v-model="queryParam.roleName"></a-input>
</a-form-item>
</a-col>
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24">
<a-button type="primary" @click="searchQuery" icon="search" style="margin-left: 18px"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
</a-col>
</span>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator" :md="24" :sm="24">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/></a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> <a style="font-weight: 600">
{{selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
<a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a></a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a href="javascript:;" @click="handleDetail(record)"></a>
</a-menu-item>
<a-menu-item>
<a @click="handlePerssion(record)"></a>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table-end -->
<!-- -->
<sys-depart-role-modal ref="modalForm" @ok="modalFormOk"/>
<dept-role-auth-modal ref="modalDeptRole" />
</a-card>
</template>
<script>
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import {getAction} from '@/api/manage'
import SysDepartRoleModal from './SysDepartRoleModal'
import DeptRoleAuthModal from './DeptRoleAuthModal'
export default {
name: 'DeptRoleInfo',
components: { DeptRoleAuthModal, SysDepartRoleModal },
mixins: [JeecgListMixin],
data() {
return {
description: '',
currentDeptId: '',
// 表头
columns: [{
title: '',
align: "center",
dataIndex: 'roleName'
},
{
title: '',
align: "center",
dataIndex: 'roleCode'
},
{
title: '',
align: "center",
dataIndex: 'departId_dictText'
},
{
title: '',
align: "center",
dataIndex: 'description'
},
{
title: '',
dataIndex: 'action',
scopedSlots: {customRender: 'action'},
align: "center",
width: 170
}],
url: {
list: "/sys/sysDepartRole/list",
delete: "/sys/sysDepartRole/delete",
deleteBatch: "/sys/sysDepartRole/deleteBatch",
}
}
},
created() {
},
methods: {
searchReset() {
this.queryParam = {}
this.currentDeptId = '';
this.loadData(1);
this.$emit('clearSelectedDepartKeys')
},
loadData(arg) {
if (!this.url.list) {
this.$message.error("请设置url.list属性!")
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
let params = this.getQueryParams();//查询条件
params.deptId = this.currentDeptId;
getAction(this.url.list, params).then((res) => {
if (res.success && res.result) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
})
},
open(record) {
this.currentDeptId = record.id;
this.loadData(1);
},
clearList() {
this.currentDeptId = '';
this.dataSource = [];
},
hasSelectDept() {
if (this.currentDeptId == '') {
this.$message.error("请选择一个部门!")
return false;
}
return true;
},
handleEdit: function (record) {
this.$refs.modalForm.title = "编辑";
this.$refs.modalForm.departDisabled = true;
this.$refs.modalForm.disableSubmit = false;
this.$refs.modalForm.edit(record,record.departId);
},
handleAdd: function () {
if (this.currentDeptId == '') {
this.$message.error("请选择一个部门!")
} else {
this.$refs.modalForm.departDisabled = true;
this.$refs.modalForm.add(this.currentDeptId);
this.$refs.modalForm.title = "新增";
}
},
handlePerssion: function(record){
this.$refs.modalDeptRole.show(record.id,record.departId);
},
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,200 @@
<template>
<a-drawer
:title="title"
:maskClosable="true"
width=600
placement="right"
:closable="true"
@close="close"
:visible="visible"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;">
<a-spin :spinning="confirmLoading">
<a-form :form="form" v-if="designNameOption.length>0">
<a-form-item label=''>
<a-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :style="{ marginTop: '12px',height:'auto' }">
<a-checkbox-group @change="designNameChange" v-model="designNameValue" style="width: 100%">
<a-row>
<template v-for="(des) in designNameOption">
<a-col :span="6">
<a-checkbox :value="des.value">{{ des.text }}</a-checkbox>
</a-col>
</template>
</a-row>
</a-checkbox-group>
</a-card>
</a-col>
</a-form-item>
</a-form>
<div v-else><h3>!</h3></div>
</a-spin>
<div class="drawer-bootom-button">
<a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
<a-menu slot="overlay">
<a-menu-item key="1" @click="checkALL"></a-menu-item>
<a-menu-item key="2" @click="cancelCheckALL"></a-menu-item>
</a-menu>
<a-button>
<a-icon type="up" />
</a-button>
</a-dropdown>
<a-popconfirm title="确定放弃编辑?" @confirm="close" okText="确定" cancelText="取消">
<a-button style="margin-right: .8rem"></a-button>
</a-popconfirm>
<a-button @click="handleSubmit(true)" type="primary"></a-button>
</div>
</a-drawer>
</template>
<script>
import {httpAction, getAction} from '@/api/manage'
import JEllipsis from '@/components/jeecg/JEllipsis'
import {initDictOptions} from '@/components/dict/JDictSelectUtil'
export default {
name: 'DeptRoleUserModal',
components: {
JEllipsis
},
data() {
return {
currentDeptId:"",
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: {},
url: {
add: "/sys/sysDepartRole/deptRoleUserAdd",
getDeptRoleList:"/sys/sysDepartRole/getDeptRoleList",
getDeptRoleByUserId:"/sys/sysDepartRole/getDeptRoleByUserId"
},
designNameOption: [],
userId: "",
newRoleId:"",
oldRoleId:"",
designNameValue:[],
desformList: [],
}
},
created() {
},
methods: {
add(record,departId) {
this.userId = record.id;
this.currentDeptId = departId;
this.loadDesformList();
this.edit({});
},
edit(record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
getAction(this.url.getDeptRoleByUserId,{userId:this.userId}).then((res) => {
if (res.success) {
var designName = [];
for (let value of res.result) {
designName.push(value.droleId)
}
this.oldRoleId=designName.join(",");
this.designNameValue = designName;
this.newRoleId = designName.join(",");
}
});
},
close() {
this.$emit('close');
this.visible = false;
},
handleSubmit() {
const that = this;
// 触发表单验证
that.confirmLoading = true;
let httpurl = this.url.add;
let method = 'post';
let formData = Object.assign(this.model, {});
//时间格式化
formData.userId = this.userId;
formData.newRoleId=this.newRoleId;
formData.oldRoleId=this.oldRoleId;
httpAction(httpurl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('reload');
that.$emit('ok');
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
},
handleCancel() {
this.designNameOption=[];
this.designNameValue=[];
this.close()
},
designNameChange(selectedValue) {
this.newRoleId=selectedValue.join(",");
},
checkALL(){
var designName = [];
for (let value of this.desformList) {
designName.push(
value.id
)
}
this.designNameValue = designName;
this.newRoleId=designName.join(",");
},
cancelCheckALL(){
this.designNameValue=[];
this.newRoleId="";
},
/** 加载desform */
loadDesformList() {
getAction(this.url.getDeptRoleList, { departId: this.currentDeptId }).then((res) => {
if (res.success) {
this.desformList = res.result
var designName = [];
for (let value of this.desformList) {
designName.push({
value: value.id,
text: value.roleName,
})
}
this.designNameOption = designName;
}
});
},
}
}
</script>
<style scoped>
.drawer-bootom-button {
position: absolute;
bottom: 0;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

View File

@ -7,7 +7,7 @@
<a-row :gutter="10"> <a-row :gutter="10">
<a-col :md="10" :sm="12"> <a-col :md="10" :sm="12">
<a-form-item label="用户账号" style="margin-left:8px"> <a-form-item label="用户账号" style="margin-left:8px">
<a-input placeholder="请输入名称查询" v-model="queryParam.username"></a-input> <a-input placeholder="请输入账号" v-model="queryParam.username"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<!--<a-col :md="8" :sm="8">--> <!--<a-col :md="8" :sm="8">-->
@ -25,7 +25,7 @@
</a-form> </a-form>
</div> </div>
<!-- --> <!-- -->
<div class="table-operator" :md="24" :sm="24" style="margin: -46px 0px 10px 2px"> <div class="table-operator" :md="24" :sm="24" style="margin-top: -15px">
<a-button @click="handleAdd" type="primary" icon="plus" style="margin-top: 16px"></a-button> <a-button @click="handleAdd" type="primary" icon="plus" style="margin-top: 16px"></a-button>
<!--<a-button @click="handleEdit" type="primary" icon="edit" style="margin-top: 16px"></a-button>--> <!--<a-button @click="handleEdit" type="primary" icon="edit" style="margin-top: 16px"></a-button>-->
<a-button @click="handleAddUserDepart" type="primary" icon="plus"></a-button> <a-button @click="handleAddUserDepart" type="primary" icon="plus"></a-button>
@ -34,7 +34,7 @@
<a-menu slot="overlay"> <a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"> <a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/> <a-icon type="delete"/>
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
<a-button style="margin-left: 8px"> <a-button style="margin-left: 8px">
@ -80,10 +80,13 @@
</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)">
<a></a> <a></a>
</a-popconfirm> </a-popconfirm>
</a-menu-item> </a-menu-item>
<a-menu-item>
<a href="javascript:;" @click="handleDeptRole(record)"></a>
</a-menu-item>
</a-menu> </a-menu>
</a-dropdown> </a-dropdown>
</span> </span>
@ -96,6 +99,7 @@
<!-- --> <!-- -->
<user-modal ref="modalForm" @ok="modalFormOk"></user-modal> <user-modal ref="modalForm" @ok="modalFormOk"></user-modal>
<Select-User-Modal ref="selectUserModal" @selectFinished="selectOK"></Select-User-Modal> <Select-User-Modal ref="selectUserModal" @selectFinished="selectOK"></Select-User-Modal>
<dept-role-user-modal ref="deptRoleUser"></dept-role-user-modal>
</a-card> </a-card>
</template> </template>
@ -104,11 +108,13 @@
import {getAction, postAction, deleteAction} from '@/api/manage' import {getAction, postAction, deleteAction} from '@/api/manage'
import SelectUserModal from './SelectUserModal' import SelectUserModal from './SelectUserModal'
import UserModal from './UserModal' import UserModal from './UserModal'
import DeptRoleUserModal from './DeptRoleUserModal'
export default { export default {
name: "DeptUserInfo", name: "DeptUserInfo",
mixins: [JeecgListMixin], mixins: [JeecgListMixin],
components: { components: {
DeptRoleUserModal,
SelectUserModal, SelectUserModal,
UserModal UserModal
}, },
@ -127,6 +133,21 @@
align: "center", align: "center",
dataIndex: 'realname' dataIndex: 'realname'
}, },
{
title: '',
align: "center",
dataIndex: 'sex_dictText'
},
{
title: '',
align: "center",
dataIndex: 'phone'
},
{
title: '',
align: "center",
dataIndex: 'orgCode'
},
{ {
title: '', title: '',
dataIndex: 'action', dataIndex: 'action',
@ -146,7 +167,12 @@
}, },
methods: { methods: {
searchReset() {
this.queryParam = {}
this.currentDeptId = '';
this.loadData(1);
this.$emit('clearSelectedDepartKeys')
},
loadData(arg) { loadData(arg) {
if (!this.url.list) { if (!this.url.list) {
this.$message.error("请设置url.list属性!") this.$message.error("请设置url.list属性!")
@ -156,11 +182,11 @@
if (arg === 1) { if (arg === 1) {
this.ipagination.current = 1; this.ipagination.current = 1;
} }
if (this.currentDeptId === '') return; //if (this.currentDeptId === '') return;
var params = this.getQueryParams();//查询条件 let params = this.getQueryParams();//查询条件
params.depId = this.currentDeptId; params.depId = this.currentDeptId;
getAction(this.url.list, params).then((res) => { getAction(this.url.list, params).then((res) => {
if (res.success) { if (res.success && res.result) {
this.dataSource = res.result.records; this.dataSource = res.result.records;
this.ipagination.total = res.result.total; this.ipagination.total = res.result.total;
} }
@ -172,6 +198,11 @@
this.$message.error("请设置url.deleteBatch属性!") this.$message.error("请设置url.deleteBatch属性!")
return return
} }
if (!this.currentDeptId) {
this.$message.error("未选中任何部门,无法取消部门与用户的关联!")
return
}
if (this.selectedRowKeys.length <= 0) { if (this.selectedRowKeys.length <= 0) {
this.$message.warning(''); this.$message.warning('');
return; return;
@ -183,12 +214,12 @@
var that = this; var that = this;
console.log(this.currentDeptId); console.log(this.currentDeptId);
this.$confirm({ this.$confirm({
title: "确认删除", title: "确认取消",
content: "是否删除选中数据?", content: "是否取消用户与选中部门的关联?",
onOk: function () { onOk: function () {
deleteAction(that.url.deleteBatch, {depId: that.currentDeptId, userIds: ids}).then((res) => { deleteAction(that.url.deleteBatch, {depId: that.currentDeptId, userIds: ids}).then((res) => {
if (res.success) { if (res.success) {
that.$message.success(res.message); that.$message.success("删除用户与选中部门关系成功!");
that.loadData(); that.loadData();
that.onClearSelected(); that.onClearSelected();
} else { } else {
@ -204,10 +235,15 @@
this.$message.error("请设置url.delete属性!") this.$message.error("请设置url.delete属性!")
return return
} }
if (!this.currentDeptId) {
this.$message.error("未选中任何部门,无法取消部门与用户的关联!")
return
}
var that = this; var that = this;
deleteAction(that.url.delete, {depId: this.currentDeptId, userId: id}).then((res) => { deleteAction(that.url.delete, {depId: this.currentDeptId, userId: id}).then((res) => {
if (res.success) { if (res.success) {
that.$message.success(res.message); that.$message.success("删除用户与选中部门关系成功!");
if (this.selectedRowKeys.length>0){ if (this.selectedRowKeys.length>0){
for(let i =0; i<this.selectedRowKeys.length;i++){ for(let i =0; i<this.selectedRowKeys.length;i++){
if (this.selectedRowKeys[i] == id){ if (this.selectedRowKeys[i] == id){
@ -232,14 +268,14 @@
this.dataSource = []; this.dataSource = [];
}, },
hasSelectDept() { hasSelectDept() {
if (this.currentDeptId == null) { if (this.currentDeptId == '') {
this.$message.error("请选择一个部门!") this.$message.error("请选择一个部门!")
return false; return false;
} }
return true; return true;
}, },
handleAddUserDepart() { handleAddUserDepart() {
if (this.currentDeptId == '') { if (this.currentDeptId == '' ) {
this.$message.error("请选择一个部门!") this.$message.error("请选择一个部门!")
} else { } else {
this.$refs.selectUserModal.visible = true; this.$refs.selectUserModal.visible = true;
@ -277,6 +313,10 @@
this.$message.warning(res.message); this.$message.warning(res.message);
} }
}) })
},
handleDeptRole(record){
this.$refs.deptRoleUser.add(record,this.currentDeptId);
this.$refs.deptRoleUser.title = "部门角色分配";
} }
} }
} }

View File

@ -30,7 +30,7 @@
</template> </template>
<script> <script>
import {changPassword} from '@/api/api' import {changePassword} from '@/api/api'
export default { export default {
name: "PasswordModal", name: "PasswordModal",
@ -96,7 +96,7 @@
if (!err) { if (!err) {
this.confirmLoading = true; this.confirmLoading = true;
let formData = Object.assign(this.model, values); let formData = Object.assign(this.model, values);
changPassword(formData).then((res)=>{ changePassword(formData).then((res)=>{
if(res.success){ if(res.success){
this.$message.success(res.message); this.$message.success(res.message);
this.$emit('ok'); this.$emit('ok');

View File

@ -13,13 +13,13 @@
<a-col :span="6"> <a-col :span="6">
<a-form-item label="账号"> <a-form-item label="账号">
<a-input placeholder="请输入账号查询" v-model="queryParam.username"></a-input> <a-input placeholder="请输入账号" v-model="queryParam.username"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-item label="性别"> <a-form-item label="性别">
<a-select v-model="queryParam.sex" placeholder="请选择性别查询"> <a-select v-model="queryParam.sex" placeholder="请选择性别">
<a-select-option value=""></a-select-option> <a-select-option value=""></a-select-option>
<a-select-option value="1"></a-select-option> <a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option> <a-select-option value="2"></a-select-option>
@ -31,20 +31,20 @@
<template v-if="toggleSearchStatus"> <template v-if="toggleSearchStatus">
<a-col :span="6"> <a-col :span="6">
<a-form-item label="邮箱"> <a-form-item label="邮箱">
<a-input placeholder="请输入邮箱查询" v-model="queryParam.email"></a-input> <a-input placeholder="请输入邮箱" v-model="queryParam.email"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-item label="手机号码"> <a-form-item label="手机号码">
<a-input placeholder="请输入手机号码查询" v-model="queryParam.phone"></a-input> <a-input placeholder="请输入手机号码" v-model="queryParam.phone"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-form-item label="状态"> <a-form-item label="状态">
<a-select v-model="queryParam.status" placeholder="请选择用户状态查询"> <a-select v-model="queryParam.status" placeholder="请选择状态">
<a-select-option value=""></a-select-option> <a-select-option value=""></a-select-option>
<a-select-option value="1"></a-select-option> <a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option> <a-select-option value="2"></a-select-option>
</a-select> </a-select>
@ -101,7 +101,7 @@
fixed:'left', fixed:'left',
width:200 width:200
},{ },{
title: '', title: '',
align:"center", align:"center",
dataIndex: 'realname', dataIndex: 'realname',
},{ },{

View File

@ -12,12 +12,12 @@
<!-- --> <!-- -->
<div class="table-page-search-wrapper"> <div class="table-page-search-wrapper">
<a-form layout="inline"> <a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="10"> <a-col :span="10">
<a-form-item label="姓名"> <a-form-item label="用户账号">
<a-input placeholder="请输入姓名" v-model="queryParam.username"></a-input> <a-input placeholder="请输入用户账号" v-model="queryParam.username"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
@ -83,7 +83,7 @@
{ {
title: '', title: '',
align: "center", align: "center",
width: 113, width: 100,
dataIndex: 'username' dataIndex: 'username'
}, },
{ {
@ -93,10 +93,22 @@
dataIndex: 'realname' dataIndex: 'realname'
}, },
{ {
title: '', title: '',
align: "center", align: "center",
width: 100, width: 100,
dataIndex: 'status' dataIndex: 'sex_dictText'
},
{
title: '',
align: "center",
width: 100,
dataIndex: 'phone'
},
{
title: '',
align: "center",
width: 150,
dataIndex: 'orgCode'
} }
], ],
columns2: [ columns2: [

View File

@ -12,16 +12,16 @@
<a-spin :spinning="confirmLoading"> <a-spin :spinning="confirmLoading">
<a-form :form="form"> <a-form :form="form">
<a-row class="form-row" :gutter="{ xs: 8, sm: 16, md: 24, lg: 32 }"> <a-row style="width: 100%;">
<a-col :lg="12"> <a-col :span="24/2">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="标题"> label="标题">
<a-input placeholder="请输入标题" v-decorator="['titile', validatorRules.title]" :readOnly="disableSubmit" style="width: 90%"/> <a-input placeholder="请输入标题" v-decorator="['titile', validatorRules.title]" :readOnly="disableSubmit"/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :lg="12"> <a-col :span="24/2">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
@ -30,76 +30,68 @@
v-decorator="[ 'msgCategory', validatorRules.msgCategory]" v-decorator="[ 'msgCategory', validatorRules.msgCategory]"
placeholder="请选择消息类型" placeholder="请选择消息类型"
:disabled="disableSubmit" :disabled="disableSubmit"
:getPopupContainer = "(target) => target.parentNode" :getPopupContainer = "(target) => target.parentNode">
style="width: 80%" >
<a-select-option value="1"></a-select-option> <a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option> <a-select-option value="2"></a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row style="width: 100%;">
<a-row class="form-row" :gutter="24"> <a-col :span="24/2">
<a-col :lg="12">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="开始时间:" label="开始时间:">
style="margin-left: 27px"> <j-date style="width: 100%" :getCalendarContainer="node => node.parentNode" v-decorator="[ 'startTime', validatorRules.startTime]" placeholder="请选择开始时间" showTime dateFormat="YYYY-MM-DD HH:mm:ss" ></j-date>
<j-date v-decorator="[ 'startTime', validatorRules.startTime]" placeholder="请选择开始时间" showTime dateFormat="YYYY-MM-DD HH:mm:ss" ></j-date>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :lg="12"> <a-col :span="24/2">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="结束时间" label="结束时间"
class="endTime"> class="endTime">
<j-date v-decorator="[ 'endTime', validatorRules.endTime]" placeholder="请选择结束时间" showTime dateFormat="YYYY-MM-DD HH:mm:ss"></j-date> <j-date style="width: 100%" :getCalendarContainer="node => node.parentNode" v-decorator="[ 'endTime', validatorRules.endTime]" placeholder="请选择结束时间" showTime dateFormat="YYYY-MM-DD HH:mm:ss"></j-date>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row style="width: 100%;">
<a-row class="form-row" :gutter="32"> <a-col :span="24/2">
<a-col :lg="9">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="优先级" label="优先级">
style="margin-left: 27px">
<a-select <a-select
v-decorator="[ 'priority', {}]" v-decorator="[ 'priority', {}]"
placeholder="请选择优先级" placeholder="请选择优先级"
:disabled="disableSubmit" :disabled="disableSubmit"
:getPopupContainer = "(target) => target.parentNode" :getPopupContainer = "(target) => target.parentNode">
style="margin-left: 5px;width: 135%">
<a-select-option value="L"></a-select-option> <a-select-option value="L"></a-select-option>
<a-select-option value="M"></a-select-option> <a-select-option value="M"></a-select-option>
<a-select-option value="H"></a-select-option> <a-select-option value="H"></a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :lg="15" push="3"> <a-col :span="24/2">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
label="通告对象类型" label="通告类型">
style="margin-left: -14px">
<a-select <a-select
v-decorator="[ 'msgType', validatorRules.msgType]" v-decorator="[ 'msgType', validatorRules.msgType]"
placeholder="请选择通告对象类型" placeholder="请选择通告类型"
:disabled="disableSubmit" :disabled="disableSubmit"
@change="chooseMsgType" @change="chooseMsgType"
:getPopupContainer = "(target) => target.parentNode" :getPopupContainer = "(target) => target.parentNode">
style="width: 200px;margin-left: 5px">
<a-select-option value="USER"></a-select-option> <a-select-option value="USER"></a-select-option>
<a-select-option value="ALL"></a-select-option> <a-select-option value="ALL"></a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row> <a-row style="width: 100%;">
<a-col :lg="24" pull="2"> <a-col :span="24/2">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelCol"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
@ -110,20 +102,19 @@
placeholder="请选择用户" placeholder="请选择用户"
v-model="selectedUser" v-model="selectedUser"
@dropdownVisibleChange="selectUserIds" @dropdownVisibleChange="selectUserIds"
style="width: 119%"
> >
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row> <a-row style="width: 100%;">
<a-col :lg="24" pull="3"> <a-col :span="24">
<a-form-item <a-form-item
:labelCol="labelCol" :labelCol="labelColX1"
:wrapperCol="wrapperCol" :wrapperCol="wrapperColX1"
label="内容" label="内容"
style="margin-left: 5px"> class="j-field-content">
<j-editor style="width: 130%" v-decorator="[ 'msgContent', {} ]" triggerChange></j-editor> <j-editor v-decorator="[ 'msgContent', {} ]" triggerChange></j-editor>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
@ -153,11 +144,19 @@
model: {}, model: {},
labelCol: { labelCol: {
xs: { span: 24 }, xs: { span: 24 },
sm: { span: 5 }, sm: { span: 6 },
}, },
wrapperCol: { wrapperCol: {
xs: { span: 24 }, xs: { span: 24 },
sm: { span: 16 }, sm: { span: 18 },
},
labelColX1: {
xs: { span: 24 },
sm: { span: 3 },
},
wrapperColX1: {
xs: { span: 24 },
sm: { span: 21 },
}, },
confirmLoading: false, confirmLoading: false,

View File

@ -0,0 +1,379 @@
<template>
<a-modal
:title="title"
:width="1000"
: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 placeholder="请输入规则名称" v-decorator="['ruleName', validatorRules.ruleName]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="规则Code">
<a-input placeholder="请输入规则Code" v-decorator="['ruleCode', validatorRules.ruleCode]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="规则描述">
<a-textarea placeholder="请输入规则描述" v-decorator="['ruleDescription', {}]"/>
</a-form-item>
</a-form>
<!-- -->
<a-tabs v-model="tabs.activeKey">
<a-tab-pane tab="局部规则" :key="tabs.design.key" forceRender>
<a-alert type="info" showIcon message="局部规则按照你输入的位数有序的校验。"/>
<j-editable-table
ref="designTable"
dragSort
rowNumber
:maxHeight="240"
:columns="tabs.design.columns"
:dataSource="tabs.design.dataSource"
style="margin-top: 8px;"
>
<template #action="props">
<my-action-button :rowEvent="props"/>
</template>
</j-editable-table>
</a-tab-pane>
<a-tab-pane tab="全局规则" :key="tabs.global.key" forceRender>
<j-editable-table
ref="globalTable"
dragSort
rowNumber
actionButton
:maxHeight="240"
:columns="tabs.global.columns"
:dataSource="tabs.global.dataSource"
>
<template #actionButtonAfter>
<a-alert type="info" showIcon message="全局规则可校验用户输入的所有字符;全局规则的优先级比局部规则的要高。" style="margin-bottom: 8px;"/>
</template>
<template #action="props">
<my-action-button :rowEvent="props" allowEmpty/>
</template>
</j-editable-table>
</a-tab-pane>
</a-tabs>
</a-spin>
</a-modal>
</template>
<script>
import pick from 'lodash.pick'
import { httpAction } from '@/api/manage'
import { validateDuplicateValue, alwaysResolve, failedSymbol } from '@/utils/util'
import { FormTypes } from '@/utils/JEditableTableUtil'
import JEditableTable from '@comp/jeecg/JEditableTable'
export default {
name: 'SysCheckRuleModal',
components: {
JEditableTable,
'my-action-button': {
props: { rowEvent: Object, allowEmpty: Boolean },
methods: {
confirmIsShow() {
const { index, allValues: { inputValues } } = this.rowEvent
let value = inputValues[index]
return value.digits || value.pattern
},
handleLineAdd() {
const { target } = this.rowEvent
target.add()
},
handleLineDelete() {
const { rowId, target } = this.rowEvent
target.removeRows(rowId)
},
renderDeleteButton() {
if (this.allowEmpty || this.rowEvent.index > 0) {
if (this.confirmIsShow()) {
return (
<a-popconfirm title="确定要删除吗?" onConfirm={this.handleLineDelete}>
<a-button icon="minus"/>
</a-popconfirm>
)
} else {
return (
<a-button icon="minus" onClick={this.handleLineDelete}/>
)
}
}
return ''
},
},
render() {
return (
<div>
<a-button onClick={this.handleLineAdd} icon="plus"/>
&nbsp;
{this.renderDeleteButton()}
</div>
)
}
}
},
data() {
return {
title: '',
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
ruleName: { rules: [{ required: true, message: '!' },] },
ruleCode: {
rules: [
{ required: true, message: 'Code!' },
{ validator: (rule, value, callback) => validateDuplicateValue('sys_check_rule', 'rule_code', value, this.model.id, callback) }
]
},
},
tabs: {
activeKey: 'design',
global: {
key: 'global',
columns: [
{
title: '',
key: 'priority',
width: '15%',
type: FormTypes.select,
defaultValue: '1',
options: [
{ title: '', value: '1' },
{ title: '', value: '0' },
],
validateRules: []
},
{
title: '',
key: 'pattern',
width: '50%',
type: FormTypes.input,
validateRules: [
{ required: true, message: '' },
{ handler: this.validatePatternHandler },
]
},
{
title: '',
key: 'message',
width: '20%',
type: FormTypes.input,
validateRules: [
{ required: true, message: '${title}' },
]
},
{
title: '',
key: 'action',
width: '15%',
slotName: 'action',
type: FormTypes.slot
}
],
dataSource: [],
},
design: {
key: 'design',
columns: [
{
title: '',
key: 'digits',
width: '15%',
type: FormTypes.inputNumber,
validateRules: [
{ required: true, message: '${title}' },
{ pattern: /^[1-9]\d*$/, message: '' },
]
},
{
title: '',
key: 'pattern',
width: '50%',
type: FormTypes.input,
validateRules: [
{ required: true, message: '' },
{ handler: this.validatePatternHandler }
]
},
{
title: '',
key: 'message',
width: '20%',
type: FormTypes.input,
validateRules: [
{ required: true, message: '${title}' },
]
},
{
title: '',
key: 'action',
width: '15%',
slotName: 'action',
type: FormTypes.slot
},
],
dataSource: [],
}
},
url: {
add: '/sys/checkRule/add',
edit: '/sys/checkRule/edit',
},
}
},
created() {
},
methods: {
validatePatternHandler(type, value, row, column, callback, target) {
if (type === 'blur' || type === 'getValues') {
try {
new RegExp(value)
callback(true)
} catch (e) {
callback(false, '')
}
} else {
callback(true) // 不填写或者填写 null 代表不进行任何操作
}
},
add() {
this.edit({})
},
edit(record) {
this.form.resetFields()
this.tabs.activeKey = this.tabs.design.key
this.tabs.global.dataSource = []
this.tabs.design.dataSource = [{ digits: '', pattern: '', message: '' }]
this.model = Object.assign({}, record)
this.visible = true
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'ruleName', 'ruleCode', 'ruleDescription'))
// 子表数据
let ruleJson = this.model.ruleJson
if (ruleJson) {
let ruleList = JSON.parse(ruleJson)
// 筛选出全局规则和局部规则
let global = [], design = [], priority = '1'
ruleList.forEach(rule => {
if (rule.digits === '*') {
global.push(Object.assign(rule, { priority }))
} else {
priority = '0'
design.push(rule)
}
})
this.tabs.global.dataSource = global
this.tabs.design.dataSource = design
}
})
},
close() {
this.$emit('close')
this.visible = false
},
handleOk() {
Promise.all([
// 主表单校验
alwaysResolve(new Promise((resolve, reject) => {
this.form.validateFields((error, values) => error ? reject(error) : resolve(values))
})),
// 局部规则子表校验
alwaysResolve(this.$refs.designTable.getValuesPromise),
// 全局规则子表校验
alwaysResolve(this.$refs.globalTable.getValuesPromise),
]).then(results => {
let [mainResult, designResult, globalResult] = results
if (mainResult.type === failedSymbol) {
return Promise.reject('')
} else if (designResult.type === failedSymbol) {
this.tabs.activeKey = this.tabs.design.key
return Promise.reject('')
} else if (globalResult.type === failedSymbol) {
this.tabs.activeKey = this.tabs.global.key
return Promise.reject('')
} else {
// 所有校验已通过,这一步是整合数据
let mainValues = mainResult.data, globalValues = globalResult.data, designValues = designResult.data
// 整合两个子表的数据
let firstGlobal = [], afterGlobal = []
globalValues.forEach(v => {
v.digits = '*'
if (v.priority === '1') {
firstGlobal.push(v)
} else {
afterGlobal.push(v)
}
})
let concatValues = firstGlobal.concat(designValues).concat(afterGlobal)
let subValues = concatValues.map(i => pick(i, 'digits', 'pattern', 'message'))
// 生成 formData用于传入后台
let ruleJson = JSON.stringify(subValues)
let formData = Object.assign(this.model, mainValues, { ruleJson })
// 判断请求方式和请求地址,并发送请求
let method = 'post', httpUrl = this.url.add
if (this.model.id) {
method = 'put'
httpUrl = this.url.edit
}
this.confirmLoading = true
return httpAction(httpUrl, formData, method)
}
}).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).catch(e => {
console.error(e)
}).finally(() => {
this.confirmLoading = false
})
},
handleCancel() {
this.close()
},
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,58 @@
<template>
<a-modal
title="功能测试"
:width="800"
:visible="visible"
@ok="visible=false"
@cancel="visible=false"
>
<a-form :form="form">
<a-form-item label="功能测试">
<a-input placeholder="请输入" v-decorator="['test', validatorRules.test]" @change="e=>testValue=e.target.value"/>
</a-form-item>
</a-form>
<a-row type="flex" :gutter="8">
<a-col v-for="(str,index) of testValue">
<a-row>
<a-col>
<a-input :value="str" style="text-align: center;width: 40px;"/>
</a-col>
<a-col style="text-align: center;">{{index+1}}</a-col>
</a-row>
</a-col>
</a-row>
</a-modal>
</template>
<script>
import { validateCheckRule } from '@/utils/util'
export default {
name: 'SysCheckRuleModal',
data() {
return {
title: '',
visible: false,
ruleCode: '',
testValue: '',
form: this.$form.createForm(this),
validatorRules: {
test: {
rules: [{ validator: (rule, value, callback) => validateCheckRule(this.ruleCode, value, callback) }]
}
},
}
},
methods: {
open(ruleCode) {
this.ruleCode = ruleCode
this.form.resetFields()
this.testValue = ''
this.visible = true
},
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,227 @@
<template>
<a-modal
:title="title"
:width="800"
: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 placeholder="请输入数据源名称" v-decorator="['name', validatorRules.name]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="数据源编码">
<a-input placeholder="请输入数据源编码" :disabled="!!model.id" v-decorator="['code', validatorRules.code]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="数据库类型">
<j-dict-select-tag placeholder="请选择数据库类型" dict-code="database_type" triggerChange v-decorator="['dbType', validatorRules.dbType]" @change="handleDbTypeChange"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="驱动类">
<a-input placeholder="请输入驱动类" v-decorator="['dbDriver', validatorRules.dbDriver]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="数据源地址">
<a-input placeholder="请输入数据源地址" v-decorator="['dbUrl', validatorRules.dbUrl]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="数据库名称">
<a-input placeholder="请输入数据库名称" v-decorator="['dbName', validatorRules.dbName]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="用户名">
<a-input placeholder="请输入用户名" v-decorator="['dbUsername', validatorRules.dbUsername]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="密码">
<a-row :gutter="8">
<a-col :span="21">
<a-input-password placeholder="请输入密码" v-decorator="['dbPassword', validatorRules.dbPassword]"/>
</a-col>
<a-col :span="3">
<a-button type="primary" size="small" style="width: 100%" @click="handleTest"></a-button>
</a-col>
</a-row>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
<a-textarea placeholder="请输入备注" v-decorator="['remark', {}]"/>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import pick from 'lodash.pick'
import { httpAction, postAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
export default {
name: 'SysDataSourceModal',
components: {},
data() {
return {
title: '',
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
code: {
validateFirst: true,
rules: [
{ required: true, message: '!' },
{
validator: (rule, value, callback) => {
let pattern = /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/
if (!pattern.test(value)) {
callback('线')
} else {
validateDuplicateValue('sys_data_source', 'code', value, this.model.id, callback)
}
}
}
]
},
name: { rules: [{ required: true, message: '!' }] },
dbType: { rules: [{ required: true, message: '!' }] },
dbDriver: { rules: [{ required: true, message: '!' }] },
dbUrl: { rules: [{ required: true, message: '!' }] },
dbName: { rules: [{ required: true, message: '!' }] },
dbUsername: { rules: [{ required: true, message: '!' }] },
dbPassword: { rules: [{ required: true, message: '!' }] }
},
url: {
add: '/sys/dataSource/add',
edit: '/sys/dataSource/edit',
},
dbDriverMap: {
// MySQL 数据库
'1': { dbDriver: 'com.mysql.jdbc.Driver' },
// Oracle
'2': { dbDriver: 'oracle.jdbc.OracleDriver' },
// SQLServer 数据库
'3': { dbDriver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver' },
}
}
},
created() {
},
methods: {
add() {
this.edit({})
},
edit(record) {
this.form.resetFields()
this.model = Object.assign({}, record)
this.visible = true
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'code', 'name', 'remark', 'dbType', 'dbDriver', 'dbUrl', 'dbName', 'dbUsername', 'dbPassword'))
})
},
close() {
this.$emit('close')
this.visible = false
},
handleOk() {
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
this.confirmLoading = true
let formData = Object.assign(this.model, values)
let httpUrl = this.url.add, method = 'post'
if (this.model.id) {
httpUrl = this.url.edit
method = 'put'
// 由于编码的特殊性,所以不能更改
formData['code'] = undefined
}
httpAction(httpUrl, formData, method).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
}
})
},
handleCancel() {
this.close()
},
// 测试数据源配置是否可以正常连接
handleTest() {
let keys = ['dbType', 'dbDriver', 'dbUrl', 'dbName', 'dbUsername', 'dbPassword']
// 获取以上字段的值,并清除校验状态
let fieldsValues = this.form.getFieldsValue(keys)
let setFields = {}
keys.forEach(key => setFields[key] = { value: fieldsValues[key], errors: null })
// 清除校验状态,目的是可以让错误文字闪烁
this.form.setFields(setFields)
// 重新校验
this.$nextTick(() => {
this.form.validateFields(keys, (errors, values) => {
if (!errors) {
let loading = this.$message.loading('', 0)
postAction('/online/cgreport/api/testConnection', fieldsValues).then(res => {
if (res.success) {
this.$message.success('')
} else throw new Error(res.message)
}).catch(error => {
this.$warning({ title: '', content: error.message || error })
}).finally(() => loading())
}
})
})
},
// 数据库类型更改时,联动更改数据库驱动
handleDbTypeChange(val) {
let dbDriver = this.dbDriverMap[val]
if (dbDriver) {
this.form.setFieldsValue(dbDriver)
}
},
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,162 @@
<template>
<a-modal
:title="title"
:width="800"
: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 placeholder="请输入部门角色名称" v-decorator="['roleName', validatorRules.roleName]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="部门角色编码">
<a-input placeholder="请输入部门角色编码" v-decorator="['roleCode', validatorRules.roleCode]" />
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="描述">
<a-input placeholder="请输入描述" v-decorator="['description', validatorRules.description]" />
</a-form-item>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import {duplicateCheck } from '@/api/api'
export default {
name: "SysDepartRoleModal",
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:{
roleName:{
rules: [
{ required: true, message: '!' },
{ min: 2, max: 30, message: ' 2 30 ', trigger: 'blur' }
]},
roleCode:{
rules: [
{ required: true, message: '!'},
{ min: 0, max: 64, message: ' 64 ', trigger: 'blur' },
{ validator: this.validateRoleCode}
]},
description:{
rules: [
{ min: 0, max: 126, message: ' 126 ', trigger: 'blur' }
]}
},
url: {
add: "/sys/sysDepartRole/add",
edit: "/sys/sysDepartRole/edit",
},
}
},
created () {
},
methods: {
add (departId) {
this.edit({},departId);
},
edit (record,departId) {
this.departId = departId;
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,'roleName','roleCode','description'))
});
},
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.departId = this.departId;
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()
},
validateRoleCode(rule, value, callback){
if(/[\u4E00-\u9FA5]/g.test(value)){
callback("部门角色编码不可输入汉字!");
}else{
var params = {
tableName: "sys_depart_role",
fieldName: "role_code",
fieldVal: value,
dataId: this.model.id,
};
duplicateCheck(params).then((res)=>{
if(res.success){
callback();
}else{
callback(res.message);
}
});
}
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -36,8 +36,8 @@
</a-form-item> </a-form-item>
</template> </template>
<a-form-item label="用户" :labelCol="labelCol" :wrapperCol="wrapperCol" > <a-form-item label="用户名" :labelCol="labelCol" :wrapperCol="wrapperCol" >
<a-input placeholder="请输入用户" v-decorator="[ 'realname', validatorRules.realname]" /> <a-input placeholder="请输入用户名" v-decorator="[ 'realname', validatorRules.realname]" />
</a-form-item> </a-form-item>
<a-form-item label="工号" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form-item label="工号" :labelCol="labelCol" :wrapperCol="wrapperCol">
@ -71,23 +71,33 @@
<a-button slot="enterButton" icon="search"></a-button> <a-button slot="enterButton" icon="search"></a-button>
</a-input-search> </a-input-search>
</a-form-item> </a-form-item>
<a-form-item label="头像" :labelCol="labelCol" :wrapperCol="wrapperCol"> <!-- update--begin--autor:wangshuai-----date:20200108------for------ -->
<a-upload <a-form-item label="身份" :labelCol="labelCol" :wrapperCol="wrapperCol">
listType="picture-card" <a-radio-group
class="avatar-uploader" v-model="identity"
:showUploadList="false" @change="identityChange">
:action="uploadAction" <a-radio value="1"></a-radio>
:data="{'isup':1}" <a-radio value="2"></a-radio>
:headers="headers" </a-radio-group>
:beforeUpload="beforeUpload" </a-form-item>
@change="handleChange" <a-form-item label="负责部门" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="departIdShow==true">
<a-select
mode="multiple"
style="width: 100%"
placeholder="请选择负责部门"
v-model="departIds"
optionFilterProp = "children"
:getPopupContainer = "(target) => target.parentNode"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
> >
<img v-if="picUrl" :src="getAvatarView()" alt="头像" style="height:104px;max-width:300px"/> <a-select-option v-for="item in resultDepartOptions" :key="item.key" :value="item.key"
<div v-else> >{{item.title}}</a-select-option
<a-icon :type="uploadLoading ? 'loading' : 'plus'" /> >
<div class="ant-upload-text"></div> </a-select>
</div> </a-form-item>
</a-upload> <!-- update--end--autor:wangshuai-----date:20200108------for------ -->
<a-form-item label="头像" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-image-upload class="avatar-uploader" text="上传" v-model="fileList" ></j-image-upload>
</a-form-item> </a-form-item>
<a-form-item label="生日" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form-item label="生日" :labelCol="labelCol" :wrapperCol="wrapperCol">
@ -145,10 +155,12 @@
import {addUser,editUser,queryUserRole,queryall } from '@/api/api' import {addUser,editUser,queryUserRole,queryall } from '@/api/api'
import { disabledAuthFilter } from "@/utils/authFilter" import { disabledAuthFilter } from "@/utils/authFilter"
import {duplicateCheck } from '@/api/api' import {duplicateCheck } from '@/api/api'
import JImageUpload from '../../../components/jeecg/JImageUpload'
export default { export default {
name: "UserModal", name: "UserModal",
components: { components: {
JImageUpload,
departWindow, departWindow,
JSelectPosition JSelectPosition
}, },
@ -164,6 +176,7 @@
checkedDepartKeys:[], checkedDepartKeys:[],
checkedDepartNames:[], // 保存部门的名称 =>title checkedDepartNames:[], // 保存部门的名称 =>title
checkedDepartNameString:"", // 保存部门的名称 =>title checkedDepartNameString:"", // 保存部门的名称 =>title
resultDepartOptions:[],
userId:"", //保存用户id userId:"", //保存用户id
disableSubmit:false, disableSubmit:false,
userDepartModel:{userId:'',departIdList:[]}, // 保存SysUserDepart的用户部门中间表数据需要的对象 userDepartModel:{userId:'',departIdList:[]}, // 保存SysUserDepart的用户部门中间表数据需要的对象
@ -213,6 +226,8 @@
] ]
} }
}, },
departIdShow:false,
departIds:[], //负责部门id
title:"操作", title:"操作",
visible: false, visible: false,
model: {}, model: {},
@ -233,11 +248,13 @@
picUrl: "", picUrl: "",
url: { url: {
fileUpload: window._CONFIG['domianURL']+"/sys/common/upload", fileUpload: window._CONFIG['domianURL']+"/sys/common/upload",
imgerver: window._CONFIG['domianURL']+"/sys/common/view", imgerver: window._CONFIG['staticDomainURL'],
userWithDepart: "/sys/user/userDepartList", // 引入为指定用户查看部门信息需要的url userWithDepart: "/sys/user/userDepartList", // 引入为指定用户查看部门信息需要的url
userId:"/sys/user/generateUserId", // 引入生成添加用户情况下的url userId:"/sys/user/generateUserId", // 引入生成添加用户情况下的url
syncUserByUserName:"/process/extActProcess/doSyncUserByUserName",//同步用户到工作流 syncUserByUserName:"/process/extActProcess/doSyncUserByUserName",//同步用户到工作流
}, },
identity:"1",
fileList:[],
} }
}, },
created () { created () {
@ -287,6 +304,9 @@
this.checkedDepartNames=[]; this.checkedDepartNames=[];
this.checkedDepartNameString = ""; this.checkedDepartNameString = "";
this.userId="" this.userId=""
this.resultDepartOptions=[];
this.departId=[];
this.departIdShow=false;
}, },
add () { add () {
this.picUrl = ""; this.picUrl = "";
@ -301,7 +321,9 @@
that.form.resetFields(); that.form.resetFields();
if(record.hasOwnProperty("id")){ if(record.hasOwnProperty("id")){
that.loadUserRoles(record.id); that.loadUserRoles(record.id);
this.picUrl = "Has no pic url yet"; setTimeout(() => {
this.fileList = record.avatar;
}, 5)
} }
that.userId = record.id; that.userId = record.id;
that.visible = true; that.visible = true;
@ -309,6 +331,14 @@
that.$nextTick(() => { that.$nextTick(() => {
that.form.setFieldsValue(pick(this.model,'username','sex','realname','email','phone','activitiSync','workNo','telephone','post')) that.form.setFieldsValue(pick(this.model,'username','sex','realname','email','phone','activitiSync','workNo','telephone','post'))
}); });
//身份为上级显示负责部门,否则不显示
if(this.model.identity=="2"){
this.identity="2";
this.departIdShow=true;
}else{
this.identity="1";
this.departIdShow=false;
}
// 调用查询用户对应的部门信息的方法 // 调用查询用户对应的部门信息的方法
that.checkedDepartKeys = []; that.checkedDepartKeys = [];
that.loadCheckedDeparts(); that.loadCheckedDeparts();
@ -320,10 +350,25 @@
getAction(that.url.userWithDepart,{userId:that.userId}).then((res)=>{ getAction(that.url.userWithDepart,{userId:that.userId}).then((res)=>{
that.checkedDepartNames = []; that.checkedDepartNames = [];
if(res.success){ if(res.success){
var depart=[];
var departId=[];
for (let i = 0; i < res.result.length; i++) { for (let i = 0; i < res.result.length; i++) {
that.checkedDepartNames.push(res.result[i].title); that.checkedDepartNames.push(res.result[i].title);
this.checkedDepartNameString = this.checkedDepartNames.join(","); this.checkedDepartNameString = this.checkedDepartNames.join(",");
that.checkedDepartKeys.push(res.result[i].key); that.checkedDepartKeys.push(res.result[i].key);
//新增负责部门选择下拉框
depart.push({
key:res.result[i].key,
title:res.result[i].title
})
departId.push(res.result[i].key)
}
that.resultDepartOptions=depart;
//判断部门id是否存在不存在择直接默认当前所在部门
if(this.model.departIds){
this.departIds=this.model.departIds.split(",");
}else{
this.departIds=departId;
} }
that.userDepartModel.departIdList = that.checkedDepartKeys that.userDepartModel.departIdList = that.checkedDepartKeys
}else{ }else{
@ -341,6 +386,11 @@
this.checkedDepartNameString=''; this.checkedDepartNameString='';
this.checkedDepartKeys = []; this.checkedDepartKeys = [];
this.selectedDepartKeys = []; this.selectedDepartKeys = [];
this.resultDepartOptions=[];
this.departIds=[];
this.departIdShow=false;
this.identity="1";
this.fileList=[];
}, },
moment, moment,
handleSubmit () { handleSubmit () {
@ -350,17 +400,22 @@
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
if (!err) { if (!err) {
that.confirmLoading = true; that.confirmLoading = true;
let avatar = that.model.avatar;
if(!values.birthday){ if(!values.birthday){
values.birthday = ''; values.birthday = '';
}else{ }else{
values.birthday = values.birthday.format(this.dateFormat); values.birthday = values.birthday.format(this.dateFormat);
} }
let formData = Object.assign(this.model, values); let formData = Object.assign(this.model, values);
formData.avatar = avatar; formData.avatar = that.fileList;
formData.selectedroles = this.selectedRole.length>0?this.selectedRole.join(","):''; formData.selectedroles = this.selectedRole.length>0?this.selectedRole.join(","):'';
formData.selecteddeparts = this.userDepartModel.departIdList.length>0?this.userDepartModel.departIdList.join(","):''; formData.selecteddeparts = this.userDepartModel.departIdList.length>0?this.userDepartModel.departIdList.join(","):'';
formData.identity=this.identity;
//如果是上级择传入departIds,否则为空
if(this.identity==="2"){
formData.departIds=this.departIds.join(",");
}else{
formData.departIds="";
}
// that.addDepartsToUser(that,formData); // 调用根据当前用户添加部门信息的方法 // that.addDepartsToUser(that,formData); // 调用根据当前用户添加部门信息的方法
let obj; let obj;
if(!this.model.id){ if(!this.model.id){
@ -380,7 +435,6 @@
that.confirmLoading = false; that.confirmLoading = false;
that.checkedDepartNames = []; that.checkedDepartNames = [];
that.userDepartModel.departIdList = {userId:'',departIdList:[]}; that.userDepartModel.departIdList = {userId:'',departIdList:[]};
that.close(); that.close();
}) })
@ -528,9 +582,6 @@
} }
} }
}, },
getAvatarView(){
return this.url.imgerver +"/"+ this.model.avatar;
},
// 搜索用户对应的部门API // 搜索用户对应的部门API
onSearch(){ onSearch(){
this.$refs.departWindow.add(this.checkedDepartKeys,this.userId); this.$refs.departWindow.add(this.checkedDepartKeys,this.userId);
@ -543,11 +594,21 @@
this.checkedDepartNameString = ''; this.checkedDepartNameString = '';
this.userId = formData.userId; this.userId = formData.userId;
this.userDepartModel.userId = formData.userId; this.userDepartModel.userId = formData.userId;
this.departIds=[];
this.resultDepartOptions=[];
var depart=[];
for (let i = 0; i < formData.departIdList.length; i++) { for (let i = 0; i < formData.departIdList.length; i++) {
this.selectedDepartKeys.push(formData.departIdList[i].key); this.selectedDepartKeys.push(formData.departIdList[i].key);
this.checkedDepartNames.push(formData.departIdList[i].title); this.checkedDepartNames.push(formData.departIdList[i].title);
this.checkedDepartNameString = this.checkedDepartNames.join(","); this.checkedDepartNameString = this.checkedDepartNames.join(",");
//新增部门选择,如果上面部门选择后不为空直接付给负责部门
depart.push({
key:formData.departIdList[i].key,
title:formData.departIdList[i].title
})
this.departIds.push(formData.departIdList[i].key)
} }
this.resultDepartOptions=depart;
this.userDepartModel.departIdList = this.selectedDepartKeys; this.userDepartModel.departIdList = this.selectedDepartKeys;
this.checkedDepartKeys = this.selectedDepartKeys //更新当前的选择keys this.checkedDepartKeys = this.selectedDepartKeys //更新当前的选择keys
}, },
@ -560,6 +621,13 @@
this.drawerWidth = 700; this.drawerWidth = 700;
} }
}, },
identityChange(e){
if(e.target.value==="1"){
this.departIdShow=false;
}else{
this.departIdShow=true;
}
}
} }
} }
</script> </script>

View File

@ -0,0 +1,191 @@
<template>
<a-modal
:width="1000"
:title="title"
:visible="innerVisible"
@cancel="handleCancel"
cancelText="关闭"
:okButtonProps="{style:{display:'none'}}"
>
<a-alert type="info" showIcon style="margin-bottom: 16px;">
<template slot="message">
<span></span>
<a style="font-weight: 600;padding: 0 4px;">{{ selectedRowKeys.length }}</a>
<span></span>
<template v-if="selectedRowKeys.length>0">
<a-divider type="vertical"/>
<a @click="handleClearSelection"></a>
<a-divider type="vertical"/>
<a @click="handleRevertBatch"></a>
<a-divider type="vertical"/>
<a @click="handleDeleteBatch"></a>
</template>
</template>
</a-alert>
<a-table
ref="table"
rowKey="id"
size="middle"
bordered
:columns="columns"
:loading="loading"
:dataSource="dataSource"
:pagination="false"
:rowSelection="{selectedRowKeys, onChange: handleTableSelectChange}"
>
<!-- -->
<template slot="avatarslot" slot-scope="text, record, index">
<div class="anty-img-wrap">
<a-avatar shape="square" :src="url.getAvatar(record.avatar)" icon="user"/>
</div>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleRevert([record.id])"><a-icon type="redo"/> </a>
<a-divider type="vertical"/>
<a @click="handleDelete([record.id])"><a-icon type="delete"/> </a>
</span>
</a-table>
</a-modal>
</template>
<script>
// 高度封装的请求,请务必使用 superRequest.call(this,{}) 的方式调用
function superRequest(options) {
this.loading = !!options.loading
options.promise.then(res => {
if (res.success && typeof options.success === 'function') {
options.success(res)
} else {
throw new Error(res.message)
}
}).catch(e => {
console.error('', e)
this.$message.warning('' + (e.message || e))
}).finally(() => {
this.loading = false
})
}
export default {
name: 'UserRecycleBinModal',
props: {
visible: {
type: Boolean,
default: false
},
},
data() {
return {
title: '',
loading: false,
innerVisible: false,
selectedRowKeys: [],
dataSource: [],
columns: [
{ title: '#', align: 'center', key: 'rowIndex', width: 80, customRender: (t, r, i) => i + 1 },
{ title: '', align: 'center', dataIndex: 'username' },
{ title: '', align: 'center', dataIndex: 'realname', },
{ title: '', align: 'center', dataIndex: 'avatar', scopedSlots: { customRender: 'avatarslot' } },
{ title: '', align: 'center', dataIndex: 'orgCode' },
{ title: '', align: 'center', dataIndex: 'action', width: 200, scopedSlots: { customRender: 'action' } }
],
url: {
getAvatar: (path) => `window._CONFIG['staticDomainURL']/${path}`,
// 回收站操作get = 获取列表put = 取回delete = 彻底删除
recycleBin: '/sys/user/recycleBin',
},
}
},
watch: {
visible: {
immediate: true,
handler(val) {
if (val) {
this.loadData()
}
this.innerVisible = val
}
},
innerVisible(val) {
this.$emit('update:visible', val)
},
},
methods: {
loadData() {
superRequest.call(this, {
loading: true,
promise: this.$http.get(this.url.recycleBin),
success: res => this.dataSource = res.result
})
},
handleOk() {
this.loadData()
this.$emit('ok')
},
handleCancel() {
this.innerVisible = false
},
// 还原用户
handleRevert(userIds) {
this.$confirm({
title: '',
content: ` ${userIds.length} `,
centered: true,
onOk: () => {
superRequest.call(this, {
loading: true,
promise: this.$http.put(this.url.recycleBin, userIds),
success: () => {
this.handleOk()
this.handleClearSelection()
this.$message.success(` ${userIds.length} `)
}
})
}
})
},
// 彻底删除用户
handleDelete(userIds) {
this.$confirm({
title: '',
content: (<div>
<p> {userIds.length} </p>
<p style="color:red;"></p>
</div>),
centered: true,
onOk: () => {
superRequest.call(this, {
loading: true,
promise: this.$http.delete(this.url.recycleBin + `?userIds=${userIds.join(',')}`),
success: () => {
this.loadData()
this.handleClearSelection()
this.$message.success(` ${userIds.length} `)
}
})
},
})
},
handleRevertBatch() {
this.handleRevert(this.selectedRowKeys)
},
handleDeleteBatch() {
this.handleDelete(this.selectedRowKeys)
},
handleClearSelection() {
this.handleTableSelectChange([], [])
},
handleTableSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys
this.selectionRows = selectionRows
},
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -45,7 +45,8 @@
<a-popconfirm title="确定放弃编辑?" @confirm="close" okText="确定" cancelText="取消"> <a-popconfirm title="确定放弃编辑?" @confirm="close" okText="确定" cancelText="取消">
<a-button style="margin-right: .8rem"></a-button> <a-button style="margin-right: .8rem"></a-button>
</a-popconfirm> </a-popconfirm>
<a-button @click="handleSubmit" type="primary" :loading="loading"></a-button> <a-button @click="handleSubmit(false)" type="primary" :loading="loading" ghost style="margin-right: 0.8rem"></a-button>
<a-button @click="handleSubmit(true)" type="primary" :loading="loading"></a-button>
</div> </div>
<role-datarule-modal ref="datarule"></role-datarule-modal> <role-datarule-modal ref="datarule"></role-datarule-modal>
@ -134,7 +135,7 @@
handleCancel () { handleCancel () {
this.close() this.close()
}, },
handleSubmit(){ handleSubmit(exit) {
let that = this; let that = this;
let params = { let params = {
roleId:that.roleId, roleId:that.roleId,
@ -147,18 +148,20 @@
if(res.success){ if(res.success){
that.$message.success(res.message); that.$message.success(res.message);
that.loading = false; that.loading = false;
that.close(); if (exit) {
that.close()
}
}else { }else {
that.$message.error(res.message); that.$message.error(res.message);
that.loading = false; that.loading = false;
that.close(); if (exit) {
that.close()
}
} }
this.loadData();
}) })
}, },
}, loadData(){
watch: {
visible () {
if (this.visible) {
queryTreeListForRole().then((res) => { queryTreeListForRole().then((res) => {
this.treeData = res.result.treeList this.treeData = res.result.treeList
this.allTreeKeys = res.result.ids this.allTreeKeys = res.result.ids
@ -170,6 +173,12 @@
}) })
}) })
} }
},
watch: {
visible () {
if (this.visible) {
this.loadData();
}
} }
} }
} }

View File

@ -1,13 +1,13 @@
<template> <template>
<a-card :bordered="false" style="width: 160%;text-align: center;margin-left:-25%"> <a-card :bordered="false" style="width: 130%;text-align: center;margin-left:-10%">
<a-steps class="steps" :current="currentTab"> <a-steps class="steps" :current="currentTab">
<a-step title="账户信息" /> <a-step title="用户账户"/>
<a-step title="身份验证" /> <a-step title="手机验证"/>
<a-step title="更改密码" /> <a-step title="密码"/>
<a-step title="完成" /> <a-step title="完成"/>
</a-steps> </a-steps>
<div class="content"> <div class="content">
<step1 v-if="currentTab === 0" @nextStep="nextStep" /> <step1 v-if="currentTab === 0" @nextStep="nextStep"/>
<step2 v-if="currentTab === 1" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/> <step2 v-if="currentTab === 1" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/>
<step3 v-if="currentTab === 2" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/> <step3 v-if="currentTab === 2" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/>
<step4 v-if="currentTab === 3" @prevStep="prevStep" @finish="finish" :userList="userList"/> <step4 v-if="currentTab === 3" @prevStep="prevStep" @finish="finish" :userList="userList"/>
@ -20,6 +20,7 @@
import Step2 from './Step2' import Step2 from './Step2'
import Step3 from './Step3' import Step3 from './Step3'
import Step4 from './Step4' import Step4 from './Step4'
export default { export default {
name: "Alteration", name: "Alteration",
components: { components: {
@ -28,11 +29,11 @@
Step3, Step3,
Step4 Step4
}, },
data () { data() {
return { return {
description: '', description: '',
currentTab: 0, currentTab: 0,
userList:{}, userList: {},
// form // form
form: null, form: null,
} }
@ -40,19 +41,19 @@
methods: { methods: {
// handler // handler
nextStep (data) { nextStep(data) {
this.userList=data; this.userList = data;
if (this.currentTab < 4) { if (this.currentTab < 4) {
this.currentTab += 1 this.currentTab += 1
} }
}, },
prevStep (data) { prevStep(data) {
this.userList=data; this.userList = data;
if (this.currentTab > 0) { if (this.currentTab > 0) {
this.currentTab -= 1 this.currentTab -= 1
} }
}, },
finish () { finish() {
this.currentTab = 0 this.currentTab = 0
} }
} }

View File

@ -9,7 +9,7 @@
<a-form-item> <a-form-item>
<a-input <a-input
size="large" size="large"
v-decorator="['username',validatorRules.username,{ validator: this.handleUsernameOrEmail }]" v-decorator="['username',{initialValue:'admin', rules: validatorRules.username.rules}]"
type="text" type="text"
placeholder="请输入帐户名 / jeecg"> placeholder="请输入帐户名 / jeecg">
<a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/> <a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/>
@ -18,7 +18,7 @@
<a-form-item> <a-form-item>
<a-input <a-input
v-decorator="['password',validatorRules.password]" v-decorator="['password',{initialValue:'123456', rules: validatorRules.password.rules}]"
size="large" size="large"
type="password" type="password"
autocomplete="false" autocomplete="false"
@ -28,7 +28,7 @@
</a-form-item> </a-form-item>
<a-row :gutter="0"> <a-row :gutter="0">
<a-col :span="14"> <a-col :span="16">
<a-form-item> <a-form-item>
<a-input <a-input
v-decorator="['inputCode',validatorRules.inputCode]" v-decorator="['inputCode',validatorRules.inputCode]"
@ -36,13 +36,13 @@
type="text" type="text"
@change="inputCodeChange" @change="inputCodeChange"
placeholder="请输入验证码"> placeholder="请输入验证码">
<a-icon slot="prefix" v-if=" inputCodeContent==verifiedCode " type="smile" :style="{ color: 'rgba(0,0,0,.25)' }"/> <a-icon slot="prefix" type="smile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
<a-icon slot="prefix" v-else type="frown" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input> </a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="10"> <a-col :span="8" style="text-align: right">
<j-graphic-code @success="generateCode" ref="jgraphicCodeRef" style="float: right" remote></j-graphic-code> <img style="margin-top: 2px;" :src="randCodeImage" @click="handleChangeCheckCode"/>
<!--<j-graphic-code @success="generateCode" ref="jgraphicCodeRef" style="float: right" remote></j-graphic-code>-->
</a-col> </a-col>
</a-row> </a-row>
@ -88,7 +88,7 @@
<router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;"> <router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">
</router-link> </router-link>
<router-link :to="{ name: 'register'}" class="forge-password" style="float: right;margin-right: 10px" > <router-link :to="{ name: 'register'}" class="forge-password" style="float: right;margin-right: 10px" >
</router-link> </router-link>
</a-form-item> </a-form-item>
@ -173,8 +173,7 @@
import Vue from 'vue' import Vue from 'vue'
import { ACCESS_TOKEN ,ENCRYPTED_STRING} from "@/store/mutation-types" import { ACCESS_TOKEN ,ENCRYPTED_STRING} from "@/store/mutation-types"
import JGraphicCode from '@/components/jeecg/JGraphicCode' import JGraphicCode from '@/components/jeecg/JGraphicCode'
import { putAction } from '@/api/manage' import { putAction,postAction,getAction } from '@/api/manage'
import { postAction } from '@/api/manage'
import { encryption , getEncryptedString } from '@/utils/encryption/aesEncrypt' import { encryption , getEncryptedString } from '@/utils/encryption/aesEncrypt'
import store from '@/store/' import store from '@/store/'
import { USER_INFO } from "@/store/mutation-types" import { USER_INFO } from "@/store/mutation-types"
@ -202,11 +201,11 @@
smsSendBtn: false, smsSendBtn: false,
}, },
validatorRules:{ validatorRules:{
username:{rules: [{ required: true, message: '!',validator: 'click'}]}, username:{rules: [{ required: true, message: '!'},{validator: this.handleUsernameOrEmail}]},
password:{rules: [{ required: true, message: '!',validator: 'click'}]}, password:{rules: [{ required: true, message: '!',validator: 'click'}]},
mobile:{rules: [{validator:this.validateMobile}]}, mobile:{rules: [{validator:this.validateMobile}]},
captcha:{rule: [{ required: true, message: '!'}]}, captcha:{rule: [{ required: true, message: '!'}]},
inputCode:{rules: [{ required: true, message: '!'},{validator: this.validateInputCode}]} inputCode:{rules: [{ required: true, message: '!'}]}
}, },
verifiedCode:"", verifiedCode:"",
inputCodeContent:"", inputCodeContent:"",
@ -216,12 +215,16 @@
departVisible:false, departVisible:false,
departSelected:"", departSelected:"",
currentUsername:"", currentUsername:"",
validate_status:"" validate_status:"",
currdatetime:'',
randCodeImage:''
} }
}, },
created () { created () {
this.currdatetime = new Date().getTime();
Vue.ls.remove(ACCESS_TOKEN) Vue.ls.remove(ACCESS_TOKEN)
this.getRouterData(); this.getRouterData();
this.handleChangeCheckCode();
// update-begin- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题 // update-begin- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题
//this.getEncrypte(); //this.getEncrypte();
// update-end- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题 // update-end- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题
@ -257,10 +260,9 @@
loginParams.password = values.password loginParams.password = values.password
loginParams.remember_me = values.rememberMe loginParams.remember_me = values.rememberMe
// update-begin- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题 // update-begin- --- author:scott ------ date:20190805 ---- for:密码加密逻辑暂时注释掉,有点问题
let checkParams = this.$refs.jgraphicCodeRef.getLoginParam() loginParams.captcha = that.inputCodeContent
loginParams.captcha = checkParams.checkCode loginParams.checkKey = that.currdatetime
loginParams.checkKey = checkParams.checkKey console.log("登录参数",loginParams)
that.Login(loginParams).then((res) => { that.Login(loginParams).then((res) => {
this.departConfirm(res) this.departConfirm(res)
}).catch((err) => { }).catch((err) => {
@ -339,6 +341,16 @@
this.stepCaptchaVisible = false this.stepCaptchaVisible = false
}) })
}, },
handleChangeCheckCode(){
this.currdatetime = new Date().getTime();
getAction(`/sys/randomImage/${this.currdatetime}`).then(res=>{
if(res.success){
this.randCodeImage = res.result
}else{
this.$message.error(res.message)
}
})
},
loginSuccess () { loginSuccess () {
// update-begin- author:sunjianlei --- date:20190812 --- for: 登录成功后不解除禁用按钮,防止多次点击 // update-begin- author:sunjianlei --- date:20190812 --- for: 登录成功后不解除禁用按钮,防止多次点击
// this.loginBtn = false // this.loginBtn = false
@ -384,12 +396,6 @@
}, },
inputCodeChange(e){ inputCodeChange(e){
this.inputCodeContent = e.target.value this.inputCodeContent = e.target.value
if(!e.target.value||0==e.target.value){
this.inputCodeNull=true
}else{
this.inputCodeContent = this.inputCodeContent.toLowerCase()
this.inputCodeNull=false
}
}, },
departConfirm(res){ departConfirm(res){
if(res.success){ if(res.success){
@ -452,10 +458,12 @@
}, },
getRouterData(){ getRouterData(){
this.$nextTick(() => { this.$nextTick(() => {
this.form.setFieldsValue({ if (this.$route.params.username) {
'username': this.$route.params.username this.form.setFieldsValue({
}); 'username': this.$route.params.username
}) });
}
})
}, },
//获取密码加密规则 //获取密码加密规则
getEncrypte(){ getEncrypte(){

View File

@ -26,7 +26,7 @@
}, },
computed: { computed: {
email () { email () {
let v = this.form && this.form.username || 'xxx' let v = this.form ? this.form.username || this.form.mobile : ' XXX '
let title = `${v} ` let title = `${v} `
this.username = v; this.username = v;
return title return title

View File

@ -1,14 +1,14 @@
<template> <template>
<div class="main"> <div class="main">
<a-form style="max-width: 500px; margin: 40px auto 0;" :form="form"> <a-form style="max-width: 500px; margin: 40px auto 0;" :form="form" @keyup.enter.native="nextStep">
<a-form-item> <a-form-item>
<a-input <a-input
v-decorator="['username',validatorRules.username]" v-decorator="['username',validatorRules.username]"
size="large" size="large"
type="text" type="text"
autocomplete="false" autocomplete="false"
placeholder="请输入用户或手机号"> placeholder="请输入用户账号或手机号">
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/> <a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input> </a-input>
</a-form-item> </a-form-item>
@ -32,6 +32,7 @@
</a-col> </a-col>
</a-row> </a-row>
<a-form-item :wrapperCol="{span: 19, offset: 5}"> <a-form-item :wrapperCol="{span: 19, offset: 5}">
<router-link style="float: left;line-height: 40px;" :to="{ name: 'login' }">使</router-link>
<a-button type="primary" @click="nextStep"></a-button> <a-button type="primary" @click="nextStep"></a-button>
</a-form-item> </a-form-item>
</a-form> </a-form>
@ -40,95 +41,99 @@
<script> <script>
import JGraphicCode from '@/components/jeecg/JGraphicCode' import JGraphicCode from '@/components/jeecg/JGraphicCode'
import { getAction } from '@/api/manage' import {getAction} from '@/api/manage'
import {checkOnlyUser } from '@/api/api' import {checkOnlyUser} from '@/api/api'
export default { export default {
name: "Step1", name: "Step1",
components: { components: {
JGraphicCode JGraphicCode
}, },
data () { data() {
return { return {
form: this.$form.createForm(this), form: this.$form.createForm(this),
inputCodeContent: "", inputCodeContent: "",
inputCodeNull:true, inputCodeNull: true,
verifiedCode:"", verifiedCode: "",
validatorRules: { validatorRules: {
username:{rules: [{ required: false},{validator: this.validateInputUsername}]}, username: {rules: [{required: false}, {validator: this.validateInputUsername}]},
inputCode:{rules: [{ required: true, message: '!'},{validator: this.validateInputCode}]}, inputCode: {rules: [{required: true, message: '!'}, {validator: this.validateInputCode}]},
}, },
} }
}, },
methods: { methods: {
nextStep () { nextStep() {
let that = this let that = this
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
if (!err){ if (!err) {
var params={} let isPhone = false;
var reg=/^[1-9]\d*$|^0$/; var params = {}
var username=values.username; var reg = /^[1-9]\d*$|^0$/;
if(reg.test(username)==true) { var username = values.username;
params.phone=username; if (reg.test(username) == true) {
}else{ params.phone = username;
params.username=username; isPhone = true
} else {
params.username = username;
}
getAction("/sys/user/querySysUser", params).then((res) => {
if (res.success) {
var userList = {
username: res.result.username,
phone: res.result.phone,
isPhone: isPhone
};
setTimeout(function () {
that.$emit('nextStep', userList)
})
}
});
} }
getAction("/sys/user/querySysUser",params).then((res)=>{ })
if(res.success){
var userList={
username:res.result.username,
phone:res.result.phone
};
setTimeout(function () {
that.$emit('nextStep',userList)
})
}
});
}
})
}, },
validateInputCode(rule, value, callback){ validateInputCode(rule, value, callback) {
if (!value || this.verifiedCode == this.inputCodeContent) { if (!value || this.verifiedCode == this.inputCodeContent) {
callback(); callback();
} else { } else {
callback(new Error("您输入的验证码不正确!")); callback(new Error("您输入的验证码不正确!"));
} }
}, },
inputCodeChange(e){ inputCodeChange(e) {
this.inputCodeContent = e.target.value; this.inputCodeContent = e.target.value;
console.log(this.inputCodeContent) console.log(this.inputCodeContent)
if(!e.target.value||0==e.target.value){ if (!e.target.value || 0 == e.target.value) {
this.inputCodeNull=true this.inputCodeNull = true
}else{ } else {
this.inputCodeContent = this.inputCodeContent.toLowerCase() this.inputCodeContent = this.inputCodeContent.toLowerCase()
this.inputCodeNull=false this.inputCodeNull = false
} }
}, },
generateCode(value){ generateCode(value) {
this.verifiedCode = value.toLowerCase(); this.verifiedCode = value.toLowerCase();
console.log(this.verifiedCode); console.log(this.verifiedCode);
}, },
validateInputUsername(rule, value, callback){ validateInputUsername(rule, value, callback) {
console.log(value); console.log(value);
var reg=/^[0-9]+.?[0-9]*/; var reg = /^[0-9]+.?[0-9]*/;
if(!value){ if (!value) {
callback("请输入用户名和手机号!"); callback("请输入用户名和手机号!");
} }
//判断用户输入账号还是手机号码 //判断用户输入账号还是手机号码
if(reg.test(value)){ if (reg.test(value)) {
var params = { var params = {
phone : value, phone: value,
}; };
checkOnlyUser(params).then((res) => { checkOnlyUser(params).then((res) => {
if (res.success) { if (res.success) {
callback("用户名不存在!") callback("用户名不存在!")
} else { } else {
callback() callback()
} }
}) })
}else{ } else {
var params = { var params = {
username: value, username: value,
}; };

View File

@ -1,80 +1,79 @@
<template> <template>
<div> <div>
<a-form :form="form" style="max-width: 500px; margin: 40px auto 0;"> <a-form :form="form" style="max-width: 500px; margin: 40px auto 0;" @keyup.enter.native="nextStep">
<a-form-item <a-form-item
label="账号名" label="账号名"
:labelCol="{span: 5}" :labelCol="{span: 5}"
:wrapperCol="{span: 19}" :wrapperCol="{span: 19}"
> >
<a-input <a-input
type="text" type="text"
autocomplete="false" autocomplete="false"
:style="{width:'310px'}" :style="{width:'310px'}"
:value="accountName" :value="accountName"
disabled> disabled>
</a-input> </a-input>
</a-form-item> </a-form-item>
<a-form-item <a-form-item
label="手机" label="手机"
:labelCol="{span: 5}" :labelCol="{span: 5}"
:wrapperCol="{span: 19}" :wrapperCol="{span: 19}"
> >
<a-input <a-input
type="text" type="text"
autocomplete="false" autocomplete="false"
:style="{width:'310px'}" :style="{width:'310px'}"
placeholder="请输入手机号" v-decorator="['phone',{initialValue: defaultPhone, rules: validatorRules.phone.rule}]"
:value="phone" placeholder="请输入手机号">
disabled> <a-icon slot="prefix" type="phone" :style="{ color: 'rgba(0,0,0,.25)'}"/>
<a-icon slot="prefix" type="phone" :style="{ color: 'rgba(0,0,0,.25)'}" /> </a-input>
</a-input> </a-form-item>
</a-form-item>
<a-form-item <a-form-item
label="验证码" label="验证码"
:labelCol="{span: 5}" :labelCol="{span: 5}"
:wrapperCol="{span: 19}" :wrapperCol="{span: 19}"
v-if="show"> v-if="show">
<a-row :gutter="16" style="margin-left: 35px"> <a-row :gutter="16" style="margin-left: 2px">
<a-col class="gutter-row" :span="10"> <a-col class="gutter-row" :span="12">
<a-input <a-input
v-decorator="['captcha',validatorRules.captcha]" v-decorator="['captcha',validatorRules.captcha]"
type="text" type="text"
placeholder="手机短信验证码" > placeholder="手机短信验证码">
</a-input> </a-input>
</a-col> </a-col>
<a-col class="gutter-row" :span="8" > <a-col class="gutter-row" :span="8">
<a-button <a-button
tabindex="-1" tabindex="-1"
size="default" size="default"
:disabled="state.smsSendBtn" :disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha" @click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码' || (state.time+' s')"></a-button> v-text="!state.smsSendBtn && '获取验证码' || (state.time+' s')"></a-button>
</a-col> </a-col>
</a-row> </a-row>
</a-form-item> </a-form-item>
<a-form-item :wrapperCol="{span: 19, offset: 5}"> <a-form-item :wrapperCol="{span: 19, offset: 5}">
<a-button style="margin-left: 8px" @click="prevStep"></a-button> <a-button style="margin-left: 8px" @click="prevStep"></a-button>
<a-button type="primary" @click="nextStep" style="margin-left: 20px"></a-button> <a-button type="primary" @click="nextStep" style="margin-left: 20px"></a-button>
</a-form-item> </a-form-item>
</a-form> </a-form>
</div> </div>
</template> </template>
<script> <script>
import { postAction } from '@/api/manage' import {postAction} from '@/api/manage'
export default { export default {
name: "Step2", name: "Step2",
props:['userList'], props: ['userList'],
data () { data() {
return { return {
form: this.$form.createForm(this), form: this.$form.createForm(this),
loading: false, loading: false,
accountName:this.userList.username, accountName: this.userList.username,
phone:this.userList.phone, dropList: "0",
dropList:"0",
captcha: "", captcha: "",
show:true, show: true,
state: { state: {
time: 60, time: 60,
smsSendBtn: false, smsSendBtn: false,
@ -83,58 +82,66 @@
captcha: "", captcha: "",
mobile: "", mobile: "",
}, },
validatorRules:{ validatorRules: {
captcha:{rule: [{ required: true, message: '!'},{validator:this.validateCaptcha}]}, captcha: {rule: [{required: true, message: '!'}, {validator: this.validateCaptcha}]},
phone: {rule: [{required: true, message: '!'}]},
}, },
} }
}, },
computed: {
defaultPhone: function(){
if(this.userList.isPhone){
return this.userList.phone
}
return null;
}
},
methods: { methods: {
nextStep () { nextStep() {
let that = this let that = this
that.loading = true that.loading = true
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
console.log(values); console.log(values);
if (!err) { if (!err) {
if(that.dropList=="0"){ if (that.dropList == "0") {
if(values.captcha==undefined){ if (values.captcha == undefined) {
this.cmsFailed("请输入短信验证码!"); this.cmsFailed("请输入短信验证码!");
}else{ } else {
var params={} var params = {}
params.phone=this.userList.phone; params.phone = this.userList.phone;
params.smscode=values.captcha; params.smscode = values.captcha;
postAction("/sys/user/phoneVerification",params).then((res)=>{ postAction("/sys/user/phoneVerification", params).then((res) => {
if(res.success){ if (res.success) {
console.log(res); console.log(res);
var userList={ var userList = {
username:this.userList.username, username: this.userList.username,
phone:this.userList.phone, phone: this.userList.phone,
smscode:res.result smscode: res.result
}; };
setTimeout(function () { setTimeout(function () {
that.$emit('nextStep',userList) that.$emit('nextStep', userList)
},0) }, 0)
}else{ } else {
this.cmsFailed(res.message); this.cmsFailed(res.message);
} }
}) })
} }
} }
}
} })
})
}, },
prevStep () { prevStep() {
this.$emit('prevStep',this.userList); this.$emit('prevStep', this.userList);
}, },
getCaptcha (e) { getCaptcha(e) {
e.preventDefault(); e.preventDefault();
let that = this; let that = this;
this.state.smsSendBtn = true; this.state.smsSendBtn = true;
let interval = window.setInterval(() => { let interval = window.setInterval(() => {
if (that.state.time-- <= 0) { if (that.state.time-- <= 0) {
that.state.time = 60; that.state.time = 60;
that.state.smsSendBtn = false; that.state.smsSendBtn = false;
window.clearInterval(interval); window.clearInterval(interval);
@ -147,30 +154,30 @@
smsmode: "2" smsmode: "2"
}; };
postAction("/sys/sms", smsParams).then(res => { postAction("/sys/sms", smsParams).then(res => {
if(!res.success ){ if (!res.success) {
setTimeout(hide, 1); setTimeout(hide, 1);
this.cmsFailed(res.message); this.cmsFailed(res.message);
} }
setTimeout(hide, 500); setTimeout(hide, 500);
}) })
}, },
cmsFailed(err){ cmsFailed(err) {
this.$notification[ 'error' ]({ this.$notification['error']({
message: "验证错误", message: "验证错误",
description:err, description: err,
duration: 4, duration: 4,
}); });
}, },
handleChangeSelect(value){ handleChangeSelect(value) {
var that=this; var that = this;
console.log(value); console.log(value);
if(value==0){ if (value == 0) {
that.dropList="0"; that.dropList = "0";
that.show=true; that.show = true;
}else{ } else {
that.dropList="1"; that.dropList = "1";
that.show=false; that.show = false;
} }
}, },
} }
@ -181,10 +188,11 @@
.stepFormText { .stepFormText {
margin-bottom: 24px; margin-bottom: 24px;
} }
.ant-form-item-label,
.ant-form-item-control { .ant-form-item-label,
line-height: 22px; .ant-form-item-control {
} line-height: 22px;
}
.getCaptcha { .getCaptcha {
display: block; display: block;

View File

@ -30,7 +30,6 @@ module.exports = {
.set('@comp', resolve('src/components')) .set('@comp', resolve('src/components'))
.set('@views', resolve('src/views')) .set('@views', resolve('src/views'))
.set('@layout', resolve('src/layout')) .set('@layout', resolve('src/layout'))
.set('@static', resolve('src/static'))
}, },
css: { css: {

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@ RUN cd /etc/yum.repos.d/ \
# 前端迁移到系统文件中 默认是80端口 同级目录下的html地址 # 前端迁移到系统文件中 默认是80端口 同级目录下的html地址
ADD ant-design-vue-jeecg/dist/ /var/www/html/ ADD ant-design-vue-jeecg/dist/ /var/www/html/
# 拷贝相关的jar包 # 拷贝相关的jar包
ADD jeecg-boot/jeecg-boot-module-system/target/jeecg-boot-module-system-2.1.1.jar jeecgboot.jar ADD jeecg-boot/jeecg-boot-module-system/target/jeecg-boot-module-system-2.1.4.jar jeecgboot.jar
EXPOSE 80 8080 81 EXPOSE 80 8080 81
ENTRYPOINT /bin/sh -c /etc/init.d/start.sh ENTRYPOINT /bin/sh -c /etc/init.d/start.sh

View File

@ -1,7 +1,7 @@
Jeecg-Boot 快速开发平台 Jeecg-Boot 快速开发平台
=============== ===============
当前最新版本: 2.1.3发布日期20191226 当前最新版本: 2.1.4发布日期20200224
## 后端技术架构 ## 后端技术架构
@ -37,11 +37,11 @@ Jeecg-Boot 快速开发平台
## 技术文档 ## 技术文档
- 在线演示 [http://boot.jeecg.org](http://boot.jeecg.org) - 在线演示 [http://boot.jeecg.com](http://boot.jeecg.com)
- 在线文档: [http://doc.jeecg.com/1273753](http://doc.jeecg.com/1273753) - 在线文档: [http://doc.jeecg.com/1273753](http://doc.jeecg.com/1273753)
- 常见问题: [入门常见问题大全](http://www.jeecg.org/forum.php?mod=viewthread&tid=7816&extra=page%3D1) - 常见问题: [入门常见问题大全](http://bbs.jeecg.com/forum.php?mod=viewthread&tid=7816&extra=page%3D1)
- QQ交流群 ①284271917、②769925425 - QQ交流群 ①284271917、②769925425

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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