admin/src/api/business/parkBook.js
@@ -16,6 +16,10 @@ export function updateById (data) { return request.post('/business/parkBook/updateById', data) } // 修改 export function reUpdate (data) { return request.post('/business/parkBook/reUpdate', data) } // 删除 export function deleteById (id) { admin/src/components/business/OperaVisitsDesWindow.vue
@@ -26,6 +26,20 @@ border :header-cell-style="{background: '#dcdde2', color: 'rgb(51, 51, 51)'}" style="width: 100%"> <el-table-column prop="status" label="状态" min-width="100px"> <template slot-scope="{row}"> <span style="color: rgba(245, 154, 35, 0.996);" v-if="row.status === 0">待提交审批</span> <span v-if="row.status === 1">审批中</span> <span v-if="row.status === 2">审核通过</span> <span style="color: red;" v-if="row.status === 3">审核不通过</span> <span v-if="row.status === 4">取消</span> <span v-if="row.status === 5">预约成功</span> <span v-if="row.status === 6">预约失败</span> <span v-if="row.status === 7">拜访中</span> <span v-if="row.status === 8">已签离</span> <span v-if="row.status === 9">已失效</span> </template> </el-table-column> <el-table-column width="150" label="姓名"> admin/src/views/business/carEvent.vue
@@ -59,6 +59,15 @@ stripe > <el-table-column prop="plateNos" label="车牌号" min-width="100px"></el-table-column> <el-table-column prop="parkName" label="停车库名称" min-width="100px"></el-table-column> <el-table-column prop="gateName" label="出入口名称" min-width="100px"></el-table-column> <el-table-column prop="eventTypeName" label="事件类型" min-width="100px"></el-table-column> <el-table-column label="出入类型" min-width="100px"> <template slot-scope="{row}"> <span v-if="row.inoutType === 0">进场</span> <span v-if="row.inoutType === 1">出场</span> </template> </el-table-column> <el-table-column label="归属用户类型" min-width="100px"> <template slot-scope="{row}"> <span v-if="row.personType === '0'">劳务访客</span> @@ -69,15 +78,6 @@ <el-table-column prop="personName" label="姓名" min-width="100px"></el-table-column> <el-table-column prop="personPhone" label="手机号" min-width="100px"></el-table-column> <el-table-column prop="personCompanyName" label="公司/部门" min-width="100px"></el-table-column> <el-table-column prop="parkName" label="停车库名称" min-width="100px"></el-table-column> <el-table-column prop="gateName" label="出入口名称" min-width="100px"></el-table-column> <el-table-column prop="eventTypeName" label="事件类型" min-width="100px"></el-table-column> <el-table-column label="出入类型" min-width="100px"> <template slot-scope="{row}"> <span v-if="row.inoutType === 0">进场</span> <span v-if="row.inoutType === 1">出场</span> </template> </el-table-column> <el-table-column label="车牌抓拍图" min-width="100px"> <template slot-scope="{row}"> <div v-if="row.platePicUrl!=null"> admin/src/views/business/parkBook.vue
@@ -19,9 +19,9 @@ <!-- 表格和分页 --> <template v-slot:table-wrap> <ul class="toolbar" v-permissions="['business:member:create', 'business:member:delete']"> <!-- <li><el-button type="primary" @click="$refs.operaCarsWindow.open('新建车辆信息表')" icon="el-icon-plus" v-permissions="['business:member:create']">新建</el-button></li>--> <li><el-button @click="syncCars" icon="el-icon-delete" v-permissions="['business:cars:sync']">同步</el-button></li> <!-- <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:cars:delete']">删除</el-button></li> --> </ul> <el-table v-loading="isWorking.search" @@ -30,7 +30,7 @@ @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55"></el-table-column> <el-table-column prop="code" label="车牌号" min-width="100px"></el-table-column> <el-table-column prop="carCode" label="车牌号" min-width="100px"></el-table-column> <el-table-column prop="parksName" label="停车场" min-width="100px"></el-table-column> <el-table-column label="用户类型" min-width="100px"> <template slot-scope="{row}"> @@ -42,12 +42,26 @@ <el-table-column prop="memberName" label="姓名" min-width="100px"></el-table-column> <el-table-column prop="memberPhone" label="手机号" min-width="100px"></el-table-column> <el-table-column prop="companyName" label="部门/公司" min-width="100px"></el-table-column> <el-table-column prop="remark" label="备注" min-width="100px"></el-table-column> <el-table-column prop="remark" label="有效期" min-width="100px"> <el-table-column prop="startTime" label="有效期" min-width="100px"> <template slot-scope="{row}"> <span>{{validity(row.startTime, row.endTime)}}</span> <!-- <span v-if="!row.startTime || !row.endTime">长期</span>--> <!-- <span v-else>{{row.startTime}} 至 {{row.endTime}}</span>--> </template> </el-table-column> <el-table-column prop="startTime" label="状态" min-width="100px"> <template slot-scope="{row}"> <div v-if="row.isdeleted==1" style="color: red">已删除</div> <div v-else style="color: green"> <span v-if="row.hkStatus==0" style="color: #435EBE">待下发</span> <span v-if="row.hkStatus==1" style="color: green">下发成功</span> <span v-if="row.hkStatus==2" style="color: red">下发失败</span> </div> </template> </el-table-column> <el-table-column prop="remark" label="备注" min-width="100px"> <template slot-scope="{row}"> <span v-if="row.isdeleted !=2">{{row.remark}}</span> </template> </el-table-column> <el-table-column prop="createDate" label="创建时间" min-width="100px"></el-table-column> @@ -59,7 +73,10 @@ > <template slot-scope="{row}"> <!-- <el-button type="text" @click="$refs.operaCarsWindow.open('编辑车辆信息表', row)" icon="el-icon-edit" v-permissions="['business:member:update']">编辑</el-button>--> <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:member:delete']">删除</el-button> <el-button type="text" @click="deleteById(row)" v-if="row.isdeleted !=1" icon="el-icon-delete" v-permissions="['business:parkbook:delete']">删除</el-button> <!-- <el-button type="text" @click="reUpdate(row)" v-if="row.isdeleted !=1 && row.hkStatus ==0" icon="el-icon-edit" v-permissions="['business:parkbook:update']">立刻下发</el-button> --> </template> </el-table-column> </el-table> @@ -80,6 +97,10 @@ import TableLayout from '@/layouts/TableLayout' import Pagination from '@/components/common/Pagination' import OperaCarsWindow from '@/components/business/OperaCarsWindow' import { validity } from '@/utils/util' import { sync } from '@/api/business/cars' import { batchLoss } from '@/api/business/memberCard' import {reUpdate} from "@/api/business/parkBook"; export default { name: 'parkBook', extends: BaseTable, @@ -102,6 +123,18 @@ 'field.main': 'id' }) this.search() }, methods: { validity (startTime, endTime) { return validity(startTime, endTime) }, reUpdate (row) { reUpdate({ id: row.id }) .then(res => { this.$message.success('操作成功') this.search() }) } } } </script> server/dmvisit_admin/src/main/java/com/doumee/task/ScheduleTool.java
@@ -80,6 +80,14 @@ } } /** * 每10分钟拉取一次最新访客登记状态(预约成功和已登记) * @throws Exception */ @Scheduled(fixedDelay= 10*60*1000) public void syncVisitOuttimeStatus() throws Exception { hkSyncVisitService.getOutTimeVisitRecord(); } /** * 下载海康系统图片数据 * @throws Exception */ server/dmvisit_service/src/main/java/com/doumee/core/utils/Constants.java
@@ -85,6 +85,7 @@ public static boolean DEALING_HK_ORG = false; public static boolean DEALING_HK_USER = false; public static boolean DEALING_HK_VISIT = false; public static boolean DEALING_HK_VISIT_EXPIRE = false; public static boolean DEALING_FROM_HK_VISIT = false; public static boolean DEALING_HK_EMPOWER = false; public static boolean DEALING_HK_EMPOWER_DETAIL = false; @@ -209,7 +210,7 @@ int nb = 2;//内部访客 } public interface VisitStatus{ //审核状态 0待审核 1已提交ERP审批 2审核通过 3审核不通过 4取消 5下发成功 6下发失败 7已登记 8已签离 //审核状态 0待审核 1已提交ERP审批 2审核通过 3审核不通过 4取消 5下发成功 6下发失败 7已登记 8已签离 9已失效 int waitCheck = 0; int submitCheck = 1; int pass = 2; @@ -219,6 +220,7 @@ int xfFail = 6; int signin= 7; int signout = 8; int invalid =9; } public interface EmpowerStatus{ //一卡通授权下发状态 0待下发 1已下发 2下发成功 3已取消 4下发失败 5任务下载已结束 server/dmvisit_service/src/main/java/com/doumee/service/business/ext/HkSyncService.java
@@ -7,6 +7,7 @@ import com.doumee.core.haikang.model.param.request.event.acs.EventAcsRequest; import com.doumee.core.haikang.model.param.request.event.parks.EventParkRequest; import com.doumee.core.haikang.model.param.request.event.visit.EventVisitRequest; import com.doumee.core.haikang.model.param.respose.AppointmentInfoResponse; import com.doumee.dao.business.model.ParkBook; import javax.servlet.http.HttpServletResponse; @@ -67,6 +68,7 @@ void syncOrgUpdateData(Date start, Date end); void syncVisitData(); void getOutTimeVisitRecord( ); void syncEmpowerData(); void syncParkBookData(); void syncParkBookBySingleModel(ParkBook c); server/dmvisit_service/src/main/java/com/doumee/service/business/impl/hksync/HkSyncBaseServiceImpl.java
@@ -8,6 +8,7 @@ import com.doumee.core.haikang.model.param.request.event.acs.EventAcsRequest; import com.doumee.core.haikang.model.param.request.event.parks.EventParkRequest; import com.doumee.core.haikang.model.param.request.event.visit.EventVisitRequest; import com.doumee.core.haikang.model.param.respose.AppointmentInfoResponse; import com.doumee.core.haikang.model.param.respose.TaskAdditionResponse; import com.doumee.core.haikang.service.HKService; import com.doumee.dao.business.model.Device; @@ -107,6 +108,9 @@ public void syncVisitData() { } @Override public void getOutTimeVisitRecord(){ } @Override public void syncEmpowerData() { } @Override server/dmvisit_service/src/main/java/com/doumee/service/business/impl/hksync/HkSyncVisitServiceImpl.java
@@ -2,7 +2,10 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.core.haikang.model.HKConstants; import com.doumee.core.haikang.model.param.BaseListPageResponse; import com.doumee.core.haikang.model.param.BaseResponse; import com.doumee.core.haikang.model.param.request.*; import com.doumee.core.haikang.model.param.respose.*; @@ -44,6 +47,112 @@ /** * 同步海康访客信息,根据erp同步组织结果,定时检查需要下发到海康的组织信息 */ @Override public void getOutTimeVisitRecord(){ if(Constants.DEALING_HK_VISIT_EXPIRE){ return ; } Constants.DEALING_HK_VISIT_EXPIRE =true; try { //查询所有需要同步的数据 List<Visits> list = getExpireVisitList(); //按照父级申请分批处理每次申请数据 if(list ==null || list.size()==0){ return; } Date date = new Date(); for(Visits c : list) { //发起海康预约接口(需要登记),根据预约返回接口封装申请记录更新字段 AppointmentInfoResponse model = getVisitRecord(c.getHkId()); if(model == null){ Visits update = new Visits(); //已失效 update.setStatus(Constants.VisitStatus.invalid); update.setEditDate(date); update.setId(c.getId()); update.setRemark("预约已被清除"); visitsMapper.updateById(update); continue; } /** * * 0:待审核(预约待审批)、 * * 1:正常(预约成功或预约审批成功后<未登记>:当前时间未超过预计来访时间)、 * * 2:迟到(预约成功或预约审批成功后<未登记>:当前时间超过预计来访时间,但未超过预计离开时间)、 * * 3:失效(预约成功或预约审批成功后<未登记>:当前时间已超过预计离开时间)、 * * 4:审核退回(预约待审批,审批人员审批退回)、 * * 5:超期自动签离(超期未签离记录访客,由后台任务定时处理签离)、 * * 6:已签离(访客签离)、 * * 7:超期未签离(访客登记,当前时间已超过预计离开时间,还未进行签离)、 * * 8:已到达;(访客登记,当前时间未超过预计离开时间)、 * * 9:审核失效(预约待审批,一直到当前时间超过预计离开时间,还未审批通过)、 * * 10:邀约中(员工发起邀约,访客还未应邀)、 * * 11:邀约失效(员工发起邀约,一直到当前时间超过预计离开时间,访客还未应邀) */ if (model.getVisitorStatus()!=null && "3,4,11".contains( model.getVisitorStatus()+"" )){ //对相应状态下的数据进行【已失效】处理 Visits update = new Visits(); //已失效 update.setStatus(Constants.VisitStatus.invalid); update.setEditDate(date); update.setId(c.getId()); update.setInDate(DateUtil.getISO8601DateByStr2(model.getVisitStartTime())); update.setOutDate(DateUtil.getISO8601DateByStr2(model.getVisitEndTime())); update.setRemark("超时未登记"); visitsMapper.updateById(update); } if (model.getVisitorStatus()!=null && "5,6".contains( model.getVisitorStatus()+"" )){ // 对相应状态下的数据进行【已签离】处理 if(!Constants.equalsInteger(c.getStatus(),Constants.VisitStatus.signout)){ Visits update = new Visits(); //已失效 update.setStatus(Constants.VisitStatus.invalid); update.setEditDate(date); update.setId(c.getId()); update.setInDate(DateUtil.getISO8601DateByStr2(model.getVisitStartTime())); update.setOutDate(DateUtil.getISO8601DateByStr2(model.getVisitEndTime())); update.setRemark("已签离"); visitsMapper.updateById(update); } } if (model.getVisitorStatus()!=null&& "7,8".contains( model.getVisitorStatus()+"")){ //如果已登记 if(!Constants.equalsInteger(c.getStatus(),Constants.VisitStatus.signin)){ Visits update = new Visits(); //已失效 update.setStatus(Constants.VisitStatus.signin); update.setEditDate(date); update.setId(c.getId()); update.setInDate(DateUtil.getISO8601DateByStr2(model.getVisitStartTime())); update.setOutDate(DateUtil.getISO8601DateByStr2(model.getVisitEndTime())); update.setRemark("超时未签到"); visitsMapper.updateById(update); } } } }catch (Exception e){ e.printStackTrace(); }finally { Constants.DEALING_HK_VISIT_EXPIRE =false; } } public AppointmentInfoResponse getVisitRecord(String orderId){ //分页遍历循环查询所有门禁设备数据 if(StringUtils.isBlank(orderId)){ return null; } AppointmentListRequest param = new AppointmentListRequest(); param.setPageNo(1); param.setPageSize(1); param.setOrderId(orderId); BaseResponse<BaseListPageResponse<AppointmentInfoResponse>> response = HKService.appointmentRecords(param); if(response == null || !StringUtils.equals(response.getCode(), HKConstants.RESPONSE_SUCCEE) ){ return null; } if(response.getData() == null || response.getData().getList() == null|| response.getData().getList().size() ==0){ return null; } return response.getData().getList().get(0); } @Override public void syncVisitData(){ if(Constants.DEALING_HK_VISIT){ @@ -292,5 +401,13 @@ List<Visits> list = visitsMapper.selectJoinList(Visits.class,queryWrapper); return list; } private List<Visits> getExpireVisitList() { MPJLambdaWrapper<Visits> queryWrapper = new MPJLambdaWrapper<>(); queryWrapper.selectAll(Visits.class); queryWrapper.in(Visits::getStatus, Arrays.asList(new Integer[]{Constants.VisitStatus.xfSuccess,Constants.VisitStatus.signin}) ); List<Visits> list = visitsMapper.selectJoinList(Visits.class,queryWrapper); return list; } }