fix: 新增 tree 组件的监听事件,优化 meta 全选的回调事件监听
This commit is contained in:
parent
35b99a3270
commit
762f480f81
10
.vscode/launch.json
vendored
Normal file
10
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"name": "http://localhost:8000/metas/big-image-preview",
|
||||||
|
"request": "launch",
|
||||||
|
"url": "http://localhost:8000/metas/big-image-preview"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,5 +1,39 @@
|
|||||||
# @zhst/biz
|
# @zhst/biz
|
||||||
|
|
||||||
|
## 0.9.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增 tree 组件的监听事件,优化 meta 全选的回调事件监听
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.8.3
|
||||||
|
- @zhst/func@0.7.4
|
||||||
|
- @zhst/meta@0.8.4
|
||||||
|
|
||||||
|
## 0.9.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 删除预览图组件,新增摄像头状态判断,修复 ts 生成失败问题
|
||||||
|
|
||||||
|
## 0.9.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 添加 biz 模块修改树形盒子组件监听事件
|
||||||
|
|
||||||
|
## 0.9.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增监听点击事件自定义
|
||||||
|
|
||||||
|
## 0.9.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增 BoxSelectTree 监听时钟点击事件,导入盒子事件
|
||||||
|
|
||||||
## 0.9.1
|
## 0.9.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
8
packages/biz/es/index.d.ts
vendored
8
packages/biz/es/index.d.ts
vendored
@ -1,8 +1,12 @@
|
|||||||
export { default as BigImageModal } from './BigImageModal';
|
export { default as BigImageModal } from './BigImageModal';
|
||||||
|
export type { BigImageModalProps } from './BigImageModal';
|
||||||
export { default as BoxSelectTree } from './boxSelectTree';
|
export { default as BoxSelectTree } from './boxSelectTree';
|
||||||
|
export type { BoxSelectTreeProps } from './boxSelectTree';
|
||||||
export { default as Tree } from './tree';
|
export { default as Tree } from './tree';
|
||||||
export type { TreeData } from './tree';
|
export type { BoxTreeProps, TreeData } from './tree';
|
||||||
export { default as TreeTransfer } from './treeTransfer';
|
export { default as TreeTransfer } from './treeTransfer';
|
||||||
|
export type { TreeTransferProps } from './treeTransfer';
|
||||||
export { default as TreeTransferModal } from './treeTransferModal';
|
export { default as TreeTransferModal } from './treeTransferModal';
|
||||||
|
export type { TreeTransferModalProps } from './treeTransferModal';
|
||||||
export { default as WarningRecordCard } from './WarningRecordCard';
|
export { default as WarningRecordCard } from './WarningRecordCard';
|
||||||
export type { IRecord, WarningRecordCardProps } from './WarningRecordCard';
|
export type { WarningRecordCardProps, IRecord } from './WarningRecordCard';
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
||||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
||||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
||||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
||||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
||||||
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { throttle as loadshThrottle, noop } from '@zhst/func';
|
|
||||||
import { useDeepEffect, useLatest } from '@zhst/hooks';
|
|
||||||
import ws from "./ws";
|
|
||||||
var getSelf = function getSelf(v) {
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
export var SocketApi = {
|
|
||||||
CameraTaskStatue: 'singer.DeviceService/SubScribeCameraTaskStatus',
|
|
||||||
DeviceStatus: 'singer.TaskManagerService/SubscribeTaskStatus',
|
|
||||||
SubscribeSolutionDeploy: 'singer.SolutionManagerService/SubscribeSolutionDeploy',
|
|
||||||
SubscribeTasksSummary: 'singer.TaskManagerService/SubscribeTasksSummary',
|
|
||||||
MonitorSubscribeResult: 'singer.MonitorService/MonitorSubscribeResult',
|
|
||||||
MonitorSubscribeStatus: 'singer.MonitorService/MonitorSubscribeStatus',
|
|
||||||
SubscribeArchiveGroupUpload: 'singer.ArchiveGroupService/CreateArchiveByImport',
|
|
||||||
SubscribeJointTask: 'singer.JointTaskService/SubscribeJointTask',
|
|
||||||
SubscribeGroupFragment: 'singer.VideoService/SubscribeVideoFragmentStatus',
|
|
||||||
// 监听视频分片状态变化,包括新建、删除、变化
|
|
||||||
SubscribeGroup: 'singer.VideoService/SubscribeGroup',
|
|
||||||
// 监听视频分组状态变化,列表变化也通知
|
|
||||||
SubscribeStreamEvent: 'singer.MediaManagerService/SubscribeStreamEvent' // 监听视频分组状态变化,列表变化也通知
|
|
||||||
};
|
|
||||||
export default (function (topic) {
|
|
||||||
var iterator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
|
|
||||||
var opt = arguments.length > 2 ? arguments[2] : undefined;
|
|
||||||
var _ref = opt || {},
|
|
||||||
_ref$req = _ref.req,
|
|
||||||
req = _ref$req === void 0 ? {} : _ref$req,
|
|
||||||
_ref$throttle = _ref.throttle,
|
|
||||||
throttle = _ref$throttle === void 0 ? 0 : _ref$throttle,
|
|
||||||
_ref$beforeLoopTmp = _ref.beforeLoopTmp,
|
|
||||||
beforeLoopTmp = _ref$beforeLoopTmp === void 0 ? getSelf : _ref$beforeLoopTmp,
|
|
||||||
_ref$shouldBreak = _ref.shouldBreak,
|
|
||||||
shouldBreak = _ref$shouldBreak === void 0 ? false : _ref$shouldBreak,
|
|
||||||
forceRefresh = _ref.forceRefresh,
|
|
||||||
close = _ref.close;
|
|
||||||
|
|
||||||
// 带上token
|
|
||||||
var reqstring = useMemo(function () {
|
|
||||||
var newReq = _objectSpread(_objectSpread({}, req), {}, {
|
|
||||||
extraHeaders: {
|
|
||||||
authorization: localStorage.getItem('USER-TOKEN')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return JSON.stringify(newReq);
|
|
||||||
}, [req]);
|
|
||||||
var latestIterator = useLatest(iterator);
|
|
||||||
useDeepEffect(function () {
|
|
||||||
if (close) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//控制socket 请求发送
|
|
||||||
if (shouldBreak) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//去抖动
|
|
||||||
|
|
||||||
var tmpData = [];
|
|
||||||
var throttleUpdate = loadshThrottle(function () {
|
|
||||||
if (tmpData.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var _tmpData = beforeLoopTmp(tmpData);
|
|
||||||
latestIterator.current(_tmpData); //加了throttle 数据就变成数组
|
|
||||||
tmpData = [];
|
|
||||||
}, throttle);
|
|
||||||
var unSubscribe = ws.subscribe(SocketApi[topic], reqstring, function (socketData) {
|
|
||||||
try {
|
|
||||||
if (!throttle) {
|
|
||||||
latestIterator.current(socketData);
|
|
||||||
} else {
|
|
||||||
tmpData.push(socketData);
|
|
||||||
throttleUpdate();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('useSocke:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return function () {
|
|
||||||
try {
|
|
||||||
unSubscribe();
|
|
||||||
throttleUpdate.cancel();
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [topic, reqstring, shouldBreak, forceRefresh, close]);
|
|
||||||
});
|
|
2
packages/biz/es/useSocket/onceChannel.d.ts
vendored
2
packages/biz/es/useSocket/onceChannel.d.ts
vendored
@ -1,2 +0,0 @@
|
|||||||
declare const startChannel: (topic: any, req: any, callback: any) => () => void;
|
|
||||||
export default startChannel;
|
|
@ -1,24 +0,0 @@
|
|||||||
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
||||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
||||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
||||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
||||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
||||||
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
||||||
//@ts-nocheck
|
|
||||||
import channel from "./ws";
|
|
||||||
var startChannel = function startChannel(topic, req, callback) {
|
|
||||||
// 带上token
|
|
||||||
var reqstring = JSON.stringify(_objectSpread(_objectSpread({}, req), {}, {
|
|
||||||
extraHeaders: {
|
|
||||||
authorization: localStorage.getItem('USER-TOKEN')
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
var unSubscribe = channel.subscribe(topic, reqstring, function (socketData) {
|
|
||||||
var shouldStop = callback(socketData);
|
|
||||||
if (shouldStop) {
|
|
||||||
unSubscribe === null || unSubscribe === void 0 || unSubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return unSubscribe;
|
|
||||||
};
|
|
||||||
export default startChannel;
|
|
@ -1,244 +0,0 @@
|
|||||||
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
||||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
||||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
||||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
||||||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
||||||
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
||||||
// @ts-nocheck
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import { has } from '@zhst/func';
|
|
||||||
import io from 'socket.io-client';
|
|
||||||
import { SOCKET_HOST } from '@common/constants';
|
|
||||||
var EMITSTATE = {
|
|
||||||
NOT_CONNECT: 0,
|
|
||||||
WAITING: 1,
|
|
||||||
CONNECT: 2
|
|
||||||
};
|
|
||||||
var initRetryTime = 0;
|
|
||||||
var intervalTime = 5 * 1000; //下次重试增加时间
|
|
||||||
var maxIntervalTime = 1 * 60 * 60 * 1000; //最大重试时间1小时
|
|
||||||
var Channel = /*#__PURE__*/function () {
|
|
||||||
function Channel() {
|
|
||||||
var _this = this;
|
|
||||||
_classCallCheck(this, Channel);
|
|
||||||
/**
|
|
||||||
* io 实例化对象
|
|
||||||
*/
|
|
||||||
_defineProperty(this, "ioIns", void 0);
|
|
||||||
/**
|
|
||||||
* 已存在的订阅列表
|
|
||||||
*/
|
|
||||||
_defineProperty(this, "listeners", [
|
|
||||||
// {
|
|
||||||
// topic: "",
|
|
||||||
// req: "",
|
|
||||||
// suInfo: {},
|
|
||||||
// hasEmit: false,//是否已经订阅
|
|
||||||
// lastRetryInterval: 0,
|
|
||||||
// handles: {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
]);
|
|
||||||
/**
|
|
||||||
* 调试信息 记录订阅/反订阅次数
|
|
||||||
*/
|
|
||||||
_defineProperty(this, "subscribeListenerId", []);
|
|
||||||
_defineProperty(this, "unSubscribeListenerId", []);
|
|
||||||
_defineProperty(this, "init", function () {
|
|
||||||
var ioIns = _this.ioIns = io(SOCKET_HOST, {
|
|
||||||
reconnection: true,
|
|
||||||
transports: ['websocket'],
|
|
||||||
forceNew: true
|
|
||||||
});
|
|
||||||
ioIns.on('connect', function () {
|
|
||||||
for (var _len = arguments.length, arg = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
||||||
arg[_key] = arguments[_key];
|
|
||||||
}
|
|
||||||
console.debug('connect', arg);
|
|
||||||
_this.ioIns = ioIns;
|
|
||||||
_this.listeners.forEach(function (v) {
|
|
||||||
_this.doEmit(v['topic'], v['req'], v['id']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ioIns.on('event', function () {
|
|
||||||
for (var _len2 = arguments.length, arg = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
||||||
arg[_key2] = arguments[_key2];
|
|
||||||
}
|
|
||||||
console.debug('event', arg);
|
|
||||||
});
|
|
||||||
ioIns.on('disconnect', function () {
|
|
||||||
for (var _len3 = arguments.length, arg = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
||||||
arg[_key3] = arguments[_key3];
|
|
||||||
}
|
|
||||||
console.debug('disconnect', arg);
|
|
||||||
_this.subscribeListenerId = [];
|
|
||||||
_this.unSubscribeListenerId = [];
|
|
||||||
});
|
|
||||||
ioIns.on('reconnect', function () {
|
|
||||||
for (var _len4 = arguments.length, arg = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
||||||
arg[_key4] = arguments[_key4];
|
|
||||||
}
|
|
||||||
console.debug('reconnect', arg);
|
|
||||||
_this.listeners.forEach(function (v) {
|
|
||||||
v['hasEmit'] = EMITSTATE.NOT_CONNECT;
|
|
||||||
_this.doEmit(v['topic'], v['req'], v['id']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
_defineProperty(this, "retry", function (listener) {
|
|
||||||
//重试逻辑
|
|
||||||
var intervalId = setTimeout(function () {
|
|
||||||
var hasExit = _this.listeners.find(function (v) {
|
|
||||||
return v['topic'] === (listener === null || listener === void 0 ? void 0 : listener['topic']) && v['req'] === listener['req'];
|
|
||||||
});
|
|
||||||
if (!hasExit) return;
|
|
||||||
listener['hasEmit'] = EMITSTATE.NOT_CONNECT;
|
|
||||||
_this.doEmit(listener['topic'], listener['req'], listener['id']);
|
|
||||||
}, listener.lastRetryInterval);
|
|
||||||
listener.intervalId = intervalId;
|
|
||||||
listener.lastRetryInterval = intervalTime + listener.lastRetryInterval > maxIntervalTime ? maxIntervalTime : intervalTime + listener.lastRetryInterval;
|
|
||||||
});
|
|
||||||
_defineProperty(this, "doEmit", function (topic, req, listenerId) {
|
|
||||||
var _this$ioIns, _this$ioIns$emit;
|
|
||||||
if (!_this.ioIns) {
|
|
||||||
_this.init();
|
|
||||||
}
|
|
||||||
//订阅过就不订阅了
|
|
||||||
var hasEmit = _this.listeners.find(function (v) {
|
|
||||||
return v['topic'] === topic && v['req'] === req && v['hasEmit'] !== EMITSTATE.NOT_CONNECT;
|
|
||||||
});
|
|
||||||
if (hasEmit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var listener = _this.listeners.find(function (v) {
|
|
||||||
return v['topic'] === topic && v['req'] === req;
|
|
||||||
});
|
|
||||||
listener['hasEmit'] = EMITSTATE.WAITING;
|
|
||||||
(_this$ioIns = _this.ioIns) === null || _this$ioIns === void 0 || (_this$ioIns$emit = _this$ioIns.emit) === null || _this$ioIns$emit === void 0 || _this$ioIns$emit.call(_this$ioIns, topic, req, function (data) {
|
|
||||||
var _this$ioIns2, _this$ioIns2$on;
|
|
||||||
console.info('emit', topic, req, data);
|
|
||||||
var suInfo = JSON.parse(data);
|
|
||||||
if (has(suInfo, 'Error.code')) {
|
|
||||||
if (suInfo.Error.code === 500) {
|
|
||||||
//后端出错
|
|
||||||
_this.retry(listener);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.debug('SUBSCRIBE', listenerId, topic, req, suInfo);
|
|
||||||
_this.subscribeListenerId.push(listenerId);
|
|
||||||
// debugger
|
|
||||||
//重新找一遍topic
|
|
||||||
var currentTopicIndex = _this.listeners.findIndex(function (v) {
|
|
||||||
return v['topic'] === topic && v['req'] === req && v['id'] === listenerId;
|
|
||||||
});
|
|
||||||
if (currentTopicIndex == -1) {
|
|
||||||
// 不存在说明listener取消了 直接反订阅
|
|
||||||
_this.ioIns.emit('UnSubscribe', JSON.stringify(suInfo), function (data) {
|
|
||||||
_this.unSubscribeListenerId.push(listenerId);
|
|
||||||
console.debug('UNSUBSCRIBE', listenerId, topic, req, data);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!suInfo['SubscribeID']) {
|
|
||||||
_this.listeners.splice(currentTopicIndex, 0);
|
|
||||||
} else {
|
|
||||||
_this.listeners[currentTopicIndex]['suInfo'] = suInfo;
|
|
||||||
_this.listeners[currentTopicIndex]['hasEmit'] = EMITSTATE.CONNECT;
|
|
||||||
}
|
|
||||||
(_this$ioIns2 = _this.ioIns) === null || _this$ioIns2 === void 0 || (_this$ioIns2$on = _this$ioIns2.on) === null || _this$ioIns2$on === void 0 || _this$ioIns2$on.call(_this$ioIns2, suInfo['SubscribeID'], function (data) {
|
|
||||||
console.info('on', suInfo['SubscribeID'], data);
|
|
||||||
try {
|
|
||||||
var socketData = JSON.parse(data);
|
|
||||||
if (has(socketData, 'Error.code')) {
|
|
||||||
if (socketData.Error.code === 500) {
|
|
||||||
//后端出错
|
|
||||||
_this.retry(listener);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var _ref = _this.listeners.find(function (v) {
|
|
||||||
return v['topic'] === topic && v['req'] === req;
|
|
||||||
}) || {},
|
|
||||||
_ref$handles = _ref.handles,
|
|
||||||
handles = _ref$handles === void 0 ? {} : _ref$handles;
|
|
||||||
Object.keys(handles).forEach(function (key) {
|
|
||||||
try {
|
|
||||||
//后面观察 为什么delete后在foreach
|
|
||||||
var func = handles[key];
|
|
||||||
if (!func) return;
|
|
||||||
func(socketData);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.debug('error', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_createClass(Channel, [{
|
|
||||||
key: "subscribe",
|
|
||||||
value: function subscribe(topic, req, handle) {
|
|
||||||
var handleId = uuidv4();
|
|
||||||
var listenerId = uuidv4();
|
|
||||||
var listener = this.listeners.find(function (v) {
|
|
||||||
return v['topic'] === topic && v['req'] === req;
|
|
||||||
});
|
|
||||||
if (listener) {
|
|
||||||
listener['handles'][handleId] = handle;
|
|
||||||
} else {
|
|
||||||
this.listeners.push({
|
|
||||||
topic: topic,
|
|
||||||
req: req,
|
|
||||||
suInfo: {},
|
|
||||||
id: listenerId,
|
|
||||||
hasEmit: EMITSTATE.NOT_CONNECT,
|
|
||||||
lastRetryInterval: initRetryTime,
|
|
||||||
handles: _defineProperty({}, "".concat(handleId), handle)
|
|
||||||
});
|
|
||||||
//未注册过 则去订阅
|
|
||||||
this.doEmit(topic, req, listenerId);
|
|
||||||
}
|
|
||||||
return this.unSubscribe.bind(this, topic, req, handleId, listenerId);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: "unSubscribe",
|
|
||||||
value: function unSubscribe(topic, req, handleId, listenerId) {
|
|
||||||
var _this2 = this;
|
|
||||||
var listener = this.listeners.find(function (v) {
|
|
||||||
return v['topic'] === topic && v['req'] === req && v['id'] === listenerId;
|
|
||||||
});
|
|
||||||
var _ref2 = listener || {},
|
|
||||||
_ref2$handles = _ref2.handles,
|
|
||||||
handles = _ref2$handles === void 0 ? {} : _ref2$handles,
|
|
||||||
suInfo = _ref2.suInfo;
|
|
||||||
if (handles[handleId]) {
|
|
||||||
delete handles[handleId];
|
|
||||||
//如果没有其他订阅就删除
|
|
||||||
if (Object.keys(handles).length === 0) {
|
|
||||||
if (this.intervalId) {
|
|
||||||
clearTimeout(this.intervalId);
|
|
||||||
}
|
|
||||||
if (listener['hasEmit'] === EMITSTATE['CONNECT']) {
|
|
||||||
this.ioIns.emit('UnSubscribe', JSON.stringify(suInfo), function (data) {
|
|
||||||
_this2.unSubscribeListenerId.push(listenerId);
|
|
||||||
console.debug('UNSUBSCRIBE', listener['id'], topic, req, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.listeners = this.listeners.filter(function (v) {
|
|
||||||
return !(v['topic'] === topic && v['req'] === req);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
return Channel;
|
|
||||||
}(); //单例
|
|
||||||
var channelIns = new Channel();
|
|
||||||
//暴露实例 调试用
|
|
||||||
window.__channel__ = channelIns;
|
|
||||||
export default channelIns;
|
|
31
packages/biz/es/utils/constants.d.ts
vendored
31
packages/biz/es/utils/constants.d.ts
vendored
@ -1,31 +0,0 @@
|
|||||||
export declare const OBJECT_GRNER_THRESHOLD = 0.8;
|
|
||||||
export declare const OBJECT_AGE_TYPE_THRESHOLD = 0.5;
|
|
||||||
export declare const MODE_KEY = "test_mode";
|
|
||||||
export declare const SEARCH_IMG_COUNT = 10;
|
|
||||||
export declare const GLOBAL_IS_ITEM_NUMBER_SHOW = false;
|
|
||||||
export declare const publicPath = "hummingbird";
|
|
||||||
export declare const ENTER_CIRCLE = "MONITORTYPE_ENTER_CIRCLE";
|
|
||||||
export declare const OUT_CIRCLE = "MONITORTYPE_OUT_CIRCLE";
|
|
||||||
export declare const TEMP = "MONITORTYPE_TEMP";
|
|
||||||
export declare const GLOBAL_IS_BOX_VMS_SHOW = true;
|
|
||||||
export declare const BODY_SEARCH_THRESHOID = 0.45;
|
|
||||||
export declare const RECORD_VERSION = "3.0.0";
|
|
||||||
export declare const DeviceTab: {
|
|
||||||
EMPTY: number;
|
|
||||||
REAL_CAMERA: number;
|
|
||||||
PREPROCESS_CAMERA: number;
|
|
||||||
TAG_CAMERA: number;
|
|
||||||
HISTORY_VIDEO_GROUP: number;
|
|
||||||
VIRTUAL_CAMERA: number;
|
|
||||||
REAL_CAMERA_NOFACE: number;
|
|
||||||
REAL_CAMERA_ONLYFACE: number;
|
|
||||||
REAL_CAMERA_NOFACE_NOBOX_NODIRECONNECT: number;
|
|
||||||
};
|
|
||||||
export declare const BOX_TYPE_LIST: {
|
|
||||||
value: string;
|
|
||||||
label: string;
|
|
||||||
}[];
|
|
||||||
export declare const ALL_LIST: {
|
|
||||||
value: string;
|
|
||||||
label: string;
|
|
||||||
}[];
|
|
8
packages/biz/lib/index.d.ts
vendored
8
packages/biz/lib/index.d.ts
vendored
@ -1,8 +1,12 @@
|
|||||||
export { default as BigImageModal } from './BigImageModal';
|
export { default as BigImageModal } from './BigImageModal';
|
||||||
|
export type { BigImageModalProps } from './BigImageModal';
|
||||||
export { default as BoxSelectTree } from './boxSelectTree';
|
export { default as BoxSelectTree } from './boxSelectTree';
|
||||||
|
export type { BoxSelectTreeProps } from './boxSelectTree';
|
||||||
export { default as Tree } from './tree';
|
export { default as Tree } from './tree';
|
||||||
export type { TreeData } from './tree';
|
export type { BoxTreeProps, TreeData } from './tree';
|
||||||
export { default as TreeTransfer } from './treeTransfer';
|
export { default as TreeTransfer } from './treeTransfer';
|
||||||
|
export type { TreeTransferProps } from './treeTransfer';
|
||||||
export { default as TreeTransferModal } from './treeTransferModal';
|
export { default as TreeTransferModal } from './treeTransferModal';
|
||||||
|
export type { TreeTransferModalProps } from './treeTransferModal';
|
||||||
export { default as WarningRecordCard } from './WarningRecordCard';
|
export { default as WarningRecordCard } from './WarningRecordCard';
|
||||||
export type { IRecord, WarningRecordCardProps } from './WarningRecordCard';
|
export type { WarningRecordCardProps, IRecord } from './WarningRecordCard';
|
||||||
|
@ -1,118 +0,0 @@
|
|||||||
var __create = Object.create;
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __getProtoOf = Object.getPrototypeOf;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
||||||
// If the importer is in node compatibility mode or this is not an ESM
|
|
||||||
// file that has been converted to a CommonJS file using a Babel-
|
|
||||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
||||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
||||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
||||||
mod
|
|
||||||
));
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
|
|
||||||
// src/useSocket/index.ts
|
|
||||||
var useSocket_exports = {};
|
|
||||||
__export(useSocket_exports, {
|
|
||||||
SocketApi: () => SocketApi,
|
|
||||||
default: () => useSocket_default
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(useSocket_exports);
|
|
||||||
var import_react = require("react");
|
|
||||||
var import_func = require("@zhst/func");
|
|
||||||
var import_hooks = require("@zhst/hooks");
|
|
||||||
var import_ws = __toESM(require("./ws"));
|
|
||||||
var getSelf = (v) => v;
|
|
||||||
var SocketApi = {
|
|
||||||
CameraTaskStatue: "singer.DeviceService/SubScribeCameraTaskStatus",
|
|
||||||
DeviceStatus: "singer.TaskManagerService/SubscribeTaskStatus",
|
|
||||||
SubscribeSolutionDeploy: "singer.SolutionManagerService/SubscribeSolutionDeploy",
|
|
||||||
SubscribeTasksSummary: "singer.TaskManagerService/SubscribeTasksSummary",
|
|
||||||
MonitorSubscribeResult: "singer.MonitorService/MonitorSubscribeResult",
|
|
||||||
MonitorSubscribeStatus: "singer.MonitorService/MonitorSubscribeStatus",
|
|
||||||
SubscribeArchiveGroupUpload: "singer.ArchiveGroupService/CreateArchiveByImport",
|
|
||||||
SubscribeJointTask: "singer.JointTaskService/SubscribeJointTask",
|
|
||||||
SubscribeGroupFragment: "singer.VideoService/SubscribeVideoFragmentStatus",
|
|
||||||
// 监听视频分片状态变化,包括新建、删除、变化
|
|
||||||
SubscribeGroup: "singer.VideoService/SubscribeGroup",
|
|
||||||
// 监听视频分组状态变化,列表变化也通知
|
|
||||||
SubscribeStreamEvent: "singer.MediaManagerService/SubscribeStreamEvent"
|
|
||||||
// 监听视频分组状态变化,列表变化也通知
|
|
||||||
};
|
|
||||||
var useSocket_default = (topic, iterator = import_func.noop, opt) => {
|
|
||||||
const {
|
|
||||||
req = {},
|
|
||||||
throttle = 0,
|
|
||||||
beforeLoopTmp = getSelf,
|
|
||||||
shouldBreak = false,
|
|
||||||
forceRefresh,
|
|
||||||
close
|
|
||||||
} = opt || {};
|
|
||||||
const reqstring = (0, import_react.useMemo)(() => {
|
|
||||||
const newReq = {
|
|
||||||
...req,
|
|
||||||
extraHeaders: {
|
|
||||||
authorization: localStorage.getItem("USER-TOKEN")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return JSON.stringify(newReq);
|
|
||||||
}, [req]);
|
|
||||||
const latestIterator = (0, import_hooks.useLatest)(iterator);
|
|
||||||
(0, import_hooks.useDeepEffect)(() => {
|
|
||||||
if (close) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (shouldBreak) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let tmpData = [];
|
|
||||||
const throttleUpdate = (0, import_func.throttle)(() => {
|
|
||||||
if (tmpData.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const _tmpData = beforeLoopTmp(tmpData);
|
|
||||||
latestIterator.current(_tmpData);
|
|
||||||
tmpData = [];
|
|
||||||
}, throttle);
|
|
||||||
const unSubscribe = import_ws.default.subscribe(SocketApi[topic], reqstring, (socketData) => {
|
|
||||||
try {
|
|
||||||
if (!throttle) {
|
|
||||||
latestIterator.current(socketData);
|
|
||||||
} else {
|
|
||||||
tmpData.push(socketData);
|
|
||||||
throttleUpdate();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("useSocke:", error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return () => {
|
|
||||||
try {
|
|
||||||
unSubscribe();
|
|
||||||
throttleUpdate.cancel();
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [topic, reqstring, shouldBreak, forceRefresh, close]);
|
|
||||||
};
|
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
|
||||||
0 && (module.exports = {
|
|
||||||
SocketApi
|
|
||||||
});
|
|
2
packages/biz/lib/useSocket/onceChannel.d.ts
vendored
2
packages/biz/lib/useSocket/onceChannel.d.ts
vendored
@ -1,2 +0,0 @@
|
|||||||
declare const startChannel: (topic: any, req: any, callback: any) => () => void;
|
|
||||||
export default startChannel;
|
|
@ -1,51 +0,0 @@
|
|||||||
var __create = Object.create;
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __getProtoOf = Object.getPrototypeOf;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
||||||
// If the importer is in node compatibility mode or this is not an ESM
|
|
||||||
// file that has been converted to a CommonJS file using a Babel-
|
|
||||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
||||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
||||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
||||||
mod
|
|
||||||
));
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
|
|
||||||
// src/useSocket/onceChannel.tsx
|
|
||||||
var onceChannel_exports = {};
|
|
||||||
__export(onceChannel_exports, {
|
|
||||||
default: () => onceChannel_default
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(onceChannel_exports);
|
|
||||||
var import_ws = __toESM(require("./ws"));
|
|
||||||
var startChannel = (topic, req, callback) => {
|
|
||||||
let reqstring = JSON.stringify({
|
|
||||||
...req,
|
|
||||||
extraHeaders: {
|
|
||||||
authorization: localStorage.getItem("USER-TOKEN")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let unSubscribe = import_ws.default.subscribe(topic, reqstring, (socketData) => {
|
|
||||||
let shouldStop = callback(socketData);
|
|
||||||
if (shouldStop) {
|
|
||||||
unSubscribe == null ? void 0 : unSubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return unSubscribe;
|
|
||||||
};
|
|
||||||
var onceChannel_default = startChannel;
|
|
@ -1,224 +0,0 @@
|
|||||||
var __create = Object.create;
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __getProtoOf = Object.getPrototypeOf;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
||||||
// If the importer is in node compatibility mode or this is not an ESM
|
|
||||||
// file that has been converted to a CommonJS file using a Babel-
|
|
||||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
||||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
||||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
||||||
mod
|
|
||||||
));
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
|
|
||||||
// src/useSocket/ws.ts
|
|
||||||
var ws_exports = {};
|
|
||||||
__export(ws_exports, {
|
|
||||||
default: () => ws_default
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(ws_exports);
|
|
||||||
var import_uuid = require("uuid");
|
|
||||||
var import_func = require("@zhst/func");
|
|
||||||
var import_socket = __toESM(require("socket.io-client"));
|
|
||||||
var import_constants = require("@common/constants");
|
|
||||||
var EMITSTATE = {
|
|
||||||
NOT_CONNECT: 0,
|
|
||||||
WAITING: 1,
|
|
||||||
CONNECT: 2
|
|
||||||
};
|
|
||||||
var initRetryTime = 0;
|
|
||||||
var intervalTime = 5 * 1e3;
|
|
||||||
var maxIntervalTime = 1 * 60 * 60 * 1e3;
|
|
||||||
var Channel = class {
|
|
||||||
constructor() {
|
|
||||||
/**
|
|
||||||
* 已存在的订阅列表
|
|
||||||
*/
|
|
||||||
this.listeners = [
|
|
||||||
// {
|
|
||||||
// topic: "",
|
|
||||||
// req: "",
|
|
||||||
// suInfo: {},
|
|
||||||
// hasEmit: false,//是否已经订阅
|
|
||||||
// lastRetryInterval: 0,
|
|
||||||
// handles: {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* 调试信息 记录订阅/反订阅次数
|
|
||||||
*/
|
|
||||||
this.subscribeListenerId = [];
|
|
||||||
this.unSubscribeListenerId = [];
|
|
||||||
this.init = () => {
|
|
||||||
const ioIns = this.ioIns = (0, import_socket.default)(import_constants.SOCKET_HOST, {
|
|
||||||
reconnection: true,
|
|
||||||
transports: ["websocket"],
|
|
||||||
forceNew: true
|
|
||||||
});
|
|
||||||
ioIns.on("connect", (...arg) => {
|
|
||||||
console.debug("connect", arg);
|
|
||||||
this.ioIns = ioIns;
|
|
||||||
this.listeners.forEach((v) => {
|
|
||||||
this.doEmit(v["topic"], v["req"], v["id"]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ioIns.on("event", (...arg) => {
|
|
||||||
console.debug("event", arg);
|
|
||||||
});
|
|
||||||
ioIns.on("disconnect", (...arg) => {
|
|
||||||
console.debug("disconnect", arg);
|
|
||||||
this.subscribeListenerId = [];
|
|
||||||
this.unSubscribeListenerId = [];
|
|
||||||
});
|
|
||||||
ioIns.on("reconnect", (...arg) => {
|
|
||||||
console.debug("reconnect", arg);
|
|
||||||
this.listeners.forEach((v) => {
|
|
||||||
v["hasEmit"] = EMITSTATE.NOT_CONNECT;
|
|
||||||
this.doEmit(v["topic"], v["req"], v["id"]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
this.retry = (listener) => {
|
|
||||||
const intervalId = setTimeout(() => {
|
|
||||||
const hasExit = this.listeners.find(
|
|
||||||
(v) => v["topic"] === (listener == null ? void 0 : listener["topic"]) && v["req"] === listener["req"]
|
|
||||||
);
|
|
||||||
if (!hasExit)
|
|
||||||
return;
|
|
||||||
listener["hasEmit"] = EMITSTATE.NOT_CONNECT;
|
|
||||||
this.doEmit(listener["topic"], listener["req"], listener["id"]);
|
|
||||||
}, listener.lastRetryInterval);
|
|
||||||
listener.intervalId = intervalId;
|
|
||||||
listener.lastRetryInterval = intervalTime + listener.lastRetryInterval > maxIntervalTime ? maxIntervalTime : intervalTime + listener.lastRetryInterval;
|
|
||||||
};
|
|
||||||
this.doEmit = (topic, req, listenerId) => {
|
|
||||||
var _a, _b;
|
|
||||||
if (!this.ioIns) {
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
const hasEmit = this.listeners.find(
|
|
||||||
(v) => v["topic"] === topic && v["req"] === req && v["hasEmit"] !== EMITSTATE.NOT_CONNECT
|
|
||||||
);
|
|
||||||
if (hasEmit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const listener = this.listeners.find((v) => v["topic"] === topic && v["req"] === req);
|
|
||||||
listener["hasEmit"] = EMITSTATE.WAITING;
|
|
||||||
(_b = (_a = this.ioIns) == null ? void 0 : _a.emit) == null ? void 0 : _b.call(_a, topic, req, (data) => {
|
|
||||||
var _a2, _b2;
|
|
||||||
console.info("emit", topic, req, data);
|
|
||||||
const suInfo = JSON.parse(data);
|
|
||||||
if ((0, import_func.has)(suInfo, "Error.code")) {
|
|
||||||
if (suInfo.Error.code === 500) {
|
|
||||||
this.retry(listener);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.subscribeListenerId.push(listenerId);
|
|
||||||
const currentTopicIndex = this.listeners.findIndex(
|
|
||||||
(v) => v["topic"] === topic && v["req"] === req && v["id"] === listenerId
|
|
||||||
);
|
|
||||||
if (currentTopicIndex == -1) {
|
|
||||||
this.ioIns.emit("UnSubscribe", JSON.stringify(suInfo), (data2) => {
|
|
||||||
this.unSubscribeListenerId.push(listenerId);
|
|
||||||
console.debug("UNSUBSCRIBE", listenerId, topic, req, data2);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!suInfo["SubscribeID"]) {
|
|
||||||
this.listeners.splice(currentTopicIndex, 0);
|
|
||||||
} else {
|
|
||||||
this.listeners[currentTopicIndex]["suInfo"] = suInfo;
|
|
||||||
this.listeners[currentTopicIndex]["hasEmit"] = EMITSTATE.CONNECT;
|
|
||||||
}
|
|
||||||
(_b2 = (_a2 = this.ioIns) == null ? void 0 : _a2.on) == null ? void 0 : _b2.call(_a2, suInfo["SubscribeID"], (data2) => {
|
|
||||||
console.info("on", suInfo["SubscribeID"], data2);
|
|
||||||
try {
|
|
||||||
const socketData = JSON.parse(data2);
|
|
||||||
if ((0, import_func.has)(socketData, "Error.code")) {
|
|
||||||
if (socketData.Error.code === 500) {
|
|
||||||
this.retry(listener);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { handles = {} } = this.listeners.find((v) => v["topic"] === topic && v["req"] === req) || {};
|
|
||||||
Object.keys(handles).forEach((key) => {
|
|
||||||
try {
|
|
||||||
const func = handles[key];
|
|
||||||
if (!func)
|
|
||||||
return;
|
|
||||||
func(socketData);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.debug("error", error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
subscribe(topic, req, handle) {
|
|
||||||
const handleId = (0, import_uuid.v4)();
|
|
||||||
const listenerId = (0, import_uuid.v4)();
|
|
||||||
const listener = this.listeners.find((v) => v["topic"] === topic && v["req"] === req);
|
|
||||||
if (listener) {
|
|
||||||
listener["handles"][handleId] = handle;
|
|
||||||
} else {
|
|
||||||
this.listeners.push({
|
|
||||||
topic,
|
|
||||||
req,
|
|
||||||
suInfo: {},
|
|
||||||
id: listenerId,
|
|
||||||
hasEmit: EMITSTATE.NOT_CONNECT,
|
|
||||||
lastRetryInterval: initRetryTime,
|
|
||||||
handles: {
|
|
||||||
[`${handleId}`]: handle
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.doEmit(topic, req, listenerId);
|
|
||||||
}
|
|
||||||
return this.unSubscribe.bind(this, topic, req, handleId, listenerId);
|
|
||||||
}
|
|
||||||
unSubscribe(topic, req, handleId, listenerId) {
|
|
||||||
const listener = this.listeners.find(
|
|
||||||
(v) => v["topic"] === topic && v["req"] === req && v["id"] === listenerId
|
|
||||||
);
|
|
||||||
const { handles = {}, suInfo } = listener || {};
|
|
||||||
if (handles[handleId]) {
|
|
||||||
delete handles[handleId];
|
|
||||||
if (Object.keys(handles).length === 0) {
|
|
||||||
if (this.intervalId) {
|
|
||||||
clearTimeout(this.intervalId);
|
|
||||||
}
|
|
||||||
if (listener["hasEmit"] === EMITSTATE["CONNECT"]) {
|
|
||||||
this.ioIns.emit("UnSubscribe", JSON.stringify(suInfo), (data) => {
|
|
||||||
this.unSubscribeListenerId.push(listenerId);
|
|
||||||
console.debug("UNSUBSCRIBE", listener["id"], topic, req, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.listeners = this.listeners.filter((v) => !(v["topic"] === topic && v["req"] === req));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var channelIns = new Channel();
|
|
||||||
window.__channel__ = channelIns;
|
|
||||||
var ws_default = channelIns;
|
|
31
packages/biz/lib/utils/constants.d.ts
vendored
31
packages/biz/lib/utils/constants.d.ts
vendored
@ -1,31 +0,0 @@
|
|||||||
export declare const OBJECT_GRNER_THRESHOLD = 0.8;
|
|
||||||
export declare const OBJECT_AGE_TYPE_THRESHOLD = 0.5;
|
|
||||||
export declare const MODE_KEY = "test_mode";
|
|
||||||
export declare const SEARCH_IMG_COUNT = 10;
|
|
||||||
export declare const GLOBAL_IS_ITEM_NUMBER_SHOW = false;
|
|
||||||
export declare const publicPath = "hummingbird";
|
|
||||||
export declare const ENTER_CIRCLE = "MONITORTYPE_ENTER_CIRCLE";
|
|
||||||
export declare const OUT_CIRCLE = "MONITORTYPE_OUT_CIRCLE";
|
|
||||||
export declare const TEMP = "MONITORTYPE_TEMP";
|
|
||||||
export declare const GLOBAL_IS_BOX_VMS_SHOW = true;
|
|
||||||
export declare const BODY_SEARCH_THRESHOID = 0.45;
|
|
||||||
export declare const RECORD_VERSION = "3.0.0";
|
|
||||||
export declare const DeviceTab: {
|
|
||||||
EMPTY: number;
|
|
||||||
REAL_CAMERA: number;
|
|
||||||
PREPROCESS_CAMERA: number;
|
|
||||||
TAG_CAMERA: number;
|
|
||||||
HISTORY_VIDEO_GROUP: number;
|
|
||||||
VIRTUAL_CAMERA: number;
|
|
||||||
REAL_CAMERA_NOFACE: number;
|
|
||||||
REAL_CAMERA_ONLYFACE: number;
|
|
||||||
REAL_CAMERA_NOFACE_NOBOX_NODIRECONNECT: number;
|
|
||||||
};
|
|
||||||
export declare const BOX_TYPE_LIST: {
|
|
||||||
value: string;
|
|
||||||
label: string;
|
|
||||||
}[];
|
|
||||||
export declare const ALL_LIST: {
|
|
||||||
value: string;
|
|
||||||
label: string;
|
|
||||||
}[];
|
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/biz",
|
"name": "@zhst/biz",
|
||||||
"version": "0.9.1",
|
"version": "0.9.6",
|
||||||
"description": "业务库",
|
"description": "业务库",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"business",
|
"business",
|
||||||
|
@ -1,24 +1,11 @@
|
|||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import { InputProps, Tabs, TabsProps, TreeDataNode, TreeProps } from 'antd'
|
import { Tabs, TabsProps } from 'antd'
|
||||||
import BoxPanel from './components/boxPanel';
|
import BoxPanel from './components/boxPanel';
|
||||||
import { ModalFormProps } from '@ant-design/pro-components';
|
import type { BoxPanelProps } from './components/boxPanel';
|
||||||
|
|
||||||
export interface BoxSelectTreeProps {
|
export interface BoxSelectTreeProps extends BoxPanelProps {
|
||||||
boxDataSource: TreeDataNode[]
|
|
||||||
data: TreeDataNode[]
|
|
||||||
onSearch?: (e: any) => void // 搜索
|
|
||||||
onItemSelect?: TreeProps['onSelect']
|
|
||||||
onItemCheck?: TreeProps['onCheck']
|
|
||||||
onTabChange?: (e: any) => void
|
onTabChange?: (e: any) => void
|
||||||
onBoxBatchDelete?: (data?: any) => void
|
|
||||||
onBoxDelete?: (data?: any) => void
|
|
||||||
onCreateSubmit?: ModalFormProps['onFinish']
|
|
||||||
tabsProps?: TabsProps
|
tabsProps?: TabsProps
|
||||||
searchInputProps?: InputProps
|
|
||||||
treeProps?: TreeProps
|
|
||||||
showOptions?: boolean
|
|
||||||
customImport?: any
|
|
||||||
extraBtns?: any
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
||||||
@ -32,18 +19,17 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
onBoxBatchDelete,
|
onBoxBatchDelete,
|
||||||
onBoxDelete,
|
onBoxDelete,
|
||||||
onCreateSubmit,
|
onCreateSubmit,
|
||||||
|
onClockClick,
|
||||||
|
onImport,
|
||||||
|
onCreate,
|
||||||
tabsProps,
|
tabsProps,
|
||||||
searchInputProps,
|
searchInputProps,
|
||||||
treeProps,
|
treeProps,
|
||||||
customImport,
|
customImport,
|
||||||
|
showOptions,
|
||||||
extraBtns,
|
extraBtns,
|
||||||
showOptions = true
|
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const onChange = (key: string) => {
|
|
||||||
onTabChange?.(key)
|
|
||||||
};
|
|
||||||
|
|
||||||
const items: TabsProps['items'] = [
|
const items: TabsProps['items'] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
@ -54,6 +40,7 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
boxDataSource={boxDataSource}
|
boxDataSource={boxDataSource}
|
||||||
treeProps={treeProps}
|
treeProps={treeProps}
|
||||||
data={data}
|
data={data}
|
||||||
|
onCreate={onCreate}
|
||||||
onCreateSubmit={onCreateSubmit}
|
onCreateSubmit={onCreateSubmit}
|
||||||
onBoxBatchDelete={onBoxBatchDelete}
|
onBoxBatchDelete={onBoxBatchDelete}
|
||||||
onBoxDelete={onBoxDelete}
|
onBoxDelete={onBoxDelete}
|
||||||
@ -63,6 +50,8 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
showOptions={showOptions}
|
showOptions={showOptions}
|
||||||
customImport={customImport}
|
customImport={customImport}
|
||||||
extraBtns={extraBtns}
|
extraBtns={extraBtns}
|
||||||
|
onClockClick={onClockClick}
|
||||||
|
onImport={onImport}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -75,6 +64,7 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
searchInputProps={searchInputProps}
|
searchInputProps={searchInputProps}
|
||||||
treeProps={treeProps}
|
treeProps={treeProps}
|
||||||
data={data}
|
data={data}
|
||||||
|
onCreate={onCreate}
|
||||||
onBoxBatchDelete={onBoxBatchDelete}
|
onBoxBatchDelete={onBoxBatchDelete}
|
||||||
onCreateSubmit={onCreateSubmit}
|
onCreateSubmit={onCreateSubmit}
|
||||||
onBoxDelete={onBoxDelete}
|
onBoxDelete={onBoxDelete}
|
||||||
@ -84,6 +74,8 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
showOptions={showOptions}
|
showOptions={showOptions}
|
||||||
customImport={customImport}
|
customImport={customImport}
|
||||||
extraBtns={extraBtns}
|
extraBtns={extraBtns}
|
||||||
|
onClockClick={onClockClick}
|
||||||
|
onImport={onImport}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -94,7 +86,7 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
defaultActiveKey="1"
|
defaultActiveKey="1"
|
||||||
centered
|
centered
|
||||||
items={items}
|
items={items}
|
||||||
onChange={onChange}
|
onChange={onTabChange}
|
||||||
tabBarGutter={0}
|
tabBarGutter={0}
|
||||||
indicator={{ size: (origin) => origin, align: 'center' }}
|
indicator={{ size: (origin) => origin, align: 'center' }}
|
||||||
{...tabsProps}
|
{...tabsProps}
|
||||||
|
@ -3,13 +3,14 @@ import{ Button, Divider, Input, Space, TreeDataNode } from 'antd'
|
|||||||
import { ModalForm, ModalFormProps, ProFormInstance, ProFormText } from '@ant-design/pro-components'
|
import { ModalForm, ModalFormProps, ProFormInstance, ProFormText } from '@ant-design/pro-components'
|
||||||
import { ClockCircleOutlined, CloseCircleOutlined, DiffOutlined, FolderAddOutlined, ImportOutlined, SwitcherOutlined } from '@ant-design/icons'
|
import { ClockCircleOutlined, CloseCircleOutlined, DiffOutlined, FolderAddOutlined, ImportOutlined, SwitcherOutlined } from '@ant-design/icons'
|
||||||
import type { TreeProps, InputProps } from 'antd';
|
import type { TreeProps, InputProps } from 'antd';
|
||||||
|
import type { BoxTreeProps } from '../../../tree';
|
||||||
import TreeTransferModal from '../../../treeTransferModal'
|
import TreeTransferModal from '../../../treeTransferModal'
|
||||||
import BoxTree from '../../../tree';
|
import BoxTree from '../../../tree';
|
||||||
|
|
||||||
export interface BoxGroupPanelProps {
|
export interface BoxPanelProps {
|
||||||
searchInputProps?: InputProps
|
searchInputProps?: InputProps
|
||||||
showOptions?: boolean
|
showOptions?: boolean
|
||||||
treeProps?: TreeProps
|
treeProps?: Partial<BoxTreeProps>
|
||||||
data: TreeDataNode[]
|
data: TreeDataNode[]
|
||||||
boxDataSource: TreeDataNode[]
|
boxDataSource: TreeDataNode[]
|
||||||
handleImport?: () => void
|
handleImport?: () => void
|
||||||
@ -20,11 +21,14 @@ export interface BoxGroupPanelProps {
|
|||||||
onBoxDelete?: (data?: any) => void
|
onBoxDelete?: (data?: any) => void
|
||||||
onCreateSubmit?: ModalFormProps['onFinish']
|
onCreateSubmit?: ModalFormProps['onFinish']
|
||||||
onClockClick?: () => void
|
onClockClick?: () => void
|
||||||
|
onImport?: () => void
|
||||||
|
onBatch?: () => void
|
||||||
|
onCreate?: () => void
|
||||||
customImport?: any
|
customImport?: any
|
||||||
extraBtns?: any
|
extraBtns?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoxGroupPanel: FC<BoxGroupPanelProps> = (props) => {
|
const BoxPanel: FC<BoxPanelProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
searchInputProps,
|
searchInputProps,
|
||||||
showOptions = true,
|
showOptions = true,
|
||||||
@ -38,6 +42,9 @@ const BoxGroupPanel: FC<BoxGroupPanelProps> = (props) => {
|
|||||||
onBoxBatchDelete,
|
onBoxBatchDelete,
|
||||||
onBoxDelete,
|
onBoxDelete,
|
||||||
onClockClick,
|
onClockClick,
|
||||||
|
onImport,
|
||||||
|
onBatch,
|
||||||
|
onCreate,
|
||||||
boxDataSource,
|
boxDataSource,
|
||||||
customImport
|
customImport
|
||||||
} = props
|
} = props
|
||||||
@ -116,7 +123,7 @@ const BoxGroupPanel: FC<BoxGroupPanelProps> = (props) => {
|
|||||||
<Input size='middle' onChange={(e) => onSearch?.(e)} placeholder='请输入盒子名称' {...searchInputProps} />
|
<Input size='middle' onChange={(e) => onSearch?.(e)} placeholder='请输入盒子名称' {...searchInputProps} />
|
||||||
{customImport || (
|
{customImport || (
|
||||||
<>
|
<>
|
||||||
<Button type="text" onClick={() => handleCheckable()} icon={!isTreeCheckable ? <DiffOutlined /> : <SwitcherOutlined />} />
|
<Button type="text" onClick={() => onBatch?.() || handleCheckable()} icon={isTreeCheckable ? <SwitcherOutlined /> : <DiffOutlined />} />
|
||||||
<Button type="text" onClick={() => onClockClick?.()} icon={<ClockCircleOutlined />} />
|
<Button type="text" onClick={() => onClockClick?.()} icon={<ClockCircleOutlined />} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -125,58 +132,65 @@ const BoxGroupPanel: FC<BoxGroupPanelProps> = (props) => {
|
|||||||
{showOptions && (
|
{showOptions && (
|
||||||
<>
|
<>
|
||||||
<Space align='center'>
|
<Space align='center'>
|
||||||
<Button type='text' style={{ padding: '4px 8px' }} icon={<ImportOutlined />} >导入盒子</Button>
|
<Button type='text' style={{ padding: '4px 8px' }} onClick={() => onImport?.()} icon={<ImportOutlined />} >导入盒子</Button>
|
||||||
<Divider type="vertical" style={{ margin: '8px 0' }} />
|
<Divider type="vertical" style={{ margin: '8px 0' }} />
|
||||||
<ModalForm<{
|
{onCreate ?
|
||||||
name: string
|
(
|
||||||
boxList?: any[]
|
<Button onClick={onCreate} type='text' style={{ padding: '4px 8px' }} icon={<FolderAddOutlined />} >新建组</Button>
|
||||||
}>
|
) : (
|
||||||
width={'600px'}
|
<ModalForm<{
|
||||||
formRef={createFormRef}
|
name: string
|
||||||
title="新建组"
|
boxList?: any[]
|
||||||
modalProps={{ destroyOnClose: true }}
|
}>
|
||||||
layout='horizontal'
|
width={'600px'}
|
||||||
labelCol={{ span: 6 }}
|
open={onCreate ? false : undefined}
|
||||||
wrapperCol={{ span: 18 }}
|
formRef={createFormRef}
|
||||||
trigger={<Button type='text' style={{ padding: '4px 8px' }} icon={<FolderAddOutlined />} >新建组</Button>}
|
title="新建组"
|
||||||
submitter={{
|
modalProps={{ destroyOnClose: true }}
|
||||||
searchConfig: {
|
layout='horizontal'
|
||||||
submitText: '确定',
|
labelCol={{ span: 6 }}
|
||||||
resetText: '取消',
|
wrapperCol={{ span: 18 }}
|
||||||
},
|
trigger={<Button type='text' style={{ padding: '4px 8px' }} icon={<FolderAddOutlined />} >新建组</Button>}
|
||||||
}}
|
submitter={{
|
||||||
onFinish={onCreateSubmit}
|
searchConfig: {
|
||||||
>
|
submitText: '确定',
|
||||||
<ProFormText
|
resetText: '取消',
|
||||||
rules={[
|
},
|
||||||
{
|
}}
|
||||||
required: true,
|
onFinish={onCreateSubmit}
|
||||||
},
|
>
|
||||||
]}
|
<ProFormText
|
||||||
width="md"
|
rules={[
|
||||||
name="name"
|
{
|
||||||
label="盒子组名称"
|
required: true,
|
||||||
placeholder="请输入盒子名称"
|
},
|
||||||
/>
|
]}
|
||||||
<ProFormText
|
width="md"
|
||||||
width="md"
|
name="name"
|
||||||
name="boxList"
|
label="盒子组名称"
|
||||||
label="盒子选择"
|
placeholder="请输入盒子名称"
|
||||||
fieldProps={{
|
/>
|
||||||
readOnly: true,
|
<ProFormText
|
||||||
value: `已选择${createFormRef.current?.getFieldValue('boxList')?.length || 0}个盒子`,
|
width="md"
|
||||||
suffix: (
|
name="boxList"
|
||||||
<Space>
|
label="盒子选择"
|
||||||
<a onClick={() => {
|
fieldProps={{
|
||||||
createFormRef.current?.setFieldValue('boxList', null)
|
readOnly: true,
|
||||||
onBoxChoiceReset()
|
value: `已选择${createFormRef.current?.getFieldValue('boxList')?.length || 0}个盒子`,
|
||||||
}} >恢复默认</a>
|
suffix: (
|
||||||
<a onClick={() => setBoxChoiceOpen(true)}>范围选择</a>
|
<Space>
|
||||||
</Space>
|
<a onClick={() => {
|
||||||
)
|
createFormRef.current?.setFieldValue('boxList', null)
|
||||||
}}
|
onBoxChoiceReset()
|
||||||
/>
|
}} >恢复默认</a>
|
||||||
</ModalForm>
|
<a onClick={() => setBoxChoiceOpen(true)}>范围选择</a>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ModalForm>
|
||||||
|
)
|
||||||
|
}
|
||||||
<Divider type="vertical" style={{ margin: '8px 0' }} />
|
<Divider type="vertical" style={{ margin: '8px 0' }} />
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<Button danger type='text' style={{ padding: '4px 8px' }} icon={<CloseCircleOutlined />} disabled={treeProps?.checkedKeys?.length <= 0} onClick={onBoxBatchDelete} >删除</Button>
|
<Button danger type='text' style={{ padding: '4px 8px' }} icon={<CloseCircleOutlined />} disabled={treeProps?.checkedKeys?.length <= 0} onClick={onBoxBatchDelete} >删除</Button>
|
||||||
@ -198,4 +212,4 @@ const BoxGroupPanel: FC<BoxGroupPanelProps> = (props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BoxGroupPanel
|
export default BoxPanel
|
||||||
|
82
packages/biz/src/boxSelectTree/demo/async.tsx
Normal file
82
packages/biz/src/boxSelectTree/demo/async.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { BoxSelectTree } from '@zhst/biz';
|
||||||
|
import { boxDataSource } from './mock'
|
||||||
|
|
||||||
|
interface DataNode {
|
||||||
|
title: string;
|
||||||
|
key: string;
|
||||||
|
isLeaf?: boolean;
|
||||||
|
children?: DataNode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const initTreeData: DataNode[] = [
|
||||||
|
{ title: '盒子组1', key: '0' },
|
||||||
|
{ title: '盒子组2', key: '1' },
|
||||||
|
{ title: '盒子组3', key: '2', isLeaf: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归更新树结构
|
||||||
|
* @param list 原数组列表
|
||||||
|
* @param key 当前选中的项
|
||||||
|
* @param children 需要插入更新的数据
|
||||||
|
* @returns newList
|
||||||
|
*/
|
||||||
|
const updateTreeData = (list: DataNode[], key: React.Key, children: DataNode[]): DataNode[] =>
|
||||||
|
list.map((node) => {
|
||||||
|
if (node.key === key) {
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
children,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (node.children) {
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
children: updateTreeData(node.children, key, children),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
|
||||||
|
const demo = () => {
|
||||||
|
const [treeData, setTreeData] = useState(initTreeData);
|
||||||
|
const [activeKey, setActiveKey] = useState('1')
|
||||||
|
const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const onLoadData = ({ key, children }: any) =>
|
||||||
|
new Promise<void>((resolve) => {
|
||||||
|
if (children) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
setTreeData((origin) =>
|
||||||
|
updateTreeData(origin, key, [
|
||||||
|
{ title: '盒子', key: `${key}-0` },
|
||||||
|
{ title: '盒子', key: `${key}-1` },
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
resolve();
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ border: '1px solid #ccc', width: '340px', minHeight: '900px' }}>
|
||||||
|
<BoxSelectTree
|
||||||
|
data={treeData}
|
||||||
|
boxDataSource={boxDataSource}
|
||||||
|
showOptions={false}
|
||||||
|
tabsProps={{
|
||||||
|
activeKey,
|
||||||
|
}}
|
||||||
|
treeProps={{
|
||||||
|
loadData: (_params) => onLoadData(_params),
|
||||||
|
checkedKeys
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default demo;
|
@ -47,8 +47,9 @@ const demo = () => {
|
|||||||
onItemCheck={onTreeCheck}
|
onItemCheck={onTreeCheck}
|
||||||
onItemSelect={e => console.log('onItemSelect', e)}
|
onItemSelect={e => console.log('onItemSelect', e)}
|
||||||
onTabChange={val => setActiveKey(val)}
|
onTabChange={val => setActiveKey(val)}
|
||||||
onBoxDelete={data => console.log('盒子删除', data)}
|
|
||||||
onBoxBatchDelete={onBoxBatchDelete}
|
onBoxBatchDelete={onBoxBatchDelete}
|
||||||
|
onClockClick={() => console.log('时钟点击事件')}
|
||||||
|
onImport={() => console.log('导入盒子')}
|
||||||
tabsProps={{
|
tabsProps={{
|
||||||
activeKey,
|
activeKey,
|
||||||
}}
|
}}
|
||||||
@ -71,7 +72,11 @@ const demo = () => {
|
|||||||
value: searchVal
|
value: searchVal
|
||||||
}}
|
}}
|
||||||
treeProps={{
|
treeProps={{
|
||||||
checkedKeys
|
onItemDelete: data => console.log('删除', data),
|
||||||
|
onItemSetting: data => console.log('配置事件', data),
|
||||||
|
onItemRename: (data) =>console.log('重命名', data),
|
||||||
|
onItemRenameFinish: async (val, data) => console.log('盒子重命名提交(返回boolean,控制弹框显示\隐藏)', val, data),
|
||||||
|
checkedKeys,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
category: Components
|
category: Components
|
||||||
title: BoxSelectTree 盒子树
|
title: BoxSelectTree 盒子树
|
||||||
demo:
|
demo:
|
||||||
cols: 4
|
cols: 2
|
||||||
group:
|
group:
|
||||||
title: 进阶组件
|
title: 进阶组件
|
||||||
order: 2
|
order: 2
|
||||||
@ -15,6 +15,7 @@ group:
|
|||||||
<code src="./demo/basic.tsx">基本用法</code>
|
<code src="./demo/basic.tsx">基本用法</code>
|
||||||
<code src="./demo/extraBtns.tsx">自定义其它按钮</code>
|
<code src="./demo/extraBtns.tsx">自定义其它按钮</code>
|
||||||
<code src="./demo/noOptions.tsx">不显示其它按钮</code>
|
<code src="./demo/noOptions.tsx">不显示其它按钮</code>
|
||||||
|
<code src="./demo/async.tsx">异步加载数据</code>
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
@ -30,5 +31,8 @@ group:
|
|||||||
| onBoxDelete | 盒子删除事件 | function: (e) => void | - | - |
|
| onBoxDelete | 盒子删除事件 | function: (e) => void | - | - |
|
||||||
| onBoxBatchDelete | 盒子批量删除事件 | function: (e) => void | - | - |
|
| onBoxBatchDelete | 盒子批量删除事件 | function: (e) => void | - | - |
|
||||||
| onCreateSubmit | 新建提交事件 | function: (e) => void | - | - |
|
| onCreateSubmit | 新建提交事件 | function: (e) => void | - | - |
|
||||||
|
| onImport | 监听导入盒子点击事件 | function: () => void | - | - |
|
||||||
|
| onClockClick | 监听时钟点击事件 | function: () => void | - | - |
|
||||||
|
| onCreate | 监听创建点击事件 | function: () => void | 如果不传默认用自带的创建事件 | - |
|
||||||
| showOptions | 展示其它功能按钮 | boolean | true | - |
|
| showOptions | 展示其它功能按钮 | boolean | true | - |
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
import BoxSelectTree from './boxSelectTree';
|
import BoxSelectTree from './boxSelectTree';
|
||||||
|
|
||||||
|
export type { BoxSelectTreeProps } from './boxSelectTree'
|
||||||
|
|
||||||
export default BoxSelectTree;
|
export default BoxSelectTree;
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
export { default as BigImageModal } from './BigImageModal'
|
export { default as BigImageModal } from './BigImageModal'
|
||||||
|
export type { BigImageModalProps } from './BigImageModal'
|
||||||
export { default as BoxSelectTree } from './boxSelectTree'
|
export { default as BoxSelectTree } from './boxSelectTree'
|
||||||
|
export type { BoxSelectTreeProps } from './boxSelectTree'
|
||||||
export { default as Tree } from './tree'
|
export { default as Tree } from './tree'
|
||||||
export type { TreeData } from './tree'
|
export type { BoxTreeProps, TreeData } from './tree'
|
||||||
export { default as TreeTransfer } from './treeTransfer'
|
export { default as TreeTransfer } from './treeTransfer'
|
||||||
|
export type { TreeTransferProps } from './treeTransfer'
|
||||||
export { default as TreeTransferModal } from './treeTransferModal'
|
export { default as TreeTransferModal } from './treeTransferModal'
|
||||||
|
export type { TreeTransferModalProps } from './treeTransferModal'
|
||||||
export { default as WarningRecordCard } from './WarningRecordCard'
|
export { default as WarningRecordCard } from './WarningRecordCard'
|
||||||
export type {IRecord, WarningRecordCardProps} from './WarningRecordCard'
|
export type { WarningRecordCardProps, IRecord } from './WarningRecordCard'
|
||||||
|
@ -17,7 +17,8 @@ export interface BoxTreeProps extends TreeProps {
|
|||||||
onItemSelect?: TreeProps['onSelect']
|
onItemSelect?: TreeProps['onSelect']
|
||||||
onItemSetting?: (_data: any) => void
|
onItemSetting?: (_data: any) => void
|
||||||
onItemDelete?: (_data: any) => void
|
onItemDelete?: (_data: any) => void
|
||||||
onRenameFinish?: (_data: any, _nodeData: any) => Promise<any>
|
onItemRename?: (_nodeData: any) => void
|
||||||
|
onItemRenameFinish?: (_data: any, _nodeData: any) => Promise<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
const boxTree: FC<BoxTreeProps> = (props) => {
|
const boxTree: FC<BoxTreeProps> = (props) => {
|
||||||
@ -29,15 +30,18 @@ const boxTree: FC<BoxTreeProps> = (props) => {
|
|||||||
data = [],
|
data = [],
|
||||||
showItemOption = true,
|
showItemOption = true,
|
||||||
treeCheckable = false,
|
treeCheckable = false,
|
||||||
onRenameFinish,
|
onItemRename,
|
||||||
|
onItemRenameFinish,
|
||||||
customOptions
|
customOptions
|
||||||
} = props
|
} = props
|
||||||
const { token } = useToken()
|
const { token } = useToken()
|
||||||
const [checkedItem, setCheckedItem] = useState<React.Key>('')
|
const [checkedItem, setCheckedItem] = useState<React.Key>('')
|
||||||
|
|
||||||
const cameraStatus = new Map([
|
const cameraStatus = new Map([
|
||||||
['0', 'success'],
|
['0', 'error'],
|
||||||
['1', 'error']
|
['1', 'success'],
|
||||||
|
['3', 'processing'],
|
||||||
|
['4', 'default'],
|
||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -54,7 +58,7 @@ const boxTree: FC<BoxTreeProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<div className={`${componentName}-item-render`}>
|
<div className={`${componentName}-item-render`}>
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
{!_nodeData.children && _nodeData.isCamera && <Badge style={{ marginRight: '6px' }} status={cameraStatus.get('0')} />}
|
{!_nodeData.children && _nodeData.isCamera && <Badge style={{ marginRight: '6px' }} status={cameraStatus.get(_nodeData.status || '4')} />}
|
||||||
<span
|
<span
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
style={(checkedItem === _nodeData.key) && _nodeData.isCamera ? {
|
style={(checkedItem === _nodeData.key) && _nodeData.isCamera ? {
|
||||||
@ -74,14 +78,18 @@ const boxTree: FC<BoxTreeProps> = (props) => {
|
|||||||
layout='horizontal'
|
layout='horizontal'
|
||||||
labelCol={{ span: 6 }}
|
labelCol={{ span: 6 }}
|
||||||
wrapperCol={{ span: 18 }}
|
wrapperCol={{ span: 18 }}
|
||||||
trigger={<EditOutlined />}
|
trigger={<EditOutlined onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
onItemRename?.(_nodeData)
|
||||||
|
}} />}
|
||||||
submitter={{
|
submitter={{
|
||||||
searchConfig: {
|
searchConfig: {
|
||||||
submitText: '确定',
|
submitText: '确定',
|
||||||
resetText: '取消',
|
resetText: '取消',
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onFinish={async (value) => onRenameFinish?.(value, _nodeData)}
|
onFinish={async (value) => onItemRenameFinish?.(value, _nodeData)}
|
||||||
>
|
>
|
||||||
<ProFormText
|
<ProFormText
|
||||||
rules={[
|
rules={[
|
||||||
@ -95,8 +103,16 @@ const boxTree: FC<BoxTreeProps> = (props) => {
|
|||||||
placeholder="请输入盒子名称"
|
placeholder="请输入盒子名称"
|
||||||
/>
|
/>
|
||||||
</ModalForm>
|
</ModalForm>
|
||||||
<SettingOutlined onClick={() => onItemSetting?.(_nodeData)} />
|
<SettingOutlined onClick={(e) => {
|
||||||
<CloseOutlined onClick={() => onItemDelete?.(_nodeData)} />
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
onItemSetting?.(_nodeData)}
|
||||||
|
} />
|
||||||
|
<CloseOutlined onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
onItemDelete?.(_nodeData)
|
||||||
|
}} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
|
@ -4,7 +4,13 @@ import BoxTree from './boxTree';
|
|||||||
export interface TreeData extends TreeDataNode {
|
export interface TreeData extends TreeDataNode {
|
||||||
children?: TreeDataNode['children'] & {
|
children?: TreeDataNode['children'] & {
|
||||||
isCamera?: boolean
|
isCamera?: boolean
|
||||||
|
/**
|
||||||
|
* 0-失败 1-成功 2-进行中 3-未知
|
||||||
|
*/
|
||||||
|
status?: '0' | '1' | '2' | '3'
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type { BoxTreeProps } from './boxTree'
|
||||||
|
|
||||||
export default BoxTree;
|
export default BoxTree;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
import TreeTransfer from "./TreeTransfer";
|
import TreeTransfer from "./TreeTransfer";
|
||||||
|
|
||||||
|
export type { TreeTransferProps } from './TreeTransfer'
|
||||||
|
|
||||||
|
export * from './treeTransferHelper'
|
||||||
|
|
||||||
export default TreeTransfer
|
export default TreeTransfer
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
import TreeTransferModal from './TreeTransferModal'
|
import TreeTransferModal from './TreeTransferModal'
|
||||||
|
|
||||||
|
export type { TreeTransferModalProps } from './TreeTransferModal'
|
||||||
|
|
||||||
export default TreeTransferModal
|
export default TreeTransferModal
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
import { useMemo } from 'react';
|
|
||||||
import { throttle as loadshThrottle, noop } from '@zhst/func';
|
|
||||||
import { useDeepEffect, useLatest } from '@zhst/hooks';
|
|
||||||
import ws from './ws';
|
|
||||||
|
|
||||||
const getSelf = (v: any) => v;
|
|
||||||
export const SocketApi = {
|
|
||||||
CameraTaskStatue: 'singer.DeviceService/SubScribeCameraTaskStatus',
|
|
||||||
DeviceStatus: 'singer.TaskManagerService/SubscribeTaskStatus',
|
|
||||||
SubscribeSolutionDeploy: 'singer.SolutionManagerService/SubscribeSolutionDeploy',
|
|
||||||
SubscribeTasksSummary: 'singer.TaskManagerService/SubscribeTasksSummary',
|
|
||||||
MonitorSubscribeResult: 'singer.MonitorService/MonitorSubscribeResult',
|
|
||||||
MonitorSubscribeStatus: 'singer.MonitorService/MonitorSubscribeStatus',
|
|
||||||
SubscribeArchiveGroupUpload: 'singer.ArchiveGroupService/CreateArchiveByImport',
|
|
||||||
SubscribeJointTask: 'singer.JointTaskService/SubscribeJointTask',
|
|
||||||
SubscribeGroupFragment: 'singer.VideoService/SubscribeVideoFragmentStatus', // 监听视频分片状态变化,包括新建、删除、变化
|
|
||||||
SubscribeGroup: 'singer.VideoService/SubscribeGroup', // 监听视频分组状态变化,列表变化也通知
|
|
||||||
SubscribeStreamEvent: 'singer.MediaManagerService/SubscribeStreamEvent', // 监听视频分组状态变化,列表变化也通知
|
|
||||||
};
|
|
||||||
type ApiKeys = keyof typeof SocketApi;
|
|
||||||
|
|
||||||
export default (
|
|
||||||
topic: ApiKeys,
|
|
||||||
iterator: any = noop,
|
|
||||||
opt?: {
|
|
||||||
req?: { [key: string]: any };
|
|
||||||
throttle?: number;
|
|
||||||
parseData?: boolean;
|
|
||||||
beforeLoopTmp?: Function;
|
|
||||||
shouldBreak: boolean;
|
|
||||||
forceRefresh: any;
|
|
||||||
close?: boolean;
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
const {
|
|
||||||
req = {},
|
|
||||||
throttle = 0,
|
|
||||||
beforeLoopTmp = getSelf,
|
|
||||||
shouldBreak = false,
|
|
||||||
forceRefresh,
|
|
||||||
close,
|
|
||||||
} = opt || {};
|
|
||||||
|
|
||||||
// 带上token
|
|
||||||
const reqstring = useMemo(() => {
|
|
||||||
const newReq = {
|
|
||||||
...req,
|
|
||||||
extraHeaders: {
|
|
||||||
authorization: localStorage.getItem('USER-TOKEN'),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return JSON.stringify(newReq);
|
|
||||||
}, [req]);
|
|
||||||
|
|
||||||
const latestIterator = useLatest(iterator);
|
|
||||||
useDeepEffect(() => {
|
|
||||||
if (close) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//控制socket 请求发送
|
|
||||||
if (shouldBreak) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//去抖动
|
|
||||||
|
|
||||||
let tmpData: any = [];
|
|
||||||
const throttleUpdate = loadshThrottle(() => {
|
|
||||||
if (tmpData.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const _tmpData = beforeLoopTmp(tmpData);
|
|
||||||
latestIterator.current(_tmpData); //加了throttle 数据就变成数组
|
|
||||||
tmpData = [];
|
|
||||||
}, throttle);
|
|
||||||
|
|
||||||
const unSubscribe = ws.subscribe(SocketApi[topic], reqstring, (socketData: any) => {
|
|
||||||
try {
|
|
||||||
if (!throttle) {
|
|
||||||
latestIterator.current(socketData);
|
|
||||||
} else {
|
|
||||||
tmpData.push(socketData);
|
|
||||||
throttleUpdate();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('useSocke:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
try {
|
|
||||||
unSubscribe();
|
|
||||||
throttleUpdate.cancel();
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [topic, reqstring, shouldBreak, forceRefresh, close]);
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
//@ts-nocheck
|
|
||||||
import channel from './ws';
|
|
||||||
|
|
||||||
const startChannel = (topic, req, callback) => {
|
|
||||||
// 带上token
|
|
||||||
let reqstring = JSON.stringify({
|
|
||||||
...req,
|
|
||||||
extraHeaders: {
|
|
||||||
authorization: localStorage.getItem('USER-TOKEN'),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let unSubscribe = channel.subscribe(topic, reqstring, (socketData) => {
|
|
||||||
let shouldStop = callback(socketData);
|
|
||||||
if (shouldStop) {
|
|
||||||
unSubscribe?.();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return unSubscribe;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default startChannel;
|
|
@ -1,222 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import { has } from '@zhst/func';
|
|
||||||
import io from 'socket.io-client';
|
|
||||||
import { SOCKET_HOST } from '@common/constants';
|
|
||||||
|
|
||||||
const EMITSTATE = {
|
|
||||||
NOT_CONNECT: 0,
|
|
||||||
WAITING: 1,
|
|
||||||
CONNECT: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
const initRetryTime = 0;
|
|
||||||
const intervalTime = 5 * 1000; //下次重试增加时间
|
|
||||||
const maxIntervalTime = 1 * 60 * 60 * 1000; //最大重试时间1小时
|
|
||||||
|
|
||||||
class Channel {
|
|
||||||
/**
|
|
||||||
* io 实例化对象
|
|
||||||
*/
|
|
||||||
ioIns;
|
|
||||||
/**
|
|
||||||
* 已存在的订阅列表
|
|
||||||
*/
|
|
||||||
listeners = [
|
|
||||||
// {
|
|
||||||
// topic: "",
|
|
||||||
// req: "",
|
|
||||||
// suInfo: {},
|
|
||||||
// hasEmit: false,//是否已经订阅
|
|
||||||
// lastRetryInterval: 0,
|
|
||||||
// handles: {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 调试信息 记录订阅/反订阅次数
|
|
||||||
*/
|
|
||||||
subscribeListenerId = [];
|
|
||||||
unSubscribeListenerId = [];
|
|
||||||
|
|
||||||
init = () => {
|
|
||||||
const ioIns = (this.ioIns = io(SOCKET_HOST, {
|
|
||||||
reconnection: true,
|
|
||||||
transports: ['websocket'],
|
|
||||||
forceNew: true,
|
|
||||||
}));
|
|
||||||
ioIns.on('connect', (...arg: any) => {
|
|
||||||
console.debug('connect', arg);
|
|
||||||
this.ioIns = ioIns;
|
|
||||||
this.listeners.forEach((v) => {
|
|
||||||
this.doEmit(v['topic'], v['req'], v['id']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ioIns.on('event', (...arg: any) => {
|
|
||||||
console.debug('event', arg);
|
|
||||||
});
|
|
||||||
|
|
||||||
ioIns.on('disconnect', (...arg: any) => {
|
|
||||||
console.debug('disconnect', arg);
|
|
||||||
this.subscribeListenerId = [];
|
|
||||||
this.unSubscribeListenerId = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
ioIns.on('reconnect', (...arg: any) => {
|
|
||||||
console.debug('reconnect', arg);
|
|
||||||
this.listeners.forEach((v) => {
|
|
||||||
v['hasEmit'] = EMITSTATE.NOT_CONNECT;
|
|
||||||
this.doEmit(v['topic'], v['req'], v['id']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
retry = (listener: { [x: string]: any; lastRetryInterval: number | undefined; intervalId: NodeJS.Timeout; } | undefined) => {
|
|
||||||
//重试逻辑
|
|
||||||
const intervalId = setTimeout(() => {
|
|
||||||
const hasExit = this.listeners.find(
|
|
||||||
(v) => v['topic'] === listener?.['topic'] && v['req'] === listener['req']
|
|
||||||
);
|
|
||||||
if (!hasExit) return;
|
|
||||||
listener['hasEmit'] = EMITSTATE.NOT_CONNECT;
|
|
||||||
this.doEmit(listener['topic'], listener['req'], listener['id']);
|
|
||||||
}, listener.lastRetryInterval);
|
|
||||||
|
|
||||||
listener.intervalId = intervalId;
|
|
||||||
listener.lastRetryInterval =
|
|
||||||
intervalTime + listener.lastRetryInterval > maxIntervalTime
|
|
||||||
? maxIntervalTime
|
|
||||||
: intervalTime + listener.lastRetryInterval;
|
|
||||||
};
|
|
||||||
|
|
||||||
doEmit = (topic, req, listenerId) => {
|
|
||||||
if (!this.ioIns) {
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
//订阅过就不订阅了
|
|
||||||
const hasEmit = this.listeners.find(
|
|
||||||
(v) => v['topic'] === topic && v['req'] === req && v['hasEmit'] !== EMITSTATE.NOT_CONNECT
|
|
||||||
);
|
|
||||||
if (hasEmit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const listener = this.listeners.find((v) => v['topic'] === topic && v['req'] === req);
|
|
||||||
listener['hasEmit'] = EMITSTATE.WAITING;
|
|
||||||
|
|
||||||
this.ioIns?.emit?.(topic, req, (data) => {
|
|
||||||
console.info('emit', topic, req, data);
|
|
||||||
const suInfo = JSON.parse(data);
|
|
||||||
if (has(suInfo, 'Error.code')) {
|
|
||||||
if (suInfo.Error.code === 500) {
|
|
||||||
//后端出错
|
|
||||||
this.retry(listener);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.debug('SUBSCRIBE', listenerId, topic, req, suInfo);
|
|
||||||
this.subscribeListenerId.push(listenerId);
|
|
||||||
// debugger
|
|
||||||
//重新找一遍topic
|
|
||||||
const currentTopicIndex = this.listeners.findIndex(
|
|
||||||
(v) => v['topic'] === topic && v['req'] === req && v['id'] === listenerId
|
|
||||||
);
|
|
||||||
if (currentTopicIndex == -1) {
|
|
||||||
// 不存在说明listener取消了 直接反订阅
|
|
||||||
this.ioIns.emit('UnSubscribe', JSON.stringify(suInfo), (data) => {
|
|
||||||
this.unSubscribeListenerId.push(listenerId);
|
|
||||||
console.debug('UNSUBSCRIBE', listenerId, topic, req, data);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!suInfo['SubscribeID']) {
|
|
||||||
this.listeners.splice(currentTopicIndex, 0);
|
|
||||||
} else {
|
|
||||||
this.listeners[currentTopicIndex]['suInfo'] = suInfo;
|
|
||||||
this.listeners[currentTopicIndex]['hasEmit'] = EMITSTATE.CONNECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.ioIns?.on?.(suInfo['SubscribeID'], (data) => {
|
|
||||||
console.info('on', suInfo['SubscribeID'], data);
|
|
||||||
try {
|
|
||||||
const socketData = JSON.parse(data);
|
|
||||||
if (has(socketData, 'Error.code')) {
|
|
||||||
if (socketData.Error.code === 500) {
|
|
||||||
//后端出错
|
|
||||||
this.retry(listener);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { handles = {} } =
|
|
||||||
this.listeners.find((v) => v['topic'] === topic && v['req'] === req) || {};
|
|
||||||
Object.keys(handles).forEach((key) => {
|
|
||||||
try {
|
|
||||||
//后面观察 为什么delete后在foreach
|
|
||||||
const func = handles[key];
|
|
||||||
if (!func) return;
|
|
||||||
func(socketData);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.debug('error', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
subscribe(topic, req, handle) {
|
|
||||||
const handleId = uuidv4();
|
|
||||||
const listenerId = uuidv4();
|
|
||||||
const listener = this.listeners.find((v) => v['topic'] === topic && v['req'] === req);
|
|
||||||
if (listener) {
|
|
||||||
listener['handles'][handleId] = handle;
|
|
||||||
} else {
|
|
||||||
this.listeners.push({
|
|
||||||
topic: topic,
|
|
||||||
req: req,
|
|
||||||
suInfo: {},
|
|
||||||
id: listenerId,
|
|
||||||
hasEmit: EMITSTATE.NOT_CONNECT,
|
|
||||||
lastRetryInterval: initRetryTime,
|
|
||||||
handles: {
|
|
||||||
[`${handleId}`]: handle,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
//未注册过 则去订阅
|
|
||||||
this.doEmit(topic, req, listenerId);
|
|
||||||
}
|
|
||||||
return this.unSubscribe.bind(this, topic, req, handleId, listenerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
unSubscribe(topic, req, handleId, listenerId) {
|
|
||||||
const listener = this.listeners.find(
|
|
||||||
(v) => v['topic'] === topic && v['req'] === req && v['id'] === listenerId
|
|
||||||
);
|
|
||||||
const { handles = {}, suInfo } = listener || {};
|
|
||||||
if (handles[handleId]) {
|
|
||||||
delete handles[handleId];
|
|
||||||
//如果没有其他订阅就删除
|
|
||||||
if (Object.keys(handles).length === 0) {
|
|
||||||
if (this.intervalId) {
|
|
||||||
clearTimeout(this.intervalId);
|
|
||||||
}
|
|
||||||
if (listener['hasEmit'] === EMITSTATE['CONNECT']) {
|
|
||||||
this.ioIns.emit('UnSubscribe', JSON.stringify(suInfo), (data) => {
|
|
||||||
this.unSubscribeListenerId.push(listenerId);
|
|
||||||
console.debug('UNSUBSCRIBE', listener['id'], topic, req, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.listeners = this.listeners.filter((v) => !(v['topic'] === topic && v['req'] === req));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//单例
|
|
||||||
const channelIns = new Channel();
|
|
||||||
//暴露实例 调试用
|
|
||||||
window.__channel__ = channelIns;
|
|
||||||
|
|
||||||
export default channelIns;
|
|
@ -1,5 +1,13 @@
|
|||||||
# @zhst/utils
|
# @zhst/utils
|
||||||
|
|
||||||
|
## 0.7.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增 tree 组件的监听事件,优化 meta 全选的回调事件监听
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.8.3
|
||||||
|
|
||||||
## 0.7.3
|
## 0.7.3
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/func",
|
"name": "@zhst/func",
|
||||||
"version": "0.7.3",
|
"version": "0.7.4",
|
||||||
"description": "函数合集",
|
"description": "函数合集",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"hooks"
|
"hooks"
|
||||||
|
@ -240,128 +240,3 @@ export const getRotateImg = (image: HTMLImageElement, rotate: number) => {
|
|||||||
commonCanvas.parentNode?.removeChild(commonCanvas);
|
commonCanvas.parentNode?.removeChild(commonCanvas);
|
||||||
return file;
|
return file;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化工具
|
|
||||||
* @param originData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const getOdRect = (originData: IOdRectOrigin) => {
|
|
||||||
let data = get(originData, 'objects', [])
|
|
||||||
.filter((v: any) => !isNull(get(v, 'infoOnSource.bboxInFrame.bboxRatio')))
|
|
||||||
.map((v: any, index: any) => {
|
|
||||||
// objectId==0 特征没有提取到过滤1掉
|
|
||||||
const rect = get(v, 'infoOnSource.bboxInFrame.bboxRatio');
|
|
||||||
const extendBox = get(v, 'infoOnSource.bboxInFrame.extendBoxRatio');
|
|
||||||
const frameTimestamp = get(v, 'timestamp'); //时间戳创建档案的时候需要
|
|
||||||
const qualityScore = get(v, 'qualityScore');
|
|
||||||
const algorithmVersion =
|
|
||||||
get(v, 'objectType') === 'OBJECT_TYPE_PEDESTRAIN'
|
|
||||||
? 'VERSION_REID_HEAD_ATTR'
|
|
||||||
: get(v, 'objectType') === 'OBJECT_TYPE_FACE'
|
|
||||||
? 'VERSION_FACE'
|
|
||||||
: 'VERSION_REID_HEAD_ATTR';
|
|
||||||
const featureData = get(v, 'feature', []).filter(
|
|
||||||
(v: any) => v.type === 'FEATURE_TYPE_BYTE'
|
|
||||||
);
|
|
||||||
const objectRectIndex = algorithmVersion === 'VERSION_FACE' ? 0 : 1;
|
|
||||||
const objectType = get(v, 'objectType');
|
|
||||||
const objectId = get(v, 'objectIndex.objectId');
|
|
||||||
const sourceObjectId = get(v, 'sourceObjectId');
|
|
||||||
return {
|
|
||||||
x: rect.x,
|
|
||||||
y: rect.y,
|
|
||||||
w: rect.w,
|
|
||||||
h: rect.h,
|
|
||||||
// faceCorrectImage: faceCorrectImage,
|
|
||||||
id: index,
|
|
||||||
qualityScore: qualityScore,
|
|
||||||
algorithmVersion: algorithmVersion,
|
|
||||||
featureData: get(featureData, '0.featureByte'),
|
|
||||||
objectRectIndex: objectRectIndex,
|
|
||||||
objectType: objectType,
|
|
||||||
objectId: objectId,
|
|
||||||
frameTimestamp: frameTimestamp,
|
|
||||||
sourceObjectId: sourceObjectId,
|
|
||||||
extendBox: extendBox,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
if (data.length > 0) {
|
|
||||||
data = data.filter((v: { objectId: string; }) => v.objectId !== '0');
|
|
||||||
} else {
|
|
||||||
throw new Error('empty');
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
//档案库od
|
|
||||||
export const getOdRectV2 = (originData: { odv2Result: any[]; }) => {
|
|
||||||
const resp = originData.odv2Result[0];
|
|
||||||
const subObjects: { x: any; y: any; w: any; h: any; id: any; qualityScore: any; algorithmVersion: any; featrueData: any; objectRectIndex: number; objectType: any; objectId: any; }[] = []; //形体
|
|
||||||
const data = get(resp, 'objects', [])
|
|
||||||
.filter((v: any) => !isNull(get(v, 'subObjects[0].infoOnSource.bboxInFrame.bboxRatio')))
|
|
||||||
.map((v: any, index: any) => {
|
|
||||||
const rect = get(v, 'infoOnSource.bboxInFrame.bboxRatio');
|
|
||||||
const qualityScore = get(v, 'qualityScore');
|
|
||||||
const algorithmVersion = get(v, 'objectType');
|
|
||||||
const featrueData = get(v, 'feature', []).filter(
|
|
||||||
(v: { name: string; }) => v.name === 'feature-body' || v.name === 'feature-face'
|
|
||||||
);
|
|
||||||
const objectRectIndex = algorithmVersion === 'OBJECT_TYPE_FACE' ? 0 : 1;
|
|
||||||
const objectType = get(v, 'objectType');
|
|
||||||
const objectId = get(v, 'objectIndex.objectId');
|
|
||||||
//如果存在subObjects的数组不为null表示形体里面带人脸,人脸的od框也要显示出来
|
|
||||||
if (get(v, 'subObjects', []).length) {
|
|
||||||
get(v, 'subObjects', []).forEach((e: any) => {
|
|
||||||
const rect = get(e, 'infoOnSource.bboxInFrame.bboxRatio');
|
|
||||||
const qualityScore = get(e, 'qualityScore');
|
|
||||||
const algorithmVersion = get(e, 'objectType');
|
|
||||||
const featrueData = get(e, 'feature', []).filter(
|
|
||||||
(v: { name: string; }) => v.name === 'feature-body' || v.name === 'feature-face'
|
|
||||||
);
|
|
||||||
const objectRectIndex = algorithmVersion === 'OBJECT_TYPE_FACE' ? 0 : 1;
|
|
||||||
const objectType = get(e, 'objectType');
|
|
||||||
const objectId = get(e, 'objectIndex.objectId');
|
|
||||||
subObjects.push({
|
|
||||||
x: rect.x,
|
|
||||||
y: rect.y,
|
|
||||||
w: rect.w,
|
|
||||||
h: rect.h,
|
|
||||||
id: index,
|
|
||||||
qualityScore: qualityScore,
|
|
||||||
algorithmVersion: algorithmVersion,
|
|
||||||
featrueData: featrueData.length ? featrueData[0].featureByte : '',
|
|
||||||
objectRectIndex: objectRectIndex,
|
|
||||||
objectType: objectType,
|
|
||||||
objectId,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
x: rect.x,
|
|
||||||
y: rect.y,
|
|
||||||
w: rect.w,
|
|
||||||
h: rect.h,
|
|
||||||
id: index,
|
|
||||||
qualityScore: qualityScore,
|
|
||||||
algorithmVersion: algorithmVersion,
|
|
||||||
featrueData: featrueData[0].featureByte,
|
|
||||||
objectRectIndex: objectRectIndex,
|
|
||||||
objectType: objectType,
|
|
||||||
objectId: objectId,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const brr = data.concat(subObjects).map((v: { id: any; }, vs: any) => {
|
|
||||||
if (String(v.id)) {
|
|
||||||
v.id = vs;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
});
|
|
||||||
if (brr.length > 0) {
|
|
||||||
console.log(brr, 'data111');
|
|
||||||
} else {
|
|
||||||
throw new Error('empty');
|
|
||||||
}
|
|
||||||
console.log(brr);
|
|
||||||
return brr;
|
|
||||||
};
|
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
# @zhst/hooks
|
# @zhst/hooks
|
||||||
|
|
||||||
|
## 0.8.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增 tree 组件的监听事件,优化 meta 全选的回调事件监听
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.7.4
|
||||||
|
|
||||||
## 0.8.2
|
## 0.8.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/hooks",
|
"name": "@zhst/hooks",
|
||||||
"version": "0.8.2",
|
"version": "0.8.3",
|
||||||
"description": "hooks合集",
|
"description": "hooks合集",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"hooks"
|
"hooks"
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
# @zhst/utils
|
# @zhst/utils
|
||||||
|
|
||||||
|
## 0.8.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增 tree 组件的监听事件,优化 meta 全选的回调事件监听
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.8.3
|
||||||
|
- @zhst/func@0.7.4
|
||||||
|
- @zhst/meta@0.8.4
|
||||||
|
|
||||||
## 0.8.3
|
## 0.8.3
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/meta",
|
"name": "@zhst/meta",
|
||||||
"version": "0.8.3",
|
"version": "0.8.4",
|
||||||
"description": "原子组件",
|
"description": "原子组件",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"meta",
|
"meta",
|
||||||
|
@ -7,7 +7,6 @@ import {
|
|||||||
isNull,
|
isNull,
|
||||||
generateImg,
|
generateImg,
|
||||||
dataURLToBlob,
|
dataURLToBlob,
|
||||||
getOdRect,
|
|
||||||
getExtendRect,
|
getExtendRect,
|
||||||
getTransformRect,
|
getTransformRect,
|
||||||
getRotateImg,
|
getRotateImg,
|
||||||
@ -17,7 +16,7 @@ import {
|
|||||||
} from '@zhst/func';
|
} from '@zhst/func';
|
||||||
import Align from 'rc-align';
|
import Align from 'rc-align';
|
||||||
import { Button, Empty } from '..';
|
import { Button, Empty } from '..';
|
||||||
import { type Rect, type IScreenshotButtonProp, type AlignType, type IOdRectOrigin } from '@zhst/types'
|
import { type Rect, type IScreenshotButtonProp, type AlignType } from '@zhst/types'
|
||||||
import Icon from '../iconfont';
|
import Icon from '../iconfont';
|
||||||
import {
|
import {
|
||||||
Cropper,
|
Cropper,
|
||||||
@ -30,10 +29,10 @@ import {
|
|||||||
import BtnGroup from './components/BtnGroup';
|
import BtnGroup from './components/BtnGroup';
|
||||||
import './index.less'
|
import './index.less'
|
||||||
import { defaultAlignOption, CROP_TYPE } from '../utils/constants'
|
import { defaultAlignOption, CROP_TYPE } from '../utils/constants'
|
||||||
|
import { getOdRect, IOdObject } from './bigImagePreviewHelper'
|
||||||
|
|
||||||
const componentName = `zhst-image__img-view`;
|
const componentName = `zhst-image__img-view`;
|
||||||
|
|
||||||
|
|
||||||
export interface ViewOption {
|
export interface ViewOption {
|
||||||
/* 图片url */
|
/* 图片url */
|
||||||
image?: string | HTMLImageElement;
|
image?: string | HTMLImageElement;
|
||||||
@ -67,7 +66,7 @@ export interface ImgViewProps extends React.HTMLAttributes<HTMLElement> {
|
|||||||
attachImg?: Array<{ label: string; url: string }>; // 缩略图列表
|
attachImg?: Array<{ label: string; url: string }>; // 缩略图列表
|
||||||
odRect?: Rect
|
odRect?: Rect
|
||||||
score?: number
|
score?: number
|
||||||
objects?: IOdRectOrigin[] // 图片人物框选
|
objects?: IOdObject
|
||||||
}
|
}
|
||||||
showAttachImgLabel?: boolean; // 是否显示缩略图
|
showAttachImgLabel?: boolean; // 是否显示缩略图
|
||||||
showOpt?: boolean; // 是否显示操作面板
|
showOpt?: boolean; // 是否显示操作面板
|
||||||
@ -77,6 +76,7 @@ export interface ImgViewProps extends React.HTMLAttributes<HTMLElement> {
|
|||||||
screenshotButtonAlign?: AlignType;
|
screenshotButtonAlign?: AlignType;
|
||||||
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
|
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
|
||||||
hideLeftTopBtn?: boolean;
|
hideLeftTopBtn?: boolean;
|
||||||
|
onRectSelect?: (obj: IOdObject) => void
|
||||||
showScore?: boolean // 是否显示相似度
|
showScore?: boolean // 是否显示相似度
|
||||||
viewOption?: ViewOption;
|
viewOption?: ViewOption;
|
||||||
}
|
}
|
||||||
@ -127,12 +127,12 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
const {
|
const {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
showScore = true,
|
showScore = false,
|
||||||
data,
|
data,
|
||||||
showOpt = false,
|
showOpt = false,
|
||||||
showAttachImgLabel = true,
|
showAttachImgLabel = true,
|
||||||
screenshotButtonAlign = defaultAlignOption,
|
screenshotButtonAlign = defaultAlignOption,
|
||||||
screenshotButtonRender = () => <div style={{ color: '#fff' }}>回调DOM</div>,
|
screenshotButtonRender = () => <div style={{ color: '#fff', width: '80px', top: 0 }}>回调DOM</div>,
|
||||||
hideLeftTopBtn = true,
|
hideLeftTopBtn = true,
|
||||||
viewOption = {}
|
viewOption = {}
|
||||||
} = props;
|
} = props;
|
||||||
@ -144,18 +144,13 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
objects = [],
|
objects = [],
|
||||||
} = data
|
} = data
|
||||||
const imgContainerRef = React.useRef(null);
|
const imgContainerRef = React.useRef(null);
|
||||||
const [isReady, setIsReady] = useState(false);
|
|
||||||
|
|
||||||
const init = useCallback(($container: null) => {
|
|
||||||
imgContainerRef.current = $container;
|
|
||||||
setIsReady(true);
|
|
||||||
}, []);
|
|
||||||
// ============================= viewer =========================
|
// ============================= viewer =========================
|
||||||
const imgInsRef = useRef<any>(null);
|
const imgInsRef = useRef<any>(null);
|
||||||
const [isImgReady, setIsImgReady] = useState(false);
|
const [isImgReady, setIsImgReady] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isReady || !imgContainerRef?.current) return;
|
if (!imgContainerRef?.current) return;
|
||||||
const handleReady = addEventListenerWrapper(imgContainerRef.current, EVENT_VIEWER_READY, () => {
|
const handleReady = addEventListenerWrapper(imgContainerRef.current, EVENT_VIEWER_READY, () => {
|
||||||
setIsImgReady(true);
|
setIsImgReady(true);
|
||||||
});
|
});
|
||||||
@ -176,7 +171,7 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
imgInsRef?.current?.destroy?.();
|
imgInsRef?.current?.destroy?.();
|
||||||
imgInsRef.current = null;
|
imgInsRef.current = null;
|
||||||
};
|
};
|
||||||
}, [isReady, imageKey]);
|
}, [imageKey]);
|
||||||
|
|
||||||
// ============================= viewer操作按钮 =========================
|
// ============================= viewer操作按钮 =========================
|
||||||
const handleOptClick = (v: string) => {
|
const handleOptClick = (v: string) => {
|
||||||
@ -227,7 +222,8 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
};
|
};
|
||||||
}, [isImgReady, showCrop, cropType, imageKey]);
|
}, [isImgReady, showCrop, cropType, imageKey]);
|
||||||
|
|
||||||
const initData = (_objects: IOdRectOrigin[]) => {
|
// 初始化页面的绘制矩形
|
||||||
|
const initData = (_objects: IOdObject | never[]) => {
|
||||||
const imgIns = imgInsRef.current;
|
const imgIns = imgInsRef.current;
|
||||||
const _odRect = odRect
|
const _odRect = odRect
|
||||||
//清理crop
|
//清理crop
|
||||||
@ -301,12 +297,15 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
handlerCropEndRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_END, (event: { detail: any; }) => {
|
handlerCropEndRef.current = addEventListenerWrapper(imgContainerRef.current, EVENT_CROP_END, (event: { detail: any; }) => {
|
||||||
const data = event.detail;
|
const data = event.detail;
|
||||||
setSelectAlgorithmVersion(null);
|
setSelectAlgorithmVersion(null);
|
||||||
setCropRect({
|
const _rect = {
|
||||||
x: data.left,
|
x: data.left,
|
||||||
y: data.top,
|
y: data.top,
|
||||||
w: data.width,
|
w: data.width,
|
||||||
h: data.height,
|
h: data.height,
|
||||||
});
|
}
|
||||||
|
setCropRect(_rect);
|
||||||
|
const p = getCropInfo({ type: cropType, rect: _rect })
|
||||||
|
console.log('p', p)
|
||||||
alignRef?.current?.forceAlign?.();
|
alignRef?.current?.forceAlign?.();
|
||||||
});
|
});
|
||||||
cropInsRef.current = new Cropper(imgContainerRef.current, {
|
cropInsRef.current = new Cropper(imgContainerRef.current, {
|
||||||
@ -317,11 +316,10 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取框选的截图框信息
|
// 获取框选的截图框信息
|
||||||
const latestCropType = useLatest(cropType);
|
const getCropInfo = async (opt: { type: string; rect: Rect }) => {
|
||||||
const latestCropRect = useLatest(cropRect);
|
const { type, rect } = opt
|
||||||
const getCropInfo = async (cb: (data: any) => void) => {
|
const cropType = type;
|
||||||
const cropType = latestCropType.current;
|
const cropRect = rect;
|
||||||
const cropRect = latestCropRect.current;
|
|
||||||
const imgIns = imgInsRef.current;
|
const imgIns = imgInsRef.current;
|
||||||
const transform = imgIns.targetTransform;
|
const transform = imgIns.targetTransform;
|
||||||
let newImgKey = imageKey;
|
let newImgKey = imageKey;
|
||||||
@ -398,8 +396,15 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
rectList[index] = newRect;
|
rectList[index] = newRect;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
cb?.({ rectList, extendRectList, selectIndex, imgKey: newImgKey })
|
|
||||||
return { rectList, extendRectList, selectIndex, imgKey: newImgKey };
|
let data = {
|
||||||
|
rectList,
|
||||||
|
extendRectList,
|
||||||
|
selectIndex,
|
||||||
|
imgKey: newImgKey
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 操作界面判断
|
// 操作界面判断
|
||||||
@ -421,22 +426,12 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
const [selectAttachImgIndex, setSelectAttachImgIndex] = useState(0);
|
const [selectAttachImgIndex, setSelectAttachImgIndex] = useState(0);
|
||||||
const [isZoomin, setIsZoomin] = useState(false);
|
const [isZoomin, setIsZoomin] = useState(false);
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改当前图片预览下标
|
|
||||||
* @param diff 跳转强度 正向后翻、负值向前翻
|
|
||||||
*/
|
|
||||||
const handleChangeIndex = (cb?: () => void) => {
|
|
||||||
if (!imageKey) return
|
|
||||||
cb?.()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================== Ref ===============================
|
// ============================== Ref ===============================
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
imgInsRef,
|
imgInsRef,
|
||||||
setShowCrop,
|
setShowCrop,
|
||||||
initData,
|
initData,
|
||||||
getCropInfo,
|
getCropInfo,
|
||||||
handleChangeIndex
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -449,7 +444,7 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
`${componentName}-main`,
|
`${componentName}-main`,
|
||||||
cropType === CROP_TYPE['AUTO'] && `${componentName}-main--cursor`
|
cropType === CROP_TYPE['AUTO'] && `${componentName}-main--cursor`
|
||||||
)}
|
)}
|
||||||
ref={init}
|
ref={imgContainerRef}
|
||||||
/>
|
/>
|
||||||
{/* 图片操作 */}
|
{/* 图片操作 */}
|
||||||
{!hideLeftTopBtn && (
|
{!hideLeftTopBtn && (
|
||||||
@ -562,7 +557,7 @@ export const BigImagePreview = React.forwardRef<ImgViewRef, ImgViewProps>((props
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showScore && <div
|
{(showScore || score) && <div
|
||||||
style={{ bottom: 20 }}
|
style={{ bottom: 20 }}
|
||||||
className={classNames(`${componentName}__face-score`)}
|
className={classNames(`${componentName}__face-score`)}
|
||||||
>
|
>
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
import { get, isNull } from "@zhst/func";
|
||||||
|
import { ObjectType, Rect } from "@zhst/types";
|
||||||
|
|
||||||
|
export interface IOdObject {
|
||||||
|
objects: {
|
||||||
|
bboxRatio: Rect
|
||||||
|
timestamp?: string
|
||||||
|
qualityScore?: string
|
||||||
|
extendBoxRatio?: any
|
||||||
|
objectType?: ObjectType
|
||||||
|
objectIndex?: {
|
||||||
|
objectId: string
|
||||||
|
}
|
||||||
|
sourceObjectId?: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化工具
|
||||||
|
* @param originData
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getOdRect = (originData: IOdObject) => {
|
||||||
|
let data = get(originData, 'objects', [])
|
||||||
|
.filter((v: any) => !isNull(get(v, 'bboxRatio')) || get(v, 'objectIndex.objectId') !== '0' )
|
||||||
|
.map((v: any, index: any) => {
|
||||||
|
const rect = get(v, 'bboxRatio');
|
||||||
|
const extendBox = get(v, 'extendBoxRatio');
|
||||||
|
const frameTimestamp = get(v, 'timestamp'); //时间戳创建档案的时候需要
|
||||||
|
const qualityScore = get(v, 'qualityScore');
|
||||||
|
const algorithmVersion =
|
||||||
|
get(v, 'objectType') === 'OBJECT_TYPE_PEDESTRAIN'
|
||||||
|
? 'VERSION_REID_HEAD_ATTR'
|
||||||
|
: get(v, 'objectType') === 'OBJECT_TYPE_FACE'
|
||||||
|
? 'VERSION_FACE'
|
||||||
|
: 'VERSION_REID_HEAD_ATTR';
|
||||||
|
const objectRectIndex = algorithmVersion === 'VERSION_FACE' ? 0 : 1;
|
||||||
|
const objectType = get(v, 'objectType');
|
||||||
|
const objectId = get(v, 'objectIndex.objectId');
|
||||||
|
const sourceObjectId = get(v, 'sourceObjectId');
|
||||||
|
return {
|
||||||
|
x: rect.x,
|
||||||
|
y: rect.y,
|
||||||
|
w: rect.w,
|
||||||
|
h: rect.h,
|
||||||
|
id: index,
|
||||||
|
qualityScore,
|
||||||
|
algorithmVersion,
|
||||||
|
objectRectIndex,
|
||||||
|
objectType,
|
||||||
|
objectId,
|
||||||
|
frameTimestamp,
|
||||||
|
sourceObjectId,
|
||||||
|
extendBox,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
};
|
@ -25,28 +25,20 @@ const props = {
|
|||||||
time: '2022-01-01', // 摄像头拍摄时间
|
time: '2022-01-01', // 摄像头拍摄时间
|
||||||
objects: [
|
objects: [
|
||||||
{
|
{
|
||||||
"infoOnSource": {
|
"bboxRatio": {
|
||||||
"bboxInFrame": {
|
"x": 0.5519352,
|
||||||
"bboxRatio": {
|
"y": 0.2965385,
|
||||||
"x": 0.5519352,
|
"w": 0.05185461,
|
||||||
"y": 0.2965385,
|
"h": 0.24698898
|
||||||
"w": 0.05185461,
|
},
|
||||||
"h": 0.24698898
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"infoOnSource": {
|
"bboxRatio": {
|
||||||
"bboxInFrame": {
|
"x": 0.58543766,
|
||||||
"bboxRatio": {
|
"y": 0.3203356,
|
||||||
"x": 0.58543766,
|
"w": 0.052037954,
|
||||||
"y": 0.3203356,
|
"h": 0.2664015
|
||||||
"w": 0.052037954,
|
},
|
||||||
"h": 0.2664015
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
43
packages/meta/src/BigImagePreview/demo/noAttach.tsx
Normal file
43
packages/meta/src/BigImagePreview/demo/noAttach.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import { Button, Space } from '@zhst/meta'
|
||||||
|
import { BigImagePreview } from '@zhst/meta'
|
||||||
|
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
heigth: '500px',
|
||||||
|
data: {
|
||||||
|
imageKey: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||||
|
odRect:{
|
||||||
|
"x":0.553125,"y":0.29722223,"w":0.048958335,"h":0.2462963
|
||||||
|
},
|
||||||
|
cameraPosition: 'string', // 摄像头位置
|
||||||
|
time: '2022-01-01', // 摄像头拍摄时间
|
||||||
|
objects: [
|
||||||
|
{
|
||||||
|
"bboxRatio": {
|
||||||
|
"x": 0.5519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
onRectSelect: data => console.log('data', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const imgRef = useRef(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space size={[8, 16]} direction="vertical">
|
||||||
|
<BigImagePreview {...props} ref={imgRef} />
|
||||||
|
<Space>
|
||||||
|
<Button type="primary" onClick={() => imgRef.current?.setShowCrop(true)}>编辑</Button>
|
||||||
|
<Button onClick={() => imgRef.current?.handleChangeIndex(1)}>下一张</Button>
|
||||||
|
<Button onClick={() => imgRef.current?.setShowCrop(false)}>取消</Button>
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: calc(100%);
|
width: calc(100%);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
font-size: 0;
|
||||||
|
|
||||||
&__face-score {
|
&__face-score {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -62,14 +63,9 @@
|
|||||||
height: 202px;
|
height: 202px;
|
||||||
transition: all 200ms;
|
transition: all 200ms;
|
||||||
|
|
||||||
&--fixed {
|
|
||||||
}
|
|
||||||
|
|
||||||
&--zoomin {
|
&--zoomin {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
&--fixed {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__tab {
|
&__tab {
|
||||||
|
@ -8,6 +8,7 @@ title: BigImagePreview 大图预览组件
|
|||||||
# BigImagePreview 大图预览组件
|
# BigImagePreview 大图预览组件
|
||||||
|
|
||||||
<code src="./demo/base.tsx">基本</code>
|
<code src="./demo/base.tsx">基本</code>
|
||||||
|
<code src="./demo/noAttach.tsx">不展示小图</code>
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ const VideoPlayer = forwardRef<VideoViewRef, VideoViewProps>((props, ref) => {
|
|||||||
adjustY: true,
|
adjustY: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
screenshotButtonRender = () => <div style={{ color: '#fff' }}>回调DOM</div>,
|
screenshotButtonRender = () => <div style={{ color: '#fff', width: '80px', top: 0 }}>回调DOM</div>,
|
||||||
onCropChange,
|
onCropChange,
|
||||||
defautlNormalizationRect: defaultNormalizationRect,
|
defautlNormalizationRect: defaultNormalizationRect,
|
||||||
} = props;
|
} = props;
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
# @zhst/request
|
# @zhst/request
|
||||||
|
|
||||||
|
## 0.8.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 新增 tree 组件的监听事件,优化 meta 全选的回调事件监听
|
||||||
|
|
||||||
## 0.8.2
|
## 0.8.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/request",
|
"name": "@zhst/request",
|
||||||
"version": "0.8.2",
|
"version": "0.8.3",
|
||||||
"description": "请求库",
|
"description": "请求库",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"request",
|
"request",
|
||||||
|
Loading…
Reference in New Issue
Block a user