Soleilw преди 1 година
родител
ревизия
82ba4c5f81

+ 0
- 542
dist/assets/index-04ZkBbBm.js
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 0
- 1
dist/assets/index-_REgwLfQ.css
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 542
- 0
dist/assets/index-nrYvv5ad.js
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 1
- 0
dist/assets/index-tVJBwrDz.css
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 14
- 14
dist/index.html Целия файл

@@ -1,14 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
<script type="module" crossorigin src="/assets/index-04ZkBbBm.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-_REgwLfQ.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
<script type="module" crossorigin src="/assets/index-nrYvv5ad.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-tVJBwrDz.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

+ 5
- 4
src/apis/models/index.ts Целия файл

@@ -10,15 +10,16 @@ export const PostCompanyRegister = postModel(url.CompanyRegister);
export const GetCaptcha = getModel(url.Captcha);
export const PostSmsSend = postModel(url.SmsSend);
export const PostJobseekerSmsLogin = postModel(url.JobseekerSmsLogin);

export const PostCustomerVerify = postModel(url.CustomerVerify);
export const PostJobseekerEditPwd = postModel(url.JobseekerEditPwd);

// 招聘会
export const PostRecruitmentBookcompany = getModel(url.RecruitmentBookcompany);// 获取招聘会参与的企业
export const PostRecruitmentList = getModel(url.RecruitmentList);// 招聘会列表

// 求职者管理中心
export const PostViewhistoryList = getModel(url.ViewhistoryList);// 获取简历被查看记录
export const PostInterviewList = getModel(url.InterviewList); // 获取应聘记录列表
export const GetViewHistoryList = getModel(url.ViewHistoryList);
export const GetInterviewList = getModel(url.InterviewList); // 获取应聘记录列表

// 企业管理中心
export const GetCompanyRecommentResume = getModel(url.CompanyRecommentResume); // 推荐简历
@@ -124,7 +125,7 @@ export const GetRecruitmentbookDetail = getModel(url.RecruitmentbookDetail); //
// 列表
export const PostJobseekerList = postModel(url.JobseekerList);
export const GetJobseekerDetail = getModel(url.JobseekerDetail);
export const GetViewhistoryList = getModel(url.ViewhistoryList);

export const PostPersonInterviewViewStatus = postModel(url.PersonInterviewViewStatus);
export const GetPersonInterviewList = getModel(url.PersonInterviewList);

+ 4
- 4
src/apis/types/url.d.ts Целия файл

