提交 f3b003fe authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 dae610b5
......@@ -29,3 +29,7 @@ export function uploadFile(data: Record<string, any>) {
})
.then(() => data)
}
// 获取当前登录的校友信息
export function getAlumniUserInfo() {
return httpRequest.get('/api/hr/api/v1/alumni-talent/login-user-info')
}
......@@ -140,7 +140,7 @@ defineExpose({ refetch, tableRef })
v-bind="item"
clearable
@change="search"
style="width: 200px"
style="width: 250px"
v-if="item.type === 'input'"
/>
<!-- select -->
......@@ -149,7 +149,7 @@ defineExpose({ refetch, tableRef })
v-bind="item"
clearable
@change="search"
style="width: 200px"
style="width: 250px"
v-if="item.type === 'select'"
>
<el-option
......
......@@ -2,6 +2,10 @@
import { ElMessage } from 'element-plus'
// import Total from '../components/Total.vue'
import Card from '../components/Card.vue'
import { useUserStore } from '@/stores/user'
const user = useUserStore()
const rows: Record<string, any>[] = [
[
{
......@@ -172,7 +176,17 @@ const rows: Record<string, any>[] = [
icon: 'https://webapp-pub.ezijing.com/project/saas/icon_7_3.png',
hoverIcon: 'https://webapp-pub.ezijing.com/project/saas/icon_7_3_hover.png',
title: '校友人才',
href: '/hr/alumni'
onClick() {
if (!user.isLogin) {
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
return
}
if (user.projects.length === 0) {
ElMessage({ message: '您尚未绑定紫荆项目,无法查看校友信息' })
} else {
window.open('/hr/alumni')
}
}
},
{
className: 'is-blue',
......
<script setup lang="ts">
import { useArea } from '@/composables/useArea'
import { sex, projectPrefix, industryCategory, industryCategoryList } from '@/utils/dictionary'
import { getAlumniList, getAlumniUserInfo } from '../api'
import { getAlumniList } from '../api'
import type { AlumniType } from '../types'
const loaded = ref(false)
const projects = ref()
getAlumniUserInfo()
.then(res => {
projects.value = res.data.projects
})
.finally(() => {
loaded.value = true
})
import { useUserStore } from '@/stores/user'
const router = useRouter()
const user = useUserStore()
const appList = ref()
......@@ -27,7 +23,7 @@ const listOptions = {
industry: '',
province: '',
city: '',
project_prefix_arr: projects.value
project_prefix_arr: user.projects
},
beforeRequest(params: any, isReset: boolean) {
if (isReset) {
......@@ -36,7 +32,7 @@ const listOptions = {
}
params.province = provinceValue.value
params.city = cityValue.value
params.project_prefix_arr = projects.value
params.project_prefix_arr = user.projects
return params
}
},
......@@ -85,20 +81,33 @@ function handleUpdateList() {
appList.value?.refetch()
})
}
onMounted(() => {
if (!user.projects.length) {
router.replace('/')
}
})
</script>
<template>
<AppList v-bind="listOptions" ref="appList" v-if="loaded">
<AppList v-bind="listOptions" ref="appList">
<template #table-actions="{ row }">
<router-link :to="`/hr/alumni/view/${row.id}`" target="_blank" style="color: #399ee8">查看</router-link>
</template>
<template #filter-province>
<el-select filterable clearable v-model="provinceValue" @change="handleUpdateList">
<el-select filterable clearable v-model="provinceValue" @change="handleUpdateList" style="width: 250px">
<el-option v-for="item in provinceList" :value="item.label" :key="item.code"></el-option>
</el-select>
</template>
<template #filter-city>
<el-select filterable clearable v-model="cityValue" @change="handleUpdateList" no-data-text="请先选择省份">
<el-select
filterable
clearable
v-model="cityValue"
@change="handleUpdateList"
no-data-text="请先选择省份"
style="width: 250px"
>
<el-option v-for="item in cityList" :value="item.label" :key="item.code"></el-option>
</el-select>
</template>
......@@ -111,7 +120,7 @@ function handleUpdateList() {
background: #f8f8f8;
border-radius: 20px;
.el-form-item__label {
width: 78px;
width: 88px;
}
}
</style>
......@@ -52,32 +52,55 @@ onMounted(() => {
<dd></dd>
</dl> -->
<dl>
<dt>姓名</dt>
<dd>{{ data.username }}</dd>
<dt><img src="@/assets/images/icon_01.png" /></dt>
<dd>
<h6>姓名</h6>
<p>{{ data.username }}</p>
</dd>
</dl>
<dl>
<dt>所在项目</dt>
<dd>{{ projectName }}</dd>
<dt><img src="@/assets/images/icon_02.png" /></dt>
<dd>
<h6>所在项目</h6>
<p>{{ projectName }}</p>
</dd>
</dl>
<dl>
<dt>所在班级</dt>
<dd>{{ classNames }}</dd>
<dt><img src="@/assets/images/icon_03.png" /></dt>
<dd>
<h6>所在班级</h6>
<p>{{ classNames }}</p>
</dd>
</dl>
<dl>
<dt>省份</dt>
<dd>{{ data.province }}</dd>
<dt><img src="@/assets/images/icon_04.png" /></dt>
<dd>
<h6>省份</h6>
<p>{{ data.province }}</p>
</dd>
</dl>
<dl>
<dt>城市</dt>
<dd>{{ data.city }}</dd>
<dt><img src="@/assets/images/icon_05.png" /></dt>
<dd>
<h6>城市</h6>
<p>{{ data.city }}</p>
</dd>
</dl>
<dl>
<dt>所在行业</dt>
<dd>{{ industryName }}</dd>
<dt><img src="@/assets/images/icon_06.png" /></dt>
<dd>
<h6>所在行业</h6>
<p>{{ industryName }}</p>
</dd>
</dl>
<dl>
<dt>工作单位</dt>
<dd>{{ data.workplace }}</dd>
<dl style="grid-column: 3/5">
<dt><img src="@/assets/images/icon_07.png" /></dt>
<dd>
<h6>工作单位</h6>
<p>
{{ data.workplace }}
</p>
</dd>
</dl>
</div>
</AppCard>
......@@ -91,26 +114,37 @@ onMounted(() => {
.alumni-info {
padding: 24px;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: 178px 268px 1fr 280px;
row-gap: 50px;
dl {
padding: 10px;
margin: 10px;
text-align: center;
min-height: 38px;
display: flex;
padding-left: 76px;
border-left: 1px dashed #c9c9c9;
}
dl:nth-child(5n + 1) {
dl:nth-child(4n + 1) {
padding-left: 0;
border-left: none;
}
dt {
font-size: 14px;
font-weight: 400;
color: #666666;
width: 40px;
img {
width: 100%;
}
}
dd {
font-size: 18px;
font-weight: 400;
color: #333333;
margin-left: 10px;
flex: 1;
overflow: hidden;
h6 {
font-size: 14px;
font-weight: 400;
color: #666;
}
p {
font-size: 18px;
font-weight: 400;
color: #333;
}
}
}
.company-info {
......
......@@ -6,6 +6,7 @@ export const routes: Array<RouteRecordRaw> = [
path: '/hr/company',
component: AppLayout,
children: [
{ path: '', redirect: '/hr/company/create' },
{
path: 'create',
component: () => import('./views/Update.vue')
......
......@@ -65,7 +65,7 @@ onMounted(() => {
</script>
<template>
<AppContainer class="company-register">
<div class="company-register">
<h1 class="company-register__title">企业信息注册</h1>
<p class="company-register__tips">请完成企业信息认证,完成后即可发布职位</p>
<AppCard>
......@@ -113,7 +113,7 @@ onMounted(() => {
</el-row>
</el-form>
</AppCard>
</AppContainer>
</div>
</template>
<style lang="scss" scoped>
......
<script setup lang="ts"></script>
<template>
<AppCard class="company-info">
<h1>企业简介<span>Company Profile</span></h1>
<p class="tips">暂未注册企业</p>
</AppCard>
</template>
<style lang="scss">
.company-info {
padding: 44px;
margin-top: 20px;
h1 {
font-size: 32px;
font-weight: bold;
line-height: 1;
color: #141414;
padding-bottom: 25px;
border-bottom: 1px solid #ddd;
span {
margin-left: 6px;
font-size: 26px;
font-family: Lato;
font-weight: 400;
line-height: 32px;
color: #666666;
}
}
.tips {
padding: 100px 0;
font-size: 26px;
font-family: Lato;
font-weight: 400;
line-height: 32px;
color: #666666;
text-align: center;
}
}
</style>
import httpRequest from '@/utils/axios'
// 获取校友列表
export function getAlumniList(params: {
project_prefix_arr: []
workplace: string
industry: string
province: string
city: string
}) {
return httpRequest.get('/api/hr/api/v1/alumni-talents', { params })
}
// 获取校友详情
export function getAlumniDetail(params: { id: string }) {
return httpRequest.get(`/api/hr/api/v1/alumni-talent/${params.id}`, { params })
}
// 获取当前登录的校友信息
export function getAlumniUserInfo() {
return httpRequest.get('/api/hr/api/v1/alumni-talent/login-user-info')
}
......@@ -7,9 +7,9 @@ const listOptions = {
remote: {},
filters: [
{ type: 'input', label: '企业名称', prop: 'name', placeholder: '请输入' },
{ type: 'select', label: '岗位类型', prop: 'type', options: jobTypeList },
{ type: 'select', label: '工作地点', prop: 'work_locations' },
{ type: 'select', label: '学历要求', prop: 'education', options: educationList },
{ type: 'select', label: '工作地点', prop: 'work_locations' },
{ type: 'select', label: '岗位类型', prop: 'type', options: jobTypeList },
{ type: 'input', label: '岗位名称', prop: 'name', placeholder: '请输入' }
],
columns: [
......@@ -25,26 +25,49 @@ const listOptions = {
],
data: [
{ id: '1', name: '企业名称', education: 1, type: 1, salary_min: 10000, salary_max: 20000, desc: '描述' },
{ id: '2', name: '企业名称', education: 1, type: 1, salary_min: 10000, salary_max: 20000, desc: '描述' }
{ id: '2', name: '企业名称', education: 1, type: 1, salary_min: 10000, salary_max: 20000, desc: '描述' },
{ id: '3', name: '企业名称', education: 1, type: 1, salary_min: 10000, salary_max: 20000, desc: '描述' },
{ id: '4', name: '企业名称', education: 1, type: 1, salary_min: 10000, salary_max: 20000, desc: '描述' },
{ id: '5', name: '企业名称', education: 1, type: 1, salary_min: 10000, salary_max: 20000, desc: '描述' }
]
}
</script>
<template>
<AppContainer>
<AppList v-bind="listOptions" ref="appList">
<template #table-actions="{ row }">
<router-link :to="`/hr/posts/job/view/${row.id}`" target="_blank">
<el-button link>查看</el-button>
</router-link>
<el-button link>启用</el-button>
<el-button link>禁用</el-button>
<router-link :to="`/hr/posts/job/update/${row.id}`">
<el-button link>编辑</el-button>
</router-link>
</template>
</AppList>
</AppContainer>
<AppList v-bind="listOptions" ref="appList">
<template #body="{ data }">
<div class="job-list">
<div class="job-item" v-for="item in data" :key="item.id">
<router-link :to="`/hr/job/view/${item.id}`" target="_blank" class="job-item__inner">
<div class="job-item-hd">
<h3>{{ item.name }}</h3>
<p>{{ item.salary_min }}-{{ item.salary_max }}</p>
</div>
<div class="job-item-bd">
<p>{{ item.province }}-{{ item.city }}</p>
<p>{{ item.education }}</p>
</div>
<div class="job-item-ft">
<p>
<router-link :to="`/hr/company/view/${item.id}`" target="_blank">{{ item.name }}</router-link>
</p>
<p>{{ item.type }}</p>
</div>
</router-link>
</div>
</div>
</template>
<template #table-actions="{ row }">
<router-link :to="`/hr/posts/job/view/${row.id}`" target="_blank">
<el-button link>查看</el-button>
</router-link>
<el-button link>启用</el-button>
<el-button link>禁用</el-button>
<router-link :to="`/hr/posts/job/update/${row.id}`">
<el-button link>编辑</el-button>
</router-link>
</template>
</AppList>
</template>
<style lang="scss" scoped>
......@@ -52,5 +75,68 @@ const listOptions = {
padding: 30px 30px 10px;
background: #fff;
border-radius: 20px;
.el-form-item__label {
width: 98px;
}
.filter-buttons {
width: 348px;
.el-form-item__content {
justify-content: flex-end;
}
}
}
.job-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
row-gap: 20px;
column-gap: 20px;
}
.job-item {
background-color: #fff;
border-radius: 20px;
overflow: hidden;
}
.job-item__inner {
display: flex;
flex-direction: column;
height: 146px;
}
.job-item-hd {
display: flex;
justify-content: space-between;
padding: 20px 20px 16px;
h3 {
flex: 1;
font-size: 18px;
line-height: 1;
font-weight: 500;
color: #333333;
}
p {
font-size: 18px;
line-height: 1;
font-weight: 500;
color: #f26a5d;
white-space: nowrap;
}
}
.job-item-bd {
flex: 1;
display: flex;
justify-content: space-between;
padding: 0 20px;
font-size: 12px;
font-weight: 400;
line-height: 32px;
color: #7a7a7a;
}
.job-item-ft {
display: flex;
justify-content: space-between;
padding: 0 20px;
height: 48px;
line-height: 48px;
background: linear-gradient(92deg, #fdf8fa 0%, #fffbf7 100%);
}
</style>
<script setup lang="ts">
import AppCard from '../../../../components/base/AppCard.vue'
</script>
<template>
<AppCard>
<div class="job-info"></div>
<h2>职位描述</h2>
</AppCard>
</template>
<style lang="scss">
.job-info {
padding: 26px;
background: #f8f8f8;
border-radius: 20px;
}
</style>
......@@ -6,6 +6,7 @@ export const routes: Array<RouteRecordRaw> = [
path: '/hr/posts',
component: HRLayout,
children: [
{ path: '', redirect: '/hr/posts/job' },
{ path: 'job', component: () => import('./views/Job.vue') },
{ path: 'job/create', component: () => import('./views/JobUpdate.vue') },
{ path: 'job/update/:id', component: () => import('./views/JobUpdate.vue') },
......
......@@ -6,9 +6,18 @@ const router = createRouter({
routes: [{ path: '/:pathMatch(.*)*', redirect: '/' }]
})
router.beforeEach((to, from, next) => {
router.beforeEach(async (to, from, next) => {
const user = useUserStore()
user.getUser()
const whiteList = ['/', '/index']
try {
await user.getUser()
} catch (e) {
console.error(e)
}
if (!user.isLogin && !whiteList.includes(to.path)) {
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
return
}
next()
})
......
import { defineStore } from 'pinia'
import { getUser, logout } from '@/api/base'
import { getUser, getAlumniUserInfo, logout } from '@/api/base'
import type { UserState } from '@/types'
interface State {
user: UserState | null
hasCompany: boolean
projects: string[]
}
export const useUserStore = defineStore({
id: 'user',
state: () => {
return {
user: null as UserState | null
}
},
state: (): State => ({
user: null,
hasCompany: false,
projects: []
}),
getters: {
isLogin: state => !!state.user,
userName: ({ user }) => {
......@@ -18,15 +23,18 @@ export const useUserStore = defineStore({
}
},
actions: {
getUser() {
return getUser().then(res => {
this.user = res.data
})
async getUser() {
const res = await getUser()
this.user = res.data
if (this.isLogin) {
const { data: alumniUser } = await getAlumniUserInfo()
this.hasCompany = alumniUser.is_registered_company
this.projects = alumniUser.projects
}
},
logout() {
return logout().then(() => {
this.user = null
})
async logout() {
await logout()
this.user = null
}
}
})
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论