巴林闲侠 2 years ago
parent
commit
b8a681ddd6
  1. BIN
      web/client/assets/images/hrImg/!.png
  2. BIN
      web/client/assets/images/hrImg/V.png
  3. BIN
      web/client/assets/images/hrImg/setUp.png
  4. 2
      web/client/index.ejs
  5. 28
      web/client/index.html
  6. 9
      web/client/src/components/setup.jsx
  7. 8
      web/client/src/sections/humanAffairs/components/personnelModal.jsx
  8. 344
      web/client/src/sections/humanAffairs/containers/employeeInformation.jsx
  9. 51
      web/client/src/sections/humanAffairs/containers/import-members-modal.js
  10. 3
      web/client/src/sections/humanAffairs/containers/index.js
  11. 3
      web/client/src/sections/humanAffairs/containers/personnelFiles.jsx
  12. 376
      web/client/src/sections/humanAffairs/containers/personnelFilesDetail.jsx
  13. 10
      web/client/src/sections/humanAffairs/nav-item.jsx
  14. 16
      web/client/src/sections/humanAffairs/routes.js

BIN
web/client/assets/images/hrImg/!.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

BIN
web/client/assets/images/hrImg/V.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

BIN
web/client/assets/images/hrImg/setUp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

2
web/client/index.ejs

@ -9,7 +9,7 @@
<link rel="shortcut icon" href="/assets/images/favicon.ico">
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_19077_10.1efd80a22a5e53e48737fd5ab150ffd2.es5.js"></script>
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_20231_3.d613c57d3bf10acf9916c8162dae204a.es5.js"></script>
</head>
<body>

28
web/client/index.html

@ -2,23 +2,23 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
<meta charset="UTF-8">
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
<link rel="shortcut icon" href="/assets/images/favicon.ico">
<link rel="shortcut icon" href="/assets/images/favicon.ico">
<script
src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_19077_11.27aacefc59cea1cbc86236576463a6d2.es5.js"></script>
</head>
<script
src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_20231_3.d613c57d3bf10acf9916c8162dae204a.es5.js"></script>
</head>
<body>
<div id='HrApp' style="height: 100%;"></div>
<div id='HrApp' style="height: 100%;"></div>
<!-- Webpack -->
<script type="text/javascript" src="http://localhost:5701/client/build/app.js"></script>
<!-- Webpack -->
<script type="text/javascript" src="http://localhost:5701/client/build/app.js"></script>
<!-- Vite -->
<!-- <script type="module">
<!-- Vite -->
<!-- <script type="module">
import RefreshRuntime from "http://localhost:5702/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => { }
@ -27,9 +27,9 @@
const global = window
</script>
<script type="module" src="http://localhost:5002/src/index.jsx"></script> -->
<!-- Vite End -->
<!-- Vite End -->
<script>
<script>
//过滤掉一些无用的警告、没有价值的报错
//代理console.warn方法
@ -45,7 +45,7 @@
// _consoleWarn(...rest);
// }
// };
</script>
</script>
</body>
</html>

9
web/client/src/components/setup.jsx

