作为 人才小程序开发者, 我想要 实现就业信息页面功能, 以便 人才用户能够查看当前就业状态、薪资记录和就业历史。
现有系统状态:
@d8d/rencai-employment-ui包基础框架已就绪src/api/index.ts)原型设计参考:
docs/小程序原型/rencai.html 提供了就业信息页面的完整原型设计技术集成模式:
yongren-employment-ui的实现模式(如果存在)@d8d/rencai-employment-ui包依赖API (史诗015):
依赖故事完成状态:
@d8d/rencai-employment-ui中实现EmploymentPage页面组件 (src/pages/EmploymentPage/EmploymentPage.tsx)src/components/CurrentEmploymentStatus.tsx)
src/utils/mockEmploymentData.ts)
src/components/SalaryRecords.tsx)
src/components/SalaryRecordItem.tsx)
src/types/employment.ts)
src/components/EmploymentHistory.tsx)
src/components/EmploymentHistoryItem.tsx)
src/types/employment.ts)
import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'leftIcon="i-heroicons-chevron-left-20-solid" leftText="返回" onClickLeft={() => Taro.navigateBack()}placeholder属性占位,移除手动空白占位fixed=true)mini-talent/src/pages/employment/index.tsx:
@d8d/rencai-employment-ui/pages/EmploymentPage/EmploymentPage导入EmploymentPage组件tests/pages/EmploymentPage/EmploymentPage.test.tsx)
pnpm typecheck确保类型检查通过故事017.001完成状态:
@d8d/rencai-employment-ui包基础框架已就绪src/api/index.ts)jest.config.cjs)故事017.002完成状态:
故事017.003完成状态:
maskUtils.ts)故事017.004完成状态:
flex flex-col实现垂直布局)故事017.012完成状态:
关键实现经验:
@d8d/server@d8d/mini-shared-ui-components中的实现来源: architecture/tech-stack.md
运行时和框架:
测试框架:
重要: mini项目使用Jest测试框架,与web应用使用的Vitest不同。
来源:
关键规范要求:
重要: UI包内部导入必须使用相对路径,不要使用别名。
正确示例:
// ✅ 正确: 使用相对路径导入同一包内的模块
import { mockEmploymentData } from '../../utils/mockEmploymentData'
import { CurrentEmploymentStatus } from '../components/CurrentEmploymentStatus'
错误示例:
// ❌ 错误: 不要使用别名导入UI包内部的模块
import { mockEmploymentData } from '@/utils/mockEmploymentData'
import { CurrentEmploymentStatus } from '@/components/CurrentEmploymentStatus'
{
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/src/index.js",
"require": "./dist/src/index.js"
},
"./api": {
"types": "./src/api/index.ts",
"import": "./src/api/index.ts",
"require": "./src/api/index.ts"
},
"./pages/EmploymentPage/EmploymentPage": {
"types": "./dist/src/pages/EmploymentPage/EmploymentPage.d.ts",
"import": "./dist/src/pages/EmploymentPage/EmploymentPage.js",
"require": "./dist/src/pages/EmploymentPage/EmploymentPage.js"
}
}
}
重要: 本故事使用前端模拟数据,数据结构必须符合后续API接口规范。
模拟数据文件位置: src/utils/mockEmploymentData.ts
数据结构示例:
// 当前就业状态(符合后续API接口规范)
export interface CurrentEmploymentStatus {
companyName: string // 企业名称(如:阿里巴巴集团)
positionName: string // 岗位名称(如:数据标注员)
hireDate: string // 入职日期(如:2023-08-15)
workStatus: EmploymentStatus // 工作状态
orderNumber: string // 订单编号(如:AL20230815001)
salaryLevel: string // 薪资水平(如:¥4,800/月)
}
// 薪资记录数据(符合后续API接口规范)
export interface SalaryRecord {
month: string // 月份(如:2023年11月)
paymentDate: string // 发放日期(如:2023-12-05)
amount: number // 薪资金额(如:4800)
}
// 就业历史数据(符合后续API接口规范)
export interface EmploymentHistoryItem {
companyName: string // 企业名称
positionName: string // 岗位名称
startDate: string // 开始日期(如:2023-08-15)
endDate: string | null // 结束日期(null表示至今,如:2023-07-31)
}
export enum EmploymentStatus {
ACTIVE = 'active', // 在职
INACTIVE = 'inactive' // 离职
}
// 模拟数据导出
export const mockCurrentEmploymentStatus: CurrentEmploymentStatus = {
companyName: '阿里巴巴集团',
positionName: '数据标注员',
hireDate: '2023-08-15',
workStatus: EmploymentStatus.ACTIVE,
orderNumber: 'AL20230815001',
salaryLevel: '¥4,800/月'
}
export const mockSalaryRecords: SalaryRecord[] = [
{
month: '2023年11月',
paymentDate: '2023-12-05',
amount: 4800
},
// ... 更多记录
]
export const mockEmploymentHistory: EmploymentHistoryItem[] = [
{
companyName: '阿里巴巴集团',
positionName: '数据标注员',
startDate: '2023-08-15',
endDate: null // 至今
},
// ... 更多记录
]
后续API集成预留:
每个UI包必须创建jest.config.cjs配置文件,参照rencai-personal-info-ui/jest.config.cjs:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['@d8d/mini-testing-utils/setup'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
'^~/(.*)$': '<rootDir>/tests/$1',
'^@tarojs/taro$': '@d8d/mini-testing-utils/testing/taro-api-mock.ts',
'\\.(css|less|scss|sass)$': '@d8d/mini-testing-utils/testing/style-mock.js',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'@d8d/mini-testing-utils/testing/file-mock.js'
},
testMatch: [
'<rootDir>/tests/**/*.spec.{ts,tsx}',
'<rootDir>/tests/**/*.test.{ts,tsx}'
],
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/index.{ts,tsx}',
'!src/**/*.stories.{ts,tsx}'
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html'],
testPathIgnorePatterns: [
'/node_modules/',
'/dist/',
'/coverage/'
],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
'^.+\\.(js|jsx)$': 'babel-jest'
},
transformIgnorePatterns: [
'/node_modules/(?!(swiper|@tarojs)/)'
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json']
}
就业信息页 (原型行630-768):
<!-- 当前就业状态 -->
<div class="card bg-white p-4 mb-4">
<h3 class="font-semibold text-gray-700 mb-3">当前就业状态</h3>
<!-- 企业图标和名称 -->
<div class="flex items-center mb-4">
<div class="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mr-3">
<i class="fas fa-building text-blue-500"></i>
</div>
<div>
<p class="font-medium text-gray-800">阿里巴巴集团</p>
<p class="text-sm text-gray-500">数据标注员</p>
</div>
</div>
<!-- 2列网格信息 -->
<div class="grid grid-cols-2 gap-3 text-sm">
<div>
<p class="text-gray-500">入职日期</p>
<p class="text-gray-800">2023-08-15</p>
</div>
<div>
<p class="text-gray-500">工作状态</p>
<span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">在职</span>
</div>
<div>
<p class="text-gray-500">订单编号</p>
<p class="text-gray-800">AL20230815001</p>
</div>
<div>
<p class="text-gray-500">薪资水平</p>
<p class="text-gray-800">¥4,800/月</p>
</div>
</div>
</div>
移动端设计规范:
bg-whiterounded-lg)p-4)mb-4)bg-blue-100)building-office-2-20-solid(替代fas fa-building)grid grid-cols-2 gap-3)rounded-full)bg-green-100 text-green-800)bg-gray-100 text-gray-800)<!-- 薪资记录 -->
<div class="card bg-white p-4 mb-4">
<div class="flex justify-between items-center mb-3">
<h3 class="font-semibold text-gray-700">薪资记录</h3>
<button class="text-blue-500 text-sm">查看全部</button>
</div>
<div class="space-y-3">
<!-- 薪资记录1 -->
<div class="flex justify-between items-center p-3 border border-gray-100 rounded-lg">
<div>
<p class="text-sm font-medium text-gray-800">2023年11月</p>
<p class="text-xs text-gray-500">发放日期: 2023-12-05</p>
</div>
<p class="text-lg font-bold text-gray-800">¥4,800</p>
</div>
<!-- ... 更多记录 -->
</div>
</div>
移动端设计规范:
bg-whiterounded-lg)space-y-3)text-sm)text-xs)text-lg),加粗 (font-bold)<!-- 就业历史 -->
<div class="card bg-white p-4">
<h3 class="font-semibold text-gray-700 mb-3">就业历史</h3>
<div class="space-y-4">
<!-- 就业记录1 -->
<div class="flex">
<!-- 时间线圆点+连线 -->
<div class="flex flex-col items-center mr-3">
<div class="w-3 h-3 rounded-full bg-blue-500"></div>
<div class="w-0.5 h-full bg-gray-200 mt-1"></div>
</div>
<!-- 内容 -->
<div class="flex-1 pb-4">
<p class="font-medium text-gray-800">阿里巴巴集团</p>
<p class="text-sm text-gray-500 mb-1">数据标注员</p>
<p class="text-xs text-gray-500">2023-08-15 至今</p>
</div>
</div>
<!-- ... 更多记录 -->
</div>
</div>
移动端设计规范:
rounded-full)bg-blue-500)bg-gray-400)w-0.5),灰色 (bg-gray-200)font-medium)text-sm)text-xs)来源: docs/stories/017.012.story.md
非TabBar页面规范(就业信息页属于此类):
leftIcon="i-heroicons-chevron-left-20-solid"和leftText="返回"@d8d/mini-shared-ui-components/components/navbarNavbar集成示例:
import Taro from '@tarojs/taro'
import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'
import { View, ScrollView } from '@tarojs/components'
export function EmploymentPage() {
return (
<View className="h-screen bg-gray-100">
{/* Navbar导航栏 - 非TabBar页面带返回按钮 */}
<Navbar
title="就业信息"
leftIcon="i-heroicons-chevron-left-20-solid"
leftText="返回"
onClickLeft={() => Taro.navigateBack()}
placeholder
fixed
/>
{/* 页面内容 */}
<ScrollView scrollY className="h-full">
{/* 页面内容 */}
</ScrollView>
</View>
)
}
关键配置:
leftIcon="i-heroicons-chevron-left-20-solid": 显示返回按钮图标leftText="返回": 显示返回按钮文字onClickLeft={() => Taro.navigateBack()}: 返回功能placeholder: 添加占位空间,避免内容被Navbar遮挡fixed: 固定在顶部来源: architecture/source-tree.md
mini-talent项目结构:
mini-talent/ # 人才小程序项目
├── src/
│ ├── app.tsx # 小程序入口
│ ├── app.config.ts # 小程序配置
│ ├── app.css # 全局样式
│ ├── pages/ # 页面目录
│ │ ├── login/ # 登录页
│ │ ├── index/ # 首页/个人主页
│ │ ├── attendance/ # 考勤记录页
│ │ ├── personal-info/ # 个人信息页
│ │ ├── employment/ # 就业信息页 (从首页跳转) - 本故事
│ │ │ └── index.tsx
│ │ └── settings/ # 设置页
├── package.json
├── jest.config.js
└── tsconfig.json
mini-ui-packages目录结构:
mini-ui-packages/
├── rencai-employment-ui/ # 人才就业信息UI包
│ ├── src/
│ │ ├── api/
│ │ │ ├── employmentClient.ts
│ │ │ └── index.ts
│ │ ├── pages/
│ │ │ └── EmploymentPage/
│ │ │ ├── EmploymentPage.tsx
│ │ │ └── index.ts (可选)
│ │ ├── components/ # UI组件
│ │ │ ├── CurrentEmploymentStatus.tsx # 当前就业状态
│ │ │ ├── SalaryRecords.tsx # 薪资记录
│ │ │ ├── SalaryRecordItem.tsx # 薪资记录项
│ │ │ ├── EmploymentHistory.tsx # 就业历史
│ │ │ └── EmploymentHistoryItem.tsx # 就业历史项
│ │ ├── types/
│ │ │ └── employment.ts # 类型定义
│ │ ├── utils/
│ │ │ └── mockEmploymentData.ts # 前端模拟数据
│ │ └── index.ts
│ ├── package.json
│ ├── jest.config.cjs
│ └── tsconfig.json
└── mini-shared-ui-components/ # 通用小程序UI组件
├── src/
│ └── components/
│ ├── status-bar.tsx
│ ├── page-container.tsx
│ ├── navbar.tsx
│ └── tab-bar.tsx
└── ...
mini-talent页面导入方式:
// mini-talent/src/pages/employment/index.tsx
import EmploymentPage from '@d8d/rencai-employment-ui/pages/EmploymentPage/EmploymentPage'
import { AuthContextProvider, useAuth } from '@d8d/rencai-auth-ui/utils'
function Employment() {
const { isLoggedIn } = useAuth()
// 未登录跳转到登录页
if (!isLoggedIn) {
Taro.navigateTo({ url: '/pages/login/index' })
return null
}
return <EmploymentPage />
}
export default function EmploymentIndex() {
return (
<AuthContextProvider>
<Employment />
</AuthContextProvider>
)
}
重要: 在Taro小程序中,<View> 组件内的子元素默认是横向布局(flex-row),需要显式添加 flex flex-col 类才能实现垂直布局。
正确示例:
// ✅ 正确: 使用 flex flex-col 实现垂直布局
<View className="flex flex-col">
<Text>企业名称: 阿里巴巴集团</Text>
<Text>岗位名称: 数据标注员</Text>
<Text>入职日期: 2023-08-15</Text>
</View>
// ❌ 错误: 缺少 flex flex-col,子元素会横向排列
<View>
<Text>企业名称: 阿里巴巴集团</Text>
<Text>岗位名称: 数据标注员</Text>
<Text>入职日期: 2023-08-15</Text>
</View>
当前就业状态卡片示例:
import { View, Text } from '@tarojs/components'
export function CurrentEmploymentStatus({ status }: { status: CurrentEmploymentStatus }) {
return (
<View className="bg-white rounded-lg p-4 mb-4">
<Text className="font-semibold text-gray-700 mb-3">当前就业状态</Text>
{/* 企业图标和名称 - 水平布局 */}
<View className="flex items-center mb-4">
{/* 企业图标 - Heroicons building */}
<View className="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mr-3">
<View className="i-heroicons-building-office-2-20-solid text-blue-500 w-6 h-6" />
</View>
<View>
<Text className="font-medium text-gray-800">{status.companyName}</Text>
<Text className="text-sm text-gray-500">{status.positionName}</Text>
</View>
</View>
{/* 2列网格信息 - 水平布局 */}
<View className="grid grid-cols-2 gap-3 text-sm">
{/* 入职日期 */}
<View className="flex flex-col">
<Text className="text-gray-500">入职日期</Text>
<Text className="text-gray-800">{status.hireDate}</Text>
</View>
{/* 工作状态 */}
<View className="flex flex-col">
<Text className="text-gray-500">工作状态</Text>
<View className={`text-xs px-2 py-1 rounded-full ${
status.workStatus === EmploymentStatus.ACTIVE
? 'bg-green-100 text-green-800'
: 'bg-gray-100 text-gray-800'
}`}>
<Text>{status.workStatus === EmploymentStatus.ACTIVE ? '在职' : '离职'}</Text>
</View>
</View>
{/* 订单编号 */}
<View className="flex flex-col">
<Text className="text-gray-500">订单编号</Text>
<Text className="text-gray-800">{status.orderNumber}</Text>
</View>
{/* 薪资水平 */}
<View className="flex flex-col">
<Text className="text-gray-500">薪资水平</Text>
<Text className="text-gray-800">{status.salaryLevel}</Text>
</View>
</View>
</View>
)
}
关键点:
flex items-center)grid grid-cols-2)flex flex-col)显示标签和值flex flex-col来源: architecture/mini-ui-package-standards.md
重要: 不要使用emoji,必须使用Heroicons图标类。
图标类命名格式: i-heroicons-{图标名称}-{尺寸}-{样式}
本故事需要的图标:
building-office-2-20-solid - 企业图标(替代fas fa-building)chevron-left-20-solid - 左箭头(返回按钮)正确示例:
// ✅ 正确: 使用Heroicons图标类
<View className="i-heroicons-building-office-2-20-solid w-6 h-6 text-blue-500" />
// ❌ 错误: 使用emoji
<Text>🏢</Text>
企业图标示例:
import { View } from '@tarojs/components'
export function CompanyIcon() {
return (
<View className="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center">
<View className="i-heroicons-building-office-2-20-solid text-blue-500 w-6 h-6" />
</View>
)
}
数据工厂模式:
// src/utils/mockEmploymentData.ts
/**
* 生成模拟就业信息数据
* @returns 就业状态、薪资记录、就业历史
*/
export function generateMockEmploymentData(): {
currentStatus: CurrentEmploymentStatus
salaryRecords: SalaryRecord[]
employmentHistory: EmploymentHistoryItem[]
} {
// 当前就业状态
const currentStatus: CurrentEmploymentStatus = {
companyName: '阿里巴巴集团',
positionName: '数据标注员',
hireDate: '2023-08-15',
workStatus: EmploymentStatus.ACTIVE,
orderNumber: 'AL20230815001',
salaryLevel: '¥4,800/月'
}
// 薪资记录(按月份倒序)
const salaryRecords: SalaryRecord[] = [
{
month: '2023年11月',
paymentDate: '2023-12-05',
amount: 4800
},
{
month: '2023年10月',
paymentDate: '2023-11-05',
amount: 4800
},
{
month: '2023年9月',
paymentDate: '2023-10-08',
amount: 4650
}
]
// 就业历史(按时间倒序)
const employmentHistory: EmploymentHistoryItem[] = [
{
companyName: '阿里巴巴集团',
positionName: '数据标注员',
startDate: '2023-08-15',
endDate: null // 至今
},
{
companyName: '腾讯科技',
positionName: '内容审核员',
startDate: '2023-03-10',
endDate: '2023-07-31'
},
{
companyName: '字节跳动',
positionName: '数据录入员',
startDate: '2022-09-01',
endDate: '2023-02-28'
}
]
return { currentStatus, salaryRecords, employmentHistory }
}
来源: architecture/testing-strategy.md
测试框架:
测试文件位置:
mini-ui-packages/<package-name>/
└── tests/
├── unit/ # 单元测试
│ └── components/
│ ├── CurrentEmploymentStatus.test.tsx
│ ├── SalaryRecords.test.tsx
│ ├── SalaryRecordItem.test.tsx
│ ├── EmploymentHistory.test.tsx
│ └── EmploymentHistoryItem.test.tsx
└── pages/ # 页面组件测试
└── EmploymentPage/
└── EmploymentPage.test.tsx
测试要求:
pnpm typecheck确保类型检查通过Mock响应示例:
const mockCurrentEmploymentStatus: CurrentEmploymentStatus = {
companyName: '阿里巴巴集团',
positionName: '数据标注员',
hireDate: '2023-08-15',
workStatus: EmploymentStatus.ACTIVE,
orderNumber: 'AL20230815001',
salaryLevel: '¥4,800/月'
}
const mockSalaryRecords: SalaryRecord[] = [
{
month: '2023年11月',
paymentDate: '2023-12-05',
amount: 4800
}
]
const mockEmploymentHistory: EmploymentHistoryItem[] = [
{
companyName: '阿里巴巴集团',
positionName: '数据标注员',
startDate: '2023-08-15',
endDate: null
}
]
来源: architecture/coding-standards.md
关键编码规范:
开发Mini UI包时,必须参考并遵循Mini UI包开发规范,该规范基于史诗011和017的经验总结。
flex flex-col实现垂直布局flex flex-col 实现垂直布局w-5 h-5、text-lg等)@/、~/等),必须使用相对路径路径使用示例:
// ✅ 正确: UI包内部使用相对路径
import { mockEmploymentData } from '../../utils/mockEmploymentData'
import { CurrentEmploymentStatus } from '../components/CurrentEmploymentStatus'
// ✅ 正确: 跨包导入使用workspace包名
import { SharedComponent } from '@d8d/mini-shared-ui-components'
// ❌ 错误: UI包内部使用别名
import { mockEmploymentData } from '@/utils/mockEmploymentData'
import { CurrentEmploymentStatus } from '@/components/CurrentEmploymentStatus'
mini-ui-packages/yongren-employment-ui (如果存在)mini-ui-packages/rencai-personal-info-ui
主要风险:
缓解措施:
来源: architecture/testing-strategy.md
测试框架:
测试文件位置:
mini-ui-packages/<package-name>/
└── tests/
├── unit/ # 单元测试
│ └── components/
│ ├── CurrentEmploymentStatus.test.tsx
│ ├── SalaryRecords.test.tsx
│ ├── SalaryRecordItem.test.tsx
│ ├── EmploymentHistory.test.tsx
│ └── EmploymentHistoryItem.test.tsx
└── pages/ # 页面组件测试
└── EmploymentPage/
└── EmploymentPage.test.tsx
组件测试:
当前就业状态测试:
薪资记录测试:
就业历史测试:
集成测试:
回归测试:
pnpm typecheck确保类型检查通过# 运行所有测试
cd mini-ui-packages/rencai-employment-ui && pnpm test
# 运行特定测试
pnpm test --testNamePattern="EmploymentPage"
# 生成覆盖率报告
pnpm test:coverage
| 日期 | 版本 | 描述 | 作者 |
|---|---|---|---|
| 2025-12-28 | 1.0 | 创建故事文档 | Bob (Scrum Master) |
| 2025-12-28 | 1.1 | 更新API状态(故事015.005已完成,可直接使用真实API) | Bob (Scrum Master) |
| 2025-12-28 | 1.2 | 状态更新为Approved | Bob (Scrum Master) |
| 2025-12-28 | 1.3 | 开发完成 - 实现就业信息页面功能 | James (Claude Code) |
此部分由开发代理在实施过程中填写
claude-sonnet-4-5-20251101
无
✅ 创建就业信息页面组件和当前就业状态卡片
CurrentEmploymentStatus组件,显示企业信息、工作状态、入职日期等building-office-2-20-solid图标✅ 实现薪资记录模块
SalaryRecords和SalaryRecordItem组件✅ 实现就业历史模块
EmploymentHistory和EmploymentHistoryItemComponent组件✅ 创建就业信息主页面组件
✅ 更新mini-talent页面集成
✅ 运行类型检查
pnpm typecheck通过✅ 编写测试
技术实现改进:
useQuery) 管理服务端状态,符合项目技术栈要求QueryClientProvider进行测试,验证RPC类型推断新增文件:
mini-ui-packages/rencai-employment-ui/src/types/employment.ts - 类型定义mini-ui-packages/rencai-employment-ui/src/components/CurrentEmploymentStatus.tsx - 当前就业状态卡片mini-ui-packages/rencai-employment-ui/src/components/SalaryRecordItem.tsx - 薪资记录项mini-ui-packages/rencai-employment-ui/src/components/SalaryRecords.tsx - 薪资记录列表mini-ui-packages/rencai-employment-ui/src/components/EmploymentHistoryItem.tsx - 就业历史项mini-ui-packages/rencai-employment-ui/src/components/EmploymentHistory.tsx - 就业历史列表mini-ui-packages/rencai-employment-ui/tests/unit/components/CurrentEmploymentStatus.test.tsx - 测试mini-ui-packages/rencai-employment-ui/tests/unit/components/SalaryRecordItem.test.tsx - 测试mini-ui-packages/rencai-employment-ui/tests/unit/components/SalaryRecords.test.tsx - 测试mini-ui-packages/rencai-employment-ui/tests/unit/components/EmploymentHistory.test.tsx - 测试mini-ui-packages/rencai-employment-ui/tests/pages/EmploymentPage/EmploymentPage.test.tsx - 页面集成测试(使用真实React Query)修改文件:
mini-ui-packages/rencai-employment-ui/src/pages/EmploymentPage/EmploymentPage.tsx - 使用React Query重构,符合项目技术栈mini-ui-packages/rencai-employment-ui/jest.config.cjs - 按照Mini UI测试规范简化配置此部分由QA代理在审查完成后填写