@@ -8,6 +8,8 @@ declare namespace urlType {
Captcha : String,
SmsSend : String,
JobseekerSmsLogin : String,
CustomerVerify : String,
JobseekerEditPwd : String,

// 招聘会
RecruitmentBookcompany : String,
@@ -102,15 +104,13 @@ declare namespace urlType {
RecruitmentbookList : String,
RecruitmentbookDetail : String,
CompanyProbationList: String,
// 知名/推荐企业
CompanyFamousList: String,

// 简历
// 列表
'JobseekerList' : String, // 查看
'JobseekerDetail' : String, // 详情
ViewhistoryList: String, // 详情
ViewHistoryList: String, // 详情
PersonInterviewList: String, // 面试邀请记录
PersonInterviewViewStatus: String, // 是否参加面试
PersonInterviewDel: String, // 删除面试邀请

+ 5
- 5
src/apis/url.ts Целия файл

@@ -11,6 +11,9 @@ export const url : urlType.url = {
Captcha: common + '/captcha', // 获取验证码
SmsSend: common + '/sms/send', // 短信验证码
JobseekerSmsLogin: web + '/jobseeker/smslogin', // 个人登录
CustomerVerify: web + '/customer/verify', // 转换为HR
JobseekerEditPwd: web + '/jobseek/edit_pwd', // 修改密码
// 招聘会
@@ -104,10 +107,7 @@ export const url : urlType.url = {
RecruitmentbookList: web + '/recruitmentbook/list', // 列表
RecruitmentbookDetail: web + '/recruitmentbook/detail', // 详情
// 见习基地
CompanyProbationList: web + '/company/probation_list', // 列表
// 知名/推荐企业
CompanyFamousList: web + '/company/famous_list', // 详情

// 反馈
FeedbackAdd: common + '/feedback/add', // 添加
@@ -119,7 +119,7 @@ export const url : urlType.url = {
// 简历
JobseekerList: web + '/jobseeker/list', // 获取简历完整资料列表
JobseekerDetail: web + '/jobseeker/detail', // 获取简历完整资料
ViewhistoryList: web + '/viewhistory/list', // 简历被查看次数
ViewHistoryList: web + '/viewhistory/list', // 简历被查看次数
PersonInterviewList: web + '/person/interview_list', // 面试邀请记录
PersonInterviewViewStatus: web + '/person/interview_view_status', // 是否参加面试
PersonInterviewDel: web + '/person/interview_del', // 删除面试邀请

+ 1
- 1
src/components/job/meet/booking/index.vue Целия файл

@@ -15,7 +15,7 @@
</a-page-header>
</template>
<template v-else>
<a-list item-layout="horizontal" :data-source="recruitmentList">
<a-list item-layout="horizontal" :data-source="recruitmentList" style="cursor: pointer;">
<template #renderItem="{ item }">
<a-list-item @click="toDetail(item)">
<a-list-item-meta>

+ 142
- 0
src/components/jobseeker/invite/apply/index.vue Целия файл

@@ -0,0 +1,142 @@
<template>
<job-search @searchData="searchData" @clearData="clearData" :search_params="commomParams.search"></job-search>
<template v-if="!jobList || jobList.length == 0">
<a-empty style="height: 100vh;">
<template #description>
无职位信息
</template>
</a-empty>
</template>
<template v-else>
<a-row :gutter="[10,20]">
<a-col span="12" v-for="(item, index) in jobList">
<a-flex vertical style="width: 100%;background-color: #fff;border-radius: 10px;padding: 20px;">
<a-card :title="item.job_name">
<template #extra>
<a-space>
<a-button @click="rejectInterview(item.id)">拒绝面试</a-button>
<a-button @click="receiveInterview(item.id)" class="main-color">接受面试</a-button>
</a-space>
</template>
<div>面试时间:{{item.invite_date}}</div>
<div>面试结果:{{item.employ_status_txt}}</div>
<div>面试企业:{{item.company_name}}</div>
</a-card>
</a-flex>
</a-col>
<a-col span="24">
<a-flex justify="center">
<a-space>
<a-pagination hideOnSinglePage :total="commomParams.page.total" @change="getPage" />
</a-space>
</a-flex>
</a-col>
</a-row>
</template>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, defineEmits, createVNode } from 'vue';
import { GetInterviewList } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal } = useCommon();
const emit = defineEmits();
let loading = ref<Boolean>(true);
let jobList = ref([]);
let total = ref<Number>(0)


const searchData = (data : object) => {
commomParams.value.search = data
getData();
}

const clearData = (data : object) => {
if (data) {
commomParams.value.search = data
} else {
commomParams.value.search = {
page: 1,
pagesize: 12,
sort: 'id',
sortby: 'asc',
keyword: ''
}
}
getData();
}


const getPage = (page, pageSize) => {
commomParams.value.search.page = page;
commomParams.value.search.pagesize = pageSize;
getData();
}
const getData = async () => {
try {
loading.value = true;
let res = await GetInterviewList(commomParams.value.search);
loading.value = false;
jobList.value = res.data.interviews;
commomParams.value.page = {
current: commomParams.value.search.page,
pageSize: commomParams.value.search.pagesize,
total: res.data.total,
pageSizeOptions: ['10', '20', '30', '40'],
hideOnSinglePage: false,
showSizeChanger: true
};
} catch {
loading.value = false;
}
}

// const toDetail = (job_id : Number, company_id : Number) => {
// sessionStorage.setItem('job_id', job_id)
// sessionStorage.setItem('tab_key', 2)
// sessionStorage.setItem('pubilc_id', company_id)
// sessionStorage.setItem('mode', 'detail')
// emit('detail')
// }

onMounted(() => {
getData();
})
</script>

<style lang="less" scoped>
.job-box {
display: flex;
flex-direction: column;
justify-content: space-around;
// align-items: center;
width: 100%;

.job-title {
padding: 20px;
background-color: #ffffff;

.aaaa {
display: flex;
justify-content: space-between;
}
}

.job-company {
padding: 20px;
background-color: #cccccc;

.aaaa {
display: flex;
justify-content: space-between;
}
}

}

.mt10 {
margin-bottom: 10px;
}
</style>

+ 8
- 0
src/components/jobseeker/invite/collect/index.vue Целия файл

@@ -0,0 +1,8 @@
<template>
</template>

<script>
</script>

<style>
</style>

+ 177
- 0
src/components/jobseeker/invite/interview/index.vue Целия файл

@@ -0,0 +1,177 @@
<template>
<job-search @searchData="searchData" @clearData="clearData" :search_params="commomParams.search"></job-search>
<template v-if="!jobList || jobList.length == 0">
<a-empty style="height: 100vh;">
<template #description>
无职位信息
</template>
</a-empty>
</template>
<template v-else>
<a-row :gutter="[10,20]">
<a-col span="12" v-for="(item, index) in jobList">
<a-flex vertical style="width: 100%;background-color: #fff;border-radius: 10px;padding: 20px;">
<a-card :title="item.job_name">
<template #extra>
<a-space>
<a-button @click="rejectInterview(item.id)">拒绝面试</a-button>
<a-button @click="receiveInterview(item.id)" class="main-color">接受面试</a-button>
</a-space>
</template>
<div>面试时间:{{item.invite_date}}</div>
<div>面试结果:{{item.employ_status_txt}}</div>
<div>面试企业:{{item.company_name}}</div>
</a-card>
</a-flex>
</a-col>
<a-col span="24">
<a-flex justify="center">
<a-space>
<a-pagination hideOnSinglePage :total="commomParams.page.total" @change="getPage" />
</a-space>
</a-flex>
</a-col>
</a-row>
</template>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, defineEmits, createVNode } from 'vue';
import { GetPersonInterviewList, PostPersonInterviewViewStatus } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal } = useCommon();
const emit = defineEmits();
let loading = ref<Boolean>(true);
let jobList = ref([]);
let total = ref<Number>(0)


const searchData = (data : object) => {
commomParams.value.search = data
getData();
}

const clearData = (data : object) => {
if (data) {
commomParams.value.search = data
} else {
commomParams.value.search = {
page: 1,
pagesize: 12,
sort: 'id',
sortby: 'asc',
keyword: ''
}
}
getData();
}


const getPage = (page, pageSize) => {
commomParams.value.search.page = page;
commomParams.value.search.pagesize = pageSize;
getData();
}
const getData = async () => {
try {
loading.value = true;
let res = await GetPersonInterviewList(commomParams.value.search);
loading.value = false;
jobList.value = res.data.list;
commomParams.value.page = {
current: commomParams.value.search.page,
pageSize: commomParams.value.search.pagesize,
total: res.data.total,
pageSizeOptions: ['10', '20', '30', '40'],
hideOnSinglePage: false,
showSizeChanger: true
};
} catch {
loading.value = false;
}
}

// const toDetail = (job_id : Number, company_id : Number) => {
// sessionStorage.setItem('job_id', job_id)
// sessionStorage.setItem('tab_key', 2)
// sessionStorage.setItem('pubilc_id', company_id)
// sessionStorage.setItem('mode', 'detail')
// emit('detail')
// }

// 接受面试
const receiveInterview = (id) => {
Modal.confirm({
title: `是否要接受面试`,
centered: true,
icon: createVNode(ExclamationCircleOutlined),
onOk() {
PostPersonInterviewViewStatus({ id: id, view_status: 2 }).then(res => {
successToast('已接受,请按时参加面试')
getData();
})
},
onCancel() {

},
});
}

// 拒绝面试
const rejectInterview = (id, num) => {
Modal.confirm({
title: `是否要拒绝面试`,
centered: true,
icon: PostPersonInterviewViewStatus(ExclamationCircleOutlined),
onOk() {
PostPersonInterviewViewStatus({ id: id, view_status: 3 }).then(res => {
successToast('已拒绝')
getData();
})
},
onCancel() {

},
});
}

onMounted(() => {
getData();
})
</script>

<style lang="less" scoped>
.job-box {
display: flex;
flex-direction: column;
justify-content: space-around;
// align-items: center;
width: 100%;

.job-title {
padding: 20px;
background-color: #ffffff;

.aaaa {
display: flex;
justify-content: space-between;
}
}

.job-company {
padding: 20px;
background-color: #cccccc;

.aaaa {
display: flex;
justify-content: space-between;
}
}

}

.mt10 {
margin-bottom: 10px;
}
</style>

+ 142
- 0
src/components/jobseeker/invite/seeme/index.vue Целия файл

@@ -0,0 +1,142 @@
<template>
<job-search @searchData="searchData" @clearData="clearData" :search_params="commomParams.search"></job-search>
<template v-if="!jobList || jobList.length == 0">
<a-empty style="height: 100vh;">
<template #description>
暂时还没有数据
</template>
</a-empty>
</template>
<template v-else>
<a-row :gutter="[10,20]">
<a-col span="12" v-for="(item, index) in jobList">
<a-flex vertical style="width: 100%;background-color: #fff;border-radius: 10px;padding: 20px;">
<a-card :title="item.job_name">
<template #extra>
<a-space>
<a-button @click="rejectInterview(item.id)">拒绝面试</a-button>
<a-button @click="receiveInterview(item.id)" class="main-color">接受面试</a-button>
</a-space>
</template>
<div>面试时间:{{item.invite_date}}</div>
<div>面试结果:{{item.employ_status_txt}}</div>
<div>面试企业:{{item.company_name}}</div>
</a-card>
</a-flex>
</a-col>
<a-col span="24">
<a-flex justify="center">
<a-space>
<a-pagination hideOnSinglePage :total="commomParams.page.total" @change="getPage" />
</a-space>
</a-flex>
</a-col>
</a-row>
</template>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, defineEmits, createVNode } from 'vue';
import { GetViewHistoryList } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal } = useCommon();
const emit = defineEmits();
let loading = ref<Boolean>(true);
let jobList = ref([]);
let total = ref<Number>(0)


