[Java开发]搭建人力资源管理系统——简历管理模块(附带下载链接)
最近一位老哥让我给他的公司开发一套人力资源管理系统,并详细描述了这个系统的一些功能,我也查找了一些人力资源的资料。因为跟老哥关系不错,就答应了他。大家都知道,人力资源管理就是管人的,从给公司开始投递简历到从公司离职,员工的方方面面都要受控,那么我们来根据这个前提,看看系统的整体规划:
- 简历管理模块
- 员工管理模块
- 员工异动管理模块
- 员工考勤管理模块
- 薪酬管理模块
- 合同管理模块
- 系统管理模块
提示:开发该系统前,先掌握后端Java语言及SpringBoot基本原理和Html语言及Vue框架和AntDesignVUE组件的基本操作方法,并掌握基本SQL语句的编写。
如果不太会,也可参考本文查漏补缺。
一、简历管理模块
我们先看一下最终的效果:
老哥的需求是:人们通过手机扫码填报简历,hr筛选留下合格简历入库,并保留合适的简历作为备用资源。所以将该模块分为4个菜单(新投简历、暂存简历、简历库、回收站)和一个手机页面(填写简历)。开发前先进行一些准备工作:
1、搭建开发环境
我们使用开源的jeecg框架和mysql数据库进行开发,需安装7个基础程序: jdk、node.js、mysql、 redis、webstorm、idea、navicat,具体的安装过程网络上有很多。我们将 jeecg源码解压后,用webstorm打开前端源码,运行yarn安装依赖包及配置运行环境;用idea打开后端源码,在application-dev.yml配置文件内配好数据库及redis密码。用navicat新建数据库并导入源码内提供的初始化jeecg-boot.sql文件。前后端成功运行后点击webstorm控制台提示的浏览地址,能成功打开登录页面并刷出验证码表明运行成功。正式进入模块开发环节。
2、数据字段设计
我们根据需求,对字段进行初期设计。简历包含人员基础信息、工作经历、评取职称、考取证书、获得荣誉等内容,因为一个人会有多个工作经历,多个证书荣誉,所以数据库表设计是标准的一对多设计。详细的字段如下。
tb_resume_list[人员简历表] 因为由Jeecg生成,所以没有加ID主键,可以参考Jeecg官方的[online表单]开发说明
字段名 | 字段类型 | 注释 | 字典 |
---|---|---|---|
resume_name | varchar | 姓名 | 否 |
resume_pic | varchar | 照片 | 否 |
resume_sfz | varchar | 身份证号码 | 否 |
resume_sex | varchar | 性别 | 否 |
resume_minzu | tinyint | 民族 | 是 |
resume_age | varchar | 年龄 | 否 |
resume_birthday | datetime | 出生日期 | 否 |
resume_tel | varchar | 电话 | 否 |
resume_address | varchar | 家庭住址 | 否 |
resume_qqwx | varchar | QQ或者微信号 | 否 |
resume_email | varchar | 电子邮箱 | 否 |
resume_party | tinyint | 政治面貌 | 是 |
resume_edu_college | varchar | 毕业院校 | 否 |
resume_edu_major | varchar | 主修专业 | 否 |
resume_edu_end_date | datetime | 毕业时间 | 否 |
resume_edu_background | tinyint | 学历 | 是 |
resume_edu_degree | tinyint | 学位 | 是 |
resume_memo | varchar | 备注 | 否 |
resume_is_read | tinyint | 已读未读 | 是 |
resume_is_passed | tinyint | 是否通过 | 是 |
resume_is_del | tinyint | 是否删除 | 是 |
resume_is_employee | tinyint | 是否入职 | 是 |
tb_career_info[人员工作经历表]
字段名 | 字段类型 | 注释 |
---|---|---|
id | int | ID |
person_id | varchar | 对应人员ID |
career_date | varchar | 前工作日期 |
career_unit | varchar | 前工作单位 |
career_post | varchar | 前工作职务 |
career_leave_reason | varchar | 离职原因 |
tb_certificate_info[人员考取证书表]
字段名 | 字段类型 | 注释 |
---|---|---|
id | int | ID |
person_id | varchar | 对应人员ID |
certificate | varchar | 资格证书名称 |
tb_honour_info[人员获得荣誉表]
字段名 | 字段类型 | 注释 |
---|---|---|
id | int | ID |
person_id | varchar | 对应人员ID |
honour | varchar | 荣誉名称 |
tb_professional_info[人员取得的职称表]
字段名 | 字段类型 | 注释 |
---|---|---|
id | int | ID |
person_id | varchar | 对应人员ID |
professional | varchar | 职称名称 |
3、代码开发
增加字典数据
根据设计好的字段添加字典数据。登录系统后打开[数据字典]菜单增加稍后用到的字典。先增加字典名称。
再点击[字典配置],添加字典项
在线表单设计
打开online表单设计菜单,填入对应的字段名称,
同步数据库及代码生成
点击同步数据库,系统会自动在数据库中将表建好。点击代码生成按钮,填入对应的参数,系统自动生成前后端分离的代码。
代码拷贝
方便我们快速开发。紧接着,我们在后端Java代码的modules文件夹及前端Vue代码的view文件夹内新建hr文件夹,并在此文件夹内各自新建resume文件夹,代表这是人资管理系统的简历管理模块。将 controller、entity、mapper、service文件夹拷入后端resume文件夹内,vue文件夹内的所有文件拷入前端resume文件夹内,这时,树形结构为这样。
增加菜单
重启程序进入系统,点击菜单管理,增加简历管理及它的下级新投简历两个菜单,填入相应信息。组件就是*.vue这个文件的路径,路径名从 view开始填写。
二级菜单路径和组件都为[/modules/hr/resume/TbResumeNewList]
增加授权
打开角色管理菜单内admin角色的授权按钮后,选中新增的菜单后刷新页面
增加成功
菜单出现了,点击后能看到对应的空表格。
4、手机端填写简历页面开发
手机端我们使用vant2作为组件库,安装及引用方法参考官网。
https://vant-contrib.gitee.io/vant/v2/#/zh-CN/quickstart
由于应聘者的不确定性,无法让其登录系统后再填报,所以填报页面设计为不登录填报,需要在前端添加免登录白名单。
1)添加页面
在前端modules文件夹内,添加与hr平级的mobile文件夹及子文件夹resume。并新增两个vue组件:NewResumeByPhone.vue及OK.vue
页面效果:
->NewResumeByPhone.vue
该页面用到了<van-notice-bar>
<van-form>
<van-field>
<van-button>
以及我封装的两个日期选择picker组件 <ZDatePicker>
<ZDateRangePicker>
、一个字典选择picker组件<ZDictPicker>
和一个照片上传组件<ZVantUploader>
。
<van-field v-model="resumeName" name="resumeName" label="姓名" placeholder="请填入姓名" :required="required" :rules="rule" />
<ZDatePicker v-model="resumeBirthday" name="resumeBirthday" type="date" label="出生日期" placeholder="请选择出生日期" :minDate="new Date(new Date().getFullYear()-100, 0, 1)" :maxDate="new Date()" :required="required" :rules="rule"/>
<ZDateRangePicker v-model="careerInfos[index].career_date" :name="'career_date_'+index" label="任期范围" type="date" placeholder="请选择任期的时间范围" :required="required" :rules="careerRule"n:index="index" :minDate="new Date(new Date().getFullYear()-60, 0, 1)" :maxDate="new Date()" @confirm="rangeDataConfirm" @confirmToNow="rangeDataConfirmToNow"/>
<ZDictPicker v-model="resumeEduDegree" name="resumeEduDegree" label="学位" placeholder="请选择学位" dictCode="edu_degree" />
<ZVantUploader v-model="resumePic" name="resumePic" label="照片" :maxCount="1" :maxSize="1024*1024"/>
页面需要添加验证码,以防止机器填报
<van-field v-model="inputCode" name="inputCode" label="验证码" placeholder="请输入验证码" :required="required" :rules="rule" ><template #extra ><img v-if="requestCodeSuccess" style="height:24px;" :src="randCodeImage" @click="handleChangeCheckCode"/><img v-else style="height:24px;" src="../../../../assets/checkcode.png" @click="handleChangeCheckCode"/></template>
</van-field>
在提交时,需要将一对多的地段合并成一个表单项,用逗号分段
//javascript
onSubmit(values) {if(this.haveCareer){for(let i=0;i<this.careerInfos.length;i++){let careerDate = values["career_date_"+i];let careerUnit = this.careerInfos[i].career_unit;let careerPost = this.careerInfos[i].career_post;let careerLeaveReason = this.careerInfos[i].career_leave_reason;values["career_"+i] = careerDate + "," + careerUnit + "," + careerPost + "," + careerLeaveReason;delete values["career_date_"+i];delete values["career_unit_"+i];delete values["career_post_"+i];delete values["career_leave_reason_"+i];}}
}
->OK.vue
该页面为提交后的结果页面,很简单。
<template><div class="main"><van-icon name="passed" size="100" color="green"/><div><span class="hint_title">提报成功</span></div><div><span class="hint_sub_title">请等待工作人员的审核</span></div></div>
</template>
2)添加路径
在前端src/config/router.config.js文件内的constantRouterMap内增加/mobile/newResume及/mobile/newResumeOK的访问路径。
//javascript
export const constantRouterMap = [{path: '/mobile/newResume',component: () => import('@/views/modules/mobile/resume/NewResumeByPhone')},{path: '/mobile/newResumeOK',component: () => import('@/views/modules/mobile/resume/OK')},
]
3)添加白名单
在src/premission.js文件内增加此路径至白名单。
//javascript
const whiteList = ['/user/login', '/user/register', '/user/register-result','/user/alteration', '/mobile/newResume', '/mobile/newResumeOK']
5、后台交互逻辑代码
页面写好后,要提交数据至后台入库了。
在后端controller、mapper、service文件夹内新增对应的方法。需要注意的是,我们需要将工作经历、证书、荣誉、职称等内容在后端拆分后再分别录入到自己的数据表中。
->TbResumeListController.java
//Java代码块
/**
* 添加手机端数据
*
* @param pageMap
* @return
*/
@AutoLog(value = "简历表-添加")
@ApiOperation(value="简历表-添加", notes="简历表-添加")
@PostMapping(value = "/addNewResumeByPhone")
public Result<?> addNewResumeByPhone(@RequestBody Map<String, String> pageMap) {if(pageMap.size() > 0){//循环遍历Map然后,对不同的信息,放入到不同的数据表中.//判断验证码String captcha = pageMap.get("inputCode");if(captcha==null){return Result.error("验证码无效");}String lowerCaseCaptcha = captcha.toLowerCase();String realKey = MD5Util.MD5Encode(lowerCaseCaptcha+pageMap.get("currDatetime"), "utf-8");Object checkCode = redisUtil.get(realKey);if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {return Result.error("验证码错误");}//验证码判断完成//获得主键IDString id = SnowflakeIdUtils.getNextSnowflakeId()+"";Map<String, String> dbMap = new HashMap<>();for (Map.Entry<String, String> entry : pageMap.entrySet()) {System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());String val = entry.getValue();if(!"".equals(val.trim())) {if(entry.getKey().contains("professional")){tbResumeListService.insertProfessionalData(id, val);}else if(entry.getKey().contains("career")){String[] tempStr = val.split(",", -1); //参数-1是为了保留逗号后面的空值String careerDate = CommFun.nvl(tempStr[0], "");String careerUnit = CommFun.nvl(tempStr[1], "");String careerPost = CommFun.nvl(tempStr[2], "");String careerLevelReason = CommFun.nvl(tempStr[3], "暂未离职");tbResumeListService.insertCareerData(id, careerDate, careerUnit, careerPost, careerLevelReason);}else if(entry.getKey().contains("certificate")){tbResumeListService.insertCertificateData(id, val);}else if(entry.getKey().contains("honour")){tbResumeListService.insertHonourData(id, val);}else{dbMap.put(entry.getKey(), val);}}}dbMap.put("id",id);dbMap.put("resume_is_passed","1");TbResumeList tbResumeList = JSON.parseObject(JSON.toJSONString(dbMap), TbResumeList.class);tbResumeListService.save(tbResumeList);return Result.OK("操作成功!");}else{return Result.OK("添加失败!");}
}
->ITbResumeListService.java
public interface ITbResumeListService extends IService<TbResumeList> {int insertCareerData(String personID, String careerDate, String careerUnit, String careerPost, String careerLevelReason);int insertProfessionalData(String personID, String professional);int insertCertificateData(String personID, String certificate);int insertHonourData(String personID, String honour);
}
->TbResumeListServiceImpl.java
@Service
public class TbResumeListServiceImpl extends ServiceImpl<TbResumeListMapper, TbResumeList> implements ITbResumeListService {@Autowiredprivate TbResumeListMapper tbResumeListMapper;@Overridepublic int insertCareerData(String personID, String careerDate, String careerUnit, String careerPost, String careerLevelReason) {return tbResumeListMapper.insertCareerData(personID, careerDate, careerUnit, careerPost, careerLevelReason);}@Overridepublic int insertProfessionalData(String personID, String professional) {return tbResumeListMapper.insertProfessionalData(personID, professional);}@Overridepublic int insertCertificateData(String personID, String certificate) {return tbResumeListMapper.insertCertificateData(personID, certificate);}@Overridepublic int insertHonourData(String personID, String honour) {return tbResumeListMapper.insertHonourData(personID, honour);}
}
->TbResumeListMapper.java
public interface TbResumeListMapper extends BaseMapper<TbResumeList> {int insertProfessionalData(String personID, String professional);int insertCareerData(String personID, String careerDate, String careerUnit, String careerPost, String careerLevelReason);int insertCertificateData(String personID, String certificate);int insertHonourData(String personID, String honour);
}
还要在xml中添加SQL语句
->TbResumeListMapper.xml
<mapper namespace="org.jeecg.modules.hr.resume.mapper.TbResumeListMapper"><!-- SQL语句 --><insert id="insertCareerData" parameterType="String">INSERT INTO tb_career_info( `person_id` , `career_date` , `career_unit` , `career_post` , `career_leave_reason` )VALUES( #{personID}, #{careerDate}, #{careerUnit}, #{careerPost}, #{careerLevelReason} )</insert><insert id="insertProfessionalData" parameterType="String">INSERT INTO tb_professional_info( `person_id` , `professional`)VALUES( #{personID}, #{professional})</insert><insert id="insertCertificateData" parameterType="String">INSERT INTO tb_certificate_info( `person_id` , `certificate` )VALUES( #{personID}, #{certificate} )</insert><insert id="insertHonourData" parameterType="String">INSERT INTO tb_honour_info( `person_id` , `honour` )VALUES( #{personID}, #{honour} )</insert>
</mapper>
通过以上操作,我们重新运行前后端代码后,登录系统就能看到数据了。比如这样
但目前表格信息里面还没有工作经历、获得荣誉、取得证书等等信息,怎么办?继续。
6、前端电脑页面显示工作经历信息
1)增加实体类(Entity)字段
在entity文件夹内打开TbResumeList.java文件,在private int resumeIsEmployee字段后再增加4个字段:
//Java代码
/**上一单位名称*/
@Excel(name = "上一单位名称", width = 15)
@ApiModelProperty(value = "上一单位名称")
private String career;
/**已获职称*/
@Excel(name = "已获职称", width = 15)
@ApiModelProperty(value = "已获职称")
private String professional;
/**资格证书*/
@Excel(name = "资格证书ID", width = 15)
@ApiModelProperty(value = "资格证书")
private String certificate;
/**曾获荣誉*/
@Excel(name = "曾获荣誉", width = 15)
@ApiModelProperty(value = "曾获荣誉")
private String honour;
2)编写多表查询SQL语句
由于是多表查询,单靠mybatis-plus提供的查询接口已经不能满足要求,所以需要自己单独编写代码。由于后面会用到对简历状态字段的查询(resumeStatusList)以及判断是否加入回收站的条件(delValue),所以在查询条件中,改成了动态拼写的SQL语句。
<!-- SQL代码 -->
<select id="getResumeData" resultType="org.jeecg.modules.hr.resume.entity.TbResumeList">SELECTa.id, a.resume_name, a.resume_pic, a.resume_sfz, a.resume_sex, a.resume_minzu, a.resume_age, a.resume_birthday, a.resume_tel, a.resume_address, a.resume_qqwx,a.resume_email, a.resume_party, a.resume_edu_college, a.resume_edu_major, a.resume_edu_end_date, a.resume_edu_background, a.resume_edu_degree, a.resume_memo,a.resume_is_read, a.resume_is_passed, a.resume_is_del, a.resume_is_employee,GROUP_CONCAT( DISTINCT c.professional ) AS professional,GROUP_CONCAT( DISTINCT concat_ws( '|', d.career_date, d.career_unit, d.career_post, d.career_leave_reason ) ) AS career,GROUP_CONCAT( DISTINCT e.certificate ) AS certificate,GROUP_CONCAT( DISTINCT f.honour ) AS honourFROMtb_resume_list aLEFT JOIN tb_professional_info c ON a.id = c.person_idLEFT JOIN tb_career_info d ON a.id = d.person_idLEFT JOIN tb_certificate_info e ON a.id = e.person_idLEFT JOIN tb_honour_info f ON a.id = f.person_id<where><if test="resumeStatusList != null and resumeStatusList.size() != 0">a.resume_is_passed in<foreach collection="resumeStatusList" index="index" item="status" open="(" separator="," close=")">#{status}</foreach></if>and a.resume_is_del = #{delValue}</where>GROUP BYa.idORDER BY a.resume_is_passed ASC, a.resume_is_employee ASC, a.create_time DESC
</select>
3)完善controller、service、mapper类的代码
->TbResumeListController.java
/*** 简历库** @param tbResumeList* @param pageNo* @param pageSize* @param req* @return*/@AutoLog(value = "简历库")@ApiOperation(value="简历库", notes="简历库")@GetMapping(value = "/list")public Result<?> list(TbResumeList tbResumeList, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {Page<TbResumeList> page = new Page<>(pageNo, pageSize);List<Integer> resumeStatusList = new ArrayList<>();resumeStatusList.add(2);int delValue = 0;IPage<TbResumeList> pageList = tbResumeListService.getResumeData(page, resumeStatusList, delValue);return Result.OK(pageList);}
->ITbResumeListService.java
IPage<TbResumeList> getResumeData(Page<TbResumeList> page, List<Integer> resumeStatusList, int delValue);
impl、mapper的代码请参考本文第5段完成。
后端的Java代码已修改完毕,现在我们看看前端Vue页面的代码该如何实现。
4)单元格内显示数据
在TbResumeListList.vue文件中,要将table的列补充完整。在备注字段前增加这4个字段
{title:'工作经历',align:"center",dataIndex: 'career',
},{title:'已获职称',align:"center",dataIndex: 'professional',
},{title:'资格证书',align:"center",dataIndex: 'certificate',
},{title:'曾获荣誉',align:"center",dataIndex: 'honour',
},
现在已经显示了需要的数据,但是这样显示对用户来说是非常不友好的。我们需要修改显示方式。
工作经历、证书等这部分内容是一对多的,也就是说,只能在这行信息内的一个单元格显示,通常有两种方法:1、后面操作格内增加一个[查看工作经历]的功能菜单,点击打开一个窗口显示详细的多条工作经历;2、在这个单元格内再显示一个表格。这里我选择了第二种。原因是:用户方便。
要想在单元格内显示自定义的表格信息。要先知道两点:1、如何在单元格内自定义显示。2、表格的html代码该怎么写。
5)工作经历单元格的自定义显示
参考AntdVue官网后,知道单元格自定义显示的方法:customRender。可以像[操作]单元格一样使用scopedSlots插槽来实现。
首先定义一个插槽并显示表格。
<span slot="customRowTable" slot-scope="text, record"> {{ text }}<div v-if="text" class="careerContainer"><table><tr><th style="width:4%;">#</th><th style="width:23%;">任期</th><th style="width:35%;">公司名称</th><th style="width:13%;">岗位</th><th style="width:25%;">离职原因</th></tr><tr v-for="(c, index) in record.career.split(',')"><td>{{ index+1 }}</td><td style="text-align: left">{{ c.split('|')[0] }}</td><td>{{ c.split('|')[1] }}</td><td>{{ c.split('|')[2] }}</td><td>{{ c.split('|')[3] }}</td></tr></table></div><div v-else style="font-size: 12px;font-style: italic;">{{ text===null?'无':text===''?'无':text==='没有'?'无':text }}</div></span>
还有表格的样式
.careerContainer table{width:700px;text-align: center}.careerContainer table tr td{font-size: 13px;padding:2px 5px 2px 5px;vertical-align: center;}.careerContainer table tr:nth-of-type(even){background:#eee;}
之后在列定义那增加scopedSlots: { customRender: ‘customRowTable’ }
{title:'工作经历',align:"center",dataIndex: 'career',scopedSlots: { customRender: 'customRowTable' }, //增加这一行,注意名字要与插槽的名字一致},
现在的显示效果应该是这样,我们继续修改职称、证书、荣誉以及照片的显示样式。
5)照片、职称、证书、荣誉单元格的自定义显示
与工作经历相同,我就直接贴代码了。
<!-- 职称、证书、荣誉的显示采用Tag标签 -->
<!-- 显示方式一样,只是Tag的颜色有区别 -->
<span slot="warpLineByGreenTag" slot-scope="text, record"> {{ text }}<div v-if="text && text !== '无' && text !== '没有'"><div v-for="(t, index) in text.split(',')" :key="t.toString()+'_green'" style="margin:1px 0 1px 0;"><a-tag color="#87d068" style="margin:0;">{{ t }}</a-tag></div></div><div v-else style="font-size: 12px;font-style: italic;">{{ text===null?'无':text===''?'无':text==='没有'?'无':text }}</div>
</span>
照片的样式用到了v-viewer组件
安装命令:npm install v-viewer --save
记得要引用哦,全局单一都可以
<span slot="imgSlot" slot-scope="text"> {{ text }}<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span><viewer v-else><img :src="showFileUrl(text)" height="100px" style="margin:0;padding:0;cursor:pointer;" alt="图片"/></viewer>
</span>
至此,我们已经完成了最终表格样式的显示。接下来要实现剩余3个页面简历库
暂存简历
回收站
。
7、新建3个vue页面、菜单及后台代码
复制vue页面,并重命名
可以复制写好的vue代码,改一下名字。我这里分别取名:
- Resume↓
- TbResumeList.vue(简历库)
- TbResumeNewList.vue(新投简历)
- TbResumeRecycleList.vue(回收站)
- TbResumeTempList.vue(暂存简历)
新增三个菜单
然后在菜单管理内新增其他三个菜单,这里我就不演示了。
后端Java接口
要实现四个页面显示不同状态的数据,需要动态传入不同的状态参数来实现。之前多表查询已经将动态查询做好了,现在只需要传入不同的参数即可。
新投简历显示新简历、不通过两个状态的记录也就是resume_is_passed字段为1或3,暂存简历显示resume_is_passed为4的记录,简历库显示resume_is_passed为2的记录,回收站显示resume_is_del为1的记录。
所以代码如下:
这里只粘贴了简历库的java代码,其他代码请自行编写。
/*** 简历库** @param pageNo 当前页* @param pageSize 每页数量* @return Result*/
@AutoLog(value = "简历库")
@ApiOperation(value="简历库", notes="简历库")
@GetMapping(value = "/list")
public Result<?> queryPageList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {Page<TbResumeList> page = new Page<>(pageNo, pageSize);List<Integer> resumeStatusList = new ArrayList<>();resumeStatusList.add(2); //状态为2已通过的状态int delValue = 0; //这里为是否放入回收站的状态。0:不放入,1:放入IPage<TbResumeList> pageList = tbResumeListService.getResumeData(page, resumeStatusList, delValue);return Result.OK(pageList);
}
完成后,不同页面应该能显示不同的数据记录了,大家可以手动改一下状态值,看数据能否正常显示。
8、增加功能按钮
增加功能菜单、处理脚本及后台接口
新投简历的后续操作有:删除
、通过
、拒绝
、暂存
四项。先修改action插槽内的菜单:
<span slot="action" slot-scope="text, record"><a-popconfirm title="确定通过该简历吗?" @confirm="() => handlePass(record.id)"><a>通过</a></a-popconfirm><a-divider type="vertical"/><a-popconfirm title="确定拒绝该简历吗?" @confirm="() => handleRefuse(record.id)"><a>拒绝</a></a-popconfirm><br><a-dropdown><a class="ant-dropdown-link">更多 <a-icon type="down" /></a><a-menu slot="overlay"><a-menu-item>
<!-- <a @click="handleDetail(record)">详情</a>--><a @click="handleTemp(record.id)">暂存</a></a-menu-item><a-menu-item><a-popconfirm title="确定移入回收站吗?" @confirm="() => handleRecycle(record.id)"><a>删除</a></a-popconfirm></a-menu-item></a-menu></a-dropdown>
</span>
然后添加处理脚本:
handlePass(id){let that = this;getAction(this.url.pass, {id: id}).then((res) => {if (res.success) {that.$message.success(res.message);that.loadData();} else {that.$message.warning(res.message);}});
},
handleRefuse(id) {let that = this;getAction(this.url.refuse, {id: id}).then((res) => {if (res.success) {that.$message.success(res.message);that.loadData();} else {that.$message.warning(res.message);}});
},
handleTemp(id){let that = this;getAction(this.url.temp, {id: id}).then((res) => {if (res.success) {that.$message.success(res.message);that.loadData();} else {that.$message.warning(res.message);}});
},
handleRecycle(id){let that = this;getAction(this.url.recycle, {id: id}).then((res) => {if (res.success) {that.$message.success(res.message);that.loadData();} else {that.$message.warning(res.message);}});
},
以及接口地址
pass: "/hr/tbResumeList/pass",
refuse: "/hr/tbResumeList/refuse",
temp: "/hr/tbResumeList/temp",
recycle: "/hr/tbResumeList/recycle",
增加后台Java处理逻辑接口
/*** 新简历通过** @param id id* @return Result*/
@AutoLog(value = "新简历通过")
@ApiOperation(value="新简历通过", notes="新简历通过")
@GetMapping(value = "/pass")
public Result<?> pass(@RequestParam(name="id") String id) {String changeValue = "2";if(tbResumeListService.changeResumeStatus(id, changeValue)){return Result.OK("操作成功!");}else{return Result.OK("操作失败!");}
}/*** 新简历拒绝** @param id id* @return Result*/
@AutoLog(value = "新简历拒绝")
@ApiOperation(value="新简历拒绝", notes="新简历拒绝")
@GetMapping(value = "/refuse")
public Result<?> refuse(@RequestParam(name="id") String id) {String changeValue = "3";if(tbResumeListService.changeResumeStatus(id, changeValue)){return Result.OK("操作成功!");}else{return Result.OK("操作失败!");}
}/*** 暂存新简历** @param id id* @return Result*/
@AutoLog(value = "暂存新简历")
@ApiOperation(value="暂存新简历", notes="暂存新简历")
@GetMapping(value = "/temp")
public Result<?> temp(@RequestParam(name="id") String id) {String changeValue = "4";if(tbResumeListService.changeResumeStatus(id, changeValue)){return Result.OK("操作成功!");}else{return Result.OK("操作失败!");}
}/*** 新简历放入回收站** @param id id* @return Result*/
@AutoLog(value = "新简历放入回收站")
@ApiOperation(value="新简历放入回收站", notes="新简历放入回收站")
@GetMapping(value = "/recycle")
public Result<?> recycle(@RequestParam(name="id") String id) {if(tbResumeListService.recycleResume(id, 1)){return Result.OK("移入回收站成功!");}else{return Result.OK("移入回收站失败!");}
}
以及SQL语句
<update id="changeResumeStatus" parameterType="String">UPDATE tb_resume_list SET resume_is_passed = #{changeValue} where id = #{id}
</update><update id="recycleResume">UPDATE tb_resume_list SET resume_is_del = #{delValue} where id = #{id}
</update>
简历库的后续操作有:入职
、删除
两项。
暂存简历的后续操作有:通过
、拒绝
、删除
三项。
回收站的后续操作有:永久删除
、还原
两项。
这些功能与新投简历的功能类似,请大家自行完成。
9、结束
至此,简历管理已经能实现它的基本功能了。人资管理系统的一个整体性能强的系统,在新投简历审核成功,需要办理入职的过程时,需要将简历数据表内的数据拷贝到员工管理数据表中,并为员工开通账号以便员工能在手机中继续完善入职后的其他信息(家庭关系、紧急联络人等)。
代码下载: 传送门
[Java开发]搭建人力资源管理系统——简历管理模块(附带下载链接)相关推荐
- 最新版阿里巴巴Java开发手册(嵩山版)-附免费下载链接
2020年8月3日,阿里技术官方宣布,阿里巴巴<Java 开发手册(嵩山版)>现已正式发布. <阿里巴巴 Java 开发手册>始于阿里内部规约,在全球Java开发者共同努力下, ...
- 十个经典java开发项目及其描述-简历用
十个经典java开发项目及其描述-简历用 1.项目名称:中介管理软件 2.项目名称:菜园(电商) 3.项目名称:房产中介管理系统 4.项目名称:物流信息平台 5.项目名称:销售存储管理系统 6.项目名 ...
- 客户管理系统代码项目_西安人力资源管理系统如何有效管理销售,提高工作的效率...
人力资源管理系统如何有效管理销售,提高工作的效率 发布人:汇聚华企管理系统 原创分享 销售过程会出现的管理问题各种各样,比如说库存状态,比如说报价,又比如说客户关系管理,其实这些管理上的问题都能用软件 ...
- java开发的公文管理系统源代码_基于jsp的公文管理系统-JavaEE实现公文管理系统 - java项目源码...
基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的公文管理系统, 该项目可用各类java课程设计大作业中, 公文管理系统的系统架构分为前后台两部分, 最终实现在线上 ...
- JavaWeb简历管理模块
Javaweb简历管理模块笔记 模块简介 要求 开发工具 静态效果展示 总结 代码仓库地址 项目代码笔记 数据库和JDBC代码 项目结构 文件上传和接收 jQuery实现ajax 分页 使用selen ...
- Java-Web机试练习题一、后台管理系统——管理员管理模块
题目:后台管理系统--管理员管理模块 一. 语言和环境 1. 实现语言:JAVA 语言. 2. 环境要求:MyEclipse/Eclipse + Tomcat + MySql. 3. 使用技术:Jsp ...
- 图书管理系统jsp代码_【程序源代码】使用Java开发的图书管理系统
关键字:java 管理系统 正文 | 内容 01 - [概述] 使用Java开发的图书管理系统,读者可以注册登录,登录时会判断账号类型再分别跳到各自对应的页面,读者可以查找,借阅,还书,查看历史借阅 ...
- java开发企业级权限管理系统_Java开发企业级权限管理系统 视频教程
第1章 课程整体概述与权限管理系统介绍 1-1 为什么企业级项目需要权限管理 1-2 权限管理的核心是什么? 1-3 理想中的权限管理应该是什么样的? 1-4 主流开源权限管理框架有哪些? 1-5 1 ...
- 06_04_任务一:拉勾教育后台管理系统[课程管理模块、图片上传、 BeanUtils封装实体类](SSM)
拉勾教育后台管理系统(SSM) 1. 项目架构 1.1 项目介绍 拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在 这个后台管理系统中,对课程信息.广告 ...
最新文章
- wpf+xml实现的一个随机生成早晚餐的小demo
- ​京东AI研究院获QuAC机器阅读理解竞赛冠军,EL-QA模型能力业界领先
- apply筛选 pandas_更快的pandas.apply搜索方法
- python使用符号 表示单行注释-Python注释符号(多行注释和单行注释)用法详解...
- android Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)
- SpringBoot+AntV实现一次前后端交互渲染多个饼状图
- matlab数字滤波器设计函数汇总(转载)
- kernel移植——从三星官方内核开始移植
- 电脑运行java游戏,电脑运行软件卡顿?这几招游戏或是办公,让你速度飞起!...
- 用汇编的眼光看C++(之指针2)
- LeetCode 113. Path Sum II
- Log4net使用指南[转]
- 结合源码探讨Android距离传感器亮灭屏机制
- 【老兵不朽】时隔1年,jQuery 发布新版 3.4.0
- 人脸识别 特征值脸_你的脸值多少钱?
- [JDK1.8] Java-I/O流使用概述
- update set命令用来修改表中的数据
- java mvc接收json_详解springmvc 接收json对象的两种方式
- 星加坡php开发_PHP 中文简繁互转代码 完美支持大陆、香港、台湾及新加坡
- 《西部世界》暗示了大数据人工智能什么
热门文章
- android+win8+双系统,Android/Win8双系统 天敏iBox睿盒D9i评测上
- 关于Android中Button的Backgroud背景设置默认为蓝紫色,且无法修改的问题
- 《C++ Primer》第15章 15.2节习题答案
- docker安装minio无法访问
- 用mask-rcnn训练自己的数据
- 2021.11.08【web刷题记录】
- android输入法框架分析,Android输入法架构.ppt
- 可汗学院计算机课程都有哪些,要录制可汗学院教学视频你需要哪些硬件和软件?...
- 腾讯云tcp认证资料考点包含哪些知识?
- 网络异常处理,ping测试报:一般故障