|
@@ -6,76 +6,26 @@ import { YongrenTabBarLayout } from '@d8d/yongren-shared-ui/components/YongrenTa
|
|
|
import { PageContainer } from '@d8d/mini-shared-ui-components/components/page-container'
|
|
import { PageContainer } from '@d8d/mini-shared-ui-components/components/page-container'
|
|
|
import { enterpriseDisabilityClient } from '../../api'
|
|
import { enterpriseDisabilityClient } from '../../api'
|
|
|
import { useRequireAuth } from '@d8d/mini-enterprise-auth-ui/hooks'
|
|
import { useRequireAuth } from '@d8d/mini-enterprise-auth-ui/hooks'
|
|
|
|
|
+import type { InferResponseType } from 'hono/client'
|
|
|
|
|
|
|
|
export interface TalentDetailProps {
|
|
export interface TalentDetailProps {
|
|
|
// 组件属性定义(目前为空)
|
|
// 组件属性定义(目前为空)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 从RPC客户端推断类型
|
|
|
|
|
+type TalentDetailResponse = InferResponseType<typeof enterpriseDisabilityClient[':id']['$get'], 200>
|
|
|
|
|
+type WorkHistoryResponse = InferResponseType<typeof enterpriseDisabilityClient[':id']['work-history']['$get'], 200>
|
|
|
|
|
+type SalaryHistoryResponse = InferResponseType<typeof enterpriseDisabilityClient[':id']['salary-history']['$get'], 200>
|
|
|
|
|
+type CreditInfoResponse = InferResponseType<typeof enterpriseDisabilityClient[':id']['credit-info']['$get'], 200>
|
|
|
|
|
+type VideoResponse = InferResponseType<typeof enterpriseDisabilityClient[':id']['videos']['$get'], 200>
|
|
|
|
|
|
|
|
|
|
+// 提取数组元素类型
|
|
|
|
|
+type WorkHistoryItem = WorkHistoryResponse['工作历史'][number]
|
|
|
|
|
+type SalaryHistoryItem = SalaryHistoryResponse['薪资历史'][number]
|
|
|
|
|
+type CreditInfoItem = CreditInfoResponse['征信信息'][number]
|
|
|
|
|
+type VideoItem = VideoResponse['视频列表'][number]
|
|
|
|
|
|
|
|
|
|
|
|
|
-interface SalaryData {
|
|
|
|
|
- id: number
|
|
|
|
|
- personId: number
|
|
|
|
|
- amount?: number
|
|
|
|
|
- paymentDate?: string
|
|
|
|
|
- period?: string
|
|
|
|
|
- type?: string
|
|
|
|
|
- notes?: string
|
|
|
|
|
- [key: string]: any
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface FileData {
|
|
|
|
|
- id: string
|
|
|
|
|
- name: string
|
|
|
|
|
- url?: string
|
|
|
|
|
- size?: number
|
|
|
|
|
- type?: string
|
|
|
|
|
- createdAt?: string
|
|
|
|
|
- [key: string]: any
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 企业专用API响应类型
|
|
|
|
|
-interface WorkHistoryItem {
|
|
|
|
|
- 订单ID: number
|
|
|
|
|
- 订单名称: string | null
|
|
|
|
|
- 入职日期: string | null
|
|
|
|
|
- 实际入职日期: string | null
|
|
|
|
|
- 离职日期: string | null
|
|
|
|
|
- 工作状态: string
|
|
|
|
|
- 个人薪资: number
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface WorkHistoryResponse {
|
|
|
|
|
- 工作历史: WorkHistoryItem[]
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface SalaryHistoryItem {
|
|
|
|
|
- 月份: string | null
|
|
|
|
|
- 基本工资: number
|
|
|
|
|
- 补贴: number
|
|
|
|
|
- 扣款: number
|
|
|
|
|
- 实发工资: number
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface SalaryHistoryResponse {
|
|
|
|
|
- 薪资历史: SalaryHistoryItem[]
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface CreditInfoItem {
|
|
|
|
|
- 文件ID: string
|
|
|
|
|
- 文件URL: string | null
|
|
|
|
|
- 上传时间: string | null
|
|
|
|
|
- 文件类型: string | null
|
|
|
|
|
- 银行卡号: string | null
|
|
|
|
|
- 持卡人姓名: string | null
|
|
|
|
|
- 银行名称: number | null
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface CreditInfoResponse {
|
|
|
|
|
- 征信信息: CreditInfoItem[]
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
const { isLoggedIn } = useRequireAuth()
|
|
const { isLoggedIn } = useRequireAuth()
|
|
|
const router = Taro.useRouter()
|
|
const router = Taro.useRouter()
|
|
@@ -87,7 +37,7 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
queryFn: async () => {
|
|
queryFn: async () => {
|
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
|
const response = await enterpriseDisabilityClient[':id'].$get({
|
|
const response = await enterpriseDisabilityClient[':id'].$get({
|
|
|
- param: { id: talentId.toString() }
|
|
|
|
|
|
|
+ param: { id: talentId }
|
|
|
})
|
|
})
|
|
|
if (response.status !== 200) {
|
|
if (response.status !== 200) {
|
|
|
throw new Error('获取人才详情失败')
|
|
throw new Error('获取人才详情失败')
|
|
@@ -99,7 +49,13 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
id: data.personId, // 映射id字段
|
|
id: data.personId, // 映射id字段
|
|
|
status: data.jobStatus, // 映射status字段
|
|
status: data.jobStatus, // 映射status字段
|
|
|
// 计算年龄
|
|
// 计算年龄
|
|
|
- age: data.birthDate ? Math.floor((Date.now() - new Date(data.birthDate).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) : undefined
|
|
|
|
|
|
|
+ age: data.birthDate ? Math.floor((Date.now() - new Date(data.birthDate).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) : undefined,
|
|
|
|
|
+ // 兼容字段映射
|
|
|
|
|
+ salary: data.salary || data.monthlySalary || data.currentSalary,
|
|
|
|
|
+ joinDate: data.joinDate || data.employmentDate || data.hireDate,
|
|
|
|
|
+ disabilityId: data.disabilityId || data.disabilityCardNumber,
|
|
|
|
|
+ idAddress: data.idAddress || data.address || data.residentialAddress,
|
|
|
|
|
+ phone: data.phone || data.mobile || data.contactPhone
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
enabled: isLoggedIn && talentId > 0
|
|
enabled: isLoggedIn && talentId > 0
|
|
@@ -112,13 +68,13 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
|
// 使用企业专用工作历史API:/api/v1/yongren/disability-person/{id}/work-history
|
|
// 使用企业专用工作历史API:/api/v1/yongren/disability-person/{id}/work-history
|
|
|
const response = await enterpriseDisabilityClient[':id']['work-history'].$get({
|
|
const response = await enterpriseDisabilityClient[':id']['work-history'].$get({
|
|
|
- param: { id: talentId.toString() }
|
|
|
|
|
|
|
+ param: { id: talentId }
|
|
|
})
|
|
})
|
|
|
if (response.status !== 200) {
|
|
if (response.status !== 200) {
|
|
|
// 可能没有工作信息,返回空对象
|
|
// 可能没有工作信息,返回空对象
|
|
|
return {}
|
|
return {}
|
|
|
}
|
|
}
|
|
|
- const data = await response.json() as WorkHistoryResponse
|
|
|
|
|
|
|
+ const data = await response.json()
|
|
|
// 企业专用工作历史API返回的是工作历史列表,取最新的一条作为当前工作信息
|
|
// 企业专用工作历史API返回的是工作历史列表,取最新的一条作为当前工作信息
|
|
|
const workHistory = data?.工作历史 || []
|
|
const workHistory = data?.工作历史 || []
|
|
|
if (workHistory.length === 0) {
|
|
if (workHistory.length === 0) {
|
|
@@ -147,17 +103,17 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
|
// 使用企业专用工作历史API:/api/v1/yongren/disability-person/{id}/work-history
|
|
// 使用企业专用工作历史API:/api/v1/yongren/disability-person/{id}/work-history
|
|
|
const response = await enterpriseDisabilityClient[':id']['work-history'].$get({
|
|
const response = await enterpriseDisabilityClient[':id']['work-history'].$get({
|
|
|
- param: { id: talentId.toString() }
|
|
|
|
|
|
|
+ param: { id: talentId }
|
|
|
})
|
|
})
|
|
|
if (response.status !== 200) {
|
|
if (response.status !== 200) {
|
|
|
// 可能没有工作信息,返回空数组
|
|
// 可能没有工作信息,返回空数组
|
|
|
return [] as WorkHistoryItem[]
|
|
return [] as WorkHistoryItem[]
|
|
|
}
|
|
}
|
|
|
- const data = await response.json() as WorkHistoryResponse
|
|
|
|
|
|
|
+ const data = await response.json()
|
|
|
// 企业专用工作历史API返回的是工作历史列表
|
|
// 企业专用工作历史API返回的是工作历史列表
|
|
|
const workHistory = data?.工作历史 || []
|
|
const workHistory = data?.工作历史 || []
|
|
|
// 按入职日期降序排序(最新的在前)
|
|
// 按入职日期降序排序(最新的在前)
|
|
|
- return workHistory.sort((a, b) => {
|
|
|
|
|
|
|
+ return workHistory.sort((a: WorkHistoryItem, b: WorkHistoryItem) => {
|
|
|
const dateA = a.入职日期 ? new Date(a.入职日期).getTime() : 0
|
|
const dateA = a.入职日期 ? new Date(a.入职日期).getTime() : 0
|
|
|
const dateB = b.入职日期 ? new Date(b.入职日期).getTime() : 0
|
|
const dateB = b.入职日期 ? new Date(b.入职日期).getTime() : 0
|
|
|
return dateB - dateA
|
|
return dateB - dateA
|
|
@@ -173,17 +129,17 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
|
// 使用企业专用薪资历史API:/api/v1/yongren/disability-person/{id}/salary-history
|
|
// 使用企业专用薪资历史API:/api/v1/yongren/disability-person/{id}/salary-history
|
|
|
const response = await enterpriseDisabilityClient[':id']['salary-history'].$get({
|
|
const response = await enterpriseDisabilityClient[':id']['salary-history'].$get({
|
|
|
- param: { id: talentId.toString() }
|
|
|
|
|
|
|
+ param: { id: talentId }
|
|
|
})
|
|
})
|
|
|
if (response.status !== 200) {
|
|
if (response.status !== 200) {
|
|
|
// 可能没有薪资信息,返回空对象
|
|
// 可能没有薪资信息,返回空对象
|
|
|
- return {} as SalaryData
|
|
|
|
|
|
|
+ return {}
|
|
|
}
|
|
}
|
|
|
- const data = await response.json() as SalaryHistoryResponse
|
|
|
|
|
|
|
+ const data = await response.json()
|
|
|
// 企业专用薪资历史API返回结构:{ 薪资历史: [...] }
|
|
// 企业专用薪资历史API返回结构:{ 薪资历史: [...] }
|
|
|
const salaryHistory = data?.薪资历史 || []
|
|
const salaryHistory = data?.薪资历史 || []
|
|
|
if (salaryHistory.length === 0) {
|
|
if (salaryHistory.length === 0) {
|
|
|
- return {} as SalaryData
|
|
|
|
|
|
|
+ return {}
|
|
|
}
|
|
}
|
|
|
// 取最新的一条薪资记录(按月份降序)
|
|
// 取最新的一条薪资记录(按月份降序)
|
|
|
const latestSalary = salaryHistory[0]
|
|
const latestSalary = salaryHistory[0]
|
|
@@ -194,7 +150,7 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
paymentDate: latestSalary.月份 || undefined,
|
|
paymentDate: latestSalary.月份 || undefined,
|
|
|
type: '月薪', // 默认类型
|
|
type: '月薪', // 默认类型
|
|
|
period: '月度' // 默认周期
|
|
period: '月度' // 默认周期
|
|
|
- } as SalaryData
|
|
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
enabled: isLoggedIn && talentId > 0
|
|
enabled: isLoggedIn && talentId > 0
|
|
|
})
|
|
})
|
|
@@ -206,10 +162,10 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
|
// 使用企业专用薪资历史API:/api/v1/yongren/disability-person/{id}/salary-history
|
|
// 使用企业专用薪资历史API:/api/v1/yongren/disability-person/{id}/salary-history
|
|
|
const response = await enterpriseDisabilityClient[':id']['salary-history'].$get({
|
|
const response = await enterpriseDisabilityClient[':id']['salary-history'].$get({
|
|
|
- param: { id: talentId.toString() }
|
|
|
|
|
|
|
+ param: { id: talentId }
|
|
|
})
|
|
})
|
|
|
if (response.status !== 200) {
|
|
if (response.status !== 200) {
|
|
|
- return [] as SalaryData[]
|
|
|
|
|
|
|
+ return []
|
|
|
}
|
|
}
|
|
|
const data = await response.json() as SalaryHistoryResponse
|
|
const data = await response.json() as SalaryHistoryResponse
|
|
|
// 企业专用薪资历史API返回结构:{ 薪资历史: [...] }
|
|
// 企业专用薪资历史API返回结构:{ 薪资历史: [...] }
|
|
@@ -222,7 +178,7 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
paymentDate: item.月份 || undefined,
|
|
paymentDate: item.月份 || undefined,
|
|
|
type: '月薪', // 默认类型
|
|
type: '月薪', // 默认类型
|
|
|
period: '月度' // 默认周期
|
|
period: '月度' // 默认周期
|
|
|
- })) as SalaryData[]
|
|
|
|
|
|
|
+ }))
|
|
|
},
|
|
},
|
|
|
enabled: isLoggedIn && talentId > 0
|
|
enabled: isLoggedIn && talentId > 0
|
|
|
})
|
|
})
|
|
@@ -234,12 +190,12 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
if (!talentId) throw new Error('无效的人才ID')
|
|
|
// 使用企业专用征信信息API:/api/v1/yongren/disability-person/{id}/credit-info
|
|
// 使用企业专用征信信息API:/api/v1/yongren/disability-person/{id}/credit-info
|
|
|
const response = await enterpriseDisabilityClient[':id']['credit-info'].$get({
|
|
const response = await enterpriseDisabilityClient[':id']['credit-info'].$get({
|
|
|
- param: { id: talentId.toString() }
|
|
|
|
|
|
|
+ param: { id: talentId }
|
|
|
})
|
|
})
|
|
|
if (response.status !== 200) {
|
|
if (response.status !== 200) {
|
|
|
- return [] as FileData[]
|
|
|
|
|
|
|
+ return []
|
|
|
}
|
|
}
|
|
|
- const data = await response.json() as CreditInfoResponse
|
|
|
|
|
|
|
+ const data = await response.json()
|
|
|
// 企业专用征信信息API返回结构:{ 征信信息: [...] }
|
|
// 企业专用征信信息API返回结构:{ 征信信息: [...] }
|
|
|
const creditInfoList = data?.征信信息 || []
|
|
const creditInfoList = data?.征信信息 || []
|
|
|
// 转换为FileData数组
|
|
// 转换为FileData数组
|
|
@@ -250,7 +206,37 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
size: undefined, // 征信信息API不返回文件大小
|
|
size: undefined, // 征信信息API不返回文件大小
|
|
|
type: item.文件类型 || undefined,
|
|
type: item.文件类型 || undefined,
|
|
|
createdAt: item.上传时间 || undefined
|
|
createdAt: item.上传时间 || undefined
|
|
|
- })) as FileData[]
|
|
|
|
|
|
|
+ }))
|
|
|
|
|
+ },
|
|
|
|
|
+ enabled: isLoggedIn && talentId > 0
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 获取工作视频 - 使用企业专用视频API
|
|
|
|
|
+ const { data: videos, isLoading: videosLoading } = useQuery({
|
|
|
|
|
+ queryKey: ['videos', talentId],
|
|
|
|
|
+ queryFn: async () => {
|
|
|
|
|
+ if (!talentId) throw new Error('无效的人才ID')
|
|
|
|
|
+ // 使用企业专用视频API:/api/v1/yongren/disability-person/{id}/videos
|
|
|
|
|
+ const response = await enterpriseDisabilityClient[':id']['videos'].$get({
|
|
|
|
|
+ param: { id: talentId }
|
|
|
|
|
+ })
|
|
|
|
|
+ if (response.status !== 200) {
|
|
|
|
|
+ // 可能没有视频,返回空数组
|
|
|
|
|
+ return []
|
|
|
|
|
+ }
|
|
|
|
|
+ const data = await response.json()
|
|
|
|
|
+ // 企业专用视频API返回结构:{ 视频列表: [...] }
|
|
|
|
|
+ const videoList = data?.视频列表 || []
|
|
|
|
|
+ // 转换为VideoData数组
|
|
|
|
|
+ return videoList.map((item) => ({
|
|
|
|
|
+ id: item.视频ID || '',
|
|
|
|
|
+ title: item.视频标题 || '未命名视频',
|
|
|
|
|
+ url: item.视频URL || undefined,
|
|
|
|
|
+ type: item.视频类型 || undefined,
|
|
|
|
|
+ uploadTime: item.上传时间 || undefined,
|
|
|
|
|
+ size: item.文件大小 || undefined,
|
|
|
|
|
+ category: (item.分类 as '个税视频' | '工资视频' | '工作视频' | '其他') || '其他'
|
|
|
|
|
+ }))
|
|
|
},
|
|
},
|
|
|
enabled: isLoggedIn && talentId > 0
|
|
enabled: isLoggedIn && talentId > 0
|
|
|
})
|
|
})
|
|
@@ -262,7 +248,7 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
})
|
|
})
|
|
|
}, [])
|
|
}, [])
|
|
|
|
|
|
|
|
- const isLoading = talentLoading || workLoading || salaryLoading || filesLoading || historyLoading || workHistoryLoading
|
|
|
|
|
|
|
+ const isLoading = talentLoading || workLoading || salaryLoading || filesLoading || historyLoading || workHistoryLoading || videosLoading
|
|
|
const hasError = talentError
|
|
const hasError = talentError
|
|
|
|
|
|
|
|
// 获取头像颜色
|
|
// 获取头像颜色
|
|
@@ -439,6 +425,64 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
</View>
|
|
</View>
|
|
|
</View>
|
|
</View>
|
|
|
|
|
|
|
|
|
|
+ {/* 历史工作内容时间线卡片 - 原型第673-739行 */}
|
|
|
|
|
+ <View className="card bg-white p-4 mb-4">
|
|
|
|
|
+ <Text className="font-semibold text-gray-700 mb-3">历史工作内容</Text>
|
|
|
|
|
+ {workHistoryLoading ? (
|
|
|
|
|
+ <View className="space-y-4">
|
|
|
|
|
+ {[1, 2, 3].map((i) => (
|
|
|
|
|
+ <View key={i} className="flex items-start animate-pulse">
|
|
|
|
|
+ <View className="w-3 h-3 bg-gray-200 rounded-full mt-1 mr-3" />
|
|
|
|
|
+ <View className="flex-1">
|
|
|
|
|
+ <View className="h-4 bg-gray-200 rounded w-1/3 mb-2" />
|
|
|
|
|
+ <View className="h-3 bg-gray-200 rounded w-2/3" />
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ) : workHistoryFull && workHistoryFull.length > 0 ? (
|
|
|
|
|
+ <View className="space-y-6">
|
|
|
|
|
+ {workHistoryFull.map((work: WorkHistoryItem, index: number) => {
|
|
|
|
|
+ const isCurrent = work.工作状态 === '在职' || index === 0
|
|
|
|
|
+ const startDate = work.入职日期 ? formatDate(work.入职日期) : '未指定'
|
|
|
|
|
+ const endDate = work.离职日期 ? formatDate(work.离职日期) : '至今'
|
|
|
|
|
+ const period = `${startDate} - ${endDate}`
|
|
|
|
|
+ const salary = work.个人薪资 ? `¥${work.个人薪资.toLocaleString()}` : '未指定'
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <View key={work.订单ID || index} className="flex items-start">
|
|
|
|
|
+ {/* 时间线圆点 */}
|
|
|
|
|
+ <View className={`w-3 h-3 rounded-full mt-1 mr-3 ${isCurrent ? 'bg-blue-500' : 'bg-gray-300'}`} />
|
|
|
|
|
+ <View className="flex-1">
|
|
|
|
|
+ {/* 公司/订单名称 */}
|
|
|
|
|
+ <Text className="font-medium text-gray-800 text-sm">
|
|
|
|
|
+ {work.订单名称 || `订单 #${work.订单ID}` || '未命名工作'}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ {/* 岗位和薪资 */}
|
|
|
|
|
+ <View className="flex flex-wrap items-center gap-2 mt-1">
|
|
|
|
|
+ <Text className="text-xs text-gray-600">岗位: {work.工作状态 || '未指定'}</Text>
|
|
|
|
|
+ <Text className="text-xs text-gray-600">薪资: {salary}</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ {/* 时间段 */}
|
|
|
|
|
+ <Text className="text-xs text-gray-500 mt-1">{period}</Text>
|
|
|
|
|
+ {/* 工作描述(如果有的话) */}
|
|
|
|
|
+ {work.工作状态 && (
|
|
|
|
|
+ <Text className="text-xs text-gray-500 mt-1">
|
|
|
|
|
+ 工作状态: {work.工作状态}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )
|
|
|
|
|
+ })}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <View className="text-center py-4">
|
|
|
|
|
+ <Text className="text-gray-400 text-sm">暂无工作历史记录</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </View>
|
|
|
|
|
+
|
|
|
{/* 薪资历史记录卡片 */}
|
|
{/* 薪资历史记录卡片 */}
|
|
|
<View className="card bg-white p-4 mb-4">
|
|
<View className="card bg-white p-4 mb-4">
|
|
|
<Text className="font-semibold text-gray-700 mb-3">薪资历史记录</Text>
|
|
<Text className="font-semibold text-gray-700 mb-3">薪资历史记录</Text>
|
|
@@ -512,6 +556,69 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
</View>
|
|
</View>
|
|
|
)}
|
|
)}
|
|
|
</View>
|
|
</View>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 工作视频管理区域 - 原型第765-829行 */}
|
|
|
|
|
+ <View className="card bg-white p-4 mb-4">
|
|
|
|
|
+ <View className="flex justify-between items-center mb-3">
|
|
|
|
|
+ <Text className="font-semibold text-gray-700">工作视频</Text>
|
|
|
|
|
+ <Text className="text-sm text-blue-500">查看更多</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ {videosLoading ? (
|
|
|
|
|
+ <View className="space-y-3">
|
|
|
|
|
+ {[1, 2, 3].map((i) => (
|
|
|
|
|
+ <View key={i} className="flex items-center p-3 bg-gray-50 rounded-lg animate-pulse">
|
|
|
|
|
+ <View className="w-10 h-10 bg-gray-200 rounded mr-3" />
|
|
|
|
|
+ <View className="flex-1">
|
|
|
|
|
+ <View className="h-4 bg-gray-200 rounded w-1/2 mb-1" />
|
|
|
|
|
+ <View className="h-3 bg-gray-200 rounded w-1/3" />
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className="flex space-x-2">
|
|
|
|
|
+ <View className="w-8 h-8 bg-gray-200 rounded" />
|
|
|
|
|
+ <View className="w-8 h-8 bg-gray-200 rounded" />
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ) : videos && videos.length > 0 ? (
|
|
|
|
|
+ <View className="space-y-3">
|
|
|
|
|
+ {/* 按分类分组显示 */}
|
|
|
|
|
+ {['个税视频', '工资视频', '工作视频', '其他'].map((category) => {
|
|
|
|
|
+ const categoryVideos = videos.filter(v => v.category === category)
|
|
|
|
|
+ if (categoryVideos.length === 0) return null
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <View key={category} className="space-y-2">
|
|
|
|
|
+ <Text className="text-sm font-medium text-gray-600 mb-1">{category}</Text>
|
|
|
|
|
+ {categoryVideos.map((video) => (
|
|
|
|
|
+ <View key={video.id} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
|
|
|
|
|
+ <View className="flex items-center">
|
|
|
|
|
+ <View className="w-10 h-10 bg-blue-100 rounded flex items-center justify-center mr-3">
|
|
|
|
|
+ <Text className="i-heroicons-play-20-solid text-blue-500 text-lg" />
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View>
|
|
|
|
|
+ <Text className="text-sm text-gray-800 font-medium">{video.title}</Text>
|
|
|
|
|
+ <Text className="text-xs text-gray-500">
|
|
|
|
|
+ {video.uploadTime ? formatDate(video.uploadTime) : '未知时间'} ·
|
|
|
|
|
+ {video.size ? ` ${(video.size / 1024 / 1024).toFixed(2)} MB` : ' 大小未知'}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className="flex space-x-2">
|
|
|
|
|
+ <Text className="i-heroicons-eye-20-solid text-blue-500 text-lg" />
|
|
|
|
|
+ <Text className="i-heroicons-arrow-down-tray-20-solid text-green-500 text-lg" />
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )
|
|
|
|
|
+ })}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <View className="text-center py-4">
|
|
|
|
|
+ <Text className="text-gray-400 text-sm">暂无工作视频</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </View>
|
|
|
</View>
|
|
</View>
|
|
|
</>
|
|
</>
|
|
|
) : (
|
|
) : (
|
|
@@ -522,6 +629,48 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
</View>
|
|
</View>
|
|
|
)}
|
|
)}
|
|
|
</ScrollView>
|
|
</ScrollView>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 底部操作按钮区域 - 原型第831-839行 */}
|
|
|
|
|
+ {talentDetail && !isLoading && !hasError && (
|
|
|
|
|
+ <View className="fixed bottom-0 left-0 right-0 p-4 bg-white border-t border-gray-200">
|
|
|
|
|
+ <View className="flex space-x-3">
|
|
|
|
|
+ {/* 联系按钮 */}
|
|
|
|
|
+ <View
|
|
|
|
|
+ className="flex-1 bg-blue-500 text-white py-3 rounded-lg font-medium flex items-center justify-center active:bg-blue-600"
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ // 联系功能:拨打电话或跳转
|
|
|
|
|
+ if (talentDetail.phone) {
|
|
|
|
|
+ Taro.makePhoneCall({
|
|
|
|
|
+ phoneNumber: talentDetail.phone
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Taro.showToast({
|
|
|
|
|
+ title: '暂无联系电话',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Text className="i-heroicons-phone-20-solid mr-2" />
|
|
|
|
|
+ <Text>联系</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 编辑按钮 */}
|
|
|
|
|
+ <View
|
|
|
|
|
+ className="flex-1 bg-gray-100 text-gray-800 py-3 rounded-lg font-medium flex items-center justify-center active:bg-gray-200"
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ // 编辑功能:跳转编辑页面
|
|
|
|
|
+ Taro.navigateTo({
|
|
|
|
|
+ url: `/pages/yongren/talent/edit?id=${talentId}`
|
|
|
|
|
+ })
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Text className="i-heroicons-pencil-square-20-solid mr-2" />
|
|
|
|
|
+ <Text>编辑</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ )}
|
|
|
</PageContainer>
|
|
</PageContainer>
|
|
|
</YongrenTabBarLayout>
|
|
</YongrenTabBarLayout>
|
|
|
)
|
|
)
|