From 498fd7a5e8559ac4b6bacddd0ca4ae4456e43349 Mon Sep 17 00:00:00 2001 From: JiaoTianBo Date: Tue, 24 Mar 2026 19:32:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E6=B7=BB=E5=8A=A0=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E5=9F=BA=E7=A1=80=E6=A1=86=E6=9E=B6=E4=B8=8E=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 初始化项目配置,新增npmrc和package.json文件 - 创建Vue 3应用入口,集成Element Plus UI库及图标插件 - 配置路由包括首页、招聘者管理、职位管理、候选人管理和定时任务五个模块 - 实现布局组件包含侧边栏菜单、顶部导航及主内容区 - 封装统一的API请求模块,包含招聘者、职位、候选人、定时任务和系统接口 - 开发Dashboard页面,实现系统概览及状态展示功能 - 开发候选人管理页面,包括搜索筛选、分页展示、详情查看及评分功能 - 开发职位管理页面,支持职位列表、搜索过滤、分页管理及关联评价方案 - 设计基础样式和交互效果,保证页面布局和风格一致性 --- .../cn.yinlihupo/ylhp_hr_2_0_fronted/.npmrc | 4 + .../ylhp_hr_2_0_fronted/index.html | 13 + .../ylhp_hr_2_0_fronted/package.json | 26 + .../ylhp_hr_2_0_fronted/src/App.vue | 18 + .../ylhp_hr_2_0_fronted/src/api/api.js | 154 ++++++ .../src/components/Layout.vue | 160 ++++++ .../ylhp_hr_2_0_fronted/src/main.js | 22 + .../ylhp_hr_2_0_fronted/src/router/index.js | 49 ++ .../src/views/Candidates.vue | 364 +++++++++++++ .../src/views/Dashboard.vue | 244 +++++++++ .../ylhp_hr_2_0_fronted/src/views/Jobs.vue | 478 ++++++++++++++++++ .../src/views/Recruiters.vue | 415 +++++++++++++++ .../src/views/Scheduler.vue | 357 +++++++++++++ .../ylhp_hr_2_0_fronted/vite.config.js | 25 + 14 files changed, 2329 insertions(+) create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/.npmrc create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/index.html create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/package.json create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/App.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/api/api.js create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/components/Layout.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/main.js create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/router/index.js create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Candidates.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Dashboard.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Jobs.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Recruiters.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Scheduler.vue create mode 100644 src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/vite.config.js diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/.npmrc b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/.npmrc new file mode 100644 index 0000000..fdb6938 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/.npmrc @@ -0,0 +1,4 @@ +# pnpm 配置 +shamefully-hoist=true +strict-peer-dependencies=false +auto-install-peers=true diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/index.html b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/index.html new file mode 100644 index 0000000..dfe92ff --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/index.html @@ -0,0 +1,13 @@ + + + + + + 简历智能体 - HR管理系统 + + + +
+ + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/package.json b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/package.json new file mode 100644 index 0000000..8b1d171 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/package.json @@ -0,0 +1,26 @@ +{ + "name": "ylhp-hr-frontend", + "version": "0.1.0", + "private": true, + "type": "module", + "packageManager": "pnpm@9.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.4.0", + "vue-router": "^4.2.0", + "pinia": "^2.1.0", + "axios": "^1.6.0", + "element-plus": "^2.5.0", + "@element-plus/icons-vue": "^2.3.0", + "dayjs": "^1.11.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.0", + "vite": "^5.0.0", + "sass": "^1.70.0" + } +} diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/App.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/App.vue new file mode 100644 index 0000000..02e6d3e --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/App.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/api/api.js b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/api/api.js new file mode 100644 index 0000000..1eae067 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/api/api.js @@ -0,0 +1,154 @@ +import axios from 'axios' + +const api = axios.create({ + baseURL: '', + timeout: 30000, + headers: { + 'Content-Type': 'application/json' + } +}) + +// 响应拦截器 - 统一处理 +api.interceptors.response.use( + (response) => { + const data = response.data + if (data.code !== 200) { + return Promise.reject(new Error(data.msg || '请求失败')) + } + return data + }, + (error) => { + return Promise.reject(error) + } +) + +// 招聘者管理 API +export const recruiterApi = { + // 获取平台来源列表 + getSources: () => api.get('/api/recruiters/sources'), + + // 获取招聘者列表 + getList: (params = {}) => api.get('/api/recruiters', { params }), + + // 获取招聘者详情 + getDetail: (id) => api.get(`/api/recruiters/${id}`), + + // 创建招聘者 + create: (data) => api.post('/api/recruiters', data), + + // 自动注册 + register: (data) => api.post('/api/recruiters/register', data), + + // 更新招聘者 + update: (id, data) => api.put(`/api/recruiters/${id}`, data), + + // 删除招聘者 + delete: (id) => api.delete(`/api/recruiters/${id}`), + + // 启用招聘者 + activate: (id) => api.post(`/api/recruiters/${id}/activate`), + + // 停用招聘者 + deactivate: (id) => api.post(`/api/recruiters/${id}/deactivate`), + + // 同步招聘者 + sync: (id) => api.post(`/api/recruiters/${id}/sync`) +} + +// 职位管理 API +export const jobApi = { + // 获取职位列表 + getList: (params = {}) => api.get('/api/jobs', { params }), + + // 筛选职位 + filter: (data) => api.post('/api/jobs/filter', data), + + // 获取职位详情 + getDetail: (id) => api.get(`/api/jobs/${id}`), + + // 创建职位 + create: (data) => api.post('/api/jobs', data), + + // 更新职位 + update: (id, data) => api.put(`/api/jobs/${id}`, data), + + // 删除职位 + delete: (id) => api.delete(`/api/jobs/${id}`), + + // 关联评价方案 + bindSchema: (id, schemaId) => api.post(`/api/jobs/${id}/bind-schema`, { evaluation_schema_id: schemaId }), + + // 获取职位关联的评价方案 + getSchema: (id) => api.get(`/api/jobs/${id}/schema`), + + // 获取评价方案列表 + getSchemaList: (params = {}) => api.get('/api/jobs/schemas/list', { params }) +} + +// 候选人管理 API +export const candidateApi = { + // 获取筛选通过的候选人 + getFiltered: (params = {}) => api.get('/candidates/filtered', { params }), + + // 筛选候选人 + filter: (data) => api.post('/candidates/filter', data), + + // 获取候选人详情 + getDetail: (id) => api.get(`/candidates/${id}`), + + // 标记候选人筛选状态 + markFiltered: (data) => api.post('/candidates/mark-filtered', data), + + // 更新候选人评分 + updateScore: (data) => api.post('/candidates/update-score', data), + + // 根据评分范围查询 + getByScoreRange: (params) => api.get('/candidates/by-score-range', { params }) +} + +// 定时任务管理 API +export const schedulerApi = { + // 获取任务列表 + getJobs: () => api.get('/api/scheduler/jobs'), + + // 获取任务状态列表 + getJobsStatus: () => api.get('/api/scheduler/jobs/status'), + + // 获取单个任务状态 + getJobStatus: (id) => api.get(`/api/scheduler/jobs/${id}/status`), + + // 立即执行任务 + runJob: (id) => api.post(`/api/scheduler/jobs/${id}/run`), + + // 暂停任务 + pauseJob: (id) => api.post(`/api/scheduler/jobs/${id}/pause`), + + // 恢复任务 + resumeJob: (id) => api.post(`/api/scheduler/jobs/${id}/resume`), + + // 更新任务配置 + updateConfig: (id, data) => api.put(`/api/scheduler/jobs/${id}/config`, data), + + // 获取调度器状态 + getStatus: () => api.get('/api/scheduler/status'), + + // 启动调度器 + start: () => api.post('/api/scheduler/start'), + + // 停止调度器 + stop: () => api.post('/api/scheduler/stop') +} + +// 系统 API +export const systemApi = { + // 获取首页信息 + getHome: () => api.get('/'), + + // 健康检查 + health: () => api.get('/health'), + + // 获取API状态 + getStatus: () => api.get('/api/status') +} + +export default api diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/components/Layout.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/components/Layout.vue new file mode 100644 index 0000000..2f8cff7 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/components/Layout.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/main.js b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/main.js new file mode 100644 index 0000000..9e3a977 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/main.js @@ -0,0 +1,22 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import ElementPlus from 'element-plus' +import * as ElementPlusIconsVue from '@element-plus/icons-vue' +import 'element-plus/dist/index.css' +import zhCn from 'element-plus/dist/locale/zh-cn.mjs' + +import App from './App.vue' +import router from './router' + +const app = createApp(App) + +// 注册所有图标 +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} + +app.use(createPinia()) +app.use(router) +app.use(ElementPlus, { locale: zhCn }) + +app.mount('#app') diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/router/index.js b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/router/index.js new file mode 100644 index 0000000..6323a7f --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/router/index.js @@ -0,0 +1,49 @@ +import { createRouter, createWebHistory } from 'vue-router' +import Layout from '@/components/Layout.vue' + +const routes = [ + { + path: '/', + component: Layout, + redirect: '/dashboard', + children: [ + { + path: 'dashboard', + name: 'Dashboard', + component: () => import('@/views/Dashboard.vue'), + meta: { title: '首页', icon: 'HomeFilled' } + }, + { + path: 'recruiters', + name: 'Recruiters', + component: () => import('@/views/Recruiters.vue'), + meta: { title: '招聘者管理', icon: 'UserFilled' } + }, + { + path: 'jobs', + name: 'Jobs', + component: () => import('@/views/Jobs.vue'), + meta: { title: '职位管理', icon: 'Briefcase' } + }, + { + path: 'candidates', + name: 'Candidates', + component: () => import('@/views/Candidates.vue'), + meta: { title: '候选人管理', icon: 'Avatar' } + }, + { + path: 'scheduler', + name: 'Scheduler', + component: () => import('@/views/Scheduler.vue'), + meta: { title: '定时任务', icon: 'Clock' } + } + ] + } +] + +const router = createRouter({ + history: createWebHistory(), + routes +}) + +export default router diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Candidates.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Candidates.vue new file mode 100644 index 0000000..b817bfb --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Candidates.vue @@ -0,0 +1,364 @@ + + + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Dashboard.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Dashboard.vue new file mode 100644 index 0000000..3b500be --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Dashboard.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Jobs.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Jobs.vue new file mode 100644 index 0000000..23cbfff --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Jobs.vue @@ -0,0 +1,478 @@ + + + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Recruiters.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Recruiters.vue new file mode 100644 index 0000000..0bb225e --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Recruiters.vue @@ -0,0 +1,415 @@ + + + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Scheduler.vue b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Scheduler.vue new file mode 100644 index 0000000..a88d5a5 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/src/views/Scheduler.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/vite.config.js b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/vite.config.js new file mode 100644 index 0000000..165f3f3 --- /dev/null +++ b/src/main/web/cn.yinlihupo/ylhp_hr_2_0_fronted/vite.config.js @@ -0,0 +1,25 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import { resolve } from 'path' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': resolve(__dirname, 'src') + } + }, + server: { + port: 3000, + proxy: { + '/api': { + target: 'http://localhost:8000', + changeOrigin: true + }, + '/candidates': { + target: 'http://localhost:8000', + changeOrigin: true + } + } + } +})