vap1 0.4.4 → 0.4.5

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.
@@ -1,5 +1,5 @@
1
1
  import { useBox } from './Box';
2
- import { ForwardRefExoticComponent, PropsWithChildren, RefAttributes } from 'react';
2
+ import type { ForwardRefExoticComponent, PropsWithChildren, RefAttributes } from 'react';
3
3
  import type { BoxProps } from './Box';
4
4
  export type BoxComponent = ForwardRefExoticComponent<PropsWithChildren<BoxProps> & RefAttributes<{
5
5
  resize: () => void;
@@ -1,5 +1,5 @@
1
- import type { FC, CSSProperties, ReactNode } from 'react';
2
1
  import type { PlainObject, Key } from '../../basetype';
2
+ import type { FC, ReactNode, CSSProperties } from 'react';
3
3
  import type { IconProps } from '../_adapt/Icon';
4
4
  type ItemRenderFunction = (record: PlainObject, searchValue?: string) => ReactNode;
5
5
  export type SListProps = {
@@ -55,6 +55,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
55
55
  Object.defineProperty(exports, "__esModule", { value: true });
56
56
  exports.SList = void 0;
57
57
  var react_1 = __importStar(require("react"));
58
+ var py_1 = require("../../utils/py");
58
59
  var lodash_1 = __importDefault(require("lodash"));
59
60
  var utils_1 = require("../../utils");
60
61
  var Icon_1 = require("../_adapt/Icon");
@@ -131,8 +132,8 @@ exports.SList = (0, react_1.memo)(function (props) {
131
132
  return;
132
133
  }
133
134
  setList(lodash_1.default.filter(all, function (item) {
134
- var title = lodash_1.default.toLower(item[props.titleField]);
135
- return title.indexOf(searchValue) >= 0;
135
+ var hited = (0, py_1.spellHit)(item[props.titleField], searchValue);
136
+ return hited.length > 0;
136
137
  }));
137
138
  }, [searchValue, props.list]);
138
139
  (0, react_1.useLayoutEffect)(function () {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { ListInit } from '../../hooks/_list';
3
2
  import type { VTableProps, VTableRef } from './VTable';
3
+ import type { ListInit } from '../../hooks/_list';
4
4
  export type STableProps = Omit<VTableProps, 'model'> & ListInit & {
5
5
  /**
6
6
  * 说明 pageSize : 默认为 false : 不分页。
@@ -149,7 +149,6 @@ var TopTable = function (props) {
149
149
  }
150
150
  }); };
151
151
  }
152
- console.log(scroll);
153
152
  return react_1.default.createElement("div", { ref: tableRef, className: 'c-table-top-container' },
154
153
  react_1.default.createElement(Table_1.Table, __assign({}, tableProps, props, { rowClassName: function (record, i) {
155
154
  var clazz = [];
@@ -37,9 +37,12 @@ export declare const useActionTree: () => ActionTreeContext;
37
37
  export declare const ActionTree: React.ForwardRefExoticComponent<import("../../utils/TreeUtil").BaseTreeOpts & Pick<import("antd/es/tree/Tree").TreeProps, "className" | "disabled" | "defaultExpandAll"> & {
38
38
  iconField?: string | ((item: any) => React.ReactNode);
39
39
  titleField: string | import("./index").LanguageField;
40
+ titleRender?: (node: PlainObject) => React.ReactNode;
40
41
  mustSelect?: boolean;
41
42
  disabledNode?: (node: PlainObject) => boolean;
42
- onSelect?: (key: Key, node: PlainObject, parentNode: PlainObject, crumb: PlainObject[], pos: number[]) => void;
43
+ onSelect?: (key: Key, node: PlainObject, parentNode: PlainObject, crumb: PlainObject[], pos: number[]) => void; /**
44
+ * 获取子节点方法
45
+ */
43
46
  searchValue?: string;
44
47
  } & BaseActionTreeProps & CacheTree & React.RefAttributes<ActionTreeRef>>;
45
48
  export declare const renderRoot: (props: ActionTreeProps, state: BaseTreeState, context: ActionTreeContext) => ReactNode;
@@ -11,6 +11,7 @@ export type BaseTreeState = Required<BaseTreeOpts> & {
11
11
  selectedKeys: string[];
12
12
  selectedNode: PlainObject;
13
13
  titleField: string;
14
+ titleRender?: (item: any) => ReactNode;
14
15
  iconField: string | ((item: any) => ReactNode);
15
16
  inited: boolean;
16
17
  langs: {
@@ -99,6 +99,7 @@ var BaseTree = function (props) {
99
99
  rootCode: '0',
100
100
  search: { word: null, keyword: null, match: null },
101
101
  titleField: 'name',
102
+ titleRender: null,
102
103
  keyField: 'id',
103
104
  iconField: null,
104
105
  sortField: null,
@@ -145,6 +146,9 @@ var BaseTree = function (props) {
145
146
  DEFAULT.langs = langs;
146
147
  }
147
148
  }
149
+ if (props.titleRender && lodash_1.default.isFunction(props.titleRender)) {
150
+ DEFAULT.titleRender = props.titleRender;
151
+ }
148
152
  var _a = __read((0, hooks_1.useSetState)(DEFAULT), 2), state = _a[0], setState = _a[1];
149
153
  var PID = (0, react_1.useRef)(null);
150
154
  var searchByKeyWord = (0, react_1.useCallback)(function (word) {
@@ -203,13 +207,18 @@ var BaseTree = function (props) {
203
207
  };
204
208
  exports.BaseTree = BaseTree;
205
209
  var getNodeParam = function (node, position, state, search, disabledNode, folderChecker) {
206
- var titleField = state.titleField, keyField = state.keyField, iconField = state.iconField;
210
+ var titleField = state.titleField, keyField = state.keyField, iconField = state.iconField, titleRender = state.titleRender;
207
211
  var param = { key: node[keyField], data: { node: node, position: position } };
208
212
  if (search.keyword) {
209
213
  param.title = react_1.default.createElement(HighLight_1.HighLight, { keyword: search.keyword, text: node[titleField] });
210
214
  }
211
215
  else {
212
- param.title = node[titleField];
216
+ if (titleRender) {
217
+ param.title = titleRender(node);
218
+ }
219
+ else {
220
+ param.title = node[titleField];
221
+ }
213
222
  }
214
223
  if (lodash_1.default.isFunction(disabledNode)) {
215
224
  if (disabledNode(node)) {
@@ -42,6 +42,7 @@ export declare const DTree: React.MemoExoticComponent<React.ForwardRefExoticComp
42
42
  * 方式二:传一个方法 ,接收一个父节点参数,必须返回 Promise<TreeNodeData[]> (不要返回 children, 仅返回一级)
43
43
  */
44
44
  titleField: string | import("./index").LanguageField;
45
+ titleRender?: (node: PlainObject) => React.ReactNode;
45
46
  mustSelect?: boolean;
46
47
  disabledNode?: (node: PlainObject) => boolean;
47
48
  onSelect?: (key: Key, node: PlainObject, parentNode: PlainObject, crumb: PlainObject[], pos: number[]) => void;
@@ -18,6 +18,7 @@ export type FTreeProps = BaseTreeProps & BaseActionTreeProps & FTreeData;
18
18
  export declare const FTree: React.MemoExoticComponent<React.ForwardRefExoticComponent<TreeUtil.BaseTreeOpts & Pick<TreeProps, "className" | "disabled" | "defaultExpandAll"> & {
19
19
  iconField?: string | ((item: any) => React.ReactNode);
20
20
  titleField: string | import("./index").LanguageField;
21
+ titleRender?: (node: import("../..").PlainObject) => React.ReactNode;
21
22
  mustSelect?: boolean;
22
23
  disabledNode?: (node: import("../..").PlainObject) => boolean;
23
24
  onSelect?: (key: import("../..").Key, node: import("../..").PlainObject, parentNode: import("../..").PlainObject, crumb: import("../..").PlainObject[], pos: number[]) => void;
@@ -36,6 +36,10 @@ export type BaseTreeProps = BaseTreeOpts & Pick<TreeProps, 'className' | 'defaul
36
36
  * 如果需要支持 i18n ,则传一个对象,支持3个字段
37
37
  */
38
38
  titleField: string | LanguageField;
39
+ /**
40
+ * 自定义标题
41
+ */
42
+ titleRender?: (node: PlainObject) => ReactNode;
39
43
  /**
40
44
  * 是否必选,
41
45
  */
@@ -1,4 +1,4 @@
1
- import type { ComponentType, ReactNode } from 'react';
1
+ import type { ReactNode, ComponentType } from 'react';
2
2
  import type { BaseOption, PlainObject } from '../../basetype';
3
3
  import type { UFormField } from './index';
4
4
  import type { ValidationRule, WrappedFormUtils } from 'antd/es/form/Form';
@@ -48,6 +48,6 @@ var StringUtil_1 = require("../../utils/StringUtil");
48
48
  var HighLight = function (props) {
49
49
  var _a = __read((0, react_1.useState)([]), 2), ptns = _a[0], setPtns = _a[1];
50
50
  (0, react_1.useLayoutEffect)(function () { return setPtns((0, StringUtil_1.searchText)(props.text, props.keyword)); }, [props]);
51
- return react_1.default.createElement(react_1.Fragment, null, ptns.map(function (ptn) { return ptn.hit ? react_1.default.createElement("span", { className: 'v-highlight' }, ptn.text) : ptn.text; }));
51
+ return ptns.map(function (ptn) { return ptn.hit ? react_1.default.createElement("span", { className: 'v-highlight' }, ptn.text) : ptn.text; });
52
52
  };
53
53
  exports.HighLight = HighLight;
@@ -33,8 +33,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
33
33
  exports.useApiGlobal = void 0;
34
34
  var lodash_1 = __importDefault(require("lodash"));
35
35
  var react_1 = require("react");
36
- var useGlobal_1 = require("./useGlobal");
37
36
  var _list_1 = require("./_list");
37
+ var useGlobal_1 = require("./useGlobal");
38
38
  var useApiBase_1 = require("./useApiBase");
39
39
  var toKey = function (pathname, hash) {
40
40
  var root = lodash_1.default.toLower(lodash_1.default.trim(pathname));
@@ -1,8 +1,10 @@
1
- import { DependencyList } from 'react';
1
+ import type { DependencyList } from 'react';
2
+ type EffectFn = () => void | (Promise<void>);
2
3
  /**
3
4
  * 简写 useEffect 用于方法执行,
4
5
  * 支持异步方法
5
6
  * 不支持 Return (unmount),
6
7
  * 默认没有 deps
7
8
  */
8
- export declare const useEffectFunction: (fn: Function, deps?: DependencyList) => void;
9
+ export declare const useEffectFunction: (fn: EffectFn, deps?: DependencyList) => void;
10
+ export {};
@@ -1,4 +1,4 @@
1
- import { Dispatch } from 'react';
1
+ import type { Dispatch } from 'react';
2
2
  type IHookStateInitialSetter<S> = () => S;
3
3
  type IHookStateInitAction<S> = S | IHookStateInitialSetter<S>;
4
4
  type IHookStateSetter<S> = ((prevState: S) => S) | (() => S);
@@ -1,4 +1,4 @@
1
- import { Dispatch, SetStateAction } from 'react';
1
+ import type { Dispatch, SetStateAction } from 'react';
2
2
  export type UseGStateOptions = {
3
3
  /**
4
4
  * 共享此模型, 默认不共享,说明 :
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"vap1","version":"0.4.4","description":"vap1, Both support MicroService and SAP FrameWork, Support IE>9","main":"index.js","author":"Xiang da","license":"ISC"}
1
+ {"name":"vap1","version":"0.4.5","description":"vap1, Both support MicroService and SAP FrameWork, Support IE>9","main":"index.js","author":"Xiang da","license":"ISC"}
package/screen/Page.js CHANGED
@@ -26,9 +26,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Page = void 0;
27
27
  var react_1 = __importStar(require("react"));
28
28
  var antd_1 = require("antd");
29
+ var utils_1 = require("../utils");
29
30
  // @ts-ignore : 全局
30
31
  var zh_CN = antd.locales.zh_CN;
31
32
  antd_1.Empty.defaultProps = { image: '/images/empty-insight.png' };
33
+ utils_1.Ajax.SESSION(utils_1.GLOBAL.CONFIG.BASIC.DICT);
32
34
  var resize = function () {
33
35
  var diff = 0.1;
34
36
  // const min: number = 0.1, max: number = 0.1;
@@ -63,9 +65,7 @@ var Page = function (props) {
63
65
  }
64
66
  window.addEventListener('resize', resize, false);
65
67
  resize();
66
- return function () {
67
- window.removeEventListener('resize', resize);
68
- };
68
+ return function () { return window.removeEventListener('resize', resize); };
69
69
  }, []);
70
70
  return react_1.default.createElement(antd_1.ConfigProvider, { locale: zh_CN,
71
71
  // autoInsertSpaceInButton={false}
@@ -169,8 +169,8 @@ export type CustomAppOptions = {
169
169
  */
170
170
  enableRule?: boolean;
171
171
  /**
172
- * 是否初始化字典,默认 true
173
- * 开启后可正常使用 Renders.DictRender
172
+ * @deprecated
173
+ * 不再有效,后续为智能引用
174
174
  */
175
175
  enableDict?: boolean;
176
176
  /**
package/utils/Global.d.ts CHANGED
@@ -30,6 +30,11 @@ export type GlobalSetting = {
30
30
  * 当项目接口不是很标准时,可以设置为false ,将会显示 抽象原因,如:添加失败,修改失败等。
31
31
  */
32
32
  TIP_ERROR: boolean;
33
+ /**
34
+ * 注册汉语拼音
35
+ * 注册后,各种 search value 支持拼音搜索
36
+ */
37
+ PY: Map<string, string>;
33
38
  };
34
39
  /**
35
40
  * 基础API设置,
package/utils/Global.js CHANGED
@@ -22,6 +22,7 @@ var DEFAULT = {
22
22
  LANG: _Support_1.Language.ZH_CN,
23
23
  USER_MENU_HOMEPAGE: true,
24
24
  TIP_ERROR: true,
25
+ PY: null,
25
26
  },
26
27
  BASIC: {
27
28
  PREFIX: '/api-common',
@@ -1,5 +1,5 @@
1
1
  import type { Render, BaseRenderOptions, OptionConvertConfig } from './_define';
2
- import type { BaseOption, PlainObject } from '../../basetype';
2
+ import type { BaseOption } from '../../basetype';
3
3
  declare const DICT_FORMATS: readonly ["tag", "color", "status", "sup", "sub", "icon", "badge", "progress", "tip", "clazz"];
4
4
  type DictFormat = typeof DICT_FORMATS[number];
5
5
  type DictRenderOptions = Omit<BaseRenderOptions, 'len' | 'format'> & {
@@ -13,6 +13,7 @@ type DictInfo = {
13
13
  type GlobalDict = {
14
14
  DICTS: BaseOption[];
15
15
  DICT_MAP: Map<string, DictInfo>;
16
+ loaded: boolean;
16
17
  };
17
18
  declare const _V_DICT: GlobalDict;
18
19
  interface DictRender extends Render {
@@ -22,8 +23,4 @@ interface DictRender extends Render {
22
23
  options: (config?: OptionConvertConfig) => BaseOption[];
23
24
  }
24
25
  export declare const DictRender: (options: string | DictRenderOptions) => DictRender;
25
- /**
26
- * 初始化字典,将字典接口的响应数组传入
27
- */
28
- export declare const initDict: (dict: PlainObject[]) => void;
29
26
  export { _V_DICT as DICT };
@@ -30,22 +30,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
30
  return (mod && mod.__esModule) ? mod : { "default": mod };
31
31
  };
32
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.DICT = exports.initDict = exports.DictRender = void 0;
33
+ exports.DICT = exports.DictRender = void 0;
34
34
  var react_1 = __importDefault(require("react"));
35
35
  var lodash_1 = __importDefault(require("lodash"));
36
36
  var index_1 = require("../index");
37
37
  var _i18n_1 = require("../../components/_i18n");
38
38
  var _Support_1 = require("../_Support");
39
+ var _AjaxUtil_1 = require("../_AjaxUtil");
40
+ var XHR_1 = require("../XHR");
39
41
  var Const_1 = require("../Const");
40
42
  var _DictBaseRender_1 = require("./_DictBaseRender");
41
43
  var DICT_FORMATS = ['tag', 'color', 'status', 'sup', 'sub', 'icon', 'badge', 'progress', 'tip', 'clazz'];
42
44
  ;
43
45
  var VALIDATE_FORMAT = new Set(DICT_FORMATS);
44
- var _V_DICT = (0, _Support_1.globalDefault)('_V_DICT', { DICTS: [], DICT_MAP: new Map() });
46
+ var _V_DICT = (0, _Support_1.globalDefault)('_V_DICT', { DICTS: [], DICT_MAP: new Map(), loaded: false });
45
47
  exports.DICT = _V_DICT;
46
- var DICT = _V_DICT.DICT_MAP;
47
48
  var _DictRender = function (props) {
48
- var root = DICT.get(props.dictType);
49
+ var root = _V_DICT.DICT_MAP.get(props.dictType);
49
50
  if (root == null)
50
51
  return props.default || Const_1.NONE; // 没有字典
51
52
  var idx = lodash_1.default.findIndex(root.nodes, function (item) { return (props.value + '') == item.value; });
@@ -106,10 +107,16 @@ var putOptions = function (arr, config) {
106
107
  return list;
107
108
  };
108
109
  var DictRender = function (options) {
110
+ if (!_V_DICT.loaded) {
111
+ _V_DICT.loaded = true;
112
+ (0, _AjaxUtil_1.SESSION)(index_1.GLOBAL.CONFIG.BASIC.DICT);
113
+ var resp = (0, XHR_1.GETSYNC)(index_1.GLOBAL.CONFIG.BASIC.DICT);
114
+ initDict(resp.data || []);
115
+ }
109
116
  var props = lodash_1.default.isString(options) ? { dictType: options } : options;
110
117
  var fn = function (txt) { return react_1.default.createElement(_DictRender, __assign({}, props, { value: txt })); };
111
118
  fn.options = function (config) {
112
- var info = DICT.get(props.dictType);
119
+ var info = _V_DICT.DICT_MAP.get(props.dictType);
113
120
  if (info == null)
114
121
  return [];
115
122
  return putOptions(info.nodes, config);
@@ -117,7 +124,7 @@ var DictRender = function (options) {
117
124
  fn.getText = function (key, defaultValue) {
118
125
  if (key === null)
119
126
  return lodash_1.default.isString(defaultValue) ? defaultValue : '';
120
- var dictInfo = DICT.get(props.dictType);
127
+ var dictInfo = _V_DICT.DICT_MAP.get(props.dictType);
121
128
  if (dictInfo == null)
122
129
  return lodash_1.default.isString(defaultValue) ? defaultValue : '';
123
130
  var dictKey = key + '';
@@ -153,7 +160,6 @@ var initDict = function (dict) {
153
160
  info.format = format;
154
161
  _V_DICT.DICTS.push({ label: root.codeValue, value: root.type });
155
162
  initNodes(root.type, dict, info.nodes);
156
- DICT.set(root.type, info);
163
+ _V_DICT.DICT_MAP.set(root.type, info);
157
164
  });
158
165
  };
159
- exports.initDict = initDict;
@@ -1,7 +1,9 @@
1
- import type { MatchPatterns } from './_Support';
1
+ import { spellMatch } from './py';
2
+ import type { MatchPatterns } from './py';
2
3
  export declare const REG_EMAIL: RegExp;
3
4
  export declare const REG_PHONE: RegExp;
4
5
  export declare const REG_TELEPHONE: RegExp;
6
+ export declare const LETTERS: Set<string>;
5
7
  export declare const REG_IPV4: RegExp;
6
8
  export declare const REG_IPV6: RegExp;
7
9
  export declare const REG_URL: RegExp;
@@ -83,6 +85,7 @@ export declare const isBoolean: (str: string) => boolean;
83
85
  * 清空首尾空格,并小写
84
86
  */
85
87
  export declare const trimLower: (str: string) => string;
88
+ export { spellMatch };
86
89
  /**
87
90
  * 搜索,用于高亮,通常与 HighLight 结合使用,或只使用 HighLight 组件
88
91
  */
@@ -127,4 +130,3 @@ type FileType = 'image' | 'pdf' | 'doc' | 'excel' | 'ppt' | 'zip' | 'video' | 'a
127
130
  * 获取文件类及 icon
128
131
  */
129
132
  export declare const getFileType: (fileName: string) => [FileType, string];
130
- export {};
@@ -28,13 +28,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  return (mod && mod.__esModule) ? mod : { "default": mod };
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.getFileType = exports.getSuffix = exports.getFileName = exports.getFloat = exports.getInteger = exports.getBoolean = exports.getString = exports.copy = exports.px = exports.replaceAll = exports.className = exports.searchText = exports.trimLower = exports.isBoolean = exports.isBTCAddress = exports.uuid = exports.genKey = exports.isId = exports.isId15 = exports.isId18 = exports.REG_ID_15 = exports.REG_ID_18 = exports.isIP = exports.isIP6 = exports.isIP4 = exports.isPhone = exports.isMAC = exports.isURL = exports.isEmail = exports.isTelePhone = exports.isMobilePhone = exports.REG_PORT = exports.REG_URL = exports.REG_IPV6 = exports.REG_IPV4 = exports.REG_TELEPHONE = exports.REG_PHONE = exports.REG_EMAIL = void 0;
31
+ exports.getFileType = exports.getSuffix = exports.getFileName = exports.getFloat = exports.getInteger = exports.getBoolean = exports.getString = exports.copy = exports.px = exports.replaceAll = exports.className = exports.searchText = exports.spellMatch = exports.trimLower = exports.isBoolean = exports.isBTCAddress = exports.uuid = exports.genKey = exports.isId = exports.isId15 = exports.isId18 = exports.REG_ID_15 = exports.REG_ID_18 = exports.isIP = exports.isIP6 = exports.isIP4 = exports.isPhone = exports.isMAC = exports.isURL = exports.isEmail = exports.isTelePhone = exports.isMobilePhone = exports.REG_PORT = exports.REG_URL = exports.REG_IPV6 = exports.REG_IPV4 = exports.LETTERS = exports.REG_TELEPHONE = exports.REG_PHONE = exports.REG_EMAIL = void 0;
32
32
  var lodash_1 = __importDefault(require("lodash"));
33
- var _Support_1 = require("./_Support");
34
33
  var dayjs_1 = __importDefault(require("dayjs"));
34
+ var _Support_1 = require("./_Support");
35
+ var py_1 = require("./py");
36
+ Object.defineProperty(exports, "spellMatch", { enumerable: true, get: function () { return py_1.spellMatch; } });
37
+ // import type { MatchPatterns } from './_Support';
35
38
  exports.REG_EMAIL = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;
36
39
  exports.REG_PHONE = /^((\+|00)86)?(1[3-9]|9[28])\d{9}$/; // https://github.com/validatorjs/validator.js/blob/master/src/lib/isMobilePhone.js
37
40
  exports.REG_TELEPHONE = /^0\d{2,3}-[1-9]\d{6,7}$/;
41
+ exports.LETTERS = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']);
38
42
  var IPv4SegmentFormat = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
39
43
  var IPv4AddressFormat = "(".concat(IPv4SegmentFormat, "[.]){3}").concat(IPv4SegmentFormat);
40
44
  exports.REG_IPV4 = new RegExp("^".concat(IPv4AddressFormat, "$"));
@@ -225,7 +229,12 @@ exports.trimLower = trimLower;
225
229
  /**
226
230
  * 搜索,用于高亮,通常与 HighLight 结合使用,或只使用 HighLight 组件
227
231
  */
228
- var searchText = function (sentence, keyword) { return (0, _Support_1.matchText)(keyword)(sentence); };
232
+ var searchText = function (sentence, keyword) {
233
+ var result = (0, py_1.spellMatch)(sentence, keyword);
234
+ if (result.hit)
235
+ return result.result;
236
+ return [{ hit: false, text: sentence }];
237
+ };
229
238
  exports.searchText = searchText;
230
239
  /**
231
240
  * 拼 className
package/utils/TreeUtil.js CHANGED
@@ -42,6 +42,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.search = exports.buildFlatTree = void 0;
43
43
  var lodash_1 = __importDefault(require("lodash"));
44
44
  var StringUtil_1 = require("../utils/StringUtil");
45
+ var py_1 = require("../utils/py");
45
46
  var buildTree = function (list, root, keyField, parentField, sortField) {
46
47
  var e_1, _a;
47
48
  if (sortField === void 0) { sortField = null; }
@@ -108,13 +109,13 @@ var search = function (tree, word, titleField) {
108
109
  return { word: word, keyword: keyword, match: match };
109
110
  };
110
111
  exports.search = search;
111
- var searchNode = function (node, pos, word, result, titleField) {
112
- var name = lodash_1.default.toLower(node[titleField]);
113
- if (name.indexOf(word) >= 0) {
112
+ var searchNode = function (node, pos, keyword, result, titleField) {
113
+ var hited = (0, py_1.spellHit)(node[titleField], keyword);
114
+ if (hited.length >= 0) {
114
115
  result.push(pos.join('-'));
115
116
  }
116
117
  if (node.children && node.children.length) {
117
- searchNodes(node.children, pos, word, result, titleField);
118
+ searchNodes(node.children, pos, keyword, result, titleField);
118
119
  }
119
120
  };
120
- var searchNodes = function (data, pos, word, result, titleField) { return data.map(function (item, idx) { return searchNode(item, __spreadArray(__spreadArray([], __read(pos), false), [idx], false), word, result, titleField); }); };
121
+ var searchNodes = function (data, pos, keyword, result, titleField) { return data.map(function (item, idx) { return searchNode(item, __spreadArray(__spreadArray([], __read(pos), false), [idx], false), keyword, result, titleField); }); };
@@ -17,12 +17,6 @@ export declare enum Language {
17
17
  export declare const globalDefault: <T>(key: GLOBAL_KEY, init: T) => T;
18
18
  export declare const TRUE_SET: Set<string>;
19
19
  export declare const FALSE_SET: Set<string>;
20
- export type MatchPatterns = {
21
- hit: boolean;
22
- text: string;
23
- };
24
- type TextMatchFunction = (sentence: string) => MatchPatterns[];
25
- export declare const matchText: (keyword: any) => TextMatchFunction;
26
20
  export declare const APP_ROOT: string;
27
21
  export declare const CACHE_URL: Set<string>;
28
22
  export {};
package/utils/_Support.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CACHE_URL = exports.APP_ROOT = exports.matchText = exports.FALSE_SET = exports.TRUE_SET = exports.globalDefault = exports.Language = exports.getGlobal = void 0;
6
+ exports.CACHE_URL = exports.APP_ROOT = exports.FALSE_SET = exports.TRUE_SET = exports.globalDefault = exports.Language = exports.getGlobal = void 0;
7
7
  var lodash_1 = __importDefault(require("lodash"));
8
8
  var getGlobal = function () {
9
9
  if (typeof window !== 'undefined') {
@@ -36,71 +36,5 @@ var globalDefault = function (key, init) {
36
36
  exports.globalDefault = globalDefault;
37
37
  exports.TRUE_SET = new Set(['1', 'true', 'yes']);
38
38
  exports.FALSE_SET = new Set(['0', 'false', 'no']);
39
- var NOT_MATCH = function (sentence) { return [{ hit: false, text: sentence }]; };
40
- var CACHE = {};
41
- var matchText = function (keyword) {
42
- var word = lodash_1.default.trim(keyword);
43
- if (word.length == 0)
44
- return NOT_MATCH;
45
- var key = word.toLowerCase();
46
- var keyLen = key.length;
47
- var FN = function (sentence) {
48
- var str = lodash_1.default.trim(sentence);
49
- if (str.length == 0)
50
- return [{ hit: false, text: '' }];
51
- var strLen = str.length;
52
- var fixed = new Array(strLen);
53
- var searchStr = str.toLowerCase();
54
- var hasFix = false;
55
- var idx = searchStr.indexOf(key);
56
- while (idx >= 0) {
57
- hasFix = true;
58
- for (var i = 0; i < keyLen; i++) {
59
- fixed[idx + i] = 1;
60
- }
61
- idx = searchStr.indexOf(key, idx + keyLen);
62
- }
63
- if (!hasFix)
64
- return [{ hit: false, text: str }];
65
- var matched = [];
66
- var tagging = false;
67
- var start = 0;
68
- for (var i = 0; i < strLen; i++) {
69
- if (fixed[i]) {
70
- if (!tagging) {
71
- tagging = true;
72
- start = i;
73
- }
74
- if (i == (strLen - 1)) {
75
- tagging = false;
76
- matched.push(start);
77
- }
78
- }
79
- else {
80
- if (tagging) {
81
- tagging = false;
82
- matched.push(start);
83
- }
84
- }
85
- }
86
- var domList = [];
87
- var cur = 0;
88
- for (var i = 0, _i = matched.length; i < _i; i++) {
89
- var pos = matched[i];
90
- domList.push({ hit: false, text: str.substring(cur, pos) });
91
- // domList.push(str.substring(pos, pos + keyLen));
92
- domList.push({ hit: true, text: str.substring(pos, pos + keyLen) });
93
- cur = pos + keyLen;
94
- }
95
- if (cur < str.length) {
96
- domList.push({ hit: false, text: str.substring(cur) });
97
- }
98
- return domList;
99
- };
100
- CACHE[keyword] = FN;
101
- // window.setTimeout(() => _.unset(CACHE, keyword), 5000)
102
- return FN;
103
- };
104
- exports.matchText = matchText;
105
39
  exports.APP_ROOT = (0, exports.getGlobal)()['APP_ROOT'] || '';
106
40
  exports.CACHE_URL = (0, exports.globalDefault)('_INNER_CACHE', new Set());
package/utils/py.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export type TextIndexItem = {
2
+ i: number;
3
+ char: string;
4
+ spell?: string;
5
+ };
6
+ export type TextIndex = TextIndexItem[];
7
+ export declare const createIndex: (txt: string) => TextIndex;
8
+ export declare const matchKeywordByIndex: (key: string, index: TextIndex) => number[];
9
+ export type MatchPatterns = {
10
+ hit: boolean;
11
+ text: string;
12
+ };
13
+ export declare const arrangeText: (text: string, hit: number[]) => MatchPatterns[];
14
+ export type SpellResult = {
15
+ hit: boolean;
16
+ result?: MatchPatterns[];
17
+ };
18
+ export declare const spellHit: (text: string, keyword: any) => number[];
19
+ export declare const spellMatch: (text: string, keyword: string) => SpellResult;
package/utils/py.js ADDED
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.spellMatch = exports.spellHit = exports.arrangeText = exports.matchKeywordByIndex = exports.createIndex = void 0;
7
+ var Global_1 = require("./Global");
8
+ var lodash_1 = __importDefault(require("lodash"));
9
+ // 创建反向索引
10
+ var createIndex = function (txt) {
11
+ var index = [];
12
+ for (var i = 0, _i = txt.length; i < _i; i++) {
13
+ var char = txt[i];
14
+ if (Global_1.CONFIG.APP.PY && Global_1.CONFIG.APP.PY.has(char)) {
15
+ index.push({ i: i, char: char, spell: Global_1.CONFIG.APP.PY.get(char) });
16
+ }
17
+ else {
18
+ index.push({ i: i, char: char.toLowerCase() });
19
+ }
20
+ }
21
+ return index;
22
+ };
23
+ exports.createIndex = createIndex;
24
+ var matchKeywordByIndex = function (key, index) {
25
+ /**
26
+ * 字符匹配分为 四步
27
+ * 1. 将需要搜索的文本创建索引
28
+ * 并将索引和关键字进行匹配
29
+ */
30
+ if (key == null || key.length == 0)
31
+ return [];
32
+ var keyword = key.toLowerCase(); // 关键字 转小写
33
+ var keywordLen = keyword.length;
34
+ var keywordCursor = 0; // 关键字 当前游标
35
+ var textLen = index.length;
36
+ var textCursor = 0; // 文本 当前游标
37
+ var hited = []; // 命中文本位置
38
+ var diff = 0; // 字数差值,用于最后计算
39
+ // - 命中次数 + 差值 = 关键字长度,否则无效
40
+ // 示例 : 关键字 hubei(length=5) 命中: 湖北(length=2) 差值 3
41
+ while (keywordCursor < keywordLen) {
42
+ var char = keyword[keywordCursor];
43
+ while (textCursor < textLen) {
44
+ /**
45
+ * 2. 将关键字从左往右 , 在索引中进行匹配
46
+ * 如果与索引中的文本一致,则直接命中
47
+ */
48
+ var matcher = index[textCursor];
49
+ if (matcher.char == char) {
50
+ hited.push(textCursor);
51
+ textCursor++;
52
+ break;
53
+ }
54
+ if (matcher.spell == null) { // 即不相同,也没有拼音时,直接下一个(双加)
55
+ textCursor++;
56
+ continue;
57
+ }
58
+ ;
59
+ /**
60
+ * 3. 在索引中有拼音的情况下,匹配汉语拼音
61
+ * 说明1 : 拼音从声母开始, 如 bei be b 可以匹配 北 , 而 ei 不行.
62
+ * 说明2 : 匹配过程中, 会将 keyword, 的游标移位 , 更改 {i} {char}
63
+ * 说明3 : 将匹配的字数存到 spell
64
+ * 如 bei = 3 be =2 b =1
65
+ * 如果 spell = 0 则没有匹配
66
+ * 说明4 : 根据spell 再计算hit
67
+ * 没有没有匹配上,则不计算 diff
68
+ */
69
+ var count = 0;
70
+ var spell = matcher.spell, _j = spell.length;
71
+ for (var j = 0; j < _j; j++) {
72
+ if (char == spell[j]) {
73
+ keywordCursor++;
74
+ char = keyword[keywordCursor];
75
+ count++;
76
+ continue;
77
+ }
78
+ // pos++;
79
+ break;
80
+ }
81
+ if (count > 0) {
82
+ hited.push(textCursor);
83
+ diff += (count - 1);
84
+ }
85
+ textCursor++;
86
+ }
87
+ /**
88
+ * 4. 如果原文本已经遍历完成 ,不管关键字有没有完成 ,都直接中段
89
+ */
90
+ if (textCursor >= (textLen - 1))
91
+ break;
92
+ keywordCursor++;
93
+ }
94
+ /**
95
+ * 5. 根据 hit / diff 计算搜索结果
96
+ */
97
+ if ((hited.length + diff) < keywordLen)
98
+ return [];
99
+ return hited;
100
+ };
101
+ exports.matchKeywordByIndex = matchKeywordByIndex;
102
+ var arrangeText = function (text, hit) {
103
+ if (hit == null || hit.length == 0 || text == null || text.length == 0)
104
+ return [{ text: text, hit: false }];
105
+ var result = [];
106
+ var LEN = text.length;
107
+ var cursor = 0;
108
+ var hited = hit[0] == 0;
109
+ var buff = '';
110
+ var HitSet = new Set(hit);
111
+ while (cursor < LEN) {
112
+ if (hited) {
113
+ if (HitSet.has(cursor)) {
114
+ buff += text[cursor]; // 连续命中,直接append
115
+ }
116
+ else { // 上次命中,但本次未命中
117
+ if (buff.length)
118
+ result.push({ text: buff, hit: true });
119
+ buff = text[cursor];
120
+ hited = false;
121
+ }
122
+ }
123
+ else {
124
+ if (HitSet.has(cursor)) { // 上次未命中,但本次命中中
125
+ if (buff.length)
126
+ result.push({ text: buff, hit: false });
127
+ buff = text[cursor];
128
+ hited = true;
129
+ }
130
+ else {
131
+ buff += text[cursor]; // 连续未命中,直接 append
132
+ }
133
+ }
134
+ cursor++;
135
+ }
136
+ // 处理最后的缓冲区内容
137
+ if (buff.length > 0)
138
+ result.push({ text: buff, hit: hited, });
139
+ return result;
140
+ };
141
+ exports.arrangeText = arrangeText;
142
+ var spellHit = function (text, keyword) {
143
+ if (text == null || text.length == 0 || keyword == null || keyword.length == 0)
144
+ return [];
145
+ var fullCheck = text.toLowerCase().indexOf(keyword.toLowerCase());
146
+ var hit;
147
+ if (fullCheck >= 0) {
148
+ hit = lodash_1.default.range(fullCheck, fullCheck + keyword.length);
149
+ }
150
+ else {
151
+ hit = (0, exports.matchKeywordByIndex)(keyword, (0, exports.createIndex)(text));
152
+ }
153
+ return hit;
154
+ };
155
+ exports.spellHit = spellHit;
156
+ var spellMatch = function (text, keyword) {
157
+ if (text == null || text.length == 0 || keyword == null || keyword.length == 0)
158
+ return { hit: false };
159
+ var fullCheck = text.toLowerCase().indexOf(keyword.toLowerCase());
160
+ var hit;
161
+ if (fullCheck >= 0) {
162
+ hit = lodash_1.default.range(fullCheck, fullCheck + keyword.length);
163
+ }
164
+ else {
165
+ hit = (0, exports.matchKeywordByIndex)(keyword, (0, exports.createIndex)(text));
166
+ }
167
+ if (hit.length == 0)
168
+ return { hit: false };
169
+ var result = (0, exports.arrangeText)(text, hit);
170
+ if (result.length == 0)
171
+ return { hit: false };
172
+ return { hit: true, result: result };
173
+ };
174
+ exports.spellMatch = spellMatch;