Explorar el Código

fix: 提取姓氏头像为共享组件,修复人才列表页样式缺失问题

- 新建 NameAvatar 共享组件 (mini/src/components/NameAvatar/)
- 支持多种尺寸 (sm/md/lg) 和颜色变体
- 更新人才列表页和详情页使用新组件
- 移除页面内的 getAvatarColor 函数和重复样式

修复问题:
- 首次进入人才列表页时,姓氏头像无样式显示
- 原因:name-avatar 样式仅在人才详情页 CSS 中定义
- 解决方案:提取为共享组件,样式随组件自动加载

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname hace 1 día
padre
commit
a50c58a92d

+ 65 - 0
mini/src/components/NameAvatar/index.css

@@ -0,0 +1,65 @@
+/* 姓氏头像组件样式 */
+
+/* 基础样式 */
+.name-avatar {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 9999px;
+}
+
+/* 文字样式 */
+.name-avatar-text {
+  color: #ffffff;
+  font-weight: 600;
+}
+
+/* 尺寸变体 */
+.name-avatar-sm {
+  width: 32px;
+  height: 32px;
+}
+.name-avatar-sm .name-avatar-text {
+  font-size: 14px;
+}
+
+.name-avatar-md {
+  width: 40px;
+  height: 40px;
+}
+.name-avatar-md .name-avatar-text {
+  font-size: 16px;
+}
+
+.name-avatar-lg {
+  width: 64px;
+  height: 64px;
+}
+.name-avatar-lg .name-avatar-text {
+  font-size: 24px;
+}
+
+/* 颜色变体 - 渐变背景 */
+.name-avatar-blue {
+  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
+}
+
+.name-avatar-green {
+  background: linear-gradient(135deg, #10b981, #059669);
+}
+
+.name-avatar-purple {
+  background: linear-gradient(135deg, #8b5cf6, #7c3aed);
+}
+
+.name-avatar-orange {
+  background: linear-gradient(135deg, #f59e0b, #d97706);
+}
+
+.name-avatar-red {
+  background: linear-gradient(135deg, #ef4444, #dc2626);
+}
+
+.name-avatar-teal {
+  background: linear-gradient(135deg, #14b8a6, #0d9488);
+}

+ 56 - 0
mini/src/components/NameAvatar/index.tsx

@@ -0,0 +1,56 @@
+import React from 'react'
+import { View, Text } from '@tarojs/components'
+import './index.css'
+
+export interface NameAvatarProps {
+  /** 姓名 */
+  name: string
+  /** 尺寸 */
+  size?: 'sm' | 'md' | 'lg'
+  /** 用于计算颜色的 ID(可选,默认基于 name) */
+  id?: number
+  /** 自定义类名 */
+  className?: string
+}
+
+/**
+ * 姓氏头像组件
+ *
+ * 显示姓氏的圆形头像,支持多种颜色和尺寸
+ *
+ * @example
+ * ```tsx
+ * <NameAvatar name="张三" size="md" id={123} />
+ * ```
+ */
+export const NameAvatar: React.FC<NameAvatarProps> = ({
+  name,
+  size = 'md',
+  id,
+  className = ''
+}) => {
+  // 颜色列表
+  const colors = ['blue', 'green', 'purple', 'orange', 'red', 'teal']
+
+  // 计算 avatar 颜色
+  const avatarColor = id !== undefined
+    ? colors[id % colors.length]
+    : colors[name.charCodeAt(0) % colors.length]
+
+  // 尺寸类名映射
+  const sizeClasses: Record<NonNullable<NameAvatarProps['size']>, string> = {
+    sm: 'name-avatar-sm',
+    md: 'name-avatar-md',
+    lg: 'name-avatar-lg'
+  }
+
+  return (
+    <View
+      className={`name-avatar name-avatar-${avatarColor} ${sizeClasses[size]} ${className}`.trim()}
+    >
+      <Text className="name-avatar-text">{name.charAt(0)}</Text>
+    </View>
+  )
+}
+
+export default NameAvatar

+ 0 - 21
mini/src/pages/yongren/talent/detail/TalentDetail.css

@@ -5,28 +5,7 @@
   background: linear-gradient(135deg, #3b82f6, #8b5cf6);
 }
 
-/* 头像颜色类 */
-.name-avatar.blue {
-  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
-}
-.name-avatar.green {
-  background: linear-gradient(135deg, #10b981, #059669);
-}
-.name-avatar.purple {
-  background: linear-gradient(135deg, #8b5cf6, #7c3aed);
-}
-.name-avatar.orange {
-  background: linear-gradient(135deg, #f59e0b, #d97706);
-}
-.name-avatar.red {
-  background: linear-gradient(135deg, #ef4444, #dc2626);
-}
-.name-avatar.teal {
-  background: linear-gradient(135deg, #14b8a6, #0d9488);
-}
-
 /* 卡片样式 */
-.card {
   border-radius: 12px;
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
 }

+ 3 - 11
mini/src/pages/yongren/talent/detail/index.tsx

@@ -5,6 +5,7 @@ import './TalentDetail.css'
 import { useQuery } from '@tanstack/react-query'
 import { PageContainer } from '@d8d/mini-shared-ui-components/components/page-container'
 import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'
+import { NameAvatar } from '@/components/NameAvatar'
 import { enterpriseDisabilityClient } from '@/api'
 import { useRequireAuth } from '@/hooks'
 // 直接从后端模块导入类型定义
@@ -257,13 +258,6 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
   const isLoading = talentLoading || workLoading || salaryLoading || filesLoading || historyLoading || workHistoryLoading || videosLoading
   const hasError = talentError
 
-  // 获取头像颜色
-  const getAvatarColor = (id: number) => {
-    const colors = ['blue', 'green', 'purple', 'orange', 'red', 'teal']
-    const index = id % colors.length
-    return colors[index]
-  }
-
   // 格式化日期
   const formatDate = (dateStr?: string) => {
     if (!dateStr) return '未指定'
@@ -422,10 +416,8 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
               <View className="gradient-bg text-white p-5">
                 <View className="flex justify-between items-start">
                   <View className="flex items-center">
-                    <View className={`name-avatar ${getAvatarColor(talentDetail.id)} w-16 h-16 rounded-full border-2 border-white mr-4 flex items-center justify-center`}>
-                      <Text className="text-white text-2xl font-bold">
-                        {talentDetail.name.charAt(0)}
-                      </Text>
+                    <View className="mr-4">
+                      <NameAvatar name={talentDetail.name} size="lg" id={talentDetail.id} className="border-2 border-white" />
                     </View>
                     <View>
                       <Text className="text-xl font-bold">{talentDetail.name}</Text>

+ 2 - 12
mini/src/pages/yongren/talent/list/index.tsx

@@ -4,6 +4,7 @@ import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro'
 import { useInfiniteQuery } from '@tanstack/react-query'
 import dayjs from 'dayjs'
 import { YongrenTabBarLayout } from '@/components/YongrenTabBarLayout'
+import { NameAvatar } from '@/components/NameAvatar'
 import { PageContainer } from '@d8d/mini-shared-ui-components/components/page-container'
 import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'
 import { enterpriseDisabilityClient } from '@/api'
@@ -152,13 +153,6 @@ const TalentManagement: React.FC<TalentManagementProps> = () => {
     })
   }
 
-  // 获取头像颜色
-  const getAvatarColor = (id: number) => {
-    const colors = ['blue', 'green', 'purple', 'orange', 'red', 'teal']
-    const index = id % colors.length
-    return colors[index]
-  }
-
   // 计算年龄基于出生日期
   const calculateAge = (birthDate: string | null): string => {
     if (!birthDate) return '未知岁'
@@ -298,11 +292,7 @@ const TalentManagement: React.FC<TalentManagementProps> = () => {
                     className="card bg-white p-4 flex items-center cursor-pointer active:bg-gray-50"
                     onClick={() => handleTalentClick(talent.personId)}
                   >
-                    <View className={`name-avatar ${getAvatarColor(talent.personId)} w-10 h-10 rounded-full flex items-center justify-center`}>
-                      <Text className="text-white font-semibold">
-                        {talent.name.charAt(0)}
-                      </Text>
-                    </View>
+                    <NameAvatar name={talent.name} size="md" id={talent.personId} />
                     <View className="flex-1 ml-3">
                       <View className="flex justify-between items-start">
                         <View className="flex flex-col">