const searchData = (data : object) => {
commomParams.value.search = data
getData();
}

const clearData = (data : object) => {
if (data) {
commomParams.value.search = data
} else {
commomParams.value.search = {
page: 1,
pagesize: 12,
sort: 'id',
sortby: 'asc',
keyword: ''
}
}
getData();
}


const getPage = (page, pageSize) => {
commomParams.value.search.page = page;
commomParams.value.search.pagesize = pageSize;
getData();
}
const getData = async () => {
try {
loading.value = true;
let res = await GetViewHistoryList(commomParams.value.search);
loading.value = false;
jobList.value = res.data.viewhistorys;
commomParams.value.page = {
current: commomParams.value.search.page,
pageSize: commomParams.value.search.pagesize,
total: res.data.total,
pageSizeOptions: ['10', '20', '30', '40'],
hideOnSinglePage: false,
showSizeChanger: true
};
} catch {
loading.value = false;
}
}

// const toDetail = (job_id : Number, company_id : Number) => {
// sessionStorage.setItem('job_id', job_id)
// sessionStorage.setItem('tab_key', 2)
// sessionStorage.setItem('pubilc_id', company_id)
// sessionStorage.setItem('mode', 'detail')
// emit('detail')
// }

onMounted(() => {
getData();
})
</script>

