Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Q
qingdaoMuseumPlatform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
node_server
qingdaoMuseumPlatform
Commits
b70ae87b
Commit
b70ae87b
authored
Jul 03, 2026
by
PC-20251223ZVQQ\Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善客流数据接入
parent
42295692
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
207 additions
and
85 deletions
+207
-85
mqttClient.ts
src/biz/mqttClient.ts
+63
-36
report.ts
src/biz/report.ts
+10
-3
running.ts
src/biz/running.ts
+134
-46
No files found.
src/biz/mqttClient.ts
View file @
b70ae87b
...
@@ -97,29 +97,30 @@ export async function processDeviceData(message) {
...
@@ -97,29 +97,30 @@ export async function processDeviceData(message) {
}
}
}
}
/** 客流触发的单条线路数据 */
interface
CustomerTriggerItem
{
/** 线路编号 */
triggerKey
:
number
;
/** 线路名称 */
triggerName
:
string
;
/** 线路UUID */
triggerUuid
:
string
;
/** 统计对象 { in: number, out: number } */
total
:
any
;
}
/**
/**
* 处理接收到的客流设备数据,并存入数据库
* 处理接收到的客流设备数据,并存入数据库
*
*
*
消息示例
:
*
当前格式(line_trigger_data)
:
* {
* {
* device_info: {
* device_info: { ... },
* device_mac: 'C0:BA:1F:02:98:F6',
* line_trigger_data: [ { line: 1, line_name: 'Line1', line_uuid: '...', total: { in: 2, out: 2 } } ],
* device_name: 'People Counter',
* time_info: { ... }
* device_sn: '6537F53875140008',
* firmware_version: 'V_125-LW.1.0.3-r4',
* hardware_version: 'V1.1',
* ip_address: '192.168.125.114',
* running_time: 4764787,
* wlan_mac: 'C0:BA:1F:02:98:F7'
* },
* region_trigger_data: { region_count_data: [ { region: 1, region_name: 'Region1', region_uuid: 'b63ffafc-857f-4d12-9dc7-d7fddfeb5f0f', total: { current_total: 9 } } ] },
* time_info: {
* dst_status: false,
* enable_dst: false,
* time: '2026-06-18T05:19:23-00:00',
* time_zone: 'UTC-0:00 Western European Time (WET), Greenwich Mean Time (GMT)'
* }
* }
* }
*
* 旧格式(已弃用,注释保留备用):
* // region_trigger_data: { region_count_data: [ { region: 1, region_name: 'Region1', region_uuid: '...', total: { current_total: 9 } } ] }
*/
*/
export
async
function
customerDeviceData
(
message
)
{
export
async
function
customerDeviceData
(
message
)
{
try
{
try
{
...
@@ -152,14 +153,42 @@ export async function customerDeviceData(message) {
...
@@ -152,14 +153,42 @@ export async function customerDeviceData(message) {
const
timeInfo
=
data
.
time_info
;
const
timeInfo
=
data
.
time_info
;
const
deviceTime
=
timeInfo
&&
timeInfo
.
time
?
new
Date
(
timeInfo
.
time
)
:
new
Date
();
const
deviceTime
=
timeInfo
&&
timeInfo
.
time
?
new
Date
(
timeInfo
.
time
)
:
new
Date
();
// ===== 提取客流数据 =====
// ===== 提取客流数据(当前使用新格式 line_trigger_data) =====
const
regionTriggerData
=
data
.
region_trigger_data
;
let
triggerItems
:
CustomerTriggerItem
[]
=
[];
if
(
!
regionTriggerData
||
!
regionTriggerData
.
region_count_data
||
regionTriggerData
.
region_count_data
.
length
===
0
)
{
console
.
warn
(
'消息缺少客流区域数据,跳过'
);
if
(
data
.
line_trigger_data
&&
Array
.
isArray
(
data
.
line_trigger_data
))
{
// 新格式:line_trigger_data,直接是数组,total: { in, out }
for
(
const
item
of
data
.
line_trigger_data
)
{
triggerItems
.
push
({
triggerKey
:
item
.
line
,
triggerName
:
item
.
line_name
||
''
,
triggerUuid
:
item
.
line_uuid
||
''
,
total
:
item
.
total
,
});
}
console
.
log
(
`[客流] 使用新格式 line_trigger_data,共
${
triggerItems
.
length
}
条线路`
);
}
/*
// ====== 旧格式(已弃用,保留备用) ======
else if (data.region_trigger_data?.region_count_data?.length > 0) {
// 旧格式:region_trigger_data.region_count_data,total: { current_total }
for (const item of data.region_trigger_data.region_count_data) {
triggerItems.push({
triggerKey: item.region,
triggerName: item.region_name || '',
triggerUuid: item.region_uuid || '',
total: item.total,
});
}
console.log(`[客流] 使用旧格式 region_trigger_data,共 ${triggerItems.length} 条区域`);
}
*/
if
(
triggerItems
.
length
===
0
)
{
console
.
warn
(
'消息缺少客流线路数据,跳过'
);
return
;
return
;
}
}
const
regionCountData
=
regionTriggerData
.
region_count_data
;
const
now
=
new
Date
();
const
now
=
new
Date
();
// ===== 设备校验/新增 =====
// ===== 设备校验/新增 =====
...
@@ -167,13 +196,13 @@ export async function customerDeviceData(message) {
...
@@ -167,13 +196,13 @@ export async function customerDeviceData(message) {
TABLENAME
.
设备表
,
{
device_id
:
deviceSn
}
TABLENAME
.
设备表
,
{
device_id
:
deviceSn
}
);
);
if
(
!
deviceRow
)
{
if
(
!
deviceRow
)
{
// 设备不存在,为每
个区域
创建一条设备记录
// 设备不存在,为每
条线路
创建一条设备记录
for
(
const
regionData
of
regionCountData
)
{
for
(
const
item
of
triggerItems
)
{
await
addData
(
await
addData
(
TABLENAME
.
设备表
,
TABLENAME
.
设备表
,
{
{
device_id
:
deviceSn
,
device_id
:
deviceSn
,
region_key
:
regionData
.
region
,
region_key
:
item
.
triggerKey
,
device_type
:
'客流传感器'
,
device_type
:
'客流传感器'
,
device_name
:
deviceName
,
device_name
:
deviceName
,
control_params
:
data
,
control_params
:
data
,
...
@@ -181,32 +210,30 @@ export async function customerDeviceData(message) {
...
@@ -181,32 +210,30 @@ export async function customerDeviceData(message) {
updated_at
:
now
,
updated_at
:
now
,
}
}
);
);
console
.
log
(
`客流设备已创建:
${
deviceSn
}
,
区域
${
regionData
.
region
}
`
);
console
.
log
(
`客流设备已创建:
${
deviceSn
}
,
线路
${
item
.
triggerKey
}
`
);
}
}
}
}
// 遍历每个区域的客流数据,逐条入库
// 遍历每条线路的客流数据,逐条入库
for
(
const
regionData
of
regionCountData
)
{
for
(
const
item
of
triggerItems
)
{
const
regionUuid
=
regionData
.
region_uuid
;
const
inCount
=
item
.
total
?.
in
??
0
;
const
regionName
=
regionData
.
region_name
||
''
;
const
outCount
=
item
.
total
?.
out
??
0
;
const
regionNumber
=
regionData
.
region
;
const
currentTotal
=
regionData
.
total
?.
current_total
??
0
;
await
addData
(
await
addData
(
TABLENAME
.
设备数据表
,
TABLENAME
.
设备数据表
,
{
{
device_id
:
deviceSn
,
device_id
:
deviceSn
,
data
:
regionData
.
total
,
data
:
item
.
total
,
received_time
:
now
,
received_time
:
now
,
device_time
:
deviceTime
,
device_time
:
deviceTime
,
created_at
:
now
,
created_at
:
now
,
}
}
);
);
console
.
log
(
`客流数据入库成功: 设备
${
deviceSn
}
,
区域
${
regionName
||
regionUuid
}
, 当前人数
${
currentTotal
}
`
);
console
.
log
(
`客流数据入库成功: 设备
${
deviceSn
}
,
${
item
.
triggerName
||
item
.
triggerUuid
}
, 进
${
inCount
}
出
${
outCount
}
`
);
}
}
console
.
log
(
`客流数据处理完成: 设备
${
deviceSn
}
, 共入库
${
regionCountData
.
length
}
条区域
数据`
);
console
.
log
(
`客流数据处理完成: 设备
${
deviceSn
}
, 共入库
${
triggerItems
.
length
}
条
数据`
);
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'客流数据处理失败:'
,
error
);
console
.
error
(
'客流数据处理失败:'
,
error
);
...
...
src/biz/report.ts
View file @
b70ae87b
...
@@ -181,16 +181,23 @@ function calcEnvDeviceDaily(records: any[]): { tempSum: number; tempCount: numbe
...
@@ -181,16 +181,23 @@ function calcEnvDeviceDaily(records: any[]): { tempSum: number; tempCount: numbe
/**
/**
* 从客流传感器数据中计算当日平均在馆人数
* 从客流传感器数据中计算当日平均在馆人数
* current_total 为当时在场人数(瞬时值),取当日所有采集值的算术平均
* 新格式使用 data.in(进)和 data.out(出)
* // 旧格式(已弃用,保留备用):current_total 为当时在场人数(瞬时值),取当日所有采集值的算术平均
*/
*/
function
calcCustomerDeviceDaily
(
records
:
any
[]):
{
visitorSum
:
number
;
visitorCount
:
number
}
{
function
calcCustomerDeviceDaily
(
records
:
any
[]):
{
visitorSum
:
number
;
visitorCount
:
number
}
{
let
sum
=
0
,
count
=
0
;
let
sum
=
0
,
count
=
0
;
for
(
const
rec
of
records
)
{
for
(
const
rec
of
records
)
{
const
d
=
rec
.
data
||
{};
const
d
=
rec
.
data
||
{};
if
(
d
.
current_total
!=
null
)
{
// ====== 新格式使用 in ======
sum
+=
Number
(
d
.
current_total
);
if
(
d
.
in
!=
null
)
{
sum
+=
Number
(
d
.
in
);
count
++
;
count
++
;
}
}
// ====== 旧格式(已弃用,保留备用) ======
// if (d.current_total != null) {
// sum += Number(d.current_total);
// count++;
// }
}
}
return
{
visitorSum
:
sum
,
visitorCount
:
count
};
return
{
visitorSum
:
sum
,
visitorCount
:
count
};
}
}
...
...
src/biz/running.ts
View file @
b70ae87b
...
@@ -296,43 +296,118 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
...
@@ -296,43 +296,118 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
tvocTrend
:
tvocTrend
tvocTrend
:
tvocTrend
};
};
// 5.1 预警监控和预警工单处理进度分析
// 5.1 预警监控和预警工单处理进度分析(从 device_fault 表获取,近30天)
let
alertStatus
=
{
const
faultStatusTextMap
:
{
[
key
:
number
]:
string
}
=
{
0
:
"未处理"
,
1
:
"已响应"
,
2
:
"已解决"
};
totalAlerts
:
3
,
resolved
:
1
,
// 降级默认值:查询或统计失败时使用,保证其他模块不受影响
responded
:
1
,
let
alertStatus
=
{
totalAlerts
:
0
,
resolved
:
0
,
responded
:
0
,
unresolved
:
0
};
unresolved
:
1
let
alertWorkLevel
:
{
[
key
:
string
]:
number
}
=
{
"一级预警"
:
0
,
"二级预警"
:
0
,
"三级预警"
:
0
};
};
let
alertWorkType
:
any
[]
=
[];
let
alertWorkOrders
=
[
let
alertWorkOrders
:
any
[]
=
[];
{
riskContent
:
"空调压缩机异常"
,
alertTime
:
"26/02/01"
,
status
:
"已解决"
},
{
riskContent
:
"温度传感器离线"
,
alertTime
:
"26/02/01"
,
status
:
"已响应"
},
try
{
{
riskContent
:
"湿度超标"
,
alertTime
:
"26/02/02"
,
status
:
"未处理"
}
// 时间范围:近30天
];
const
thirtyDaysAgo
=
new
Date
(
nowTime
.
getTime
()
-
30
*
86400000
);
let
alertWorkThreeOrders
=
[
const
timeFilter
=
{
"%gte%"
:
formatLocalTime
(
thirtyDaysAgo
)
};
{
riskContent
:
"空调压缩机异常"
,
alertTime
:
"26/02/01"
,
alertAddress
:
"A馆1F辉煌厅"
,
device_id
:
"3-1-0-0"
,
faultCode
:
"LU"
,
status
:
"已解决"
},
{
riskContent
:
"温度传感器离线"
,
alertTime
:
"26/02/01"
,
alertAddress
:
"A馆1F海外厅"
,
device_id
:
"3-1-0-1"
,
faultCode
:
"018"
,
status
:
"已响应"
},
// ---- 统计查询:只取 status/level/fault_type,避免传输无用字段 ----
{
riskContent
:
"湿度超标"
,
alertTime
:
"26/02/02"
,
alertAddress
:
"A馆1F走廊"
,
device_id
:
"2-4-0-0"
,
faultCode
:
"13"
,
status
:
"未处理"
}
const
statsRes
=
await
selectDataListByParam
(
TABLENAME
.
设备故障表
,
];
{
occurred_time
:
timeFilter
},
let
alertWorkLevel
=
{
[
"status"
,
"level"
,
"fault_type"
]);
"一级预警"
:
1
,
const
statsFaults
:
any
[]
=
Array
.
isArray
(
statsRes
.
data
)
?
statsRes
.
data
:
[];
"二级预警"
:
1
,
const
totalAlerts
=
statsFaults
.
length
;
"三级预警"
:
1
};
// alertStatus:按处理状态一次遍历统计
let
alertWorkType
=
[{
count
:
1
,
name
:
"设备故障"
,
proportion
:
'50%'
},
let
resolved
=
0
,
responded
=
0
,
unresolved
=
0
;
{
count
:
2
,
name
:
"环境异常"
,
proportion
:
'50%'
},
for
(
const
f
of
statsFaults
)
{
{
count
:
0
,
name
:
"安全事件"
,
proportion
:
'0%'
}];
if
(
f
.
status
===
2
)
resolved
++
;
// 5.2. 预警监控数据
else
if
(
f
.
status
===
1
)
responded
++
;
else
if
(
f
.
status
===
0
)
unresolved
++
;
}
alertStatus
=
{
totalAlerts
,
resolved
,
responded
,
unresolved
};
// alertWorkLevel:按故障等级统计
for
(
const
f
of
statsFaults
)
{
if
(
f
.
level
===
1
)
alertWorkLevel
[
"一级预警"
]
++
;
else
if
(
f
.
level
===
2
)
alertWorkLevel
[
"二级预警"
]
++
;
else
if
(
f
.
level
===
3
)
alertWorkLevel
[
"三级预警"
]
++
;
}
// alertWorkType:按故障类型统计
let
faultTypeCountMap
=
new
Map
<
string
,
number
>
();
for
(
const
f
of
statsFaults
)
{
const
typeName
=
f
.
fault_type
||
"其他"
;
faultTypeCountMap
.
set
(
typeName
,
(
faultTypeCountMap
.
get
(
typeName
)
||
0
)
+
1
);
}
for
(
const
[
name
,
count
]
of
faultTypeCountMap
)
{
alertWorkType
.
push
({
count
,
name
,
proportion
:
totalAlerts
>
0
?
((
count
/
totalAlerts
)
*
100
).
toFixed
(
0
)
+
'%'
:
'0%'
});
}
// ---- 工单列表查询:DB 层倒序 + LIMIT 10,避免全量拉到内存排序 ----
const
ordersRes
=
await
selectDataListByParam
(
TABLENAME
.
设备故障表
,
{
occurred_time
:
timeFilter
,
"%orderDesc%"
:
"occurred_time"
,
"%limit%"
:
10
},
[
"id"
,
"device_id"
,
"fault_type"
,
"fault_code"
,
"fault_description"
,
"occurred_time"
,
"level"
,
"status"
]);
const
sortedFaults
:
any
[]
=
Array
.
isArray
(
ordersRes
.
data
)
?
[...
ordersRes
.
data
]
:
[];
// 三级页面需要展示 alertAddress,需查设备表和区域表
let
deviceRegionMap
=
new
Map
<
string
,
string
>
();
if
(
regionType
&&
sortedFaults
.
length
>
0
)
{
const
faultUniqueDeviceIds
=
[...
new
Set
(
sortedFaults
.
map
((
f
:
any
)
=>
f
.
device_id
))];
const
devicesRes
=
await
selectDataListByParam
(
TABLENAME
.
设备表
,
{
device_id
:
{
"%in%"
:
faultUniqueDeviceIds
}
},
[
"device_id"
,
"region_key"
]);
const
regionKeySet
=
new
Set
<
string
>
();
const
deviceRegionKeyMap
=
new
Map
<
string
,
string
>
();
for
(
const
d
of
devicesRes
.
data
)
{
deviceRegionKeyMap
.
set
(
d
.
device_id
,
d
.
region_key
);
if
(
d
.
region_key
)
regionKeySet
.
add
(
d
.
region_key
);
}
if
(
regionKeySet
.
size
>
0
)
{
const
regionsRes
=
await
selectDataListByParam
(
TABLENAME
.
区域表
,
{
id
:
{
"%in%"
:
[...
regionKeySet
]
}
},
[
"id"
,
"name"
]);
const
regionNameMap
=
new
Map
<
string
,
string
>
();
for
(
const
r
of
regionsRes
.
data
)
{
regionNameMap
.
set
(
String
(
r
.
id
),
r
.
name
);
}
for
(
const
[
deviceId
,
regionKey
]
of
deviceRegionKeyMap
)
{
deviceRegionMap
.
set
(
deviceId
,
regionNameMap
.
get
(
regionKey
)
||
''
);
}
}
alertWorkOrders
=
sortedFaults
.
map
((
f
:
any
)
=>
({
riskContent
:
f
.
fault_description
||
f
.
fault_type
||
''
,
alertTime
:
f
.
occurred_time
||
''
,
status
:
faultStatusTextMap
[
f
.
status
]
||
'未知'
,
alertAddress
:
deviceRegionMap
.
get
(
f
.
device_id
)
||
''
,
device_id
:
f
.
device_id
||
''
,
faultCode
:
f
.
fault_code
||
''
,
}));
}
else
{
alertWorkOrders
=
sortedFaults
.
map
((
f
:
any
)
=>
({
riskContent
:
f
.
fault_description
||
f
.
fault_type
||
''
,
alertTime
:
f
.
occurred_time
||
''
,
status
:
faultStatusTextMap
[
f
.
status
]
||
'未知'
,
}));
}
}
catch
(
err
)
{
console
.
error
(
"预警监控数据查询失败,使用空数据降级:"
,
err
);
}
resultAny
.
alertManagement
=
{
resultAny
.
alertManagement
=
{
alertStatus
:
alertStatus
,
alertStatus
,
alertWorkLevel
:
alertWorkLevel
,
alertWorkLevel
,
alertWorkType
:
alertWorkType
,
alertWorkType
,
alertWorkOrders
:
alertWorkOrders
alertWorkOrders
,
};
};
// 三级页面,预警信息展示不同
if
(
regionType
)
{
resultAny
.
alertManagement
.
alertWorkOrders
=
alertWorkThreeOrders
;
}
// 6.1 人流监控及客流量趋势分析
// 6.1 人流监控及客流量趋势分析
let
regionInfos
:
any
=
[];
let
regionInfos
:
any
=
[];
...
@@ -370,16 +445,25 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
...
@@ -370,16 +445,25 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
"%orderAsc%"
:
"device_time"
"%orderAsc%"
:
"device_time"
},
[
"device_id"
,
"data"
,
"device_time"
]);
},
[
"device_id"
,
"data"
,
"device_time"
]);
// 统计区域类型的客流量
// 统计区域类型的客流量
(新格式使用 in/out)
for
(
let
rec
of
customerDeviceDatas
.
data
)
{
for
(
let
rec
of
customerDeviceDatas
.
data
)
{
let
data
=
rec
.
data
;
let
data
=
rec
.
data
;
// if (data.presence === '进') {
// ====== 旧格式(已弃用,保留备用) ======
if
(
data
.
current_total
)
{
// if (data.current_total) {
totalRegionCustomerNum
+=
data
.
current_total
;
// totalRegionCustomerNum += data.current_total;
// if (!regionCustomerMap.has(regionName)) {
// regionCustomerMap.set(regionName, data.current_total);
// } else {
// regionCustomerMap.set(regionName, totalNum + data.current_total);
// }
// }
const
netVisitor
=
(
data
.
in
??
0
);
if
(
netVisitor
>
0
)
{
totalRegionCustomerNum
+=
netVisitor
;
if
(
!
regionCustomerMap
.
has
(
regionName
))
{
if
(
!
regionCustomerMap
.
has
(
regionName
))
{
regionCustomerMap
.
set
(
regionName
,
data
.
current_total
);
regionCustomerMap
.
set
(
regionName
,
netVisitor
);
}
else
{
}
else
{
regionCustomerMap
.
set
(
regionName
,
totalNum
+
data
.
current_total
);
regionCustomerMap
.
set
(
regionName
,
totalNum
+
netVisitor
);
}
}
}
}
}
}
...
@@ -393,7 +477,7 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
...
@@ -393,7 +477,7 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
let
yesterdayCustomer
=
0
;
let
yesterdayCustomer
=
0
;
// 计算每个区域的饱和度(客流量/区域最大承载量),并转换成表格
// 计算每个区域的饱和度(客流量/区域最大承载量),并转换成表格
for
(
let
[
regionName
,
customerNum
]
of
regionCustomerMap
.
entries
())
{
for
(
let
[
regionName
,
customerNum
]
of
regionCustomerMap
.
entries
())
{
let
regionMaxCustomer
=
regionMaxCustomerMap
.
get
(
regionName
)
||
1000
0
;
// 默认最大承载量为10
000
let
regionMaxCustomer
=
regionMaxCustomerMap
.
get
(
regionName
)
||
1000
;
// 默认最大承载量为1
000
let
saturation
=
`
${((
customerNum
/
regionMaxCustomer
)
*
100
).
toFixed
(
2
)}
%`
;
let
saturation
=
`
${((
customerNum
/
regionMaxCustomer
)
*
100
).
toFixed
(
2
)}
%`
;
regionCustomerTable
.
push
({
regionName
,
customerNum
,
saturation
});
regionCustomerTable
.
push
({
regionName
,
customerNum
,
saturation
});
todayCustomer
+=
customerNum
;
todayCustomer
+=
customerNum
;
...
@@ -419,8 +503,10 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
...
@@ -419,8 +503,10 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
let
d
=
new
Date
(
rec
.
device_time
);
let
d
=
new
Date
(
rec
.
device_time
);
let
hourKey
=
`
${
d
.
getHours
()}
时`
;
let
hourKey
=
`
${
d
.
getHours
()}
时`
;
let
data
=
rec
.
data
;
let
data
=
rec
.
data
;
// let customerNum = data.presence === '进' ? 1 : 0;
// ====== 旧格式(已弃用,保留备用) ======
let
customerNum
=
data
.
current_total
;
// let customerNum = data.current_total;
// ====== 新格式使用 in ======
let
customerNum
=
data
.
in
??
0
;
if
(
!
hourlyCustomerMap
.
has
(
hourKey
))
{
if
(
!
hourlyCustomerMap
.
has
(
hourKey
))
{
hourlyCustomerMap
.
set
(
hourKey
,
customerNum
);
hourlyCustomerMap
.
set
(
hourKey
,
customerNum
);
}
else
{
}
else
{
...
@@ -443,8 +529,10 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
...
@@ -443,8 +529,10 @@ export async function getRunAnalysis(regionGroup: string, regionType: string) {
},
[
"device_id"
,
"data"
,
"device_time"
]);
},
[
"device_id"
,
"data"
,
"device_time"
]);
for
(
let
rec
of
yesterdayDatas
.
data
)
{
for
(
let
rec
of
yesterdayDatas
.
data
)
{
let
data
=
rec
.
data
;
let
data
=
rec
.
data
;
// let customerNum = data.presence === '进' ? 1 : 0;
// ====== 旧格式(已弃用,保留备用) ======
let
customerNum
=
data
.
current_total
;
// let customerNum = data.current_total;
// ====== 新格式使用 in ======
let
customerNum
=
data
.
in
??
0
;
yesterdayCustomer
+=
customerNum
;
yesterdayCustomer
+=
customerNum
;
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment