770 lines
24 KiB
Vue
770 lines
24 KiB
Vue
<!-- @format -->
|
||
|
||
<template>
|
||
<div class="ns-table" :class="{ 'ns-table-no-search': !(formConfig?.schemas.length > 0) }">
|
||
<!-- tabletitle -->
|
||
<!-- <div
|
||
class="ns-table-title"
|
||
@click="
|
||
() => {
|
||
showBack ? navigateBack() : '';
|
||
}
|
||
"
|
||
v-if="tableTitle">
|
||
<ns-icon v-if="showBack" class="backIcon" name="left" />{{ tableTitle }}
|
||
</div> -->
|
||
<div class="ns-table-container">
|
||
<!-- todo drag -->
|
||
|
||
<div class="ns-part-tree" v-if="!isEmpty(treeConfig)">
|
||
<ns-tree-api
|
||
ref="treeElRef"
|
||
v-bind="getTreeBindValue"
|
||
@reload="reload"
|
||
@select="treeSelect" />
|
||
</div>
|
||
<div class="ns-part-table">
|
||
<a-spin :spinning="tableState.loading">
|
||
<div class="ns-table-search" v-if="!isEmpty(formConfig)">
|
||
<ns-form
|
||
ref="formElRef"
|
||
class="ns-table-form"
|
||
:showAction="true"
|
||
v-bind="formConfig"
|
||
:expand="expand"
|
||
:showExpand="showExpand"
|
||
:expandAll="expandAll"
|
||
:title="formConfig.title"
|
||
:showExpandAll="showExpandAll"
|
||
:model="formModel"
|
||
@finish="formFinish" />
|
||
</div>
|
||
<div class="ns-table-main">
|
||
<ns-table-header
|
||
v-if="!isEmpty(headerActions) || tableTitle"
|
||
:headerActions="headerActions"
|
||
:searchData="formModel"
|
||
:tableTitle="tableTitle"
|
||
:data="tableState.selectedRows">
|
||
<template #header="data">
|
||
<slot name="header" v-bind="data || {}"></slot>
|
||
</template>
|
||
</ns-table-header>
|
||
<ns-basic-table ref="tableElRef" v-bind="getTableBindValues" :dataSource="tableData">
|
||
<template #emptyText>
|
||
<template v-if="tableState.loadError">
|
||
<div class="ns-table-content">
|
||
<div class="fetch-error">
|
||
<p>{{ tableState.loadErrorMessage }}</p>
|
||
<ns-button type="primary" ghost @click="reload">重新加载</ns-button></div
|
||
></div
|
||
>
|
||
</template>
|
||
<template v-else-if="tableState.loading"
|
||
><div class="ns-table-content"></div
|
||
></template>
|
||
<template v-else>
|
||
<div class="ns-table-content"> <a-empty /> </div>
|
||
</template>
|
||
</template>
|
||
|
||
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
|
||
<slot :name="item" v-bind="data || {}"></slot>
|
||
<template v-if="item === 'bodyCell'">
|
||
<template v-if="data?.column?.textEllipsis">
|
||
<span
|
||
class="tool-tips"
|
||
:style="{ width: `${data.column.textWidth || data.column.width}px` }">
|
||
<ns-tooltip
|
||
placement="top"
|
||
v-if="
|
||
data.column.customRender
|
||
? data.column.customRender(data)
|
||
: data.record[data.column.dataIndex]
|
||
">
|
||
<template #title>
|
||
<span>{{
|
||
data.column.customRender
|
||
? data.column.customRender(data)
|
||
: data.record[data.column.dataIndex] || '-'
|
||
}}</span>
|
||
</template>
|
||
<span class="text-ellipsis">{{
|
||
data.column.customRender
|
||
? data.column.customRender(data)
|
||
: data.record[data.column.dataIndex] || '-'
|
||
}}</span>
|
||
</ns-tooltip>
|
||
<span class="text-ellipsis" v-else> - </span>
|
||
</span>
|
||
</template>
|
||
<template v-if="data.column.dataIndex === 'tableAction'">
|
||
<ns-table-action
|
||
:data="data.record"
|
||
:searchData="formModel"
|
||
:columnActions="getColumnActions" />
|
||
</template>
|
||
<template v-if="data.column.edit">
|
||
<ns-table-cell
|
||
:value="data.text"
|
||
:record="data.record"
|
||
:column="data.column"
|
||
:index="data.index" />
|
||
</template>
|
||
</template>
|
||
<template v-if="item === 'footer'">
|
||
<ns-table-footer :footerActions="footerActions" :data="ediRowData" />
|
||
</template>
|
||
</template>
|
||
|
||
<template #bodyCell="data" v-if="!Object.keys($slots).includes('bodyCell')">
|
||
<template v-if="data.column.textEllipsis">
|
||
<span
|
||
class="tool-tips"
|
||
:style="{ width: `${data.column.textWidth || data.column.width}px` }">
|
||
<ns-tooltip
|
||
placement="top"
|
||
v-if="
|
||
data.column.customRender
|
||
? data.column.customRender(data)
|
||
: data.record[data.column.dataIndex]
|
||
">
|
||
<template #title>
|
||
<span>{{
|
||
data.column.customRender
|
||
? data.column.customRender(data)
|
||
: data.record[data.column.dataIndex] || '-'
|
||
}}</span>
|
||
</template>
|
||
<span class="text-ellipsis">{{
|
||
data.column.customRender
|
||
? data.column.customRender(data)
|
||
: data.record[data.column.dataIndex] || '-'
|
||
}}</span>
|
||
</ns-tooltip>
|
||
<span class="text-ellipsis" v-else> - </span>
|
||
</span>
|
||
</template>
|
||
<template v-if="data.column.dataIndex === 'tableAction'">
|
||
<ns-table-action
|
||
:data="data.record"
|
||
:searchData="formModel"
|
||
:columnActions="getColumnActions" />
|
||
</template>
|
||
<template v-if="data.column.edit">
|
||
<ns-table-cell
|
||
:value="data.text"
|
||
:record="data.record"
|
||
:column="data.column"
|
||
:index="data.index" />
|
||
</template>
|
||
</template>
|
||
|
||
<template
|
||
#footer
|
||
v-if="!Object.keys($slots).includes('footer') && !isEmpty(footerActions)">
|
||
<ns-table-footer :footerActions="footerActions" :data="ediRowData" />
|
||
</template>
|
||
</ns-basic-table>
|
||
</div>
|
||
</a-spin>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
import { computed, defineComponent, provide, reactive, ref, unref, watch } from 'vue';
|
||
import { RequestParams } from '/nerv-lib/component/table/table';
|
||
import {
|
||
cloneDeep,
|
||
debounce,
|
||
throttle,
|
||
get,
|
||
isArray,
|
||
isEmpty,
|
||
isEqual,
|
||
isFunction,
|
||
isObject,
|
||
isString,
|
||
isUndefined,
|
||
} from 'lodash-es';
|
||
import NsTableAction from './table-action.vue';
|
||
import NsTableHeader from './table-header.vue';
|
||
import NsTableFooter from './table-footer.vue';
|
||
import NsTableCell from './edit/table-cell.vue';
|
||
import { useParams } from '/nerv-lib/use/use-params';
|
||
import { transformColumns } from '/nerv-lib/component/table/table-columns';
|
||
import NsBasicTable from '/nerv-lib/component/table/basic-table.vue';
|
||
import { tableProps } from '/nerv-lib/component/table/props';
|
||
import { AxiosRequestConfig } from 'axios';
|
||
import { useApi } from '/nerv-lib/use/use-api';
|
||
import { useRoute } from 'vue-router';
|
||
import { useTableEdit } from '/nerv-lib/component/table/use-table-edit';
|
||
import { Form } from 'ant-design-vue';
|
||
import { stringUtil } from '/nerv-lib/util/string-util';
|
||
import { useTableRefresh } from '/nerv-lib/component/table/use-table-refresh';
|
||
import { tableConfig } from '/nerv-base/config/table.config';
|
||
import { useTableSession } from '/nerv-lib/component/table/use-table-session';
|
||
import { useTableColumn } from '/nerv-lib/component/table/use-table-column';
|
||
import { useNavigate } from '/nerv-lib/use/use-navigate';
|
||
import { object } from 'vue-types';
|
||
export default defineComponent({
|
||
name: 'NsTable',
|
||
components: {
|
||
NsBasicTable,
|
||
NsTableAction,
|
||
NsTableHeader,
|
||
NsTableFooter,
|
||
NsTableCell,
|
||
},
|
||
props: tableProps,
|
||
|
||
emits: ['cellChange', 'update:value', 'dataSourceChange', 'update:dataSource'],
|
||
setup(props, { attrs, emit }) {
|
||
const tableElRef = ref(null);
|
||
const formElRef = ref(null);
|
||
const treeElRef = ref(null);
|
||
const dataRef = ref([]);
|
||
const treeParamsRef = ref({});
|
||
const formParamsRef = ref({});
|
||
const orderRef = ref({});
|
||
const formModel = reactive<Recordable>({});
|
||
const tableData = ref<Recordable[]>([]);
|
||
const tableState = reactive({
|
||
selectedRowKeys: [],
|
||
selectedRows: [],
|
||
loading: false,
|
||
loadError: false,
|
||
loadErrorMessage: '',
|
||
loadinterval: 0,
|
||
});
|
||
const clearCheck = () => {
|
||
tableState.selectedRowKeys = [];
|
||
tableState.selectedRows = [];
|
||
};
|
||
const route = useRoute();
|
||
const { getColumnActionWidth } = useTableColumn({
|
||
columnActions: Object.assign({}, tableConfig.columnActions, props.columnActions),
|
||
});
|
||
const { navigateBack } = useNavigate();
|
||
const defaultPageRef = ref(1 - props.pageFieldOffset);
|
||
|
||
const { setTableSession } = useTableSession(
|
||
formModel,
|
||
formParamsRef,
|
||
defaultPageRef,
|
||
treeParamsRef,
|
||
);
|
||
|
||
const { delayFetch } = useTableRefresh({ props, reload });
|
||
|
||
watch(
|
||
[() => props.value, () => props.dataSource],
|
||
() => {
|
||
tableData.value = props.value || props.dataSource || [];
|
||
},
|
||
{
|
||
immediate: true,
|
||
},
|
||
);
|
||
|
||
const formItemContext = Form.useInjectFormItemContext();
|
||
|
||
const getColumnActions = computed(() => {
|
||
const { actions } = props.columnActions as any;
|
||
const _tableConfig = cloneDeep(tableConfig);
|
||
if (actions) {
|
||
_tableConfig.columnActions.width = getColumnActionWidth(actions);
|
||
}
|
||
return Object.assign(_tableConfig.columnActions, props.columnActions);
|
||
});
|
||
|
||
const getColumns = computed(() => {
|
||
const columns = transformColumns(cloneDeep(props.columns || []));
|
||
const { title, width, dataIndex, fixed } = getColumnActions.value;
|
||
if (props.columnActions) {
|
||
columns.push({
|
||
title,
|
||
width,
|
||
dataIndex,
|
||
fixed,
|
||
});
|
||
}
|
||
return columns;
|
||
});
|
||
|
||
watch(
|
||
() => tableData.value,
|
||
(val) => {
|
||
// console.log(val, tableData.value);
|
||
|
||
if (isEqual(val, tableData.value)) return;
|
||
|
||
const data = cloneDeep(tableData.value);
|
||
if (props.editable) {
|
||
Object.keys(data).forEach((key) => {
|
||
delete data[key][props.rowKey];
|
||
});
|
||
}
|
||
// emit('update:value', data);
|
||
emit('dataSourceChange', data);
|
||
formItemContext.onFieldChange();
|
||
},
|
||
{
|
||
deep: true,
|
||
},
|
||
);
|
||
|
||
const tableEdit = useTableEdit({
|
||
dataSource: tableData,
|
||
columns: getColumns,
|
||
rowKey: props.rowKey,
|
||
editable: ref(props.editable),
|
||
});
|
||
provide('tableEdit', tableEdit);
|
||
|
||
const { getParams } = useParams();
|
||
|
||
const rowSelection = computed(() => {
|
||
const { rowSelection } = props;
|
||
if (rowSelection === false || rowSelection === null) {
|
||
return null;
|
||
}
|
||
return Object.assign(
|
||
{
|
||
fixed: true,
|
||
columnWidth: 48,
|
||
preserveSelectedRowKeys: true, // 跨页选中默认不清除选中key
|
||
selectedRowKeys: tableState.selectedRowKeys,
|
||
onChange: (selectedRowKeys: never[], selectedRows: never[]) => {
|
||
tableState.selectedRowKeys = selectedRowKeys;
|
||
tableState.selectedRows = selectedRows;
|
||
},
|
||
},
|
||
isFunction(rowSelection) ? rowSelection(tableState) : rowSelection,
|
||
);
|
||
});
|
||
|
||
const customizeRenderEmpty = computed(() => {
|
||
return () => '暂无数据';
|
||
});
|
||
|
||
const formFinish = debounce((data: object) => {
|
||
formParamsRef.value = data;
|
||
fetch({
|
||
page: 1,
|
||
});
|
||
}, 300);
|
||
|
||
function setLoading(loading: boolean) {
|
||
tableState.loading = loading;
|
||
}
|
||
|
||
const tableChangeEvent = (pagination: Props, filters: [], sorter: any) => {
|
||
if (sorter?.field) {
|
||
if (sorter.order) {
|
||
orderRef.value = {
|
||
[props.paramsOrderField]: stringUtil.toLine(
|
||
`${sorter.field} ${sorter.order.replace('end', '')}`,
|
||
),
|
||
};
|
||
} else {
|
||
orderRef.value = { [props.paramsOrderField]: '' }; //覆盖默认params
|
||
}
|
||
fetch({
|
||
page: pagination?.current || getPagination.value?.current || 1,
|
||
pageSize: pagination?.pageSize,
|
||
});
|
||
} else if (pagination?.current) {
|
||
fetch({
|
||
page: pagination?.current,
|
||
pageSize: pagination.pageSize,
|
||
});
|
||
}
|
||
};
|
||
|
||
// pagination
|
||
const getPagination: Recordable | Boolean = computed(() => {
|
||
const { pagination } = props;
|
||
const { getPageParams } = attrs;
|
||
|
||
if (pagination) {
|
||
const current = get(dataRef.value, props.pageField);
|
||
|
||
function getTotal() {
|
||
let total = 0;
|
||
if (isFunction(getPageParams)) {
|
||
total = getPageParams(dataRef)['total'];
|
||
} else {
|
||
total = get(dataRef.value, props.totalField);
|
||
}
|
||
return total;
|
||
}
|
||
|
||
return {
|
||
showQuickJumper: true,
|
||
showLessItems: true,
|
||
showSizeChanger: true,
|
||
showTotal: (total: number, range: Array<number>) => {
|
||
return `显示第${range[0]}到${range[1]}条记录 ,共 ${
|
||
get(dataRef.value, props.totalField) || total
|
||
} 条记录`;
|
||
},
|
||
...(pagination as Props),
|
||
total: getTotal(),
|
||
current: (current >= 0 ? current : 1) + props.pageFieldOffset, // 后端1 开始
|
||
pageSize: get(dataRef.value, props.sizeField),
|
||
};
|
||
}
|
||
return false;
|
||
});
|
||
|
||
const getTableBindValues = computed(() => {
|
||
const { params, dynamicParams } = props;
|
||
return {
|
||
...attrs,
|
||
...props,
|
||
rowSelection: rowSelection.value,
|
||
params: dynamicParams
|
||
? getParams({ ...route.params, ...route.query }, dynamicParams, params)
|
||
: params || {},
|
||
columns: getColumns.value,
|
||
pagination: getPagination.value,
|
||
onChange: tableChangeEvent,
|
||
};
|
||
});
|
||
|
||
watch(
|
||
() => getTableBindValues.value.api,
|
||
() => {
|
||
// console.log(getTableBindValues.value.api);
|
||
// fetch(); //路由切换导致api切换 导致发送请求
|
||
},
|
||
{
|
||
immediate: true,
|
||
},
|
||
);
|
||
|
||
// watch(
|
||
// () => getTableBindValues.value.params,
|
||
// () => {
|
||
// fetch();
|
||
// },
|
||
// {
|
||
// immediate: true,
|
||
// },
|
||
// );
|
||
|
||
/**
|
||
* 请求函数
|
||
* @param requestParams 主要是传入页面,部分变量闭包处理
|
||
* @param clearDelay 是否需要清除刷新时间(页面操作之后,自动刷新重新计算)
|
||
*/
|
||
|
||
function fetch(requestParams: RequestParams = {}, clearDelay = true) {
|
||
clearDelay && delayFetch();
|
||
if (tableState.loadinterval) {
|
||
clearTimeout(tableState.loadinterval);
|
||
}
|
||
if (tableState.loading) {
|
||
tableState.loadinterval = setTimeout(() => {
|
||
fetch(requestParams, clearDelay);
|
||
}, 500);
|
||
return;
|
||
}
|
||
const { api, pagination } = props;
|
||
const { page, pageSize } = requestParams;
|
||
if (api) {
|
||
let pageParams: Recordable = {};
|
||
|
||
if (pagination !== false) {
|
||
pageParams = {
|
||
[props.paramsPageField]: page ? page - props.pageFieldOffset : defaultPageRef.value, // 后端0 开始
|
||
[props.paramsPageSizeField]:
|
||
pageSize || getPagination.value?.pageSize || props.defaultPageSize,
|
||
};
|
||
} else {
|
||
//判断是否是系统菜单页面过来,是的话修改分页总数dyfadd
|
||
if (props.tableTitle == '系统菜单') {
|
||
pageParams = {};
|
||
// [props.paramsPageField]: defaultPageRef.value, // 后端0 开始
|
||
// [props.paramsPageSizeField]:999,
|
||
} else {
|
||
pageParams = {
|
||
[props.paramsPageField]: defaultPageRef.value, // 后端0 开始
|
||
[props.paramsPageSizeField]:
|
||
pageSize || getPagination.value?.pageSize || props.defaultPageSize,
|
||
};
|
||
}
|
||
}
|
||
const httpParams = {
|
||
...getTableBindValues.value.params,
|
||
...pageParams,
|
||
...formParamsRef.value,
|
||
...treeParamsRef.value,
|
||
...orderRef.value,
|
||
};
|
||
if (!checkrequiredParams(httpParams)) {
|
||
console.log('check fail');
|
||
return;
|
||
}
|
||
setTableSession(pageParams[props.paramsPageField]);
|
||
|
||
clearDelay && setLoading(true);
|
||
|
||
const requestConfig: AxiosRequestConfig = { method: 'get' };
|
||
const { httpRequest } = useApi();
|
||
httpRequest({
|
||
api,
|
||
params: httpParams,
|
||
pathParams: { ...route.params, ...route.query },
|
||
requestConfig,
|
||
})
|
||
.then((res: any) => {
|
||
tableState.loadError = false;
|
||
tableState.loadErrorMessage = '';
|
||
dataRef.value = res;
|
||
|
||
tableData.value = get(unref(dataRef), props.listField);
|
||
|
||
//saas项目配置
|
||
if (attrs['getPageParams']) {
|
||
const getPageParams = attrs['getPageParams'];
|
||
let realPage = getPageParams(dataRef, pageParams.page)['page'];
|
||
if (realPage !== pageParams.page) {
|
||
fetch({ page: realPage });
|
||
}
|
||
}
|
||
emit('update:dataSource', tableData.value);
|
||
clearDelay && setLoading(false);
|
||
})
|
||
.catch((error: any) => {
|
||
const { response, code, message } = error || {};
|
||
let errMessage = response?.data?.msg;
|
||
const err: string = error?.toString?.() ?? '';
|
||
if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
|
||
errMessage = '接口请求超时,请刷新页面重试!';
|
||
}
|
||
if (err?.includes('Network Error')) {
|
||
errMessage = '网络异常,请检查您的网络连接是否正常!';
|
||
}
|
||
tableState.loadError = true;
|
||
tableState.loadErrorMessage = errMessage;
|
||
clearDelay && setLoading(false);
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检测requiredParams是否全部获得数据
|
||
* @param params
|
||
*/
|
||
function checkrequiredParams(params: Recordable) {
|
||
const { params: dynamicParams } = getTableBindValues.value as any;
|
||
let { requiredParams } = props;
|
||
if (requiredParams) {
|
||
if (requiredParams === true) requiredParams = dynamicParams as any;
|
||
if (isFunction(requiredParams)) {
|
||
console.error(
|
||
'Property dynamicParams of props cannot set to Function when using requiredParams',
|
||
);
|
||
return false;
|
||
} else {
|
||
if (isString(requiredParams)) {
|
||
if (isUndefined(params[requiredParams])) return false;
|
||
} else if (isArray(requiredParams)) {
|
||
for (let i = 0, l = requiredParams.length; i < l; i++) {
|
||
if (isUndefined(params[requiredParams[i]])) return false;
|
||
}
|
||
} else if (isObject(requiredParams)) {
|
||
const keys = Object.keys(requiredParams);
|
||
for (let i = 0, l = keys.length; i < l; i++) {
|
||
if (isUndefined(params[keys[i]])) return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function treeSelect(
|
||
selectedKeys: never[],
|
||
e: {
|
||
selected: boolean;
|
||
selectedNodes: { props: { dataRef: any } }[];
|
||
node: any;
|
||
event: any;
|
||
},
|
||
) {
|
||
console.log(selectedKeys, e);
|
||
const { dataRef } = e.node;
|
||
treeParamsRef.value = getParams(dataRef, getTreeBindValue.value.dynamicParams);
|
||
fetch({
|
||
page: 1,
|
||
});
|
||
}
|
||
|
||
const getTreeData = computed(() => {
|
||
return props?.treeConfig?.treeData || [];
|
||
});
|
||
|
||
const getTreeWidth = computed(() => {
|
||
return props?.treeConfig?.width || '300px';
|
||
});
|
||
|
||
const getTreeBindValue = computed(() => ({
|
||
...props?.treeConfig,
|
||
}));
|
||
//todo 异步加载|| 树形接口
|
||
|
||
function reload(clearDelay = true) {
|
||
const pagination = unref(getPagination);
|
||
fetch(
|
||
{
|
||
page: pagination === false ? 1 : pagination.current,
|
||
},
|
||
clearDelay,
|
||
);
|
||
}
|
||
|
||
provide('reload', reload); //提供刷新功能
|
||
provide('clearCheck', clearCheck); //提供清空选中功能
|
||
|
||
return {
|
||
navigateBack,
|
||
reload,
|
||
clearCheck,
|
||
formElRef,
|
||
treeElRef,
|
||
tableElRef,
|
||
getColumnActions,
|
||
getTableBindValues,
|
||
formModel,
|
||
tableState,
|
||
isEmpty,
|
||
formFinish,
|
||
tableChangeEvent,
|
||
treeSelect,
|
||
getTreeBindValue,
|
||
getTreeWidth,
|
||
getTreeData,
|
||
customizeRenderEmpty,
|
||
tableData,
|
||
treeParamsRef,
|
||
formParamsRef,
|
||
};
|
||
},
|
||
});
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.backIcon {
|
||
cursor: pointer;
|
||
margin-right: 6px;
|
||
}
|
||
.ns-table-title {
|
||
text-align: left;
|
||
height: 46px;
|
||
line-height: 46px;
|
||
//font-size: 16px;
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
user-select: text;
|
||
padding-left: 16px;
|
||
background: #fff;
|
||
width: calc(100% + 32px);
|
||
margin-left: -16px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.ns-table-container {
|
||
display: flex;
|
||
.ns-part-tree {
|
||
width: 255px; //设计需求 树改成255px
|
||
// padding: 16px;
|
||
overflow-y: auto;
|
||
}
|
||
.ns-part-table {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
}
|
||
:deep(.ant-spin-container) {
|
||
display: flex;
|
||
flex-direction: column;
|
||
.ns-table-main {
|
||
height: 100%;
|
||
}
|
||
}
|
||
.ns-table-content {
|
||
// background: #e5ebf0;
|
||
margin: 16px;
|
||
}
|
||
|
||
:deep(.ant-spin-nested-loading > div > .ant-spin) {
|
||
max-height: none;
|
||
}
|
||
.ns-table-search {
|
||
padding-top: 16px;
|
||
}
|
||
:deep(.ant-form-item) {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.ns-table {
|
||
position: relative;
|
||
// min-height: 400px;
|
||
// background: #e5ebf0;
|
||
.ant-spin-nested-loading {
|
||
height: 100%;
|
||
// min-height: 400px;
|
||
}
|
||
|
||
.ns-table-content {
|
||
min-height: 300px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.fetch-error {
|
||
p {
|
||
line-height: 40px;
|
||
padding: 0;
|
||
margin: 0;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.ant-btn {
|
||
width: 88px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.text-ellipsis {
|
||
display: inline-block;
|
||
vertical-align: top;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
max-width: 100%;
|
||
}
|
||
.tool-tips {
|
||
display: inline-block;
|
||
vertical-align: top;
|
||
padding: 0;
|
||
word-wrap: break-word;
|
||
word-break: break-word;
|
||
width: 100%;
|
||
}
|
||
//鼠标指上颜色
|
||
:deep(
|
||
.ant-table-tbody > tr.ant-table-row:hover > td,
|
||
.ant-table-tbody > tr > td.ant-table-cell-row-hover
|
||
) {
|
||
background: #f4f8ff !important;
|
||
}
|
||
</style>
|