成达考勤大屏幕

This commit is contained in:
2023-12-04 18:12:02 +08:00
parent d696348af5
commit c8077dc07c
20 changed files with 11776 additions and 1 deletions
@@ -0,0 +1,323 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="KqShowScreen.aspx.cs" Inherits="FineUIPro.Web.HSSE.KqShowScreen.KqShowScreen" %>
<!DOCTYPE html>
<html lang="en">
<head runat="server">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../res/lib/flex.js"></script>
<link rel="stylesheet" href="../../res/css/kqshowscreen.css">
</head>
<body>
<div class="context">
<div class="left site">
<div class="block">
<div class="title">当前现场总人数</div>
<div class="main xc">
<div class="number" id="divTotal">
0
</div>
</div>
</div>
<div class="block1 ">
<div class="title">当前公司现场人数</div>
<div class="main gsxc">
<ul id="ulcom" >
</ul>
</div>
</div>
</div>
<div class="right site">
<div class="block1">
<div class="top">
<div class="info">
<ul id="infoul">
</ul>
</div>
<div class="photo">
<img id="header" src="">
</div>
</div>
</div>
<div class="block">
<div class="title">当前现场岗位人数量</div>
<div class="main" id="gwnum">
</div>
</div>
</div>
</div>
</body>
</html>
<script src="../../res/lib/echarts.min.js"></script>
<script src="../../res/lib/jquery.js"></script>
<script>
var projectid = '<%=ProjectId%>'
function createGWNUM(name, value1) {
let type = name//['焊工', '电工', '架子工', '木工', '管工', '仪表安装工', '电气安装工', '钢筋工', '起重司机', '钳工', '起重指挥', '混凝土工', '维护电工']
let value = value1// [100, 96, 89, 88, 87, 81, 80, 76, 75, 72, 70, 65, 62, 61]
let opt = {
grid: {
top: 20,
left: 60,
right:60
// bottom: 30
},
xAxis: {
type: 'category',
data: type,
axisLine: {
lineStyle: {
color: '#84D7FE'
}
},
axisTick: {
show: false
},
axisLabel: {
interval: 0, // 坐标轴刻度标签的显示间隔
rotate: -30 // 标签倾斜的角度
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#84D7FE'
}
},
splitLine: {
lineStyle: {
color: '#2E87AC',
type: 'dashed'
}
}
},
dataZoom: [
{
show: true,
type: 'slider', // 单独滚动条
filterMode: 'none', // 不过滤数据 - 保证 y 轴数据范围不变
brushSelect: true,
bottom: 0,
height: 10,
backgroundColor: 'transparent',
// 选中范围的填充颜色
fillerColor: 'transparent',
borderWidth: 0,
borderColor: 'transparent',
dataBackground: {
lineStyle: {
color: 'transparent'
},
areaStyle: {
color: 'transparent'
}
},
selectedDataBackground: {
lineStyle: {
color: 'transparent'
},
areaStyle: {
color: 'transparent'
}
},
startValue: 0,
endValue: 10,
xAxisIndex: [0],
showDetail: false,
handleSize: '0%',
// 移动手柄尺寸高度
// 测试发现手柄颜色和边框颜色会出现 偏差,所有设置手柄高度为0, 添加边框高度。由边框撑起高度
moveHandleSize: 0, // 设置拖动手柄高度为0,只由边框负责高度展示
// 不展示拖动手柄图标
moveHandleIcon: 'none',
moveHandleStyle: {
// borderColor: systemTheme === 'light' ? '#E4E6E7' : '#5d6177',
borderColor:'#5d6177',
borderWidth: 10, // 设置边框高度
borderType: 'solid',
borderCap: 'round',
// 保证拖动手柄右边框结尾有圆角
borderJoin: 'round'
},
// 拖动高亮时设置
emphasis: {
moveHandleStyle: {
// borderColor: systemTheme === 'light' ? '#E4E6E7' : '#5d6177',
borderColor: '#5d6177',
borderWidth: 10,
borderType: 'solid',
borderCap: 'round'
}
}
}
],
series: [
{
name: '',
data: value,
type: 'bar',
label: {
show: true,
color: '#ffffff',
position: 'top',
},
barWidth: 16,
itemStyle: {
normal: {
color:function(d){return "#"+Math.floor(Math.random()*(256*256*256-1) ).toString(16);}
}
}
}
]
};
var myEchart = echarts.init(document.getElementById('gwnum'));
myEchart.setOption(opt);
}
getData();
function getData() {
$.ajax({
url: "KqShowScreen.aspx/getData",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({
projectId: projectid
}),
success: function (data) {
if (data.d != null) {
var workPost = data.d.workPost;
if (workPost != null) {
createGWNUM(workPost.name, workPost.value)
}
var company = data.d.company;
if (company != null) {
var chtml = '';
company.forEach(function (item, index, arr) {
chtml += ' <li><span>' + item.name + '</span><span>' + item.value +'</span></li>';
})
$("#ulcom").html(chtml)
}
var person = data.d.person;
if (person != null) {
var phtml = '<li><span>所属单位</span><span>' + person.UnitName +'</span></li>'+
'<li ><span>姓名</span><span>' + person.PersonName +'</span></li>' +
'<li><span>岗位</span><span>' + person.WorkPostName+'</span></li>' +
'<li><span>班组</span><span>' + person.teamGroupName +'</span></li>' +
'<li><span>' + person.inOut+'时间</span><span>' + person.ChangeTime+'</span></li>';
$("#infoul").html(phtml)
$("#header").src(person.PhotoUrl);
}
$("#divTotal").html(data.d.total)
}
}
})
}
// 设定默认值
var websock = null;
var cishu = 0;
// 每10分钟 通过 websocket 向服务器发送一次心跳 证明客户端没有离线 依然在线可以正常接受消息
setInterval(websocketsend, 20000);
initWebsocket();
function initWebsocket() {
/*
* 初始化 websock
* 连接 服务器地址
* 并绑定 websock 四个事件方法
*/
websock = new WebSocket('ws://localhost:1000');
// 接收服务器返回的数据
websock.onmessage = this.websocketonmessage;
// 连接建立时触发
websock.onopen = this.websocketonopen;
// 连接中发生异常
websock.onerror = this.websocketonerror;
// 连接关闭时触发
websock.onclose = this.websocketclose;
cishu = 0;
}
function websocketonopen(){
websocketsend();
}
function websocketonerror() {
/*
* websocket 连接建立失败 执行的方法
* 注:我这里加了个判断,如果联系建立失败就在连接几次
*/
if (cishu < 5) {
cishu = cishu + 1;
initWebsocket();
}
}
function websocketsend() {
/*
* websocket 数据发送 通过 websock.send() 方法向服务器发送数据
* 注:这里随便发哈,主要作用就是通过这个动作,让客户端与服务端建立联系
*/
let actions = {
"projectid": projectid
};
websock.send(JSON.stringify(actions));
}
function websocketclose(e) {
/*
* websocket 连接关闭 执行的方法
*/
console.log('断开连接', e);
}
function websocketonmessage(e) {
/*
* websocket 数据接收 执行的方法
* 注:服务器通过 websocke 向客户端发送数据时,这里的方法就会自动触发啦
*/
if ("newinout" == e.data);
{
getData();
}
}
</script>
@@ -0,0 +1,193 @@
using BLL;
using FastReport.Data;
using FineUIPro.Web.HSSE.SitePerson;
using FineUIPro.Web.ProjectData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace FineUIPro.Web.HSSE.KqShowScreen
{
public partial class KqShowScreen : PageBase
{
#region
/// <summary>
/// 项目主键
/// </summary>
public string ProjectId
{
get
{
return (string)ViewState["ProjectId"];
}
set
{
ViewState["ProjectId"] = value;
}
}
#endregion
#region
/// <summary>
/// 加载页面
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.ProjectId = this.CurrUser.LoginProjectId;
}
}
#endregion
[WebMethod]
public static object getData(string projectId)
{
int total = 0;
HashSet<string> ids = new HashSet<string>();
HashSet<string> idsIn = new HashSet<string>();
Dictionary<string,DateTime> inperson = new Dictionary<string, DateTime>();
Dictionary<string, DateTime> outPerson = new Dictionary<string, DateTime>();
DateTime dateTime = DateTime.Now.AddDays(-1);
var inout = Funs.DB.SitePerson_PersonInOut.Where(x => x.ProjectId == projectId && x.ChangeTime > dateTime).OrderByDescending(x => x.ChangeTime);
Dictionary<string, int> company = new Dictionary<string, int>();
Dictionary<string, int> workPost = new Dictionary<string, int>();
foreach (var io in inout)
{
ids.Add(io.PersonId);
if (io.IsIn.HasValue && io.IsIn.Value) //24小时内最晚的入场
{
if (inperson.ContainsKey(io.PersonId))
{
if (inperson[io.PersonId] < io.ChangeTime.Value)
{
inperson[io.PersonId] = io.ChangeTime.Value;
}
}
else
{
if (io.ChangeTime.HasValue)
{
inperson.Add(io.PersonId, io.ChangeTime.Value);
}
}
}
else //24小时内最晚的出场
{
if (outPerson.ContainsKey(io.PersonId))
{
if (outPerson[io.PersonId] < io.ChangeTime.Value)
{
outPerson[io.PersonId] = io.ChangeTime.Value;
}
}
else
{
if (io.ChangeTime.HasValue)
{
outPerson.Add(io.PersonId, io.ChangeTime.Value);
}
}
}
}
foreach (var id in ids)
{
if (inperson.ContainsKey(id) && !outPerson.ContainsKey(id))//只有入场没有出场 在场
{
idsIn.Add(id);
total++;
}
else if (inperson.ContainsKey(id) && outPerson.ContainsKey(id))
{
if (inperson[id] < outPerson[id])//最晚入场时间 小于出场时间 在场
{
idsIn.Add(id);
total++;
}
}
}
HashSet<string> keys1 = new HashSet<string>();
HashSet<string> keys2 = new HashSet<string>();
foreach (var io in inout)
{
if (idsIn.Contains(io.PersonId))
{
if (!string.IsNullOrEmpty(io.WorkPostName))
{
if (!keys1.Contains(io.PersonId))
{
keys1.Add(io.PersonId);
if (workPost.ContainsKey(io.WorkPostName))
{
workPost[io.WorkPostName] = workPost[io.WorkPostName] + 1;
}
else
{
workPost[io.WorkPostName] = 1;
}
}
}
if (!string.IsNullOrEmpty(io.UnitName))
{
if (!keys2.Contains(io.PersonId))
{
keys2.Add(io.PersonId);
if (company.ContainsKey(io.UnitName))
{
company[io.UnitName] = company[io.UnitName] + 1;
}
else
{
company[io.UnitName] = 1;
}
}
}
}
}
var personInOut = inout.FirstOrDefault();
var person = Funs.DB.SitePerson_Person.FirstOrDefault(x => x.PersonId == personInOut.PersonId);
string teamGroupName = "";
string inOut = "出场";
string PhotoUrl = "";
PhotoUrl = "../../"+person.PhotoUrl;
if (personInOut.IsIn ==true)
{
inOut = "入场";
}
if (!string.IsNullOrEmpty(person.TeamGroupId))
{
var teamGroup = Funs.DB.ProjectData_TeamGroup.FirstOrDefault(x => x.TeamGroupId == person.TeamGroupId);
if (teamGroup != null)
{
teamGroupName = teamGroup.TeamGroupName;
}
}
List<object> comStatic = new List<object>();
foreach (var key in company.Keys)
{
comStatic.Add(new { name =key, value=company[key] });
}
List<string> workPostName = new List<string>();
List<int> workPostValue = new List<int>();
foreach (var key in workPost.Keys)
{
workPostName.Add(key);
workPostValue.Add(workPost[key]);
}
return new { company = comStatic, total, workPost = new { name = workPostName, value = workPostValue }, person = new{ personInOut.PersonName,personInOut.UnitName, personInOut.WorkPostName , inOut, PhotoUrl , teamGroupName, ChangeTime = personInOut.ChangeTime.Value.ToString("yyyy-MM-dd HH:mm")} };
}
}
}
@@ -0,0 +1,17 @@
//------------------------------------------------------------------------------
// <自动生成>
// 此代码由工具生成。
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </自动生成>
//------------------------------------------------------------------------------
namespace FineUIPro.Web.HSSE.KqShowScreen
{
public partial class KqShowScreen
{
}
}