效果:
html
<div class="byLawBox">
<div class="titleBox">规章制度公示</div>
<div class="contentBox">
<TableList
:loading="byLawloading"
ref="byLawtablistRef"
:hasImport="false"
:hasExport="false"
@getData="byLawgetData"
:columns="byLawcolumns"
:showHeader="false"
:MaxResultCount="10"
:ischange="false"
>
<template #customtable="{ column, record }">
<template v-if="column.key === 'icon'">
<file-word-outlined
style="color: #1683ff"
v-if="
findFileType(record.FilePath[0]?.DisPlayName) == '.doc' ||
findFileType(record.FilePath[0]?.DisPlayName) == '.docx'
" />
<file-ppt-outlined
style="color: #f57b11"
v-if="
findFileType(record.FilePath[0]?.DisPlayName) == '.ppt' ||
findFileType(record.FilePath[0]?.DisPlayName) == '.pptx'
" />
<file-excel-outlined
style="color: #15c34f"
v-if="
findFileType(record.FilePath[0]?.DisPlayName) == '.xlsx' ||
findFileType(record.FilePath[0]?.DisPlayName) == '.xLs'
" />
<file-pdf-outlined
style="color: #e83c35"
v-if="
findFileType(record.FilePath[0]?.DisPlayName) == '.pdf'
"
/></template>
</template>
<template #operation="{ column, record }">
<a @click="preview(record)"> 预览</a>
<a-divider type="vertical" />
<a @click="downLoadEvent(record)"> 下载</a>
</template></TableList
>
</div>
</div>
javascript
const downLoadEvent = (param2) => {
//下载操作
if (
Array.isArray(param2.FilePath) &&
param2?.FilePath?.length &&
param2?.FilePath[0]?.FileId
) {
axios
.get(
window.defaultconfig.fileUrl +
"/api/FileManage/Download" +
`?Id=${param2.FilePath[0].FileId}`,
{ responseType: "arraybuffer" }
)
.then((res) => {
const blob = new Blob([res.data], { type: "application/vnd.ms-excel" });
const objectUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.download = param2.FilePath[0].DisPlayName;
a.href = objectUrl;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
.catch((error) => {
message.error("系统异常,请联系管理员");
});
} else {
message.error("文件不存在,无法下载");
}
};
javascript
const byLawcolumns = [
{
title: "图标",
dataIndex: "icon",
key: "icon",
align: "right",
width: 20,
},
{
title: "文件名",
dataIndex: "FilePath",
ellipsis: true,
key: "FilePath",
align: "left",
customRender: ({ text }) => text[0].DisPlayName,
},
{
title: "操作",
dataIndex: "operation",
key: "operation",
align: "right",
width: 100,
},
];
table组件
html
<template>
<div class="tableBox">
<div class="btn-add">
<a-space>
<a-upload
v-model:file-list="fileList"
v-if="hasImport"
name="file"
accept=".xls,.xlsx"
action=""
:headers="headers"
@change="handleChange"
>
<a-button type="primary"> 导入 </a-button>
</a-upload>
<a-button type="primary" v-if="hasExport" @click="handleAllExport"
>导出全部</a-button
>
<a-button type="primary" v-if="allDel">全部删除</a-button>
<a-button
:disabled="dataSource.length === 0 || flagselectedRowKeys"
v-if="rowSelection"
@click="delEvent(selecrowdata, 'many')"
>批量删除</a-button
>
<a-button
:disabled="dataSource.length === 0 || flagselectedRowKeys"
v-if="rowSelectionEdit"
@click="manyEditEvent(selecrowdata, 'many')"
>批量修改</a-button
>
<a-button
:disabled="dataSource.length === 0 || flagselectedRowKeys"
v-if="markread"
@click="handleFlagRead(selecrowdata, 'hasread')"
>标记已读</a-button
>
<a-button
type="primary"
v-if="operatingButton?.addbtn"
@click="editEvent('add')"
>{{ addbtnName ? addbtnName : "添加" }}</a-button
>
<a-button
:disabled="dataSource.length === 0"
type="primary"
v-if="operatingButton?.export"
@click="exportEvent('export')"
>{{ "新建导出" }}</a-button
>
<a-button
type="primary"
v-if="operatingButton?.exportRecord"
@click="exportEvent('exportRecord')"
>{{ "导出记录" }}</a-button
>
<a-button type="primary" v-if="hasgoback" @click="handlegoback"
>返回</a-button
>
</a-space>
</div>
<a-table
:rowKey="row => row.id?row.id:row.Id"
:showHeader="showHeader"
:dataSource="dataSource"
:columns="columns"
:loading="loading"
:scroll="{ x: tableOtherobj.scroll }"
:expandIconColumnIndex="expandIconSet.expandIconColumnIndex"
:expandIconAsCell="expandIconSet.expandIconAsCell"
@expand="handleexpand"
@expandedRowsChange="expandedRowsChange"
:row-selection="
rowSelection || markread || rowSelection2||rowSelectionEdit
? {selectedRowKeys:selecrowdata, ...objrowSelection }
: null
"
:pagination="pagination ? objArray.pagination : false"
>
<template #bodyCell="{ column, record, index }">
<slot name="customtable" :column="column" :record="record"></slot>
<template v-if="column.key === 'operation'">
<span>
<slot name="operation" :column="column" :record="record"></slot>
<a
@click="editEvent('download', record)"
v-if="operatingButton?.reportdownload"
>
报表下载</a
>
<a-divider type="vertical" v-if="dividerbutton?.reportdownload" />
<a
@click="editEvent('detail', record)"
v-if="operatingButton?.detail"
>
查看</a
>
<a-divider type="vertical" v-if="dividerbutton?.detail" />
<slot name="editOperation" :column="column" :record="record">
<a @click="editEvent('edit', record)" v-if="operatingButton?.edit"
>修改</a
>
</slot>
<a-divider type="vertical" v-if="dividerbutton?.edit" />
<a
@click="delEvent(record)"
v-if="operatingButton?.del"
style="color: red"
>删除</a
>
<a-divider type="vertical" v-if="dividerbutton?.del" />
</span>
</template>
<template v-if="column.key === 'index'">
<span>{{
`${
(objArray.pagination.current - 1) * objArray.pagination.pageSize +
index +
1
}`
}}</span>
</template>
<template v-if="column.key === objType.typeName && objType.isshow">
<span class="blockBox" v-if="objType[record[objType.typeName]]"
:style="{
borderColor:objTypecolor.isshow
? objTypecolor[record[objType.typeName]]
: '#fff',
color: objTypecolor.isshow
? objTypecolor[record[objType.typeName]]
: null,
backgroundColor:objTypeBgcolor.isshow
? objTypeBgcolor[record[objType.typeName]]
: null,
}"
>{{ objType[record[objType.typeName]] }}</span
>
<!-- marginLeft:objType.marginLeft?objType.marginLeft:'',
marginRight:objType.marginRight?objType.marginRight:'' -->
<span :style="{color:`#FF0000`,color:!objType[record[objType.typeName]]?'#999':''}" v-else>{{
objType[record[objType.typeName]]? objType[record[objType.typeName]]:'暂无数据'
}}</span>
</template>
<template v-if="column.key === obj2Type?.typeName && obj2Type?.isshow">
<span>{{ obj2Type[record[obj2Type.typeName]] }}</span>
</template>
</template>
</a-table>
</div>
</template>
<script setup>
import { reactive, ref, watch, toRefs } from "vue";
const props = defineProps({
editColor:{
type: Boolean,
default: false,
},
ischange:{
type: Boolean,
default: true,
},
// 请求最大条数
MaxResultCount: {
type: Number,
default: 0,
},
// 是否显示表头
showHeader: {
type: Boolean,
default: true,
},
addbtnName: {
type: String,
default: "",
},
editTxt:{
type: String,
default: "修改",
},
operatingButton: {
//操作按钮
reportdownload: {
type: Boolean,
default: false,
},
edit: {
type: Boolean,
default: true,
},
del: {
type: Boolean,
default: true,
},
detail: {
type: Boolean,
default: false,
},
},
dividerbutton: {
//操作按钮之间的分割线
reportdownload: {
type: Boolean,
default: false,
},
edit: {
type: Boolean,
default: true,
},
del: {
type: Boolean,
default: false,
},
detail: {
type: Boolean,
default: false,
},
},
allDel: {
//按钮:全部删除
type: Boolean,
default: false,
},
columns: {
//表格表头
type: Array,
default: [],
},
formessagedivider: {
type: Boolean,
default: false,
},
hasImport: {
//按钮:导入
type: Boolean,
default: false,
},
hasExport: {
//按钮:导出
type: Boolean,
default: false,
},
markread: {
// 按钮:标记已读
type: Boolean,
default: false,
},
hasDetail: {
//表格详情
type: Boolean,
default: false,
},
tableOtherobj: {
type: Object,
default: {
// hasAddbtn: true,// 表格上是否有添加按钮
// hasDetail: false,//操作中是否有详情
scroll: false, //表格是否有横向滚动,以及x,方向的 值是多少 number
actionwidth: "120",
},
},
hasedit: {
//表格修改
type: Boolean,
default: true,
},
hasdel: {
//表格删除
type: Boolean,
default: true,
},
hasseeprocess: {
//表格查看过程
type: Boolean,
default: false,
},
pagination: {
//分页
type: Boolean,
default: true,
},
// 是否有批量操作
rowSelection: {
type: Boolean,
default: false,
},
rowSelectionEdit: {
type: Boolean,
default: false,
},
rowSelection2: {
// 是否可以选择
type: Boolean,
default: false,
},
hasgoback: {
//返回按钮
type: Boolean,
default: false,
},
searchkey: {
// 查询的字段
type: Object,
default: {},
},
objType: {
//后台返回摸个字段,不能直接显示,而是根据不同值显示对应的其他内容
type: Object,
default: {
isshow: false, //是否显示
typeName: "type", // 属性值 '需要转义的表格字段,当type=1时显示公司级;当typ=2时显示部门级'
1: "公司级",
2: "部门级",
},
},
obj2Type: {
//页面需要两个字段都用枚举时
type: Object,
default: {
isshow: false, //是否显示
typeName: "type", // 属性值 '需要转义的表格字段,当type=1时显示公司级;当typ=2时显示部门级'
1: "公司级",
2: "部门级",
},
},
objTypecolor: {
type: Object,
default: {
isshow: false, //是否显示
typeName: "monitorDataReportType", // 属性值 '需要设置颜色的字段'
day: "#FF0000",
month: "#FFFF00",
},
},
objTypeBgcolor: {
type: Object,
default: {
isshow: false, //是否显示
typeName: "monitorDataReportType", // 属性值 '需要设置颜色的字段'
day: "#FF0000",
month: "#FFFF00",
},
},
expandIconSet: {
// 表格嵌套时,那个控制的展开折叠图表的位置
type: Object,
default: {
expandIconColumnIndex: 2, //想让展开图标放在第几列
expandIconAsCell: false, 想让展开图标放在第几列 设置的配套属性
},
},
loading: false, //表格loading
});
const {
objTypecolor,
obj2Type,
operatingButton,
dividerbutton,
formessagedivider,
markread,
columns,
hasImport,
hasExport,
hasDetail,
tableOtherobj,
hasedit,
hasdel,
hasseeprocess,
pagination,
rowSelection,
rowSelectionEdit,
hasgoback,
searchkey,
objType,
expandIconSet,
} = toRefs(props);
// 发送给父组件的方法
const emits = defineEmits([
"openModel",
"handleDelTable",
"getData",
"FlagRead",
"handleTableRowSelec",
"exportXlsx",
"importXlsx",
]);
// 批量删除
let flagselectedRowKeys = ref(true);
let selecrowdata = ref();
const objrowSelection = {
// selectedRowKeys: selectedRowKeys,
//selectedRowKeys 选中行的datasource 中元素key的值; selectedRows为所选元素中datasource 是一个数组。
onChange: (selectedRowKeys, selectedRows) => {
let falg = selectedRowKeys.length ? false : true;
flagselectedRowKeys.value = falg;
selecrowdata.value = [...selectedRowKeys];
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
emits("handleTableRowSelec", selectedRowKeys, selectedRows);
},
};
// 返回
const handlegoback = () => {
history.back();
};
// 操作
const editEvent = (param1, param2) => {
emits("openModel", param1, param2);
};
//导出操作
const exportEvent = (param1) => {
emits("exportEvent", param1);
};
const delEvent = (param1, param2) => {
emits("handleDelTable", param1);
};
const manyEditEvent=(param1, param2)=>{
emits("handleEditTable", param1,selecrowdata.value);
}
const handleFlagRead = () => {
emits("FlagRead", selecrowdata);
};
// 分页方法
let objArray = reactive({
// 请求参数
searchParams: {},
// 分页信息
pagination: {
current: 1,
total: 0,
pageSize: props.MaxResultCount ? props.MaxResultCount : 25,
showSizeChanger: props.ischange,
showTotal: (total) => `共 ${total} 条`,
pageSizeOptions: [ "15", "20", "25", "30", "40"],
onChange: (page, pageSize) => {
handleSizeChange(page, pageSize);
},
},
// 批量选中
selectedRowKeys: [],
// 选中的行数据
selectedRows: [],
});
const handleSizeChange = (page, pageSize) => {
if (objArray.pagination.pageSize != pageSize) {
objArray.pagination.current = 1;
objArray.pagination.pageSize = pageSize;
} else {
objArray.pagination.current = page;
}
emits("getData", props.searchkey, objArray.pagination);
};
// 嵌套子表格
const handleexpand = (expanded, record) => {
console.log(expanded, record, "expanded, record");
};
const expandedRowsChange = (expandedRows) => {
console.log(expandedRows, "expandedRows");
};
// 导出全部
const handleAllExport = () => {
emits("exportXlsx");
};
// 导入
const headers = {
authorization: "authorization-text",
};
const fileList = ref([]);
const handleChange = (info) => {
if (info.file.status !== "uploading") {
console.log(info.file, info.fileList);
}
if (info.file.status === "done") {
message.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === "error") {
message.error(`${info.file.name} file upload failed.`);
}
emits("importXlsx", info);
};
const handleImportant = () => {};
const dataSource = ref([]);
const getData = (data, total) => {
dataSource.value = data;
objArray.pagination.total = total;
};
const setpage = (pageojb) => {
objArray.pagination.current = pageojb.current;
objArray.pagination.pageSize = pageojb.pageSize;
};
defineExpose({ getData, setpage,selecrowdata });
</script>
<style lang="less" scoped>
.btn-add {
text-align: right;
/* margin-bottom: 20px; */
/* margin-top: 20px; */
}
:deep(.ant-select-single:not(.ant-select-customize-input)) {
.ant-select-selector {
height: 24px !important;
}
}
:deep(.ant-select-single) {
.ant-select-selector {
.ant-select-selection-item {
line-height: 22px !important;
}
}
}
.blockBox{
padding: 0px 5px;
// margin:0px 33px;
border: 1px solid;
border-radius: 3px;
font-size: 14px;
}
</style>