zmdms-webui 3.1.8 → 3.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/applayoutsider/menu/MainMenu.js +1 -1
- package/dist/es/applayoutsider/menu/SubMenu.js +8 -1
- package/dist/es/canvastable/canvasTable.js +1 -0
- package/dist/es/config/MyStorage.js +11 -5
- package/dist/es/config/ZtxkContext.d.ts +10 -0
- package/dist/es/config/ZtxkContext.js +2 -0
- package/dist/es/config/index.js +1 -0
- package/dist/es/config/utils.js +58 -1
- package/dist/es/dynamicsetting/dynamicDrawer.js +61 -19
- package/dist/es/dynamicsetting/dynamicSetting.js +4 -4
- package/dist/es/dynamicsetting/hooks.js +4 -4
- package/dist/es/dynamicsetting/index.css +1 -1
- package/dist/es/dynamicsetting/index.js +1 -0
- package/dist/es/dynamicsetting/interface.d.ts +5 -0
- package/dist/es/dynamicsetting/useDynamic.js +5 -1
- package/dist/es/dynamicsetting/useSearch.js +26 -6
- package/dist/es/dynamicsetting/useTemplate.d.ts +4 -0
- package/dist/es/dynamicsetting/useTemplate.js +428 -0
- package/dist/es/electronsignatures/content.js +974 -0
- package/dist/es/electronsignatures/dgcomponents/contract-comparison.js +2 -2
- package/dist/es/electronsignatures/dgcomponents/file-comparison-btn.js +136 -0
- package/dist/es/electronsignatures/dgcomponents/new-contract-comparison.js +54 -0
- package/dist/es/electronsignatures/dgcomponents/useContractColumns.js +110 -39
- package/dist/es/electronsignatures/electron-signatures-fragment.js +11 -3
- package/dist/es/electronsignatures/electroncomponents/electron-seal-batch-download.js +179 -67
- package/dist/es/electronsignatures/electroncomponents/electron-seal-detail.js +5 -5
- package/dist/es/electronsignatures/electroncomponents/electron-seal-item-detail.js +15 -0
- package/dist/es/electronsignatures/electroncomponents/electron-seal-item.js +9 -6
- package/dist/es/electronsignatures/electroncomponents/useElectronColumns.js +330 -154
- package/dist/es/electronsignatures/electroncomponents/useFetchElectronData.js +58 -9
- package/dist/es/electronsignatures/electroncomponents/utils.js +119 -28
- package/dist/es/electronsignatures/filecomponents/file-operation.js +6 -4
- package/dist/es/electronsignatures/filecomponents/new-file-operation.js +56 -0
- package/dist/es/electronsignatures/filecomponents/useFileColumns.js +179 -102
- package/dist/es/electronsignatures/hooks/useGetQjVerifyCode.js +134 -0
- package/dist/es/electronsignatures/hooks/useMergeRecords.js +4 -3
- package/dist/es/electronsignatures/hooks/useParseElectronSetting.js +5 -3
- package/dist/es/electronsignatures/hooks/useParseIsNeedElectronData.js +21 -2
- package/dist/es/electronsignatures/hooks/useParseQunjSingleData.js +6 -1
- package/dist/es/electronsignatures/hooks/useParseRecords.js +41 -34
- package/dist/es/electronsignatures/index.css +1 -1
- package/dist/es/electronsignatures/index.js +18 -833
- package/dist/es/electronsignatures/interface.d.ts +129 -5
- package/dist/es/electronsignatures/interface.js +9 -4
- package/dist/es/electronsignatures/qunjcomponents/qunj-check.js +2 -2
- package/dist/es/electronsignatures/qunjcomponents/qunj-detail.js +135 -14
- package/dist/es/electronsignatures/qunjcomponents/qunj-list.js +33 -13
- package/dist/es/electronsignatures/qunjcomponents/useFetchQunjData.js +8 -3
- package/dist/es/electronsignatures/qunjcomponents/useQunjColumns.js +202 -202
- package/dist/es/electronsignatures/translatecomponents/TranslateButton.js +27 -0
- package/dist/es/electronsignatures/translatecomponents/useTranslateCom.js +35 -0
- package/dist/es/form/common-search-list.js +28 -9
- package/dist/es/form/form.js +13 -11
- package/dist/es/form/useCommonSearch.js +3 -4
- package/dist/es/table/components/EnhanceBodyBasicCell.js +9 -0
- package/dist/es/table/components/useDragRef.js +6 -0
- package/dist/es/table/constant.js +4 -1
- package/dist/es/table/hooks/useCtrl.js +44 -0
- package/dist/es/table/hooks/useSelectSubtotal.js +376 -0
- package/dist/es/table/index.css +1 -1
- package/dist/es/table/interface.d.ts +2 -0
- package/dist/es/table/table.js +14 -2
- package/dist/index.build.d.ts +1 -0
- package/dist/index.dark.css +1 -1
- package/dist/index.default.css +1 -1
- package/dist/index.es.js +1 -0
- package/dist/less/components/DynamicSetting/style/index.less +38 -0
- package/dist/less/components/ElectronSignatures/style/index.less +37 -5
- package/dist/less/components/Table/style/index.less +32 -0
- package/package.json +2 -2
- package/dist/es/electronsignatures/electroncomponents/electron-seal-download.js +0 -74
package/dist/es/form/form.js
CHANGED
|
@@ -17,6 +17,7 @@ import CommonSearchList from './common-search-list.js';
|
|
|
17
17
|
import { COMMON_SEARCH_KEY, useCommonSearch, useCommonSearchModal } from './useCommonSearch.js';
|
|
18
18
|
import ButtonCom from '../button/button.js';
|
|
19
19
|
import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
|
|
20
|
+
import '../dynamicsetting/useTemplate.js';
|
|
20
21
|
|
|
21
22
|
var FORM_DYNAMIC_KEY = "ztxk-webui-dynamic-form";
|
|
22
23
|
var FormContext = createContext({});
|
|
@@ -36,11 +37,19 @@ var Form = function (props, ref) {
|
|
|
36
37
|
// (enableCommonSearch ? isCommonSearch !== false : !!isCommonSearch);
|
|
37
38
|
// 是否开启新的表单布局模式
|
|
38
39
|
var isNewFormLayoutEnabled = getFinalValue(enableNewFormLayout, isNewFormLayout);
|
|
40
|
+
// 获取新的items 如果传入了配置项的话,配置项优先
|
|
41
|
+
var configInfoItems = useFormPreferencesCreateNewItems(formPreferences, items).configInfoItems;
|
|
42
|
+
// 根据items 和 dynamicKey 获取到动态列配置信息
|
|
43
|
+
var _c = useDynamicListByItems(configInfoItems, {
|
|
44
|
+
dynamicKey: dynamicKey,
|
|
45
|
+
formPreferences: formPreferences,
|
|
46
|
+
dynamicVersion: dynamicVersion,
|
|
47
|
+
}), dynamicList = _c.dynamicList, currentDynamicList = _c.currentDynamicList, onCurrentListChange = _c.onCurrentListChange, newItems = _c.newItems, dynamicSettingRef = _c.dynamicSettingRef;
|
|
39
48
|
// 常用搜索hooks
|
|
40
|
-
var
|
|
49
|
+
var _d = useCommonSearch({
|
|
41
50
|
commonSearchKey: dynamicKey || window.location.pathname,
|
|
42
51
|
isCommonSearchEnabled: isCommonSearchEnabled,
|
|
43
|
-
}), commonSearchList =
|
|
52
|
+
}), commonSearchList = _d.commonSearchList, setCommonSearchList = _d.setCommonSearchList, currentCommonSearchKey = _d.currentCommonSearchKey, setCurrentCommonSearchKey = _d.setCurrentCommonSearchKey, setData = _d.setData, deleteData = _d.deleteData, setReplaceData = _d.setReplaceData, reTransformData = _d.reTransformData, updateServerData = _d.updateServerData;
|
|
44
53
|
var onCommonSearchHandle = useCommonSearchModal({
|
|
45
54
|
commonSearchList: commonSearchList,
|
|
46
55
|
currentCommonSearchKey: currentCommonSearchKey,
|
|
@@ -48,15 +57,8 @@ var Form = function (props, ref) {
|
|
|
48
57
|
setData: setData,
|
|
49
58
|
isCommonSearchEnabled: isCommonSearchEnabled,
|
|
50
59
|
setCurrentCommonSearchKey: setCurrentCommonSearchKey,
|
|
60
|
+
currentDynamicList: currentDynamicList,
|
|
51
61
|
}).onCommonSearchHandle;
|
|
52
|
-
// 获取新的items 如果传入了配置项的话,配置项优先
|
|
53
|
-
var configInfoItems = useFormPreferencesCreateNewItems(formPreferences, items).configInfoItems;
|
|
54
|
-
// 根据items 和 dynamicKey 获取到动态列配置信息
|
|
55
|
-
var _d = useDynamicListByItems(configInfoItems, {
|
|
56
|
-
dynamicKey: dynamicKey,
|
|
57
|
-
formPreferences: formPreferences,
|
|
58
|
-
dynamicVersion: dynamicVersion,
|
|
59
|
-
}), dynamicList = _d.dynamicList, onCurrentListChange = _d.onCurrentListChange, newItems = _d.newItems, dynamicSettingRef = _d.dynamicSettingRef;
|
|
60
62
|
// 主容器类名
|
|
61
63
|
var wrapClasses = classNames("ztxk-form", wrapClassName, {
|
|
62
64
|
"ztxk-form--bottom-border": bottomBorder,
|
|
@@ -192,7 +194,7 @@ var Form = function (props, ref) {
|
|
|
192
194
|
}) }, { children: [isNewFormLayoutEnabled && dynamicKey ? (jsx(ButtonCom, __assign({ type: "default", onClick: function () { var _a; return (_a = dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.setVisible(true); } }, { children: "\u81EA\u5B9A\u4E49" }))) : null, isCommonSearchEnabled ? (jsx(ButtonCom, __assign({ style: {
|
|
193
195
|
width: "100%",
|
|
194
196
|
marginLeft: isNewFormLayoutEnabled && dynamicKey ? 10 : 0,
|
|
195
|
-
}, onClick: onCommonSearchHandle }, { children: isNewFormLayoutEnabled ? "常用搜索" : "保存为常用搜索" }))) : null] }))) : null] }))) : null] })), isCommonSearchEnabled ? (jsx(CommonSearchList, { commonSearchList: commonSearchList, setCommonSearchList: setCommonSearchList, currentCommonSearchKey: currentCommonSearchKey, setCurrentCommonSearchKey: setCurrentCommonSearchKey, form: form, reTransformData: reTransformData, deleteData: deleteData, setReplaceData: setReplaceData, updateServerData: updateServerData, onSearchHandle: onSearchHandleInner })) : null] })));
|
|
197
|
+
}, onClick: onCommonSearchHandle }, { children: isNewFormLayoutEnabled ? "常用搜索" : "保存为常用搜索" }))) : null] }))) : null] }))) : null] })), isCommonSearchEnabled ? (jsx(CommonSearchList, { commonSearchList: commonSearchList, setCommonSearchList: setCommonSearchList, currentCommonSearchKey: currentCommonSearchKey, setCurrentCommonSearchKey: setCurrentCommonSearchKey, form: form, reTransformData: reTransformData, deleteData: deleteData, setReplaceData: setReplaceData, updateServerData: updateServerData, onSearchHandle: onSearchHandleInner, dynamicSettingRef: dynamicSettingRef, dynamicKey: dynamicKey })) : null] })));
|
|
196
198
|
};
|
|
197
199
|
var MemoForm = memo(forwardRef(Form));
|
|
198
200
|
MemoForm.displayName = "ZTXK_WEBUI_Form";
|
|
@@ -17,9 +17,7 @@ function useCommonSearch(options) {
|
|
|
17
17
|
var commonSearchKey = options.commonSearchKey, isCommonSearchEnabled = options.isCommonSearchEnabled;
|
|
18
18
|
var customConfigFetch = useBaseContext().customConfigFetch;
|
|
19
19
|
// 常用搜索列表存储实例
|
|
20
|
-
var storageRef = useRef(isCommonSearchEnabled
|
|
21
|
-
? new MyStorage({ tableKey: COMMON_SEARCH_KEY })
|
|
22
|
-
: null);
|
|
20
|
+
var storageRef = useRef(isCommonSearchEnabled ? new MyStorage({ name: COMMON_SEARCH_KEY }) : null);
|
|
23
21
|
// 常用搜索列表
|
|
24
22
|
var _a = useState([]), commonSearchList = _a[0], setCommonSearchList = _a[1];
|
|
25
23
|
// 当前选中的常用搜索key值
|
|
@@ -213,7 +211,7 @@ function useCommonSearch(options) {
|
|
|
213
211
|
};
|
|
214
212
|
}
|
|
215
213
|
function useCommonSearchModal(options) {
|
|
216
|
-
var commonSearchList = options.commonSearchList, currentCommonSearchKey = options.currentCommonSearchKey, form = options.form, setData = options.setData, isCommonSearchEnabled = options.isCommonSearchEnabled, setCurrentCommonSearchKey = options.setCurrentCommonSearchKey;
|
|
214
|
+
var commonSearchList = options.commonSearchList, currentCommonSearchKey = options.currentCommonSearchKey, form = options.form, setData = options.setData, isCommonSearchEnabled = options.isCommonSearchEnabled, setCurrentCommonSearchKey = options.setCurrentCommonSearchKey, currentDynamicList = options.currentDynamicList;
|
|
217
215
|
var iptRef = useRef(null);
|
|
218
216
|
useEffect(function () {
|
|
219
217
|
var _a;
|
|
@@ -260,6 +258,7 @@ function useCommonSearchModal(options) {
|
|
|
260
258
|
value: currentData,
|
|
261
259
|
// key: currentCommonSearchKey || Date.now(),
|
|
262
260
|
key: Date.now(),
|
|
261
|
+
dynamicList: currentDynamicList,
|
|
263
262
|
};
|
|
264
263
|
_c.label = 1;
|
|
265
264
|
case 1:
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { __rest, __assign } from '../../_virtual/_tslib.js';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
var EnhanceBodyBasicCell = function (props) {
|
|
5
|
+
props.onMouseEnter; props.onMouseLeave; var resetProps = __rest(props, ["onMouseEnter", "onMouseLeave"]);
|
|
6
|
+
return jsx("td", __assign({}, resetProps));
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export { EnhanceBodyBasicCell as default };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useRef } from 'react';
|
|
2
2
|
import { TABLE_DRAG_ROW_TYPE } from '../constant.js';
|
|
3
|
+
import useCtrl from '../hooks/useCtrl.js';
|
|
3
4
|
import { useDrop } from '../../node_modules/react-dnd/dist/hooks/useDrop/useDrop.js';
|
|
4
5
|
import { useDrag } from '../../node_modules/react-dnd/dist/hooks/useDrag/useDrag.js';
|
|
5
6
|
|
|
6
7
|
function useDragRef(index, moveRow) {
|
|
7
8
|
var ref = useRef(null);
|
|
9
|
+
var ctrlKeyPressedRef = useCtrl().ctrlKeyPressedRef;
|
|
8
10
|
// 定义放置项
|
|
9
11
|
var _a = useDrop(function () { return ({
|
|
10
12
|
accept: TABLE_DRAG_ROW_TYPE,
|
|
@@ -35,6 +37,10 @@ function useDragRef(index, moveRow) {
|
|
|
35
37
|
}); },
|
|
36
38
|
canDrag: function (monitor) {
|
|
37
39
|
var _a;
|
|
40
|
+
// 如果摁下了ctrl键 不可以拖拽行
|
|
41
|
+
if (ctrlKeyPressedRef.current) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
38
44
|
// 获取当前焦点元素
|
|
39
45
|
var activeElementType = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.tagName.toLowerCase();
|
|
40
46
|
// 检查当前活动元素是否是input, textarea, 或者其他您希望排除的元素类型
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
/** 表格动态配置的key值 */
|
|
1
2
|
var TABLE_DYNAMIC_KEY = "ztxk-webui-dynamic-table";
|
|
3
|
+
/** 表格动态配置的模板设置功能的表名 */
|
|
4
|
+
var TABLE_DYNAMIC_TEMPLATE_KEY = "ztxk-webui-template-setting__table";
|
|
2
5
|
var TABLE_DRAG_ROW_TYPE = Symbol("table-drag-row");
|
|
3
6
|
var INNER_TABLE_PAGINATION_POSITION = ["bottomLeft"];
|
|
4
7
|
var INNER_TABLE_PAGINATION_PAGESIZEOPTIONS = ["10", "20", "30", "40"];
|
|
@@ -12,4 +15,4 @@ var MERGE_INDEX = "__row_index";
|
|
|
12
15
|
// 合计行标识
|
|
13
16
|
var IS_SUMMARY = "__is_summary__";
|
|
14
17
|
|
|
15
|
-
export { ASCEND, DESCEND, ERROR_TD_CLASSNAME, INNER_TABLE_PAGINATION_PAGESIZEOPTIONS, INNER_TABLE_PAGINATION_POSITION, IS_SUMMARY, MERGE_INDEX, MERGE_KEY, MERGE_ROW_SPANS, TABLE_DRAG_ROW_TYPE, TABLE_DYNAMIC_KEY };
|
|
18
|
+
export { ASCEND, DESCEND, ERROR_TD_CLASSNAME, INNER_TABLE_PAGINATION_PAGESIZEOPTIONS, INNER_TABLE_PAGINATION_POSITION, IS_SUMMARY, MERGE_INDEX, MERGE_KEY, MERGE_ROW_SPANS, TABLE_DRAG_ROW_TYPE, TABLE_DYNAMIC_KEY, TABLE_DYNAMIC_TEMPLATE_KEY };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// ==================== 主 Hook ====================
|
|
4
|
+
/**
|
|
5
|
+
* 监听 Ctrl 键状态的 Hook
|
|
6
|
+
* 支持 Windows 的 Ctrl 键和 Mac 的 Command 键
|
|
7
|
+
* @returns Ctrl 键状态和相关方法
|
|
8
|
+
*/
|
|
9
|
+
function useCtrl() {
|
|
10
|
+
var ctrlKeyPressedRef = useRef(false);
|
|
11
|
+
/**
|
|
12
|
+
* 判断是否按下 Ctrl 键(Windows)或 Command 键(Mac)
|
|
13
|
+
* @param e 键盘或鼠标事件
|
|
14
|
+
* @returns 是否按下 Ctrl/Cmd 键
|
|
15
|
+
*/
|
|
16
|
+
var getCtrlKeyPressed = useCallback(function (e) {
|
|
17
|
+
return e.ctrlKey || e.metaKey;
|
|
18
|
+
}, []);
|
|
19
|
+
// 监听 Ctrl 键状态
|
|
20
|
+
useEffect(function () {
|
|
21
|
+
var handleKeyDown = function (e) {
|
|
22
|
+
if (getCtrlKeyPressed(e)) {
|
|
23
|
+
ctrlKeyPressedRef.current = true;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var handleKeyUp = function (e) {
|
|
27
|
+
if (!getCtrlKeyPressed(e)) {
|
|
28
|
+
ctrlKeyPressedRef.current = false;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
32
|
+
document.addEventListener("keyup", handleKeyUp);
|
|
33
|
+
return function () {
|
|
34
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
35
|
+
document.removeEventListener("keyup", handleKeyUp);
|
|
36
|
+
};
|
|
37
|
+
}, [getCtrlKeyPressed]);
|
|
38
|
+
return {
|
|
39
|
+
ctrlKeyPressedRef: ctrlKeyPressedRef,
|
|
40
|
+
getCtrlKeyPressed: getCtrlKeyPressed,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { useCtrl as default };
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
2
|
+
import { domFind, domParentsUntil } from '../../config/utils.js';
|
|
3
|
+
import { copyToClipboard, plus } from 'zmdms-utils';
|
|
4
|
+
import useCtrl from './useCtrl.js';
|
|
5
|
+
|
|
6
|
+
// ==================== 工具函数 ====================
|
|
7
|
+
/**
|
|
8
|
+
* 设置禁用框选
|
|
9
|
+
* @param disabled 是否禁用
|
|
10
|
+
*/
|
|
11
|
+
var setSelectDisabled = function (disabled) {
|
|
12
|
+
document.body.style.userSelect = disabled ? "none" : "text";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* 解析数值,支持千分符、金额符号、百分号等格式
|
|
16
|
+
* @param value 原始值
|
|
17
|
+
* @returns 解析后的数字
|
|
18
|
+
*/
|
|
19
|
+
function parseValue(value) {
|
|
20
|
+
// 移除千分符和金额符号,并替换逗号
|
|
21
|
+
value = value.replace(/[$,]/g, "").replace(/,/g, "");
|
|
22
|
+
// 如果是百分号,除以100并返回
|
|
23
|
+
if (value.endsWith("%")) {
|
|
24
|
+
return parseFloat(value) / 100;
|
|
25
|
+
}
|
|
26
|
+
// 尝试将字符串转换为数字,如果无法转换,则返回NaN
|
|
27
|
+
var parsedValue = parseFloat(value);
|
|
28
|
+
return isNaN(parsedValue) ? 0 : parsedValue;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 计算数组值的总和(支持分数格式)
|
|
32
|
+
* @param arr 字符串数组
|
|
33
|
+
* @returns 计算结果
|
|
34
|
+
*/
|
|
35
|
+
function sumArrayValues(arr) {
|
|
36
|
+
var sum = 0;
|
|
37
|
+
if (arr.find(function (item) { return item.indexOf("/"); })) {
|
|
38
|
+
var newArr = arr.map(function (item) {
|
|
39
|
+
var i = item.split("/");
|
|
40
|
+
return i.map(function (item) { return parseValue(item); });
|
|
41
|
+
});
|
|
42
|
+
var result = newArr.reduce(function (prev, current) {
|
|
43
|
+
var prevLen = prev.length;
|
|
44
|
+
var currentLen = current.length;
|
|
45
|
+
if (prevLen > currentLen) {
|
|
46
|
+
return prev.map(function (item, index) { return plus(current[index] || 0, item || 0); });
|
|
47
|
+
}
|
|
48
|
+
return current.map(function (item, index) { return plus(prev[index] || 0, item || 0); });
|
|
49
|
+
}, []);
|
|
50
|
+
return result.join("/");
|
|
51
|
+
}
|
|
52
|
+
for (var i = 0; i < arr.length; i++) {
|
|
53
|
+
var value = arr[i];
|
|
54
|
+
var parsedValue = parseValue(value);
|
|
55
|
+
sum = plus(sum, parsedValue);
|
|
56
|
+
}
|
|
57
|
+
return sum;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 判断传入的dom元素中的值
|
|
61
|
+
* 一种情况就是直接通过innerText获取
|
|
62
|
+
* 另外一种就是通过输入框获取
|
|
63
|
+
* @param td 表格单元格元素
|
|
64
|
+
* @returns 单元格中的文本值
|
|
65
|
+
*/
|
|
66
|
+
function getCellValue(td) {
|
|
67
|
+
var _a, _b, _c, _d;
|
|
68
|
+
if (!td) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
// 查找 antd Select 显示的值
|
|
73
|
+
var antdSelect = td.querySelector(".ant-select-selection-item");
|
|
74
|
+
if (antdSelect) {
|
|
75
|
+
return (_a = antdSelect.textContent) !== null && _a !== void 0 ? _a : "";
|
|
76
|
+
}
|
|
77
|
+
// 优先查找输入框元素的值
|
|
78
|
+
var inputElement = td.querySelector("input, textarea");
|
|
79
|
+
if (inputElement) {
|
|
80
|
+
return (_b = inputElement.value) !== null && _b !== void 0 ? _b : "";
|
|
81
|
+
}
|
|
82
|
+
// 查找带 contenteditable 属性的元素
|
|
83
|
+
var editableElement = td.querySelector('[contenteditable="true"]');
|
|
84
|
+
if (editableElement && editableElement.innerText !== undefined) {
|
|
85
|
+
return editableElement.innerText;
|
|
86
|
+
}
|
|
87
|
+
// 查找 antd 相关组件的输入值
|
|
88
|
+
var antdInput = td.querySelector(".ant-input, .ant-input-number-input");
|
|
89
|
+
if (antdInput) {
|
|
90
|
+
if ("value" in antdInput) {
|
|
91
|
+
return (_c = antdInput.value) !== null && _c !== void 0 ? _c : "";
|
|
92
|
+
}
|
|
93
|
+
return (_d = antdInput.textContent) !== null && _d !== void 0 ? _d : "";
|
|
94
|
+
}
|
|
95
|
+
// 默认通过 innerText 获取
|
|
96
|
+
var innerText = td.innerText;
|
|
97
|
+
if (innerText !== undefined && innerText !== null) {
|
|
98
|
+
// 去除 "复制" 等后缀文字
|
|
99
|
+
return innerText.replace(/\s+复制/g, "").trim();
|
|
100
|
+
}
|
|
101
|
+
return "";
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error("获取单元格值失败", error);
|
|
105
|
+
return "";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// ==================== 主 Hook ====================
|
|
109
|
+
/**
|
|
110
|
+
* 表格小计选择 Hook
|
|
111
|
+
* 支持框选单元格并计算总和,支持 Ctrl 多选
|
|
112
|
+
* @param tableRef 表格容器引用
|
|
113
|
+
* @param props 配置项
|
|
114
|
+
* @returns 提示元素引用
|
|
115
|
+
*/
|
|
116
|
+
function useSelectSubtotal(tableRef, props) {
|
|
117
|
+
var isMove = props.isMove, isEdit = props.isEdit, scroll = props.scroll;
|
|
118
|
+
var tipRef = useRef(null);
|
|
119
|
+
var rowResultRef = useRef([]);
|
|
120
|
+
var getCtrlKeyPressed = useCtrl().getCtrlKeyPressed;
|
|
121
|
+
/**
|
|
122
|
+
* 找到每个单元格实际对应的坐标
|
|
123
|
+
* 处理行列合并的情况
|
|
124
|
+
*/
|
|
125
|
+
var cellPosition = useCallback(function (container) {
|
|
126
|
+
console.time("计算单元格位置耗时");
|
|
127
|
+
var rowsLen = container.rows.length;
|
|
128
|
+
// 取第一行第一列数据出来。计算得到最长的列数
|
|
129
|
+
var firstRowCells = container.rows[0].cells;
|
|
130
|
+
// 因为antd表格的第一行 就有最长列。
|
|
131
|
+
var firstRowCellsLen = firstRowCells.length;
|
|
132
|
+
// 创建一个数组,记录下对当前行的影响(因为可能之前的行有行合并,会导致后面的行中有列不显示)
|
|
133
|
+
var effectRowCells = new Array(firstRowCellsLen).fill(0);
|
|
134
|
+
// 记录遍历结果(二维数组,记录行列信息)
|
|
135
|
+
var rowResult = [];
|
|
136
|
+
// 遍历每一行
|
|
137
|
+
for (var i = 1; i < rowsLen; i++) {
|
|
138
|
+
var row = container.rows[i]; // 当前行
|
|
139
|
+
var cellResult = [];
|
|
140
|
+
// 记录当前行跳过的列数
|
|
141
|
+
var jumpCells = 0;
|
|
142
|
+
// 记录横向扩展(列合并)影响的元素
|
|
143
|
+
var effectCols = 0;
|
|
144
|
+
// 遍历每一个单元格
|
|
145
|
+
for (var j = 0; j < firstRowCellsLen; j++) {
|
|
146
|
+
var effectRowCellItem = effectRowCells[j];
|
|
147
|
+
// 左侧的列存在列合并,影响到了当前列
|
|
148
|
+
if (effectCols > 0) {
|
|
149
|
+
cellResult.push({ td: null, rowIndex: i, cellIndex: j });
|
|
150
|
+
effectCols--;
|
|
151
|
+
jumpCells++;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
// 如果当前位置的在之前的行列的影响范围内,说明这一列的数据是空的。
|
|
155
|
+
if (effectRowCellItem > 0) {
|
|
156
|
+
cellResult.push({ td: null, rowIndex: i, cellIndex: j });
|
|
157
|
+
effectRowCells[j]--;
|
|
158
|
+
jumpCells++;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// 这里获取实际的单元格时,需要减去跳过的列数
|
|
162
|
+
var cell = row.cells[j - jumpCells];
|
|
163
|
+
if (!cell || !(cell === null || cell === void 0 ? void 0 : cell.rowSpan) || !(cell === null || cell === void 0 ? void 0 : cell.colSpan)) {
|
|
164
|
+
cellResult.push({ td: null, rowIndex: i, cellIndex: j });
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
var colSpan = (cell === null || cell === void 0 ? void 0 : cell.colSpan) - 0;
|
|
168
|
+
var rowSpan = (cell === null || cell === void 0 ? void 0 : cell.rowSpan) - 0;
|
|
169
|
+
if (colSpan > 1) {
|
|
170
|
+
effectCols += colSpan - 1;
|
|
171
|
+
}
|
|
172
|
+
if (rowSpan > 1) {
|
|
173
|
+
effectRowCells[j] += rowSpan - 1;
|
|
174
|
+
}
|
|
175
|
+
// 如果行列合并都存在的话。那么列合并会影响到合并的行数据
|
|
176
|
+
if (colSpan > 1 && rowSpan > 1) {
|
|
177
|
+
for (var k = 1; k < colSpan; k++) {
|
|
178
|
+
effectRowCells[j + k] += rowSpan - 1;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
cellResult.push({ td: cell, rowIndex: i, cellIndex: j });
|
|
182
|
+
}
|
|
183
|
+
rowResult.push(cellResult);
|
|
184
|
+
}
|
|
185
|
+
console.timeEnd("计算单元格位置耗时");
|
|
186
|
+
return rowResult;
|
|
187
|
+
}, []);
|
|
188
|
+
useEffect(function () {
|
|
189
|
+
var tableContent = domFind(tableRef.current, ".ant-table-content");
|
|
190
|
+
if (!tableContent) {
|
|
191
|
+
tableContent = domFind(tableRef.current, ".ant-table-container");
|
|
192
|
+
}
|
|
193
|
+
var tbody = domFind(tableContent, ".ant-table-tbody");
|
|
194
|
+
var container = tbody === null || tbody === void 0 ? void 0 : tbody.parentNode;
|
|
195
|
+
var $tip = tipRef.current;
|
|
196
|
+
var isDragging = false;
|
|
197
|
+
var startCell = null; // 开始选中的项
|
|
198
|
+
var lastEndCell = null; // 最终选中的项
|
|
199
|
+
var textArr = []; // 选中的文本
|
|
200
|
+
var textPositionArr = []; // 包含位置信息
|
|
201
|
+
if (!container) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
var mousedownHandler = function (e) {
|
|
205
|
+
// 当编辑模式时,需要摁下ctrl键才可以复制。
|
|
206
|
+
if ((isMove || isEdit) && !getCtrlKeyPressed(e)) {
|
|
207
|
+
clearSelections(); // 清除之前的选择
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
// 摁住ctrl键时,去掉body的默认行为。
|
|
211
|
+
if (getCtrlKeyPressed(e)) {
|
|
212
|
+
setSelectDisabled(true);
|
|
213
|
+
}
|
|
214
|
+
// 这里回导致复制内容失败
|
|
215
|
+
// setSelectDisabled(true);
|
|
216
|
+
// 这里要判断如果最上层是TD也行
|
|
217
|
+
var target = e.target.tagName === "TD"
|
|
218
|
+
? e.target
|
|
219
|
+
: domParentsUntil(e.target, "td");
|
|
220
|
+
if ((target === null || target === void 0 ? void 0 : target.tagName) === "TD") {
|
|
221
|
+
isDragging = true;
|
|
222
|
+
startCell = target;
|
|
223
|
+
// 是否按下ctrl键 可以选取多段内容
|
|
224
|
+
if (!getCtrlKeyPressed(e)) {
|
|
225
|
+
clearSelections();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
container.addEventListener("mousedown", mousedownHandler);
|
|
230
|
+
var mouseupHandler = function (e) {
|
|
231
|
+
setSelectDisabled(false);
|
|
232
|
+
isDragging = false;
|
|
233
|
+
startCell = null;
|
|
234
|
+
lastEndCell = null;
|
|
235
|
+
if (textArr.length && $tip && tableContent) {
|
|
236
|
+
var contaienrRect = tableContent.getBoundingClientRect();
|
|
237
|
+
var result = sumArrayValues(textArr);
|
|
238
|
+
var maxLeft = contaienrRect.width;
|
|
239
|
+
var maxTop = contaienrRect.height;
|
|
240
|
+
var top_1 = 0, left = 0;
|
|
241
|
+
if (e.target) {
|
|
242
|
+
$tip.innerText = "\u5C0F\u8BA1\uFF1A ".concat(result, " \u5DF2\u9009\uFF1A").concat(textArr.length, "\u9879");
|
|
243
|
+
top_1 = e.clientY - contaienrRect.top;
|
|
244
|
+
left = e.clientX - contaienrRect.left;
|
|
245
|
+
var tipRect = $tip.getBoundingClientRect();
|
|
246
|
+
if (top_1 + tipRect.height >= maxTop) {
|
|
247
|
+
top_1 = top_1 - tipRect.height;
|
|
248
|
+
}
|
|
249
|
+
if (left + tipRect.width >= maxLeft) {
|
|
250
|
+
left = left - tipRect.width;
|
|
251
|
+
}
|
|
252
|
+
$tip.style.top = "".concat(top_1, "px");
|
|
253
|
+
$tip.style.left = "".concat(left, "px");
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// 是否按下ctrl键
|
|
257
|
+
if (!getCtrlKeyPressed(e)) {
|
|
258
|
+
container.classList.remove("ztxk-table--select-none");
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
container.addEventListener("mouseup", mouseupHandler);
|
|
262
|
+
var mousemoveHandler = function (e) {
|
|
263
|
+
if (isDragging && e.target.tagName === "TD") {
|
|
264
|
+
if (lastEndCell !== e.target) {
|
|
265
|
+
lastEndCell = e.target;
|
|
266
|
+
if (startCell !== lastEndCell) {
|
|
267
|
+
container.classList.add("ztxk-table--select-none");
|
|
268
|
+
var isCtrl = getCtrlKeyPressed(e);
|
|
269
|
+
selectCells(startCell, lastEndCell, isCtrl); // 仅在必要时更新选择
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
container.addEventListener("mousemove", mousemoveHandler);
|
|
275
|
+
var selectCells = function (start, end, isCtrl) {
|
|
276
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
277
|
+
if (!isCtrl) {
|
|
278
|
+
clearSelections(); // 清除之前的选择
|
|
279
|
+
}
|
|
280
|
+
if (!start || !end)
|
|
281
|
+
return;
|
|
282
|
+
rowResultRef.current = cellPosition(container);
|
|
283
|
+
var rowResult = rowResultRef.current;
|
|
284
|
+
var startRow = start.parentNode.rowIndex;
|
|
285
|
+
var startCol = start.cellIndex;
|
|
286
|
+
var endRow = end.parentNode.rowIndex;
|
|
287
|
+
var endCol = end.cellIndex;
|
|
288
|
+
var startCell = (_b = (_a = rowResult[startRow - 1]) === null || _a === void 0 ? void 0 : _a.find) === null || _b === void 0 ? void 0 : _b.call(_a, function (item) {
|
|
289
|
+
return item.td === start;
|
|
290
|
+
});
|
|
291
|
+
if (startCell) {
|
|
292
|
+
startCol = startCell.cellIndex;
|
|
293
|
+
}
|
|
294
|
+
var endCell = (_d = (_c = rowResult[endRow - 1]) === null || _c === void 0 ? void 0 : _c.find) === null || _d === void 0 ? void 0 : _d.call(_c, function (item) {
|
|
295
|
+
return item.td === end;
|
|
296
|
+
});
|
|
297
|
+
if (endCell) {
|
|
298
|
+
endCol = endCell.cellIndex;
|
|
299
|
+
}
|
|
300
|
+
var initRow = Math.min(startRow, endRow);
|
|
301
|
+
var lenRow = Math.max(startRow, endRow);
|
|
302
|
+
var initCell = Math.min(startCol, endCol);
|
|
303
|
+
var lenCell = Math.max(startCol, endCol);
|
|
304
|
+
// 标记当前选择区域的单元格为选中状态
|
|
305
|
+
for (var i = initRow; i <= lenRow; i++) {
|
|
306
|
+
for (var j = initCell; j <= lenCell; j++) {
|
|
307
|
+
var $td = (_f = (_e = rowResult[i - 1]) === null || _e === void 0 ? void 0 : _e[j]) === null || _f === void 0 ? void 0 : _f.td;
|
|
308
|
+
(_g = $td === null || $td === void 0 ? void 0 : $td.classList) === null || _g === void 0 ? void 0 : _g.add("move-selected");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// 重新构建 textArr 和 textPositionArr(基于所有已选中的单元格)
|
|
312
|
+
textArr = [];
|
|
313
|
+
textPositionArr = [];
|
|
314
|
+
// 遍历所有单元格,按行组织已选中的单元格
|
|
315
|
+
var rowsCount = rowResult.length;
|
|
316
|
+
var colsCount = ((_h = rowResult[0]) === null || _h === void 0 ? void 0 : _h.length) || 0;
|
|
317
|
+
for (var i = 0; i < rowsCount; i++) {
|
|
318
|
+
var rowPositionArr = [];
|
|
319
|
+
for (var j = 0; j < colsCount; j++) {
|
|
320
|
+
var $td = (_k = (_j = rowResult[i]) === null || _j === void 0 ? void 0 : _j[j]) === null || _k === void 0 ? void 0 : _k.td;
|
|
321
|
+
if ($td && $td.classList.contains("move-selected")) {
|
|
322
|
+
var innerText = getCellValue($td);
|
|
323
|
+
textArr.push(innerText);
|
|
324
|
+
rowPositionArr.push(innerText);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (rowPositionArr.length > 0) {
|
|
328
|
+
textPositionArr.push(rowPositionArr);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
var clearSelections = function () {
|
|
333
|
+
textArr = [];
|
|
334
|
+
textPositionArr = [];
|
|
335
|
+
if ($tip) {
|
|
336
|
+
$tip.innerText = "";
|
|
337
|
+
$tip.style.top = "-1000px";
|
|
338
|
+
$tip.style.left = "-1000px";
|
|
339
|
+
}
|
|
340
|
+
var selectedCells = container.querySelectorAll(".move-selected");
|
|
341
|
+
selectedCells.forEach(function (cell) { return cell.classList.remove("move-selected"); });
|
|
342
|
+
};
|
|
343
|
+
var keydownHandle = function (event) {
|
|
344
|
+
// 检查按下的键是否是C键
|
|
345
|
+
var isCKey = event.key === "c" || event.key === "C";
|
|
346
|
+
// 检查是否按下了Ctrl键(在Windows中)或Cmd键(在Mac中)
|
|
347
|
+
var isCtrlPressed = event.ctrlKey || event.metaKey;
|
|
348
|
+
// 如果同时按下了Ctrl/Cmd键和C键,则执行你的复制操作
|
|
349
|
+
if (isCtrlPressed && isCKey && textPositionArr.length > 0) {
|
|
350
|
+
console.log("复制文本textPositionArr", textPositionArr);
|
|
351
|
+
// 执行你的复制操作,例如将文本添加到剪贴板
|
|
352
|
+
var textToCopy = textPositionArr
|
|
353
|
+
.map(function (row) { return row.join("\t"); })
|
|
354
|
+
.join("\n");
|
|
355
|
+
copyToClipboard(textToCopy);
|
|
356
|
+
// 阻止浏览器默认的复制操作
|
|
357
|
+
event.preventDefault();
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
document.addEventListener("keydown", keydownHandle);
|
|
361
|
+
return function () {
|
|
362
|
+
if (container) {
|
|
363
|
+
container.removeEventListener("mousedown", mousedownHandler);
|
|
364
|
+
container.removeEventListener("mouseup", mouseupHandler);
|
|
365
|
+
container.removeEventListener("mousemove", mousemoveHandler);
|
|
366
|
+
}
|
|
367
|
+
document.removeEventListener("keydown", keydownHandle);
|
|
368
|
+
};
|
|
369
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
370
|
+
}, [scroll === null || scroll === void 0 ? void 0 : scroll.x, scroll === null || scroll === void 0 ? void 0 : scroll.y]);
|
|
371
|
+
return {
|
|
372
|
+
tipRef: tipRef,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export { useSelectSubtotal as default };
|