添加应聘登记表预览和打印功能- 新增应聘登记表预览对话框,用于展示面试者详细信息

- 添加打印功能,支持将应聘登记表打印为 A4 格式
- 优化面试信息列表界面,增加预览按钮
- 新增 FillForm 页面用于填写应聘登记表
This commit is contained in:
tzy 2025-05-30 10:55:50 +08:00
parent 6a628c64f8
commit f59eaf59ac
10 changed files with 1229 additions and 55 deletions

View File

@ -42,3 +42,4 @@ export function delInterviewer(id) {
method: 'delete'
})
}

View File

@ -28,3 +28,10 @@ export function uploadDispatchingFile(data){
method:'post'
})
}
export function updateImages(data) {
return request({
url: '/restaurant/images/update',
method: 'put',
data: data
});
}

View File

@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register']
const whiteList = ['/login', '/register', '/FillForm']
router.beforeEach((to, from, next) => {
NProgress.start()

View File

@ -45,6 +45,10 @@ export const constantRoutes = [
path: '/login',
component: () => import('@/views/login'),
hidden: true
}, {
path: '/FillForm',
component: () => import('@/views/personnelMatters/interviewer/FillForm.vue'),
hidden: true
},
{
path: '/register',
@ -134,6 +138,16 @@ export const dynamicRoutes = [
}
]
},
{
path: '/personnelMatters/interviewer/fill-form',
name: 'FillForm',
component: () => import('@/views/personnelMatters/interviewer/FillForm.vue'),
hidden: true,
meta: { title: '应聘登记表填写',
icon: 'form',
requiresAuth: false
}
},
{
path: '/tool/gen-edit',
component: Layout,
@ -152,6 +166,7 @@ export const dynamicRoutes = [
// 防止连续点击多次路由报错
let routerPush = Router.prototype.push;
let routerReplace = Router.prototype.replace;
// push
Router.prototype.push = function push(location) {

View File

@ -9,14 +9,14 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="参数码" prop="paramCode">
<el-form-item label="参数码" prop="paramCode">
<el-input
v-model="queryParams.paramCode"
placeholder="请输入参数码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item-->
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@ -73,10 +73,10 @@
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" />-->
<el-table-column label="参数名" align="center" prop="paramName" />
<!-- <el-table-column label="参数码" align="center" prop="paramCode" />-->
<el-table-column label="参数码" align="center" prop="paramCode" />
<el-table-column label="参数值" align="center" prop="paramValue" />
<el-table-column label="说明" align="center" prop="description" />
<el-table-column label="备注" align="center" prop="remark" />
<!-- <el-table-column label="备注" align="center" prop="remark" />-->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
@ -102,20 +102,20 @@
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="参数名" prop="paramName">
<el-input v-model="form.paramName" placeholder="请输入参数名" />
<el-input v-model="form.paramName" placeholder="请输入参数名" disabled />
</el-form-item>
<el-form-item label="参数码" prop="paramCode">
<el-input v-model="form.paramCode" placeholder="请输入参数码" disabled/>
</el-form-item>
<!-- <el-form-item label="参数码" prop="paramCode">
<el-input v-model="form.paramCode" placeholder="请输入参数码" />
</el-form-item>-->
<el-form-item label="参数值" prop="paramValue">
<el-input v-model="form.paramValue" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="说明" prop="description">
<el-input v-model="form.description" type="textarea" placeholder="请输入内容" />
<el-input v-model="form.description" type="textarea" placeholder="请输入内容" disabled/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<!-- <el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form-item>-->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>

View File

@ -0,0 +1,464 @@
<template>
<div class="app-container">
<h2 class="form-title">应聘登记表填写</h2>
<el-form :model="form" :rules="rules" ref="registerForm" label-width="120px" class="mobile-form">
<!-- 基本信息 -->
<div class="form-section">
<h3 class="section-title">基本信息</h3>
<el-form-item label="应聘部门" prop="department">
<el-input v-model="form.department" placeholder="请输入应聘部门"/>
</el-form-item>
<el-form-item label="应聘岗位" prop="post">
<el-input v-model="form.post" placeholder="请输入应聘岗位"/>
</el-form-item>
<el-form-item label="期望薪资" prop="salary">
<el-input v-model="form.salary" placeholder="请输入期望薪资"/>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名"/>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select v-model="form.gender" placeholder="请选择性别" style="width: 100%">
<el-option label="男" value="男"/>
<el-option label="女" value="女"/>
</el-select>
</el-form-item>
<el-form-item label="出生年月日" prop="birth">
<el-date-picker v-model="form.birth" type="date" value-format="yyyy-MM-dd" style="width: 100%" placeholder="请选择出生年月日"/>
</el-form-item>
</div>
<!-- 个人情况 -->
<div class="form-section">
<h3 class="section-title">个人情况</h3>
<el-form-item label="民族" prop="nation">
<el-input v-model="form.nation" placeholder="请输入民族"/>
</el-form-item>
<el-form-item label="目前工作状况" prop="jobStatus">
<el-select v-model="form.jobStatus" placeholder="请选择工作状况" style="width: 100%">
<el-option label="在职" value="在职"/>
<el-option label="待业" value="待业"/>
<el-option label="其他" value="其他"/>
</el-select>
</el-form-item>
<el-form-item label="婚姻情况" prop="maritalStatus">
<el-select v-model="form.maritalStatus" placeholder="请选择工作状况" style="width: 100%">
<el-option label="已婚" value="已婚"/>
<el-option label="单身" value="单身"/>
<el-option label="未婚" value="未婚"/>
</el-select>
</el-form-item>
<el-form-item label="政治面貌" prop="politicalStatus">
<el-select v-model="form.politicalStatus" placeholder="请选择政治面貌" style="width: 100%">
<el-option label="群众" value="群众"/>
<el-option label="党员" value="党员"/>
<el-option label="团员" value="团员"/>
<el-option label="预备党员" value="预备党员"/>
</el-select>
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="form.idCard" placeholder="请输入身份证号"/>
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话"/>
</el-form-item>
</div>
<!-- 教育背景 -->
<div class="form-section">
<h3 class="section-title">教育背景</h3>
<el-form-item label="最高学历" prop="education">
<el-select v-model="form.education" placeholder="请选择最高学历">
<el-option
v-for="dict in educationOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="专业" prop="major">
<el-input v-model="form.major" placeholder="请输入专业"/>
</el-form-item>
<el-form-item label="毕业学校" prop="school">
<el-input v-model="form.school" placeholder="请输入毕业学校"/>
</el-form-item>
<el-form-item label="学位" prop="degree">
<el-input v-model="form.degree" placeholder="请输入学位"/>
</el-form-item>
<el-form-item label="职称" prop="title">
<el-input v-model="form.title" placeholder="请输入职称"/>
</el-form-item>
<el-form-item label="到岗时间" prop="arrivalDate">
<el-date-picker v-model="form.arrivalDate" type="date" value-format="yyyy-MM-dd" style="width: 100%" placeholder="请选择到岗时间"/>
</el-form-item>
</div>
<!-- 地址信息 -->
<div class="form-section">
<h3 class="section-title">地址信息</h3>
<el-form-item label="户口所在地" prop="registeredAddress">
<el-input v-model="form.registeredAddress" placeholder="请输入户口所在地详细地址"/>
</el-form-item>
<el-form-item label="现居住地址" prop="currentAddress">
<el-input v-model="form.currentAddress" placeholder="请输入现居住地址"/>
</el-form-item>
</div>
<!-- 家庭成员 -->
<div class="form-section">
<h3 class="section-title">家庭成员</h3>
<div v-for="(item, index) in form.familyList" :key="index" class="family-item">
<el-form-item :label="'成员' + (index + 1)" class="family-member">
<el-input v-model="item.relation" placeholder="称谓" class="mb-2"/>
<el-input v-model="item.name" placeholder="姓名" class="mb-2"/>
<el-input v-model="item.age" placeholder="年龄" class="mb-2"/>
<el-input v-model="item.address" placeholder="现居地" class="mb-2"/>
<el-input v-model="item.company" placeholder="工作单位" class="mb-2"/>
<el-input v-model="item.job" placeholder="职务" class="mb-2"/>
<el-button v-if="form.familyList.length > 1" @click="form.familyList.splice(index, 1)" type="danger" size="small" icon="el-icon-delete">删除</el-button>
</el-form-item>
</div>
<el-button @click="form.familyList.push({relation:'',name:'',age:'',address:'',company:'',job:''})" type="primary" size="small" icon="el-icon-plus">添加家庭成员</el-button>
</div>
<!-- 教育培训经历 -->
<div class="form-section">
<h3 class="section-title">教育培训经历</h3>
<div v-for="(item, index) in form.educationList" :key="index" class="family-item">
<el-form-item :label="'经历' + (index + 1)" class="family-member">
<el-input v-model="item.start" placeholder="起止时间" class="mb-2"/>
<el-input v-model="item.school" placeholder="学校/培训机构名称" class="mb-2"/>
<el-input v-model="item.major" placeholder="专业/培训内容" class="mb-2"/>
<el-input v-model="item.certificate" placeholder="学历证书" class="mb-2"/>
<el-input v-model="item.remark" placeholder="备注" class="mb-2"/>
<el-button v-if="form.educationList.length > 1" @click="form.educationList.splice(index, 1)" type="danger" size="small" icon="el-icon-delete">删除</el-button>
</el-form-item>
</div>
<el-button @click="form.educationList.push({start:'',school:'',major:'',certificate:'',remark:''})" type="primary" size="small" icon="el-icon-plus">添加培训经历</el-button>
</div>
<!-- 主要工作经历 -->
<div class="form-section">
<h3 class="section-title">主要工作经历</h3>
<div v-for="(item, index) in form.workList" :key="index" class="family-item">
<el-form-item :label="'工作经历' + (index + 1)" class="family-member">
<el-input v-model="item.start" placeholder="起止时间" class="mb-2"/>
<el-input v-model="item.company" placeholder="工作单位" class="mb-2"/>
<el-input v-model="item.position" placeholder="工作岗位" class="mb-2"/>
<el-input v-model="item.content" placeholder="工作内容" class="mb-2"/>
<el-input v-model="item.salary" placeholder="薪资水平" class="mb-2"/>
<el-input v-model="item.reason" placeholder="离职原因" class="mb-2"/>
<el-button v-if="form.workList.length > 1" @click="form.workList.splice(index, 1)" type="danger" size="small" icon="el-icon-delete">删除</el-button>
</el-form-item>
</div>
<el-button @click="form.workList.push({start:'',company:'',position:'',content:'',salary:'',reason:''})" type="primary" size="small" icon="el-icon-plus">添加工作经历</el-button>
</div>
<!-- 应聘渠道 -->
<div class="form-section">
<h3 class="section-title">应聘渠道</h3>
<el-form-item label="外部渠道">
<div class="channel-options">
<el-checkbox v-model="form.channelJobFair">人才招聘会</el-checkbox>
<el-checkbox v-model="form.channelWebsite">招聘网站</el-checkbox>
<el-checkbox v-model="form.channelFriend">朋友推荐</el-checkbox>
<el-checkbox v-model="form.channelOther">其他</el-checkbox>
</div>
</el-form-item>
<el-form-item label="介绍人" prop="referrer">
<el-input v-model="form.referrer" placeholder="请输入介绍人"/>
</el-form-item>
<el-form-item label="关系" prop="referrerRelation">
<el-input v-model="form.referrerRelation" placeholder="请输入关系"/>
</el-form-item>
<el-form-item label="职务" prop="referrerJob">
<el-input v-model="form.referrerJob" placeholder="请输入职务"/>
</el-form-item>
</div>
<!-- 提交按钮 -->
<div class="form-actions">
<el-button type="primary" @click="submitForm" class="submit-btn">提交</el-button>
<el-button @click="resetForm" class="reset-btn">重置</el-button>
</div>
<!-- 承诺声明 -->
<div class="promise-section">
<h3 class="section-title">承诺声明</h3>
<div class="promise-content">
<p class="promise-item">1. 以上内容必须逐项真实填写公司行政人事部有权进行调查了解如提供虚假信息公司有权作辞退处理</p>
<p class="promise-item">2. 本人已知悉公司面试同意仅为初步录用需参加准员工培训并考核合格才正式录用</p>
<p class="promise-item">3. 本人入职前无任何不良行为或触犯法律的记录</p>
</div>
<el-checkbox v-model="form.promiseAgreed" class="promise-checkbox">我已阅读并同意以上承诺声明</el-checkbox>
</div>
</el-form>
</div>
</template>
<script>
import { addInterviewer } from '@/api/personnelMatters/interviewer'
import { getDicts } from "@/api/system/dict/data";
export default {
name: 'FillForm',
data() {
return {
//
loading: true,
//
title: "",
//
open: false,
//
educationOptions: [],
form: {
department: '',
post: '',
salary: '',
fillDate: '',
name: '',
gender: '',
birth: '',
nation: '',
maritalStatus: '',
politicalStatus: '',
idCard: '',
jobStatus: '',
education: '',
major: '',
school: '',
degree: '',
title: '',
arrivalDate: '',
registeredAddress: '',
currentAddress: '',
phone: '',
educationList: [{start:'',school:'',major:'',certificate:'',remark:''}],
workList: [{start:'',company:'',position:'',content:'',salary:'',reason:''}],
familyList: [{relation:'',name:'',age:'',address:'',company:'',job:''}],
channelJobFair: false,
channelWebsite: false,
channelFriend: false,
channelOther: false,
referrer: '',
referrerRelation: '',
referrerJob: '',
promiseAgreed: false
},
rules: {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
department: [{ required: true, message: '请输入应聘部门', trigger: 'blur' }],
post: [{ required: true, message: '请输入应聘岗位', trigger: 'blur' }],
promiseAgreed: [{ required: true, message: '请阅读并同意承诺声明', trigger: 'change' }]
}
}
},
created() {
this.getDicts("sys_level").then(response => {
this.educationOptions = response.data;
});
},
methods: {
submitForm() {
this.$refs.registerForm.validate(valid => {
if (valid) {
if (!this.form.promiseAgreed) {
this.$message.warning('请阅读并同意承诺声明');
return;
}
// JSON
const fromData = {
...this.form,
submitTime: new Date().toISOString(), //
fromData: JSON.stringify(this.form) //
};
addInterviewer(fromData).then(res => {
this.$message.success('提交成功');
this.resetForm();
}).catch(() => {
this.$message.error('提交失败');
});
}
});
},
resetForm() {
this.$refs.registerForm.resetFields();
this.form.educationList = [{start:'',school:'',major:'',certificate:'',remark:''}];
this.form.workList = [{start:'',company:'',position:'',content:'',salary:'',reason:''}];
this.form.familyList = [{relation:'',name:'',age:'',address:'',company:'',job:''}];
this.form.promiseAgreed = false;
}
}
}
</script>
<style scoped>
.app-container {
max-width: 100%;
margin: 0 auto;
background: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px #eee;
}
.form-title {
text-align: center;
margin-bottom: 30px;
font-size: 1.5rem;
color: #333;
}
.section-title {
font-size: 1.2rem;
color: #409EFF;
margin: 20px 0;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.form-section {
margin-bottom: 30px;
padding: 15px;
background: #f9f9f9;
border-radius: 8px;
}
.mobile-form {
width: 100%;
}
.mobile-form .el-form-item {
margin-bottom: 20px;
}
.mobile-form .el-input,
.mobile-form .el-select,
.mobile-form .el-date-picker {
width: 100%;
}
.family-item {
background: #fff;
padding: 15px;
margin-bottom: 15px;
border-radius: 4px;
border: 1px solid #eee;
}
.family-member {
margin-bottom: 10px;
}
.mb-2 {
margin-bottom: 10px;
}
.channel-options {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.form-actions {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 30px;
}
.submit-btn,
.reset-btn {
min-width: 120px;
}
.promise-section {
margin-top: 30px;
padding: 20px;
background: #f8f8f8;
border-radius: 8px;
border: 1px solid #e8e8e8;
}
.promise-content {
margin: 15px 0;
padding: 15px;
background: #fff;
border-radius: 4px;
border: 1px solid #eee;
}
.promise-item {
margin-bottom: 12px;
line-height: 1.6;
color: #333;
font-size: 14px;
position: relative;
padding-left: 20px;
}
.promise-item:last-child {
margin-bottom: 0;
}
.promise-item::before {
content: "•";
position: absolute;
left: 0;
color: #409EFF;
font-weight: bold;
}
.promise-checkbox {
display: block;
margin-top: 15px;
font-weight: bold;
color: #409EFF;
}
@media screen and (max-width: 768px) {
.app-container {
padding: 15px;
}
.form-title {
font-size: 1.3rem;
margin-bottom: 20px;
}
.section-title {
font-size: 1.1rem;
}
.form-section {
padding: 10px;
}
.mobile-form .el-form-item {
margin-bottom: 15px;
}
.form-actions {
flex-direction: column;
gap: 10px;
}
.submit-btn,
.reset-btn {
width: 100%;
}
.promise-section {
padding: 15px;
}
.promise-content {
padding: 10px;
}
.promise-item {
font-size: 13px;
padding-left: 15px;
}
}
</style>

View File

@ -76,6 +76,12 @@
<el-table-column label="备注" align="center" prop="remarks" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="text"
size="small"
icon="el-icon-view"
@click="handlePreview(scope.row)"
v-hasPermi="['tool:gen:preview']"
>预览</el-button>
<el-button
size="mini"
type="text"
@ -101,7 +107,168 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 预览界面 -->
<el-dialog :title="preview.title" :visible.sync="preview.open" width="900px" top="5vh" append-to-body>
<div v-loading="preview.loading" class="resume-preview">
<div class="print-header">
<h2 style="text-align:center;">应聘登记表</h2>
<el-button type="primary" icon="el-icon-printer" @click="handlePrint" style="margin-bottom: 10px;">打印</el-button>
</div>
<div id="printContent">
<table class="resume-table" border="1" cellspacing="0" cellpadding="4" style="width:100%;border-collapse:collapse;border:2px solid #000">
<!-- 头部信息 -->
<tr>
<td colspan="2">应聘部门{{ preview.data.department }}</td>
<td colspan="2">应聘岗位{{ preview.data.post }}</td>
<td colspan="2">期望薪资{{ preview.data.salary }}</td>
<td colspan="2">填表日期{{ preview.data.fillDate }}</td>
</tr>
<!-- 基本信息 -->
<tr>
<td width="10%">姓名</td>
<td width="15%">{{ preview.data.name }}</td>
<td width="8%">性别</td>
<td width="10%">{{ preview.data.gender }}</td>
<td width="12%">出生年月</td>
<td width="15%">{{ preview.data.birth }}</td>
<td width="8%">民族</td>
<td width="12%">{{ preview.data.nation }}</td>
</tr>
<!-- 目前工作状况 -->
<tr>
<td>目前工作状况</td>
<td colspan="7">{{ preview.data.jobStatus }}</td>
</tr>
<!-- 第二段信息 -->
<tr>
<td>婚姻情况</td>
<td>{{ preview.data.maritalStatus }}</td>
<td>政治面貌</td>
<td>{{ preview.data.politicalStatus }}</td>
<td>身份证号</td>
<td colspan="3">{{ preview.data.idCard }}</td>
</tr>
<tr>
<td>最高学历</td>
<td>{{ preview.data.education }}</td>
<td>专业</td>
<td>{{ preview.data.major }}</td>
<td>毕业学校</td>
<td colspan="3">{{ preview.data.school }}</td>
</tr>
<tr>
<td>学位</td>
<td>{{ preview.data.degree }}</td>
<td>职称</td>
<td>{{ preview.data.title }}</td>
<td>到岗时间</td>
<td colspan="3">{{ preview.data.arrivalDate }}</td>
</tr>
<tr>
<td>户口所在地详细地址</td>
<td colspan="7">{{ preview.data.registeredAddress }}</td>
</tr>
<tr>
<td>现居住地址</td>
<td colspan="4">{{ preview.data.currentAddress }}</td>
<td>联系电话</td>
<td colspan="2">{{ preview.data.phone }}</td>
</tr>
<!-- 教育培训经历 -->
<tr>
<td :rowspan="4">教育<br>培训<br>经历</td>
<td>起止时间</td>
<td>学校/培训机构名称</td>
<td>专业/培训内容</td>
<td>学历/证书</td>
<td colspan="3">备注</td>
</tr>
<tr v-for="i in 3" :key="'edu'+i">
<td>{{ preview.data.educationList[i-1] ? preview.data.educationList[i-1].start : '' }}</td>
<td>{{ preview.data.educationList[i-1] ? preview.data.educationList[i-1].school : '' }}</td>
<td>{{ preview.data.educationList[i-1] ? preview.data.educationList[i-1].major : '' }}</td>
<td>{{ preview.data.educationList[i-1] ? preview.data.educationList[i-1].certificate : '' }}</td>
<td colspan="3">{{ preview.data.educationList[i-1] ? preview.data.educationList[i-1].remark : '' }}</td>
</tr>
<!-- 主要工作经历 -->
<tr>
<td rowspan="4">主要<br>工作<br>经历</td>
<td>起止时间</td>
<td>工作单位</td>
<td>工作岗位</td>
<td colspan="2">工作内容</td>
<td>薪资水平</td>
<td>离职原因</td>
</tr>
<tr v-for="i in 3" :key="'work'+i">
<td>{{ preview.data.workList[i-1] ? preview.data.workList[i-1].start : '' }}</td>
<td>{{ preview.data.workList[i-1] ? preview.data.workList[i-1].company : '' }}</td>
<td>{{ preview.data.workList[i-1] ? preview.data.workList[i-1].position : '' }}</td>
<td colspan="2">{{ preview.data.workList[i-1] ? preview.data.workList[i-1].content : '' }}</td>
<td>{{ preview.data.workList[i-1] ? preview.data.workList[i-1].salary : '' }}</td>
<td>{{ preview.data.workList[i-1] ? preview.data.workList[i-1].reason : '' }}</td>
</tr>
<!-- 家庭成员 -->
<tr>
<td :rowspan="4">家庭成员</td>
<td>称谓</td>
<td>姓名</td>
<td>年龄</td>
<td colspan="2">现居地</td>
<td>工作单位</td>
<td>职务</td>
</tr>
<tr v-for="i in 3" :key="'family'+i">
<td>{{ preview.data.familyList[i-1] ? preview.data.familyList[i-1].relation : '' }}</td>
<td>{{ preview.data.familyList[i-1] ? preview.data.familyList[i-1].name : '' }}</td>
<td>{{ preview.data.familyList[i-1] ? preview.data.familyList[i-1].age : '' }}</td>
<td colspan="2">{{ preview.data.familyList[i-1] ? preview.data.familyList[i-1].address : '' }}</td>
<td>{{ preview.data.familyList[i-1] ? preview.data.familyList[i-1].company : '' }}</td>
<td>{{ preview.data.familyList[i-1] ? preview.data.familyList[i-1].job : '' }}</td>
</tr>
<!-- 应聘渠道 -->
<tr>
<td colspan="8" style="height: 40px;">
<div style="display: flex; align-items: center; height: 100%;">
<span style="margin-right: 20px;">应聘渠道</span>
<el-checkbox v-model="preview.data.channelJobFair" disabled>人才招聘会</el-checkbox>
<el-checkbox v-model="preview.data.channelWebsite" disabled>招聘网站</el-checkbox>
<el-checkbox v-model="preview.data.channelFriend" disabled>朋友推荐</el-checkbox>
<el-checkbox v-model="preview.data.channelOther" disabled>其他渠道</el-checkbox>
</div>
</td>
</tr>
<!-- 介绍人信息 -->
<tr>
<td colspan="8" style="height: 40px;">
<div style="display: flex; align-items: center; height: 100%;">
<span style="margin-right: 20px;">介绍人{{ preview.data.referrer || '' }}</span>
<span style="margin-right: 20px;">关系{{ preview.data.referrerRelation || '' }}</span>
<span>职务{{ preview.data.referrerJob || '' }}</span>
</div>
</td>
</tr>
<!-- 承诺部分 -->
<tr>
<td colspan="8" style="text-align:left;padding:10px; height: 40px;">
<b>本人承诺</b><br>
1. 以上内容必须逐项真实填写公司行政人事部有权进行调查了解如提供虚假信息公司有权作辞退处理<br>
2. 本人已知悉公司面试同意仅为初步录用需参加准员工培训并考核合格才正式录用<br>
3. 本人入职前无任何不良行为或触犯法律的记录
</td>
</tr>
<!-- 签名 -->
<tr>
<td colspan="4" style="height: 40px;">签名__________</td>
<td colspan="4" style="height: 40px;">日期__________</td>
</tr>
</table>
</div>
</div>
</el-dialog>
<!-- 添加或修改面试信息对话框 -->
<el-dialog :title="title" v-dialog-drag :visible.sync="open" width="680px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="98px">
@ -179,6 +346,46 @@ export default {
name: "Interviewer",
data() {
return {
//
preview: {
open: false,
title: "应聘登记表预览",
loading: false,
data: {
department: '',
post: '',
salary: '',
fillDate: '',
name: '',
gender: '',
birth: '',
nation: '',
maritalStatus: '',
politicalStatus: '',
idCard: '',
jobStatus: '',
education: '',
major: '',
school: '',
degree: '',
title: '',
arrivalDate: '',
registeredAddress: '',
currentAddress: '',
phone: '',
educationList: [],
workList: [],
familyList: [],
channelJobFair: false,
channelWebsite: false,
channelFriend: false,
channelOther: false,
referrer: '',
referrerRelation: '',
referrerJob: '',
promiseAgreed: false
}
},
//
loading: true,
//
@ -218,10 +425,104 @@ export default {
this.getList();
},
methods: {
/** 预览按钮 */
handlePreview(row) {
this.preview.loading = true;
this.preview.open = true;
//
getInterviewer(row.id).then(response => {
if (response.code === 200 && response.data) {
try {
// JSON
const formData = JSON.parse(response.data.fromData);
//
/* if (!this.validateFormData(formData)) {
this.$message.error('数据格式不正确,请检查');
this.preview.open = false;
return;
} */
//
this.preview.data = {
department: formData.department || '',
post: formData.post || '',
salary: formData.salary || '',
fillDate: formData.fillDate || '',
name: formData.name || '',
gender: formData.gender || '',
birth: formData.birth || '',
nation: formData.nation || '',
maritalStatus: formData.maritalStatus || '',
politicalStatus: formData.politicalStatus || '',
idCard: formData.idCard || '',
jobStatus: formData.jobStatus || '',
education: formData.education || '',
major: formData.major || '',
school: formData.school || '',
degree: formData.degree || '',
title: formData.title || '',
arrivalDate: formData.arrivalDate || '',
registeredAddress: formData.registeredAddress || '',
currentAddress: formData.currentAddress || '',
phone: formData.phone || '',
educationList: Array.isArray(formData.educationList) ? formData.educationList : [],
workList: Array.isArray(formData.workList) ? formData.workList : [],
familyList: Array.isArray(formData.familyList) ? formData.familyList : [],
channelJobFair: !!formData.channelJobFair,
channelWebsite: !!formData.channelWebsite,
channelFriend: !!formData.channelFriend,
channelOther: !!formData.channelOther,
referrer: formData.referrer || '',
referrerRelation: formData.referrerRelation || '',
referrerJob: formData.referrerJob || '',
promiseAgreed: !!formData.promiseAgreed
};
} catch (error) {
this.$message.error('数据解析失败:' + error.message);
this.preview.open = false;
}
} else {
this.$message.error(response.msg || '获取数据失败');
this.preview.open = false;
}
}).catch(error => {
this.$message.error('获取数据失败:' + error.message);
this.preview.open = false;
}).finally(() => {
this.preview.loading = false;
});
},
/** 验证表单数据 */
validateFormData(data) {
//
const requiredFields = ['name', 'gender', 'phone', 'post'];
for (const field of requiredFields) {
if (!data[field]) {
return false;
}
}
//
if (data.educationList && !Array.isArray(data.educationList)) {
return false;
}
if (data.workList && !Array.isArray(data.workList)) {
return false;
}
if (data.familyList && !Array.isArray(data.familyList)) {
return false;
}
return true;
},
/** 查询面试信息列表 */
getList() {
this.loading = true;
listInterviewer(this.queryParams).then(response => {
console.log("===================="+this.interviewerList);
this.interviewerList = response.rows;
this.total = response.total;
this.loading = false;
@ -315,7 +616,245 @@ export default {
this.download('system/interviewer/export', {
...this.queryParams
}, `interviewer_${new Date().getTime()}.xlsx`)
}
},
/** 打印功能 */
handlePrint() {
//
const printWindow = window.open('', '_blank');
if (!printWindow) {
this.$message.error('请允许浏览器打开新窗口');
return;
}
//
const printContent = document.getElementById('printContent').innerHTML;
//
const printHtml = `
<!DOCTYPE html>
<html>
<head>
<title>应聘登记表</title>
<style>
@page {
size: A4;
margin: 0.3cm;
}
body {
margin: 0;
padding: 0;
font-family: "Microsoft YaHei", sans-serif;
font-size: 12px;
width: 100%;
}
.print-title {
text-align: center;
font-size: 16px;
font-weight: bold;
margin: 2px 0 5px 0;
padding: 0;
}
.resume-table {
width: 100%;
border-collapse: collapse;
border: 1px solid #000;
margin: 0;
padding: 0;
table-layout: fixed;
}
.resume-table td {
padding: 3px 4px;
border: 1px solid #000;
vertical-align: middle;
line-height: 1.3;
word-break: break-all;
height: 28px;
}
.resume-table tr {
height: 28px;
}
.resume-table tr:nth-child(even) {
background-color: #f8f9fa;
}
/* 设置列宽 */
.resume-table td:nth-child(1) { width: 10%; }
.resume-table td:nth-child(2) { width: 15%; }
.resume-table td:nth-child(3) { width: 10%; }
.resume-table td:nth-child(4) { width: 15%; }
.resume-table td:nth-child(5) { width: 12%; }
.resume-table td:nth-child(6) { width: 15%; }
.resume-table td:nth-child(7) { width: 8%; }
.resume-table td:nth-child(8) { width: 15%; }
/* 应聘渠道和介绍人信息样式 */
.info-row {
height: 28px !important;
padding: 2px 6px !important;
}
.info-row span {
margin-right: 12px;
}
.checkbox-group {
display: inline-flex;
align-items: center;
gap: 12px;
}
.checkbox-item {
display: inline-flex;
align-items: center;
}
.checkbox-item input[type="checkbox"] {
margin-right: 3px;
}
@media print {
body {
padding: 0;
margin: 0;
width: 100%;
}
.resume-table {
page-break-inside: avoid;
width: 100%;
border: 1px solid #000 !important;
}
.resume-table tr {
page-break-inside: avoid;
page-break-after: auto;
height: 28px;
}
.resume-table td {
padding: 3px 4px;
height: 28px;
border: 1px solid #000 !important;
}
/* 确保表格占满页面宽度 */
.resume-table, .resume-table td {
width: 100% !important;
}
/* 隐藏复选框的默认样式 */
input[type="checkbox"] {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
</style>
</head>
<body>
<h1 class="print-title">应聘登记表</h1>
${printContent}
</body>
</html>
`;
//
printWindow.document.write(printHtml);
printWindow.document.close();
//
printWindow.onload = function() {
printWindow.print();
//
printWindow.onafterprint = function() {
printWindow.close();
};
};
},
}
};
</script>
<style scoped>
.interview-preview-form .el-form-item {
margin-bottom: 10px;
}
.resume-preview .el-row {
margin-bottom: 8px;
}
.resume-preview .el-divider {
margin: 18px 0 10px 0;
}
.resume-table td {
padding: 6px;
border: 1px solid #666;
vertical-align: middle;
min-height: 28px;
}
.resume-table tr {
height: 28px;
}
/* 应聘渠道和介绍人信息样式 */
.info-row {
height: 28px !important;
padding: 2px 6px !important;
}
.info-row span {
margin-right: 12px;
}
.checkbox-group {
display: inline-flex;
align-items: center;
gap: 12px;
}
.checkbox-item {
display: inline-flex;
align-items: center;
}
.checkbox-item input[type="checkbox"] {
margin-right: 3px;
}
.print-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
@media print {
/* 打印样式 */
.el-dialog__header,
.el-dialog__footer,
.print-header .el-button {
display: none !important;
}
.el-dialog {
position: absolute;
left: 0;
top: 0;
margin: 0;
padding: 0;
width: 100% !important;
}
.el-dialog__body {
padding: 0;
}
.resume-preview {
padding: 5px;
}
.resume-table {
page-break-inside: auto;
width: 100% !important;
}
.resume-table tr {
page-break-inside: avoid;
page-break-after: auto;
}
.resume-table td {
padding: 3px 4px;
min-height: 28px;
}
}
</style>

View File

@ -34,17 +34,31 @@
<el-table-column label="员工姓名" align="center" prop="name" />
<el-table-column label="照片地址" align="center" prop="imageUrl">
<template slot-scope="scope">
<el-link :href="scope.row.imageUrl" :underline="false" target="_blank">查看图片</el-link>
<el-image
style="width: 100px; height: 100px"
:src="scope.row.imageUrl"
:preview-src-list="[scope.row.imageUrl]"
fit="cover"
>
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-upload"
@click="handleUpload(scope.row)"
>上传</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['equipment:images:remove']"
>删除</el-button>
</template>
</el-table-column>
@ -58,22 +72,32 @@
@pagination="getList"
/>
<!-- 添加照片管理对话框 -->
<el-dialog :title="title" v-dialog-drag :visible.sync="open" width="400px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="98px">
<el-form-item label="姓名:" prop="name">
<el-input
v-model="form.name"
placeholder="请输入姓名"
clearable
@keyup.enter.native="handleQuery"
/>
<!-- 上传图片对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="员工照片:" prop="imageUrl">
<input type="file" @change="uploadDispatchings" />
<el-form-item label="照片">
<el-upload
class="upload-demo"
:action="upload.url"
:headers="upload.headers"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload"
:file-list="fileList"
:data="form"
list-type="picture"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过2MB</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitUpload"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
@ -81,7 +105,9 @@
</template>
<script>
import { listImages, delImages,uploadDispatchingFile } from "@/api/restaurant/images";
import { listImages, delImages, uploadDispatchingFile } from "@/api/restaurant/images";
import { getToken } from "@/utils/auth";
export default {
name: "Images",
data() {
@ -105,13 +131,28 @@ export default {
name: null,
},
//
form: {},
form: {
id: undefined,
name: undefined,
imageUrl: undefined
},
//
rules: {
name: [
{ required: true, message: "姓名不能为空", trigger: "blur" }
],
}
]
},
//
upload: {
//
url: process.env.VUE_APP_BASE_API + "/restaurant/images/upload",
//
headers: { Authorization: "Bearer " + getToken() }
},
//
fileList: [],
//
currentRow: null
};
},
created() {
@ -135,9 +176,11 @@ export default {
/** 表单重置 */
reset() {
this.form = {
name: null,
imageUrl: null,
id: undefined,
name: undefined,
imageUrl: undefined
};
this.fileList = [];
this.resetForm("form");
},
/** 搜索按钮操作 */
@ -154,37 +197,96 @@ export default {
handleAdd() {
this.reset();
this.open = true;
this.title = "添加照片管理";
this.title = "添加照片";
},
/** 上传按钮操作 */
handleUpload(row) {
this.reset();
this.form = { ...row };
this.currentRow = row;
this.open = true;
this.title = "修改照片";
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除姓名为"' + row.name + '"的数据项?').then(function() {
this.$modal.confirm('是否确认删除该图片').then(() => {
return delImages(row.id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 员工照片上传 */
uploadDispatchings(event) {
let file = event.target.files[0];
var formData = new FormData();
formData.append("file", file);
formData.append("name", this.form.name);
uploadDispatchingFile(formData).then(res => {
if (res.code == 200) {
this.$modal.msgSuccess("上传成功");
this.open = false;
this.getList();
} else {
this.$modal.msgSuccess("上传失败");
this.open = false;
this.getList();
/** 文件上传成功处理 */
handleSuccess(response, file, fileList) {
if (response.code === 200) {
this.form.imageUrl = response.data;
this.$modal.msgSuccess("上传成功");
this.getList();
this.open = false;
} else {
this.$modal.msgError(response.msg || "上传失败");
}
},
/** 文件上传前的处理 */
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传图片只能是 JPG/PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
},
/** 文件列表移除时的钩子 */
handleRemove(file, fileList) {
this.fileList = fileList;
},
/** 点击文件列表中已上传的文件时的钩子 */
handlePreview(file) {
window.open(file.url);
},
/** 提交上传 */
submitUpload() {
this.$refs["form"].validate(valid => {
if (valid) {
if (!this.form.imageUrl) {
this.$modal.msgError("请先上传图片");
return;
}
if (this.form.id) {
//
uploadDispatchingFile(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
//
uploadDispatchingFile(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
}
}
};
</script>
<style scoped>
.image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #f5f7fa;
color: #909399;
font-size: 30px;
}
</style>

View File

@ -59,6 +59,18 @@
<el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
<el-table-column prop="leader" label="负责人" width="260"></el-table-column>
<el-table-column prop="phone" label="联系电话" width="260"></el-table-column>
<el-table-column prop="isOverTime" label="是否加班" width="260">
<template slot-scope="scope">
<el-switch
v-model="scope.row.isOverTime"
:active-value="1"
:inactive-value="0"
active-text="是"
inactive-text="否"
@change="handleIsOverTimeChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
@ -137,6 +149,16 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="是否加班" prop="isOverTime">
<el-radio-group v-model="form.isOverTime">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
@ -176,7 +198,8 @@ export default {
//
queryParams: {
deptName: undefined,
status: undefined
status: undefined,
isOverTime: undefined
},
//
form: {},
@ -203,7 +226,12 @@ export default {
getList() {
this.loading = true;
listDept(this.queryParams).then(response => {
this.deptList = this.handleTree(response.data, "deptId");
// isOverTime
const data = response.data.map(item => ({
...item,
isOverTime: Number(item.isOverTime)
}));
this.deptList = this.handleTree(data, "deptId");
this.loading = false;
});
},
@ -231,6 +259,7 @@ export default {
deptName: undefined,
leader: undefined,
phone: undefined,
isOverTime: 0,
status: "0"
};
this.resetForm("form");
@ -269,6 +298,9 @@ export default {
this.reset();
getDept(row.deptId).then(response => {
this.form = response.data;
// isOverTime
this.form.isOverTime = Number(this.form.isOverTime);
console.log('修改表单数据:', this.form);
this.open = true;
this.title = "修改部门";
listDeptExcludeChild(row.deptId).then(response => {
@ -308,6 +340,18 @@ export default {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 修改是否加班状态 */
handleIsOverTimeChange(row) {
updateDept(row).then(() => {
this.$modal.msgSuccess("修改成功");
//
if (this.form.deptId === row.deptId) {
this.form.isOverTime = row.isOverTime;
}
}).catch(() => {
row.isOverTime = row.isOverTime === 1 ? 0 : 1;
});
}
}
};

View File

@ -38,6 +38,7 @@
<el-table-column label="本年累计专项附加扣除" align="center" prop="specialDeduction" />
<el-table-column label="本年累计已发工资" align="center" prop="totalWages" />
<el-table-column label="本年累计已缴个税" align="center" prop="aggregatePersonalIncomeTax" />
<el-table-column label="销售提成" align="center" prop="salesCommission" />
<el-table-column label="备注" align="center" prop="remarks" />
<el-table-column label="操作" align="center" fixed="right" width="100" class-name="small-padding fixed-width">
<template slot-scope="scope">
@ -277,6 +278,7 @@ export default {
specialDeduction: null,
totalWages: null,
aggregatePersonalIncomeTax: null,
salesCommission:null,
remarks: null,
};
this.resetForm("form");