|
|
<template>
|
|
|
<!-- 组件容器,使用 app-container 类名 -->
|
|
|
<div class="app-container">
|
|
|
|
|
|
<!-- 筛选条件容器 -->
|
|
|
<div class="filter-container">
|
|
|
<!-- 插槽,用于插入自定义筛选内容 -->
|
|
|
<slot name="filter-content" />
|
|
|
|
|
|
<!-- Element UI 行布局 -->
|
|
|
<el-row>
|
|
|
<!-- Element UI 列布局 -->
|
|
|
<el-col>
|
|
|
<!-- 当 options.addRoute 存在时显示添加按钮 -->
|
|
|
<el-button v-if="options.addRoute" type="primary" icon="el-icon-plus" @click="handleAdd">添加</el-button>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 当 multiShow 为 true 且 options.multiActions 存在时显示批量操作容器 -->
|
|
|
<div v-show="multiShow && options.multiActions" class="filter-container">
|
|
|
|
|
|
<!-- Element UI 下拉选择框,用于选择批量操作 -->
|
|
|
<el-select v-model="multiNow" :placeholder="selectedLabel" class="filter-item" style="width: 130px" @change="handleOption">
|
|
|
<!-- 循环渲染批量操作选项 -->
|
|
|
<el-option
|
|
|
v-for="item in options.multiActions"
|
|
|
:key="item.value"
|
|
|
:label="item.label"
|
|
|
:value="item.value"
|
|
|
/>
|
|
|
</el-select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- Element UI 表格,显示数据列表 -->
|
|
|
<el-table
|
|
|
v-loading="listLoading"
|
|
|
:data="dataList.records"
|
|
|
:header-cell-style="{'background':'#f2f3f4', 'color':'#555', 'font-weight':'bold', 'line-height':'32px'}"
|
|
|
border
|
|
|
fit
|
|
|
highlight-current-row
|
|
|
@selection-change="handleSelection"
|
|
|
>
|
|
|
|
|
|
<!-- 当 options.multi 为 true 时显示多选列 -->
|
|
|
<el-table-column
|
|
|
v-if="options.multi"
|
|
|
align="center"
|
|
|
type="selection"
|
|
|
width="55"
|
|
|
/>
|
|
|
|
|
|
<!-- 插槽,用于插入自定义表格列 -->
|
|
|
<slot name="data-columns" />
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<!-- 分页组件,当总数据量大于 0 时显示 -->
|
|
|
<pagination v-show="dataList.total>0" :total="dataList.total" :page.sync="listQuery.current" :limit.sync="listQuery.size" @pagination="getList" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
// 从公共 API 模块导入列表查询、删除数据和更改状态的方法
|
|
|
import { fetchList, deleteData, changeState } from '@/api/common'
|
|
|
// 导入分页组件
|
|
|
import Pagination from '@/components/Pagination'
|
|
|
|
|
|
export default {
|
|
|
// 组件名称
|
|
|
name: 'PagingTable',
|
|
|
// 注册子组件
|
|
|
components: { Pagination },
|
|
|
// 组件入参
|
|
|
props: {
|
|
|
options: {
|
|
|
type: Object,
|
|
|
default: () => {
|
|
|
return {
|
|
|
// 批量操作选项数组
|
|
|
multiActions: [],
|
|
|
// 列表请求的 API 地址
|
|
|
listUrl: '/exam/api',
|
|
|
// 删除数据请求的 API 地址
|
|
|
deleteUrl: '',
|
|
|
// 更改状态请求的 API 地址
|
|
|
stateUrl: '',
|
|
|
// 是否支持批量操作
|
|
|
multi: false
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 列表查询参数
|
|
|
listQuery: {
|
|
|
type: Object,
|
|
|
default: () => {
|
|
|
return {
|
|
|
// 当前页码
|
|
|
current: 1,
|
|
|
// 每页显示的数据量
|
|
|
size: 10,
|
|
|
// 其他查询参数
|
|
|
params: {},
|
|
|
// 时间戳,用于防止缓存
|
|
|
t: 0
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
// 接口返回的数据列表
|
|
|
dataList: {
|
|
|
// 总数据量
|
|
|
total: 0
|
|
|
},
|
|
|
// 数据加载状态标识
|
|
|
listLoading: true,
|
|
|
// 选中的数据 ID 数组
|
|
|
selectedIds: [],
|
|
|
// 选中的数据对象数组
|
|
|
selectedObjs: [],
|
|
|
// 显示已选中的项数提示文本
|
|
|
selectedLabel: '',
|
|
|
// 是否显示批量操作区域
|
|
|
multiShow: false,
|
|
|
// 当前选中的批量操作标识
|
|
|
multiNow: ''
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
|
|
|
// 检测查询参数变化,当变化时重新获取数据列表
|
|
|
listQuery: {
|
|
|
handler() {
|
|
|
this.getList()
|
|
|
},
|
|
|
deep: true
|
|
|
}
|
|
|
},
|
|
|
// 组件创建完成后调用获取数据列表的方法
|
|
|
created() {
|
|
|
this.getList()
|
|
|
},
|
|
|
methods: {
|
|
|
|
|
|
/**
|
|
|
* 添加数据跳转方法
|
|
|
* 如果 options.addRoute 存在,则跳转到指定路由;否则打印提示信息
|
|
|
*/
|
|
|
handleAdd() {
|
|
|
if (this.options.addRoute) {
|
|
|
this.$router.push({ name: this.options.addRoute, params: {}})
|
|
|
return
|
|
|
}
|
|
|
console.log('未设置添加数据跳转路由!')
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
* 查询数据列表方法
|
|
|
* 发送请求获取数据列表,并更新组件数据
|
|
|
*/
|
|
|
getList() {
|
|
|
this.listLoading = true
|
|
|
this.listQuery.t = new Date().getTime()
|
|
|
fetchList(this.options.listUrl, this.listQuery).then(response => {
|
|
|
this.dataList = response.data
|
|
|
this.listLoading = false
|
|
|
})
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
* 搜索方法
|
|
|
* 重新调用获取数据列表的方法
|
|
|
*/
|
|
|
handleFilter() {
|
|
|
// 重新搜索
|
|
|
this.getList()
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
* 批量操作回调方法
|
|
|
* 根据选中的批量操作标识执行相应操作
|
|
|
* @param {string} v - 当前选中的批量操作标识
|
|
|
*/
|
|
|
handleOption(v) {
|
|
|
this.multiNow = ''
|
|
|
|
|
|
// 内部消化的操作
|
|
|
if (v === 'delete') {
|
|
|
this.handleDelete()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if (v === 'enable') {
|
|
|
this.handleState(0)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if (v === 'disable') {
|
|
|
this.handleState(1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 向外回调的操作
|
|
|
this.$emit('multi-actions', { opt: v, ids: this.selectedIds })
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
* 修改状态方法,用于启用或禁用数据
|
|
|
* 发送请求修改选中数据的状态,并在成功后重新获取数据列表
|
|
|
* @param {number} state - 要修改成的状态值
|
|
|
*/
|
|
|
handleState(state) {
|
|
|
// 修改状态
|
|
|
changeState(this.options.stateUrl, this.selectedIds, state).then(response => {
|
|
|
if (response.code === 0) {
|
|
|
this.$message({
|
|
|
type: 'success',
|
|
|
message: '状态修改成功!'
|
|
|
})
|
|
|
|
|
|
// 重新搜索
|
|
|
this.getList()
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
* 删除数据方法
|
|
|
* 先检查是否有选中数据,有则弹出确认对话框,确认后发送删除请求并重新获取数据列表
|
|
|
*/
|
|
|
handleDelete() {
|
|
|
if (this.selectedIds.length === 0) {
|
|
|
this.$message({
|
|
|
message: '请至少选择一条数据!',
|
|
|
type: 'warning'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 删除
|
|
|
this.$confirm('确实要删除吗?', '提示', {
|
|
|
confirmButtonText: '确定',
|
|
|
cancelButtonText: '取消',
|
|
|
type: 'warning'
|
|
|
}).then(() => {
|
|
|
deleteData(this.options.deleteUrl, this.selectedIds).then(() => {
|
|
|
this.$message({
|
|
|
type: 'success',
|
|
|
message: '删除成功!'
|
|
|
})
|
|
|
this.getList()
|
|
|
})
|
|
|
})
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
* 列表多选操作方法
|
|
|
* 处理表格多选变化事件,更新选中数据的相关信息并触发事件
|
|
|
* @param {Array} val - 当前选中的数据对象数组
|
|
|
*/
|
|
|
handleSelection(val) {
|
|
|
const ids = []
|
|
|
val.forEach(row => {
|
|
|
ids.push(row.id)
|
|
|
})
|
|
|
|
|
|
this.selectedObjs = val
|
|
|
this.selectedIds = ids
|
|
|
this.multiShow = ids.length > 0
|
|
|
this.selectedLabel = '已选' + ids.length + '项'
|
|
|
|
|
|
this.$emit('select-changed', { ids: this.selectedIds, objs: this.selectedObjs })
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
|
|
|
/* 筛选容器内筛选项的样式,设置左外边距 */
|
|
|
.filter-container .filter-item{
|
|
|
margin-left: 5px;
|
|
|
}
|
|
|
|
|
|
/* 筛选容器内第一个筛选项的样式,取消左外边距 */
|
|
|
.filter-container .filter-item:first-child{
|
|
|
margin-left: 0px;
|
|
|
}
|
|
|
</style>
|