Browse Source

(*)请假统计--添加备注功能以及导出web+api提交

master
Archer_cdm 2 years ago
parent
commit
b96f8ef9cb
  1. 42
      api/app/lib/controllers/attendance/index.js
  2. 43
      api/app/lib/models/vacate_remark.js
  3. 3
      api/app/lib/routes/attendance/index.js
  4. 4
      web/client/src/sections/humanAffairs/actions/index.js
  5. 15
      web/client/src/sections/humanAffairs/actions/vacateRemark.js
  6. 26
      web/client/src/sections/humanAffairs/containers/leaveStatistics.jsx
  7. 48
      web/client/src/sections/humanAffairs/containers/vacateRemark.js
  8. 5
      web/client/src/utils/webapi.js

42
api/app/lib/controllers/attendance/index.js

@ -205,10 +205,14 @@ async function vacateStatistic(ctx) {
startDate, endDate, pepUserIds startDate, endDate, pepUserIds
}) })
const remarkList = await models.VacateRemark.findAll({}); //查询备注
returnD.forEach(u => { returnD.forEach(u => {
let vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId) let vacateStatistic = sumRes.filter(s => s.pepUserId == u.pepUserId)
let remarkData = remarkList.filter(e => e.pepUserId == u.pepUserId)
u.vacateDuration = vacateStatistic.reduce((sum, vs) => sum + vs.duration, 0) u.vacateDuration = vacateStatistic.reduce((sum, vs) => sum + vs.duration, 0)
u.vacateStatistic = vacateStatistic u.vacateStatistic = vacateStatistic
u.remark = remarkData.length ? remarkData[0].remark : null
}) })
ctx.status = 200; ctx.status = 200;
ctx.body = { ctx.body = {
@ -255,6 +259,8 @@ async function exportVacateStatistic(ctx) {
startDate, endDate, pepUserIds startDate, endDate, pepUserIds
}) })
const remarkList = await models.VacateRemark.findAll({}); //查询备注
returnD.forEach(u => { returnD.forEach(u => {
u.departmrnt = u.departmrnt.map(dep => dep.name).join('、') u.departmrnt = u.departmrnt.map(dep => dep.name).join('、')
u.role = u.role.map(r => r.name).join('、') u.role = u.role.map(r => r.name).join('、')
@ -269,6 +275,9 @@ async function exportVacateStatistic(ctx) {
}, 0) }, 0)
} }
u.vacateDayStatisticDuration = (u.vacateDayStatisticDuration || 0) / 3600 u.vacateDayStatisticDuration = (u.vacateDayStatisticDuration || 0) / 3600
u.userActiveStatus = u.userActiveStatus == 1 ? '在职' : u.userActiveStatus == 2 ? '离职' : '特殊状态-特殊账号'
let remarkData = remarkList.filter(e => e.pepUserId == u.pepUserId)
u.remark = remarkData.length ? (remarkData[0].remark == '' ? '无' : remarkData[0].remark) : '无'
}) })
const header = [{ const header = [{
@ -283,6 +292,9 @@ async function exportVacateStatistic(ctx) {
}, { }, {
title: '职位', title: '职位',
key: 'role', key: 'role',
}, {
title: '在职状态',
key: 'userActiveStatus',
},] },]
.concat(vacateTypeRes.map(v => { .concat(vacateTypeRes.map(v => {
return { return {
@ -302,6 +314,12 @@ async function exportVacateStatistic(ctx) {
defaultValue: '0', defaultValue: '0',
}] }]
) )
.concat(
[{
title: '备注',
key: 'remark',
}]
)
const fileName = `请假统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}${startDate && endDate ? '-' : ''}${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}${startDate || endDate ? '_' : ''}${moment().format('YYYYMMDDHHmmss')}` + '.csv' const fileName = `请假统计_${startDate ? moment(startDate).format('YYYY-MM-DD') : ''}${startDate && endDate ? '-' : ''}${endDate ? moment(endDate).format('YYYY-MM-DD') : ''}${startDate || endDate ? '_' : ''}${moment().format('YYYYMMDDHHmmss')}` + '.csv'
const filePath = await simpleExcelDown({ data: returnD, header, fileName: fileName }) const filePath = await simpleExcelDown({ data: returnD, header, fileName: fileName })
@ -320,10 +338,34 @@ async function exportVacateStatistic(ctx) {
} }
} }
// 添加请假统计备注
async function vacateRemark(ctx) {
try {
const { models } = ctx.fs.dc;
const { remark, pepUserId } = ctx.query;
let oldData = await models.VacateRemark.findOne({ where: { pepUserId: pepUserId } });
if (oldData) {
await models.VacateRemark.update({ remark, pepUserId }, { where: { pepUserId: pepUserId } });
} else {
await models.VacateRemark.create({ remark, pepUserId });
}
ctx.status = 200;
ctx.body = '添加备注成功';
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "添加备注失败"
}
}
}
module.exports = { module.exports = {
overtimeStatistic, overtimeStatistic,
exportOvertimeStatistic, exportOvertimeStatistic,
vacateType, vacateType,
vacateStatistic, vacateStatistic,
exportVacateStatistic, exportVacateStatistic,
vacateRemark
}; };

