no message

This commit is contained in:
小陌 2024-03-17 21:50:27 +08:00
parent 4211f52de0
commit ecb9ea7749
3 changed files with 166 additions and 112 deletions

View File

@ -110,7 +110,7 @@
</template>
<!-- xUserSelect -->
<template v-else-if="item.component == 'xuserselect'">
<x-user-select v-model="data[item.name]" :type="item.type"></x-user-select>
<x-user-select v-model="data[item.name]" v-bind="bind"></x-user-select>
</template>
<template v-else-if="item.component == 'formtable'">
<x-form-table ref="xformtable" v-model="data[item.name]" v-bind="bind"> </x-form-table>

View File

@ -3,130 +3,169 @@
-->
<template>
<div class="x-form-table" ref="xFormTable">
<el-table :data="data" ref="table" border stripe>
<el-table-column type="index" width="50" fixed="left">
<template #header>
<el-button v-if="!hideAdd" type="primary" icon="el-icon-plus" size="small" circle @click="rowAdd"></el-button>
</template>
<template #default="scope">
<div :class="['x-form-table-handle', {'x-form-table-handle-delete':!hideDelete}]">
<span>{{scope.$index + 1}}</span>
<div :class="['x-form-table-handle', { 'x-form-table-handle-delete': !hideDelete }]">
<span>{{ scope.$index + 1 }}</span>
<el-button v-if="!hideDelete" type="danger" icon="el-icon-delete" size="small" plain circle @click="rowDel(scope.row, scope.$index)"></el-button>
</div>
</template>
</el-table-column>
<el-table-column label="" width="50" v-if="dragSort">
<template #default>
<div class="move" style="cursor: move;"><el-icon-d-caret style="width: 1em; height: 1em;"/></div>
<div class="move" style="cursor: move;"><el-icon-d-caret style="width: 1em; height: 1em;" /></div>
</template>
</el-table-column>
<template v-for="(item, index) in column" :key="index">
<el-table-column v-if="!item.hide && item.name" :column-key="item.name" v-bind="item">
<template #default="scope">
<el-input v-if="item.type=='input'" v-bind="item.options" v-model="scope.row[item.name]"> </el-input>
<el-link v-else-if="item.type=='link'" :href="scope.row[item.name]" v-bind="item.options">
<el-input v-if="(item.type || item.component) == 'input'" v-bind="item.bind" v-model="scope.row[item.name]"> </el-input>
<el-select v-else-if="(item.type || item.component) == 'select'" v-model="scope.row[item.name]" v-bind="item.bind" clearable filterable style="width: 100%;">
<el-option v-for="(option, index) in item.options" :key="index" v-bind="option"></el-option>
</el-select>
<el-switch v-else-if="(item.type || item.component) == 'switch'" v-model="scope.row[item.name]" v-bind="item.bind" />
<el-link v-else-if="(item.type || item.component) == 'link'" :href="scope.row[item.name]" v-bind="item.bind">
{{ item.options && item.options.label || scope.row[item.name] }}
</el-link>
<p v-else>
{{scope.row[item.name]}}
<span class="text">{{ scope.row[item.name] }}</span>
</p>
</template>
</el-table-column>
</template>
<slot></slot>
<template #empty>
{{placeholder}}
{{ placeholder }}
</template>
</el-table>
</div>
</template>
<script>
import Sortable from 'sortablejs'
import Sortable from 'sortablejs'
export default {
props: {
modelValue: { type: Array, default: () => [] },
addTemplate: { type: Object, default: () => {} },
column: { type: Array, default: () => [] },
placeholder: { type: String, default: "暂无数据" },
dragSort: { type: Boolean, default: false },
hideAdd: { type: Boolean, default: false },
hideDelete: { type: Boolean, default: false }
},
data(){
return {
data: [],
}
},
mounted(){
export default {
props: {
modelValue: { type: Array, default: () => [] },
addTemplate: { type: Object, default: () => { } },
column: { type: Array, default: () => [] },
placeholder: { type: String, default: "暂无数据" },
dragSort: { type: Boolean, default: false },
hideAdd: { type: Boolean, default: false },
hideDelete: { type: Boolean, default: false }
},
data() {
return {
data: [],
}
},
mounted() {
this.data = this.modelValue
if (this.dragSort) {
this.rowDrop()
}
},
watch: {
modelValue() {
this.data = this.modelValue
if(this.dragSort){
this.rowDrop()
}
},
watch:{
modelValue(){
this.data = this.modelValue
data: {
handler() {
this.$emit('update:modelValue', this.data);
},
data: {
handler(){
this.$emit('update:modelValue', this.data);
},
deep: true
}
},
methods: {
rowDrop(){
const _this = this
const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(tbody, {
handle: ".move",
animation: 300,
ghostClass: "ghost",
onEnd({ newIndex, oldIndex }) {
_this.data.splice(newIndex, 0, _this.data.splice(oldIndex, 1)[0])
const newArray = _this.data.slice(0)
const tmpHeight = _this.$refs.xFormTable.offsetHeight
_this.$refs.xFormTable.style.setProperty('height', tmpHeight + 'px')
_this.data = []
deep: true
}
},
methods: {
rowDrop() {
const _this = this
const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(tbody, {
handle: ".move",
animation: 300,
ghostClass: "ghost",
onEnd({ newIndex, oldIndex }) {
_this.data.splice(newIndex, 0, _this.data.splice(oldIndex, 1)[0])
const newArray = _this.data.slice(0)
const tmpHeight = _this.$refs.xFormTable.offsetHeight
_this.$refs.xFormTable.style.setProperty('height', tmpHeight + 'px')
_this.data = []
_this.$nextTick(() => {
_this.data = newArray
_this.$nextTick(() => {
_this.data = newArray
_this.$nextTick(() => {
_this.$refs.xFormTable.style.removeProperty('height')
})
_this.$refs.xFormTable.style.removeProperty('height')
})
}
})
},
rowAdd(){
const temp = JSON.parse(JSON.stringify(this.addTemplate || {}))
this.data.push(temp)
},
rowDel(row, index){
this.data.splice(index, 1)
},
//
pushRow(row){
const temp = row || JSON.parse(JSON.stringify(this.addTemplate || {}))
this.data.push(temp)
},
//index
deleteRow(index){
this.data.splice(index, 1)
}
})
}
})
},
rowAdd() {
const temp = JSON.parse(JSON.stringify(this.addTemplate || {}))
this.data.push(temp)
},
rowDel(row, index) {
this.$emit('update:modelValue', this.data);
//
this.$emit('delete', index, row)
this.data.splice(index, 1)
},
//
pushRow(row) {
const temp = row || JSON.parse(JSON.stringify(this.addTemplate || {}))
this.data.push(temp)
},
//index
deleteRow(index) {
this.data.splice(index, 1)
}
}
}
</script>
<style scoped>
.x-form-table {width: 100%;}
.x-form-table .x-form-table-handle {text-align: center;}
.x-form-table .x-form-table-handle span {display: inline-block;}
.x-form-table .x-form-table-handle button {display: none;}
.x-form-table .hover-row .x-form-table-handle-delete span {display: none;}
.x-form-table .hover-row .x-form-table-handle-delete button {display: inline-block;}
.x-form-table .move {text-align: center;font-size: 14px;margin-top: 3px;}
.text {
cursor: pointer;
display: inline;
white-space: nowrap;
overflow: hidden;
/* 隐藏溢出的内容 */
text-overflow: ellipsis;
/* 在文本溢出处显示省略号 */
}
.x-form-table {
width: 100%;
}
.x-form-table .x-form-table-handle {
text-align: center;
}
.x-form-table .x-form-table-handle span {
display: inline-block;
}
.x-form-table .x-form-table-handle button {
display: none;
}
.x-form-table .hover-row .x-form-table-handle-delete span {
display: none;
}
.x-form-table .hover-row .x-form-table-handle-delete button {
display: inline-block;
}
.x-form-table .move {
text-align: center;
font-size: 14px;
margin-top: 3px;
}
</style>

View File

@ -7,7 +7,7 @@
<div class="x-user-select" :style="{ 'height': _height, 'width': _width }">
<div class="x-user-select__left">
<div class="x-user-select__search">
<el-input v-model="keyword" prefix-icon="el-icon-search" placeholder="搜索成员">
<el-input v-model="keyword" prefix-icon="el-icon-search" :placeholder="config.placeholder || '搜索用户'">
<template #append>
<el-button icon="el-icon-search" @click="search"></el-button>
</template>
@ -36,15 +36,16 @@
<header>已选 ({{ selected.length }})</header>
<ul>
<el-scrollbar>
<li v-for="(item, index) in selected" :key="item.id">
<x-form-table v-model="selected" :hideAdd="true" placeholder="暂无数据" :column="config.column" @delete="setCheckedKeys" />
<!-- <li v-for="(item, index) in selected" :key="item.id">
<span class="name">
<el-avatar size="small">{{ item.name.substring(0, 1) }}</el-avatar>
<el-avatar size="small">{{ item.name.toString().substring(0, 1) }}</el-avatar>
<label>{{ item.name }}</label>
</span>
<span class="delete">
<el-button type="danger" icon="el-icon-delete" circle size="small" @click="deleteSelected(index)"></el-button>
</span>
</li>
</li> -->
</el-scrollbar>
</ul>
</div>
@ -108,12 +109,22 @@ export default {
modelValue: { type: Array, default: () => [] },
type: { type: [String, Number], default: 1 },
height: { type: [String, Number], default: 280 },
width: { type: [String, Number], default: 600 },
width: { type: [String, Number], default: '100%' },
datatype: { type: [String, Number], default: 'id' },
config: {
type: Object, default: () => ({
config: []
})
},
},
watch: {
// selected
selectedIds(newVal) {
this.$emit('update:modelValue', newVal);
if (this.datatype == 'id') {
this.$emit('update:modelValue', newVal);
return true;
}
this.$emit('update:modelValue', this.selected);
},
},
computed: {
@ -128,7 +139,8 @@ export default {
}
},
mounted() {
this.value = this.modelValue;
this.userProps = Object.assign({}, config.user.props, this.config.userProps || {});
this.groupProps = Object.assign({}, config.group.props, this.config.groupProps || {});
this.open()
},
methods: {
@ -154,16 +166,18 @@ export default {
async getUser() {
this.showUserloading = true;
var params = {
[config.user.request.keyword]: this.keyword || null,
[config.user.request.groupid]: this.groupid || null,
[config.user.request.page]: this.currentPage,
[config.user.request.limit]: this.limit
[this.config.keyword || config.user.request.keyword]: this.keyword || null,
[this.config.groupid || config.user.request.groupid]: this.groupid || null,
[this.config.page || config.user.request.page]: this.currentPage,
[this.config.limit || config.user.request.limit]: this.limit
}
var res = await this.$http.get('user/index/lists', params);
var res = await this.$http.get(this.config.url || 'user/index/lists', params);
this.showUserloading = false;
this.user = config.user.parseData(res).rows;
this.total = config.user.parseData(res).total || 0;
this.$refs.userScrollbar.setScrollTop(0)
this.selected = this.modelValue
},
//
async getRole() {
@ -171,8 +185,6 @@ export default {
var res = await this.$http.get('user/group/roleList', { type: 'system' });
this.showGrouploading = false;
this.role = res.data
// 使filterID
this.selected = this.role.filter(item => this.modelValue.includes(item.id)).map(item => ({
id: item[config.role.props.key],
@ -191,11 +203,11 @@ export default {
userClick(data, checked) {
if (checked) {
this.selected.push({
id: data[config.user.props.key],
name: data[config.user.props.label]
id: data[this.userProps.key],
name: data[this.userProps.label]
})
} else {
this.selected = this.selected.filter(item => item.id != data[config.user.props.key])
this.selected = this.selected.filter(item => item.id != data[this.userProps.key])
}
},
//
@ -209,14 +221,16 @@ export default {
this.currentPage = 1
this.getUser()
},
//
setCheckedKeys() {
this.$nextTick(() => {
this.type == 1 ? this.$refs.userTree.setCheckedKeys(this.selectedIds) : this.$refs.groupTree.setCheckedKeys(this.selectedIds)
})
},
//
deleteSelected(index) {
this.selected.splice(index, 1);
if (this.type == 1) {
this.$refs.userTree.setCheckedKeys(this.selectedIds)
} else if (this.type == 2) {
this.$refs.groupTree.setCheckedKeys(this.selectedIds)
}
this.setCheckedKeys()
},
//
roleClick(data, checked) {
@ -245,7 +259,8 @@ export default {
}
.x-user-select__left {
width: calc((100%*0.7 - 10px));
min-width: 320px;
flex: none;
}
.x-user-select__right {
@ -264,13 +279,13 @@ export default {
}
.x-user-select__tree {
width: 50%;
width: 40%;
height: 100%;
border-right: 1px solid var(--el-border-color-light);
}
.x-user-select__user {
width: 50%;
width: 60%;
height: 100%;
display: flex;
flex-direction: column;
@ -308,7 +323,7 @@ export default {
}
.x-user-select__selected {
width: calc((100%*0.3 - 20px));
width: 100%;
border: 1px solid var(--el-border-color-light);
background: var(--el-color-white);
}
@ -368,7 +383,7 @@ export default {
}
.x-user-select-role .x-user-select__left {
width: calc((100% - 20px)/2);
min-width: 200px;
}
.x-user-select-role .x-user-select__tree {
@ -377,7 +392,7 @@ export default {
}
.x-user-select-role .x-user-select__selected {
width: calc((100% - 20px)/2);
width: 100%;
}
.x-user-select-role .x-user-select__select {