fix: comprehensive UI fix — all table columns have explicit widths, no ellipsis on data, consistent scroll.x

This commit is contained in:
2026-07-06 16:56:35 +08:00
parent 26754dc3fa
commit be75437861
13 changed files with 73 additions and 63 deletions

View File

@@ -196,26 +196,30 @@ const BillsPage: React.FC = () => {
}; };
const columns = [ const columns = [
{ title: '学生', render: (_: any, r: any) => r.student?.name || '-' }, { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
{ title: '账单周期', render: (_: any, r: any) => `${r.periodStart} ~ ${r.periodEnd}` }, { title: '账单周期', width: 200, render: (_: any, r: any) => `${r.periodStart} ~ ${r.periodEnd}` },
{ {
title: '分摊费用', title: '分摊费用',
dataIndex: 'sharedAmount', dataIndex: 'sharedAmount',
width: 120,
render: (v: number) => `¥${Number(v).toFixed(2)}`, render: (v: number) => `¥${Number(v).toFixed(2)}`,
}, },
{ {
title: '个人费用', title: '个人费用',
dataIndex: 'personalAmount', dataIndex: 'personalAmount',
width: 120,
render: (v: number) => `¥${Number(v).toFixed(2)}`, render: (v: number) => `¥${Number(v).toFixed(2)}`,
}, },
{ {
title: '总计', title: '总计',
dataIndex: 'totalAmount', dataIndex: 'totalAmount',
width: 100,
render: (v: number) => <strong>¥{Number(v).toFixed(2)}</strong>, render: (v: number) => <strong>¥{Number(v).toFixed(2)}</strong>,
}, },
{ {
title: '可用押金', title: '可用押金',
dataIndex: 'availableDeposit', dataIndex: 'availableDeposit',
width: 120,
render: (v: number) => render: (v: number) =>
v > 0 ? ( v > 0 ? (
<span style={{ color: '#52c41a' }}>¥{Number(v).toFixed(2)}</span> <span style={{ color: '#52c41a' }}>¥{Number(v).toFixed(2)}</span>
@@ -226,6 +230,7 @@ const BillsPage: React.FC = () => {
{ {
title: '抵扣后应付', title: '抵扣后应付',
dataIndex: 'amountAfterDeposit', dataIndex: 'amountAfterDeposit',
width: 130,
render: (v: number, r: any) => { render: (v: number, r: any) => {
const has = Number(r.availableDeposit || 0) > 0; const has = Number(r.availableDeposit || 0) > 0;
if (!has) return <span style={{ color: '#999' }}>-</span>; if (!has) return <span style={{ color: '#999' }}>-</span>;
@@ -241,11 +246,13 @@ const BillsPage: React.FC = () => {
{ {
title: '状态', title: '状态',
dataIndex: 'status', dataIndex: 'status',
width: 90,
render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text}</Tag>, render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text}</Tag>,
}, },
{ {
title: '生成时间', title: '生成时间',
dataIndex: 'generatedAt', dataIndex: 'generatedAt',
width: 160,
render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm'), render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm'),
}, },
{ {

View File

@@ -152,7 +152,7 @@ const ClassesPage: React.FC = () => {
const columns: ColumnsType<ClassItem> = [ const columns: ColumnsType<ClassItem> = [
{ {
title: '班级名称', dataIndex: 'name', title: '班级名称', dataIndex: 'name', width: 120,
sorter: (a, b) => a.name.localeCompare(b.name), sorter: (a, b) => a.name.localeCompare(b.name),
}, },
{ title: '编码', dataIndex: 'code', width: 140 }, { title: '编码', dataIndex: 'code', width: 140 },

View File

@@ -164,7 +164,7 @@ const ClassroomRentalsPage: React.FC = () => {
const columns = [ const columns = [
{ {
title: '教室', title: '教室', width: 120,
dataIndex: 'classroom', dataIndex: 'classroom',
render: (c: any) => render: (c: any) =>
c ? ( c ? (
@@ -177,7 +177,7 @@ const ClassroomRentalsPage: React.FC = () => {
), ),
}, },
{ {
title: '租赁方', title: '租赁方', width: 100,
dataIndex: 'tenant', dataIndex: 'tenant',
render: (t: any) => render: (t: any) =>
t ? ( t ? (
@@ -188,19 +188,19 @@ const ClassroomRentalsPage: React.FC = () => {
'-' '-'
), ),
}, },
{ title: '开始日期', dataIndex: 'startDate' }, { title: '开始日期', dataIndex: 'startDate', width: 110 },
{ title: '结束日期', dataIndex: 'endDate' }, { title: '结束日期', dataIndex: 'endDate', width: 110 },
{ {
title: '时长', title: '时长', width: 80,
render: (_: any, r: any) => { render: (_: any, r: any) => {
const d = dayjs(r.endDate).diff(dayjs(r.startDate), 'day') + 1; const d = dayjs(r.endDate).diff(dayjs(r.startDate), 'day') + 1;
return `${d}`; return `${d}`;
}, },
}, },
{ title: '日租金', dataIndex: 'dailyRate', render: (v: any) => (v ? `¥${v}` : '-') }, { title: '日租金', dataIndex: 'dailyRate', width: 100, render: (v: any) => (v ? `¥${v}` : '-') },
{ title: '总额', dataIndex: 'totalAmount', render: (v: any) => (v ? `¥${v}` : '-') }, { title: '总额', dataIndex: 'totalAmount', width: 100, render: (v: any) => (v ? `¥${v}` : '-') },
{ {
title: '合同', title: '合同', width: 120,
dataIndex: 'contractPath', dataIndex: 'contractPath',
render: (v: string, r: any) => render: (v: string, r: any) =>
v ? ( v ? (

View File

@@ -136,22 +136,22 @@ const ClassroomsPage: React.FC = () => {
const columns = [ const columns = [
{ {
title: '教室名', title: '教室名', width: 120,
dataIndex: 'name', dataIndex: 'name',
sorter: (a: any, b: any) => a.name.localeCompare(b.name), sorter: (a: any, b: any) => a.name.localeCompare(b.name),
}, },
{ title: '楼栋', dataIndex: 'building' }, { title: '楼栋', dataIndex: 'building', width: 80 },
{ title: '楼层', dataIndex: 'floor' }, { title: '楼层', dataIndex: 'floor', width: 80 },
{ {
title: '类型', title: '类型', width: 90,
dataIndex: 'roomType', dataIndex: 'roomType',
render: (v: string) => <Tag color={typeColor[v] || 'default'}>{v || '-'}</Tag>, render: (v: string) => <Tag color={typeColor[v] || 'default'}>{v || '-'}</Tag>,
}, },
{ title: '容量', dataIndex: 'capacity' }, { title: '容量', dataIndex: 'capacity', width: 80 },
{ title: '课程类型', dataIndex: 'courseType', render: (v: string) => v || '-' }, { title: '课程类型', dataIndex: 'courseType', width: 100, render: (v: string) => v || '-' },
{ title: '负责人', dataIndex: 'supervisor', render: (v: string) => v || '-' }, { title: '负责人', dataIndex: 'supervisor', width: 100, render: (v: string) => v || '-' },
{ {
title: '状态', title: '状态', width: 100,
dataIndex: 'status', dataIndex: 'status',
render: (s: string, record: { currentUsage?: CurrentUsage | null }) => { render: (s: string, record: { currentUsage?: CurrentUsage | null }) => {
const effectiveStatus = record.currentUsage ? 'in_use' : s; const effectiveStatus = record.currentUsage ? 'in_use' : s;

View File

@@ -205,8 +205,8 @@ const DepartmentsPage: React.FC = () => {
const memberColumns = [ const memberColumns = [
{ title: 'ID', dataIndex: 'userId', key: 'userId', width: 60 }, { title: 'ID', dataIndex: 'userId', key: 'userId', width: 60 },
{ title: '用户名', dataIndex: ['user', 'username'], key: 'username' }, { title: '用户名', dataIndex: ['user', 'username'], key: 'username', width: 120 },
{ title: '姓名', dataIndex: ['user', 'name'], key: 'name' }, { title: '姓名', dataIndex: ['user', 'name'], key: 'name', width: 120 },
{ {
title: '默认部门', title: '默认部门',
dataIndex: 'isDefault', dataIndex: 'isDefault',

View File

@@ -217,9 +217,9 @@ const DepositsPage: React.FC = () => {
}; };
const columns = [ const columns = [
{ title: '学生', render: (_: any, r: any) => r.student?.name || '-' }, { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
{ title: '押金金额', dataIndex: 'amount', render: (v: number) => `¥${Number(v).toFixed(2)}` }, { title: '押金金额', dataIndex: 'amount', width: 110, render: (v: number) => `¥${Number(v).toFixed(2)}` },
{ title: '缴纳日期', dataIndex: 'paidDate' }, { title: '缴纳日期', dataIndex: 'paidDate', width: 110 },
{ {
title: '状态', title: '状态',
dataIndex: 'status', dataIndex: 'status',
@@ -241,9 +241,9 @@ const DepositsPage: React.FC = () => {
dataIndex: 'deductionAmount', dataIndex: 'deductionAmount',
render: (v: any) => (v > 0 ? `¥${Number(v).toFixed(2)}` : '-'), render: (v: any) => (v > 0 ? `¥${Number(v).toFixed(2)}` : '-'),
}, },
{ title: '扣除原因', dataIndex: 'deductionReason', render: (v: any) => v || '-' }, { title: '扣除原因', dataIndex: 'deductionReason', width: 120, render: (v: any) => v || '-' },
{ title: '退还日期', dataIndex: 'refundDate', render: (v: any) => v || '-' }, { title: '退还日期', dataIndex: 'refundDate', width: 110, render: (v: any) => v || '-' },
{ title: '备注', dataIndex: 'notes', render: (v: any) => v || '-' }, { title: '备注', dataIndex: 'notes', width: 120, render: (v: any) => v || '-' },
{ {
title: '操作', title: '操作',
width: 240, width: 240,
@@ -307,21 +307,21 @@ const DepositsPage: React.FC = () => {
]; ];
const pendingColumns = [ const pendingColumns = [
{ title: '学生', render: (_: any, r: any) => r.student?.name || '-' }, { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
{ title: '押金金额', dataIndex: 'amount', render: (v: number) => `¥${Number(v).toFixed(2)}` }, { title: '押金金额', dataIndex: 'amount', width: 110, render: (v: number) => `¥${Number(v).toFixed(2)}` },
{ title: '缴纳日期', dataIndex: 'paidDate' }, { title: '缴纳日期', dataIndex: 'paidDate', width: 110 },
{ {
title: '审批状态', title: '审批状态', width: 120,
dataIndex: 'refundStatus', dataIndex: 'refundStatus',
render: (s: string) => <Tag color={refundStatusMap[s]?.color}>{refundStatusMap[s]?.text || s}</Tag>, render: (s: string) => <Tag color={refundStatusMap[s]?.color}>{refundStatusMap[s]?.text || s}</Tag>,
}, },
{ {
title: '申请时间', title: '申请时间', width: 160,
dataIndex: 'refundRequestedAt', dataIndex: 'refundRequestedAt',
render: (v: any) => (v ? dayjs(v).format('YYYY-MM-DD HH:mm') : '-'), render: (v: any) => (v ? dayjs(v).format('YYYY-MM-DD HH:mm') : '-'),
}, },
{ {
title: '操作', title: '操作', width: 200,
render: (_: unknown, record: PendingRefund) => ( render: (_: unknown, record: PendingRefund) => (
<Space> <Space>
<PermissionButton <PermissionButton

View File

@@ -199,17 +199,17 @@ const ExpensesPage: React.FC = () => {
}; };
const roomColumns = [ const roomColumns = [
{ title: '宿舍', render: (_: any, r: any) => r.room?.roomNumber || '-' }, { title: '宿舍', width: 120, render: (_: any, r: any) => r.room?.roomNumber || '-' },
{ {
title: '费用类型', title: '费用类型', width: 100,
dataIndex: 'expenseType', dataIndex: 'expenseType',
render: (v: string) => <Tag>{typeMap[v] || v}</Tag>, render: (v: string) => <Tag>{typeMap[v] || v}</Tag>,
}, },
{ title: '金额', dataIndex: 'amount', render: (v: number) => `¥${Number(v).toFixed(2)}` }, { title: '金额', dataIndex: 'amount', width: 100, render: (v: number) => `¥${Number(v).toFixed(2)}` },
{ title: '账单周期', render: (_: any, r: any) => `${r.periodStart} ~ ${r.periodEnd}` }, { title: '账单周期', width: 200, render: (_: any, r: any) => `${r.periodStart} ~ ${r.periodEnd}` },
{ title: '说明', dataIndex: 'description' }, { title: '说明', dataIndex: 'description', width: 150 },
{ {
title: '录入时间', title: '录入时间', width: 160,
dataIndex: 'createdAt', dataIndex: 'createdAt',
render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm'), render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm'),
}, },
@@ -259,15 +259,15 @@ const ExpensesPage: React.FC = () => {
]; ];
const personalColumns = [ const personalColumns = [
{ title: '学生', render: (_: any, r: any) => r.student?.name || '-' }, { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
{ {
title: '费用类型', title: '费用类型', width: 100,
dataIndex: 'expenseType', dataIndex: 'expenseType',
render: (v: string) => <Tag color="orange">{typeMap[v] || v}</Tag>, render: (v: string) => <Tag color="orange">{typeMap[v] || v}</Tag>,
}, },
{ title: '金额', dataIndex: 'amount', render: (v: number) => `¥${Number(v).toFixed(2)}` }, { title: '金额', dataIndex: 'amount', render: (v: number) => `¥${Number(v).toFixed(2)}` },
{ title: '日期', dataIndex: 'expenseDate' }, { title: '日期', dataIndex: 'expenseDate', width: 110 },
{ title: '说明', dataIndex: 'description' }, { title: '说明', dataIndex: 'description', width: 150 },
{ {
title: '操作', title: '操作',
width: 120, width: 120,

View File

@@ -174,13 +174,14 @@ const OccupanciesPage: React.FC = () => {
}; };
const columns = [ const columns = [
{ title: '学生', render: (_: any, r: any) => r.student?.name || '-' }, { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
{ title: '宿舍', render: (_: any, r: any) => r.room?.roomNumber || '-' }, { title: '宿舍', width: 120, render: (_: any, r: any) => r.room?.roomNumber || '-' },
{ title: '入住日期', dataIndex: 'checkInDate' }, { title: '入住日期', dataIndex: 'checkInDate', width: 110 },
{ title: '计费起始', dataIndex: 'billingStartDate' }, { title: '计费起始', dataIndex: 'billingStartDate', width: 110 },
{ {
title: '退宿日期', title: '退宿日期',
dataIndex: 'checkOutDate', dataIndex: 'checkOutDate',
width: 110,
render: (v: any) => v || <Tag color="green"></Tag>, render: (v: any) => v || <Tag color="green"></Tag>,
}, },
{ title: '计费截止', dataIndex: 'billingEndDate', render: (v: any) => v || '-' }, { title: '计费截止', dataIndex: 'billingEndDate', render: (v: any) => v || '-' },

View File

@@ -75,7 +75,7 @@ const OperationLogsPage: React.FC = () => {
}, },
}, },
{ {
title: '详情', title: '详情', width: 200,
dataIndex: 'detail', dataIndex: 'detail',
ellipsis: true, ellipsis: true,
render: (v: string) => render: (v: string) =>

View File

@@ -186,11 +186,12 @@ const RoomsPage: React.FC = () => {
{ {
title: '房间号', title: '房间号',
dataIndex: 'roomNumber', dataIndex: 'roomNumber',
width: 100,
sorter: (a: any, b: any) => a.roomNumber.localeCompare(b.roomNumber), sorter: (a: any, b: any) => a.roomNumber.localeCompare(b.roomNumber),
}, },
{ title: '楼栋', dataIndex: 'building' }, { title: '楼栋', dataIndex: 'building', width: 80 },
{ title: '楼层', dataIndex: 'floor' }, { title: '楼层', dataIndex: 'floor', width: 80 },
{ title: '类型', dataIndex: 'roomType', render: (v: any) => v || '-' }, { title: '类型', dataIndex: 'roomType', width: 90, render: (v: any) => v || '-' },
{ {
title: '租赁类型', title: '租赁类型',
dataIndex: 'rentalCategory', dataIndex: 'rentalCategory',
@@ -207,9 +208,10 @@ const RoomsPage: React.FC = () => {
width: 100, width: 100,
render: (v: number) => (v ? `¥${v}` : '-'), render: (v: number) => (v ? `¥${v}` : '-'),
}, },
{ title: '额定人数', dataIndex: 'capacity' }, { title: '额定人数', dataIndex: 'capacity', width: 80 },
{ {
title: '当前入住', title: '当前入住',
width: 80,
render: (_: any, r: any) => render: (_: any, r: any) =>
r.status === 'archived' ? ( r.status === 'archived' ? (
<Tag color="#999">-</Tag> <Tag color="#999">-</Tag>
@@ -231,6 +233,7 @@ const RoomsPage: React.FC = () => {
{ {
title: '状态', title: '状态',
dataIndex: 'status', dataIndex: 'status',
width: 80,
render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text || s}</Tag>, render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text || s}</Tag>,
}, },
{ {

View File

@@ -249,7 +249,6 @@ const StudentsPage: React.FC = () => {
title: '电话', title: '电话',
dataIndex: 'phone', dataIndex: 'phone',
width: 140, width: 140,
ellipsis: true,
render: (v: string, record: any) => { render: (v: string, record: any) => {
if (!v) return '-'; if (!v) return '-';
return ( return (
@@ -266,14 +265,12 @@ const StudentsPage: React.FC = () => {
title: '学号', title: '学号',
dataIndex: 'studentNumber', dataIndex: 'studentNumber',
width: 120, width: 120,
ellipsis: true,
render: (v: string) => v || '-', render: (v: string) => v || '-',
}, },
{ {
title: '身份证', title: '身份证',
dataIndex: 'idNumber', dataIndex: 'idNumber',
width: 180, width: 180,
ellipsis: true,
render: (v: string, record: any) => { render: (v: string, record: any) => {
if (!v) return '-'; if (!v) return '-';
return ( return (
@@ -287,18 +284,20 @@ const StudentsPage: React.FC = () => {
}, },
}, },
{ title: '民族', dataIndex: 'ethnicity', width: 90 }, { title: '民族', dataIndex: 'ethnicity', width: 90 },
{ title: '紧急联系人', dataIndex: 'emergencyContact', ellipsis: true }, { title: '紧急联系人', dataIndex: 'emergencyContact', width: 100 },
{ title: '紧急联系人电话', dataIndex: 'emergencyPhone', ellipsis: true }, { title: '紧急联系人电话', dataIndex: 'emergencyPhone', width: 130 },
{ {
title: '所属机构', title: '所属机构',
dataIndex: 'tenant', dataIndex: 'tenant',
width: 100,
render: (tenant: { name?: string } | null) => render: (tenant: { name?: string } | null) =>
tenant?.name ? <Tag color="purple">{tenant.name}</Tag> : '-', tenant?.name ? <Tag color="purple">{tenant.name}</Tag> : '-',
}, },
{ title: '负责人', dataIndex: 'supervisor', ellipsis: true }, { title: '负责人', dataIndex: 'supervisor', width: 100 },
{ {
title: '状态', title: '状态',
dataIndex: 'status', dataIndex: 'status',
width: 80,
render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text || s}</Tag>, render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text || s}</Tag>,
}, },
{ {

View File

@@ -84,7 +84,7 @@ const TenantsPage: React.FC = () => {
const columns = [ const columns = [
{ {
title: '租赁方名称', title: '租赁方名称', width: 120,
dataIndex: 'name', dataIndex: 'name',
render: (v: string, r: any) => ( render: (v: string, r: any) => (
<Space> <Space>
@@ -97,10 +97,10 @@ const TenantsPage: React.FC = () => {
</Space> </Space>
), ),
}, },
{ title: '联系人', dataIndex: 'contact', render: (v: string) => v || '-' }, { title: '联系人', dataIndex: 'contact', width: 100, render: (v: string) => v || '-' },
{ title: '电话', dataIndex: 'phone', render: (v: string) => v || '-' }, { title: '电话', dataIndex: 'phone', width: 120, render: (v: string) => v || '-' },
{ {
title: '颜色', title: '颜色', width: 80,
dataIndex: 'color', dataIndex: 'color',
render: (v: string) => render: (v: string) =>
v ? ( v ? (

View File

@@ -248,7 +248,7 @@ const UsersPage: React.FC = () => {
dataSource={data} dataSource={data}
rowKey="id" rowKey="id"
loading={loading} loading={loading}
scroll={{ x: 1000 }} scroll={{ x: 1250 }}
pagination={false} pagination={false}
/> />