43
api/app/lib/models/vacate_remark.js

@ -0,0 +1,43 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const VacateRemark = sequelize.define("vacateRemark", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "vacate_remark_id_uindex"
},
pepUserId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: 'pep用户id',
primaryKey: false,
field: "pep_user_id",
autoIncrement: false
},
remark: {
type: DataTypes.TEXT,
allowNull: true,
defaultValue: null,
comment: '备注',
primaryKey: false,
field: "remark",
autoIncrement: false
}
}, {
tableName: "vacate_remark",
comment: "",
indexes: []
});
dc.models.VacateRemark = VacateRemark;
return VacateRemark;
};

3
api/app/lib/routes/attendance/index.js

@ -17,4 +17,7 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/attendance/vacate/export'] = { content: '请假统计导出', visible: true }; app.fs.api.logAttr['GET/attendance/vacate/export'] = { content: '请假统计导出', visible: true };
router.get('/attendance/vacate/export', attendance.exportVacateStatistic); router.get('/attendance/vacate/export', attendance.exportVacateStatistic);
app.fs.api.logAttr['PUT/attendance/vacate/creat/remark'] = { content: '添加请假统计备注', visible: true };
router.put('/attendance/vacate/creat/remark', attendance.vacateRemark);
}; };

4
web/client/src/sections/humanAffairs/actions/index.js

