feat(card-list): 添加字段列数配置支持多列布局
- 新增 fieldColumns 配置项控制卡片内字段排列列数 - 支持通过 colSpan 设置字段跨列显示 - 优化卡片内容布局样式和字段显示效果 - 调整对账模块相关页面布局
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
VITE_BASE=/
|
VITE_BASE=/
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_GLOB_API_URL=http://192.168.110.100:9000/finance
|
VITE_GLOB_API_URL=http://59.110.212.44:9000/finance
|
||||||
|
|
||||||
# 是否开启压缩,可以设置为 none, brotli, gzip
|
# 是否开启压缩,可以设置为 none, brotli, gzip
|
||||||
VITE_COMPRESS=none
|
VITE_COMPRESS=none
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineComponent, ref, watch } from 'vue';
|
import { defineComponent, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { Button, Divider, Input, Select, Space } from 'ant-design-vue';
|
import { Button, Divider, Input, Select } from 'ant-design-vue';
|
||||||
|
|
||||||
export interface RemoteOption {
|
export interface RemoteOption {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -70,15 +70,20 @@ const addItem = (e: Event) => {
|
|||||||
<template #dropdownRender="{ menuNode: menu }">
|
<template #dropdownRender="{ menuNode: menu }">
|
||||||
<VNodes :vnodes="menu" />
|
<VNodes :vnodes="menu" />
|
||||||
<Divider style="margin: 4px 0" />
|
<Divider style="margin: 4px 0" />
|
||||||
<Space style="padding: 4px 8px">
|
<div style="padding: 4px 8px; display: flex">
|
||||||
<Input ref="inputRef" v-model:value="inputValue" placeholder="在此手动输入" />
|
<Input
|
||||||
|
ref="inputRef"
|
||||||
|
v-model:value="inputValue"
|
||||||
|
placeholder="在此手动输入"
|
||||||
|
style="flex: 1"
|
||||||
|
/>
|
||||||
<Button type="text" @click="addItem">
|
<Button type="text" @click="addItem">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<!-- <PlusOutlined /> -->
|
<!-- <PlusOutlined /> -->
|
||||||
</template>
|
</template>
|
||||||
新增
|
新增
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Select>
|
</Select>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ function getDefaultState(): CardListProps {
|
|||||||
data: [],
|
data: [],
|
||||||
showTitle: true,
|
showTitle: true,
|
||||||
gridColumns: 3,
|
gridColumns: 3,
|
||||||
|
fieldColumns: 1,
|
||||||
pagerConfig: {
|
pagerConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
current: 1,
|
current: 1,
|
||||||
|
|||||||
@@ -73,6 +73,40 @@ const cardStyle = (item: any) => {
|
|||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 卡片内容样式
|
||||||
|
const cardContentStyle = computed(() => {
|
||||||
|
const fieldColumns = gridOptions.value?.fieldColumns || 1;
|
||||||
|
|
||||||
|
if (fieldColumns > 1) {
|
||||||
|
return {
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: `repeat(${fieldColumns}, 1fr)`,
|
||||||
|
columnGap: '10px', // 控制列间距
|
||||||
|
rowGap: '8px', // 控制行间距,设置更小的值
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
|
// 卡片字段样式
|
||||||
|
const cardFieldStyle = (column: any) => {
|
||||||
|
const fieldColumns = gridOptions.value?.fieldColumns || 1;
|
||||||
|
const colSpan = column?.colSpan || 1;
|
||||||
|
|
||||||
|
if (fieldColumns > 1) {
|
||||||
|
return {
|
||||||
|
marginBottom: '0px',
|
||||||
|
paddingBottom: '0px',
|
||||||
|
height: 'auto',
|
||||||
|
lineHeight: 'normal',
|
||||||
|
gridColumn: `span ${colSpan}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
// const errorCardStyle = (item: any) => {
|
// const errorCardStyle = (item: any) => {
|
||||||
// const errorData = gridOptions.value?.errorData || [];
|
// const errorData = gridOptions.value?.errorData || [];
|
||||||
// return errorData.some((errorItem) => errorItem.id === item.id)
|
// return errorData.some((errorItem) => errorItem.id === item.id)
|
||||||
@@ -234,11 +268,12 @@ onUnmounted(() => {
|
|||||||
<slot name="card-extra" :row="item" :index="index"></slot>
|
<slot name="card-extra" :row="item" :index="index"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content" :style="cardContentStyle">
|
||||||
<div
|
<div
|
||||||
v-for="column in gridOptions?.columns"
|
v-for="column in gridOptions?.columns"
|
||||||
:key="column?.field || ''"
|
:key="column?.field || ''"
|
||||||
class="card-field"
|
class="card-field"
|
||||||
|
:style="cardFieldStyle(column)"
|
||||||
v-show="
|
v-show="
|
||||||
!column?.show ||
|
!column?.show ||
|
||||||
(typeof column.show === 'function' ? column.show(item) : column.show)
|
(typeof column.show === 'function' ? column.show(item) : column.show)
|
||||||
@@ -290,27 +325,26 @@ onUnmounted(() => {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.card-content {
|
.card-content {
|
||||||
.card-field {
|
.card-field {
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-item {
|
.field-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
.field-title {
|
.field-title {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: rgba(0, 0, 0, 0.85);
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-value {
|
.field-value {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
color: rgba(0, 0, 0, 0.65);
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
&.field-edit {
|
&.field-edit {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -349,7 +383,6 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-content {
|
.card-content {
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
min-width: 0; // 防止内容撑开
|
min-width: 0; // 防止内容撑开
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ export interface CardListColumn<T = any> {
|
|||||||
show?: ((row: T) => boolean) | boolean;
|
show?: ((row: T) => boolean) | boolean;
|
||||||
/** 编辑渲染组件 */
|
/** 编辑渲染组件 */
|
||||||
editRender?: { name: string; props?: Record<string, any> };
|
editRender?: { name: string; props?: Record<string, any> };
|
||||||
|
/** 字段占列数 */
|
||||||
|
colSpan?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CardListPagination {
|
export interface CardListPagination {
|
||||||
@@ -49,6 +51,8 @@ export interface CardListOptions<T = any> {
|
|||||||
cardClass?: string;
|
cardClass?: string;
|
||||||
/** 网格列数 */
|
/** 网格列数 */
|
||||||
gridColumns?: number;
|
gridColumns?: number;
|
||||||
|
/** 字段列数,控制卡片内字段排列的列数 */
|
||||||
|
fieldColumns?: number;
|
||||||
/** 网格高度 */
|
/** 网格高度 */
|
||||||
gridHeight?: string;
|
gridHeight?: string;
|
||||||
/** 分页配置 */
|
/** 分页配置 */
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ const routes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// meta: {
|
// meta: {
|
||||||
// title: '用户管理2',
|
// title: '测试',
|
||||||
// },
|
// },
|
||||||
// name: 'Users2',
|
// name: 'Test',
|
||||||
// path: '/system/users2',
|
// path: '/system/test',
|
||||||
// component: () => import('#/components/CardListDemo.vue'),
|
// component: () => import('#/views/test.vue'),
|
||||||
// },
|
// },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ const gridOptions = computed(() => ({
|
|||||||
},
|
},
|
||||||
field: 'tel',
|
field: 'tel',
|
||||||
title: '用户手机号',
|
title: '用户手机号',
|
||||||
|
colSpan: 2,
|
||||||
},
|
},
|
||||||
{ editRender: { name: 'Input' }, field: 'orderMoney', title: '订单金额' },
|
{ editRender: { name: 'Input' }, field: 'orderMoney', title: '订单金额' },
|
||||||
{ editRender: { name: 'Input' }, field: 'realMoney', title: '实际金额' },
|
{ editRender: { name: 'Input' }, field: 'realMoney', title: '实际金额' },
|
||||||
@@ -107,6 +108,8 @@ const gridOptions = computed(() => ({
|
|||||||
name: 'Select',
|
name: 'Select',
|
||||||
props: {
|
props: {
|
||||||
options: [
|
options: [
|
||||||
|
{ label: '1个月', value: '1' },
|
||||||
|
{ label: '3个月', value: '3' },
|
||||||
{ label: '半年', value: '6' },
|
{ label: '半年', value: '6' },
|
||||||
{ label: '一年', value: '12' },
|
{ label: '一年', value: '12' },
|
||||||
{ label: '两年', value: '24' },
|
{ label: '两年', value: '24' },
|
||||||
@@ -123,9 +126,10 @@ const gridOptions = computed(() => ({
|
|||||||
],
|
],
|
||||||
showTitle: true,
|
showTitle: true,
|
||||||
titleField: 'productName',
|
titleField: 'productName',
|
||||||
gridColumns: 4,
|
gridColumns: 3,
|
||||||
gridHeight: '355px',
|
fieldColumns: 2,
|
||||||
cardHeight: '345px',
|
gridHeight: '220px',
|
||||||
|
cardHeight: '210px',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const [Grid, gridApi] = useCardList<CreateOrderType>({
|
const [Grid, gridApi] = useCardList<CreateOrderType>({
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ function onCompleteCheckCreated() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<div class="flex flex-1 flex-col gap-2">
|
<div class="flex w-3/4 flex-1 flex-col gap-2">
|
||||||
<Card
|
<Card
|
||||||
:tab-list="tabList"
|
:tab-list="tabList"
|
||||||
:active-tab-key="activeTabKey"
|
:active-tab-key="activeTabKey"
|
||||||
@@ -293,7 +293,7 @@ function onCompleteCheckCreated() {
|
|||||||
<Card
|
<Card
|
||||||
v-if="activeTabKey !== '0'"
|
v-if="activeTabKey !== '0'"
|
||||||
:title="`已选列表(${selectedData.length})`"
|
:title="`已选列表(${selectedData.length})`"
|
||||||
class="h-[405px] w-full"
|
class="h-[270px] w-full"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
@@ -322,6 +322,7 @@ function onCompleteCheckCreated() {
|
|||||||
padding: 5px !important;
|
padding: 5px !important;
|
||||||
}
|
}
|
||||||
.order-card {
|
.order-card {
|
||||||
|
width: 100%;
|
||||||
:deep(.ant-card-body) {
|
:deep(.ant-card-body) {
|
||||||
padding: 1px !important;
|
padding: 1px !important;
|
||||||
height: calc(100% - 46px); // 减去标签页头部高度
|
height: calc(100% - 46px); // 减去标签页头部高度
|
||||||
|
|||||||
14
apps/finance/src/views/test.vue
Normal file
14
apps/finance/src/views/test.vue
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { TabPane, Tabs } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const activeKey = ref(1);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Tabs v-model:active-key="activeKey" :style="{ height: '200px' }">
|
||||||
|
<TabPane v-for="i in 30" :key="i" :tab="`Tab-${i}`">Content of tab {{ i }}</TabPane>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
Reference in New Issue
Block a user