Commit ac4c4c57 authored by 廖旭伟's avatar 廖旭伟

Merge remote-tracking branch 'origin/master'

parents 76e4a7e5 58f8cd80
......@@ -14,7 +14,7 @@ const tagsMap = {
const baseUrl = process.env.VUE_APP_API_BASE_URL + "/";
export default {
mounted() {
this.getData();
// this.getData();
},
watch: {
$route(route) {
......
......@@ -21,7 +21,7 @@
export default {
props: {
thirdList: {
type: Boolean,
type: Array,
default: [],
},
activeName: {
......
......@@ -174,7 +174,6 @@ export default {
value = false;
return;
} else {
console.log(this.attendanceClassDetailList.length, "执行了");
this.attendanceClassDetailList.forEach((item, index) => {
let valueres = this.judgeStatus(
this.attendanceClassDetailList,
......@@ -217,7 +216,6 @@ export default {
},
// 判断添加上下班考勤时间
judgeStatus(arr, index) {
console.log(arr, index, "ces");
let status = true;
if (arr.length == 0) {
} else {
......@@ -266,24 +264,24 @@ export default {
status = false;
return;
}
if (arr.length > 1 && index > 0) {
// 上一次比较
let lastoffTime =
transFormMinut(arr[index - 1].offWorkDate) +
transFormMinut(arr[index - 1].offWorkDateAfter);
// if (arr.length > 1 && index > 0) {
// // 上一次比较
// let lastoffTime =
// transFormMinut(arr[index - 1].offWorkDate) +
// transFormMinut(arr[index - 1].offWorkDateAfter);
let currentwokeTime =
transFormMinut(arr[index].goWorkDate) -
transFormMinut(arr[index].goWorkDateBefore);
// let currentwokeTime =
// transFormMinut(arr[index].goWorkDate) -
// transFormMinut(arr[index].goWorkDateBefore);
if (currentwokeTime <= lastoffTime) {
this.$message.error(
`第${index}上班考勤时间需大于第${index - 1}上班考勤时间`
);
status = false;
return;
}
}
// if (currentwokeTime <= lastoffTime) {
// this.$message.error(
// `第${index}上班考勤时间需大于第${index - 1}上班考勤时间`
// );
// status = false;
// return;
// }
// }
}
return status;
},
......@@ -354,7 +352,6 @@ export default {
});
this.currentIndex = this.attendanceClassDetailList.length - 1;
this.form.classResponsiblePersonId = this.form.classResponsiblePersonId.toString();
console.log(this.currentIndex, "执行了");
}
this.open = true;
},
......
......@@ -64,10 +64,10 @@
/>
<Field
label="时长(单位:)"
label="时长(单位:小时)"
disabled
prop="duration"
v-model="form.duration"
v-model="form.duration / 60 / 60"
placeholder="请输入时长(秒)"
:maxLength="4"
/>
......@@ -169,14 +169,14 @@ export default {
{ required: true, message: "请输入请假人", trigger: "blur" },
],
deptId: [{ required: true, message: "请选择部门", trigger: "change" }],
phoneNumber: [
{ required: true, message: "请输入电话号码", trigger: "blur" },
{
validator: valid.phone,
message: "电话号码格式不正确",
trigger: "blur",
},
],
// phoneNumber: [
// { required: true, message: "请输入电话号码", trigger: "blur" },
// {
// validator: valid.phone,
// message: "电话号码格式不正确",
// trigger: "blur",
// },
// ],
leaveType: [
{ required: true, message: "请选择请假类型", trigger: "change" },
],
......@@ -187,9 +187,9 @@ export default {
{ required: true, message: "请选择结束时间", trigger: "change" },
],
duration: [{ required: true, message: "请输入时长", trigger: "blur" }],
reason: [
{ required: true, message: "请输入请假理由", trigger: "blur" },
],
// reason: [
// { required: true, message: "请输入请假理由", trigger: "blur" },
// ],
approverId: [
{ required: true, message: "请选择审批人", trigger: "change" },
],
......
......@@ -282,9 +282,11 @@ export default {
},
// 表格接收数据后
afterRender(data) {
console.log(data);
let addobjArr = [];
data.dyncColumns.map((item) => {
let obj = {
show: true,
label: item.name,
prop: "",
formatter: (row) => {
......@@ -299,6 +301,7 @@ export default {
}
},
};
addobjArr.push(obj);
});
this.config.columns = [...this.initalArr, ...addobjArr];
this.$refs.layoutTable.showType = "tableSelect";
......@@ -512,6 +515,8 @@ export default {
},
data() {
return {
// 动态新增列表
addColumn: [],
progress: false,
percent: 0,
upload: {
......@@ -666,25 +671,25 @@ export default {
show: true,
},
{
label: "考勤打卡记录详细信息",
width: 120,
prop: "subColumns",
show: true,
formatter: (row) => {
let widthsize = this.columnSet.reduce((pre, cur) => {
return pre + Number(cur.width);
}, 50);
return (
<el-popover placement="right" width={widthsize} trigger="click">
{this.renderTable(row.attendanceRecordDetailList)}
<el-button type="text" slot="reference">
详细
</el-button>
</el-popover>
);
},
},
// {
// label: "考勤打卡记录详细信息",
// width: 120,
// prop: "subColumns",
// show: true,
// formatter: (row) => {
// let widthsize = this.columnSet.reduce((pre, cur) => {
// return pre + Number(cur.width);
// }, 50);
// return (
// <el-popover placement="right" width={widthsize} trigger="click">
// {this.renderTable(row.attendanceRecordDetailList)}
// <el-button type="text" slot="reference">
// 详细
// </el-button>
// </el-popover>
// );
// },
// },
// {
// label: "操作",
// width: 240,
......
......@@ -168,9 +168,18 @@ export default {
let index = arr.findIndex((item) => item.createTime == currentTime);
if (index > -1) {
return arr[index].attendanceSummary ? (
<el-tag type={"danger"} size="mini">
{arr[index].attendanceSummary}
</el-tag>
<el-tooltip
class="item"
effect="dark"
content={
arr[index].createTime + " " + arr[index].attendanceSummary
}
placement="top-start"
>
<el-tag type={"danger"} size="mini">
{arr[index].attendanceSummary}
</el-tag>
</el-tooltip>
) : (
"-"
);
......
<template>
<div className="page">
<el-card style="height:80vh;overflow:scroll-y">
<LayoutTable notPagination :data="tableData" ref="layoutTable" :config="tableConfig" notSearch></LayoutTable>
</el-card>
<drawer-show ref="drawerform" @ok="getData" />
</div>
<div className="page">
<el-card style="height:80vh;overflow:scroll-y">
<LayoutTable
notPagination
:data="tableData"
notAdd
notDel
ref="layoutTable"
:config="tableConfig"
notSearch
></LayoutTable>
</el-card>
<drawer-show ref="drawerform" @ok="getData" />
</div>
</template>
<script>
/** 表单弹出框模式需引入 */
import {handleTree} from "@/assets/utils/table";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import drawerShow from "./drawershow";
import table from "@/assets/mixins/table";
export default {
name: "DeptList",
components: {
drawerShow,
Treeselect
},
mixins: [table],
created() {
this.query={"page":1,"size":-1}
},
methods: {
/** 重写新增方法 */
toAdd(row) {
this.$refs.drawerform.add(row,this.menuOptions);
},
/** 重写编辑方法 */
toEdit(row) {
this.$refs.drawerform.edit(row,this.menuOptions);
},
/** 重写查看方法 */
toView(row) {
this.$refs.drawerform.view(row, this.menuOptions);
},
afterRender(data) {
data.data = handleTree(data.data, "id", "parentId");
console.log("tree data:",data.data)
this.menuOptions = data.data;
this.$refs.layoutTable.showType = "treetable"
},
},
data() {
return {
config: {
showType:'treetable',
isshowTabPane:true,
/** 树表是否默认展开 */
expand: false,
columns: [
{type: "selection", width: 60},
{label: "部门名称", prop: "deptName"},
{label: "成员数量", prop: "personNum"},
{label: "负责人", prop: "workName"},
/** 表单弹出框模式需引入 */
import { handleTree } from "@/assets/utils/table";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import drawerShow from "./drawershow";
import table from "@/assets/mixins/table";
export default {
name: "DeptList",
components: {
drawerShow,
Treeselect,
},
mixins: [table],
created() {
this.query = { page: 1, size: -1 };
},
methods: {
/** 重写新增方法 */
toAdd(row) {
this.$refs.drawerform.add(row, this.menuOptions);
},
/** 重写编辑方法 */
toEdit(row) {
this.$refs.drawerform.edit(row, this.menuOptions);
},
/** 重写查看方法 */
toView(row) {
this.$refs.drawerform.view(row, this.menuOptions);
},
afterRender(data) {
data.data = handleTree(data.data, "id", "parentId");
console.log("tree data:", data.data);
this.menuOptions = data.data;
this.$refs.layoutTable.showType = "treetable";
},
},
data() {
return {
config: {
showType: "treetable",
isshowTabPane: true,
/** 树表是否默认展开 */
expand: false,
columns: [
{ type: "selection", width: 60 },
{ label: "部门名称", prop: "deptName" },
{ label: "成员数量", prop: "personNum" },
{ label: "负责人", prop: "workName" },
// {label: "部门状态", prop: "deptStatus",formatter: this.formatter},
// {label: "部门状态", prop: "deptStatus",formatter: this.formatter},
// {label: "顺序", prop: "orderNum",formatter: this.formatter},
// {label: "顺序", prop: "orderNum",formatter: this.formatter},
// {label: "创建用户", prop: "createUserId", formatter: this.formatter},
{
label: "操作",
width: 240,
formatter: row => {
return (
<table-buttons noAdd noView row={row} onEdit={this.toEdit} onView={this.toView} onDel={this.toDel} />
)
}
}
]
}
};
}
// {label: "创建用户", prop: "createUserId", formatter: this.formatter},
// {
// label: "操作",
// width: 240,
// formatter: (row) => {
// return (
// <table-buttons
// noAdd
// noView
// row={row}
// onEdit={this.toEdit}
// onView={this.toView}
// onDel={this.toDel}
// />
// );
// },
// },
],
},
};
</script>
\ No newline at end of file
},
};
</script>
......@@ -7,7 +7,7 @@
@handleClick="handleClick"
></tab-pane>
</div>
<div class="totalNum flex" v-if="tableData.staff">
<!-- <div class="totalNum flex" v-if="tableData.staff">
<div class="item">
在职员工 <span class="num">{{ tableData.staff.inWorkStaff }}</span>
</div>
......@@ -34,7 +34,7 @@
待离职 <span class="num">{{ tableData.staff.resignationStaff }}</span>
</div>
</div>
</div>
</div> -->
<el-row :gutter="20">
<el-col :span="6" :xs="12" class="mytree">
<div class="titles">选择部门</div>
......@@ -59,7 +59,7 @@
</el-col>
<el-col :span="18" :xs="12">
<el-row>
<LayoutTable notDel :data="tableData" :config="tableConfig">
<LayoutTable notDel notAdd :data="tableData" :config="tableConfig">
<el-button
type="primary"
@click="doExport"
......@@ -104,9 +104,7 @@
<i class="el-icon-refresh"></i>
<span
>上次同步时间:{{
tableData.staff
? tableData.staff.refreshDate
: "--"
tableData.staff ? tableData.staff.refreshDate : "--"
}}</span
>
</span>
......@@ -416,7 +414,14 @@ export default {
};
</script>
<style>
<style lang="less" scoped>
/deep/.el-tree-node__expand-icon {
font-size: 18px !important;
color: #606266;
}
/deep/.el-tree-node__content {
padding-left: 2px !important;
}
.el-card__body {
padding: 10px;
}
......@@ -556,7 +561,7 @@ export default {
border-top: 1px dashed #4386c6;
height: 20px;
top: 12px;
width: 24px;
width: 20px;
}
}
.titles {
......
......@@ -150,6 +150,39 @@
</properties>
</profile>
<profile>
<id>reg</id>
<properties>
<profiles.active>reg</profiles.active>
<profiles.server.port>17500</profiles.server.port>
<profiles.server.path>/attendance</profiles.server.path>
<profiles.publish.path>/home/publish</profiles.publish.path>
<profiles.nacos.server-addr>127.0.0.1:8848</profiles.nacos.server-addr>
<profiles.nacos.group>DEFAULT_GROUP</profiles.nacos.group>
<profiles.nacos.namespace>smart-gov</profiles.nacos.namespace>
<profiles.log.path>/home/mortals/app/logs</profiles.log.path>
<profiles.log.level>INFO</profiles.log.level>
<profiles.sms.smsSendUrl>http://sms.wx3.com.cn/api/index/index</profiles.sms.smsSendUrl>
<profiles.sms.apiId>ADsUXLrS81vZDU95</profiles.sms.apiId>
<profiles.hik.host>10.207.153.105:443</profiles.hik.host>
<profiles.hik.protocol>https://</profiles.hik.protocol>
<profiles.hik.appKey>25594054</profiles.hik.appKey>
<profiles.hik.appSecret>K12IkZoSLxpsJjrUPtfV</profiles.hik.appSecret>
<profiles.dingtalk.domain>http://172.15.28.113:8918</profiles.dingtalk.domain>
<profiles.dingtalk.oaUrl>172.15.28.113:8919</profiles.dingtalk.oaUrl>
<profiles.dingtalk.agentId>2652674890</profiles.dingtalk.agentId>
<profiles.dingtalk.appKey>dingpqzradgfr4efdi2j</profiles.dingtalk.appKey>
<profiles.dingtalk.appSecret>bF2WALmo5_Wuj3hg5gXeWqezrYnZChUJ88HjzNWpkA9ivdOxfBDGOGYcfVRfB3vd</profiles.dingtalk.appSecret>
<profiles.dingtalk.aesKey>1QcPYuSpAc98OS3qQwwx5HPH85CZDidxF95yBGad2fJ</profiles.dingtalk.aesKey>
<profiles.dingtalk.token>m3WeuVx5kcTY76kh22uWZOTSu0XjvcwNhd</profiles.dingtalk.token>
<profiles.dingtalk.opUserId>254868153920685466</profiles.dingtalk.opUserId>
<profiles.webUrl>https://ybswxxcx.zwfwhfgjjfzj.yibin.gov.cn/performance-h5</profiles.webUrl>
<package.environment>build</package.environment>
<skipUi>false</skipUi>
</properties>
</profile>
</profiles>
<properties>
......
......@@ -190,7 +190,10 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
JSONObject data = new JSONObject();
String token = authTokenService.getToken(request);
HomeStatInfo homeStatInfo = new HomeStatInfo();
HomeStatInfo homeStatInfo = cacheService.get(RedisKey.KEY_HOME_STAT_CACHE, HomeStatInfo.class);
/* HomeStatInfo homeStatInfo = new HomeStatInfo();
StaffQuery staffQuery = new StaffQuery();
......@@ -207,8 +210,8 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
homeStatInfo.setTotalDeptNum(totalDeptNum);
AttendanceRecordHikQuery hikQuery = new AttendanceRecordHikQuery();
/* hikQuery.setAttendanceDateStart(DateUtil.beginOfMonth(new Date()).toDateStr());
hikQuery.setAttendanceDateEnd(DateUtil.today()); */
*//* hikQuery.setAttendanceDateStart(DateUtil.beginOfMonth(new Date()).toDateStr());
hikQuery.setAttendanceDateEnd(DateUtil.today()); *//*
hikQuery.setAttendanceDateStart(DateUtil.yesterday().toDateStr());
hikQuery.setAttendanceDateEnd(DateUtil.yesterday().toDateStr());
......@@ -222,17 +225,17 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
//获取当月打卡人数,如果存在
/* Long totalCache = cacheService.hget(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.format(new Date(), "yyyy-MM"), Long.class);
*//* Long totalCache = cacheService.hget(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.format(new Date(), "yyyy-MM"), Long.class);
if (ObjectUtils.isEmpty(totalCache)) {
totalCache = recordHikService.find(hikQuery).parallelStream().map(item -> item.getStaffId()).distinct().count();
cacheService.hset(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.format(new Date(), "yyyy-MM"), totalCache);
}*/
}*//*
/* Long totalCache = cacheService.hget(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.yesterday().toDateStr(), Long.class);
*//* Long totalCache = cacheService.hget(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.yesterday().toDateStr(), Long.class);
if (ObjectUtils.isEmpty(totalCache)) {
totalCache = recordHikService.find(hikQuery).parallelStream().map(item -> item.getStaffId()).distinct().count();
cacheService.hset(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.yesterday().toDateStr(), totalCache);
}*/
}*//*
//迟到次数
......@@ -260,14 +263,14 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
.count();
/* AttendanceVacationRecordQuery vacationRecordQuery = new AttendanceVacationRecordQuery();
*//* AttendanceVacationRecordQuery vacationRecordQuery = new AttendanceVacationRecordQuery();
vacationRecordQuery.setCreateTimeStart(DateUtil.beginOfMonth(new Date()).toDateStr());
vacationRecordQuery.setCreateTimeEnd(DateUtil.today());
int levealPersonNum = vacationRecordService.count(vacationRecordQuery, getContext());*/
int levealPersonNum = vacationRecordService.count(vacationRecordQuery, getContext());*//*
AttendanceLeaveRecordQuery leaveRecordQuery = new AttendanceLeaveRecordQuery();
/* leaveRecordQuery.setCreateTimeStart(DateUtil.beginOfMonth(new Date()).toDateStr());
leaveRecordQuery.setCreateTimeEnd(DateUtil.today());*/
*//* leaveRecordQuery.setCreateTimeStart(DateUtil.beginOfMonth(new Date()).toDateStr());
leaveRecordQuery.setCreateTimeEnd(DateUtil.today());*//*
leaveRecordQuery.setCreateTimeStart(DateUtil.yesterday().toDateStr());
leaveRecordQuery.setCreateTimeEnd(DateUtil.yesterday().toDateStr());
leaveRecordQuery.setProcessStatus(ProcessStatusEnum.已处理.getValue());
......@@ -275,12 +278,12 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
//总打卡记录
/* long totalAttend = attendanceRecordEntities.parallelStream().flatMap(item -> item.getAttendanceRecordDetailList().parallelStream()).count();
*//* long totalAttend = attendanceRecordEntities.parallelStream().flatMap(item -> item.getAttendanceRecordDetailList().parallelStream()).count();
long lackOfCardsAttend = attendanceRecordEntities.parallelStream()
.flatMap(item -> item.getAttendanceRecordDetailList().stream())
.filter(f -> GoWorkResultEnum.缺卡.getValue() == f.getGoWorkResult() || OffWorkResultEnum.缺卡.getValue() == f.getOffWorkResult())
.count();*/
.count();*//*
//异常考勤记录
//未考勤
// long noAtt=lackOfCards;
......@@ -298,7 +301,7 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
homeStatInfo.setLatePersonNum(beLate);
homeStatInfo.setLeftEarlyPersonNum(leaveEarly);
homeStatInfo.setMissCardPersonNum(lackOfCards);
homeStatInfo.setAttendPersonNum(totalAttendPersonNum);
homeStatInfo.setAttendPersonNum(totalAttendPersonNum);*/
data.put("homeStat", homeStatInfo);
data.put("token", token);
......
......@@ -26,4 +26,7 @@ public class RedisKey {
/** 考勤统计 **/
public static final String KEY_ATTENDANCE_STAT_CACHE = "attendance:stat";
public static final String KEY_HOME_STAT_CACHE = "attendance:home:stat";
}
......@@ -15,6 +15,7 @@ import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikEntity;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
import com.mortals.xhx.module.attendance.service.AttendanceRecordHikService;
import com.mortals.xhx.module.attendance.service.AttendanceStatService;
import com.mortals.xhx.module.hik.door.model.req.door.DoorEventReq;
import com.mortals.xhx.module.hik.door.model.rsp.door.DoorEventDataInfo;
import com.mortals.xhx.module.hik.door.service.IHikDoorService;
......@@ -46,23 +47,30 @@ public class SyncDoorsEventAfterTaskImpl implements ITaskExcuteService {
@Autowired
private IHikDoorService hikDoorService;
@Autowired
private AttendanceStatService attendanceStatService;
@Override
public void excuteTask(ITask task) throws AppException {
// syncDoorEvents();
// syncDoorEvents();
//判断时间段 不在时间段的 不做计算
//早上9点 子晚上8点 计算
Date beginDateTime=DateUtil.parseDateTime(DateUtil.today()+" 09:00:00");
Date endDateTime=DateUtil.parseDateTime(DateUtil.today()+" 20:30:00");
Date beginDateTime = DateUtil.parseDateTime(DateUtil.today() + " 09:00:00");
Date endDateTime = DateUtil.parseDateTime(DateUtil.today() + " 20:30:00");
boolean in = DateUtil.isIn(new Date(), beginDateTime, endDateTime);
if(in){
calculateAttendByDay();
}
if (in) {
calculateAttendByDay();
}
//统计当日
log.info("统计当日考勤");
attendanceStatService.homeStat(null);
log.info("统计当日考勤结束");
}
private void calculateAttendByDay() {
Context context = new Context();
UserEntity userEntity = new UserEntity();
......@@ -115,7 +123,7 @@ public class SyncDoorsEventAfterTaskImpl implements ITaskExcuteService {
doorEventReq.setPageNo(i);
doorEventReq.setPageSize(1000);
doorEventsRest = hikDoorService.getDoorEvents(doorEventReq);
// log.info("doorEventsRest:{} msg:{},page:{}", doorEventsRest.getCode(), doorEventsRest.getMsg(), doorEventReq.getPageNo());
// log.info("doorEventsRest:{} msg:{},page:{}", doorEventsRest.getCode(), doorEventsRest.getMsg(), doorEventReq.getPageNo());
getDoorEvents(doorEventsRest);
}
}
......
......@@ -77,13 +77,14 @@ public class SyncDoorsEventTaskImpl implements ITaskExcuteService {
private void syncDoorEvents() {
DoorEventReq doorEventReq = new DoorEventReq();
List<Integer> eventTypes = new ArrayList<>();
eventTypes.add(196885);
eventTypes.add(196887);
eventTypes.add(196893);
eventTypes.add(196888);
eventTypes.add(196889);
eventTypes.add(196890);
eventTypes.add(196891);
// eventTypes.add(196885);
// eventTypes.add(196887);
// eventTypes.add(196893);
// eventTypes.add(196888);
// eventTypes.add(196889);
// eventTypes.add(196890);
// eventTypes.add(196891);
eventTypes.add(196893);//人脸认证通过
doorEventReq.setEventTypes(eventTypes);
// 获取当天的开始时间
//Date todayStart = DateUtil.offsetHour(new Date(), -5).toJdkDate();
......
......@@ -24,4 +24,8 @@ public interface AttendanceStatService extends ICRUDService<AttendanceStatEntity
void doAttendanceSummary(AttendanceSummaryQuery query);
Result<AttendanceStatEntity> findExt(AttendanceSummaryQuery params, PageInfo pageInfo, Context context) throws AppException;
void homeStat(Context context) throws AppException;
}
\ No newline at end of file
package com.mortals.xhx.module.attendance.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.common.code.GoWorkResultEnum;
import com.mortals.xhx.common.code.LeaveTypeEnum;
import com.mortals.xhx.common.code.OffWorkResultEnum;
import com.mortals.xhx.common.code.ProcessStatusEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.HomeStatInfo;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.attendance.dao.AttendanceSummaryDao;
import com.mortals.xhx.module.attendance.model.AttendanceStaffStatEntity;
import com.mortals.xhx.module.attendance.model.AttendanceStaffStatQuery;
import com.mortals.xhx.module.attendance.model.AttendanceStatQuery;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.model.vo.AttendanceSummaryQuery;
import com.mortals.xhx.module.attendance.model.vo.ErrorSummaryVo;
import com.mortals.xhx.module.attendance.model.vo.LeaveSummaryVo;
import com.mortals.xhx.module.attendance.model.vo.VacationBalanceSummaryVo;
import com.mortals.xhx.module.attendance.service.AttendanceLeaveRecordService;
import com.mortals.xhx.module.attendance.service.AttendanceRecordService;
import com.mortals.xhx.module.attendance.service.AttendanceStaffStatService;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.holiday.model.HolidayEntity;
import com.mortals.xhx.module.holiday.model.HolidayQuery;
import com.mortals.xhx.module.holiday.service.HolidayService;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.service.StaffService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.attendance.dao.AttendanceStatDao;
import com.mortals.xhx.module.attendance.model.AttendanceStatEntity;
import com.mortals.xhx.module.attendance.service.AttendanceStatService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
......@@ -52,6 +64,19 @@ public class AttendanceStatServiceImpl extends AbstractCRUDServiceImpl<Attendanc
@Autowired
private HolidayService holidayService;
@Autowired
private StaffService staffService;
@Autowired
private DeptService deptService;
@Autowired
private AttendanceRecordService recordService;
@Autowired
private AttendanceLeaveRecordService leaveRecordService;
@Autowired
private ICacheService cacheService;
@Override
protected void findAfter(AttendanceStatEntity entity, Context context, List<AttendanceStatEntity> list) throws AppException {
// DateUtil.parse(entity.getStartTime()).year();
......@@ -169,12 +194,12 @@ public class AttendanceStatServiceImpl extends AbstractCRUDServiceImpl<Attendanc
holidayQuery.setStartTimeStart(query.getSummaryTime());
holidayQuery.setStartTimeEnd(query.getSummaryTime());
HolidayEntity holidayEntity = holidayService.selectOne(holidayQuery);
if(holidayEntity!=null){
if(holidayEntity.getWorkorholiday()==0){
if (holidayEntity != null) {
if (holidayEntity.getWorkorholiday() == 0) {
//特定节假日
isReturn = true;
}
}else {
} else {
//判断是否为周末
Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtils.StrToDate(query.getSummaryTime()));
......@@ -189,7 +214,7 @@ public class AttendanceStatServiceImpl extends AbstractCRUDServiceImpl<Attendanc
//当天不统计
isReturn = true;
}
if(isReturn){
if (isReturn) {
return;
}
log.info("开始汇总[" + query.getSummaryTime() + "]考勤.....");
......@@ -231,7 +256,7 @@ public class AttendanceStatServiceImpl extends AbstractCRUDServiceImpl<Attendanc
if (temp != null) {
BeanUtils.copyProperties(item, temp, BeanUtil.getNullPropertyNames(item));
temp.setGoTimes(0); //默认只要有异常考勤,当天就不算全勤
if(item.getMorningTimes()>0){
if (item.getMorningTimes() > 0) {
temp.setNonCompliancePunch(new BigDecimal(item.getMorningTimes()));
}
this.dao.update(temp);
......@@ -432,4 +457,120 @@ public class AttendanceStatServiceImpl extends AbstractCRUDServiceImpl<Attendanc
return result;
}
@Override
public void homeStat(Context context) throws AppException {
HomeStatInfo homeStatInfo = new HomeStatInfo();
StaffQuery staffQuery = new StaffQuery();
staffQuery.setStatusNotList(Arrays.asList(3));
int totalPersonNum = staffService.count(staffQuery, context);
homeStatInfo.setTotalPersonNum(totalPersonNum);
staffQuery.setSource(1);
Integer totalAttendPersonNum = staffService.count(staffQuery, context);
int totalDeptNum = deptService.count(new DeptQuery(), context);
homeStatInfo.setTotalDeptNum(totalDeptNum);
AttendanceRecordHikQuery hikQuery = new AttendanceRecordHikQuery();
/* hikQuery.setAttendanceDateStart(DateUtil.beginOfMonth(new Date()).toDateStr());
hikQuery.setAttendanceDateEnd(DateUtil.today()); */
hikQuery.setAttendanceDateStart(DateUtil.yesterday().toDateStr());
hikQuery.setAttendanceDateEnd(DateUtil.yesterday().toDateStr());
AttendanceRecordQuery attendanceRecordQuery = new AttendanceRecordQuery();
// attendanceRecordQuery.setAttendanceDateStart(DateUtil.beginOfMonth(new Date()).toDateStr());
//attendanceRecordQuery.setAttendanceDateEnd(DateUtil.today());
attendanceRecordQuery.setAttendanceDateStart(DateUtil.yesterday().toDateStr());
attendanceRecordQuery.setAttendanceDateEnd(DateUtil.yesterday().toDateStr());
List<AttendanceRecordEntity> attendanceRecordEntities = recordService.find(attendanceRecordQuery);
//获取当月打卡人数,如果存在
/* Long totalCache = cacheService.hget(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.format(new Date(), "yyyy-MM"), Long.class);
if (ObjectUtils.isEmpty(totalCache)) {
totalCache = recordHikService.find(hikQuery).parallelStream().map(item -> item.getStaffId()).distinct().count();
cacheService.hset(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.format(new Date(), "yyyy-MM"), totalCache);
}*/
/* Long totalCache = cacheService.hget(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.yesterday().toDateStr(), Long.class);
if (ObjectUtils.isEmpty(totalCache)) {
totalCache = recordHikService.find(hikQuery).parallelStream().map(item -> item.getStaffId()).distinct().count();
cacheService.hset(RedisKey.KEY_ATTENC_TOTOAL_CACHE, DateUtil.yesterday().toDateStr(), totalCache);
}*/
//迟到次数
long beLate = attendanceRecordEntities.parallelStream()
.flatMap(item -> item.getAttendanceRecordDetailList().stream())
.filter(f -> GoWorkResultEnum.迟到.getValue() == f.getGoWorkResult() || OffWorkResultEnum.迟到.getValue() == f.getOffWorkResult())
.map(i -> i.getStaffId())
.distinct()
.count();
//早退次数
long leaveEarly = attendanceRecordEntities.parallelStream()
.flatMap(item -> item.getAttendanceRecordDetailList().stream())
.filter(f -> GoWorkResultEnum.早退.getValue() == f.getGoWorkResult() || OffWorkResultEnum.早退.getValue() == f.getOffWorkResult())
.map(i -> i.getStaffId())
.distinct()
.count();
//缺卡次数
long lackOfCards = attendanceRecordEntities.parallelStream()
.flatMap(item -> item.getAttendanceRecordDetailList().stream())
.filter(f -> GoWorkResultEnum.缺卡.getValue() == f.getGoWorkResult() || OffWorkResultEnum.缺卡.getValue() == f.getOffWorkResult())
.map(i -> i.getStaffId())
.distinct()
.count();
/* AttendanceVacationRecordQuery vacationRecordQuery = new AttendanceVacationRecordQuery();
vacationRecordQuery.setCreateTimeStart(DateUtil.beginOfMonth(new Date()).toDateStr());
vacationRecordQuery.setCreateTimeEnd(DateUtil.today());
int levealPersonNum = vacationRecordService.count(vacationRecordQuery, getContext());*/
AttendanceLeaveRecordQuery leaveRecordQuery = new AttendanceLeaveRecordQuery();
/* leaveRecordQuery.setCreateTimeStart(DateUtil.beginOfMonth(new Date()).toDateStr());
leaveRecordQuery.setCreateTimeEnd(DateUtil.today());*/
leaveRecordQuery.setCreateTimeStart(DateUtil.yesterday().toDateStr());
leaveRecordQuery.setCreateTimeEnd(DateUtil.yesterday().toDateStr());
leaveRecordQuery.setProcessStatus(ProcessStatusEnum.已处理.getValue());
int levealPersonNum = leaveRecordService.count(leaveRecordQuery, context);
//总打卡记录
/* long totalAttend = attendanceRecordEntities.parallelStream().flatMap(item -> item.getAttendanceRecordDetailList().parallelStream()).count();
long lackOfCardsAttend = attendanceRecordEntities.parallelStream()
.flatMap(item -> item.getAttendanceRecordDetailList().stream())
.filter(f -> GoWorkResultEnum.缺卡.getValue() == f.getGoWorkResult() || OffWorkResultEnum.缺卡.getValue() == f.getOffWorkResult())
.count();*/
//异常考勤记录
//未考勤
// long noAtt=lackOfCards;
long att = totalAttendPersonNum - lackOfCards;
// long att = totalAttend - lackOfCardsAttend;
if (att != 0L) {
BigDecimal bigDecimal = new BigDecimal(att).divide(new BigDecimal(totalAttendPersonNum), 4, BigDecimal.ROUND_CEILING).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_CEILING);
homeStatInfo.setAttendRadio(bigDecimal.toString() + "%");
} else {
homeStatInfo.setAttendRadio("0%");
}
homeStatInfo.setLevealPersonNum(levealPersonNum);
homeStatInfo.setLatePersonNum(beLate);
homeStatInfo.setLeftEarlyPersonNum(leaveEarly);
homeStatInfo.setMissCardPersonNum(lackOfCards);
homeStatInfo.setAttendPersonNum(totalAttendPersonNum);
cacheService.set(RedisKey.KEY_HOME_STAT_CACHE, JSON.toJSONString(homeStatInfo));
}
}
\ No newline at end of file
package com.mortals.xhx.module.attendance.web;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSONObject;
......@@ -50,6 +51,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
......@@ -338,16 +342,55 @@ public class AttendanceRecordController extends BaseCRUDJsonBodyMappingControlle
super.doListBefore(query, model, context);
}
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
//putIfAbsent方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则依旧为原来的值。
//如果返回null表示添加数据成功(不重复),不重复(null==null :TRUE)
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
@Override
protected int doListAfter(AttendanceRecordEntity query, Map<String, Object> model, Context context) throws AppException {
List<AttendanceRecordEntity> list = (List<AttendanceRecordEntity>) model.get(KEY_RESULT_DATA);
//求出列表中最多detail 的 添加动态列
List<AttendanceRecordDetailEntity> collect = list.parallelStream()
.flatMap(item -> item.getAttendanceRecordDetailList().stream())
.distinct()
.filter(distinctByKey(f->f.getOrderNum()))
.sorted(Comparator.comparingInt(AttendanceRecordDetailEntity::getOrderNum))
.collect(Collectors.toList());
//list.parallelStream().collect(Collectors.groupingBy())
List<AttDsyncColumn> dsyncColumns = new ArrayList<>();
/* for (int i = 1; i <= collect.size(); i++) {
AttDsyncColumn attDsyncColumn = new AttDsyncColumn();
attDsyncColumn.setName(String.format("上班%s打卡时间", i));
attDsyncColumn.setProperty("goWorkDate");
attDsyncColumn.setOrderNum(i);
dsyncColumns.add(attDsyncColumn);
attDsyncColumn = new AttDsyncColumn();
attDsyncColumn.setName(String.format("上班%s打卡结果", i));
attDsyncColumn.setProperty("goWorkResult");
attDsyncColumn.setOrderNum(i);
dsyncColumns.add(attDsyncColumn);
attDsyncColumn = new AttDsyncColumn();
attDsyncColumn.setName(String.format("下班%s打卡时间", i));
attDsyncColumn.setProperty("offWorkDate");
attDsyncColumn.setOrderNum(i);
dsyncColumns.add(attDsyncColumn);
attDsyncColumn = new AttDsyncColumn();
attDsyncColumn.setName(String.format("下班%s打卡结果",i));
attDsyncColumn.setProperty("offWorkResult");
attDsyncColumn.setOrderNum(i);
dsyncColumns.add(attDsyncColumn);
}*/
collect.forEach(item -> {
AttDsyncColumn attDsyncColumn = new AttDsyncColumn();
attDsyncColumn.setName(String.format("上班%s打卡时间", item.getOrderNum()));
......@@ -391,7 +434,7 @@ public class AttendanceRecordController extends BaseCRUDJsonBodyMappingControlle
return null;
}).filter(f -> f != null).collect(Collectors.toList());
if (ObjectUtils.isEmpty(addDetailList)) {
if (!ObjectUtils.isEmpty(addDetailList)) {
recordEntity.getAttendanceRecordDetailList().addAll(addDetailList);
List<AttendanceRecordDetailEntity> orderList = recordEntity.getAttendanceRecordDetailList().stream().sorted(Comparator.comparingInt(AttendanceRecordDetailEntity::getOrderNum))
.collect(Collectors.toList());
......@@ -399,57 +442,6 @@ public class AttendanceRecordController extends BaseCRUDJsonBodyMappingControlle
}
}
model.put("dyncColumns", dsyncColumns);
/* //出勤情况
//总人数
Integer total = (Integer)model.get("total");
//未出勤
Integer noAtt = 0;
//迟到
Integer beLate = 0;
//早退
Integer leaveEarly = 0;
//缺卡
Integer lackOfCards = 0;
for (AttendanceRecordEntity attendanceRecordEntity : list) {
boolean a = true;
for (AttendanceRecordDetailEntity item : attendanceRecordEntity.getAttendanceRecordDetailList()) {
if (item.getGoWorkResult()==3){
lackOfCards=lackOfCards+1;
}
if (item.getGoWorkResult()==4){
beLate = beLate+1;
}
if (item.getOffWorkResult()==3){
lackOfCards=lackOfCards+1;
}
if (item.getOffWorkResult()==5){
leaveEarly = leaveEarly +1;
}
if (item.getGoWorkResult()!=3 || item.getOffWorkResult()!=3){
a = false;
}
}
if (a){
noAtt = noAtt+1;
}
}
String attPercentage = "";
if (total!=0){
float l = ((total - noAtt) / total)*100;
attPercentage =l+"%";
}else {
attPercentage = "0";
}
AttendanceStatus attendanceStatus = new AttendanceStatus();
attendanceStatus.setNeedAttNum(total);
attendanceStatus.setAttPercentage(attPercentage);
attendanceStatus.setNoAtt(noAtt);
attendanceStatus.setBeLate(beLate);
attendanceStatus.setLeaveEarly(leaveEarly);
attendanceStatus.setLackOfCards(lackOfCards);
model.put("attendanceStatus",attendanceStatus);*/
return super.doListAfter(query, model, context);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment