人员简历

This commit is contained in:
Chengliang 2022-12-29 18:04:58 +08:00
parent 80b9c2f288
commit a9bdbe3d2d
9 changed files with 2015 additions and 283 deletions

11
package-lock.json generated
View File

@ -5,6 +5,7 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"baidu-template-pro": "^1.0.0",
"dom-to-image": "^2.6.0", "dom-to-image": "^2.6.0",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
@ -301,6 +302,11 @@
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
}, },
"node_modules/baidu-template-pro": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/baidu-template-pro/-/baidu-template-pro-1.0.0.tgz",
"integrity": "sha512-gnw6uvCn4CvZZ9d1Tu+a0B7BjQuNXvDcxsJk7bwxTpNutj6JFIxcy2sS0rB2/0/t9GwatoEIXd8HV0qkXpdRow=="
},
"node_modules/base64-arraybuffer": { "node_modules/base64-arraybuffer": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
@ -2213,6 +2219,11 @@
} }
} }
}, },
"baidu-template-pro": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/baidu-template-pro/-/baidu-template-pro-1.0.0.tgz",
"integrity": "sha512-gnw6uvCn4CvZZ9d1Tu+a0B7BjQuNXvDcxsJk7bwxTpNutj6JFIxcy2sS0rB2/0/t9GwatoEIXd8HV0qkXpdRow=="
},
"base64-arraybuffer": { "base64-arraybuffer": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",

View File

@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"baidu-template-pro": "^1.0.0",
"dom-to-image": "^2.6.0", "dom-to-image": "^2.6.0",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",

View File

@ -3,6 +3,11 @@ import {
WeaTools WeaTools
} from 'ecCom' } from 'ecCom'
export const getHasRight = (params) => { export const getHasRight = () => {
return WeaTools.callApi('/api/bs/hrmorganization/personnelresume/hasRight', 'GET', params); return WeaTools.callApi('/api/bs/hrmorganization/personnelresume/hasRight', 'GET');
}
export const getPersonnelResume = (params) => {
return WeaTools.callApi('/api/bs/hrmorganization/personnelresume/getResumeList', 'GET', params);
} }

View File

@ -0,0 +1,57 @@
;(function(window){
//符合commonjs规范引入依赖
if(typeof module !== 'undefined'){
window.saveAs = require('file-saver')
window.baidu = require('baidu-template-pro')
}
function getModelHtml(mhtml,style=''){
return`
Content-Type: text/html; charset="utf-8"
<!DOCTYPE html>
<html>
<head>
<style>
${style}
</style>
</head>
<body>
${mhtml}
</body>
</html>
`
}
//主函数
let exportWord = ({mhtml,style,filename,data,selector})=>{
if(selector){
let nodes = window.document.querySelectorAll(selector)
mhtml = nodes.length>0?Array.from(nodes).reduce((a,b)=>a+b.innerHTML,''):''
}
//没有baiduTemplatePro.js依赖时必须传入selector
if (!selector && typeof baidu === 'undefined') {
console.error("wordExport : missing (selector) for params without depandency (baiduTemplatePro.js)");
return;
}
if (typeof saveAs === "undefined") {
console.error("wordExport : missing dependency (FileSaver.js)");
return;
}
//没有模板引擎时将获取节点的html字符串生成模板
let html = typeof baidu !== 'undefined'?baidu.template(getModelHtml(mhtml,style),data):getModelHtml(mhtml)
let blob = new Blob([html],{type:'application/msword;charset=utf-8'})
saveAs(blob,filename+'.docx')
}
//添加exportWord到全局对象
window.exportWord = window.exportWord||exportWord
//如果符合commonjs规范exports出去
if(typeof module==='object'&&typeof module.exports==='object'){
module.exports = {exportWord}
}
})(window)

View File

