Files
codePortAdmin/src/mock/project.ts
2025-12-28 22:09:44 +08:00

184 lines
7.8 KiB
TypeScript

/**
* 项目相关模拟数据
*/
import type { ProjectInfo, ProjectTag, ProjectPublisher, ProjectQueryParams, ProjectListResult, WorkType } from '@/types'
// 模拟项目标签
const mockProjectTags: ProjectTag[] = [
{ id: 1, name: 'Vue', color: '#42b883' },
{ id: 2, name: 'React', color: '#61dafb' },
{ id: 3, name: 'Node.js', color: '#339933' },
{ id: 4, name: 'Python', color: '#3776ab' },
{ id: 5, name: 'Java', color: '#007396' },
{ id: 6, name: 'Go', color: '#00add8' },
{ id: 7, name: '小程序', color: '#07c160' },
{ id: 8, name: 'APP开发', color: '#ff6b6b' },
{ id: 9, name: '数据分析', color: '#845ef7' },
{ id: 10, name: 'AI/ML', color: '#ff922b' }
]
// 模拟发布人
const mockPublishers: ProjectPublisher[] = [
{ id: 1, username: 'techcorp', nickname: '科技有限公司', avatar: 'https://api.dicebear.com/7.x/identicon/svg?seed=techcorp', company: '科技有限公司' },
{ id: 2, username: 'startup', nickname: '创业团队', avatar: 'https://api.dicebear.com/7.x/identicon/svg?seed=startup', company: '创新科技' },
{ id: 3, username: 'bigcompany', nickname: '大厂HR', avatar: 'https://api.dicebear.com/7.x/identicon/svg?seed=bigcompany', company: '某大厂' },
{ id: 4, username: 'freelancer', nickname: '独立开发者', avatar: 'https://api.dicebear.com/7.x/identicon/svg?seed=freelancer' },
{ id: 5, username: 'agency', nickname: '外包公司', avatar: 'https://api.dicebear.com/7.x/identicon/svg?seed=agency', company: '软件外包' }
]
const projectNames = [
'企业官网开发项目', '电商小程序开发', '数据可视化平台', 'CRM系统定制开发',
'APP后端接口开发', '在线教育平台开发', '社交应用开发', '物流管理系统',
'AI智能客服系统', '区块链应用开发', '医疗健康APP', '金融风控系统'
]
const locations = ['北京', '上海', '深圳', '杭州', '广州', '成都', '武汉', '南京', '不限']
const workTypes: WorkType[] = ['fulltime', 'parttime', 'remote', 'internship']
const descriptions = [
'我们正在寻找有经验的开发者加入我们的项目,参与核心功能的开发和优化。项目采用最新的技术栈,有良好的代码规范和开发流程。',
'这是一个具有挑战性的项目,需要您具备扎实的编程基础和良好的学习能力。我们提供灵活的工作时间和有竞争力的薪资待遇。',
'加入我们的团队,您将有机会参与大型项目的架构设计和技术选型,与优秀的工程师一起工作,不断提升自己的技术能力。'
]
const requirements = [
'1. 3年以上相关开发经验\n2. 熟悉主流开发框架\n3. 良好的代码规范意识\n4. 具备团队协作精神\n5. 有大型项目经验优先',
'1. 本科及以上学历\n2. 熟练掌握至少一门编程语言\n3. 了解常用设计模式\n4. 具备独立解决问题的能力\n5. 有开源项目经验优先',
'1. 2年以上工作经验\n2. 熟悉敏捷开发流程\n3. 具备良好的沟通能力\n4. 能够承受一定的工作压力\n5. 对技术有热情'
]
const benefits = [
'五险一金、带薪年假、弹性工作、免费午餐、定期团建、技术分享会',
'远程办公、股权激励、年终奖金、技术培训、健身房、零食饮料',
'双休、节日福利、项目奖金、晋升通道清晰、技术氛围好'
]
// 生成模拟项目数据
function generateMockProjects(): ProjectInfo[] {
const projects: ProjectInfo[] = []
for (let i = 1; i <= 40; i++) {
const salaryMin = Math.floor(Math.random() * 20 + 5) * 1000
const salaryMax = salaryMin + Math.floor(Math.random() * 15 + 5) * 1000
const deadlineDate = new Date(Date.now() + Math.floor(Math.random() * 60 + 10) * 24 * 60 * 60 * 1000)
const isExpired = Math.random() > 0.9
const tag1 = mockProjectTags[i % mockProjectTags.length]!
const tag2 = mockProjectTags[(i + 3) % mockProjectTags.length]!
const isPinned = Math.random() > 0.8
const pinnedDays = [3, 7, 14, 30][Math.floor(Math.random() * 4)]
projects.push({
id: i,
name: projectNames[i % projectNames.length]!,
salaryMin,
salaryMax,
salaryUnit: Math.random() > 0.7 ? '项目' : '月',
publisher: mockPublishers[i % mockPublishers.length]!,
location: locations[i % locations.length]!,
workType: workTypes[i % workTypes.length]!,
description: descriptions[i % descriptions.length]!,
requirements: requirements[i % requirements.length]!,
benefits: benefits[i % benefits.length]!,
tags: tag1.id === tag2.id ? [tag1] : [tag1, tag2],
contactEmail: `hr${i}@example.com`,
deadline: deadlineDate.toISOString(),
status: isExpired ? 'expired' : (Math.random() > 0.2 ? 'active' : 'closed'),
createdAt: new Date(Date.now() - Math.floor(Math.random() * 30 * 24 * 60 * 60 * 1000)).toISOString(),
updatedAt: new Date(Date.now() - Math.floor(Math.random() * 7 * 24 * 60 * 60 * 1000)).toISOString(),
isPinned,
pinnedUntil: isPinned ? new Date(Date.now() + pinnedDays! * 24 * 60 * 60 * 1000).toISOString() : undefined,
exposureCount: Math.floor(Math.random() * 500),
lastExposureAt: Math.random() > 0.5 ? new Date(Date.now() - Math.floor(Math.random() * 3 * 24 * 60 * 60 * 1000)).toISOString() : undefined
})
}
return projects.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
}
let mockProjects = generateMockProjects()
// 模拟延迟
function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms))
}
// 获取项目列表
export async function mockGetProjectList(params: ProjectQueryParams = {}): Promise<ProjectListResult> {
await delay(300)
const { page = 1, pageSize = 10, keyword, workType, tagId, status, location } = params
let filtered = [...mockProjects]
if (keyword) {
filtered = filtered.filter(p => p.name.includes(keyword) || p.publisher.nickname.includes(keyword))
}
if (workType) {
filtered = filtered.filter(p => p.workType === workType)
}
if (tagId) {
filtered = filtered.filter(p => p.tags.some(t => t.id === tagId))
}
if (status) {
filtered = filtered.filter(p => p.status === status)
}
if (location) {
filtered = filtered.filter(p => p.location === location || p.location === '不限')
}
const start = (page - 1) * pageSize
const list = filtered.slice(start, start + pageSize)
return { list, total: filtered.length, page, pageSize }
}
// 删除项目
export async function mockDeleteProject(id: number): Promise<void> {
await delay(200)
mockProjects = mockProjects.filter(p => p.id !== id)
}
// 批量删除项目
export async function mockBatchDeleteProjects(ids: number[]): Promise<void> {
await delay(300)
mockProjects = mockProjects.filter(p => !ids.includes(p.id))
}
// 获取项目标签列表
export async function mockGetProjectTags(): Promise<ProjectTag[]> {
await delay(100)
return mockProjectTags
}
// 获取工作地点列表
export async function mockGetLocations(): Promise<string[]> {
await delay(100)
return locations
}
// 设置项目置顶
export async function mockSetProjectPin(id: number, isPinned: boolean, days?: number): Promise<ProjectInfo | null> {
await delay(200)
const project = mockProjects.find(p => p.id === id)
if (project) {
project.isPinned = isPinned
project.pinnedUntil = isPinned && days ? new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString() : undefined
project.updatedAt = new Date().toISOString()
return project
}
return null
}
// 手动曝光项目
export async function mockExposeProject(id: number): Promise<ProjectInfo | null> {
await delay(200)
const project = mockProjects.find(p => p.id === id)
if (project) {
project.exposureCount += 1
project.lastExposureAt = new Date().toISOString()
project.updatedAt = new Date().toISOString()
return project
}
return null
}