@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.
- package/lib/api/index.d.ts +5 -0
- package/lib/api/index.js +18 -0
- package/lib/api/linkage.d.ts +161 -0
- package/lib/api/linkage.js +74 -0
- package/lib/api/lock.d.ts +195 -0
- package/lib/api/lock.js +129 -0
- package/lib/api/log.d.ts +166 -0
- package/lib/api/log.js +44 -0
- package/lib/api/setting.d.ts +14 -0
- package/lib/api/setting.js +36 -0
- package/lib/api/temp.d.ts +211 -0
- package/lib/api/temp.js +130 -0
- package/lib/api/user.d.ts +154 -0
- package/lib/api/user.js +59 -0
- package/lib/api/video.d.ts +9 -0
- package/lib/api/video.js +17 -0
- package/lib/config/dp-code/index.d.ts +175 -0
- package/lib/config/dp-code/index.js +224 -0
- package/lib/config/dp-map/common.d.ts +102 -0
- package/lib/config/dp-map/common.js +120 -0
- package/lib/config/dp-map/normal.d.ts +6 -0
- package/lib/config/dp-map/normal.js +51 -0
- package/lib/config/dp-map/open.d.ts +21 -0
- package/lib/config/dp-map/open.js +62 -0
- package/lib/config/dp-map/unlock-method-big.d.ts +559 -0
- package/lib/config/dp-map/unlock-method-big.js +237 -0
- package/lib/config/dp-map/unlock-method.d.ts +551 -0
- package/lib/config/dp-map/unlock-method.js +231 -0
- package/lib/config/index.d.ts +46 -0
- package/lib/config/index.js +56 -0
- package/lib/constant.d.ts +101 -0
- package/lib/constant.js +136 -0
- package/lib/dp-interface.d.ts +7 -0
- package/lib/dp-interface.js +1 -0
- package/lib/event.d.ts +8 -0
- package/lib/event.js +9 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.js +92 -0
- package/lib/interface.d.ts +807 -0
- package/lib/interface.js +1 -0
- package/lib/linkage.d.ts +26 -0
- package/lib/linkage.js +175 -0
- package/lib/log.d.ts +91 -0
- package/lib/log.js +314 -0
- package/lib/media.d.ts +43 -0
- package/lib/media.js +80 -0
- package/lib/open.d.ts +48 -0
- package/lib/open.js +247 -0
- package/lib/other.d.ts +36 -0
- package/lib/other.js +178 -0
- package/lib/parse/index.d.ts +6 -0
- package/lib/parse/index.js +22 -0
- package/lib/signal.d.ts +26 -0
- package/lib/signal.js +38 -0
- package/lib/sleep.d.ts +61 -0
- package/lib/sleep.js +121 -0
- package/lib/state.d.ts +54 -0
- package/lib/state.js +429 -0
- package/lib/sync/remote-serect-key.d.ts +5 -0
- package/lib/sync/remote-serect-key.js +60 -0
- package/lib/sync/t0.d.ts +5 -0
- package/lib/sync/t0.js +33 -0
- package/lib/sync/temp.d.ts +7 -0
- package/lib/sync/temp.js +88 -0
- package/lib/sync/unlock-mothod.d.ts +5 -0
- package/lib/sync/unlock-mothod.js +54 -0
- package/lib/temporary.d.ts +226 -0
- package/lib/temporary.js +637 -0
- package/lib/unlock-method.d.ts +269 -0
- package/lib/unlock-method.js +723 -0
- package/lib/user.d.ts +108 -0
- package/lib/user.js +361 -0
- package/lib/utils/base64-to-hex.d.ts +1 -0
- package/lib/utils/base64-to-hex.js +12 -0
- package/lib/utils/byte.d.ts +19 -0
- package/lib/utils/byte.js +74 -0
- package/lib/utils/constant.d.ts +11 -0
- package/lib/utils/constant.js +17 -0
- package/lib/utils/device.d.ts +207 -0
- package/lib/utils/device.js +353 -0
- package/lib/utils/errors.d.ts +2 -0
- package/lib/utils/errors.js +125 -0
- package/lib/utils/event.d.ts +23 -0
- package/lib/utils/event.js +144 -0
- package/lib/utils/hex-to-base64.d.ts +1 -0
- package/lib/utils/hex-to-base64.js +8 -0
- package/lib/utils/hex-to-bytes.d.ts +6 -0
- package/lib/utils/hex-to-bytes.js +16 -0
- package/lib/utils/index.d.ts +169 -0
- package/lib/utils/index.js +419 -0
- package/lib/utils/log.d.ts +5 -0
- package/lib/utils/log.js +78 -0
- package/lib/utils/publishDps.d.ts +11 -0
- package/lib/utils/publishDps.js +91 -0
- 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
|
+
};
|