whistle.mock-plugins 1.1.3-dev.6 → 1.1.3-dev.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -10,12 +10,12 @@ import AppLayout from '../components/AppLayout';
|
|
|
10
10
|
import {
|
|
11
11
|
Table, Button, Modal, Form, Input, Select, message, Switch,
|
|
12
12
|
Popconfirm, Alert, Space, Card, Badge, Tooltip, Row, Col,
|
|
13
|
-
Popover, Checkbox, Tag, Input as AntInput, Radio, Drawer
|
|
13
|
+
Popover, Checkbox, Tag, Input as AntInput, Radio, Drawer, Dropdown, Menu
|
|
14
14
|
} from 'antd';
|
|
15
15
|
import {
|
|
16
16
|
PlusOutlined, EditOutlined, DeleteOutlined,
|
|
17
17
|
FileTextOutlined, PlusCircleOutlined, SettingOutlined,
|
|
18
|
-
SearchOutlined, FilterOutlined, ReloadOutlined
|
|
18
|
+
SearchOutlined, FilterOutlined, ReloadOutlined, DownOutlined
|
|
19
19
|
} from '@ant-design/icons';
|
|
20
20
|
import '../styles/interface-management.css';
|
|
21
21
|
import axios from 'axios';
|
|
@@ -976,15 +976,15 @@ const InterfaceManagement = () => {
|
|
|
976
976
|
重构后版本 V2
|
|
977
977
|
</div>
|
|
978
978
|
|
|
979
|
-
<Card className="interface-
|
|
980
|
-
<div className="
|
|
981
|
-
<div className="
|
|
979
|
+
<Card className="interface-control-panel">
|
|
980
|
+
<div className="control-panel-header">
|
|
981
|
+
<div className="control-left">
|
|
982
982
|
<div className="feature-selector">
|
|
983
983
|
<span>功能模块:</span>
|
|
984
984
|
<Select
|
|
985
985
|
value={selectedFeatureId}
|
|
986
986
|
onChange={handleSelectFeature}
|
|
987
|
-
style={{ width:
|
|
987
|
+
style={{ width: 200 }}
|
|
988
988
|
placeholder="选择功能模块"
|
|
989
989
|
loading={featuresLoading}
|
|
990
990
|
dropdownMatchSelectWidth={false}
|
|
@@ -1005,13 +1005,42 @@ const InterfaceManagement = () => {
|
|
|
1005
1005
|
onSearch={handleSearch}
|
|
1006
1006
|
value={searchValue}
|
|
1007
1007
|
onChange={(e) => setSearchValue(e.target.value)}
|
|
1008
|
-
style={{ width:
|
|
1008
|
+
style={{ width: 220, marginLeft: 12 }}
|
|
1009
1009
|
enterButton={<SearchOutlined />}
|
|
1010
1010
|
allowClear
|
|
1011
1011
|
/>
|
|
1012
|
+
|
|
1013
|
+
<Dropdown
|
|
1014
|
+
overlay={
|
|
1015
|
+
<Menu
|
|
1016
|
+
selectedKeys={selectedGroup ? [selectedGroup] : ['ALL_GROUPS']}
|
|
1017
|
+
onClick={({ key }) => {
|
|
1018
|
+
if (key === 'ALL_GROUPS') {
|
|
1019
|
+
setSelectedGroup(null);
|
|
1020
|
+
} else {
|
|
1021
|
+
setSelectedGroup(key === selectedGroup ? null : key);
|
|
1022
|
+
}
|
|
1023
|
+
}}
|
|
1024
|
+
>
|
|
1025
|
+
<Menu.Item key="ALL_GROUPS">全部分组</Menu.Item>
|
|
1026
|
+
{groups.map(group => (
|
|
1027
|
+
<Menu.Item key={group}>
|
|
1028
|
+
{group} ({interfaces.filter(item => item.group === group).length})
|
|
1029
|
+
</Menu.Item>
|
|
1030
|
+
))}
|
|
1031
|
+
</Menu>
|
|
1032
|
+
}
|
|
1033
|
+
trigger={['click']}
|
|
1034
|
+
disabled={groups.length === 0}
|
|
1035
|
+
>
|
|
1036
|
+
<Button style={{ marginLeft: 12 }} icon={<FilterOutlined />}>
|
|
1037
|
+
{selectedGroup ? `分组: ${selectedGroup}` : '分组筛选'}
|
|
1038
|
+
<DownOutlined />
|
|
1039
|
+
</Button>
|
|
1040
|
+
</Dropdown>
|
|
1012
1041
|
</div>
|
|
1013
1042
|
|
|
1014
|
-
<div className="
|
|
1043
|
+
<div className="control-right">
|
|
1015
1044
|
<Space>
|
|
1016
1045
|
<Tooltip title="刷新数据">
|
|
1017
1046
|
<Button
|
|
@@ -1026,132 +1055,46 @@ const InterfaceManagement = () => {
|
|
|
1026
1055
|
icon={<PlusOutlined />}
|
|
1027
1056
|
onClick={handleAddInterface}
|
|
1028
1057
|
disabled={!selectedFeatureId || selectedFeature?.active === false}
|
|
1029
|
-
className="add-interface-button"
|
|
1030
1058
|
>
|
|
1031
1059
|
添加接口
|
|
1032
1060
|
</Button>
|
|
1033
1061
|
</Space>
|
|
1034
1062
|
</div>
|
|
1035
1063
|
</div>
|
|
1036
|
-
</Card>
|
|
1037
|
-
|
|
1038
|
-
{!features.length && (
|
|
1039
|
-
<Alert
|
|
1040
|
-
message="未找到功能模块"
|
|
1041
|
-
description="请先在模拟数据页面创建功能模块,然后再添加接口"
|
|
1042
|
-
type="warning"
|
|
1043
|
-
showIcon
|
|
1044
|
-
style={{ marginBottom: 16 }}
|
|
1045
|
-
/>
|
|
1046
|
-
)}
|
|
1047
|
-
|
|
1048
|
-
{selectedFeature?.active === false && (
|
|
1049
|
-
<Alert
|
|
1050
|
-
message="功能模块已禁用"
|
|
1051
|
-
description="当前功能模块已被禁用,所有关联接口不会生效。您可以在模拟数据页面启用此功能模块。"
|
|
1052
|
-
type="warning"
|
|
1053
|
-
showIcon
|
|
1054
|
-
style={{ marginBottom: 16 }}
|
|
1055
|
-
/>
|
|
1056
|
-
)}
|
|
1057
|
-
|
|
1058
|
-
{/* 分组筛选和操作区域 */}
|
|
1059
|
-
<Card className="filter-card" bordered={false}>
|
|
1060
|
-
<div className="filter-header">
|
|
1061
|
-
<div className="filter-title">
|
|
1062
|
-
<FilterOutlined /> 分组筛选
|
|
1063
|
-
</div>
|
|
1064
|
-
{selectedGroup && (
|
|
1065
|
-
<Button
|
|
1066
|
-
type="link"
|
|
1067
|
-
onClick={() => setSelectedGroup(null)}
|
|
1068
|
-
size="small"
|
|
1069
|
-
>
|
|
1070
|
-
清除筛选
|
|
1071
|
-
</Button>
|
|
1072
|
-
)}
|
|
1073
|
-
</div>
|
|
1074
|
-
|
|
1075
|
-
<div className="group-tags-container">
|
|
1076
|
-
{groups.length === 0 ? (
|
|
1077
|
-
<div className="empty-groups">暂无分组</div>
|
|
1078
|
-
) : (
|
|
1079
|
-
<div className="group-tags">
|
|
1080
|
-
{groups.map(group => (
|
|
1081
|
-
<Tag
|
|
1082
|
-
key={group}
|
|
1083
|
-
color={selectedGroup === group ? "blue" : "default"}
|
|
1084
|
-
onClick={() => setSelectedGroup(group === selectedGroup ? null : group)}
|
|
1085
|
-
className={`group-tag ${selectedGroup === group ? 'active' : ''}`}
|
|
1086
|
-
>
|
|
1087
|
-
{group} ({interfaces.filter(item => item.group === group).length})
|
|
1088
|
-
</Tag>
|
|
1089
|
-
))}
|
|
1090
|
-
</div>
|
|
1091
|
-
)}
|
|
1092
|
-
</div>
|
|
1093
1064
|
|
|
1094
|
-
{
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
type="primary"
|
|
1104
|
-
size="small"
|
|
1105
|
-
loading={groupActionLoading}
|
|
1106
|
-
>
|
|
1107
|
-
批量启用
|
|
1108
|
-
</Button>
|
|
1109
|
-
</Popconfirm>
|
|
1110
|
-
|
|
1111
|
-
<Popconfirm
|
|
1112
|
-
title={`确定要禁用分组 "${selectedGroup}" 中的所有接口吗?`}
|
|
1113
|
-
onConfirm={() => handleBatchToggleActive(false)}
|
|
1114
|
-
okText="确定"
|
|
1115
|
-
cancelText="取消"
|
|
1116
|
-
>
|
|
1117
|
-
<Button
|
|
1118
|
-
danger
|
|
1119
|
-
size="small"
|
|
1120
|
-
loading={groupActionLoading}
|
|
1121
|
-
>
|
|
1122
|
-
批量禁用
|
|
1123
|
-
</Button>
|
|
1124
|
-
</Popconfirm>
|
|
1125
|
-
</div>
|
|
1126
|
-
)}
|
|
1127
|
-
</Card>
|
|
1128
|
-
|
|
1129
|
-
{/* 接口列表状态栏 */}
|
|
1130
|
-
<Card className="list-header-card" bordered={false}>
|
|
1131
|
-
<div className="list-header">
|
|
1132
|
-
<div className="list-header-info">
|
|
1133
|
-
<div className="feature-info">
|
|
1134
|
-
<span className="label">功能模块:</span>
|
|
1135
|
-
<span className="value">{selectedFeature?.name}</span>
|
|
1065
|
+
{/* 统计和批量操作行 */}
|
|
1066
|
+
<div className="control-panel-stats">
|
|
1067
|
+
<div className="stats-left">
|
|
1068
|
+
<Space size="large">
|
|
1069
|
+
<span className="stat-item">
|
|
1070
|
+
<span className="stat-label">功能模块:</span>
|
|
1071
|
+
<span className="stat-value">{selectedFeature?.name}</span>
|
|
1072
|
+
</span>
|
|
1073
|
+
|
|
1136
1074
|
{selectedGroup && (
|
|
1137
|
-
<
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
{searchValue ? (
|
|
1142
|
-
<Badge
|
|
1143
|
-
count={`搜索"${searchValue}" - ${filteredInterfaces.length}个结果`}
|
|
1144
|
-
style={{ backgroundColor: '#108ee9' }}
|
|
1145
|
-
/>
|
|
1146
|
-
) : (
|
|
1147
|
-
<Badge
|
|
1148
|
-
count={`共 ${filteredInterfaces.length} 个接口`}
|
|
1149
|
-
style={{ backgroundColor: '#52c41a' }}
|
|
1150
|
-
/>
|
|
1075
|
+
<span className="stat-item">
|
|
1076
|
+
<span className="stat-label">分组:</span>
|
|
1077
|
+
<Tag color="blue">{selectedGroup}</Tag>
|
|
1078
|
+
</span>
|
|
1151
1079
|
)}
|
|
1152
|
-
|
|
1080
|
+
|
|
1081
|
+
<span className="stat-item">
|
|
1082
|
+
{searchValue ? (
|
|
1083
|
+
<Badge
|
|
1084
|
+
count={`搜索"${searchValue}" - ${filteredInterfaces.length}个结果`}
|
|
1085
|
+
style={{ backgroundColor: '#108ee9' }}
|
|
1086
|
+
/>
|
|
1087
|
+
) : (
|
|
1088
|
+
<Badge
|
|
1089
|
+
count={`共 ${filteredInterfaces.length} 个接口`}
|
|
1090
|
+
style={{ backgroundColor: '#52c41a' }}
|
|
1091
|
+
/>
|
|
1092
|
+
)}
|
|
1093
|
+
</span>
|
|
1094
|
+
</Space>
|
|
1153
1095
|
</div>
|
|
1154
|
-
|
|
1096
|
+
|
|
1097
|
+
<div className="stats-right">
|
|
1155
1098
|
{selectedRowKeys.length > 0 && (
|
|
1156
1099
|
<Space>
|
|
1157
1100
|
<span className="selected-count">
|
|
@@ -1175,72 +1118,127 @@ const InterfaceManagement = () => {
|
|
|
1175
1118
|
</Popconfirm>
|
|
1176
1119
|
</Space>
|
|
1177
1120
|
)}
|
|
1121
|
+
|
|
1122
|
+
{selectedGroup && (
|
|
1123
|
+
<Space style={{ marginLeft: selectedRowKeys.length > 0 ? 16 : 0 }}>
|
|
1124
|
+
<Popconfirm
|
|
1125
|
+
title={`确定要启用分组 "${selectedGroup}" 中的所有接口吗?`}
|
|
1126
|
+
onConfirm={() => handleBatchToggleActive(true)}
|
|
1127
|
+
okText="确定"
|
|
1128
|
+
cancelText="取消"
|
|
1129
|
+
>
|
|
1130
|
+
<Button
|
|
1131
|
+
type="primary"
|
|
1132
|
+
size="small"
|
|
1133
|
+
loading={groupActionLoading}
|
|
1134
|
+
>
|
|
1135
|
+
分组启用
|
|
1136
|
+
</Button>
|
|
1137
|
+
</Popconfirm>
|
|
1138
|
+
<Popconfirm
|
|
1139
|
+
title={`确定要禁用分组 "${selectedGroup}" 中的所有接口吗?`}
|
|
1140
|
+
onConfirm={() => handleBatchToggleActive(false)}
|
|
1141
|
+
okText="确定"
|
|
1142
|
+
cancelText="取消"
|
|
1143
|
+
>
|
|
1144
|
+
<Button
|
|
1145
|
+
danger
|
|
1146
|
+
size="small"
|
|
1147
|
+
loading={groupActionLoading}
|
|
1148
|
+
>
|
|
1149
|
+
分组禁用
|
|
1150
|
+
</Button>
|
|
1151
|
+
</Popconfirm>
|
|
1152
|
+
</Space>
|
|
1153
|
+
)}
|
|
1154
|
+
|
|
1155
|
+
{/* 列设置按钮 */}
|
|
1156
|
+
<Popover
|
|
1157
|
+
title="自定义显示列"
|
|
1158
|
+
trigger="click"
|
|
1159
|
+
open={columnConfigVisible}
|
|
1160
|
+
onOpenChange={handleColumnConfigToggle}
|
|
1161
|
+
content={
|
|
1162
|
+
<div style={{ width: 280 }}>
|
|
1163
|
+
<div style={{ marginBottom: 12 }}>
|
|
1164
|
+
<Space>
|
|
1165
|
+
<Button size="small" onClick={handleSelectAllColumns}>
|
|
1166
|
+
全选
|
|
1167
|
+
</Button>
|
|
1168
|
+
<Button size="small" onClick={handleResetColumns}>
|
|
1169
|
+
重置
|
|
1170
|
+
</Button>
|
|
1171
|
+
</Space>
|
|
1172
|
+
</div>
|
|
1173
|
+
<Checkbox.Group
|
|
1174
|
+
value={tableConfig.visibleColumns || COLUMN_CONFIG.map(col => col.key)}
|
|
1175
|
+
onChange={handleColumnConfigChange}
|
|
1176
|
+
style={{ width: '100%' }}
|
|
1177
|
+
>
|
|
1178
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
1179
|
+
{COLUMN_CONFIG.map(col => (
|
|
1180
|
+
<Checkbox
|
|
1181
|
+
key={col.key}
|
|
1182
|
+
value={col.key}
|
|
1183
|
+
disabled={col.required}
|
|
1184
|
+
style={{
|
|
1185
|
+
width: '100%',
|
|
1186
|
+
color: col.required ? '#999' : undefined
|
|
1187
|
+
}}
|
|
1188
|
+
>
|
|
1189
|
+
{col.title}
|
|
1190
|
+
{col.required && (
|
|
1191
|
+
<span style={{ color: '#999', fontSize: '12px', marginLeft: 4 }}>
|
|
1192
|
+
(必须)
|
|
1193
|
+
</span>
|
|
1194
|
+
)}
|
|
1195
|
+
</Checkbox>
|
|
1196
|
+
))}
|
|
1197
|
+
</div>
|
|
1198
|
+
</Checkbox.Group>
|
|
1199
|
+
</div>
|
|
1200
|
+
}
|
|
1201
|
+
>
|
|
1202
|
+
<Tooltip title="自定义显示列">
|
|
1203
|
+
<Button
|
|
1204
|
+
icon={<SettingOutlined />}
|
|
1205
|
+
type="text"
|
|
1206
|
+
size="middle"
|
|
1207
|
+
className="column-settings-btn"
|
|
1208
|
+
style={{
|
|
1209
|
+
marginLeft: (selectedRowKeys.length > 0 || selectedGroup) ? 16 : 0,
|
|
1210
|
+
color: '#666'
|
|
1211
|
+
}}
|
|
1212
|
+
>
|
|
1213
|
+
列设置
|
|
1214
|
+
</Button>
|
|
1215
|
+
</Tooltip>
|
|
1216
|
+
</Popover>
|
|
1178
1217
|
</div>
|
|
1179
1218
|
</div>
|
|
1180
1219
|
</Card>
|
|
1220
|
+
|
|
1221
|
+
{!features.length && (
|
|
1222
|
+
<Alert
|
|
1223
|
+
message="未找到功能模块"
|
|
1224
|
+
description="请先在模拟数据页面创建功能模块,然后再添加接口"
|
|
1225
|
+
type="warning"
|
|
1226
|
+
showIcon
|
|
1227
|
+
style={{ marginBottom: 16 }}
|
|
1228
|
+
/>
|
|
1229
|
+
)}
|
|
1230
|
+
|
|
1231
|
+
{selectedFeature?.active === false && (
|
|
1232
|
+
<Alert
|
|
1233
|
+
message="功能模块已禁用"
|
|
1234
|
+
description="当前功能模块已被禁用,所有关联接口不会生效。您可以在模拟数据页面启用此功能模块。"
|
|
1235
|
+
type="warning"
|
|
1236
|
+
showIcon
|
|
1237
|
+
style={{ marginBottom: 16 }}
|
|
1238
|
+
/>
|
|
1239
|
+
)}
|
|
1240
|
+
|
|
1181
1241
|
|
|
1182
|
-
{/* 列配置区域 */}
|
|
1183
|
-
<div style={{
|
|
1184
|
-
marginBottom: 16,
|
|
1185
|
-
display: 'flex',
|
|
1186
|
-
justifyContent: 'flex-end',
|
|
1187
|
-
alignItems: 'center'
|
|
1188
|
-
}}>
|
|
1189
|
-
<Popover
|
|
1190
|
-
title="自定义显示列"
|
|
1191
|
-
trigger="click"
|
|
1192
|
-
open={columnConfigVisible}
|
|
1193
|
-
onOpenChange={handleColumnConfigToggle}
|
|
1194
|
-
content={
|
|
1195
|
-
<div style={{ width: 280 }}>
|
|
1196
|
-
<div style={{ marginBottom: 12 }}>
|
|
1197
|
-
<Space>
|
|
1198
|
-
<Button size="small" onClick={handleSelectAllColumns}>
|
|
1199
|
-
全选
|
|
1200
|
-
</Button>
|
|
1201
|
-
<Button size="small" onClick={handleResetColumns}>
|
|
1202
|
-
重置
|
|
1203
|
-
</Button>
|
|
1204
|
-
</Space>
|
|
1205
|
-
</div>
|
|
1206
|
-
<Checkbox.Group
|
|
1207
|
-
value={tableConfig.visibleColumns || COLUMN_CONFIG.map(col => col.key)}
|
|
1208
|
-
onChange={handleColumnConfigChange}
|
|
1209
|
-
style={{ width: '100%' }}
|
|
1210
|
-
>
|
|
1211
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
1212
|
-
{COLUMN_CONFIG.map(col => (
|
|
1213
|
-
<Checkbox
|
|
1214
|
-
key={col.key}
|
|
1215
|
-
value={col.key}
|
|
1216
|
-
disabled={col.required}
|
|
1217
|
-
style={{
|
|
1218
|
-
width: '100%',
|
|
1219
|
-
color: col.required ? '#999' : undefined
|
|
1220
|
-
}}
|
|
1221
|
-
>
|
|
1222
|
-
{col.title}
|
|
1223
|
-
{col.required && (
|
|
1224
|
-
<span style={{ color: '#999', fontSize: '12px', marginLeft: 4 }}>
|
|
1225
|
-
(必须)
|
|
1226
|
-
</span>
|
|
1227
|
-
)}
|
|
1228
|
-
</Checkbox>
|
|
1229
|
-
))}
|
|
1230
|
-
</div>
|
|
1231
|
-
</Checkbox.Group>
|
|
1232
|
-
</div>
|
|
1233
|
-
}
|
|
1234
|
-
>
|
|
1235
|
-
<Button
|
|
1236
|
-
icon={<SettingOutlined />}
|
|
1237
|
-
size="small"
|
|
1238
|
-
type="text"
|
|
1239
|
-
>
|
|
1240
|
-
列设置
|
|
1241
|
-
</Button>
|
|
1242
|
-
</Popover>
|
|
1243
|
-
</div>
|
|
1244
1242
|
|
|
1245
1243
|
<Card className="list-container-card" bordered={false} bodyStyle={{ padding: 0 }}>
|
|
1246
1244
|
<div className="interface-list-container">
|
|
@@ -15,38 +15,40 @@
|
|
|
15
15
|
--transition-time: 0.3s;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
.interface-management-container {
|
|
19
|
-
padding: 24px;
|
|
20
|
-
background: #f5f7fa;
|
|
21
|
-
}
|
|
22
18
|
|
|
23
|
-
/*
|
|
24
|
-
.interface-
|
|
19
|
+
/* 统一控制台 */
|
|
20
|
+
.interface-control-panel {
|
|
25
21
|
margin-bottom: 16px;
|
|
26
22
|
border-radius: 12px;
|
|
27
23
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
28
24
|
overflow: hidden;
|
|
29
25
|
}
|
|
30
26
|
|
|
31
|
-
.
|
|
27
|
+
.control-panel-header {
|
|
32
28
|
display: flex;
|
|
33
29
|
justify-content: space-between;
|
|
34
30
|
align-items: center;
|
|
35
31
|
padding: 8px 0;
|
|
32
|
+
border-bottom: 1px solid #f0f0f0;
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
.
|
|
35
|
+
.control-left {
|
|
39
36
|
display: flex;
|
|
40
37
|
align-items: center;
|
|
41
38
|
flex-wrap: wrap;
|
|
42
|
-
gap:
|
|
39
|
+
gap: 8px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.control-right {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
.feature-selector {
|
|
46
48
|
display: flex;
|
|
47
49
|
align-items: center;
|
|
48
50
|
background: #f9f9f9;
|
|
49
|
-
padding:
|
|
51
|
+
padding: 6px 12px;
|
|
50
52
|
border-radius: var(--border-radius);
|
|
51
53
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
|
52
54
|
transition: all var(--transition-time);
|
|
@@ -57,9 +59,89 @@
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
.feature-selector span {
|
|
60
|
-
margin-right:
|
|
62
|
+
margin-right: 8px;
|
|
61
63
|
font-weight: 600;
|
|
62
64
|
color: var(--text-secondary);
|
|
65
|
+
font-size: 14px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.control-panel-stats {
|
|
69
|
+
display: flex;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
align-items: center;
|
|
72
|
+
padding: 12px 0 8px 0;
|
|
73
|
+
min-height: 40px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.stats-left {
|
|
77
|
+
display: flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
flex-wrap: wrap;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.stats-right {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
gap: 12px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.stat-item {
|
|
89
|
+
display: inline-flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
font-size: 14px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.stat-label {
|
|
95
|
+
color: var(--text-secondary);
|
|
96
|
+
margin-right: 6px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.stat-value {
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
color: var(--font-color);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.selected-count {
|
|
105
|
+
font-weight: 600;
|
|
106
|
+
color: var(--primary-color);
|
|
107
|
+
font-size: 13px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* 列设置按钮 */
|
|
111
|
+
.column-settings-btn {
|
|
112
|
+
transition: all 0.2s ease;
|
|
113
|
+
border-radius: 6px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.column-settings-btn:hover {
|
|
117
|
+
background-color: #f5f5f5;
|
|
118
|
+
color: var(--primary-color) !important;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.column-settings-btn:active {
|
|
122
|
+
background-color: #e6f7ff;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* 旧版样式兼容 */
|
|
126
|
+
.interface-header-card {
|
|
127
|
+
margin-bottom: 16px;
|
|
128
|
+
border-radius: 12px;
|
|
129
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.interface-management-header {
|
|
134
|
+
display: flex;
|
|
135
|
+
justify-content: space-between;
|
|
136
|
+
align-items: center;
|
|
137
|
+
padding: 8px 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.feature-selector-container {
|
|
141
|
+
display: flex;
|
|
142
|
+
align-items: center;
|
|
143
|
+
flex-wrap: wrap;
|
|
144
|
+
gap: 12px;
|
|
63
145
|
}
|
|
64
146
|
|
|
65
147
|
.interface-actions {
|