JeecgBoot 2.4.6版本发布

This commit is contained in:
zhangdaiscott
2021-08-13 15:26:20 +08:00
parent 1e1cee2f4b
commit 275290c6ec
57 changed files with 1306 additions and 329 deletions

View File

@ -1,9 +1,9 @@
<template>
<div class="components-input-demo-presuffix">
<!---->
<a-input @click="openModal" placeholder="请点击选择部门" v-model="departNames" readOnly :disabled="disabled">
<a-input @click="openModal" placeholder="请点击选择部门" v-model="textVals" readOnly :disabled="disabled">
<a-icon slot="prefix" type="cluster" title="部门选择控件"/>
<a-icon v-if="departIds" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
<a-icon v-if="storeVals" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
</a-input>
<j-select-depart-modal
@ -11,7 +11,10 @@
:modal-width="modalWidth"
:multi="multi"
:rootOpened="rootOpened"
:depart-id="departIds"
:depart-id="value"
:store="storeField"
:text="textField"
:treeOpera="treeOpera"
@ok="handleOK"
@initComp="initComp"/>
</div>
@ -19,6 +22,7 @@
<script>
import JSelectDepartModal from './modal/JSelectDepartModal'
import { underLinetoHump } from '@/components/_util/StringUtil'
export default {
name: 'JSelectDepart',
components:{
@ -52,56 +56,70 @@
// 自定义返回字段,默认返回 id
customReturnField: {
type: String,
default: 'id'
default: ''
},
backDepart: {
type: Boolean,
default: false,
required: false
},
// 存储字段 [key field]
store: {
type: String,
default: 'id',
required: false
},
// 显示字段 [label field]
text: {
type: String,
default: 'departName',
required: false
},
treeOpera: {
type: Boolean,
default: false,
required: false
}
},
data(){
return {
visible:false,
confirmLoading:false,
departNames:"",
departIds:''
storeVals: '', //[key values]
textVals: '' //[label values]
}
},
computed:{
storeField(){
let field = this.customReturnField
if(!field){
field = this.store;
}
return underLinetoHump(field)
},
textField(){
return underLinetoHump(this.text)
}
},
mounted(){
this.departIds = this.value
this.storeVals = this.value
},
watch:{
value(val){
//update-begin-author:wangshuai date:20201124 for:组件 JSelectDepart.vue不是默认id时新内容编辑问题 gitee I247X2
// if (this.customReturnField === 'id') {
this.departIds = val
// }
//update-end-author:wangshuai date:20201124 for:组件 JSelectDepart.vue不是默认id时新内容编辑问题 gitee I247X2
this.storeVals = val
}
},
methods:{
initComp(departNames){
this.departNames = departNames
//update-begin-author:lvdandan date:20200513 for:TESTA-438 部门选择组件自定义返回值,数据无法回填
//TODO 当返回字段为部门名称时会有问题,因为部门名称不唯一
//返回字段不为id时根据返回字段获取id
if(this.customReturnField !== 'id' && this.value){
const dataList = this.$refs.innerDepartSelectModal.dataList;
console.log('this.value',this.value)
this.departIds = this.value.split(',').map(item => {
const data = dataList.filter(d=>d[this.customReturnField] === item)
return data.length > 0 ? data[0].id : ''
}).join(',')
}
//update-end-author:lvdandan date:20200513 for:TESTA-438 部门选择组件自定义返回值,数据无法回填
initComp(textVals){
this.textVals = textVals
},
//返回选中的部门信息
backDeparInfo(){
if(this.backDepart===true){
if(this.departIds && this.departIds.length>0){
let arr1 = this.departIds.split(',')
let arr2 = this.departNames.split(',')
let arr1 = this.storeVals.split(',')
let arr2 = this.textVals.split(',')
let info = []
for(let i=0;i<arr1.length;i++){
info.push({
@ -116,17 +134,21 @@
openModal(){
this.$refs.innerDepartSelectModal.show()
},
handleOK(rows, idstr) {
let value = ''
handleOK(rows) {
if (!rows && rows.length <= 0) {
this.departNames = ''
this.departIds = ''
this.textVals = ''
this.storeVals = ''
} else {
value = rows.map(row => row[this.customReturnField]).join(',')
this.departNames = rows.map(row => row['departName']).join(',')
this.departIds = idstr
let arr1 = []
let arr2 = []
for(let dep of rows){
arr1.push(dep[this.storeField])
arr2.push(dep[this.textField])
}
this.storeVals = arr1.join(',')
this.textVals = arr2.join(',')
}
this.$emit("change", value)
this.$emit("change", this.storeVals)
this.backDeparInfo()
},
getDepartNames(){

View File

@ -1,19 +1,28 @@
<template>
<div>
<a-input-search
v-model="userNames"
v-model="textVals"
placeholder="请先选择用户"
readOnly
unselectable="on"
@search="onSearchDepUser">
<a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
</a-input-search>
<j-select-user-by-dep-modal ref="selectModal" :modal-width="modalWidth" :multi="multi" @ok="selectOK" :user-ids="value" @initComp="initComp"/>
<j-select-user-by-dep-modal
ref="selectModal"
:modal-width="modalWidth"
:multi="multi"
@ok="selectOK"
:user-ids="value"
:store="storeField"
:text="textField"
@initComp="initComp"/>
</div>
</template>
<script>
import JSelectUserByDepModal from './modal/JSelectUserByDepModal'
import { underLinetoHump } from '@/components/_util/StringUtil'
export default {
name: 'JSelectUserByDep',
@ -42,20 +51,44 @@
type: Boolean,
default: false,
required: false
},
// 存储字段 [key field]
store: {
type: String,
default: 'username',
required: false
},
// 显示字段 [label field]
text: {
type: String,
default: 'realname',
required: false
}
},
data() {
return {
userIds: "",
userNames: ""
storeVals: '', //[key values]
textVals: '' //[label values]
}
},
computed:{
storeField(){
let field = this.customReturnField
if(!field){
field = this.store;
}
return underLinetoHump(field)
},
textField(){
return underLinetoHump(this.text)
}
},
mounted() {
this.userIds = this.value
this.storeVals = this.value
},
watch: {
value(val) {
this.userIds = val
this.storeVals = val
}
},
model: {
@ -63,15 +96,15 @@
event: 'change'
},
methods: {
initComp(userNames) {
this.userNames = userNames
initComp(textVals) {
this.textVals = textVals
},
//返回选中的用户信息
backDeparInfo(){
if(this.backUser===true){
if(this.userIds && this.userIds.length>0){
let arr1 = this.userIds.split(',')
let arr2 = this.userNames.split(',')
if(this.storeVals && this.storeVals.length>0){
let arr1 = this.storeVals.split(',')
let arr2 = this.textVals.split(',')
let info = []
for(let i=0;i<arr1.length;i++){
info.push({
@ -86,21 +119,22 @@
onSearchDepUser() {
this.$refs.selectModal.showModal()
},
selectOK(rows, idstr) {
selectOK(rows) {
console.log("当前选中用户", rows)
console.log("当前选中用户ID", idstr)
if (!rows) {
this.userNames = ''
this.userIds = ''
this.storeVals = ''
this.textVals = ''
} else {
let temp = ''
let temp1 = []
let temp2 = []
for (let item of rows) {
temp += ',' + item.realname
temp1.push(item[this.storeField])
temp2.push(item[this.textField])
}
this.userNames = temp.substring(1)
this.userIds = idstr
this.storeVals = temp1.join(',')
this.textVals = temp2.join(',')
}
this.$emit("change", this.userIds)
this.$emit("change", this.storeVals)
}
}
}

View File

@ -6,6 +6,7 @@
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
@update:fullscreen="isFullscreen"
wrapClassName="j-depart-select-modal"
switchFullscreen
cancelText="关闭">
@ -13,9 +14,9 @@
<a-input-search style="margin-bottom: 1px" placeholder="请输入部门名称按回车进行搜索" @search="onSearch" />
<a-tree
checkable
class="my-dept-select-tree"
:class="treeScreenClass"
:treeData="treeData"
:checkStrictly="true"
:checkStrictly="checkStrictly"
@check="onCheck"
@select="onSelect"
@expand="onExpand"
@ -32,8 +33,23 @@
<span v-else>{{title}}</span>
</template>
</a-tree>
</a-spin>
<!--底部父子关联操作和确认取消按钮-->
<template slot="footer" v-if="treeOpera && multi">
<div class="drawer-bootom-button">
<a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
<a-menu slot="overlay">
<a-menu-item key="1" @click="switchCheckStrictly(1)">父子关联</a-menu-item>
<a-menu-item key="2" @click="switchCheckStrictly(2)">取消关联</a-menu-item>
</a-menu>
<a-button>
树操作 <a-icon type="up" />
</a-button>
</a-dropdown>
<a-button @click="handleCancel" type="primary" style="margin-right: 0.8rem">关闭</a-button>
<a-button @click="handleSubmit" type="primary" >确认</a-button>
</div>
</template>
</j-modal>
</template>
@ -41,7 +57,7 @@
import { queryDepartTreeList } from '@/api/api'
export default {
name: 'JSelectDepartModal',
props:['modalWidth','multi','rootOpened','departId'],
props:['modalWidth','multi','rootOpened','departId', 'store', 'text','treeOpera'],
data(){
return {
visible:false,
@ -52,7 +68,9 @@
dataList:[],
checkedKeys:[],
checkedRows:[],
searchValue:""
searchValue:"",
checkStrictly: true,
fullscreen:false
}
},
created(){
@ -64,15 +82,18 @@
},
visible: {
handler() {
if (this.departId) {
this.checkedKeys = this.departId.split(",");
// console.log('this.departId', this.departId)
} else {
this.checkedKeys = [];
}
this.initDepartComponent(true)
}
}
},
computed:{
treeScreenClass() {
return {
'my-dept-select-tree': true,
'fullscreen': this.fullscreen,
}
},
},
methods:{
show(){
this.visible=true
@ -80,6 +101,7 @@
this.checkedKeys=[]
},
loadDepart(){
// 这个方法是找到所有的部门信息
queryDepartTreeList().then(res=>{
if(res.success){
let arr = [...res.result]
@ -92,20 +114,23 @@
}
})
},
initDepartComponent(){
let names = ''
initDepartComponent(flag){
let arr = []
//该方法两个地方用 1.visible改变事件重新设置选中项 2.组件编辑页面回显
let fieldName = flag==true?'key':this.text
if(this.departId){
let currDepartId = this.departId
let arr2 = this.departId.split(',')
for(let item of this.dataList){
if(currDepartId.indexOf(item.key)>=0){
names+=","+item.title
if(arr2.indexOf(item[this.store])>=0){
arr.push(item[fieldName])
}
}
if(names){
names = names.substring(1)
}
}
this.$emit("initComp",names)
if(flag==true){
this.checkedKeys = [...arr]
}else{
this.$emit("initComp", arr.join(','))
}
},
reWriterWithSlot(arr){
for(let item of arr){
@ -129,8 +154,11 @@
}
}
this.expandedKeys=[...keys]
//全部keys
//this.allTreeKeys = [...keys]
}else{
this.expandedKeys=[]
//this.allTreeKeys = []
}
},
onCheck (checkedKeys,info) {
@ -139,25 +167,32 @@
this.checkedKeys = [...arr]
this.checkedRows = (this.checkedKeys.length === 0) ? [] : [info.node.dataRef]
}else{
this.checkedKeys = checkedKeys.checked
if(this.checkStrictly){
this.checkedKeys = checkedKeys.checked
}else{
this.checkedKeys = checkedKeys
}
this.checkedRows = this.getCheckedRows(this.checkedKeys)
}
},
onSelect(selectedKeys,info) {
let keys = []
keys.push(selectedKeys[0])
if(!this.checkedKeys || this.checkedKeys.length===0 || !this.multi){
this.checkedKeys = [...keys]
this.checkedRows=[info.node.dataRef]
}else{
let currKey = info.node.dataRef.key
if(this.checkedKeys.indexOf(currKey)>=0){
this.checkedKeys = this.checkedKeys.filter(item=> item !==currKey)
//取消关联的情况下才走onSelect的逻辑
if(this.checkStrictly){
let keys = []
keys.push(selectedKeys[0])
if(!this.checkedKeys || this.checkedKeys.length===0 || !this.multi){
this.checkedKeys = [...keys]
this.checkedRows=[info.node.dataRef]
}else{
this.checkedKeys.push(...keys)
let currKey = info.node.dataRef.key
if(this.checkedKeys.indexOf(currKey)>=0){
this.checkedKeys = this.checkedKeys.filter(item=> item !==currKey)
}else{
this.checkedKeys.push(...keys)
}
}
this.checkedRows = this.getCheckedRows(this.checkedKeys)
}
this.checkedRows = this.getCheckedRows(this.checkedKeys)
},
onExpand (expandedKeys) {
this.expandedKeys = expandedKeys
@ -235,6 +270,16 @@
}
}
return rows
},
switchCheckStrictly (v) {
if(v==1){
this.checkStrictly = false
}else if(v==2){
this.checkStrictly = true
}
},
isFullscreen(val){
this.fullscreen=val
}
}
}
@ -244,8 +289,22 @@
<style lang="less" scoped>
// 限制部门选择树高度,避免部门太多时点击确定不便
.my-dept-select-tree{
height: 350px;
height:350px;
&.fullscreen{
height: calc(100vh - 250px);
}
overflow-y: scroll;
}
.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

@ -63,7 +63,7 @@
export default {
name: 'JSelectUserByDepModal',
components: {},
props: ['modalWidth', 'multi', 'userIds'],
props: ['modalWidth', 'multi', 'userIds', 'store', 'text'],
data() {
return {
queryParam: {
@ -159,27 +159,27 @@
if (this.userIds) {
// 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
let values = this.userIds.split(',') + ','
getUserList({
username: values,
pageNo: 1,
pageSize: values.length
}).then((res) => {
if (res.success) {
this.selectionRows = []
let selectedRowKeys = []
let realNames = []
res.result.records.forEach(user => {
realNames.push(user['realname'])
let param = {[this.store]: values}
getAction('/sys/user/getMultiUser', param).then((list)=>{
this.selectionRows = []
let selectedRowKeys = []
let textArray = []
if(list && list.length>0){
for(let user of list){
textArray.push(user[this.text])
selectedRowKeys.push(user['id'])
this.selectionRows.push(user)
})
this.selectedRowKeys = selectedRowKeys
this.$emit('initComp', realNames.join(','))
}
}
this.selectedRowKeys = selectedRowKeys
this.$emit('initComp', textArray.join(','))
})
} else {
// JSelectUserByDep组件bug issues/I16634
this.$emit('initComp', '')
// 前端用户选择单选无法置空的问题 #2610
this.selectedRowKeys = []
}
},
async loadData(arg) {
@ -254,7 +254,7 @@
handleSubmit() {
let that = this;
this.getSelectUserRows();
that.$emit('ok', that.selectUserRows, that.selectUserIds);
that.$emit('ok', that.selectUserRows);
that.searchReset(0)
that.close();
},