smart-admin/smart-admin-web-javascript/src/components/support/table-operator/smart-table-column-modal.vue
zhoumingfa ac0f1ae2b9 Merge branch 'master' of https://gitee.com/DxrHelloWorld/smart-admin
 Conflicts:
	smart-admin-api-java17-springboot3/sa-base/src/main/resources/code-generator-template/java/dao/Dao.java.vm
	smart-admin-web-typescript/src/api/system/employee-api.ts
2025-02-16 00:07:11 +08:00

307 lines
9.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* 表格列设置
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-08-26 23:45:51
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*
-->
<template>
<a-modal :width="800" :open="visible" title="设置列" :destroyOnClose="true" :closable="false">
<div v-if="!tableId">
<a-alert type="error" show-icon class="smart-margin-bottom10">
<template #message> 您尚未设置 TableOperator 组件的 tableId</template>
</a-alert>
<a-alert type="error" class="smart-margin-bottom10">
<template #message>
1. 请在 src\constants\support\table-id-const.js 中配置 tableId 常量
<br />
<br />
2. 在自己的业务表格页面组件中使用如下
<br />
导入: import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
<br />
使用: {{ '<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.XXX" :refresh="queryData" />' }}
<br />
<br />
3. 具体用法可参考员工管理
</template>
</a-alert>
</div>
<div v-else>
<a-alert type="info" show-icon class="smart-margin-bottom10">
<template #icon><smile-outlined /></template>
<template #message> 可以通过拖拽行直接修改顺序哦 <pushpin-outlined />为固定列不可拖拽 </template>
</a-alert>
<a-table
id="smartTableColumnModalTable"
rowKey="columnKey"
row-class-name="column-row"
:columns="tableColumns"
:dataSource="tableData"
:rowSelection="{ checkStrictly: false, selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
:pagination="false"
size="small"
bordered
>
<template #bodyCell="{ text, record, index, column }">
<template v-if="column.dataIndex === 'title'">
<a-button type="text" :class="record.fixed ? '' : 'handle'" size="small" style="width: 100%; text-align: left">
<template #icon>
<drag-outlined v-if="!record.fixed" />
<pushpin-outlined v-else />
</template>
{{ text }}
</a-button>
</template>
<template v-if="column.dataIndex === 'width'">
<a-input-number v-model:value="record.width" style="width: 90px; margin-left: 10px; margin-right: 3px" size="small" />px
</template>
<template v-if="column.dataIndex === 'operate'">
<div class="smart-table-operate" v-if="!record.fixed">
<a-button @click="up(index)" v-show="index > 0" type="link" class="handle" size="small" style="margin-right: 12px"> 上移 </a-button>
<a-button @click="down(index)" type="link" class="handle" size="small" v-show="index !== tableData.length - 1"> 下移</a-button>
</div>
</template>
</template>
</a-table>
</div>
<template #footer>
<a-button key="back" @click="hide">取消</a-button>
<a-button v-if="tableId" key="submit" type="primary" :loading="submitLoading" @click="save">保存</a-button>
<a-button v-if="tableId" key="back" :loading="submitLoading" @click="reset" danger style="margin-left: 20px">恢复默认</a-button>
</template>
</a-modal>
</template>
<script setup>
import { SmartLoading } from '/@/components/framework/smart-loading';
import { tableColumnApi } from '/@/api/support/table-column-api';
import { nextTick, ref } from 'vue';
import _ from 'lodash';
import Sortable from 'sortablejs';
import { message, Modal } from 'ant-design-vue';
import { mergeColumn } from './smart-table-column-merge';
import { smartSentry } from '/@/lib/smart-sentry';
const emit = defineEmits(['change']);
defineExpose({ show });
// ---------------- 显示 / 隐藏 --------------------
let tableId = null;
const visible = ref(false);
//显示
function show(columns, showTableId) {
tableId = showTableId;
visible.value = true;
getUserTableColumns(tableId, _.cloneDeep(columns));
}
//隐藏
function hide() {
visible.value = false;
}
//获取用户的列数据
async function getUserTableColumns(tableId, columns) {
if (!tableId) {
return;
}
SmartLoading.show();
let userTableColumnArray = [];
try {
let res = await tableColumnApi.getColumns(tableId);
if (res.data) {
try {
userTableColumnArray = JSON.parse(res.data);
} catch (e1) {
smartSentry.captureError(e1);
}
}
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
//根据前端列和后端列构建新的列数据
tableData.value = mergeColumn(columns, userTableColumnArray);
//将已经显示的展示出来
for (const item of tableData.value) {
if (item.showFlag) {
selectedRowKeyList.value.push(item.columnKey);
}
}
nextTick(() => {
initDrag();
});
}
// --------------------- 表格渲染 --------------------------------
const tableData = ref([]);
const tableColumns = [
{
title: '列',
dataIndex: 'title',
},
{
title: '宽度(像素)',
dataIndex: 'width',
width: 150,
},
{
title: '操作',
dataIndex: 'operate',
width: 150,
rowDrag: true,
},
];
// --------------------- 表格移动【拖拽移动、上移、下移】 --------------------------------
//初始化拖拽
function initDrag() {
let tbody = document.querySelector('#smartTableColumnModalTable tbody');
Sortable.create(tbody, {
animation: 300,
dragClass: 'smart-ghost-class', //设置拖拽样式类名
ghostClass: 'smart-ghost-class', //设置拖拽停靠样式类名
chosenClass: 'smart-ghost-class', //设置选中样式类名
handle: '.handle',
onEnd({ newIndex, oldIndex }) {
if (newIndex === oldIndex) {
return;
}
moveTableData(oldIndex, newIndex);
},
});
}
//上移
function up(oldIndex) {
let newIndex = oldIndex - 1;
if (newIndex < 0) {
return;
}
//如果下一个是固定列,则也不可移动
if (tableData.value[newIndex].fixed) {
return;
}
moveTableData(oldIndex, newIndex);
}
//下移
function down(oldIndex) {
let newIndex = oldIndex + 1;
if (newIndex >= tableData.value.length) {
return;
}
//如果下一个是固定列,则也不可移动
if (tableData.value[newIndex].fixed) {
return;
}
moveTableData(oldIndex, newIndex);
}
//移动表格数据
function moveTableData(oldIndex, newIndex) {
const currRow = tableData.value.splice(oldIndex, 1)[0];
tableData.value.splice(newIndex, 0, currRow);
}
// ----------- table 批量操作 start -----------
const selectedRowKeyList = ref([]);
function onSelectChange(keyArray) {
selectedRowKeyList.value = keyArray;
}
// -------------------------提交表单【恢复默认、保存、取消】 ------------------------
const submitLoading = ref(false);
//重置
function reset() {
Modal.confirm({
title: '确定要恢复默认吗?',
content: '确定恢复默认后,该信息将不可恢复',
okText: '确定恢复',
okType: 'danger',
onOk() {
(async () => {
submitLoading.value = true;
try {
await tableColumnApi.deleteColumns(tableId);
message.success('恢复默认成功');
emit('change', []);
hide();
} catch (e) {
smartSentry.captureError(e);
} finally {
submitLoading.value = false;
}
})();
},
cancelText: '取消',
onCancel() {},
});
}
//保存
async function save() {
submitLoading.value = true;
try {
let columnList = [];
for (let index = 0; index < tableData.value.length; index++) {
let item = tableData.value[index];
let column = {
columnKey: item.columnKey,
sort: index + 1,
};
if (item.width) {
column.width = item.width;
}
column.showFlag = selectedRowKeyList.value.indexOf(item.columnKey) > -1;
columnList.push(column);
}
columnList = _.sortBy(columnList, (e) => e.sort);
await tableColumnApi.updateTableColumn({
tableId,
columnList,
});
message.success('保存成功');
emit('change', columnList);
hide();
} catch (e) {
smartSentry.captureError(e);
} finally {
submitLoading.value = false;
}
}
</script>
<style scoped lang="less">
.column-row:hover {
background-color: red !important;
}
.column-row {
cursor: pointer;
}
.blue-background-class {
background-color: red !important;
}
:deep(.ant-table-tbody) {
.ant-table-row-selected > td {
background-color: #ffffff;
}
}
</style>