123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 |
- <template>
- <div class="page_container">
- <base-title title="门禁管理" />
- <div class="page_content">
- <!-- 都匀人员不统计 -->
- <div class="person_title">人员信息</div>
- <div class="person_num_box">
- <vue-seamless
- :data="personList"
- class="seamless-warp"
- :class-option="scrollOption"
- ref="seamlessScroll"
- :key="seamLessTimeKey"
- >
- <div v-if="personList.length">
- <div class="item" v-for="item of personList" :key="item.id">
- <div class="left">
- <img :src="item.imgUrl" @click="delInfo(item)" />
- </div>
- <div class="divider"></div>
- <div class="right">
- <div class="position">{{ item.type }}</div>
- <div class="rymain">
- <div class="row">
- <div style="width: 40%">
- <span>姓名:</span>
- <span class="val">{{ item.name }}</span>
- </div>
- <div v-show="item.phone">
- <span>电话号码:</span>
- <span class="val" style="color: #00e0ff">{{
- item.phone
- }}</span>
- </div>
- </div>
- <div class="row">
- <div>
- <span>人员类型:</span>
- <span class="val">{{ item.personType }}</span>
- </div>
- </div>
- <div class="row">
- <div>
- <span>岗位名称:</span>
- <span class="val">{{ item.posi }}</span>
- </div>
- </div>
- <div class="row">
- <span>所属单位:</span>
- </div>
- <div class="row" v-if="item.comp">
- <span class="val">{{ item.comp }}</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div v-else>暂无数据</div>
- </vue-seamless>
- </div>
- <!-- <div class="person_type_box">
- <div class="person_title">出入设备</div>
- <div class="type_content">
- <div class="left_part">
- <img
- :src="require('@/assets/imgs/panels/img_personnel_02@2x.png')"
- alt=""
- @click="openPersonList()"
- />
- <span class="totle">{{ count }}</span>
- <span class="text">总数</span>
- </div>
- <div class="right_part">
- <div
- class="row_item"
- v-for="(item, index) in devicesTypeCount"
- :key="index"
- >
- <img
- v-if="item.name === '员工'"
- :src="require('@/assets/imgs/panels/icon_staff@2x.png')"
- alt=""
- />
- <img
- v-if="item.name === '访客'"
- :src="require('@/assets/imgs/panels/icon_visitor@2x.png')"
- alt=""
- />
- <img
- v-if="item.name === '施工'"
- :src="require('@/assets/imgs/panels/icon_construction@2x.png')"
- alt=""
- />
- <div class="row_main">
- <img
- :src="require('@/assets/imgs/panels/icon_arrow@2x.png')"
- alt=""
- />
- <span class="name">{{ item.name }}</span>
- <div class="line"></div>
- <span class="num">{{ item.value }}</span>
- <span class="unit">个</span>
- </div>
- </div>
- </div>
- </div>
- </div> -->
- <!-- <div class="person_events_box">
- <div class="person_title">出入信息</div>
- <div class="person_event_box">
- <vue-seamless
- :data="eventsList"
- class="seamless-warp-event"
- :class-option="scrollOptionEvent"
- ref="seamlessScroll"
- :key="seamLessTimeKeyEvent"
- >
- <div v-if="eventsList.length">
- <div class="event_item" v-for="item of eventsList" :key="item.id">
- <div class="person_event_title">
- <span class="person_event_name">{{
- item.accessControlName
- }}</span>
- <span class="split"></span>
- <span class="person_event_time">{{ item.eventTime }}</span>
- </div>
- <div class="person_event_content">{{ item.content }}</div>
- </div>
- </div>
- <div v-else>暂无数据</div>
- </vue-seamless>
- </div>
- </div> -->
- <div class="person_type_box">
- <div class="person_title">类型统计</div>
- <div class="type_content">
- <div class="left_part">
- <img
- :src="require('@/assets/imgs/panels/img_personnel_01@2x.png')"
- alt=""
- @click="openPersonList()"
- />
- <span class="totle">{{ total }}</span>
- <span class="text">总数</span>
- </div>
- <div class="right_part">
- <div
- class="row_item"
- v-for="(item, index) in personTypeCount"
- :key="index"
- >
- <img
- v-if="item.name === '站内员工'"
- :src="require('@/assets/imgs/panels/icon_staff@2x.png')"
- alt=""
- />
- <img
- v-if="item.name === '访客人员'"
- :src="require('@/assets/imgs/panels/icon_visitor@2x.png')"
- alt=""
- />
- <img
- v-if="item.name === '施工人员'"
- :src="require('@/assets/imgs/panels/icon_construction@2x.png')"
- alt=""
- />
- <div class="row_main">
- <img
- :src="require('@/assets/imgs/panels/icon_arrow@2x.png')"
- alt=""
- />
- <span class="name">{{ item.name }}</span>
- <div class="line"></div>
- <span class="num">{{ item.value }}</span>
- <span class="unit">人</span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import BaseTitle from "./BaseTitle.vue";
- import VueSeamless from "vue-seamless-scroll";
- import { getPersonTypeList, getAccessInfo } from "@/API/positioning";
- import {
- setAreaPersonOut,
- getAreaPersonList,
- getAccessLogList,
- } from "@/API/accessControl";
- import Dayjs from "dayjs";
- import { openDialog } from "@/utils/mapUtil.js";
- export default {
- name: "PersonStatistics",
- components: { BaseTitle, VueSeamless },
- data() {
- return {
- total: 4,
- count: 6,
- seamLessTimeKey: new Date().getTime(),
- seamLessTimeKeyEvent: new Date().getTime(),
- personTypeCount: [
- {
- name: "站内员工",
- value: 0,
- },
- {
- name: "访客人员",
- value: 0,
- },
- {
- name: "施工人员",
- value: 0,
- },
- ],
- devicesTypeCount: [
- {
- name: "都匀末站",
- value: 3,
- },
- {
- name: "凯口清管站",
- value: 1,
- },
- {
- name: "独山首站",
- value: 2,
- },
- ],
- personRiskCount: [
- {
- code: "306001",
- name: "3万方汽油罐区",
- value: 0,
- },
- {
- code: "306002",
- name: "8万方汽油罐区",
- value: 0,
- },
- {
- code: "306003",
- name: "20万方柴油油罐区",
- value: 0,
- },
- {
- code: "306004",
- name: "500方泄压罐",
- value: 0,
- },
- ],
- scrollOption: {
- limitMoveNum: 2,
- singleHeight: 173,
- waitTime: 5000,
- openWatch: true,
- },
- scrollOptionEvent: {
- limitMoveNum: 1,
- singleHeight: 66.5,
- waitTime: 5000,
- openWatch: true,
- },
- defaultPhoto: "~@/assets/imgs/stationMap/img_无照片.png",
- personList: [
- {
- id: "1",
- name: "",
- pic: "",
- type: "值班干部",
- posi: "主任",
- personType: "员工",
- comp: "XXXXX公司",
- phone: 15500001111,
- imgUrl: "~@/assets/imgs/stationMap/img_无照片.png",
- },
- ],
- eventsList: [
- {
- id: "1",
- accessControlName: "门口人脸识别",
- eventTime: "2025-01-16 15:51:46",
- content: "【张华亚】在门禁【门口人脸识别】人脸认证通过",
- },
- // {
- // id: "3",
- // name: "306004",
- // startTime: "2022-11-16 15:51:46",
- // content: "周界入侵触发,事件等级较低",
- // },
- // {
- // id: "4",
- // name: "306003",
- // startTime: "2022-11-16 15:51:46",
- // content: "激光云台触发气体泄漏,事件等级中",
- // },
- ],
- };
- },
- created() {
- // this.openPersonInfo();
- // this.initAccessLogList();
- },
- computed: {
- VUE_APP_BASE_API() {
- return process.env.VUE_APP_BASE_API;
- },
- },
- mounted() {
- this.startMqtt();
- let timer = null;
- if (!timer) {
- timer = setInterval(() => {
- this.getMessage();
- }, 3000);
- }
- this.$once("hook:beforeDestroy", () => {
- clearInterval(timer);
- timer = null;
- });
- // this.getPersonTypeList();
- },
- methods: {
- openDialog,
- async initAccessLogList() {
- try {
- const params = {
- pageSize: 100,
- pageIndex: 1,
- startTime: Dayjs(new Date())
- .subtract(1, "day")
- .format("YYYY-MM-DD HH:mm:ss"),
- endTime: Dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"),
- };
- const res = await getAccessLogList(params);
- this.eventsList = res.data.content;
- console.log("门禁事件列表", params, this.eventsList);
- } catch (err) {
- console.log(err);
- }
- },
- async openPersonInfo() {
- try {
- const res = await getAccessInfo({ id: "789185626355277824" });
- const data = res.data;
- console.log("门禁信息", data);
- if (data.remark) {
- const c = data.remark.split(":");
- if (c.length == 3) {
- this.personTypeCount[0].value = c[0]; //员工
- this.personTypeCount[1].value = c[2]; //访客
- this.personTypeCount[2].value = c[1]; //施工
- this.total = Number(c[0]) + Number(c[1]) + Number(c[2]);
- }
- }
- } catch (err) {
- console.log(err);
- }
- },
- openPersonList() {
- // this.openDialog(
- // "进站跟踪",
- // "https://10.0.0.201:8082/#/main?nolayout=1&token={token}",
- // 1500,
- // 760
- // );
- // this.$store.dispatch("globalConfig/setPersonListDialog", {
- // show: true,
- // dialogMsg: this.personList,
- // type: "All",
- // });
- },
- async getPersonTypeList() {
- try {
- const p = {};
- const res = await getPersonTypeList(p);
- // console.log(res.data);
- } catch (err) {
- console.log(err);
- }
- },
- startMqtt() {
- const topics = [
- // "CountArea/AllCount/All",
- // "CountArea/RiskCount/All",
- // "CountArea/PersonTypeCount/All",
- "AccessControl/Log",
- ];
- const _this = this;
- this.$store.dispatch("mqtt/subscribe", {
- topic: topics,
- onMessage: (topic, message, packet) => {
- const content = message.toString();
- // if (topic === "CountArea/AllCount/All") {
- // this.total = content;
- // } else if (topic === "CountArea/RiskCount/All") {
- // const data = JSON.parse(content);
- // this.personRiskCount.forEach((item) => {
- // item.value = data[item.code];
- // });
- // } else if (topic === "CountArea/PersonTypeCountDic/All") {
- // const data = JSON.parse(content);
- // } else
- console.log("门禁内容调整", content);
- if (topic === "AccessControl/Log") {
- //站内人员变动,重新查询数据
- // if (
- // JSON.parse(content).AreaId == "791707314364096512" &&
- // JSON.parse(content).PersonId != null
- // ) {
- this.getMessage();
- // }
- }
- },
- });
- this.$once("hook:beforeDestroy", () => {
- this.$store.dispatch("mqtt/unsubscribe", topics);
- });
- },
- async getMessage() {
- try {
- let res = await getAreaPersonList({ id: "791707314364096512" });
- if (res.code === 20000) {
- // console.log(res);
- if (res.data.content != null && res.data.content != undefined) {
- let localList = [];
- let workList = [];
- let visitList = [];
- let personInfoList = [];
- res.data.content.forEach((i) => {
- if (i.typeBelong == 1) {
- personInfoList.push({
- id: i.workNo,
- name: i.name,
- pic: "",
- type: i.positionName,
- posi: i.positionName,
- personType: i.typeName,
- comp: i.departmentName == null ? "" : i.departmentName,
- phone: i.telephone,
- imgUrl:
- i.photoPath == null
- ? this.defaultPhoto
- : "/yapi" + i.photoPath,
- });
- } else {
- personInfoList.push({
- id: i.workNo,
- name: i.name,
- pic: "",
- type: i.positionName,
- posi: i.positionName,
- personType: i.typeName,
- comp: i.companyName == null ? "" : i.companyName,
- phone: i.telephone,
- imgUrl:
- i.photoPath == null
- ? this.defaultPhoto
- : "/yapi" + i.photoPath,
- });
- }
- switch (i.type) {
- //访客
- case "546093319541760000":
- visitList.push({
- id: i.id,
- workNo: i.workNo,
- name: i.name,
- });
- break;
- //施工
- case "403245878963347456":
- workList.push({
- id: i.id,
- workNo: i.workNo,
- name: i.name,
- });
- break;
- //员工
- case "255022541838691649":
- localList.push({
- id: i.id,
- workNo: i.workNo,
- name: i.name,
- });
- break;
- }
- });
- this.personList = personInfoList.sort(function (a, b) {
- return a.id - b.id;
- });
- this.personTypeCount[0].value = localList.length; //员工
- this.personTypeCount[1].value = visitList.length; //访客
- this.personTypeCount[2].value = workList.length; //施工
- this.total = localList.length + workList.length + visitList.length;
- // console.log(
- // "数据数组:",
- // personInfoList,
- // localList,
- // visitList,
- // workList
- // );
- }
- } else {
- }
- } catch (error) {
- console.log(error);
- }
- },
- async delPersonMessage(item) {
- try {
- let res = await setAreaPersonOut({
- areaId: "791707314364096512",
- personId: item.id,
- });
- } catch (error) {
- console.log(error);
- }
- },
- delInfo(item) {
- this.$confirm("是否将" + item.name + "从入场列表中删除,?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- console.log("删除" + item.name + "人员已入场信息!");
- this.delPersonMessage(item); //删除接口
- this.$message({
- type: "success",
- message: "删除成功!",
- });
- setTimeout(() => {
- this.getMessage();
- }, 500);
- })
- .catch(() => {
- this.$message({
- type: "info",
- message: "已取消删除",
- });
- });
- },
- },
- beforeDestroy() {},
- };
- </script>
- <style lang="less" scoped>
- .page_container {
- width: 410px;
- z-index: 2;
- .page_content {
- width: 100%;
- height: 62%;
- .person_title {
- margin-top: 4px;
- padding-left: 20px;
- height: 24px;
- line-height: 24px;
- background: url(~@/assets/imgs/panels/title_bg_01@2x.png) no-repeat;
- background-size: 100% 100%;
- font-family: MicrosoftYaHei-Bold;
- font-size: 14px;
- color: #e0f3ff;
- letter-spacing: 0.88px;
- text-shadow: 0 0 10px #1162ff;
- font-weight: 700;
- }
- .person_type_box {
- width: 100%;
- height: 154px;
- .person_title {
- margin-top: 10px;
- }
- .type_content {
- margin-top: 4px;
- width: 100%;
- height: 126px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- .left_part {
- width: 110px;
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- img {
- width: 64px;
- height: 64px;
- }
- .totle {
- font-size: 30px;
- color: #ffffff;
- letter-spacing: 1.26px;
- text-shadow: 0 0 10px rgba(0, 180, 255, 0.5);
- font-weight: 700;
- }
- .text {
- font-size: 14px;
- color: #ffffff;
- letter-spacing: 0;
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
- font-weight: 400;
- }
- }
- }
- }
- .person_num_box {
- width: 100%;
- height: 342px;
- overflow: hidden;
- .num_content {
- width: 100%;
- height: 168px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- .left_part {
- width: 110px;
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- img {
- width: 80px;
- height: 80px;
- }
- }
- }
- .seamless-warp {
- .item {
- margin-top: 9px;
- height: 164px;
- display: flex;
- position: relative;
- .left {
- width: 25%;
- height: 100%;
- text-align: center;
- margin-right: 8px;
- img {
- width: 120px;
- height: 160px;
- }
- }
- .divider {
- width: 5%;
- }
- .right {
- width: 70%;
- min-height: 163px;
- position: relative;
- .position {
- font-family: 优设标题黑;
- font-size: 18px;
- color: #ffffff;
- letter-spacing: 1.29px;
- position: absolute;
- z-index: 99;
- background-image: linear-gradient(180deg, #eeeeee, #5cd5ff);
- -webkit-background-clip: text;
- background-clip: text;
- color: transparent;
- font-weight: 400;
- padding-left: 10px;
- }
- .rymain {
- width: 100%;
- height: calc(100% - 14px);
- position: absolute;
- bottom: 0;
- opacity: 0.9;
- background-image: linear-gradient(
- 270deg,
- rgba(0, 24, 46, 0.1) 0%,
- #00487b 98%
- );
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- font-size: 12px;
- color: #b3c0d4;
- // padding-top: 12px;
- .row {
- display: flex;
- padding-left: 5px;
- font-family: MicrosoftYaHei;
- .val {
- color: #ffffff;
- white-space: nowrap; /*强制单行显示*/
- text-overflow: ellipsis; /*超出部分省略号表示*/
- overflow: hidden; /*超出部分隐藏*/
- width: 256px; /*设置显示的最大宽度*/
- }
- }
- .row:nth-child(2) {
- margin-top: -8px;
- }
- }
- }
- }
- }
- }
- .person_events_box {
- .person_event_box {
- height: 66px;
- overflow: hidden;
- .seamless-warp-event {
- max-height: 66px;
- .event_item {
- height: 14%;
- position: relative;
- .person_event_title {
- margin-top: 2px;
- height: 27px;
- background-image: linear-gradient(
- 90deg,
- #53a3ff 2%,
- rgba(249, 40, 40, 0) 100%
- );
- display: flex;
- align-items: center;
- color: #fff;
- position: relative;
- img {
- width: 14px;
- height: 14px;
- }
- .person_event_name {
- margin-left: 19px;
- }
- .split {
- width: 2px;
- height: 20px;
- border-left: 2px solid #fff;
- margin: 0 8px;
- }
- }
- .person_event_content {
- margin-left: 14px;
- padding: 10px 0;
- font-size: 13px;
- color: #ffffff;
- letter-spacing: 1px;
- font-weight: 400;
- }
- }
- }
- }
- }
- .right_part {
- width: 300px;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- align-items: center;
- .row_item {
- width: 300px;
- height: 30px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
- &:last-child {
- margin-bottom: 0;
- }
- img {
- width: 30px;
- height: 30px;
- }
- .row_main {
- width: 260px;
- height: 30px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- background-color: rgba(51, 125, 206, 0.27);
- padding-right: 10px;
- .name {
- flex-shrink: 0;
- text-align: center;
- font-size: 13px;
- color: #ffffff;
- letter-spacing: 0;
- font-weight: 400;
- }
- .line {
- margin: 0 10px;
- width: 100%;
- height: 1px;
- border-top: 1px dashed #fff;
- opacity: 0.4;
- }
- .num {
- flex-shrink: 0;
- font-size: 18px;
- color: #ffffff;
- letter-spacing: 0;
- font-weight: 700;
- }
- .unit {
- opacity: 0.4;
- font-family: MicrosoftYaHei;
- font-size: 12px;
- color: #ffffff;
- letter-spacing: 0;
- font-weight: 400;
- }
- }
- }
- }
- }
- }
- </style>
|