nayota-show-sdk 1.3.63 → 1.3.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,10 @@ function shouldUseIot(action) {
10
10
  * @file 设备类型api
11
11
  * @module 设备类型接口
12
12
  * @category 设备管理
13
+ * @import
14
+ * import { deviceClass } from 'nayota-show-sdk'
15
+ * const { list, create, getOne, updateOne, deleteOne, deleteMany, getDeviceOffline, onlineRate } = deviceClass
16
+ * list({ page: 1, limit: 10 })
13
17
  * @categoryOrder 2
14
18
  */
15
19
 
@@ -209,6 +213,48 @@ export function getDeviceOffline(data) {
209
213
  })
210
214
  }
211
215
 
216
+ /**
217
+ * 获取设备类型在线率
218
+ * @param {Object} query - 查询参数
219
+ * @param {number} query.year - 统计年份,例如 2026
220
+ * @param {number} [query.month] - 统计月份,1-12;不传表示查询整年
221
+ * @param {string} [query.creator] - 所属用户ID
222
+ * @param {Array<string>|string} [query.deviceClasses] - 设备类型ID列表,也兼容逗号分隔字符串
223
+ * @returns {number} code - 返回码,0表示成功
224
+ * @returns {Object} data - 在线率统计结果
225
+ * @returns {number} data.year - 统计年份
226
+ * @returns {number|null} data.month - 统计月份;查询全年时为 null
227
+ * @returns {number} data.startTime - 统计开始时间戳
228
+ * @returns {number} data.endTime - 统计结束时间戳
229
+ * @returns {Object} data.summary - 所有设备类型汇总在线率
230
+ * @returns {number} data.summary.onlineDuration - 汇总在线时长,单位毫秒
231
+ * @returns {number} data.summary.offlineDuration - 汇总离线时长,单位毫秒
232
+ * @returns {number} data.summary.totalDuration - 汇总总时长,单位毫秒
233
+ * @returns {number} data.summary.onlineRate - 汇总在线率,0-1
234
+ * @returns {number} data.summary.onlineRatePercent - 汇总在线率百分比
235
+ * @returns {Array<Object>} data.items - 各设备类型在线率列表
236
+ * @returns {string} data.items[].deviceClass - 设备类型ID
237
+ * @returns {string} data.items[].deviceClassName - 设备类型名称
238
+ * @returns {number} data.items[].alarmTotal - 参与统计的在离线 alarm 数量
239
+ * @returns {Object} data.items[].summary - 当前设备类型在线率汇总
240
+ * @returns {number} data.items[].summary.onlineDuration - 在线时长,单位毫秒
241
+ * @returns {number} data.items[].summary.offlineDuration - 离线时长,单位毫秒
242
+ * @returns {number} data.items[].summary.totalDuration - 总时长,单位毫秒
243
+ * @returns {number} data.items[].summary.onlineRate - 在线率,0-1
244
+ * @returns {number} data.items[].summary.onlineRatePercent - 在线率百分比
245
+ */
246
+ export function onlineRate(query) {
247
+ if (shouldUseIot('onlineRate')) {
248
+ return executeIotModuleAction(MODULE_NAME, 'onlineRate', query)
249
+ }
250
+
251
+ return requestShow({
252
+ url: '/device-classes/online-rate',
253
+ method: 'get',
254
+ params: query
255
+ })
256
+ }
257
+
212
258
  export default {
213
259
  list,
214
260
  create,
@@ -216,5 +262,6 @@ export default {
216
262
  deleteOne,
217
263
  deleteMany,
218
264
  getOne,
219
- getDeviceOffline
265
+ getDeviceOffline,
266
+ onlineRate
220
267
  }
package/index.test.js CHANGED
@@ -1,27 +1,38 @@
1
- import sdk from './index'
1
+ let modules
2
+ beforeAll(() => {
3
+ jest.mock('./__mocks__/requireContext')
2
4
 
3
- describe('nayota-show-sdk exports', () => {
4
- test('exposes config entry and core API modules', () => {
5
- expect(sdk).toBeDefined()
6
- expect(typeof sdk.config).toBe('function')
7
- expect(typeof sdk.on).toBe('function')
8
-
9
- expect(sdk.area).toBeDefined()
10
- expect(typeof sdk.area.list).toBe('function')
11
-
12
- expect(sdk.areaClass).toBeDefined()
13
- expect(typeof sdk.areaClass.getOne).toBe('function')
14
-
15
- expect(sdk.components).toBeDefined()
16
- expect(typeof sdk.components.create).toBe('function')
5
+ modules = require('./index.js')
6
+ })
17
7
 
18
- expect(sdk.departs).toBeDefined()
19
- expect(typeof sdk.departs.updateOne).toBe('function')
8
+ // Test the modules object
9
+ describe('modules', () => {
10
+ test('should have the correct structure', () => {
11
+ expect(modules).toBeDefined()
12
+ expect(typeof modules).toBe('object')
13
+ expect(Object.keys(modules)).toHaveLength(17) // Assuming there is only one module in the littleTool directory
20
14
 
21
- expect(sdk.devices).toBeDefined()
22
- expect(typeof sdk.devices.easyList).toBe('function')
15
+ // Test the structure of the module
16
+ // const module = modules['api'] // Assuming the module name is 'api'
17
+ // expect(module).toBeDefined()
18
+ // expect(typeof module).toBe('object')
19
+ // expect(Object.keys(module)).toHaveLength(13) // Assuming there are 13 sub-modules in the api directory
23
20
 
24
- expect(sdk.deviceClass).toBeDefined()
25
- expect(typeof sdk.deviceClass.deleteOne).toBe('function')
21
+ // // Test the structure of each sub-module
22
+ // expect(module['alarms']).toBeDefined()
23
+ // expect(module['checkReduces']).toBeDefined()
24
+ // expect(module['user']).toBeDefined()
25
+ // expect(module['httpDrives']).toBeDefined()
26
+ // expect(module['hardwares']).toBeDefined()
27
+ // expect(module['checks']).toBeDefined()
28
+ // expect(module['cloudHardwares']).toBeDefined()
29
+ // expect(module['loraSlaves']).toBeDefined()
30
+ // expect(module['lorawanDevices']).toBeDefined()
31
+ // expect(module['nbiotDrives']).toBeDefined()
32
+ // expect(module['nbm2mDevices']).toBeDefined()
33
+ // expect(module['netDrives']).toBeDefined()
34
+ // expect(module['netMqttDevices']).toBeDefined()
35
+ // // 添加alarms list请求的测试
36
+ // expect(module['alarms']['list']).toBeDefined()
26
37
  })
27
38
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nayota-show-sdk",
3
- "version": "1.3.63",
3
+ "version": "1.3.66",
4
4
  "description": "nayota-show-server rest-api",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1,12 +1,24 @@
1
1
  import urlcfg from '../config/urlcfg'
2
2
  import createHttpInstance from './http-factory'
3
3
 
4
+ function isLegacySuccessCode(code) {
5
+ if (typeof code === 'number') {
6
+ return code >= 200 && code < 300
7
+ }
8
+
9
+ if (typeof code === 'string' && /^2\d{2}$/.test(code)) {
10
+ return true
11
+ }
12
+
13
+ return false
14
+ }
15
+
4
16
  function normalizeIotResponseData(data) {
5
17
  if (!data || typeof data !== 'object' || Array.isArray(data)) {
6
18
  return data
7
19
  }
8
20
 
9
- if (data.code === 200) {
21
+ if (isLegacySuccessCode(data.code)) {
10
22
  return {
11
23
  ...data,
12
24
  code: 0
@@ -16,10 +28,15 @@ function normalizeIotResponseData(data) {
16
28
  return data
17
29
  }
18
30
 
31
+ function isIotSuccessResponseData(data) {
32
+ return data && typeof data === 'object' && data.code === 0
33
+ }
34
+
19
35
  export default function httpConfigIot() {
20
36
  return createHttpInstance({
21
37
  getBaseUrl: () => urlcfg.getIotUrl(),
22
38
  contentType: 'application/json;charset=UTF-8',
23
- normalizeResponseData: normalizeIotResponseData
39
+ normalizeResponseData: normalizeIotResponseData,
40
+ isSuccessResponseData: isIotSuccessResponseData
24
41
  })
25
42
  }
@@ -4,10 +4,15 @@ import axios from 'axios'
4
4
  import urlcfg from '../config/urlcfg'
5
5
  import emitter from './EventEmitter'
6
6
 
7
+ function isSuccessStatus(status) {
8
+ return typeof status === 'number' && status >= 200 && status < 300
9
+ }
10
+
7
11
  function createHttpInstance({
8
12
  getBaseUrl,
9
13
  contentType,
10
- normalizeResponseData
14
+ normalizeResponseData,
15
+ isSuccessResponseData
11
16
  }) {
12
17
  const http = axios.create({
13
18
  baseURL: getBaseUrl(),
@@ -53,8 +58,12 @@ function createHttpInstance({
53
58
  return res
54
59
  }
55
60
 
56
- if (res.status === 200) {
57
- if (data.code !== 0) {
61
+ if (isSuccessStatus(res.status)) {
62
+ const success = typeof isSuccessResponseData === 'function'
63
+ ? isSuccessResponseData(data, res)
64
+ : data.code === 0
65
+
66
+ if (!success) {
58
67
  return Promise.reject(data)
59
68
  }
60
69
  return data
@@ -199,18 +199,19 @@ export function parseLegacySort(sortValue, sortFieldMap = {}) {
199
199
 
200
200
  export function buildLegacyListResponse(response, mapItem) {
201
201
  const payload = extractResponsePayload(response)
202
- const items = Array.isArray(payload?.items)
203
- ? payload.items
204
- : Array.isArray(payload?.rows)
205
- ? payload.rows
206
- : Array.isArray(payload)
207
- ? payload
202
+ const data = payload?.data !== undefined ? payload.data : payload
203
+ const items = Array.isArray(data?.items)
204
+ ? data.items
205
+ : Array.isArray(data?.rows)
206
+ ? data.rows
207
+ : Array.isArray(data)
208
+ ? data
208
209
  : []
209
210
 
210
211
  return {
211
212
  code: 0,
212
213
  data: {
213
- total: Number(payload?.total ?? items.length ?? 0),
214
+ total: Number(data?.total ?? items.length ?? 0),
214
215
  rows: items.map(item => (mapItem ? mapItem(item) : withLegacyId(item)))
215
216
  }
216
217
  }
@@ -503,11 +503,17 @@ export const iotModuleSpecs = {
503
503
  },
504
504
  fromResponse(response) {
505
505
  const payload = response && response.data && response.status ? response.data : response
506
+ const data = payload?.data !== undefined ? payload.data : payload
507
+ const rows = Array.isArray(data?.rows)
508
+ ? data.rows
509
+ : Array.isArray(data?.items)
510
+ ? data.items
511
+ : []
506
512
  return {
507
513
  code: 0,
508
514
  data: {
509
- total: Number(payload?.total || 0),
510
- rows: Array.isArray(payload?.rows) ? payload.rows.map(item => withLegacyId(item)) : []
515
+ total: Number(data?.total ?? rows.length ?? 0),
516
+ rows: rows.map(item => withLegacyId(item))
511
517
  }
512
518
  }
513
519
  }
@@ -1,49 +0,0 @@
1
- import httpConfigIot from './utils/http-config-iot'
2
-
3
- jest.mock('axios', () => {
4
- const create = jest.fn(() => {
5
- const instance = jest.fn()
6
- instance.interceptors = {
7
- request: { use: jest.fn() },
8
- response: { use: jest.fn() }
9
- }
10
- return instance
11
- })
12
-
13
- return {
14
- __esModule: true,
15
- default: {
16
- create,
17
- defaults: {
18
- headers: {
19
- common: {}
20
- }
21
- }
22
- }
23
- }
24
- })
25
-
26
- describe('httpConfigIot', () => {
27
- test('normalizes iot success code 200 into legacy success code 0', () => {
28
- const http = httpConfigIot()
29
- const responseInterceptor = http.interceptors.response.use.mock.calls[0][0]
30
-
31
- expect(
32
- responseInterceptor({
33
- status: 200,
34
- headers: {},
35
- data: {
36
- code: 200,
37
- data: {
38
- id: 'space-1'
39
- }
40
- }
41
- })
42
- ).toEqual({
43
- code: 0,
44
- data: {
45
- id: 'space-1'
46
- }
47
- })
48
- })
49
- })
@@ -1,29 +0,0 @@
1
- import { buildLegacyListResponse } from './utils/iot-adapter-helpers'
2
-
3
- describe('iot adapter helpers', () => {
4
- test('wraps list responses as code + data.total/data.rows', () => {
5
- const result = buildLegacyListResponse({
6
- total: 1,
7
- items: [
8
- {
9
- id: 'type-1',
10
- name: '风速仪'
11
- }
12
- ]
13
- })
14
-
15
- expect(result).toEqual({
16
- code: 0,
17
- data: {
18
- total: 1,
19
- rows: [
20
- {
21
- id: 'type-1',
22
- _id: 'type-1',
23
- name: '风速仪'
24
- }
25
- ]
26
- }
27
- })
28
- })
29
- })