<style lang="less" scoped>
.job-box {
display: flex;
flex-direction: column;
justify-content: space-around;
// align-items: center;
width: 100%;

.job-title {
padding: 20px;
background-color: #ffffff;

.aaaa {
display: flex;
justify-content: space-between;
}
}

.job-company {
padding: 20px;
background-color: #cccccc;

.aaaa {
display: flex;
justify-content: space-between;
}
}

}

.mt10 {
margin-bottom: 10px;
}
</style>

+ 58
- 28
src/components/layout/header/aHeader.vue Целия файл

@@ -3,8 +3,7 @@
<a-col span="18">
<a-row>
<a-col span="4">
<image-container
:imgObj="{src: '/images/logo.png',width: '153px',height:'50px'}"></image-container>
<image-container :imgObj="{src: '/images/logo.png',width: '153px',height:'50px'}"></image-container>
</a-col>
<a-col span="16" style="color: aliceblue;">
<a-top-menu></a-top-menu>
@@ -91,12 +90,12 @@
</a-menu-item>
<a-menu-item key="6">
<a-space :size="80">
<div>修改密码</div>
<div>成为招聘者</div>
</a-space>
</a-menu-item>
<a-menu-item key="7">
<a-space :size="80">
<div @click="quit">安全退出</div>
<div @click="quit">安全退出</div>
</a-space>
</a-menu-item>
</a-menu>
@@ -108,41 +107,52 @@
</a-dropdown>
</template>
</template>
<template v-else >
<div @click="toLogin" style="cursor: pointer;">
登录/注册
</div>
<template v-else>
<div @click="toLogin" style="cursor: pointer;">
登录/注册
</div>
</template>
</div>
</a-col>
</a-row>
</a-col>
</a-row>
<a-modal v-model:open="openHr" centered title="成为招聘者" @ok="hrOk">
<a-input v-model:value="form.code" placeholder="请输入验证码" size="large" />
</a-modal>
</template>
<script lang="ts" setup>
import { ref, onMounted, computed, defineProps, defineEmits } from 'vue';
import ATopMenu from '@/components/layout/menu/aMenu.vue';
import { PostCustomerVerify } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
import { store } from '@/store/index';
import { router } from '@/router/index';
const emit = defineEmits();

// 成为招聘者
let openHr = ref<Boolean>(false);
let form = ref({
code: ''
})

