/** * 评分权重设置页:调整九大评价维度权重,支持套用预设模板。 * 数据通过 useWeightSettings 获取,页面只负责交互与渲染。 */ import { Ionicons } from '@expo/vector-icons'; import { useRouter } from 'expo-router'; import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useWeightSettings } from '../../src/hooks'; import { colors } from '../../src/theme'; const MIN_WEIGHT = 0; const MAX_WEIGHT = 100; const STEP = 1; function Header({ onBack }: { onBack: () => void }) { return ( 评分权重设置 ); } export default function WeightSettingsScreen() { const router = useRouter(); const { settings, dimensions, totalWeight, loading, error, saving, refresh, updateWeight, applyTemplate, save, } = useWeightSettings(); const isValid = totalWeight === 100; // 错误态 if (error) { return (
router.back()} /> 加载失败,请重试 重试 ); } // 加载态 if (loading) { return (
router.back()} /> 加载中… ); } return (
router.back()} /> 权重总和 {totalWeight}% {isValid ? '配置合理,可直接保存' : '各维度权重之和需等于 100%'} 预设模板 {(settings?.templates ?? []).map((template) => ( applyTemplate(template.id)} > {template.name} {template.description} ))} 评价维度 {dimensions.map((item, index) => { const isLast = index === dimensions.length - 1; return ( {item.name} {item.isReversed ? ( 反向指标 ) : null} {item.weight}% updateWeight(item.id, Math.max(MIN_WEIGHT, item.weight - STEP)) } > updateWeight(item.id, Math.min(MAX_WEIGHT, item.weight + STEP)) } > ); })} {saving ? '保存中…' : '保存设置'} ); } const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: colors.pageBg }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingVertical: 12, backgroundColor: colors.surface, borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: colors.borderLight, }, headerBtn: { width: 32, alignItems: 'center' }, headerTitle: { fontSize: 17, fontWeight: '500', color: colors.textPrimary }, content: { padding: 8, paddingBottom: 24 }, stateWrap: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12 }, stateText: { fontSize: 14, color: colors.textSecondary }, retryBtn: { paddingHorizontal: 20, paddingVertical: 8, borderRadius: 8, backgroundColor: colors.primaryLight, }, retryText: { fontSize: 14, color: colors.primaryText }, summaryCard: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', padding: 8, borderRadius: 8, backgroundColor: colors.primaryLight, }, summaryCardWarn: { backgroundColor: colors.dangerLight }, summaryLabel: { fontSize: 12, color: colors.textSecondary, marginBottom: 4 }, summaryValue: { fontSize: 24, fontWeight: '500', color: colors.primaryText }, summaryValueWarn: { color: colors.dangerText }, summaryHint: { flex: 1, textAlign: 'right', fontSize: 12, color: colors.textSecondary }, sectionHeader: { flexDirection: 'row', alignItems: 'center', marginTop: 20, marginBottom: 12 }, sectionBar: { width: 3, height: 14, borderRadius: 2, backgroundColor: colors.primaryBtn, marginRight: 8, }, sectionTitle: { fontSize: 15, fontWeight: '500', color: colors.textPrimary }, templateRow: { gap: 10, paddingRight: 16 }, templateCard: { width: 140, padding: 8, borderRadius: 8, backgroundColor: colors.surface, borderWidth: StyleSheet.hairlineWidth, borderColor: colors.borderLight, }, templateName: { fontSize: 14, fontWeight: '500', color: colors.textPrimary, marginBottom: 4 }, templateDesc: { fontSize: 11, color: colors.textSecondary }, dimensionCard: { borderRadius: 8, backgroundColor: colors.surface, borderWidth: StyleSheet.hairlineWidth, borderColor: colors.borderLight, paddingHorizontal: 8, }, dimRow: { paddingVertical: 14, borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: colors.borderLight, }, dimRowLast: { borderBottomWidth: 0 }, dimHead: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 }, dimName: { fontSize: 14, color: colors.textPrimary, marginRight: 6 }, reversedTag: { paddingHorizontal: 6, paddingVertical: 1, borderRadius: 4, backgroundColor: colors.infoLight, marginRight: 6, }, reversedText: { fontSize: 10, color: colors.infoText }, dimValue: { marginLeft: 'auto', fontSize: 14, fontWeight: '500', color: colors.primaryText }, dimTrack: { height: 6, borderRadius: 3, backgroundColor: colors.borderLight, overflow: 'hidden', marginBottom: 10, }, dimFill: { height: '100%', borderRadius: 3 }, dimActions: { flexDirection: 'row', gap: 8 }, stepBtn: { width: 28, height: 28, borderRadius: 6, alignItems: 'center', justifyContent: 'center', backgroundColor: colors.primaryLight, }, footer: { padding: 16, backgroundColor: colors.surface, borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: colors.borderLight, }, saveBtn: { height: 46, borderRadius: 10, alignItems: 'center', justifyContent: 'center', backgroundColor: colors.primaryBtn, }, saveBtnDisabled: { backgroundColor: colors.border }, saveText: { fontSize: 15, fontWeight: '500', color: colors.white }, });