@ -20,7 +20,7 @@ import {
Button, Button,
message, message,
Switch, Switch,
Menu, Dropdown, Icon, Select Menu, Dropdown, Icon, Select,Progress
} from 'antd' } from 'antd'
import { import {
WeaSwitch, WeaSwitch,
@ -32,6 +32,7 @@ import {
import '../../style/resume.less'; import '../../style/resume.less';
import { renderNoright } from '../../util'; import { renderNoright } from '../../util';
import { exportWord } from '../mhtmlToWord'
const toJS = mobx.toJS; const toJS = mobx.toJS;
@ -120,9 +121,13 @@ export default class PersonnelResume extends React.Component {
const type = event.node.props.type || '0'; const type = event.node.props.type || '0';
const id = event.node.props.id || ''; const id = event.node.props.id || '';
personnelResume.nodeType = type; personnelResume.nodeType = type;
debugger
if (type == '4') { if (type == '4') {
personnelResume.resourceId = id; personnelResume.resourceId = id;
personnelResume.getPersonnelResume(); setTimeout(function() {
personnelResume.getPersonnelResume();
},1000)
} }
} }
@ -202,6 +207,29 @@ export default class PersonnelResume extends React.Component {
this[key] && this[key](); this[key] && this[key]();
} }
//导出当前
currentExport() {
const {
personnelResume
} = this.props;
const {
resumeList
} = personnelResume;
exportWord({
filename:`人员简历-${resumeList.lastName}`,
selector:"#personnel-resume",
style:`.title {
font-size: 18px;
font-weight: 900;
text-align: center;
}
.photos{
width: 100px;
height: 120px;
}`
})
}
isEmptyObject(obj) { isEmptyObject(obj) {
for (let key in obj) { for (let key in obj) {
return false; return false;
@ -216,7 +244,7 @@ export default class PersonnelResume extends React.Component {
personnelResume personnelResume
} = this.props; } = this.props;
const { const {
hasRight, defaultShowLeft, resumeList hasRight, defaultShowLeft, resumeList,percent
} = personnelResume; } = personnelResume;
if (hasRight === false) { if (hasRight === false) {
@ -241,102 +269,104 @@ export default class PersonnelResume extends React.Component {
onDropMenuClick={(e) => this.handleMenuClick(e)} onDropMenuClick={(e) => this.handleMenuClick(e)}
> >
<WeaLeftRightLayout ecId={`${this && this.props && this.props.ecId || ''}_WeaLeftRightLayout@7muhhb`} isNew={true} showLeft={defaultShowLeft} leftCom={this.getTree()}> <WeaLeftRightLayout ecId={`${this && this.props && this.props.ecId || ''}_WeaLeftRightLayout@7muhhb`} isNew={true} showLeft={defaultShowLeft} leftCom={this.getTree()}>
<div id='personnel-resume'> {
<div className='content'> !this.isEmptyObject(resumeList) ? <div id='personnel-resume'>
<p className='title'>人员简历信息</p> <div className='content'>
<table border="1" align="center" width="750" cellspacing='0' className='resume-table'> <p className='title'>人员简历信息</p>
<tr align="center" height='50'> <table border="1" align="center" width="750" cellspacing='0' className='resume-table'>
<td colspan="7">基本信息</td> <tr align="center" height='50'>
</tr> <td colspan="7">基本信息</td>
<tr align="center" height='50'> </tr>
<td width="100" >姓名</td> <tr align="center" height='50'>
<td width="100">{resumeList.lastName}</td> <td width="100" >姓名</td>
<td width="100">性别</td> <td width="100">{resumeList.lastName}</td>
<td width="100">{resumeList.sex}</td> <td width="100">性别</td>
<td width="100">出生年月</td> <td width="100">{resumeList.sex}</td>
<td width="100">{resumeList.birthday}</td> <td width="100">出生年月</td>
<td rowspan="3"><img style={{ "width": "100px", "height": "120px" }} src={resumeList.image} /></td> <td width="100">{resumeList.birthday}</td>
</tr> <td rowspan="3"><img className='photos' src={resumeList.image} /></td>
<tr align="center" height='50'> </tr>
<td width="100" >籍贯</td> <tr align="center" height='50'>
<td width="100">{resumeList.native}</td> <td width="100" >籍贯</td>
<td width="100">政治面貌</td> <td width="100">{resumeList.native}</td>
<td width="100">{resumeList.politics}</td> <td width="100">政治面貌</td>
<td width="100">部门</td> <td width="100">{resumeList.politics}</td>
<td width="100">{resumeList.department}</td> <td width="100">部门</td>
</tr> <td width="100">{resumeList.department}</td>
<tr align="center" height='50'> </tr>
<td width="100">婚姻状况</td> <tr align="center" height='50'>
<td width="100">{resumeList.marriage}</td> <td width="100">婚姻状况</td>
<td width="100">岗位</td> <td width="100">{resumeList.marriage}</td>
<td width="100">{resumeList.jobtitle}</td> <td width="100">岗位</td>
<td width="100">入职时间</td> <td width="100">{resumeList.jobtitle}</td>
<td width="100">{resumeList.companystartdate}</td> <td width="100">入职时间</td>
</tr> <td width="100">{resumeList.companystartdate}</td>
<tr align="center" height='50'> </tr>
<td width="100">参加工作时间</td> <tr align="center" height='50'>
<td width="100" colspan="2">{resumeList.workstartdate}</td> <td width="100">参加工作时间</td>
<td width="100" colspan="2">身份证号</td> <td width="100" colspan="2">{resumeList.workstartdate}</td>
<td width="100" colspan="2">{resumeList.idCard}</td> <td width="100" colspan="2">身份证号</td>
</tr> <td width="100" colspan="2">{resumeList.idCard}</td>
<tr align="center" height='50'> </tr>
<td width="100" rowspan="2">家庭地址</td> <tr align="center" height='50'>
<td width="100" rowspan="2" colspan="2">{resumeList.address}</td> <td width="100" rowspan="2">家庭地址</td>
<td width="100" colspan="2">联系电话</td> <td width="100" rowspan="2" colspan="2">{resumeList.address}</td>
<td width="100" colspan="2">{resumeList.telephone}</td> <td width="100" colspan="2">联系电话</td>
</tr> <td width="100" colspan="2">{resumeList.telephone}</td>
<tr align="center" height='50'> </tr>
<td width="100" colspan="2">E-mail</td> <tr align="center" height='50'>
<td width="100" colspan="2">{resumeList.email}</td> <td width="100" colspan="2">E-mail</td>
</tr> <td width="100" colspan="2">{resumeList.email}</td>
</tr>
{ {
resumeList.tables.map((item, index) => { resumeList.tables.map((item, index) => {
return ( return (
<React.Fragment key={index}> <React.Fragment key={index}>
<tr align="center" height='50'> <tr align="center" height='50'>
<td colspan="7">{item.title}</td> <td colspan="7">{item.title}</td>
</tr> </tr>
<tr align="center" height='50'> <tr align="center" height='50'>
{ {
item.columns.map(column => { item.columns.map(column => {
return ( return (
<td width="100" rowspan={column.rowspans} colspan={column.colspans}>{column.name}</td> <td width="100" rowspan={column.rowspans} colspan={column.colspans}>{column.name}</td>
) )
}) })
} }
</tr> </tr>
{ {
item.datas.map(data => { item.datas.map(data => {
return ( return (
<tr align="center" height='50'> <tr align="center" height='50'>
{ {
data.map((row, index) => { data.map((row, index) => {
return ( return (
<td width="100" rowspan={row.rowspans} colspan={row.colspans}>{row.value}</td> <td width="100" rowspan={row.rowspans} colspan={row.colspans}>{row.value}</td>
) )
}) })
} }
</tr> </tr>
) )
}) })
} }
</React.Fragment> </React.Fragment>
) )
}) })
} }
<tr align="center" height='200'> <tr align="center" height='200'>
<td width="100">个人自述</td> <td width="100">个人自述</td>
<td width="100" colspan="6">{resumeList.selfStatement}</td> <td width="100" colspan="6">{resumeList.selfStatement}</td>
</tr> </tr>
</table> </table>
</div> </div>
</div> </div>
: <Progress percent={percent} strokeWidth={10} />}
</WeaLeftRightLayout> </WeaLeftRightLayout>
</WeaTop> </WeaTop>
</WeaRightMenu> </WeaRightMenu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

View File

@ -32,196 +32,199 @@ export class PersonnelResumeStore {
@observable form = new WeaForm(); @observable form = new WeaForm();
@observable loading = true; @observable loading = true;
@observable resourceId = ''; @observable resourceId = '';
@observable resumeList = { @observable resumeList = {};
lastName: '徐凤年', @observable percent = 0;
sex: '男', @observable visible = false;
birthday: '1999-10-10', // @observable resumeList = {
image: '/weaver/weaver.file.FileDownload?fileid=1538', // lastName: '徐凤年',
native: '上海', // sex: '男',
politics: '党员', // birthday: '1999-10-10',
department: '财务部', // image:'',
marriage: '已婚', // native: '上海',
jobtitle: '剑道第一人', // politics: '党员',
companystartdate: '2020-12-31', // department: '财务部',
workstartdate: '2011-10-10', // marriage: '已婚',
idCard: '3409871298377483992', // jobtitle: '剑道第一人',
address: '江苏省南京市雨花台区润和创智中心', // companystartdate: '2020-12-31',
telephone: '19823045643', // workstartdate: '2011-10-10',
email: '16378324@163.com', // idCard: '3409871298377483992',
selfStatement:'本人性格开朗,秦武大帝转世,世间武道的第一人', // address: '江苏省南京市雨花台区润和创智中心',
tables: [ // telephone: '19823045643',
{ // email: '16378324@163.com',
title: '二、社会保险及住房公积金缴纳情况(单位/元)', // selfStatement:'本人性格开朗,秦武大帝转世,世间武道的第一人',
columns: [ // tables: [
{ // {
name: '首次参保时间', // title: '二、社会保险及住房公积金缴纳情况(单位/元)',
colspans: 2, // columns: [
rowspans: 1 // {
}, // name: '首次参保时间',
{ // colspans: 2,
name: '养老保险', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '养老保险',
{ // colspans: 1,
name: '医疗保险', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '医疗保险',
{ // colspans: 1,
name: '失业保险', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '失业保险',
{ // colspans: 1,
name: '住房公积金', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '住房公积金',
{ // colspans: 1,
name: '企业年金', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '企业年金',
], // colspans: 1,
datas: [ // rowspans: 1
[{ // },
value: '2022-10-02', // ],
colspans: 2, // datas: [
rowspans: 1 // [{
}, { // value: '2022-10-02',
value: '80', // colspans: 2,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, // value: '80',
{ // colspans: 1,
value: '36', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, { // value: '36',
value: '360', // colspans: 1,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, { // value: '360',
value: '180', // colspans: 1,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, { // value: '180',
value: '20000', // colspans: 1,
colspans: 2, // rowspans: 1
rowspans: 1 // }, {
}] // value: '20000',
] // colspans: 2,
}, // rowspans: 1
{ // }]
title: '三、家庭成员信息(包括父母、配偶、子女)', // ]
columns: [ // },
{ // {
name: '关系', // title: '三、家庭成员信息(包括父母、配偶、子女)',
colspans: 2, // columns: [
rowspans: 1 // {
}, // name: '关系',
{ // colspans: 2,
name: '姓名', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '姓名',
{ // colspans: 1,
name: '工作单位及职务', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '工作单位及职务',
{ // colspans: 1,
name: '联系电话', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, // name: '联系电话',
{ // colspans: 1,
name: '住址', // rowspans: 1
colspans: 2, // },
rowspans: 1 // {
} // name: '住址',
], // colspans: 2,
datas: [ // rowspans: 1
[ // }
{ // ],
value: '父子', // datas: [
colspans: 2, // [
rowspans: 1 // {
}, { // value: '父子',
value: '徐晓', // colspans: 2,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, // value: '徐晓',
{ // colspans: 1,
value: '北凉王', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, { // value: '北凉王',
value: '1589756859', // colspans: 1,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, { // value: '1589756859',
value: '江苏省南京市北凉军营', // colspans: 1,
colspans: 2, // rowspans: 1
rowspans: 1 // }, {
} // value: '江苏省南京市北凉军营',
], // colspans: 2,
[ // rowspans: 1
{ // }
value: '母子', // ],
colspans: 2, // [
rowspans: 1 // {
}, { // value: '母子',
value: '吴素', // colspans: 2,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, // value: '吴素',
{ // colspans: 1,
value: '北凉王妃', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, { // value: '北凉王妃',
value: '15897566487', // colspans: 1,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, { // value: '15897566487',
value: '江苏省南京市北凉龙雀军团', // colspans: 1,
colspans: 2, // rowspans: 1
rowspans: 1 // }, {
} // value: '江苏省南京市北凉龙雀军团',
], // colspans: 2,
[ // rowspans: 1
{ // }
value: '女儿', // ],
colspans: 2, // [
rowspans: 1 // {
}, { // value: '女儿',
value: '徐念凉', // colspans: 2,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, // value: '徐念凉',
{ // colspans: 1,
value: '北凉公主', // rowspans: 1
colspans: 1, // },
rowspans: 1 // {
}, { // value: '北凉公主',
value: '15897566587', // colspans: 1,
colspans: 1, // rowspans: 1
rowspans: 1 // }, {
}, { // value: '15897566587',
value: '莽荒之地', // colspans: 1,
colspans: 2, // rowspans: 1
rowspans: 1 // }, {
} // value: '莽荒之地',
] // colspans: 2,
] // rowspans: 1
// }
// ]
// ]
} // }
] // ]
} // }
@observable defaultShowLeft = true; @observable defaultShowLeft = true;
@ -231,12 +234,15 @@ export class PersonnelResumeStore {
@action("获取操作按钮") getHasRight() { @action("获取操作按钮") getHasRight() {
let _this = this;
Api.getHasRight().then(res => { Api.getHasRight().then(res => {
if (res.code === 200) { if (res.code === 200) {
this.setHasRight(res.data.hasRight); this.setHasRight(res.data.hasRight);
res.data.rightMenu && this.setRightMenu(res.data.rightMenu); res.data.rightMenu && this.setRightMenu(res.data.rightMenu);
res.data.topMenu && this.setTopMenu(res.data.topMenu); res.data.topMenu && this.setTopMenu(res.data.topMenu);
res.data.hasRight && this.getPersonnelResume(); setTimeout(function() {
res.data.hasRight && _this.getPersonnelResume();
},1000)
} else { } else {
message.warning(res.msg); message.warning(res.msg);
} }
@ -246,8 +252,38 @@ export class PersonnelResumeStore {
} }
@action("获取人员简历") getPersonnelResume() { @action("获取人员简历") getPersonnelResume() {
this.resumeList = {};
this.percent = 0;
this.visible = false;
this.interval = setInterval(() => this.getImportProcess(), 200);
let params = {
id:this.resourceId
}
Api.getPersonnelResume(params).then(res => {
if (res.code === 200) {
this.percent = 100;
this.visible = true;
this.resumeList = res.data;
} else {
clearInterval(this.interval);
message.warning("简历模板加载失败");
}
}, error => {
message.warning(error.msg);
})
}
@action("头部加载进度条") getImportProcess() {
if(this.visible) {
clearInterval(this.interval);
}else {
let max = 95;
let min = this.percent;
if(this.percent < max) {
this.percent = Math.floor(Math.random() * (max - min)) + min;
}
}
} }
setTopMenu(topMenu) { setTopMenu(topMenu) {

View File

@ -22,6 +22,10 @@
} }
.resume-table { .resume-table {
margin-top: 20px; margin-top: 20px;
.photos{
width: 100px;
height: 120px;
}
} }
} }
} }

1588
yarn.lock Normal file

File diff suppressed because it is too large Load Diff