const token = computed(() => {
return store.state.token
})
const role = computed(() => {
return store.state.role
})
const pageType = computed(() => {
return store.state.pageType
})
const toLogin = () => {
router.push('/login')
}
const quit = () => {
store.commit('setShowLoginBox', {
showLoginBox: true
@@ -152,7 +162,7 @@
store.commit('permissions/SET_MENU', [])
router.push('/job/home')
}
const returnHome = () => {
store.commit('getPageType', {
pageType: ''
@@ -165,9 +175,9 @@
store.commit('permissions/SET_MENU', [])
router.push('/job/home')
}
const handleMenuClick = (val) => {
if(val.key == 3) {
if (val.key == 3) {
store.commit('getPageType', {
pageType: 'company'
})
@@ -176,7 +186,7 @@
store.commit('permissions/SET_MENU', [])
router.push('/manage/home')
}
if(val.key == 6) {
if (val.key == 6) {
store.commit('getPageType', {
pageType: 'company'
})
@@ -187,7 +197,7 @@
}
}
const personalMenuClick = (val) => {
if(val.key == 3) {
if (val.key == 3) {
store.commit('getPageType', {
pageType: 'personal'
})
@@ -196,7 +206,7 @@
store.commit('permissions/SET_MENU', [])
router.push('/jobseeker/home')
}
if(val.key == 4) {
if (val.key == 4) {
store.commit('getPageType', {
pageType: 'personal'
})
@@ -205,7 +215,7 @@
store.commit('permissions/SET_MENU', [])
router.push('/jobseeker/resume')
}
if(val.key == 5) {
if (val.key == 5) {
store.commit('getPageType', {
pageType: ''
})
@@ -217,8 +227,13 @@
store.commit('permissions/SET_MENU', [])
router.push('/personal')
}
if(val.key == 6) {
if (val.key == 6) {
debugger
openHr.value = true
form.value.code = ''
}

if (val.key == 7) {
store.commit('getPageType', {
pageType: 'personal'
})
@@ -228,8 +243,24 @@
router.push('/jobseeker/home')
}
}



const hrOk = () => {
if (!form.value.code) {
warnToast('请输入验证码')
return;
} else {
successToast('已经成为招聘者,请重新登录')
quit()
router.push('/login')
// PostCustomerVerify(form.value).then(res => {
// successToast('已经成为招聘者,请重新登录')
// quit()
// })
}

}
</script>

<style lang="less" scoped>
@@ -249,10 +280,9 @@
justify-content: flex-end;
color: #fff;
}
:deep(.ant-btn) {
margin-right: 20px !important;
}
</style>

+ 14
- 1
src/router/jobseekerDynamic.ts Целия файл

@@ -37,6 +37,8 @@ const JobseekerResumeRoute : AppRouteRecordRaw = {
},
};



// 职位搜索
const JobseekerSearchRoute : AppRouteRecordRaw = {
path: '/jobseeker/search',
@@ -48,6 +50,16 @@ const JobseekerSearchRoute : AppRouteRecordRaw = {
},
};

const JobseekerPasswordRoute : AppRouteRecordRaw = {
path: '/jobseeker/password',
name: 'JobseekerPassword',
component: routerList.JobseekerPassword,
meta: {
title: '修改密码',
icon: HomeOutlined
},
};




@@ -57,5 +69,6 @@ export const routesJobseekerModuleList : AppRouteModule[] = [
JobseekerHomeRoute,
JobseekerRecommendRoute,
JobseekerResumeRoute,
JobseekerSearchRoute
JobseekerSearchRoute,
JobseekerPasswordRoute
];

+ 3
- 1
src/router/routerList.ts Целия файл

@@ -33,6 +33,7 @@ import JobseekerHome from '@/views/jobseeker/home/index.vue';
import JobseekerRecommend from '@/views/jobseeker/recommend/index.vue';
import JobseekerResume from '@/views/jobseeker/resume/index.vue';
import JobseekerSearch from '@/views/jobseeker/search/index.vue';
import JobseekerPassword from '@/views/jobseeker/password/index.vue';

export const routerList = {
Home,
@@ -64,5 +65,6 @@ export const routerList = {
JobseekerHome,
JobseekerRecommend,
JobseekerResume,
JobseekerSearch
JobseekerSearch,
JobseekerPassword
}

+ 49
- 23
src/views/common/personal/index.vue Целия файл

@@ -2,7 +2,9 @@
<div v-if="mode== 'detail'">
<a-page-header>
<template #title>
<a-button @click="back" type="link"><ArrowLeftOutlined />前往更多求职</a-button>
<a-button @click="back" type="link">
<ArrowLeftOutlined />前往更多求职
</a-button>
</template>
<a-list item-layout="vertical">
<a-list-item>
@@ -52,6 +54,27 @@
<a-descriptions-item label="传真">{{companyDetail.fax}}</a-descriptions-item>
</a-descriptions>
</div>
<div style="margin: 20px 0; padding: 20px;background-color: #ffffff;">
<a-descriptions :column="7" title="企业相册" layout="vertical">
<a-descriptions-item label="联系地址"
span="2">{{companyDetail.detail_address}}</a-descriptions-item>
<a-descriptions-item label="联系人">{{companyDetail.contact}}</a-descriptions-item>
<a-descriptions-item label="联系手机">{{companyDetail.mobile}}</a-descriptions-item>
<a-descriptions-item label="联系电话">{{companyDetail.phone}}</a-descriptions-item>
<a-descriptions-item label="Email">{{companyDetail.email}}</a-descriptions-item>
<a-descriptions-item label="传真">{{companyDetail.fax}}</a-descriptions-item>
</a-descriptions>
</div>
<div style="margin: 20px 0; padding: 20px;background-color: #ffffff;">
<a-descriptions :column="1" title="地图位置" layout="vertical">
<a-descriptions-item span="1">
<div v-if="companyDetail.latitude && companyDetail.longitude" style="width: 100%;">
<v-map :lat="companyDetail.latitude" :lng="companyDetail.longitude"></v-map>
</div>
</a-descriptions-item>
</a-descriptions>
</div>

</a-tab-pane>
<a-tab-pane :key="2" tab="招聘职位" force-render>
<template v-if="!jobList || jobList.length == 0">
@@ -64,20 +87,22 @@
<template v-else>
<a-row :gutter="10">
<a-col span="6">
<a-card hoverable style="width: 100%">
<template #cover>
<job-card :list="jobList" @detail="toDetail"></job-card>
</template>
<template #actions>
<a-col span="24">
<a-pagination simple hideOnSinglePage v-model:current="current"
:total="total" @change="pageChange" />
</a-col>
</template>
</a-card>
<div style="height: calc(100vh - 100px); overflow: auto;background-color: #ffffff;">
<a-card hoverable style="width: 100%">
<template #cover>
<job-card :list="jobList" @detail="toDetail"></job-card>
</template>
<template #actions>
<a-col span="24">
<a-pagination simple hideOnSinglePage v-model:current="current"
:total="total" @change="pageChange" />
</a-col>
</template>
</a-card>
</div>
</a-col>
<a-col span="18">
<div v-if="job_id" style="padding: 20px;background-color: #ffffff;">
<div v-if="job_id" style="height: calc(100vh - 100px); overflow: auto;padding: 20px;background-color: #ffffff;">
<job-detail :id="job_id"></job-detail>
</div>
</a-col>
@@ -88,7 +113,7 @@
</a-page-header>
</div>
<div v-else>
<job-list @detail="showDetail"></job-list>
<job-list @detail="showDetail"></job-list>
<job-internship @detail="showDetail"></job-internship>
<!-- <job-detail></job-detail> -->
</div>
@@ -100,6 +125,7 @@
import JobCard from '@/components/job/card/index.vue'
import JobList from '@/components/job/list/index.vue'
import JobInternship from '@/components/job/internship/index.vue'
import vMap from '@/components/map/map-iframe.vue'
import { PostCompanyInfo, GetJobCompanyjobs } from '@/apis/models';
import { ArrowLeftOutlined } from '@ant-design/icons-vue';
import { router } from '@/router';
@@ -132,7 +158,7 @@
current.value = page
getJobCompanyjobs()
}
const back = (page) => {
sessionStorage.removeItem('pubilc_id')
sessionStorage.removeItem('mode')
@@ -140,7 +166,7 @@
sessionStorage.removeItem('job_id')
mode.value = sessionStorage.getItem('mode')
}
const showDetail = (page) => {
mode.value = sessionStorage.getItem('mode')
activeKey.value = sessionStorage.getItem('tab_key') ? Number(sessionStorage.getItem('tab_key')) : 1
@@ -148,13 +174,13 @@
pubilc_id.value = sessionStorage.getItem('pubilc_id') ? Number(sessionStorage.getItem('pubilc_id')) : pubilc_id.value;
if (sessionStorage.getItem('pubilc_id') != 0 || sessionStorage.getItem('id') != 0) {
PostCompanyInfo({ id: pubilc_id.value ? pubilc_id.value : sessionStorage.getItem('id') }).then(res => {
companyDetail.value = res.data
})
companyDetail.value = res.data
})
getJobCompanyjobs()
}
}

onMounted(() => {
if (mode.value == 'detail') {
@@ -162,8 +188,8 @@
pubilc_id.value = sessionStorage.getItem('pubilc_id') ? Number(sessionStorage.getItem('pubilc_id')) : pubilc_id.value;
if (sessionStorage.getItem('pubilc_id') != 0 || sessionStorage.getItem('id') != 0) {
PostCompanyInfo({ id: pubilc_id.value ? pubilc_id.value : sessionStorage.getItem('id') }).then(res => {
companyDetail.value = res.data
})
companyDetail.value = res.data
})
getJobCompanyjobs()
}
}
@@ -173,7 +199,7 @@
sessionStorage.removeItem('pubilc_id')
sessionStorage.removeItem('mode')
sessionStorage.removeItem('tab_key')
sessionStorage.removeItem('job_id')
sessionStorage.removeItem('job_id')
})
</script>


+ 62
- 72
src/views/jobseeker/home/index.vue Целия файл

@@ -8,7 +8,9 @@
<a-list-item-meta>
<template #title>
{{basic.seekername}}
<a-button type="link" class="main-color"><EditOutlined style="color: #4FBE70" />修改简历</a-button>
<a-button type="link" @click="toResume" class="main-color">
<EditOutlined style="color: #4FBE70" />修改简历
</a-button>
</template>
<template #description>
会员编号:{{basic.id}}
@@ -18,16 +20,35 @@
</template>
</a-list-item-meta>
<div style="margin-left: 108px;">
<a-descriptions :column="2">
<a-descriptions :column="3">
<a-descriptions-item
label="登录账号">{{basic.mobile ? basic.mobile : '未知'}}</a-descriptions-item>
<a-descriptions-item><a-button type="link" class="main-color"><FileSearchOutlined style="color: #4FBE70" />预览简历</a-button></a-descriptions-item>
<a-descriptions-item
label="QQ">{{basic.qq ? basic.qq : '未填写'}}</a-descriptions-item>
<a-descriptions-item><a-button type="link" class="main-color"><RedoOutlined style="color: #4FBE70" />预览简历</a-button></a-descriptions-item>
<a-descriptions-item
label="电子邮箱">{{basic.email ? basic.email : '未填写'}}</a-descriptions-item>
<a-descriptions-item label="简历被查看次数">{{seeLength}}次</a-descriptions-item>
<a-descriptions-item><a-button type="link" class="main-color">
<FileSearchOutlined style="color: #4FBE70" />预览简历
</a-button></a-descriptions-item>
<a-descriptions-item label="简历是否可见">
<a-switch></a-switch>
</a-descriptions-item>
<a-descriptions-item label="QQ">
{{basic.qq ? basic.qq : '未填写'}}
</a-descriptions-item>
<a-descriptions-item>
<a-button type="link" class="main-color">
<RedoOutlined style="color: #4FBE70" />预览简历
</a-button>
</a-descriptions-item>
<a-descriptions-item label="简历是否在家政可见">
<a-switch></a-switch>
</a-descriptions-item>
<a-descriptions-item label="电子邮箱">
{{basic.email ? basic.email : '未填写'}}
</a-descriptions-item>
<a-descriptions-item label="简历被查看次数">
{{seeLength}}次
</a-descriptions-item>
<a-descriptions-item label="是否接收面试邀请通知">
<a-switch></a-switch>
</a-descriptions-item>
</a-descriptions>
</div>
</a-list-item>
@@ -35,59 +56,20 @@
</div>
</a-col>
<a-col span="18">
<a-space align="cneter" direction="vertical">
<div style="width: 100%;font-size: 24px;">
推荐简历
</div>
<a-row :gutter="[20,20]">
<a-col span="12" v-for="(item, index) in jobList">
<div class="talent-box">
<a-list>
<a-list-item>
<template #actions>
<a-button>
<StarOutlined />
收藏
</a-button>
<a-button>
邀请面试
</a-button>
</template>
<a-list-item-meta>
<template #title>
{{item.seekername}}
</template>
<template #description>
<div>
{{item.gender}}
<a-divider type="vertical" />
{{item.education_text}}
<a-divider type="vertical" />
{{item.now_level1_text}}{{item.now_level2_text}}
</div>
<div style="margin-top: 10px; overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;">
<div v-html="item.introduction"></div>
</div>
</template>
<template #avatar>
<a-avatar :src="item.photo" :size="48" />
</template>
</a-list-item-meta>
</a-list-item>
</a-list>
</div>
</a-col>
<a-col span="24">
<a-flex justify="center">
<a-button size="large" type="primary">查看更多</a-button>
</a-flex>
</a-col>
</a-row>
</a-space>
<a-tabs v-model:activeKey="activeKey" @change="activeKeyChange">
<a-tab-pane :key="1" tab="面试记录">
<invite-interview></invite-interview>
</a-tab-pane>
<a-tab-pane :key="2" tab="投递记录" force-render>
<invite-apply></invite-apply>
</a-tab-pane>
<a-tab-pane :key="3" tab="谁看过我">
<invite-seeme></invite-seeme>
</a-tab-pane>
<a-tab-pane :key="4" tab="收藏的职位">
<invite-collect></invite-collect>
</a-tab-pane>
</a-tabs>
</a-col>
</a-row>
</div>
@@ -96,25 +78,33 @@

<script setup lang="ts">
import { ref, computed, onMounted, createVNode } from 'vue';
import JobTalents from '@/components/job/talents/index.vue'
import { GetJobseekerDetail, GetCompanyRecommentResume, GetViewhistoryList, GetPersonInterviewList } from '@/apis/models';
import { EditOutlined, FileSearchOutlined,RedoOutlined } from '@ant-design/icons-vue';
import InviteInterview from '@/components/jobseeker/invite/interview/index.vue'
import InviteApply from '@/components/jobseeker/invite/apply/index.vue'
import InviteSeeme from '@/components/jobseeker/invite/seeme/index.vue'
import InviteCollect from '@/components/jobseeker/invite/collect/index.vue'
import { GetJobseekerDetail, GetCompanyRecommentResume, GetViewHistoryList, GetPersonInterviewList } from '@/apis/models';
import { EditOutlined, FileSearchOutlined, RedoOutlined } from '@ant-design/icons-vue';
import { useCommon } from '@/hooks/useCommon';
let { commomParams, ExclamationCircleOutlined, Modal } = useCommon();
let { commomParams, ExclamationCircleOutlined, Modal, onMenu } = useCommon();
let jobList = ref<object[]>([])
let basic = ref<Object>({})
let seeLength = ref<Number>(0)

const toResume = () => {
debugger
onMenu('/jobseeker/resume')
}
onMounted(() => {
GetJobseekerDetail({ customer_id: sessionStorage.getItem('id') }).then(res => {
basic.value = res.data
})

GetViewhistoryList().then(res => {
GetViewHistoryList().then(res => {
seeLength.value = res.data.viewhistorys ? res.data.viewhistorys.length : 0
})
GetPersonInterviewList({status: 0}).then(res => {
if(res.data.list.length > 0) {
GetPersonInterviewList({ status: 0 }).then(res => {
if (res.data.list.length > 0) {
Modal.confirm({
title: `您有${res.data.list.length}条待查看面试邀请`,
centered: true,
@@ -122,10 +112,10 @@
okText: '前往查看',
cancelText: '关闭',
onOk() {
},
onCancel() {
},
});
}

+ 157
- 0
src/views/jobseeker/password/index.vue Целия файл

@@ -0,0 +1,157 @@
<template>
<div class="content-padding-inline" style="margin: 30px 0;">
<a-row :gutter="[20,20]" type="flex" justify="center">
<a-col span="18">
<a-card title="修改密码">
<a-form :model="createForm" layout="vertical">
<a-row gutter="20">
<a-col span="12">
<a-row gutter="20">
<a-col span="24">
<a-form-item label="手机号">
<a-input v-model:value="smsForm.mobile" placeholder="手机号" size="large" />
</a-form-item>
</a-col>
<a-col span="12">
<a-form-item label="验证码">
<a-input v-model:value="smsForm.captcha" placeholder="验证码" size="large" />
</a-form-item>
</a-col>
<a-col span="12">
<a-form-item label="图形验证码">
<image-container :imgObj="{src: codeImage,width: '100%',height: '40px', mode: 'fill'}"
@click="getCaptcha"></image-container>
</a-form-item>
</a-col>
<a-col span="18">
<a-form-item label="短信验证码">
<a-input v-model:value="createForm.sms_code" placeholder="短信验证码" size="large" />
</a-form-item>
</a-col>
<a-col span="6">
<a-form-item label="验证码">
<a-button type="primary" block size="large" @click="sendCode"
:disabled="state.disabled">
{{ state.codeTxt }}</a-button>
</a-form-item>
</a-col>
<a-col span="24">
<a-form-item label="确认密码" name="comform_password">
<a-input v-model:value="createForm.new_password" placeholder="请输入确认密码"
size="large" />
</a-form-item>
</a-col>
<a-col span="24">
<a-form-item label="">
<a-button type="primary" block @click="saveForm" size="large">保存</a-button>
</a-form-item>
</a-col>
</a-row>
</a-col>
</a-row>

</a-form>
</a-card>
</a-col>
</a-row>

</div>

</template>


<script setup lang="ts">
import { ref, onMounted, computed, onBeforeUnmount } from 'vue';
import { PostJobseekerEditPwd, PostSmsSend, GetCaptcha } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
let smsForm = ref<Object>({
mobile: "",
captcha: "",
capt_id: ""
})
let createForm = ref({
sms_code: '',
new_password: '',
})

let capt_id = ref<String>('')
let codeImage = ref<String>('')
interface State {
count : number;
sending : boolean;
disabled : boolean;
}
const state = ref<State>({
count: 60,
codeTxt: '获取验证码',
disabled: false,
});

let timer = ref<any>(null)
const sendCode = () => {
smsForm.value.capt_id = capt_id.value;
if (!smsForm.value.mobile) {
warnToast('请输入手机号')
return false;
}
if (!smsForm.value.captcha) {
warnToast('请输入图形验证码')
return false;
}
PostSmsSend(smsForm.value).then(res => {
successToast('发送验证码成功,验证码有效期为一分钟');
timer.value = setInterval(function () {
if (state.value.count > 1) {
state.value.count = state.value.count - 1;
state.value.codeTxt = '剩余' + (state.value.count - 1) + '秒';
state.value.disabled = true
} else {
clearInterval(timer.value);
state.value.count = 60;
state.value.codeTxt = '获取验证码';
state.value.disabled = false
};
}, 1000)
})
};



const getCaptcha = () => {
createForm.value.captcha = '';
GetCaptcha().then(res => {
capt_id.value = res.data.capt_id;
codeImage.value = res.data.img;
})
}


const saveForm = () => {
PostJobseekerEditPwd(createForm.value).then(res => {
successToast('修改成功')
resetForm()
})
}

const resetForm = () => {
createForm.value = {
sms_code: '',
new_password: '',
}
}



onMounted(() => {
getCaptcha()
})

onBeforeUnmount(() => {
clearInterval(timer.value);
})
</script>

<style scoped lang="less">

</style>

+ 1
- 1
src/views/login/login.vue Целия файл

@@ -150,7 +150,7 @@
let { store, ExclamationCircleOutlined, Modal } = useCommon();
let currentModule = ref<String>('login') // 当前模块 login 登录 resiter 注册
let loginSegmentedValue = ref<String>('我要求职') // 个人或者企业 // 我要求职 个人求职 我要招聘 企业
let loginMethod = ref<String>('password') // 登录方式 // password 密码登录 message 短信登录
let loginMethod = ref<String>('message') // 登录方式 // password 密码登录 message 短信登录
let registerSegmentedValue = ref<String>('求职者注册') // 注册方式
let createForm = ref<LoginType.LoginFormType>(dataForm)
let smsLoginForm = ref<LoginType.SmsLoginFormType>(smsLoginDataForm)

Loading…
Отказ
Запис