import XinTable from '@/components/XinTable'; import { Badge, Image, Typography } from 'antd'; import type { ICarousel } from '@/domain/iCarousel'; import type { XinTableColumn } from '@/components/XinTable/typings'; import type { ISysFileInfo } from '@/domain/iSysFile'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; const { Title, Text } = Typography; /** * 从 image 字段中提取预览 URL * image 字段可能是 ISysFileInfo 对象或 URL 字符串 */ function getImageUrl(image: ISysFileInfo | string | null | undefined): string { if (!image) return ''; if (typeof image === 'string') return image; return image.preview_url || image.file_url || ''; } /** 首页轮播图管理 */ export default function CarouselPage() { const { t } = useTranslation(); const columns: XinTableColumn[] = [ { title: t('system.carousel.id'), dataIndex: 'id', hideInForm: true, width: 80, sorter: true, align: 'center', }, { title: t('system.carousel.title'), dataIndex: 'title', valueType: 'text', colProps: { span: 12 }, rules: [{ required: true, message: t('system.carousel.title.required') }], }, { title: t('system.carousel.image'), dataIndex: 'image_id', valueType: 'image', colProps: { span: 24 }, rules: [{ required: true, message: t('system.carousel.image.required') }], hideInSearch: true, fieldProps: { action: '/system/file/list/upload', mode: 'single', maxCount: 1, changeType: "id" }, render: (_value: ISysFileInfo | string, record: ICarousel) => { const url = getImageUrl(record.image); if (!url) return '-'; return ( ); }, }, { title: t('system.carousel.link'), dataIndex: 'link', valueType: 'text', colProps: { span: 12 }, hideInSearch: true, fieldProps: { placeholder: t('system.carousel.link.placeholder'), }, }, { title: t('system.carousel.status'), dataIndex: 'status', valueType: 'select', filters: [ { text: t('system.carousel.status.normal'), value: 0 }, { text: t('system.carousel.status.disabled'), value: 1 }, ], colProps: { span: 12 }, rules: [{ required: true, message: t('system.carousel.status.required') }], fieldProps: { options: [ { label: t('system.carousel.status.normal'), value: 0 }, { label: t('system.carousel.status.disabled'), value: 1 }, ], }, render: (value: number) => { return value === 0 ? : ; }, }, { title: t('system.carousel.sort'), dataIndex: 'sort', valueType: 'digit', colProps: { span: 12 }, hideInSearch: true, initialValue: 0, fieldProps: { min: 0, style: { width: '100%' }, }, }, { title: t('system.carousel.createdAt'), dataIndex: 'created_at', render: (value: string) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm') : '-'), hideInForm: true, hideInSearch: true, width: 160, }, ]; return ( <>
{t('system.carousel.page.title')} {t('system.carousel.page.description')}
api="/system/carousel" columns={columns} rowKey="id" accessName="system.carousel" formProps={{ grid: true, colProps: { span: 12 }, rowProps: { gutter: [30, 0] }, layout: 'vertical', }} modalProps={{ width: 800 }} searchProps={false} scroll={{ x: 1000 }} /> ); }