@ -9,7 +9,8 @@ function Setup(props) {
const {
close,
tableType,
tableList
tableList,
length
} = props;
console.log(tableType,
@ -25,7 +26,7 @@ function Setup(props) {
ischeck();
}, []);
function ischeck(value) {
if (check.length >= 8) {
if (check.length >= length) {
if (check.includes(value)) {
return false;
} else {
@ -49,12 +50,12 @@ function Setup(props) {
textAlign: "center",
marginLeft: 6,
background:
check.length == 8
check.length == length
? "rgba(40, 123, 255, 1)"
: "rgba(176, 176, 176, 1)",
}}
>
{check.length}/8
{check.length}/length
</span>
</div>
}

8
web/client/src/sections/humanAffairs/components/personnelModal.jsx

@ -187,7 +187,9 @@ function pushModal (props) {
rules={[{ required: true, message: "请输入人员编号" }]} />
<div style={{ marginLeft: 12, color: '#005ABD', cursor: "pointer", fontSize: 14 }} onClick={() => {
let formList = form.current.getValues()
memberSeach(formList.userCode)
if(formList.userCode){
memberSeach(formList.userCode)
}
}}>
搜索
</div>
@ -328,7 +330,7 @@ function pushModal (props) {
label='籍贯:'
showClear
style={{ width: 184 }}
initValue={editObj?.nativePlace.split('-') || ""}
initValue={editObj?.nativePlace?.split('-') || ""}
>
</Form.Cascader>
</div>
@ -371,7 +373,7 @@ function pushModal (props) {
field='workPlace'
label='工作地点:'
showClear
initValue={editObj?.workPlace.split('-') || ""}
initValue={editObj?.workPlace?.split('-') || ""}
style={{ width: 184 }}
>
</Form.Cascader>

344
web/client/src/sections/humanAffairs/containers/employeeInformation.jsx

@ -0,0 +1,344 @@
import React, { useEffect, useState, useRef } from 'react';
import { connect } from 'react-redux';
import { Select, SkeletonScreen, Button, Pagination, Skeleton, Form } from '@douyinfe/semi-ui';
import { IconSearch } from '@douyinfe/semi-icons';
import '../style.less'
import { Setup } from "$components";
import moment from 'moment'
import { set } from 'nprogress';
const employeeInformation = (props) => {
const { dispatch, actions, history, user, loading, socket, xqMembers } = props
const { humanAffairs } = actions;
const form = useRef();//
let [archivesList, setArchivesList] = useState([]);
const [personnelModal, setPersonnelModal] = useState(false);//
const [exportModalVs, setExportModalVs] = useState(false);
const [keyword, setKeyword] = useState('');//
const [keywordTarget, setKeywordTarget] = useState('');//
const [downloadUrl, setDownloadUrl] = useState('')
let [typeChoose, setTypeChoose] = useState('');
const [setup, setSetup] = useState(false);//
const [setupp, setSetupp] = useState([]);//
const [query, setQuery] = useState({ limit: 10, page: 0 }); //
const [limits, setLimits] = useState()//
const EMPLOYEEINFORMATION = "employeeInformation";
const tableList = [//
{
title: '推送信息',
list: [
{ name: "策略类型", value: "pushWay" },
{ name: "推送机制", value: "noticeWay" },
{ name: "监听设备数量", value: "monitorCount" },
{ name: "累计推送次数", value: "logCount" },
]
}
];
useEffect(() => {
getMemberSearchList()
// attribute();
// localStorage.getItem(EMPLOYEEINFORMATION) == null
// ? localStorage.setItem(
// EMPLOYEEINFORMATION,
// JSON.stringify(['pushWay','noticeWay','logCount','monitorCount'])
// )
// : "";
}, [typeChoose])
function getMemberSearchList () {//
dispatch(humanAffairs.getMemberList({ keywordTarget, keyword, state: typeChoose })).then((res) => {//
if (res.success) {
setArchivesList(res.payload?.data?.rows)
}
})
}
function typeOnChange (e) {//
setTypeChoose(e.target.value);
}
function seachValueChange (value) {
setKeyword(value)
}
//
function attribute () {
const arr = localStorage.getItem(EMPLOYEEINFORMATION)
? JSON.parse(localStorage.getItem(EMPLOYEEINFORMATION))
: [];
const column = [
{
title: "关联项目",
dataIndex: "noticeWay",
key: "noticeWay",
render: (_, r, index) => {
return r.noticeWay;
},
},
{
title: "创建时间",
dataIndex: "logCount",
key: "logCount",
render: (_, r, index) => {
return (r.logCount + '次')
},
},
{
title: "接收人",
dataIndex: "monitorCount",
key: "monitorCount",
render: (_, r, index) => {
return r.monitorCount
},
},
{
title: "监听问题",
dataIndex: "pushWay",
key: "pushWay",
render: (_, r, index) => {
return r.pushWay == 'email' ? '邮件通知' : '短信通知';
},
},
{
title: "通知时效",
dataIndex: "text1",
key: "text1",
render: (_, r, index) => {
return r.text1
},
},
{
title: "启用状态",
dataIndex: "text2",
key: "text2",
render: (_, r, index) => {
return r.text2
},
},
{
title: "推送次数",
dataIndex: "time",
key: "time",
render: (_, r, index) => {
return r.time
},
},
];
for (let i = 0; i < arr.length; i++) {
let colum = column.filter((item) => {
return item.key === arr[i];
});
columns.splice(i + 2, 0, colum[0]);
}
setSetupp(columns);
}
return (
<>
<div style={{ padding: '0px 12px' }}>
<div style={{ display: 'flex' }}>
<div style={{ color: 'rgba(0,0,0,0.45)', fontSize: 14 }}>人事管理</div>
<div style={{ color: 'rgba(0,0,0,0.45)', fontSize: 14, margin: '0px 8px' }}>/</div>
<div style={{ color: 'rgba(0,0,0,0.45)', fontSize: 14 }}>档案中心</div>
<div style={{ color: '#033C9A', fontSize: 14, margin: '0px 8px' }}>/</div>
<div style={{ color: '#033C9A', fontSize: 14 }}>人员档案</div>
</div>
<div style={{ background: '#FFFFFF', boxShadow: '0px 0px 12px 2px rgba(220,222,224,0.2)', borderRadius: 2, padding: '20px 0px 20px 19px ', marginTop: 12 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<div style={{ width: 0, height: 20, borderLeft: '3px solid #0F7EFB', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div>
<div style={{ fontFamily: "YouSheBiaoTiHei", fontSize: 24, color: '#033C9A', marginLeft: 8 }}>员工信息</div>
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>EMPLOYEE INFORMATION</div>
</div>
</div>
<div style={{ marginRight: 20, marginTop: 18 }}>
<Form
labelPosition="left"
labelAlign="right"
labelWidth="80px"
onValueChange={(values, field) => {
console.log('values', values);
}}
getFormApi={(formApi) => (form.current = formApi)}
>
<div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Form.Select value={keywordTarget}
pure onChange={setKeywordTarget} placeholder='请选择搜索类型' style={{ width: 200 }} showClear>
<Select.Option value='role'>职位</Select.Option>
<Select.Option value='dep'>部门</Select.Option>
<Select.Option value='number'>编号</Select.Option>
<Select.Option value='name'>姓名</Select.Option>
</Form.Select>
<Form.Input suffix={<IconSearch />}
pure
showClear
placeholder='请输入或选择关键词'
value={keyword}
style={{ width: 346, marginLeft: 12, marginRight: 12 }}
onChange={seachValueChange}>
</Form.Input>
<Form.DatePicker
label='入职时间:'
field='enableType' type="dateRange" density="compact" showClear style={{ width: 370, color: "#F9F9F9" }} />
</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Form.Select
label='婚姻状况:'
labelPosition="left"
field='enableType'
style={{ width: 246, marginRight: 20, color: "#F9F9F9", }}
placeholder="全部"
filter
showClear
>
{/* {.map((item) => {
return (
<Form.Select.Option key={item.value} value={item.value}>
{item.name}
</Form.Select.Option>
);
})} */}
</Form.Select>
<Form.Select
label='户籍地:'
labelPosition="left"
field='enableType'
style={{ width: 246, marginRight: 20, color: "#F9F9F9", }}
placeholder="全部"
filter
showClear
>
{/* {.map((item) => {
return (
<Form.Select.Option key={item.value} value={item.value}>
{item.name}
</Form.Select.Option>
);
})} */}
</Form.Select>
<Form.Select
label='工作地点:'
labelPosition="left"
field='enableType'
style={{ width: 246, marginRight: 20, color: "#F9F9F9", }}
placeholder="全部"
filter
showClear
>
{/* {.map((item) => {
return (
<Form.Select.Option key={item.value} value={item.value}>
{item.name}
</Form.Select.Option>
);
})} */}
</Form.Select>
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<img src="/assets/images/hrImg/export.png" alt="" style={{ width: 20, height: 20, cursor: "pointer", marginRight: 15 }}
// onClick={() => setSetup(true)}
/>
<img src="/assets/images/hrImg/setup.png" alt="" style={{ width: 20, height: 20, cursor: "pointer", marginRight: 15 }}
onClick={() => setSetup(true)}
/>
<Button theme='solid' type='primary' style={{ width: 80, borderRadius: 2, height: 32, background: '#DBECFF', color: '#005ABD' }}
onClick={() => {
// dispatch(humanAffairs.getMemberList({ keywordTarget, keyword, state: typeChoose })).then((res) => {//
// if (res.success) {
// setArchivesList(res.payload.data.rows)
// }
// })
}}>查询</Button>
</div>
</div>
</div>
</Form>
<div style={{ border: '1px solid #C7E1FF', background: '#F4F8FF', borderRadius: 2, height: 32, width: 669, padding: '8px 0px 7px 12px', display: 'flex', alignItems: 'center', color: '#0F7EFB', fontSize: 12 }}>
<img src="/assets/images/hrImg/!.png" alt="" style={{ width: 14, height: 14, marginRight: 8 }} />
表格中带有认证标识"
<img src="/assets/images/hrImg/V.png" alt="" style={{ width: 14, height: 14 }} />
"信息的为系统基础数据来源于项企PEP钉钉等系统其他数据均为导入或自定义数据
</div>
{/* <div style={{ marginTop: 20 }}>
<Skeleton
// loading={loading}
loading={false}
active={true}
placeholder={SkeletonScreen()}
>
<Table
columns={setupp.filter((s) => s)}
dataSource={tableData}
bordered={false}
empty="暂无数据"
pagination={false}
onRow={handleRow}
rowSelection={rowSelection}
/>
</Skeleton>
<div
style={{
display: "flex",
justifyContent: "space-between",
padding: "20px 20px",
}}
>
<div>
</div>
<div style={{ display: 'flex', }}>
<span style={{ lineHeight: "30px", fontSize: 13, color: 'rgba(0,90,189,0.8)' }}>
{limits}条信息
</span>
<Pagination
className="22"
total={limits}
showSizeChanger
currentPage={query.page + 1}
pageSizeOpts={[10, 20, 30, 40]}
onChange={(currentPage, pageSize) => {
setQuery({ limit: pageSize, page: currentPage - 1 });
page.current = currentPage - 1
}}
/>
</div>
</div>
</div> */}
</div>
</div>
</div>
{setup ? (
<Setup
tableType={EMPLOYEEINFORMATION}
tableList={tableList}
length={25}
close={() => {
setSetup(false);
attribute();
// setcameraSetup(false);
}}
/>
) : (
""
)}
</>
)
}
function mapStateToProps (state) {
const { auth, global, MemberSearch, webSocket } = state;
return {
// loading: members.isRequesting,
user: auth.user,
actions: global.actions,
xqMembers: MemberSearch.data,
// socket: webSocket.socket
};
}
export default connect(mapStateToProps)(employeeInformation);

51
web/client/src/sections/humanAffairs/containers/import-members-modal.js

@ -31,8 +31,24 @@ const ImportMembersModal = props => {
}
}
const dldCsvMb = () => {
//表头
let head = "人员编号,姓名,证件号,性别(男/女),出生年月日(例2022/02/01),籍贯,婚育状态(已婚/未婚/已婚已育),政治面貌,联系方式,工作地点,毕业院校,学历,专业,毕业时间,入职时间,转试用期时间,转正时间,离职日期,工作经验(年),历史工作经历与职务\n"
//数据
//let data = 1 + ',' + 2 + ',' + 3 + ',' + 4 + ',' + 5
let templateCsv = "data:text/csv;charset=utf-8,\ufeff" + head;
//创建一个a标签
let link = document.createElement("a");
//为a标签设置属性
link.setAttribute("href", templateCsv);
link.setAttribute("download", "人资系统人员信息导入模板.csv");
//点击a标签
link.click();
}
const download = () => {
dldTemplate();
//dldTemplate();
dldCsvMb();
let str = "";
rule.forEach((v, i) => {
str += `${v}\r\n`
@ -40,21 +56,21 @@ const ImportMembersModal = props => {
dldText("填写说明.txt", str);
}
const dldTemplate = () => {
let dataTable = [];
let option = {};
option.fileName = '人资系统人员信息导入模板';
option.datas = [
{
sheetData: dataTable,
sheetName: '人资系统人员信息导入模板',
sheetFilter: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中需显示的列数据
sheetHeader: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中每列的表头名称
}
]
let toExcel = new ExportJsonExcel(option); //生成excel文件
toExcel.saveExcel(); //下载excel文件
}
// const dldTemplate = () => {
// let dataTable = [];
// let option = {};
// option.fileName = '人资系统人员信息导入模板';
// option.datas = [
// {
// sheetData: dataTable,
// sheetName: '人资系统人员信息导入模板',
// sheetFilter: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中需显示的列数据
// sheetHeader: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'], //excel文件中每列的表头名称
// }
// ]
// let toExcel = new ExportJsonExcel(option); //生成excel文件
// toExcel.saveExcel(); //下载excel文件
// }
const dldText = (filename, text) => {
var element = document.createElement('a');
@ -68,7 +84,7 @@ const ImportMembersModal = props => {
document.body.removeChild(element);
}
//const action = '/file/qiniu/upload?type=excel&token=' + user.token;
const fileLimit = '.xls,.xlsx,.csv';
const fileLimit = '.csv';
const getFileBlob = (url) => {
return new Promise((resolve, reject) => {
@ -88,6 +104,7 @@ const ImportMembersModal = props => {
const workbook = XLSX.read(result, {
type: "binary",
cellDates: true,//设为true,将天数的时间戳转为时间格式
codepage: 936
});
let data = []; // 存储获取到的数据
// 遍历每张工作表进行读取(这里默认只读取第一张表)

3
web/client/src/sections/humanAffairs/containers/index.js

@ -2,5 +2,6 @@
import PersonnelFiles from './personnelFiles';
import PersonnelFilesDetail from './personnelFilesDetail';
import EmployeeInformation from './employeeInformation';
export { PersonnelFiles, PersonnelFilesDetail };
export { PersonnelFiles, PersonnelFilesDetail, EmployeeInformation };

3
web/client/src/sections/humanAffairs/containers/personnelFiles.jsx

@ -32,6 +32,7 @@ const Rest = (props) => {
}, [typeChoose])
function getMemberSearchList () {//
dispatch(humanAffairs.getMemberSearch())
dispatch(humanAffairs.getMemberList({ keywordTarget, keyword, state: typeChoose })).then((res) => {//
if (res.success) {
setArchivesList(res.payload?.data?.rows)
@ -161,7 +162,7 @@ const Rest = (props) => {
<div style={{ marginLeft: 4 }}>
<div style={{ display: 'flex' }}>
<div style={{ color: '#005ABD', fontSize: 14, marginRight: 6 }}>
{item.pepUserId}
{item.userCode}
</div>
{
item.departmrnt.map((ite, idx) => {

376
web/client/src/sections/humanAffairs/containers/personnelFilesDetail.jsx

@ -151,99 +151,134 @@ const Rest = (props) => {
}
})
}
function getWorkOption () {//线
function getWorkOption () {//线
let date = [];
let showdate = []
let showdate1 = []
dispatch(humanAffairs.getMemberOvertime({ pepUserId: history?.location?.search.slice(1), startDate: startDate, endDate: endDate })).then((res) => {//
if (res.success) {
setTableData(res.payload?.data?.data)
setTableStatistic(res.payload?.data)
}
})
var date = [];
date.push([2017, 6, 1].join("/"));
date.push([2017, 6, 2].join("/"));
date.push([2017, 6, 3].join("/"));
date.push([2017, 6, 4].join("/"));
date.push([2017, 6, 5].join("/"));
date.push([2017, 6, 6].join("/"));
date.push([2017, 6, 7].join("/"));
date.push([2017, 6, 8].join("/"));
date.push([2017, 6, 9].join("/"));
let data = {
legend: {
data: ["调休", "折算"],
left: 'right',
icon: 'roundRect',
itemHeight: 3, //
},
color: ['#0F7EFB', '#FE9812'], //线
xAxis: [
{
boundaryGap: false,
data: date,
},
],
yAxis: [
{
type: "value",
name: '小时'
},
],
dataZoom: [
{
id: "dataZoomX",
type: "slider",
start: 0,
end: 100,
handleIcon:
"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
handleSize: "80%",
},
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
let textdate = [];
for (let i = 0; i < res.payload?.data?.dayStatisticData?.length; i++) {
if (textdate.findIndex((ev) => {
return ev.time == moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM')
}) !== -1) {
textdate[textdate.findIndex((ev) => {
return ev.time == moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM')
})].num
=
textdate[textdate.findIndex((ev) => {
return ev.time == moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM')
})].num + res.payload.data.dayStatisticData[i].duration / 3600
}
else {
textdate.push({
time: moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM'),
num: res.payload.data.dayStatisticData[i].duration / 3600,
compensate: res.payload.data.dayStatisticData[i].compensate
})
}
}
console.log('textdate', textdate);
for (let l = 0; l < textdate.length; l++) {
if (textdate[l].compensate == '调休') {
showdate.push([textdate[l].time, textdate[l].num])
}
else {
showdate1.push([textdate[l].time, textdate[l].num])
}
}
},
series: [
{
name: "调休",
type: "line",
areaStyle: {
color: 'rgba(14,156,255,0.5)',
opacity: 0.1
if (!startDate && !endDate) {
for (let i = 0; i < 12; i++) {
date.unshift(moment(new Date()).subtract(i, 'months').format('YYYY/MM'));
}
}
else {
let nowdate = moment(startDate).format('YYYY/MM')
date.push(nowdate)
for (let o = 0; o < 10000; o++) {
if (nowdate !== moment(endDate).format('YYYY/MM')) {
nowdate = moment(nowdate).add(1, 'months').format('YYYY/MM')
date.push(nowdate)
}
else {
break
}
}
}
let data = {
legend: {
data: ["调休", "折算"],
left: 'right',
icon: 'roundRect',
itemHeight: 3, //
},
smooth: true,
data: [
["2017/6/1", 1],
["2017/6/3", 3],
["2017/6/5", 5],
["2017/6/7", 4],
["2017/6/9", 4],
color: ['#0F7EFB', '#FE9812'], //线
xAxis: [
{
boundaryGap: false,
data: date,
},
],
yAxis: [
{
type: "value",
name: '小时'
},
],
},
{
name: "折算",
type: "line",
areaStyle: {
color: 'rgba(254,152,18,0.2)',
dataZoom: [
{
id: "dataZoomX",
type: "slider",
start: 0,
end: 100,
handleIcon:
"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
handleSize: "80%",
},
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
smooth: true,
data: [
["2017/6/2", 3],
["2017/6/4", 1],
["2017/6/6", 6],
["2017/6/8", 3],
series: [
{
name: "调休",
type: "line",
areaStyle: {
color: 'rgba(14,156,255,0.5)',
opacity: 0.1
},
smooth: true,
data: showdate,
},
{
name: "折算",
type: "line",
areaStyle: {
color: 'rgba(254,152,18,0.2)',
},
smooth: true,
data: showdate1,
},
],
},
],
}
setOption(data)
}
setOption(data)
}
})
}
function getLeaveOption () {//线
let date = [];
let showdate = []
dispatch(humanAffairs.getMemberVacate({ pepUserId: history?.location?.search.slice(1), startDate: startDate, endDate: endDate })).then((res) => {//
if (res.success) {
setLeaveData(res.payload?.data?.data)
@ -270,78 +305,109 @@ const Rest = (props) => {
setLeaveStatistic({
compassionate, sick, year, other, all
})
}
})
var date = [];
date.push([2017, 6, 1].join("/"));
date.push([2017, 6, 2].join("/"));
date.push([2017, 6, 3].join("/"));
date.push([2017, 6, 4].join("/"));
date.push([2017, 6, 5].join("/"));
date.push([2017, 6, 6].join("/"));
date.push([2017, 6, 7].join("/"));
date.push([2017, 6, 8].join("/"));
date.push([2017, 6, 9].join("/"));
let data = {
color: ['#0F7EFB', '#FE9812'], //线
xAxis: [
{
boundaryGap: false,
data: date,
},
],
yAxis: [
{
type: "value",
name: '小时'
},
],
dataZoom: [
{
id: "dataZoomX",
type: "slider",
start: 0,
end: 100,
handleIcon:
"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
handleSize: "80%",
},
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
let textdate = [];
for (let i = 0; i < res.payload?.data?.dayStatisticData?.length; i++) {
if (textdate.findIndex((ev) => {
return ev.time == moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM')
}) !== -1) {
textdate[textdate.findIndex((ev) => {
return ev.time == moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM')
})].num
=
textdate[textdate.findIndex((ev) => {
return ev.time == moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM')
})].num + res.payload.data.dayStatisticData[i].duration / 3600
}
else {
textdate.push({
time: moment(res.payload.data.dayStatisticData[i].day).format('YYYY/MM'),
num: res.payload.data.dayStatisticData[i].duration / 3600
})
}
}
},
series: [
{
name: "调休",
type: "line",
areaStyle: {
color: 'rgba(14,156,255,0.5)',
opacity: 0.1
for (let l = 0; l < textdate.length; l++) {
showdate.push([textdate[l].time, textdate[l].num])
}
if (!startDate && !endDate) {
for (let i = 0; i < 12; i++) {
date.unshift(moment(new Date()).subtract(i, 'months').format('YYYY/MM'));
}
}
else {
let nowdate = moment(startDate).format('YYYY/MM')
date.push(nowdate)
for (let o = 0; o < 10000; o++) {
if (nowdate !== moment(endDate).format('YYYY/MM')) {
nowdate = moment(nowdate).add(1, 'months').format('YYYY/MM')
date.push(nowdate)
}
else {
break
}
}
}
let data = {
color: ['#0F7EFB', '#FE9812'], //线
xAxis: [
{
boundaryGap: false,
data: date,
},
],
yAxis: [
{
type: "value",
name: '小时'
},
],
dataZoom: [
{
id: "dataZoomX",
type: "slider",
start: 0,
end: 100,
handleIcon:
"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
handleSize: "80%",
},
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
smooth: true,
data: [
["2017/6/1", 1],
["2017/6/3", 3],
["2017/6/5", 5],
["2017/6/7", 4],
["2017/6/9", 4],
series: [
{
name: "调休",
type: "line",
areaStyle: {
color: 'rgba(14,156,255,0.5)',
opacity: 0.1
},
smooth: true,
data: showdate,
},
],
},
],
}
setLeaveOption(data)
}
setLeaveOption(data)
}
})
}
function handleChange (date) {
console.log('datedatedatedate', date);
setStartDate(moment(date[0]).format('YYYY-MM-DD'))
setEndDate(moment(date[1]).format('YYYY-MM-DD'))
if (date.length > 1) {
setStartDate(moment(date[0]).format('YYYY-MM-DD'))
setEndDate(moment(date[1]).format('YYYY-MM-DD'))
}
else {
setStartDate('')
setEndDate('')
}
}
return (
<>
@ -616,7 +682,7 @@ const Rest = (props) => {
试用期
</div>
<div style={{ color: '#4A4A4A', fontSize: 13 }}>
{pepObj.regularDate ? moment(pepObj.regularDate).diff(pepObj.hiredate, 'months', true) + '个月' : '暂无'}
{pepObj.regularDate ? moment(pepObj.regularDate).diff(pepObj.hiredate, 'months', true).toFixed(1) + '个月' : '暂无'}
</div>
</div>
{
@ -635,7 +701,7 @@ const Rest = (props) => {
</div>
</div>
<div style={{ borderRight: '1px solid #DCDEE0', margin: '-16px 0px -20px 0px' }}></div>
<div style={{ marginLeft: 30, marginTop: 8, paddingRight: 30 }}>
<div style={{ marginLeft: 30, marginTop: 8, paddingRight: 30, width: '38%' }}>
<div style={{ color: '#4A4A4A', fontSize: 14 }}>
/她的历史工作经历与职务
</div>
@ -646,8 +712,8 @@ const Rest = (props) => {
</div>
<div style={{ borderBottom: '1px solid #DCDEE0', margin: '24px 0px 24px -20px' }}></div>
<div style={{ paddingLeft: 17 }}>
<div style={{ color: '#4A4A4A', fontSize: 14, marginBottom: 10 }}>
动作
<div style={{ color: '#4A4A4A', fontSize: 14, marginBottom: 10, fontWeight: 'bold' }}>
动作
</div>
<div style={{ color: '#4A4A4A', fontSize: 14, display: 'flex', alignItems: 'center' }}>
时间筛选<DatePicker onChange={handleChange} type="dateRange" density="compact" style={{ width: 242 }} />
@ -685,7 +751,7 @@ const Rest = (props) => {
工作日
</div>
<div style={{ fontSize: 14, color: '#005ABD', marginLeft: 5 }}>
{tableStatistic.sumPayWorkday / 60 / 60 + tableStatistic.sumTakeRestWorkday / 60 / 60||0}小时
{tableStatistic.sumPayWorkday / 60 / 60 + tableStatistic.sumTakeRestWorkday / 60 / 60 || 0}小时
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', width: '19.87%' }}>
@ -693,7 +759,7 @@ const Rest = (props) => {
普通假日
</div>
<div style={{ fontSize: 14, color: '#005ABD', marginLeft: 5 }}>
{tableStatistic.sumTakeRestDayoff / 60 / 60 + tableStatistic.sumTakeRestDayoff / 60 / 60||0}小时
{tableStatistic.sumTakeRestDayoff / 60 / 60 + tableStatistic.sumTakeRestDayoff / 60 / 60 || 0}小时
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', width: '19.03%' }}>
@ -701,7 +767,7 @@ const Rest = (props) => {
法定假日
</div>
<div style={{ fontSize: 14, color: '#005ABD', marginLeft: 5 }}>
{tableStatistic.sumPayFestivals / 60 / 60 + tableStatistic.sumTakeRestFestivals / 60 / 60||0}小时
{tableStatistic.sumPayFestivals / 60 / 60 + tableStatistic.sumTakeRestFestivals / 60 / 60 || 0}小时
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', width: '19.217%' }}>
@ -709,7 +775,7 @@ const Rest = (props) => {
累计加班时长
</div>
<div style={{ fontSize: 14, color: '#005ABD', marginLeft: 5 }}>
{tableStatistic.sumPayWorkday / 60 / 60 + tableStatistic.sumTakeRestWorkday / 60 / 60 + tableStatistic.sumTakeRestDayoff / 60 / 60 + tableStatistic.sumTakeRestDayoff / 60 / 60 + tableStatistic.sumPayFestivals / 60 / 60 + tableStatistic.sumTakeRestFestivals / 60 / 60||0}小时
{tableStatistic.sumPayWorkday / 60 / 60 + tableStatistic.sumTakeRestWorkday / 60 / 60 + tableStatistic.sumTakeRestDayoff / 60 / 60 + tableStatistic.sumTakeRestDayoff / 60 / 60 + tableStatistic.sumPayFestivals / 60 / 60 + tableStatistic.sumTakeRestFestivals / 60 / 60 || 0}小时
</div>
</div>
</div>

10
web/client/src/sections/humanAffairs/nav-item.jsx

@ -12,11 +12,19 @@ export function getNavItem (user, dispatch) {
{
itemKey: 'archivesCenter',
text: '档案中心',
icon: <iconpark-icon style={{ width: 20, height: 20 }} name="iconjianshezhong"></iconpark-icon>,
icon: <iconpark-icon style={{ width: 20, height: 20 }} name="iconcbrengongdangan"></iconpark-icon>,
to: '/humanAffairs/archivesCenter/personnelFiles',
items: [{
itemKey: 'personnelFiles', to: '/humanAffairs/archivesCenter/personnelFiles', text: '人员档案'
}]
},{
itemKey: 'employeeRelations',
text: '员工关系',
icon: <iconpark-icon style={{ width: 20, height: 20 }} name="iconcbyuangongguanxi"></iconpark-icon>,
to: '/humanAffairs/employeeRelations/employeeInformation',
items: [{
itemKey: 'employeeInformation', to: '/humanAffairs/employeeRelations/employeeInformation', text: '员工信息'
}]
},
]
},

16
web/client/src/sections/humanAffairs/routes.js

@ -1,4 +1,4 @@
import { PersonnelFiles,PersonnelFilesDetail } from './containers';
import { PersonnelFiles, PersonnelFilesDetail, EmployeeInformation } from './containers';
export default [{
type: 'inner',
@ -17,9 +17,19 @@ export default [{
component: PersonnelFiles,
breadcrumb: '人员档案',
}]
},]
}, {
path: '/employeeRelations',
key: 'employeeRelations',
breadcrumb: '员工关系',
childRoutes: [{
path: '/employeeInformation',
key: 'employeeInformation',
component: EmployeeInformation,
breadcrumb: '员工信息',
}]
}]
}
},{
}, {
type: 'inner',
route: {
path: "/personnelFilesDetail",

Loading…
Cancel
Save