@ray-js/lock-sdk 1.0.0-beta-1

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.
Files changed (95) hide show
  1. package/lib/api/index.d.ts +5 -0
  2. package/lib/api/index.js +18 -0
  3. package/lib/api/linkage.d.ts +161 -0
  4. package/lib/api/linkage.js +74 -0
  5. package/lib/api/lock.d.ts +195 -0
  6. package/lib/api/lock.js +129 -0
  7. package/lib/api/log.d.ts +166 -0
  8. package/lib/api/log.js +44 -0
  9. package/lib/api/setting.d.ts +14 -0
  10. package/lib/api/setting.js +36 -0
  11. package/lib/api/temp.d.ts +211 -0
  12. package/lib/api/temp.js +130 -0
  13. package/lib/api/user.d.ts +154 -0
  14. package/lib/api/user.js +59 -0
  15. package/lib/api/video.d.ts +9 -0
  16. package/lib/api/video.js +17 -0
  17. package/lib/config/dp-code/index.d.ts +175 -0
  18. package/lib/config/dp-code/index.js +224 -0
  19. package/lib/config/dp-map/common.d.ts +102 -0
  20. package/lib/config/dp-map/common.js +120 -0
  21. package/lib/config/dp-map/normal.d.ts +6 -0
  22. package/lib/config/dp-map/normal.js +51 -0
  23. package/lib/config/dp-map/open.d.ts +21 -0
  24. package/lib/config/dp-map/open.js +62 -0
  25. package/lib/config/dp-map/unlock-method-big.d.ts +559 -0
  26. package/lib/config/dp-map/unlock-method-big.js +237 -0
  27. package/lib/config/dp-map/unlock-method.d.ts +551 -0
  28. package/lib/config/dp-map/unlock-method.js +231 -0
  29. package/lib/config/index.d.ts +46 -0
  30. package/lib/config/index.js +56 -0
  31. package/lib/constant.d.ts +101 -0
  32. package/lib/constant.js +136 -0
  33. package/lib/dp-interface.d.ts +7 -0
  34. package/lib/dp-interface.js +1 -0
  35. package/lib/event.d.ts +8 -0
  36. package/lib/event.js +9 -0
  37. package/lib/index.d.ts +25 -0
  38. package/lib/index.js +92 -0
  39. package/lib/interface.d.ts +807 -0
  40. package/lib/interface.js +1 -0
  41. package/lib/linkage.d.ts +26 -0
  42. package/lib/linkage.js +175 -0
  43. package/lib/log.d.ts +91 -0
  44. package/lib/log.js +314 -0
  45. package/lib/media.d.ts +43 -0
  46. package/lib/media.js +80 -0
  47. package/lib/open.d.ts +48 -0
  48. package/lib/open.js +247 -0
  49. package/lib/other.d.ts +36 -0
  50. package/lib/other.js +178 -0
  51. package/lib/parse/index.d.ts +6 -0
  52. package/lib/parse/index.js +22 -0
  53. package/lib/signal.d.ts +26 -0
  54. package/lib/signal.js +38 -0
  55. package/lib/sleep.d.ts +61 -0
  56. package/lib/sleep.js +121 -0
  57. package/lib/state.d.ts +54 -0
  58. package/lib/state.js +429 -0
  59. package/lib/sync/remote-serect-key.d.ts +5 -0
  60. package/lib/sync/remote-serect-key.js +60 -0
  61. package/lib/sync/t0.d.ts +5 -0
  62. package/lib/sync/t0.js +33 -0
  63. package/lib/sync/temp.d.ts +7 -0
  64. package/lib/sync/temp.js +88 -0
  65. package/lib/sync/unlock-mothod.d.ts +5 -0
  66. package/lib/sync/unlock-mothod.js +54 -0
  67. package/lib/temporary.d.ts +226 -0
  68. package/lib/temporary.js +637 -0
  69. package/lib/unlock-method.d.ts +269 -0
  70. package/lib/unlock-method.js +723 -0
  71. package/lib/user.d.ts +108 -0
  72. package/lib/user.js +361 -0
  73. package/lib/utils/base64-to-hex.d.ts +1 -0
  74. package/lib/utils/base64-to-hex.js +12 -0
  75. package/lib/utils/byte.d.ts +19 -0
  76. package/lib/utils/byte.js +74 -0
  77. package/lib/utils/constant.d.ts +11 -0
  78. package/lib/utils/constant.js +17 -0
  79. package/lib/utils/device.d.ts +207 -0
  80. package/lib/utils/device.js +353 -0
  81. package/lib/utils/errors.d.ts +2 -0
  82. package/lib/utils/errors.js +125 -0
  83. package/lib/utils/event.d.ts +23 -0
  84. package/lib/utils/event.js +144 -0
  85. package/lib/utils/hex-to-base64.d.ts +1 -0
  86. package/lib/utils/hex-to-base64.js +8 -0
  87. package/lib/utils/hex-to-bytes.d.ts +6 -0
  88. package/lib/utils/hex-to-bytes.js +16 -0
  89. package/lib/utils/index.d.ts +169 -0
  90. package/lib/utils/index.js +419 -0
  91. package/lib/utils/log.d.ts +5 -0
  92. package/lib/utils/log.js +78 -0
  93. package/lib/utils/publishDps.d.ts +11 -0
  94. package/lib/utils/publishDps.js +91 -0
  95. package/package.json +37 -0
