Explorar el Código

♻️ refactor(statistics): 统一字段命名并优化数据展示

- 后端服务:将户籍统计查询字段从`householdProvince/householdCity`更新为`province/city`以匹配实体模型
- 后端服务:为在职状态统计添加数字到中文的映射,提升前端可读性
- 前端界面:移除所有统计卡片标题的底部边距(`mb-3`),统一为内容区域添加顶部边距(`mt-3`)
- 前端界面:优化“暂无数据”和加载状态的垂直间距,保持视觉一致性
yourname hace 3 semanas
padre
commit
98976b2208

+ 11 - 5
allin-packages/statistics-module/src/services/statistics.service.ts

@@ -208,12 +208,12 @@ export class StatisticsService {
 
     const query = this.disabledPersonRepository
       .createQueryBuilder('dp')
-      .select('dp.householdProvince', 'province')
-      .addSelect('dp.householdCity', 'city')
+      .select('dp.province', 'province')
+      .addSelect('dp.city', 'city')
       .addSelect('COUNT(dp.id)', 'value')
       .where('dp.id IN (:...personIds)', { personIds })
-      .andWhere('dp.householdProvince IS NOT NULL')
-      .groupBy('dp.householdProvince, dp.householdCity');
+      .andWhere('dp.province IS NOT NULL')
+      .groupBy('dp.province, dp.city');
 
     const rawStats = await query.getRawMany();
     const total = rawStats.reduce((sum, item) => sum + parseInt(item.value), 0);
@@ -264,8 +264,14 @@ export class StatisticsService {
     const rawStats = await query.getRawMany();
     const total = rawStats.reduce((sum, item) => sum + parseInt(item.value), 0);
 
+    // jobStatus映射:0-未在职,1-已在职
+    const jobStatusMap: Record<number, string> = {
+      0: '未在职',
+      1: '已在职'
+    };
+
     const stats = rawStats.map(item => ({
-      key: item.key,
+      key: jobStatusMap[item.key] || `未知(${item.key})`,
       value: parseInt(item.value),
       percentage: total > 0 ? (parseInt(item.value) / total) * 100 : 0
     }));

+ 16 - 16
mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx

@@ -192,7 +192,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
 
         {/* 残疾类型分布 */}
         <View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700 mb-3">残疾类型分布</Text>
+          <Text className="font-semibold text-gray-700">残疾类型分布</Text>
           {isLoadingDisability ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (
@@ -201,7 +201,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
               if (stats.length > 0) {
                 return (
                   <>
-                    <View className="chart-container mb-2 h-40 relative">
+                    <View className="chart-container mb-2 mt-3 h-40 relative">
                       {stats.map((item: any, index: number) => {
                         const maxValue = Math.max(...stats.map((s: any) => s.value || 0))
                         const height = maxValue > 0 ? ((item.value || 0) / maxValue) * 160 : 0
@@ -226,7 +226,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
                   </>
                 )
               } else {
-                return <Text className="text-gray-500 text-center py-4">暂无数据</Text>
+                return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
               }
             })()
           )}
@@ -234,13 +234,13 @@ const Statistics: React.FC<StatisticsProps> = () => {
 
         {/* 性别分布 */}
         <View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700 mb-3">性别分布</Text>
+          <Text className="font-semibold text-gray-700">性别分布</Text>
           {isLoadingGender ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (() => {
               const genderStats = getStats(genderData)
               return genderStats.length > 0 ? (
-                <View className="bar-chart flex items-end justify-center gap-10 h-32">
+                <View className="bar-chart flex items-end justify-center gap-10 h-32 mt-3">
                   {genderStats.map((item: any, index: number) => {
                     const maxValue = Math.max(...genderStats.map((s: any) => s.value || 0))
                     const height = maxValue > 0 ? ((item.value || 0) / maxValue) * 100 : 0
@@ -267,14 +267,14 @@ const Statistics: React.FC<StatisticsProps> = () => {
 
         {/* 年龄分布 */}
         <View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700 mb-3">年龄分布</Text>
+          <Text className="font-semibold text-gray-700">年龄分布</Text>
           {isLoadingAge ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (() => {
               const ageStats = getStats(ageData)
               return ageStats.length > 0 ? (
                 <>
-                  <View className="pie-chart-container flex justify-center mb-4">
+                  <View className="pie-chart-container flex justify-center mb-4 mt-3">
                     {/* 简单的饼图表示 - 使用conic-gradient模拟饼图 */}
                     <View
                       className="w-32 h-32 rounded-full"
@@ -316,14 +316,14 @@ const Statistics: React.FC<StatisticsProps> = () => {
 
         {/* 户籍省份分布 */}
         <View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700 mb-3">户籍省份分布</Text>
+          <Text className="font-semibold text-gray-700">户籍省份分布</Text>
           {isLoadingHousehold ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (() => {
               const stats = getStats(householdData)
               if (stats.length > 0) {
                 return (
-                  <View className="space-y-3">
+                  <View className="space-y-3 mt-3">
                     {stats.slice(0, 6).map((item: HouseholdDistributionResponse['stats'][0], index: number) => {
                       const maxValue = Math.max(...stats.map((s: HouseholdDistributionResponse['stats'][0]) => s.value || 0))
                       const width = maxValue > 0 ? ((item.value || 0) / maxValue) * 100 : 0
@@ -347,21 +347,21 @@ const Statistics: React.FC<StatisticsProps> = () => {
                   </View>
                 )
               } else {
-                return <Text className="text-gray-500 text-center py-4">暂无数据</Text>
+                return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
               }
             })()}
         </View>
 
         {/* 在职状态统计 */}
         <View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700 mb-3">在职状态统计</Text>
+          <Text className="font-semibold text-gray-700">在职状态统计</Text>
           {isLoadingJobStatus ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (() => {
               const stats = getStats(jobStatusData)
               if (stats.length > 0) {
                 return (
-                  <View className="flex items-center justify-center">
+                  <View className="flex items-center justify-center mt-3">
                     {/* 环形图占位 */}
                     <View className="w-32 h-32 rounded-full border-8 border-blue-500 border-t-transparent transform -rotate-45" />
                     <View className="ml-6 flex flex-col">
@@ -384,21 +384,21 @@ const Statistics: React.FC<StatisticsProps> = () => {
                   </View>
                 )
               } else {
-                return <Text className="text-gray-500 text-center py-4">暂无数据</Text>
+                return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
               }
             })()}
         </View>
 
         {/* 薪资分布 */}
         <View className="card bg-white p-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700 mb-3">薪资分布</Text>
+          <Text className="font-semibold text-gray-700">薪资分布</Text>
           {isLoadingSalary ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (() => {
               const stats = getStats(salaryData)
               if (stats.length > 0) {
                 return (
-                  <View className="space-y-3">
+                  <View className="space-y-3 mt-3">
                     {stats.map((item: SalaryDistributionResponse['stats'][0], index: number) => {
                       const maxValue = Math.max(...stats.map((s: SalaryDistributionResponse['stats'][0]) => s.value || 0))
                       const width = maxValue > 0 ? ((item.value || 0) / maxValue) * 100 : 0
@@ -422,7 +422,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
                   </View>
                 )
               } else {
-                return <Text className="text-gray-500 text-center py-4">暂无数据</Text>
+                return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
               }
             })()}
         </View>