@ -8,6 +8,7 @@ import * as personalTrainRecord from './personalTrainRecord'
import * as resourceRepository from './resourceRepository' import * as resourceRepository from './resourceRepository'
import * as employeeCommunication from './employeeCommunication' import * as employeeCommunication from './employeeCommunication'
import * as employeeAssessment from './employeeAssessment' import * as employeeAssessment from './employeeAssessment'
import * as vacateRemark from './vacateRemark'
export default { export default {
...personnelFiles, ...personnelFiles,
@ -17,5 +18,6 @@ export default {
...personalTrainRecord, ...personalTrainRecord,
...resourceRepository, ...resourceRepository,
...employeeCommunication, ...employeeCommunication,
...employeeAssessment ...employeeAssessment,
...vacateRemark
} }

15
web/client/src/sections/humanAffairs/actions/vacateRemark.js

@ -0,0 +1,15 @@
'use strict';
import { ApiTable, basicAction } from '$utils'
export function createVacateRemark(query) {//添加请假统计备注
return (dispatch) => basicAction({
type: "put",
dispatch: dispatch,
query: query,
actionType: "PUT_VACATE_REMARK",
url: `${ApiTable.createVacateRemark}`,
msg: { option: '添加备注' },
reducer: {},
});
}

26
web/client/src/sections/humanAffairs/containers/leaveStatistics.jsx

@ -1,6 +1,7 @@
import React, { useEffect, useState, useRef, useMemo } from 'react'; import React, { useEffect, useState, useRef, useMemo } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Table, Button, Pagination, Skeleton, Form, Tooltip } from '@douyinfe/semi-ui'; import { Table, Button, Pagination, Skeleton, Form, Tooltip } from '@douyinfe/semi-ui';
import VacateRemark from './vacateRemark';
import { IconSearch } from '@douyinfe/semi-icons'; import { IconSearch } from '@douyinfe/semi-icons';
import { SkeletonScreen } from "$components"; import { SkeletonScreen } from "$components";
import '../style.less' import '../style.less'
@ -26,6 +27,8 @@ const leaveStatistics = (props) => {
const [downloadUrl, setDownloadUrl] = useState('')//pdf const [downloadUrl, setDownloadUrl] = useState('')//pdf
const LEAVESTATISTICS = "leaveStatistics"; const LEAVESTATISTICS = "leaveStatistics";
const page = useRef(query.page);// const page = useRef(query.page);//
const [modalV, setModalV] = useState(false);
const [remark, setRemark] = useState(null);
const [tableList, setTableList] = useState([{ const [tableList, setTableList] = useState([{
title: '展示信息', title: '展示信息',
@ -255,7 +258,11 @@ const leaveStatistics = (props) => {
dataIndex: "remark", dataIndex: "remark",
key: "remark", key: "remark",
render: (_, r, index) => { render: (_, r, index) => {
// return (r.vacateCount ? r.vacateCount : '0') return (
r.remark?.length > 22 ? <Tooltip content={r.remark}>
{r.remark.slice(0, 21) + '...'}
</Tooltip> : (r.remark ? r.remark : '无')
)
}, },
}) })
column.push({ column.push({
@ -266,7 +273,10 @@ const leaveStatistics = (props) => {
render: (_, r, index) => { render: (_, r, index) => {
return ( return (
<div> <div>
<span style={{ color: '#1890FF', cursor: 'pointer' }}>添加备注</span> <span style={{ color: '#1890FF', cursor: 'pointer' }} onClick={() => {
setModalV(true);
setRemark({ pepUserId: r.pepUserId, remark: r.remark })
}}>添加备注</span>
</div> </div>
) )
}, },
@ -292,6 +302,11 @@ const leaveStatistics = (props) => {
} }
} }
const scroll = useMemo(() => ({}), []); const scroll = useMemo(() => ({}), []);
const closeAndFetch = () => {
setModalV(false)
getAttendanceVacateList();
}
return ( return (
<> <>
<div style={{ padding: '0px 12px' }}> <div style={{ padding: '0px 12px' }}>
@ -454,6 +469,13 @@ const leaveStatistics = (props) => {
</div> </div>
</div> </div>
</div> </div>
{
modalV ? <VacateRemark
remarkData={remark}
close={() => closeAndFetch()}
onCancel={() => setModalV(false)} /> : ''
}
</div> </div>
{setup ? ( {setup ? (
<Setup <Setup

48
web/client/src/sections/humanAffairs/containers/vacateRemark.js

@ -0,0 +1,48 @@
import React, { useEffect, useRef, useState } from 'react';
import { connect } from "react-redux";
import { Modal, Form } from "@douyinfe/semi-ui";
const VacateRemark = (props) => {
const { dispatch, actions, onCancel, close, remarkData } = props;
console.log(actions, 'actionsactionsactions');
const { humanAffairs } = actions;
const form = useRef();//表单
//初始化
useEffect(() => { }, []);
function handleOk() {
form.current.validate().then((values) => {
dispatch(humanAffairs.createVacateRemark({ pepUserId: remarkData.pepUserId, remark: values.remark || '' })).then((res) => {
if (res.success) {
close();
}
})
})
}
return (
<Modal title='添加备注'
visible={true}
destroyOnClose
okText='保存' width={800}
onOk={handleOk}
onCancel={onCancel}>
<Form getFormApi={(formApi) => (form.current = formApi)} labelPosition={'left'}>
<Form.TextArea
field="remark"
label='备注'
initValue={remarkData?.remark || ""}
placeholder="请输入备注"
/>
</Form>
</Modal>
)
}
function mapStateToProps(state) {
const { global } = state;
return {
actions: global.actions,
};
}
export default connect(mapStateToProps)(VacateRemark);

5
web/client/src/utils/webapi.js

@ -64,7 +64,10 @@ export const ApiTable = {
getEmployeeCommunicate: 'employee/communicate/list', getEmployeeCommunicate: 'employee/communicate/list',
//考核 //考核
getemployeeAssessmentList: 'employessAssessment/list/{type}' getemployeeAssessmentList: 'employessAssessment/list/{type}',
// 请假统计添加备注
createVacateRemark: 'attendance/vacate/creat/remark'
}; };
export const RouteTable = { export const RouteTable = {

Loading…
Cancel
Save