@@ -0,0 +1,723 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import "core-js/modules/esnext.iterator.constructor.js";
3
+ import "core-js/modules/esnext.iterator.map.js";
4
+ import dpUtils from "@ray-js/tuya-dp-transform";
5
+ import { bindUnlockMethodToUser, bindUnlockMethodToUserByRecord, checkFreeUnlockMethods, createUnlockMethod, removeUnlockMethod, editUnlockMethod, fetchCreatePasswordSN, fetchFreeUnlockMethods, getUnlockMethodInfo, unbindMemberUnlockMethod } from "./api/lock";
6
+ import { getUserDetail } from "./api/user";
7
+ import config from "./config";
8
+ import dpCodes from "./config/dp-code";
9
+ import { add as addMap, reportAdd as reportAddMap, remove as removeMap, reportRemove as reportRemoveMap } from "./config/dp-map/unlock-method";
10
+ import { add as addBigMap, reportAdd as reportAddBigMap, remove as removeBigMap, reportRemove as reportRemoveBigMap } from "./config/dp-map/unlock-method-big";
11
+ import { validConfigDpMap } from "./config/dp-map/common";
12
+ import { getPermanentSetting, getUnlockMethodTypeByDpCode, getUnlockMethodTypeByType, isAdmin, parallelOnly, sleep } from "./utils";
13
+ import { getError } from "./utils/errors";
14
+ import { publishDps } from "./utils/publishDps";
15
+ import { encrypt } from "./utils/device";
16
+ import emitter from "./utils/event";
17
+ import { DPCHANGE, UNLOCK_METHOD_EVENT } from "./utils/constant";
18
+ import { sendPhoneVerifyCode } from "./api";
19
+ const getAddUnlockError = status => {
20
+ if (status >= 0 && status <= 10) {
21
+ return getError(1015 + status);
22
+ }
23
+ if (status === 0xfe) {
24
+ return getError(1026);
25
+ }
26
+ return getError(1016);
27
+ };
28
+
29
+ /**
30
+ * 获取开锁方式详细信息
31
+ * @param {number} id 开锁方式 id
32
+ * @returns
33
+ */
34
+ export const getUnlockMethodDetail = async id => {
35
+ var _cloudData$notifyInfo, _cloudData$notifyInfo2, _cloudData$notifyInfo3;
36
+ const cloudData = await getUnlockMethodInfo({
37
+ devId: config.devInfo.devId,
38
+ opModeId: id
39
+ });
40
+ const detail = {
41
+ isBound: cloudData.allocateFlag === 1,
42
+ phase: cloudData.phase,
43
+ dpId: Number(cloudData.opmode),
44
+ isSpecial: cloudData.unlockAttr === 1,
45
+ unlockName: cloudData.unlockName,
46
+ userId: cloudData.userId,
47
+ unlockId: Number(cloudData.opmodeValue),
48
+ lockUserId: cloudData.lockUserId,
49
+ id: cloudData.opmodeId,
50
+ userType: cloudData.userType,
51
+ notifyInfo: {
52
+ appSend: !!((_cloudData$notifyInfo = cloudData.notifyInfo) !== null && _cloudData$notifyInfo !== void 0 && _cloudData$notifyInfo.appSend),
53
+ msgPhone: (_cloudData$notifyInfo2 = cloudData.notifyInfo) === null || _cloudData$notifyInfo2 === void 0 ? void 0 : _cloudData$notifyInfo2.msgPhone,
54
+ countryCode: (_cloudData$notifyInfo3 = cloudData.notifyInfo) === null || _cloudData$notifyInfo3 === void 0 ? void 0 : _cloudData$notifyInfo3.countryCode
55
+ }
56
+ };
57
+ return detail;
58
+ };
59
+ const getUnlockMethodBase = async (type, userId) => {
60
+ const {
61
+ idsByCode,
62
+ devInfo: {
63
+ devId
64
+ },
65
+ supportBigData,
66
+ dpSchema
67
+ } = config;
68
+ const unlockMethodConfig = getUnlockMethodTypeByType(type);
69
+ const addDpCode = supportBigData ? dpCodes.unlockMethodCreateW : dpCodes.unlockMethodCreate;
70
+ const dpId = idsByCode[unlockMethodConfig.code];
71
+ const [user, sn] = await Promise.all([getUserDetail({
72
+ devId: devId,
73
+ userId: userId
74
+ }), fetchCreatePasswordSN({
75
+ devId: devId,
76
+ dpId
77
+ })]);
78
+ const {
79
+ userType,
80
+ lockUserId,
81
+ userTimeSet
82
+ } = user;
83
+ let validConfig;
84
+ // 处理时效配置
85
+ if (userTimeSet) {
86
+ validConfig = dpUtils.parse(userTimeSet,
87
+ // @ts-expect-error
88
+ validConfigDpMap.childMap);
89
+ } else {
90
+ validConfig = getPermanentSetting();
91
+ }
92
+
93
+ // 组装开始入录数据
94
+ const dpData = {
95
+ type: unlockMethodConfig.id,
96
+ stage: 0,
97
+ admin: isAdmin(userType),
98
+ memberId: lockUserId,
99
+ unlockId: supportBigData ? 0xffff : 0xff,
100
+ validConfig,
101
+ validNum: 0,
102
+ pwdLength: 0,
103
+ pwd: [],
104
+ sn
105
+ };
106
+ return {
107
+ unlockMethodConfig,
108
+ devId,
109
+ userType,
110
+ lockUserId,
111
+ sn,
112
+ dpId,
113
+ addDpCode,
114
+ addDpMap: supportBigData ? addBigMap : addMap,
115
+ addDpReportMap: supportBigData ? reportAddBigMap : reportAddMap,
116
+ dpData
117
+ };
118
+ };
119
+ const checkSpecial = (isSpecial, params, oldSetting) => {
120
+ const supportedPhone = checkSpecialSupportPhone();
121
+ if (isSpecial) {
122
+ if (!(params !== null && params !== void 0 && params.appSend)) {
123
+ if (!supportedPhone) {
124
+ throw getError(1057);
125
+ } else if (!(params !== null && params !== void 0 && params.msgPhone)) {
126
+ throw getError(1058);
127
+ }
128
+ }
129
+ if (supportedPhone && params !== null && params !== void 0 && params.msgPhone) {
130
+ if (!params.countryCode) {
131
+ throw getError(1056);
132
+ }
133
+ if (params.msgPhone !== (oldSetting === null || oldSetting === void 0 ? void 0 : oldSetting.msgPhone) && !params.verifyCode) {
134
+ throw getError(1055);
135
+ }
136
+ }
137
+ }
138
+ return {
139
+ unlockAttr: isSpecial ? 1 : 0,
140
+ notifyInfo: {
141
+ appSend: !!(params !== null && params !== void 0 && params.appSend),
142
+ msgPhone: supportedPhone ? params === null || params === void 0 ? void 0 : params.msgPhone : undefined,
143
+ countryCode: supportedPhone ? params === null || params === void 0 ? void 0 : params.countryCode : undefined,
144
+ msgPhoneVerifyCode: supportedPhone ? params === null || params === void 0 ? void 0 : params.verifyCode : undefined
145
+ }
146
+ };
147
+ };
148
+
149
+ /**
150
+ * 检查是否支持短信通知
151
+ * @returns 是否支持短信通知
152
+ */
153
+ export const checkSpecialSupportPhone = () => {
154
+ return !!config.dpSchema[dpCodes.message];
155
+ };
156
+
157
+ /**
158
+ * 添加开锁密码
159
+ */
160
+ export const addPassword = async params => {
161
+ // 数据验证
162
+ if (!params.password) {
163
+ throw getError(1054);
164
+ }
165
+ const specialInfo = checkSpecial(!!params.isSpecial, params.specialInfo);
166
+ const {
167
+ lockUserId,
168
+ dpData,
169
+ sn,
170
+ addDpCode,
171
+ addDpMap,
172
+ addDpReportMap,
173
+ devId,
174
+ dpId,
175
+ unlockMethodConfig
176
+ } = await getUnlockMethodBase("password", params.userId);
177
+ dpData.pwdLength = params.password.length;
178
+ dpData.pwd = params.password.split("").map(Number);
179
+ const res = await publishDps({
180
+ [addDpCode]: dpUtils.format(dpData, addDpMap)
181
+ }, {
182
+ checkReport: dpData => {
183
+ if (typeof dpData[addDpCode] !== "undefined") {
184
+ const result = dpUtils.parse(dpData[addDpCode], addDpReportMap);
185
+ console.log("AddPassword checkReport", result);
186
+ let hasReport = result.type === unlockMethodConfig.id && [0xff, 0xfd].includes(result.stage);
187
+ // 是否严格模式
188
+ if (config.strictMode) {
189
+ hasReport = hasReport && result.memberId === lockUserId && result.sn === sn;
190
+ }
191
+ if (hasReport) {
192
+ if (result.memberId !== lockUserId) {
193
+ console.warn(`AddPassword: lockUserId mismatch, expected ${lockUserId}, got ${result.memberId}`);
194
+ }
195
+ return result;
196
+ }
197
+ return false;
198
+ }
199
+ console.warn("AddPassword: An invalid value may have been reported");
200
+ return false;
201
+ }
202
+ });
203
+ if (res.stage === 0xfd) {
204
+ // 0xfd 表示添加失败
205
+ throw getAddUnlockError(res.status);
206
+ }
207
+
208
+ // 保存云端数据
209
+ const aesPwd = await encrypt(devId, params.password);
210
+
211
+ // 收到上报成功后,隔 300毫秒再保存云端
212
+ await sleep(300);
213
+ return await createUnlockMethod(_objectSpread({
214
+ devId: devId,
215
+ userId: params.userId,
216
+ unlockId: `${dpId}-${res.unlockId}`,
217
+ unlockName: params.name,
218
+ unlockDetail: aesPwd
219
+ }, specialInfo));
220
+ };
221
+ const addUnlockMethodData = {
222
+ unlockMethodConfig: {},
223
+ total: 0,
224
+ dpCode: "",
225
+ dpMap: {},
226
+ sn: 0,
227
+ lockUserId: 0,
228
+ timeoutId: 0,
229
+ userId: "",
230
+ // 云端用户 id
231
+ unlockDpId: 0
232
+ };
233
+ const handleAddTimeout = () => {
234
+ clearTimeout(addUnlockMethodData.timeoutId);
235
+ // @ts-expect-error
236
+ addUnlockMethodData.timeoutId = setTimeout(() => {
237
+ emitter.off(DPCHANGE, handleAddReport);
238
+ // 超时处理
239
+ emitter.emit(UNLOCK_METHOD_EVENT, {
240
+ type: addUnlockMethodData.unlockMethodConfig.type,
241
+ stage: "fail",
242
+ lockUserId: addUnlockMethodData.lockUserId,
243
+ error: getError(1002)
244
+ });
245
+ }, 15000);
246
+ };
247
+ const handleAddReport = async dps => {
248
+ if (dps[addUnlockMethodData.dpCode]) {
249
+ const result = dpUtils.parse(dps[addUnlockMethodData.dpCode], addUnlockMethodData.dpMap);
250
+ let eventData = null;
251
+ if (result.type !== addUnlockMethodData.unlockMethodConfig.id) {
252
+ // 开锁方式类型不匹配或sn(消息uuid)不匹配,忽略此次上报
253
+ return;
254
+ }
255
+ if (config.strictMode) {
256
+ // 严格模式下,严格匹配协议规则
257
+ if (result.sn !== addUnlockMethodData.sn || result.memberId !== addUnlockMethodData.lockUserId) {
258
+ return;
259
+ }
260
+ } else {
261
+ // 非严格模式下,告警不匹配
262
+ if (result.sn !== addUnlockMethodData.sn) {
263
+ // sn 不匹配,告警
264
+ console.warn(`AddUnlockMethod: sn mismatch, expected ${addUnlockMethodData.sn}, got ${result.sn}`);
265
+ }
266
+ if (result.memberId !== addUnlockMethodData.lockUserId) {
267
+ // 成员 id 不匹配,告警
268
+ console.warn(`AddUnlockMethod: lockUserId mismatch, expected ${addUnlockMethodData.lockUserId}, got ${result.memberId}`);
269
+ }
270
+ }
271
+ const type = addUnlockMethodData.unlockMethodConfig.type;
272
+ switch (result.stage) {
273
+ case 0xfc:
274
+ {
275
+ // 重新计时
276
+ handleAddTimeout();
277
+ // 录入中
278
+ eventData = {
279
+ type,
280
+ stage: "step",
281
+ lockUserId: result.memberId,
282
+ step: result.step,
283
+ total: addUnlockMethodData.total
284
+ };
285
+ break;
286
+ }
287
+ case 0xfd:
288
+ {
289
+ clearMonitoringAddReport();
290
+ // 录入失败
291
+ eventData = {
292
+ stage: "fail",
293
+ type,
294
+ lockUserId: result.memberId,
295
+ error: getAddUnlockError(result.status)
296
+ };
297
+ break;
298
+ }
299
+ case 0xfe:
300
+ {
301
+ clearMonitoringAddReport();
302
+ if (isCancelAddUnlockMethod) {
303
+ // 主动取消录入,则不处理
304
+ isCancelAddUnlockMethod = false;
305
+ return;
306
+ }
307
+ // 取消录入
308
+ eventData = {
309
+ stage: "fail",
310
+ type,
311
+ lockUserId: result.memberId,
312
+ error: getAddUnlockError(result.status)
313
+ };
314
+ break;
315
+ }
316
+ case 0xff:
317
+ {
318
+ clearMonitoringAddReport();
319
+ try {
320
+ // 收到上报成功后,隔 300毫秒再保存云端
321
+ await sleep(300);
322
+ // 直接添加云端接口,确保云端数据与设备侧一致
323
+ const res = await createUnlockMethod({
324
+ devId: config.devInfo.devId,
325
+ userId: addUnlockMethodData.userId,
326
+ unlockId: `${addUnlockMethodData.unlockDpId}-${result.unlockId}`,
327
+ unlockName: "",
328
+ unlockAttr: 0
329
+ });
330
+ eventData = {
331
+ stage: "success",
332
+ type,
333
+ id: res.opModeId,
334
+ name: res.unlockName
335
+ };
336
+ } catch {
337
+ eventData = {
338
+ stage: "fail",
339
+ type,
340
+ lockUserId: result.memberId,
341
+ error: getError(1053)
342
+ };
343
+ }
344
+ break;
345
+ }
346
+ default:
347
+ // 其他状态,则不处理
348
+ }
349
+ if (eventData) {
350
+ if (emitter.hasListener(UNLOCK_METHOD_EVENT)) {
351
+ emitter.emit(UNLOCK_METHOD_EVENT, eventData);
352
+ } else {
353
+ // 由于存在上报录入开始后,紧跟着会上报失败,因此项无监听器时则暂存数据
354
+ emitter.cache(UNLOCK_METHOD_EVENT, eventData);
355
+ }
356
+ }
357
+ }
358
+ };
359
+ const clearMonitoringAddReport = () => {
360
+ console.log("clearMonitoringAddReport");
361
+ clearTimeout(addUnlockMethodData.timeoutId);
362
+ // 清除监听器
363
+ emitter.off(DPCHANGE, handleAddReport);
364
+ };
365
+ const monitoringAddReport = option => {
366
+ // 缓存添加开锁方式的数据
367
+ Object.assign(addUnlockMethodData, option);
368
+ // 先移除之前的监听器,确保不会重复添加
369
+ emitter.clearCache(UNLOCK_METHOD_EVENT);
370
+ emitter.off(DPCHANGE, handleAddReport);
371
+ emitter.on(DPCHANGE, handleAddReport);
372
+ // 超时处理
373
+ handleAddTimeout();
374
+ };
375
+ export const startAddUnlockMethod = async params => {
376
+ const {
377
+ unlockMethodConfig,
378
+ lockUserId,
379
+ dpData,
380
+ sn,
381
+ addDpCode,
382
+ addDpMap,
383
+ addDpReportMap,
384
+ dpId
385
+ } = await getUnlockMethodBase(params.type, params.userId);
386
+ isCancelAddUnlockMethod = false;
387
+ const res = await publishDps({
388
+ [addDpCode]: dpUtils.format(dpData, addDpMap)
389
+ }, {
390
+ checkReport: dpData => {
391
+ if (typeof dpData[addDpCode] !== "undefined") {
392
+ const result = dpUtils.parse(dpData[addDpCode], addDpReportMap);
393
+ let hasReport = result.type === unlockMethodConfig.id;
394
+ // 是否严格模式
395
+ if (config.strictMode) {
396
+ hasReport = hasReport && result.memberId === lockUserId && result.sn === sn;
397
+ }
398
+ if (hasReport) {
399
+ if (result.memberId !== lockUserId) {
400
+ console.warn(`StartAddUnlockMethod: lockUserId mismatch, expected ${lockUserId}, got ${result.memberId}`);
401
+ }
402
+ // 由于有些锁对sn 的支持不一样,这里不强制 sn 相等
403
+ if (result.sn !== sn) {
404
+ console.warn("AddPassword: An invalid sn may have been reported");
405
+ }
406
+ return result;
407
+ }
408
+ return false;
409
+ }
410
+ console.warn("AddPassword: An invalid value may have been reported");
411
+ return false;
412
+ }
413
+ });
414
+ if (res.stage === 0) {
415
+ // 触发 dp 上报监听
416
+ monitoringAddReport({
417
+ unlockMethodConfig,
418
+ total: res.total,
419
+ dpCode: addDpCode,
420
+ dpMap: addDpReportMap,
421
+ sn,
422
+ lockUserId,
423
+ userId: params.userId,
424
+ unlockDpId: dpId
425
+ });
426
+ return {
427
+ total: res.total
428
+ };
429
+ }
430
+ if (res.stage === 0xfd) {
431
+ // 0xfd 表示添加失败
432
+ throw getAddUnlockError(res.status);
433
+ }
434
+ throw getError(1027);
435
+ };
436
+
437
+ // /**
438
+ // * 添加开锁方式
439
+ // * @param {AddUnlockMethodParams} params 入参
440
+ // * @returns
441
+ // */
442
+ // export const addUnlockMethod = async (params: AddUnlockMethodParams) => {
443
+ // const specialInfo = checkSpecial(!!params.isSpecial, params.specialInfo);
444
+ // const recordDpCode = getUnlockMethodTypeByType(params.type).code;
445
+
446
+ // const dpId = config.idsByCode[recordDpCode];
447
+
448
+ // return await createUnlockMethod({
449
+ // devId: config.devInfo.devId,
450
+ // userId: params.userId,
451
+ // unlockId: `${dpId}-${params.unlockId}`,
452
+ // unlockName: params.name,
453
+ // ...specialInfo,
454
+ // });
455
+ // };
456
+
457
+ /**
458
+ * 更新开锁方式
459
+ * 仅支持更新开锁方式名称和特殊开锁方式的通知信息
460
+ * @param {updateUnlockMethodParams} params 入参
461
+ * @returns
462
+ */
463
+ export const updateUnlockMethod = async params => {
464
+ // 获取开锁方式的详细信息
465
+ const detail = await getUnlockMethodDetail(params.id);
466
+ // 数据验证
467
+ const specialInfo = checkSpecial(!!params.isSpecial, params.specialInfo, detail.notifyInfo);
468
+ return await editUnlockMethod(_objectSpread({
469
+ devId: config.devInfo.devId,
470
+ opModeId: params.id,
471
+ unlockName: params.name
472
+ }, specialInfo));
473
+ };
474
+ // 标记是否主动取消录入
475
+ let isCancelAddUnlockMethod = false;
476
+ /**
477
+ * 取消添加开锁方式
478
+ * @param {CancelAddUnlockMethodParams} params 入参
479
+ * @returns
480
+ */
481
+ export const cancelAddUnlockMethod = parallelOnly(async params => {
482
+ // 获取 dp 数据
483
+ const {
484
+ dpData,
485
+ addDpCode,
486
+ addDpMap,
487
+ addDpReportMap,
488
+ unlockMethodConfig,
489
+ lockUserId,
490
+ sn
491
+ } = await getUnlockMethodBase(params.type, params.userId);
492
+ dpData.stage = 0xfe; // 设置 stage 为 0xfe,表示取消添加
493
+ isCancelAddUnlockMethod = true;
494
+ await publishDps({
495
+ [addDpCode]: dpUtils.format(dpData, addDpMap)
496
+ }, {
497
+ checkReport: dpData => {
498
+ if (typeof dpData[addDpCode] !== "undefined") {
499
+ const result = dpUtils.parse(dpData[addDpCode], addDpReportMap);
500
+ let hasReport = result.type === unlockMethodConfig.id;
501
+ // 是否严格模式
502
+ if (config.strictMode) {
503
+ hasReport = hasReport && result.stage === 0xfe && result.memberId === lockUserId && result.sn === sn;
504
+ }
505
+ if (hasReport) {
506
+ return result;
507
+ }
508
+ console.warn("CancelAddUnlockMethod: An invalid value may have been reported");
509
+ }
510
+ return false;
511
+ }
512
+ });
513
+ return true;
514
+ });
515
+
516
+ /**
517
+ * 删除开锁方式
518
+ * @param {number} id 开锁方式 id
519
+ */
520
+ export const deleteUnlockMethod = parallelOnly(async id => {
521
+ const {
522
+ lockUserId,
523
+ unlockId,
524
+ userType,
525
+ dpId
526
+ } = await getUnlockMethodDetail(id);
527
+ const dpCode = config.codesById[dpId];
528
+ const unlockMethodConfig = getUnlockMethodTypeByDpCode(dpCode);
529
+ // 获取对应的 dp
530
+ const removeDPCode = config.supportBigData ? dpCodes.unlockMethodDelW : dpCodes.unlockMethodDel;
531
+ if (!config.dpSchema[removeDPCode]) {
532
+ throw getError(1014);
533
+ }
534
+ const dpData = {
535
+ type: unlockMethodConfig.id,
536
+ stage: 0,
537
+ admin: isAdmin(userType),
538
+ memberId: lockUserId,
539
+ unlockId,
540
+ target: 1
541
+ };
542
+ const res = await publishDps({
543
+ [removeDPCode]: dpUtils.format(dpData, config.supportBigData ? removeBigMap : removeMap)
544
+ }, {
545
+ checkReport: dpData => {
546
+ if (typeof dpData[removeDPCode] !== "undefined") {
547
+ const result = dpUtils.parse(dpData[removeDPCode], config.supportBigData ? reportRemoveBigMap : reportRemoveMap);
548
+ let hasReport = result.type === unlockMethodConfig.id;
549
+ // 是否严格模式
550
+ if (config.strictMode) {
551
+ hasReport = hasReport && result.stage === 0 && result.memberId === lockUserId && result.unlockId === unlockId;
552
+ }
553
+ if (hasReport) {
554
+ if (result.unlockId !== unlockId) {
555
+ console.warn(`RemoveUnlockMethod: unlockId mismatch, expected ${unlockId}, got ${result.unlockId}`);
556
+ }
557
+ return result;
558
+ }
559
+ console.warn("RemoveUnlockMethod: An invalid value may have been reported");
560
+ }
561
+ return false;
562
+ }
563
+ });
564
+ if (res.status !== 255 && res.status !== 1) {
565
+ switch (res.status) {
566
+ case 2:
567
+ throw getError(1029);
568
+ case 0:
569
+ default:
570
+ throw getError(1028);
571
+ }
572
+ }
573
+ await removeUnlockMethod({
574
+ devId: config.devInfo.devId,
575
+ opmodeId: id
576
+ });
577
+ });
578
+
579
+ /**
580
+ * 检测是否有未绑定的开锁方式
581
+ * @returns
582
+ */
583
+ export const checkUnBindUnlockMethods = async () => {
584
+ const data = await checkFreeUnlockMethods({
585
+ devId: config.devInfo.devId
586
+ });
587
+ // 由于atop 返回的值,双端不一致,这里处理下
588
+ return data === true || data === 1;
589
+ };
590
+
591
+ /**
592
+ * 获取未关联开锁方式列表
593
+ */
594
+ export const getUnbindUnlockMethods = async () => {
595
+ const cloudData = await fetchFreeUnlockMethods({
596
+ devId: config.devInfo.devId
597
+ });
598
+
599
+ // 转化数据
600
+ const list = cloudData.map(item => {
601
+ const unlockMethodConfig = getUnlockMethodTypeByDpCode(item.standardDp);
602
+ return {
603
+ type: unlockMethodConfig.type,
604
+ list: item.unlockInfo.map(unlock => {
605
+ return {
606
+ unlockId: Number(unlock.unlockId.split("-")[1]),
607
+ unlockName: unlock.unlockName,
608
+ id: unlock.opmodeId,
609
+ unlockSn: unlock.unlockSn,
610
+ type: unlockMethodConfig.type,
611
+ dpId: Number(item.opmode),
612
+ dpCode: item.standardDp
613
+ };
614
+ })
615
+ };
616
+ });
617
+ return list;
618
+ };
619
+
620
+ /**
621
+ * 绑定未关联开锁方式到用户入参
622
+ */
623
+
624
+ /**
625
+ * 绑定未关联开锁方式到用户
626
+ * @param params
627
+ * @returns
628
+ */
629
+ export const bindUnlockMethod = params => {
630
+ const unlockIds = params.unlockList.map(item => {
631
+ const unlockMethodConfig = getUnlockMethodTypeByType(item.type);
632
+ const dpId = config.idsByCode[unlockMethodConfig.code];
633
+ return `${dpId}-${item.unlockId}`;
634
+ });
635
+ return bindUnlockMethodToUser({
636
+ devId: config.devInfo.devId,
637
+ userId: params.userId,
638
+ unlockIds: unlockIds
639
+ });
640
+ };
641
+
642
+ /**
643
+ * 解绑用户的开锁方式
644
+ * @param {number} id 开锁方式 id
645
+ * @returns
646
+ */
647
+ export const unbindUnlockMethod = async id => {
648
+ const detail = await getUnlockMethodDetail(id);
649
+ if (!detail.isBound) {
650
+ throw getError(1050);
651
+ }
652
+ return unbindMemberUnlockMethod({
653
+ devId: config.devInfo.devId,
654
+ userId: detail.userId,
655
+ unlockIds: [`${detail.dpId}-${detail.unlockId}`]
656
+ });
657
+ };
658
+ /**
659
+ * 绑定开门记录中未关联开锁方式到用户
660
+ * @param {UnbindUnlockMethodParams} params
661
+ * @returns
662
+ */
663
+ export const bindUnlockMethodFromLog = params => {
664
+ const {
665
+ idsByCode
666
+ } = config;
667
+ const unlockIds = params.unlockList.map(item => {
668
+ const unlockMethodConfig = getUnlockMethodTypeByType(item.type);
669
+ const dpId = idsByCode[unlockMethodConfig.code];
670
+ return `${dpId}-${item.unlockId}`;
671
+ });
672
+ return bindUnlockMethodToUserByRecord({
673
+ devId: config.devInfo.devId,
674
+ userId: params.userId,
675
+ unlockIds: unlockIds
676
+ });
677
+ };
678
+ /**
679
+ *
680
+ * @param params
681
+ * @returns
682
+ */
683
+ export const sendVerifyCode = params => {
684
+ return sendPhoneVerifyCode(_objectSpread(_objectSpread({}, params), {}, {
685
+ devId: config.devInfo.devId
686
+ }));
687
+ };
688
+
689
+ /**
690
+ * 添加开锁方式步骤事件类型
691
+ */
692
+
693
+ /**
694
+ * 添加开锁方式成员事件类型
695
+ */
696
+
697
+ /**
698
+ * 添加开锁方式错误事件类型
699
+ */
700
+
701
+ /**
702
+ * 添加开锁方式监听器事件类型
703
+ */
704
+
705
+ /**
706
+ * 添加开锁方式步骤监听器类型
707
+ */
708
+
709
+ /**
710
+ * 注册开锁方式步骤监听器
711
+ * @param {AddUnlockMethodListener} listener 监听器
712
+ */
713
+ export const onAddUnlockMethod = listener => {
714
+ emitter.on(UNLOCK_METHOD_EVENT, listener);
715
+ };
716
+
717
+ /**
718
+ * 注销开锁方式步骤监听器
719
+ * @param {AddUnlockMethodListener} listener 监听器
720
+ */
721
+ export const offAddUnlockMethod = listener => {
722
+ emitter.off(UNLOCK_METHOD_EVENT, listener);
723
+ };