Soleilw 1 год назад
Родитель
Сommit
b8b0c1fb6a

+ 0
- 1
dist/assets/index-0kds0h5a.css
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 1
- 0
dist/assets/index-9Ic14vNC.css
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 0
- 542
dist/assets/index-JJeaanAG.js
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 542
- 0
dist/assets/index-M75Plfpg.js
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 2
- 2
dist/index.html Просмотреть файл

@@ -5,8 +5,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-JJeaanAG.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-0kds0h5a.css">
<script type="module" crossorigin src="/assets/index-M75Plfpg.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-9Ic14vNC.css">
</head>
<body>
<div id="app"></div>

+ 1
- 1
src/apis/index.ts Просмотреть файл

@@ -59,7 +59,7 @@ instance.interceptors.response.use(function (response) {
msgModel(response.data.msg)
break;
case 600:
if (response.data.errors) {
if (response.data.errors && Object.keys(response.data.errors).length > 0 ) {
msgModel(response.data.errors)
} else {
msgModel(response.data.msg)

+ 19
- 3
src/apis/models/index.ts Просмотреть файл

@@ -7,11 +7,14 @@ export const PostImageUpload = postModel(url.ImageUpload);

export const PostJobseekerRegister = postModel(url.JobseekerRegister);
export const PostCompanyRegister = postModel(url.CompanyRegister);
export const PostJobseekerlogin = postModel(url.Jobseekerlogin);
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 PostCompanyLoginByMobile = postModel(url.CompanyLoginByMobile);


// 招聘会
export const PostRecruitmentBookcompany = getModel(url.RecruitmentBookcompany);// 获取招聘会参与的企业
@@ -85,11 +88,11 @@ export const PostCompanyTalentPoolDel = postModel(url.CompanyTalentPoolDel); //
export const GetCompanyTalentPoolList = getModel(url.CompanyTalentPoolList); // 人才库列表

// 企业开通微信小程序账号公司权限
export const PostCompanycustomercodeAdd = getModel(url.CompanycustomercodeAdd); // 添加
export const PostCompanycustomercodeAdd = postModel(url.CompanycustomercodeAdd); // 添加
export const PostCompanycustomercodeDel = postModel(url.CompanycustomercodeDel); // 删除
export const PostCompanycustomercodeUpdate = postModel(url.CompanycustomercodeUpdate); // 编辑
export const PostCompanycustomercodeList = getModel(url.CompanycustomercodeList); // 列表
export const PostCompanycustomercodeDetail = getModel(url.CompanycustomercodeDetail); // 添加
export const GetCompanycustomercodeList = getModel(url.CompanycustomercodeList); // 列表
export const GetCompanycustomercodeDetail = getModel(url.CompanycustomercodeDetail); // 添加
// 展示广告位
export const GetAdvertscheduleList = getModel(url.AdvertscheduleList); // 添加

@@ -121,6 +124,19 @@ export const PostRecruitmentbookUpdate = postModel(url.RecruitmentbookUpdate); /
export const GetRecruitmentbookList = getModel(url.RecruitmentbookList); // 列表
export const GetRecruitmentbookDetail = getModel(url.RecruitmentbookDetail); // 详情

// 收藏
export const PostJobseekAddfavorite = postModel(url.JobseekAddfavorite);
export const PostJobseekDelfavorite = postModel(url.JobseekDelfavorite);
export const PostJobseekUpdatefavorite = postModel(url.JobseekUpdatefavorite);
export const GetJobseekListfavorite = getModel(url.JobseekListfavorite);
export const GetJobseekFavoritedetail = getModel(url.JobseekFavoritedetail);
// 投递
export const PostJobseekAddapplication = postModel(url.JobseekAddapplication);
export const PostJobseekDelapplication = postModel(url.JobseekDelapplication);
export const PostJobseekUpdateapplication = postModel(url.JobseekUpdateapplication);
export const GetJobseekListapplication = getModel(url.JobseekListapplication);
export const GetJobseekApplicationdetail = getModel(url.JobseekApplicationdetail);

// 简历
// 列表
export const PostJobseekerList = postModel(url.JobseekerList);

+ 14
- 0
src/apis/types/url.d.ts Просмотреть файл

@@ -10,6 +10,8 @@ declare namespace urlType {
JobseekerSmsLogin : String,
CustomerVerify : String,
JobseekerEditPwd : String,
CompanyLoginByMobile: String,
Jobseekerlogin: String,

// 招聘会
RecruitmentBookcompany : String,
@@ -104,6 +106,18 @@ declare namespace urlType {
RecruitmentbookList : String,
RecruitmentbookDetail : String,
// 收藏
'JobseekAddfavorite':String,
'JobseekDelfavorite': String,
'JobseekUpdatefavorite': String,
'JobseekListfavorite': String,
'JobseekFavoritedetail': String,
// 投递
'JobseekAddapplication': String,
'JobseekDelapplication':String,
'JobseekUpdateapplication': String,
'JobseekListapplication': String,
'JobseekApplicationdetail':String,

// 简历

+ 39
- 21
src/apis/url.ts Просмотреть файл

@@ -1,29 +1,34 @@
let web: string = '/web';
let common: string = '/common';
let web : string = '/web';
let common : string = '/common';
// 角色
export const url : urlType.url = {
// 字典
dictTree: common + '/dict/tree',
ImageUpload: common + '/image/upload?imgtype=1',
JobseekerRegister: web + '/jobseeker/register', // 个人注册
CompanyRegister: web + '/company/register', // 企业注册
Captcha: common + '/captcha', // 获取验证码
SmsSend: common + '/sms/send', // 短信验证码
JobseekerSmsLogin: web + '/jobseeker/smslogin', // 个人登录
Jobseekerlogin: web + '/jobseeker/login', // 个人登录
CustomerVerify: web + '/customer/verify', // 转换为HR
JobseekerEditPwd: web + '/jobseek/edit_pwd', // 修改密码
CompanyLoginByMobile: web + '/company/login_by_mobile', // 企业登录



// 招聘会
RecruitmentBookcompany: web + '/recruitment/bookcompany', // 获取招聘会参与的企业
RecruitmentList: web + '/recruitment/list', // 招聘会列表
// 求职者管理中心
ViewhistoryList: web + '/viewhistory/list', // 获取简历被查看记录
InterviewList: web + '/interview/list', // 获取应聘记录列表
// 企业管理中心
CompanyRecommentResume: web + '/company/recomment_resume', // 推荐简历
CompanyProfile: web + '/company/profile', // 企业基本资料
@@ -49,14 +54,14 @@ export const url : urlType.url = {
CompanyJobRecycleList: web + '/company/job_recycle_list', // 回收站列表
CompanyJobRecoverRecycle: web + '/company/job_recover_recycle', // 回收站列表
CompanyJobStatusChange: web + '/company/job_status_change', // 回收站列表
// 部门管理
CompanyDepartmentAdd: web + '/company/department_add', // 新增部门
CompanyDepartmentEdit: web + '/company/department_edit', // 编辑部门
CompanyDepartmentList: web + '/company/department_list', // 部门列表
CompanyDepartmentDel: web + '/company/department_del', // 部门删除
CompanyRecrBookList: web + '/company/recr_book_list', // 已预定招聘会列表
// 简历管理
CompanyResumeList: web + '/company/resume_list', // 收到的简历列表
CompanyResumeRecycle: web + '/company/resume_recycle', // 简历放进回收站
@@ -68,29 +73,29 @@ export const url : urlType.url = {
CompanyResumeInterviewAdmission: web + '/company/interview_admission', // 是否录取
CompanyResumeInterviewViewStatus: web + '/company/interview_view_status', // 是否参加面试
CompanyResumeViewedContactList: web + '/company/viewed_contact_list', // 已查看联系方式
// 人才库
CompanyTalentPoolAdd: web + '/company/talent_pool_add', // 添加人才库
CompanyTalentPoolDel: web + '/company/talent_pool_del', // 删除人才库记录
CompanyTalentPoolList: web + '/company/talent_pool_list', // 人才库列表

// 企业开通微信小程序账号公司权限
CompanycustomercodeAdd: web + '/companycustomercode/add', // 添加
CompanycustomercodeDel: web + '/companycustomercode/del', // 删除
CompanycustomercodeUpdate: web + '/companycustomercode/update', // 编辑
CompanycustomercodeList: web + '/companycustomercode/list', // 列表
CompanycustomercodeDetail: web + '/companycustomercode/detail', // 详情
// 展示广告位
AdvertscheduleList: web + '/advertschedule/list', // 详情
// 资讯
SectionList: web + '/section/list', // 列表
SectionDetail: web + '/section/detail', // 详情
ArticleList: web + '/article/list',
ArticlenDetail: web + '/article/detail',
ArticleList: web + '/article/list',
ArticlenDetail: web + '/article/detail',
// 职位
JobDetail: web + '/job/detail', // 获取职位详情
JobSearch: web + '/job/search', // 职位搜索
@@ -99,23 +104,23 @@ export const url : urlType.url = {
JobUrgentjobs: web + '/job/urgentjobs', // 急招职位
JobHighpayjobs: web + '/job/highpayjobs', // 高薪职位
JobCampusjobs: web + '/job/campusjobs', // 校园招聘
// 招聘会企业预定
RecruitmentbookAdd: web + '/recruitmentbook/add', // 添加
RecruitmentbookDel: web + '/recruitmentbook/del', // 删除
RecruitmentbookUpdate: web + '/recruitmentbook/update', // 编辑
RecruitmentbookList: web + '/recruitmentbook/list', // 列表
RecruitmentbookDetail: web + '/recruitmentbook/detail', // 详情



// 反馈
FeedbackAdd: common + '/feedback/add', // 添加
FeedbackDel: common + '/feedback/del', // 删除
FeedbackUpdate: common + '/feedback/update', // 编辑
FeedbackList: common + '/feedback/list', // 列表
FeedbackDetail: common + '/feedback/detail', // 详情
// 简历
JobseekerList: web + '/jobseeker/list', // 获取简历完整资料列表
JobseekerDetail: web + '/jobseeker/detail', // 获取简历完整资料
@@ -123,8 +128,21 @@ export const url : urlType.url = {
PersonInterviewList: web + '/person/interview_list', // 面试邀请记录
PersonInterviewViewStatus: web + '/person/interview_view_status', // 是否参加面试
PersonInterviewDel: web + '/person/interview_del', // 删除面试邀请

// 收藏
'JobseekAddfavorite': web + '/jobseek/addfavorite', // 添加
'JobseekDelfavorite': web + '/jobseek/delfavorite', // 删除
'JobseekUpdatefavorite': web + '/jobseek/updatefavorite', // 修改
'JobseekListfavorite': web + '/jobseek/listfavorite', // 查看
'JobseekFavoritedetail': web + '/jobseek/favoritedetail', // 详情
// 投递
'JobseekAddapplication': web + '/jobseek/addapplication', // 添加
'JobseekDelapplication': web + '/jobseek/delapplication', // 删除
'JobseekUpdateapplication': web + '/jobseek/updateapplication', // 修改
'JobseekListapplication': web + '/jobseek/listapplication', // 查看
'JobseekApplicationdetail': web + '/jobseek/applicationdetail', // 详情


// 基本资料
'JobapplicantAdd': web + '/jobapplicant/add', // 添加
'JobapplicantDel': web + '/jobapplicant/del', // 删除
@@ -184,5 +202,5 @@ export const url : urlType.url = {
'JobapplicantUpdateexperience': web + '/jobapplicant/updateexperience', // 修改
'JobapplicantListexperience': web + '/jobapplicant/listexperience', // 查看
'JobapplicantExperiencedetail': web + '/jobapplicant/experiencedetail', // 详情
}

+ 134
- 0
src/components/company/result/index.vue Просмотреть файл

@@ -0,0 +1,134 @@
<template>
<template v-if="!seekerList || seekerList.length == 0">
<a-empty style="height: 100vh;">
<template #description>
无求职者信息
</template>
</a-empty>
</template>
<template v-else>
<a-row :gutter="[20,20]">
<a-col span="24" v-for="(item, index) in seekerList">
<a-card>
<div class="talent-box">
<a-list>
<a-list-item>
<template #actions>
<a-button @click="detail(item)">
<StarOutlined />
预览
</a-button>
<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>
<image-container
:imgObj="{src: '/images/onlylogo.jpg',width: '48px',height:'48px'}"></image-container>

</template>
</a-list-item-meta>
</a-list-item>
</a-list>
</div>
</a-card>

</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>
<resume-detail v-if="detail_record" :detail_record="detail_record"></resume-detail>
</template>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, defineProps, watch } from 'vue';
import ResumeDetail from '@/components/jobseeker/resume/detail/index.vue'
import { PostJobseekerList } from '@/apis/models';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal, showOtherModal1 } = useCommon();
let props = defineProps(['search']);
let seekerList = ref<object[]>([])
let loading = ref<Boolean>(true);


const getPage = (data : object) => {
commomParams.value.search.page = data.current;
commomParams.value.search.pagesize = data.pageSize;
getData();
}
const getData = async () => {
try {
loading.value = true;
let res = await PostJobseekerList(commomParams.value.search);
loading.value = false;
seekerList.value = res.data.seekers;
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 onLoadMore = () => {
commomParams.value.search.page = commomParams.value.search.page + 1;
getData();
}

let detail_record = ref<Object>(null)
const detail = (record) => {
detail_record.value = record;
showOtherModal1()
}
// onMounted(() => {
// getData();
// })

watch(() => [props.search], (newVal) => {
if (newVal[0] ) {
commomParams.value.search = newVal[0];
getData();
}
}, { immediate: true })
</script>

<style scoped lang="less">

</style>

+ 65
- 30
src/components/company/search/index.vue Просмотреть файл

@@ -77,45 +77,42 @@
<a-input v-model:value="value" placeholder="请输入计算机能力" size="large" />
</a-form-item>
</a-col>
<!--
<a-col span="12">
<a-form-item label="工作经验">
<a-xuanze :dict="2021" placeholder="请选择工作经验" @saveSelect="saveEthnicity"
:select_content="commomParams.search.ethnicity"></a-xuanze>
</a-form-item>
</a-col>
<a-col span="12">
<a-form-item label="最小年龄" name="age_min">
<a-xuanze :dict="2012" placeholder="请选择民族" @saveSelect="saveEthnicity"
:select_content="commomParams.search.ethnicity"></a-xuanze>
</a-col> -->
<!-- <a-col span="6">
<a-form-item label="最大年龄">
<a-input-number :min="0" v-model:value="commomParams.search.keyword" placeholder="请输入最小年龄"
size="large" style="width: 100%;"/>
</a-form-item>
</a-col>
<a-col span="12">
<a-form-item label="最大年龄" name="age_max">
<a-xuanze :dict="2012" placeholder="请选择民族" @saveSelect="saveEthnicity"
:select_content="commomParams.search.ethnicity"></a-xuanze>
<a-col span="6">
<a-form-item label="最大年龄">
<a-input-number :max="99" v-model:value="commomParams.search.keyword" placeholder="请输入最大年龄"
size="large" style="width: 100%;"/>
</a-form-item>
</a-col>

<a-col span="12">
<a-form-item label="最小年龄" name="age_min">
<a-xuanze :dict="2012" placeholder="请选择民族" @saveSelect="saveEthnicity"
:select_content="commomParams.search.ethnicity"></a-xuanze>
</a-col> -->
<a-col span="6">
<a-form-item label="最小工作经验(年)">
<a-input-number :min="0" v-model:value="commomParams.search.min_work_experience" placeholder="请输入最小工作经验"
size="large" style="width: 100%;"/>
</a-form-item>
</a-col>

<a-col span="12">
<a-form-item label="最大年龄" name="age_max">
<a-xuanze :dict="2012" placeholder="请选择民族" @saveSelect="saveEthnicity"
:select_content="commomParams.search.ethnicity"></a-xuanze>
<a-col span="6">
<a-form-item label="最大工作经验(年)">
<a-input-number :max="99" v-model:value="commomParams.search.max_work_experience" placeholder="请输入最大工作经验"
size="large" style="width: 100%;"/>
</a-form-item>
</a-col>
<a-col span="24">
<a-flex justify="flex-end">
<a-space>
<a-button type="primary" @click="saveForm" size="large">开始搜索</a-button>
<a-button type="primary" @click="getData" size="large">开始搜索</a-button>
</a-space>
</a-flex>
</a-col>
@@ -163,20 +160,20 @@
commomParams.value.search.english = 0;
commomParams.value.search.mandarin = 0;
commomParams.value.search.cantonese = 0;
commomParams.value.search.other_language = '';
commomParams.value.search.other_language = 0;
commomParams.value.search.max_work_experience = 0;
commomParams.value.search.min_work_experience = 0;
commomParams.value.search.gender = '不限';
commomParams.value.search.gender = '';
commomParams.value.search.maxheight = 0;
commomParams.value.search.minheight = 0;
commomParams.value.search.maxweight = 0;
commomParams.value.search.minweight = 0;

watch(() => props.search_params, (newVal) => {
emit('searchData', commomParams.value.search)
}, {
immediate: true
})
// watch(() => props.search_params, (newVal) => {
// emit('searchData', commomParams.value.search)
// }, {
// immediate: true
// })

const getData = () => {
emit('searchData', commomParams.value.search)
@@ -194,6 +191,44 @@

emit('clearData', commomParams.value.search)
}

const saveTitle = (data) => {
commomParams.value.search.title = data.val ? data.val : 0;
}

const saveEducation = (data) => {
commomParams.value.search.education = data.val ? data.val : 0;
}

const saveMaritalStatus = (data) => {
commomParams.value.search.marital_status = data.val ? data.val : 0;
}

const savePoliticalStatus = (data) => {
commomParams.value.search.title = data.val ? data.val : 0;
}

const saveAvailableDateDesire = (data) => {
commomParams.value.search.available_date_desire = data.val ? data.val : 0;
}

const saveEnglish = (data) => {
commomParams.value.search.english = data.val ? data.val : 0;
}

const saveMandarin = (data) => {
commomParams.value.search.mandarin = data.val ? data.val : 0;
}

const saveCantonese = (data) => {
commomParams.value.search.cantonese = data.val ? data.val : 0;
}

const saveOtherLanguage = (data) => {
commomParams.value.search.other_language = data.val ? data.val : 0;
}
</script>

<style>

+ 6
- 10
src/components/jobseeker/invite/apply/index.vue Просмотреть файл

@@ -13,14 +13,10 @@
<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>
<div>企业查看状态:{{item.status_text}}</div>
</template>
<div>面试时间:{{item.invite_date}}</div>
<div>面试结果:{{item.employ_status_txt}}</div>
<div>面试企业:{{item.company_name}}</div>
<div>投递时间:{{item.created_at}}</div>
<div>企业名称:{{item.company_name}}</div>
</a-card>
</a-flex>
</a-col>
@@ -37,7 +33,7 @@

<script setup lang="ts">
import { ref, computed, onMounted, defineEmits, createVNode } from 'vue';
import { GetInterviewList } from '@/apis/models';
import { GetJobseekListapplication } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal } = useCommon();
@@ -76,9 +72,9 @@
const getData = async () => {
try {
loading.value = true;
let res = await GetInterviewList(commomParams.value.search);
let res = await GetJobseekListapplication(commomParams.value.search);
loading.value = false;
jobList.value = res.data.interviews;
jobList.value = res.data.jobapplicationrecords;
commomParams.value.page = {
current: commomParams.value.search.page,
pageSize: commomParams.value.search.pagesize,

+ 143
- 2
src/components/jobseeker/invite/collect/index.vue Просмотреть файл

@@ -1,8 +1,149 @@
<template>
<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="8" v-for="(item, index) in jobList">
<a-card :title="item.job_name">
<template #extra>
<a-button @click="cancelCollect(item.id,item.job_id)">取消收藏</a-button>
</template>
<div>企业名称:{{item.company_name}}</div>
<div>收藏时间:{{item.created_at}}</div>
<a-popover trigger="click" placement="rightTop">
<template #content>
<job-detail v-if="detail_record" :detail_record="detail_record"></job-detail>
</template>
<a-button @click="detail(item.job_id)">详情</a-button>
</a-popover>
</a-card>
</a-col>
</a-row>
</template>
</template>

<script>
<script setup lang="ts">
import { ref, computed, onMounted, defineEmits, createVNode } from 'vue';
import { GetJobseekListfavorite, PostJobseekUpdatefavorite } from '@/apis/models';
import JobDetail from '@/components/jobseeker/invite/detail/index.vue'
import { warnToast, successToast } from '@/utils/toastHelper';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal, showOtherModal1 } = useCommon();
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 GetJobseekListfavorite(commomParams.value.search);
loading.value = false;
jobList.value = res.data.jobapplicantfavorites;
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 cancelCollect = (id : Number, job_id : Number) => {
Modal.confirm({
title: `是否要取消收藏该职位`,
centered: true,
icon: createVNode(ExclamationCircleOutlined),
onOk() {
PostJobseekUpdatefavorite({ id: id, job_id: job_id }).then(res => {
successToast('已取消收藏')
getData();
})
},
onCancel() {

},
});
}
let detail_record = ref<Object>(null)
const detail = (record) => {
detail_record.value = record;
showOtherModal1()
}


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

<style>
<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>

+ 86
- 0
src/components/jobseeker/invite/detail/index.vue Просмотреть файл

@@ -0,0 +1,86 @@
<template>
<a-spin :spinning="spinning">
<template v-if="detail">
<a-card :title="detail.base.name" style="width: 500px;" :bordered="false">
<template #extra>{{detail.base.pay_range_text}}</template>
<a-flex style="width: 100%;">
<a-descriptions :column="1" title="职位描述">
<a-descriptions-item label="职位性质">{{detail.company.nature_text}}</a-descriptions-item>
<a-descriptions-item label="招聘人数">{{detail.base.invite_count}}人</a-descriptions-item>
<a-descriptions-item
label="工作地区">{{detail.locations ? detail.locations[0].name : '未知地址'}}</a-descriptions-item>
<a-descriptions-item label="月新范围">{{detail.base.pay_range_text}}</a-descriptions-item>
<a-descriptions-item label="食宿条件">{{detail.base.shisu_text}}</a-descriptions-item>
<a-descriptions-item label="节假日">{{detail.base.holidays_text}}</a-descriptions-item>
<a-descriptions-item label="有效期">{{detail.base.disabled_date}}</a-descriptions-item>
<a-descriptions-item label="有效期至">{{detail.base.name}}</a-descriptions-item>
<a-descriptions-item label="联系人">{{detail.contact.contact}}</a-descriptions-item>
<a-descriptions-item
label="职业类别">{{detail.base.types ? detail.base.types[0].name : '未知'}}</a-descriptions-item>
<a-descriptions-item label="联系电话">{{detail.contact.mobile}} <a-button size="small">
查看
</a-button></a-descriptions-item>
<a-descriptions-item></a-descriptions-item>
<a-descriptions-item label="职业描述">
<div v-html="detail.base.describe_text"></div></a-descriptions-item>
</a-descriptions>
</a-flex>
</a-card>
</template>
</a-spin>
</template>

<script setup lang="ts">
import { ref, onMounted, defineProps, computed, watch, defineEmits } from 'vue';
import { GetJobDetail } from '@/apis/models';
import { message } from 'ant-design-vue';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, hideOtherModal1, openOtherModel_1 } = useCommon();
const emit = defineEmits();
let props = defineProps(['detail_record']);
let detail = ref<Object>(null)
let spinning = ref<Boolean>(false); // 加载中

openOtherModel_1 = computed(() => {
return store.state.openOtherModel_1;
})

watch(() => [props.detail_record], (newVal) => {
if (newVal[0]) {
spinning.value = false
GetJobDetail({ id: props.detail_record }).then(res => {
detail.value = res.data
console.log(detail.value)
})
}
}, { immediate: true })

const cancelModal = () => {
hideOtherModal1()
}
</script>

<style lang="less" scoped>
.a-row:first-child {
border-bottom: none;
border-radius: 10px 10px 0 0;
}

.a-row:last-child {
border-radius: 0 0 10px 10px;
}

.a-row {
padding: 6px;
border: 1px #f0f0f0 solid;

.a-col:first-child {}
}

.a-col {
padding: 6px;
// padding-top: 6px;
}
</style>

+ 16
- 3
src/components/jobseeker/invite/interview/index.vue Просмотреть файл

@@ -11,7 +11,7 @@
<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">
<a-card :title="item.job_name" @click="detail(item.job_id)">
<template #extra>
<a-space>
<a-button @click="rejectInterview(item.id)">拒绝面试</a-button>
@@ -21,6 +21,12 @@
<div>面试时间:{{item.invite_date}}</div>
<div>面试结果:{{item.employ_status_txt}}</div>
<div>面试企业:{{item.company_name}}</div>
<a-popover trigger="click" placement="rightTop">
<template #content>
<job-detail v-if="detail_record" :detail_record="detail_record"></job-detail>
</template>
<a-button @click="detail(item.job_id)">详情</a-button>
</a-popover>
</a-card>
</a-flex>
</a-col>
@@ -38,9 +44,10 @@
<script setup lang="ts">
import { ref, computed, onMounted, defineEmits, createVNode } from 'vue';
import { GetPersonInterviewList, PostPersonInterviewViewStatus } from '@/apis/models';
import JobDetail from '@/components/jobseeker/invite/detail/index.vue'
import { warnToast, successToast } from '@/utils/toastHelper';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal } = useCommon();
let { store, commomParams, dayjs, richOption, ExclamationCircleOutlined, Modal, showOtherModal1 } = useCommon();
const emit = defineEmits();
let loading = ref<Boolean>(true);
let jobList = ref([]);
@@ -123,7 +130,7 @@
Modal.confirm({
title: `是否要拒绝面试`,
centered: true,
icon: PostPersonInterviewViewStatus(ExclamationCircleOutlined),
icon: createVNode(ExclamationCircleOutlined),
onOk() {
PostPersonInterviewViewStatus({ id: id, view_status: 3 }).then(res => {
successToast('已拒绝')
@@ -136,6 +143,12 @@
});
}

let detail_record = ref<Object>(null)
const detail = (record) => {
detail_record.value = record;
showOtherModal1()
}

onMounted(() => {
getData();
})

+ 215
- 0
src/components/jobseeker/resume/detail/index.vue Просмотреть файл

@@ -0,0 +1,215 @@
<template>
<a-modal v-model:visible="openOtherModel_1" title="预览简历" ok-text="提交" cancel-text="取消" @ok="sumbitForm"
@cancel="cancelModal" width="60%">
<a-spin :spinning="spinning">
<a-typography>
<a-typography-title :level="4">基本资料</a-typography-title>
<a-typography-paragraph>
<a-row :gutter="[20,20]">
<a-col span="24">
<a-row :gutter="[20,20]">
<a-col span="10">
<a-row>
<a-col span="24">
姓&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名:{{detail.seekername}}
</a-col>
<a-col span="24">
性&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;别:{{detail.gender}}
</a-col>
<a-col span="24">
身份证号:{{detail.id_number}}
</a-col>
<a-col span="24">
民&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;族:{{detail.ethnicity_txt}}
</a-col>
<a-col span="24">
身&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;高:{{detail.height}}cm
</a-col>
<a-col span="24">
政治面貌:{{detail.political_status_txt}}
</a-col>
<a-col span="24">
联系方式:{{detail.mobile}}
</a-col>
<a-col span="24">
邮&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱:{{detail.email}}
</a-col>
</a-row>
</a-col>
<a-col span="8">
<a-row>
<a-col span="24">
出生日期:{{detail.dob}}
</a-col>
<a-col span="24">
婚姻状况:{{detail.marital_status_txt}}
</a-col>
<a-col span="24">
学&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;历:{{detail.education_txt}}
</a-col>
<a-col span="24">
体&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;重:{{detail.weight}}kg
</a-col>
<a-col span="24">
现居地址:{{detail.now_level1_txt ? detail.now_level1_txt : ''}}{{detail.now_level2_txt ? detail.now_level2_txt : ''}}{{detail.now_level3_txt ? detail.now_level3_txt : ''}}{{detail.now_level4_txt ? detail.now_level4_txt : ''}}
</a-col>
<a-col span="24">
籍&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;贯:{{detail.native_place_txt}}
</a-col>
<a-col span="24">
户口地址:{{detail.now_level1_txt ? detail.now_level1_txt : ''}}{{detail.now_level2_txt ? detail.now_level2_txt : ''}}{{detail.now_level3_txt ? detail.now_level3_txt : ''}}{{detail.now_level4_txt ? detail.now_level4_txt : ''}}
</a-col>
</a-row>
</a-col>
<a-col span="6">
<image-container
:imgObj="{src: detail.photo? 'https://admin1.jcjob.cn/img/' + detail.photo : '', width: '200px',height: '280px',mode: 'fill'}"></image-container>
</a-col>
</a-row>
</a-col>
</a-row>
</a-typography-paragraph>
<a-typography-title :level="4">个人简介</a-typography-title>
<a-typography-paragraph>
<div v-html="detail.description"></div>
</a-typography-paragraph>
<a-typography-title :level="4">求职期望</a-typography-title>
<a-typography-paragraph>
<a-row>
<a-col span="24">
工作经验:{{detail.work_experience}}年
</a-col>
<a-col span="24">
期望薪资:{{detail.salary_range_txt}}
</a-col>
<a-col span="24">
<a-row>
<a-col span="8" v-if="detail.desire_areas">
<a-row>
<a-col span="24" v-for="(item,index) in detail.desire_areas">
期望地址{{index + 1}}:{{item.level1_txt ? item.level1_txt : ''}}{{item.level2_txt ? item.level2_txt : ''}}{{item.level3_txt ? item.level3_txt : ''}}{{item.level4_txt ? item.level4_txt : ''}}
</a-col>
</a-row>
</a-col>
<a-col span="8" v-if="detail.desire_positions">
<a-row>
<a-col span="24" v-for="(item,index) in detail.desire_positions">
期望职位{{index + 1}}:{{item.level1_txt ? item.level1_txt : ''}}{{item.level2_txt ? item.level2_txt : ''}}
</a-col>
</a-row>
</a-col>
<a-col span="8" v-if="detail.desire_industrys">
<a-row>
<a-col span="24" v-for="(item,index) in detail.desire_industrys">
期望行业{{index + 1}}:{{item.industry_txt}}
</a-col>
</a-row>
</a-col>
</a-row>
</a-col>
</a-row>
</a-typography-paragraph>
</a-typography>
<a-typography-title :level="4">专业技能掌握能力</a-typography-title>
<a-typography-paragraph>
<a-row>
<a-col span="24">
英&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;语:{{detail.english_txt}}
</a-col>
<a-col span="24">
国&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;语:{{detail.mandarin_txt}}
</a-col>
<a-col span="24">
粤&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;语:{{detail.cantonese_txt}}
</a-col>
<a-col span="24">
第二外语:{{detail.salary_range_txt}}
</a-col>
<a-col span="24">
计算机能力:{{detail.computer_skills}}
</a-col>
</a-row>
</a-typography-paragraph>
<a-typography-title :level="4">工作经历</a-typography-title>
<a-typography-paragraph>
<template v-for="(item,index) in detail.experiences">
<a-card :title="item.company_name" style="margin-bottom: 10px;">
<template #extra>{{item.position}}</template>
<p>工作时间:{{item.start_year}}.{{item.start_month}}至{{item.end_year}}.{{item.end_month}}</p>
<p>离职原因:{{item.reason_for_leaving}}</p>
</a-card>
</template>
</a-typography-paragraph>
<a-typography-title :level="4">教育/培训经历</a-typography-title>
<a-typography-paragraph>
<template v-for="(item,index) in detail.trainings">
<a-card :title="item.school_or_institution" style="margin-bottom: 10px;">
<template #extra>{{item.major}}</template>
<p>教育/培训时间:{{item.start_year}}.{{item.start_month}}至{{item.end_year}}.{{item.end_month}}</p>
<p>曾担任的职务:{{item.positions_held}}</p>
<p>获得的证书:{{item.certificate}}</p>
<p>获得的奖项:{{item.awards}}</p>
</a-card>
</template>
</a-typography-paragraph>
</a-spin>
</a-modal>
</template>

<script setup lang="ts">
import { ref, onMounted, defineProps, computed, watch, defineEmits } from 'vue';
import { GetJobseekerDetail, GetJobapplicantIntroductiondetail, PostJobapplicantTrainingdetail, PostJobapplicantDesireindustrydetail, PostJobapplicantExperiencedetail } from '@/apis/models';
import { message } from 'ant-design-vue';
import { useCommon } from '@/hooks/useCommon';
let { store, commomParams, hideOtherModal1, openOtherModel_1 } = useCommon();
const emit = defineEmits();
let props = defineProps(['detail_record']);
let detailTitle = ref<String>('')
let detail = ref<Object>({})
let trainList = ref<Object[]>([])
let experienceList = ref<Object[]>([])
let introduction = ref<Object>({})
let spinning = ref<Boolean>(false); // 加载中

openOtherModel_1 = computed(() => {
return store.state.openOtherModel_1;
})

watch(() => [props.detail_record], (newVal) => {
if (newVal[0]) {
spinning.value = false
GetJobseekerDetail({ customer_id: props.detail_record.customer_id }).then(res => {
detail.value = res.data
console.log(detail.value)
})
}
}, { immediate: true })

const cancelModal = () => {
hideOtherModal1()
}
</script>

<style lang="less" scoped>
.a-row:first-child {
border-bottom: none;
border-radius: 10px 10px 0 0;
}

.a-row:last-child {
border-radius: 0 0 10px 10px;
}

.a-row {
padding: 6px;
border: 1px #f0f0f0 solid;

.a-col:first-child {}
}

.a-col {
padding: 6px;
// padding-top: 6px;
}
</style>

+ 5
- 4
src/components/layout/header/aHeader.vue Просмотреть файл

@@ -264,10 +264,11 @@
let interviewListLength = ref<Number>(0)
onMounted(() => {
GetPersonInterviewList({ status: 0 }).then(res => {
interviewListLength.value = res.data.list.length
})
if(sessionStorage.getItem('pageType') == 'personal' && sessionStorage.getItem('role') == 'personal') {
GetPersonInterviewList({ status: 0 }).then(res => {
interviewListLength.value = res.data.list.length
})
}
})
</script>


+ 21
- 0
src/components/user/conver/columns.ts Просмотреть файл

@@ -0,0 +1,21 @@

export const cols = <ColType.type[]>[
{
title: '验证码',
dataIndex: 'code'
}, {
title: '绑定的账号',
dataIndex: 'customer.username'
}, {
title: '使用状态',
dataIndex: 'customer_id'
}, {
title: '生成时间',
dataIndex: 'created_at',
},
{
title: '操作',
dataIndex: 'operation',
slots: { customRender: 'operation' },
},
]

+ 141
- 0
src/components/user/conver/index.vue Просмотреть файл

@@ -0,0 +1,141 @@
<template>
<a-search @searchData="searchData" @clearData="clearData" :search_params="commomParams.search"></a-search>
<a-card title="转换验证码">
<template #extra>
<a-button @click="getCode">生成验证码</a-button>
</template>
<a-biaoge :data="commomParams.table.data" :columns="commomParams.table.columns" :pagination="commomParams.page"
@page="getPage" :loading="loading">
<template #default="{ record }">
<a-row :gutter="20">
<a-col>
<a-dropdown placement="bottomRight">
<template #overlay>
<a-menu>
<a-menu-item key="1">
<a-button @click="copyCode(record.code)" block>复制</a-button>
</a-menu-item>
<a-menu-item key="2">
<a-button @click="del(record.id)" block>删除</a-button>
</a-menu-item>
</a-menu>
</template>
<a-button>
操作
<DownOutlined />
</a-button>
</a-dropdown>
</a-col>
</a-row>
</template>
</a-biaoge>
</a-card>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, defineEmits, createVNode } from 'vue';
import { PostCompanycustomercodeAdd, PostCompanycustomercodeDel, PostCompanycustomercodeUpdate, GetCompanycustomercodeList } from '@/apis/models';
import ASearch from '@/components/user/conver/search.vue';
import { useCommon } from '@/hooks/useCommon';
import { cols } from '@/components/user/conver/columns';
import { warnToast, successToast } from '@/utils/toastHelper';
const emit = defineEmits();
let { commomParams, ExclamationCircleOutlined, Modal } = useCommon();
let loading = ref<Boolean>(true);

onMounted(() => {
getData();
})

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: 10,
sort: 'id',
sortby: 'asc',
keyword: ''
}
}
getData();
}


const getPage = (data : object) => {
commomParams.value.search.page = data.current;
commomParams.value.search.pagesize = data.pageSize;
getData();
}
const getData = async () => {
try {
loading.value = true;
let res = await GetCompanycustomercodeList(commomParams.value.search);
loading.value = false;
commomParams.value.table.data = res.data.companycustomercodes;
commomParams.value.table.columns = cols;
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 edit = (record : Object) => {
emit('toEdit', { record: record })
}


const getCode = (id) => {
Modal.confirm({
title: '是否要生成验证码',
icon: createVNode(ExclamationCircleOutlined),
centered: true,
onOk() {
PostCompanycustomercodeAdd().then(res => {
successToast('已生成验证码')
getData()
})
},
onCancel() {

},
});
}

const copyCode = async (code) => {
try {
await navigator.clipboard.writeText(code);
successToast('复制成功');
} catch (err) {
warnToast('复制到剪贴板失败,请手动复制');
}
}



const del = (id : number) => {
commomParams.value.delParam = { id: id };
PostCompanycustomercodeDel(commomParams.value.delParam).then(res => {
successToast('删除成功');
getData();
})
}
</script>

<style scoped lang="less">

</style>

+ 54
- 0
src/components/user/conver/search.vue Просмотреть файл

@@ -0,0 +1,54 @@
<template>
<a-form :model="commomParams.search">
<a-row :gutter="20">
<a-col span="6">
<a-form-item>
<a-input-search v-model:value="commomParams.search.keyword" placeholder="请输入账号名" enter-button="搜索"
@search="getData" />
</a-form-item>
</a-col>
<a-col span="6">
<a-button type="primary" @click="clearSearch">重置</a-button>
</a-col>
</a-row>
</a-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
import { useCommon } from '@/hooks/useCommon';
let { commomParams } = useCommon();
let props = defineProps(['search_params']);
const emit = defineEmits();


watch(() => props.search_params, (newVal) => {
emit('searchData', commomParams.value.search)
},{
immediate: true
})

const getData = () => {
emit('searchData', commomParams.value.search)
}

// 清空搜索
const clearSearch = () => {
commomParams.value.search = {
page: 1,
pagesize: 10,
sort: 'id',
sortby: 'asc',
keyword: ''
}
emit('clearData', commomParams.value.search)
}
</script>

<style>
</style>

+ 2
- 2
src/components/user/email/index.vue Просмотреть файл

@@ -5,8 +5,8 @@
<a-col span="12">
<a-row>
<a-col span="24">
<a-form-item required label="邮箱" name="email">
<a-input v-model:value="createForm.email" placeholder="请输入邮箱" />
<a-form-item label="邮箱" name="email">
<a-input v-model:value="createForm.email" placeholder="请输入邮箱" size="large"/>
</a-form-item>
</a-col>
<a-col span="24">

+ 6
- 1
src/store/mutations.ts Просмотреть файл

@@ -27,6 +27,10 @@ const getShowEdit = (state, payload) => {
state.show_edit = payload.show_edit;
}

const getOpenMoreModel = (state : object, payload : object) => {
state.openOtherModel_1 = payload.openOtherModel_1;
}

export const mutations = {
getRouteName,
setShowLoginBox,
@@ -34,5 +38,6 @@ export const mutations = {
getToken,
getRole,
getPageType,
getShowEdit
getShowEdit,
getOpenMoreModel
}

+ 2
- 1
src/store/state.ts Просмотреть файл

@@ -7,5 +7,6 @@ export const state = <StateType>{
token: '',
role: '',
pageType: '',
show_edit: false
show_edit: false,
openOtherModel_1: false,
}

+ 2
- 1
src/store/types.ts Просмотреть файл

@@ -5,5 +5,6 @@ export interface StateType {
token ?: String,
role ?: String,
pageType ?: String,
show_edit ?: Boolean
show_edit ?: Boolean,
openOtherModel_1 : Boolean,
}

+ 32
- 7
src/views/company/search/index.vue Просмотреть файл

@@ -4,13 +4,24 @@
<a-col span="18">
<a-row>
<a-col span="4">
<common-left-sider :menu_list="menu_list" :selected_key="[1]"
<common-left-sider :menu_list="menu_list" :selected_key="[2]"
@changeKey="changeKey"></common-left-sider>
</a-col>
<a-col span="20">
<div style="width: 100%;background-color: #fff;padding: 20px;border-radius: 10px;">
<resume-search v-if="curKey == 1"></resume-search>
<resume-result v-if="curKey == 2"></resume-result>
<resume-search v-if="curKey == 1" @searchData="searchData"></resume-search>
<a-tabs v-model:activeKey="activeKey" @change="activeKeyChange" v-if="curKey == 2"
type="card">
<a-tab-pane :key="1" tab="推荐人才">
<resume-result v-if="activeKey == 1" :search="searchParams"></resume-result>
</a-tab-pane>
<a-tab-pane :key="2" tab="最新简历" force-render>
<resume-result :search="searchParams"></resume-result>
</a-tab-pane>
<a-tab-pane :key="3" tab="应届毕业生">
<resume-result v-if="activeKey == 3" :search="searchParams"></resume-result>
</a-tab-pane>
</a-tabs>
</div>
</a-col>
</a-row>
@@ -22,13 +33,27 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import ResumeSearch from '@/components/company/search/index.vue'
import ResumeResult from '@/components/resume/result/index.vue'
let menu_list = ref([{ title: '简历搜索', key: 1 },{ title: '搜索结果', key: 2 }])
let curKey = ref<Number>(1)
import ResumeResult from '@/components/company/result/index.vue'
let menu_list = ref([{ title: '简历搜索', key: 1 }, { title: '简历列表', key: 2 }])
let curKey = ref<Number>(2)
let activeKey = ref<Number>(1);
let searchParams = ref<any>(null)

const changeKey = (data) => {
curKey.value = data.key;
}

const searchData = (data) => {
searchParams.value = data;
if(activeKey.value == 2) {
searchParams.value.sortby = 'desc'
}
curKey.value = 2
}
</script>

<style>
<style scoped>
:deep(.ant-tabs-tab-btn) {
color: #4FBE70 !important;
}
</style>

+ 25
- 9
src/views/jobseeker/home/index.vue Просмотреть файл

@@ -33,8 +33,8 @@
{{basic.qq ? basic.qq : '未填写'}}
</a-descriptions-item>
<a-descriptions-item>
<a-button type="link" class="main-color">
<RedoOutlined style="color: #4FBE70" />刷新简历
<a-button type="link" class="main-color" @click="refreshResume">
<RedoOutlined style="color: #4FBE70" :spin="refreshing" rotate="90"/>刷新简历
</a-button>
</a-descriptions-item>
<a-descriptions-item label="简历是否在家政可见">
@@ -58,16 +58,16 @@
<a-col span="18">
<a-tabs v-model:activeKey="activeKey" @change="activeKeyChange">
<a-tab-pane :key="1" tab="面试记录">
<invite-interview></invite-interview>
<invite-interview v-if="activeKey == 1"></invite-interview>
</a-tab-pane>
<a-tab-pane :key="2" tab="投递记录" force-render>
<invite-apply></invite-apply>
<invite-apply v-if="activeKey == 2"></invite-apply>
</a-tab-pane>
<a-tab-pane :key="3" tab="谁看过我">
<invite-seeme></invite-seeme>
<invite-seeme v-if="activeKey == 3"></invite-seeme>
</a-tab-pane>
<a-tab-pane :key="4" tab="收藏的职位">
<invite-collect></invite-collect>
<invite-collect v-if="activeKey == 4"></invite-collect>
</a-tab-pane>
</a-tabs>
</a-col>
@@ -82,18 +82,34 @@
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 { GetJobseekerDetail, GetCompanyRecommentResume, GetViewHistoryList, GetPersonInterviewList, PostJobapplicantUpdate } from '@/apis/models';
import { warnToast, successToast } from '@/utils/toastHelper';
import { EditOutlined, FileSearchOutlined, RedoOutlined } from '@ant-design/icons-vue';
import { useCommon } from '@/hooks/useCommon';
let { commomParams, ExclamationCircleOutlined, Modal, onMenu } = useCommon();
let jobList = ref<object[]>([])
let jobList = ref<Object[]>([])
let basic = ref<Object>({})
let seeLength = ref<Number>(0)
let activeKey = ref<Number>(1)
let refreshing = ref<Boolean>(false)
let createForm = ref<Object>({
hide_resume: 0,
house_keeping_status: 0,
remind_interview: 2
})

const toResume = () => {
debugger
onMenu('/jobseeker/resume')
}
const refreshResume = () => {
refreshing.value = true;
successToast('简历已刷新')
refreshing.value = false
}
onMounted(() => {
GetJobseekerDetail({ customer_id: sessionStorage.getItem('id') }).then(res => {
basic.value = res.data

+ 14
- 3
src/views/login/data.ts Просмотреть файл

@@ -1,6 +1,6 @@
export let dataForm = {
username: "18022147412",
password: "123456",
username: "",
password: "",
capt_id: "",
captcha: ""
}
@@ -72,6 +72,17 @@ export const reset = () => {
capt_id: "",
captcha: ""
}
smsDataForm = {
mobile: "",
captcha: "",
capt_id: ""
};
smsLoginDataForm = {
mobile: "",
sms_code: "",
}

return { dataForm, otherDataForm, personalDataForm, companyDataForm }
return { dataForm, otherDataForm, personalDataForm, companyDataForm, smsDataForm, smsLoginDataForm}
}

+ 74
- 46
src/views/login/login.vue Просмотреть файл

@@ -141,7 +141,7 @@

<script lang="ts" setup>
import { ref, onMounted, computed, onBeforeUnmount } from 'vue';
import { GetCaptcha, PostCompanyLogin, PostSmsSend, PostJobseekerSmsLogin } from '@/apis/models';
import { GetCaptcha, PostJobseekerlogin,PostCompanyLogin, PostSmsSend, PostJobseekerSmsLogin, PostCompanyLoginByMobile} from '@/apis/models';
import { store } from '@/store/index';
import { router } from '@/router/index';
import { dataForm, otherDataForm, personalDataForm, companyDataForm, smsDataForm, smsLoginDataForm, reset } from '@/views/login/data.ts';
@@ -206,39 +206,36 @@


const loginTypeChange = () => {
getCaptcha()
resetForm()
}

const changeLoginMethod = (val : string) => {
loginMethod.value = val;
createForm.value = reset().dataForm as LoginType.LoginFormType;
getCaptcha()
resetForm()
}

const toModule = (val : string) => {
currentModule.value = val;
createForm.value = reset().dataForm as LoginType.LoginFormType;
personalForm.value = reset().dataForm as RegisterType.RegisterPersonalFormType;
companyForm.value = reset().dataForm as RegisterType.RegisterCompanyFormType;
smsForm.value = reset().dataForm as LoginType.SmsFormType;
smsLoginForm.value = reset().dataForm as LoginType.SmsLoginFormType;
personalForm.value = reset().personalDataForm as RegisterType.RegisterPersonalFormType;
companyForm.value = reset().companyDataForm as RegisterType.RegisterCompanyFormType;
smsForm.value = reset().smsDataForm as LoginType.SmsFormType;
smsLoginForm.value = reset().smsLoginDataForm as LoginType.SmsLoginFormType;
getCaptcha()
}

const resetForm = () => {
createForm.value = reset().dataForm as LoginType.LoginFormType;
personalForm.value = reset().dataForm as RegisterType.RegisterPersonalFormType;
companyForm.value = reset().dataForm as RegisterType.RegisterCompanyFormType;
smsForm.value = reset().dataForm as LoginType.SmsFormType;
smsLoginForm.value = reset().dataForm as LoginType.SmsLoginFormType;
personalForm.value = reset().personalDataForm as RegisterType.RegisterPersonalFormType;
companyForm.value = reset().companyDataForm as RegisterType.RegisterCompanyFormType;
smsForm.value = reset().smsDataForm as LoginType.SmsFormType;
smsLoginForm.value = reset().smsLoginDataForm as LoginType.SmsLoginFormType;
getCaptcha()
}

const getCaptcha = () => {
capt_id.value = ''
createForm.value.captcha = '';
GetCaptcha().then(res => {
capt_id.value = res.data.capt_id;
codeImage.value = res.data.img;
@@ -247,9 +244,9 @@

const login = () => {
if (loginSegmentedValue.value == '我要求职') {
if (loginMethod == 'password') {
if (loginMethod.value == 'password') {
createForm.value.capt_id = capt_id.value;
PostCompanyLogin(createForm.value).then(res => {
PostJobseekerlogin(createForm.value).then(res => {
successToast('登录成功');
store.commit('setShowLoginBox', {
showLoginBox: false
@@ -258,19 +255,19 @@
token: res.data.jwttoken.accesstoken
})
store.commit('getRole', {
role: 'company'
role: 'personal'
})
store.commit('getPageType', {
pageType: 'company'
pageType: 'personal'
})
sessionStorage.setItem('token', res.data.jwttoken.accesstoken)
sessionStorage.setItem('role', 'company')
sessionStorage.setItem('pageType', 'company')
sessionStorage.setItem('id', res.data.company_id)
sessionStorage.setItem('role', 'personal')
sessionStorage.setItem('pageType', 'personal')
sessionStorage.setItem('id', res.data.customerid)
store.commit('permissions/SET_PERMISSION', null)
store.commit('permissions/SET_MENU', [])
resetForm()
router.push('/manage/home')
router.push('/jobseeker/home')
}).catch(err => {
getCaptcha()
})
@@ -304,32 +301,63 @@
})
}
} else {
createForm.value.capt_id = capt_id.value;
PostCompanyLogin(createForm.value).then(res => {
successToast('登录成功');
store.commit('setShowLoginBox', {
showLoginBox: false
})
store.commit('getToken', {
token: res.data.jwttoken.accesstoken
})
store.commit('getRole', {
role: 'company'
if (loginMethod.value == 'password') {
createForm.value.capt_id = capt_id.value;
PostCompanyLogin(createForm.value).then(res => {
successToast('登录成功');
store.commit('setShowLoginBox', {
showLoginBox: false
})
store.commit('getToken', {
token: res.data.jwttoken.accesstoken
})
store.commit('getRole', {
role: 'company'
})
store.commit('getPageType', {
pageType: 'company'
})
sessionStorage.setItem('token', res.data.jwttoken.accesstoken)
sessionStorage.setItem('role', 'company')
sessionStorage.setItem('pageType', 'company')
sessionStorage.setItem('id', res.data.company_id)
store.commit('permissions/SET_PERMISSION', null)
store.commit('permissions/SET_MENU', [])
resetForm()
router.push('/manage/home')
}).catch(err => {
getCaptcha()
})
store.commit('getPageType', {
pageType: 'company'
} else {
smsLoginForm.value.mobile = createForm.value.username ? createForm.value.username : '';
smsLoginForm.value.sms_code = Number(smsLoginForm.value.sms_code)
PostCompanyLoginByMobile(smsLoginForm.value).then(res => {
successToast('登录成功');
store.commit('setShowLoginBox', {
showLoginBox: false
})
store.commit('getToken', {
token: res.data.jwttoken.accesstoken
})
store.commit('getRole', {
role: 'company'
})
store.commit('getPageType', {
pageType: 'company'
})
sessionStorage.setItem('token', res.data.jwttoken.accesstoken)
sessionStorage.setItem('role', 'company')
sessionStorage.setItem('pageType', 'company')
sessionStorage.setItem('id', res.data.company_id)
store.commit('permissions/SET_PERMISSION', null)
store.commit('permissions/SET_MENU', [])
resetForm()
router.push('/manage/home')
}).catch(err => {
getCaptcha()
})
sessionStorage.setItem('token', res.data.jwttoken.accesstoken)
sessionStorage.setItem('role', 'company')
sessionStorage.setItem('pageType', 'company')
sessionStorage.setItem('id', res.data.company_id)
store.commit('permissions/SET_PERMISSION', null)
store.commit('permissions/SET_MENU', [])
resetForm()
router.push('/manage/home')
}).catch(err => {
getCaptcha()
})
}
}

}

+ 3
- 1
src/views/manage/user/index.vue Просмотреть файл

@@ -12,6 +12,7 @@
<user-expense v-if="curKey == 1"></user-expense>
<user-password v-if="curKey == 2"></user-password>
<user-email v-if="curKey == 3"></user-email>
<user-conver v-if="curKey == 4"></user-conver>
</div>
</a-col>
</a-row>
@@ -25,8 +26,9 @@
import UserExpense from '@/components/user/expense/index.vue'
import UserPassword from '@/components/user/password/index.vue'
import UserEmail from '@/components/user/email/index.vue'
import UserConver from '@/components/user/conver/index.vue'
let companyList = ref<object[]>([{}, {}, {}, {}, {}, {}])
let menu_list = ref([{ title: '费用管理', key: 1 },{ title: '修改登录密码', key: 2},{ title: '修改邮箱', key: 3}])
let menu_list = ref([{ title: '费用管理', key: 1 },{ title: '修改登录密码', key: 2},{ title: '修改邮箱', key: 3},{ title: '生成招聘者代码', key: 4}])
let curKey = ref<Number>(1)
const changeKey = (data) => {
curKey.value = data.key;

Загрузка…
Отмена
Сохранить