websocket、字典、配置
This commit is contained in:
parent
62c0b86313
commit
6d16d72e3e
18
src/App.vue
18
src/App.vue
@ -5,24 +5,30 @@
|
||||
<transition v-if="isLock && $route.name !== 'login'" name="slide-up">
|
||||
<LockScreen />
|
||||
</transition>
|
||||
<global-websocket :uri="'/api/websocket/'+userInfo.id" @rollback="rollback" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, onUnmounted } from 'vue';
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
import { computed, onMounted, onUnmounted,defineAsyncComponent ,h } from 'vue';
|
||||
import { ConfigProvider,notification } from 'ant-design-vue';
|
||||
import { LockScreen } from '@/components/Lockscreen';
|
||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import zhCN from 'ant-design-vue/es/locale/zh_CN';
|
||||
import dayjs from 'dayjs';
|
||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||
import Watermark from '@/utils/wartermark';
|
||||
import { initWebSocket,sendWebSocket } from '@/components/Websocket/index';
|
||||
const GlobalWebsocket = defineAsyncComponent(() => import('@/components/Websocket/index.vue'));
|
||||
import 'dayjs/locale/zh-cn';
|
||||
dayjs.locale('zh-cn');
|
||||
|
||||
const route = useRoute();
|
||||
const locale = zhCN;
|
||||
const useLockscreen = useLockscreenStore();
|
||||
const userStore = useUserStore();
|
||||
const userInfo: object = userStore.getUserInfo || {};
|
||||
const isLock = computed(() => useLockscreen.isLock);
|
||||
const lockTime = computed(() => useLockscreen.lockTime);
|
||||
const {getIsWaterMark} = useProjectSetting();
|
||||
@ -45,7 +51,13 @@
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const rollback = (msg)=>{
|
||||
notification.info({
|
||||
message: '通知',
|
||||
description: () =>
|
||||
h('div', msg),
|
||||
});
|
||||
}
|
||||
onMounted(() => {
|
||||
if(getIsWaterMark.value) {
|
||||
const waterText = import.meta.env.VITE_GLOB_APP_TITLE;
|
||||
|
155
src/components/Websocket/index.vue
Normal file
155
src/components/Websocket/index.vue
Normal file
@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script setup lang="ts" name="global-websocket">
|
||||
import { reactive, ref, computed,onMounted,onUnmounted } from 'vue';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
const emit = defineEmits(['rollback']);
|
||||
|
||||
const props = defineProps({
|
||||
uri: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
webSocket: ref(), // webSocket实例
|
||||
lockReconnect: false, // 重连锁,避免多次重连
|
||||
maxReconnect: 6, // 最大重连次数, -1 标识无限重连
|
||||
reconnectTime: 0, // 重连尝试次数
|
||||
heartbeat: {
|
||||
interval: 30 * 1000, // 心跳间隔时间
|
||||
timeout: 10 * 1000, // 响应超时时间
|
||||
pingTimeoutObj: ref(), // 延时发送心跳的定时器
|
||||
pongTimeoutObj: ref(), // 接收心跳响应的定时器
|
||||
pingMessage: JSON.stringify({ type: 'ping' }), // 心跳请求信息
|
||||
},
|
||||
});
|
||||
|
||||
const token = computed(() => {
|
||||
return useUserStore().getToken;
|
||||
});
|
||||
|
||||
const tenant = computed(() => {
|
||||
return Session.getTenant();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
initWebSocket();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
state.webSocket.close();
|
||||
clearTimeoutObj(state.heartbeat);
|
||||
});
|
||||
|
||||
const initWebSocket = () => {
|
||||
// ws地址
|
||||
let host = window.location.host;
|
||||
let wsUri =`${location.protocol === 'https:' ? 'wss' : 'ws'}://${host}${props.uri}`;
|
||||
|
||||
// 建立连接
|
||||
state.webSocket = new WebSocket(wsUri);
|
||||
// 连接成功
|
||||
state.webSocket.onopen = onOpen;
|
||||
// 连接错误
|
||||
state.webSocket.onerror = onError;
|
||||
// 接收信息
|
||||
state.webSocket.onmessage = onMessage;
|
||||
// 连接关闭
|
||||
state.webSocket.onclose = onClose;
|
||||
};
|
||||
|
||||
const reconnect = () => {
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
if (state.lockReconnect || (state.maxReconnect !== -1 && state.reconnectTime > state.maxReconnect)) {
|
||||
return;
|
||||
}
|
||||
state.lockReconnect = true;
|
||||
setTimeout(() => {
|
||||
state.reconnectTime++;
|
||||
// 建立新连接
|
||||
initWebSocket();
|
||||
state.lockReconnect = false;
|
||||
}, 5000);
|
||||
};
|
||||
/**
|
||||
* 清空定时器
|
||||
*/
|
||||
const clearTimeoutObj = (heartbeat: any) => {
|
||||
heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj);
|
||||
heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj);
|
||||
};
|
||||
/**
|
||||
* 开启心跳
|
||||
*/
|
||||
const startHeartbeat = () => {
|
||||
const webSocket = state.webSocket;
|
||||
const heartbeat = state.heartbeat;
|
||||
// 清空定时器
|
||||
clearTimeoutObj(heartbeat);
|
||||
// 延时发送下一次心跳
|
||||
heartbeat.pingTimeoutObj = setTimeout(() => {
|
||||
// 如果连接正常
|
||||
if (webSocket.readyState === 1) {
|
||||
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
||||
webSocket.send(heartbeat.pingMessage);
|
||||
// 心跳发送后,如果服务器超时未响应则断开,如果响应了会被重置心跳定时器
|
||||
heartbeat.pongTimeoutObj = setTimeout(() => {
|
||||
webSocket.close();
|
||||
}, heartbeat.timeout);
|
||||
} else {
|
||||
// 否则重连
|
||||
reconnect();
|
||||
}
|
||||
}, heartbeat.interval);
|
||||
};
|
||||
|
||||
/**
|
||||
* 连接成功事件
|
||||
*/
|
||||
const onOpen = () => {
|
||||
//开启心跳
|
||||
startHeartbeat();
|
||||
state.reconnectTime = 0;
|
||||
};
|
||||
/**
|
||||
* 连接失败事件
|
||||
* @param e
|
||||
*/
|
||||
const onError = () => {
|
||||
//重连
|
||||
reconnect();
|
||||
};
|
||||
|
||||
/**
|
||||
* 连接关闭事件
|
||||
* @param e
|
||||
*/
|
||||
const onClose = () => {
|
||||
//重连
|
||||
reconnect();
|
||||
};
|
||||
/**
|
||||
* 接收服务器推送的信息
|
||||
* @param msgEvent
|
||||
*/
|
||||
const onMessage = (msgEvent: any) => {
|
||||
//收到服务器信息,心跳重置并发送
|
||||
startHeartbeat();
|
||||
// if (msgEvent.data.indexOf('pong') > 0) {
|
||||
// return;
|
||||
// }
|
||||
// let text =''
|
||||
// try{
|
||||
// text = JSON.parse(msgEvent.data);
|
||||
// }catch(e){
|
||||
// return
|
||||
// }
|
||||
|
||||
emit('rollback', msgEvent.data);
|
||||
};
|
||||
</script>
|
@ -1,10 +1,6 @@
|
||||
import { h } from 'vue';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
},
|
||||
{
|
||||
title: '配置名称',
|
||||
dataIndex: 'name',
|
||||
@ -17,4 +13,11 @@ export const columns = [
|
||||
title: '排序',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
},
|
||||
];
|
||||
|
@ -1,9 +1,8 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<a-row :gutter="10" class="mt-3">
|
||||
<a-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-card shadow="hover" class="border-0">
|
||||
<template #title>
|
||||
<a-space>
|
||||
<a-input
|
||||
type="text"
|
||||
@ -13,10 +12,7 @@
|
||||
/>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="
|
||||
pager.page = 1;
|
||||
loadDataTable();
|
||||
"
|
||||
@click="reloadTable"
|
||||
>
|
||||
<template #icon> <SearchOutlined /> </template>查询
|
||||
</a-button>
|
||||
@ -29,37 +25,40 @@
|
||||
</template>
|
||||
新建
|
||||
</a-button>
|
||||
<a-button type="warning" @click="handleEdit" v-perm="['sys:config:edit']">
|
||||
<template #icon> <EditOutlined /> </template>编辑
|
||||
</a-button>
|
||||
<a-button type="danger" @click="handleDelete()" v-perm="['sys:config:delete']">
|
||||
<a-button type="danger" @click="handleDelete()" v-perm="['sys:config:delete']" :disabled="!selectionData.length">
|
||||
<template #icon> <DeleteOutlined /> </template>删除
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
:showTableSetting="false"
|
||||
ref="tableRef"
|
||||
:row-selection="{ onChange: onSelectionChange }"
|
||||
:customRow="rowClick"
|
||||
:row-class-name="setRowClassName"
|
||||
:pagination="{showQuickJumper:false,showSizeChanger:false}"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleEdit(record.id)" v-perm="['sys:dict:update']">
|
||||
<template #icon><EditOutlined /></template>
|
||||
编辑
|
||||
</a-button>
|
||||
<a-button type="primary" danger @click="handleDelete(record.id)" v-perm="['sys:dict:delete']">
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
删除
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
<div :style="{ height: fwbHeight + 'px' }" class="dict-list-box">
|
||||
<div
|
||||
v-for="(item, index) in configDataList"
|
||||
:key="index"
|
||||
@click="onCheckedRow(item)"
|
||||
class="dict-item"
|
||||
:class="item.id == configId ? 'active' : ''"
|
||||
>
|
||||
<span class="t1"
|
||||
>{{ item.name }}<span class="t2">({{ item.code }})</span></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<pagination
|
||||
style="justify-content: flex-end"
|
||||
class="mt-10 flex"
|
||||
@change="loadDataTable"
|
||||
v-model="pager"
|
||||
/>
|
||||
</BasicTable>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17">
|
||||
<a-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
|
||||
<a-card shadow="hover" class="mb-4 border-0 proCard">
|
||||
<configItem :configId="configId" v-if="configItemShow" />
|
||||
</a-card>
|
||||
@ -80,6 +79,7 @@
|
||||
import { getConfigList, configDelete } from '@/api/data/config';
|
||||
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue';
|
||||
import configItem from './configItem.vue';
|
||||
import { columns } from './columns';
|
||||
import { Modal, message } from 'ant-design-vue';
|
||||
|
||||
/**
|
||||
@ -92,7 +92,9 @@
|
||||
*/
|
||||
const configId = ref(0);
|
||||
const configItemShow = ref(false);
|
||||
const tableRef = ref();
|
||||
const editVisible = ref(false);
|
||||
const selectionData = ref([]);
|
||||
|
||||
/**
|
||||
* 定义查询参数
|
||||
@ -100,17 +102,7 @@
|
||||
const params = ref({
|
||||
name: '',
|
||||
});
|
||||
const configDataList = ref([]);
|
||||
|
||||
/**
|
||||
* 定义分页参数
|
||||
*/
|
||||
const pager = ref({
|
||||
page: 1,
|
||||
size: 10,
|
||||
count: configDataList.value.length,
|
||||
});
|
||||
const fwbHeight = document.body.clientHeight - 370;
|
||||
|
||||
/**
|
||||
* 执行添加
|
||||
@ -124,7 +116,9 @@
|
||||
/**
|
||||
* 执行编辑
|
||||
*/
|
||||
const handleEdit = () => {
|
||||
const handleEdit = async(id) => {
|
||||
configId.value = id;
|
||||
await nextTick();
|
||||
editVisible.value = true;
|
||||
};
|
||||
|
||||
@ -136,36 +130,61 @@
|
||||
configId.value = row.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新字典项值列表
|
||||
*/
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({ pageNo: 1 });
|
||||
}
|
||||
/**
|
||||
* 加载数据列表
|
||||
*/
|
||||
const loadDataTable = async () => {
|
||||
const result = await getConfigList({
|
||||
...params.value,
|
||||
pageNo: pager.value.page,
|
||||
pageSize: pager.value.size,
|
||||
});
|
||||
configId.value = result?.records[0]?.id;
|
||||
configItemShow.value = true;
|
||||
configDataList.value = result.records;
|
||||
pager.value.count = result.total;
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getConfigList({ ...params.value, ...res });
|
||||
configId.value = result?.records[0]?.id
|
||||
configItemShow.value = true
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* 执行删除
|
||||
*/
|
||||
async function handleDelete() {
|
||||
async function handleDelete(id) {
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除?',
|
||||
onOk: async () => {
|
||||
configDelete(configId.value);
|
||||
id ? await configDelete(id) : await configBatchDelete(selectionData.value);
|
||||
message.success('删除成功');
|
||||
pager.value.page = 1;
|
||||
loadDataTable();
|
||||
reloadTable();
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 选项发生变化
|
||||
* @param value 参数
|
||||
*/
|
||||
function onSelectionChange(value) {
|
||||
selectionData.value = value;
|
||||
}
|
||||
/**
|
||||
* 数据行点击事件
|
||||
* @param record 参数
|
||||
*/
|
||||
const rowClick = (record) => {
|
||||
return {
|
||||
onClick: () => {
|
||||
configId.value = record.id;
|
||||
},
|
||||
};
|
||||
};
|
||||
/**
|
||||
* 设置选项行类名
|
||||
* @param record 参数
|
||||
*/
|
||||
const setRowClassName = (record) => {
|
||||
return record.id === configId.value ? 'clickRowStyle' : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* 钩子函数
|
||||
@ -220,3 +239,18 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.ant-table-tbody {
|
||||
.ant-table-row.clickRowStyle,
|
||||
.ant-table-cell-row.clickRowStyle {
|
||||
td {
|
||||
background-color: #e7eeff !important;
|
||||
}
|
||||
&:hover {
|
||||
td {
|
||||
background-color: #e7eeff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,10 +1,6 @@
|
||||
import { h } from 'vue';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
},
|
||||
{
|
||||
title: '字典名称',
|
||||
dataIndex: 'name',
|
||||
@ -13,4 +9,11 @@ export const columns = [
|
||||
title: '字典编码',
|
||||
dataIndex: 'code',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
},
|
||||
];
|
||||
|
@ -1,9 +1,8 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<a-row :gutter="10" class="mt-3">
|
||||
<a-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7">
|
||||
<a-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
|
||||
<a-card shadow="hover" class="border-0">
|
||||
<template #title>
|
||||
<a-space>
|
||||
<a-input
|
||||
type="text"
|
||||
@ -14,13 +13,14 @@
|
||||
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="
|
||||
pager.page = 1;
|
||||
loadDataTable();
|
||||
"
|
||||
@click="reloadTable"
|
||||
>
|
||||
<template #icon> <SearchOutlined /> </template>查询
|
||||
</a-button>
|
||||
|
||||
</a-space>
|
||||
<div style="margin-top: 15px">
|
||||
<a-space>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="dictRefresh"
|
||||
@ -28,46 +28,46 @@
|
||||
>
|
||||
<template #icon> <RedoOutlined /> </template>刷新缓存</a-button
|
||||
>
|
||||
</a-space>
|
||||
<div style="margin-top: 15px">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleAdd" v-perm="['sys:dict:add']">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
新建
|
||||
</a-button>
|
||||
<a-button type="warning" @click="handleEdit" v-perm="['sys:dict:edit']">
|
||||
<template #icon> <EditOutlined /> </template>编辑
|
||||
</a-button>
|
||||
<a-button type="danger" @click="handleDelete()" v-perm="['sys:dict:delete']">
|
||||
<a-button type="danger" @click="handleDelete()" v-perm="['sys:dict:delete']" :disabled="!selectionData.length">
|
||||
<template #icon> <DeleteOutlined /> </template>删除
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
:showTableSetting="false"
|
||||
ref="tableRef"
|
||||
:row-selection="{ onChange: onSelectionChange }"
|
||||
:customRow="rowClick"
|
||||
:row-class-name="setRowClassName"
|
||||
:pagination="{showQuickJumper:false,showSizeChanger:false}"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleEdit(record.id)" v-perm="['sys:dict:update']">
|
||||
<template #icon><EditOutlined /></template>
|
||||
编辑
|
||||
</a-button>
|
||||
<a-button type="primary" danger @click="handleDelete(record.id)" v-perm="['sys:dict:delete']">
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
删除
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
<div :style="{ height: fwbHeight + 'px' }" class="dict-list-box">
|
||||
<div
|
||||
v-for="(item, index) in dictDataList"
|
||||
:key="index"
|
||||
@click="onCheckedRow(item)"
|
||||
class="dict-item"
|
||||
:class="item.id == dictId ? 'active' : ''"
|
||||
>
|
||||
<span class="t1"
|
||||
>{{ item.name }}<span class="t2">({{ item.code }})</span></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<pagination
|
||||
style="justify-content: flex-end"
|
||||
class="mt-10 flex"
|
||||
@change="loadDataTable"
|
||||
v-model="pager"
|
||||
/>
|
||||
</BasicTable>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17">
|
||||
<a-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
|
||||
<a-card shadow="hover" class="mb-4 border-0 proCard">
|
||||
<dictItem :dictId="dictId" v-if="dictItemShow" />
|
||||
</a-card>
|
||||
@ -88,6 +88,7 @@
|
||||
import { getDictList, refreshCache, dictDelete } from '@/api/data/dictionary';
|
||||
import { PlusOutlined, EditOutlined, DeleteOutlined, RedoOutlined } from '@ant-design/icons-vue';
|
||||
import dictItem from './dictItem.vue';
|
||||
import { columns } from './columns';
|
||||
import { Modal, message } from 'ant-design-vue';
|
||||
|
||||
/**
|
||||
@ -100,7 +101,9 @@
|
||||
*/
|
||||
const dictId = ref(0);
|
||||
const dictItemShow = ref(false);
|
||||
const tableRef = ref();
|
||||
const editVisible = ref(false);
|
||||
const selectionData = ref([]);
|
||||
|
||||
/**
|
||||
* 定义查询参数
|
||||
@ -108,17 +111,6 @@
|
||||
const params = ref({
|
||||
name: '',
|
||||
});
|
||||
const dictDataList = ref([]);
|
||||
|
||||
/**
|
||||
* 定义分页参数
|
||||
*/
|
||||
const pager = ref({
|
||||
page: 1,
|
||||
size: 20,
|
||||
count: dictDataList.value.length,
|
||||
});
|
||||
const fwbHeight = document.body.clientHeight - 370;
|
||||
|
||||
/**
|
||||
* 添加字典
|
||||
@ -139,7 +131,9 @@
|
||||
/**
|
||||
* 执行编辑
|
||||
*/
|
||||
const handleEdit = () => {
|
||||
const handleEdit = async (id) => {
|
||||
dictId.value = id;
|
||||
await nextTick();
|
||||
editVisible.value = true;
|
||||
};
|
||||
|
||||
@ -151,37 +145,62 @@
|
||||
dictId.value = row.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新字典项值列表
|
||||
*/
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({ pageNo: 1 });
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载数据列表
|
||||
*/
|
||||
const loadDataTable = async () => {
|
||||
const result = await getDictList({
|
||||
...params.value,
|
||||
pageNo: pager.value.page,
|
||||
pageSize: pager.value.size,
|
||||
});
|
||||
dictId.value = result?.records[0]?.id;
|
||||
dictItemShow.value = true;
|
||||
dictDataList.value = result.records;
|
||||
pager.value.count = result.total;
|
||||
const loadDataTable = async (res: any) => {
|
||||
const result = await getDictList({ ...params.value, ...res });
|
||||
dictId.value = result?.records[0]?.id
|
||||
dictItemShow.value = true
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* 执行删除
|
||||
*/
|
||||
async function handleDelete() {
|
||||
async function handleDelete(id) {
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除?',
|
||||
onOk: async () => {
|
||||
dictDelete(dictId.value);
|
||||
id ? await dictDelete(id) : await dictBatchDelete(selectionData.value);
|
||||
message.success('删除成功');
|
||||
pager.value.page = 1;
|
||||
loadDataTable();
|
||||
reloadTable();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 选项发生变化
|
||||
* @param value 参数
|
||||
*/
|
||||
function onSelectionChange(value) {
|
||||
selectionData.value = value;
|
||||
}
|
||||
/**
|
||||
* 数据行点击事件
|
||||
* @param record 参数
|
||||
*/
|
||||
const rowClick = (record) => {
|
||||
return {
|
||||
onClick: () => {
|
||||
dictId.value = record.id;
|
||||
},
|
||||
};
|
||||
};
|
||||
/**
|
||||
* 设置选项行类名
|
||||
* @param record 参数
|
||||
*/
|
||||
const setRowClassName = (record) => {
|
||||
return record.id === dictId.value ? 'clickRowStyle' : '';
|
||||
};
|
||||
/**
|
||||
* 钩子函数
|
||||
*/
|
||||
@ -235,3 +254,18 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.ant-table-tbody {
|
||||
.ant-table-row.clickRowStyle,
|
||||
.ant-table-cell-row.clickRowStyle {
|
||||
td {
|
||||
background-color: #e7eeff !important;
|
||||
}
|
||||
&:hover {
|
||||
td {
|
||||
background-color: #e7eeff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user