@wangcheng051/plugin-kit 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +275 -2
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +320 -0
- package/dist/index.js +802 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +8 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +98 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CRM Platform Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,276 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @wangcheng051/plugin-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CRM 后台 React 插件包,基于 **React 17 + antd 5 + ag-grid 31**。
|
|
4
|
+
|
|
5
|
+
以 ag-grid 表格封装为核心,配合主题配置与通用工具函数,用于搭建 CRM 后台管理系统。
|
|
6
|
+
|
|
7
|
+
## 环境要求
|
|
8
|
+
|
|
9
|
+
| 依赖 | 版本范围 | 说明 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| react / react-dom | `^17.0.2` | React 17 无 `createRoot`,需使用 `ReactDOM.render` |
|
|
12
|
+
| antd | `^5.21.6` | 二次封装基于 antd 5 API |
|
|
13
|
+
| ag-grid-react / ag-grid-community | `^31.0.1` | 社区版,无列工具面板 / SetFilter |
|
|
14
|
+
| @ant-design/icons | `^5.5.1` | 由 antd 引入,通常已随 antd 安装 |
|
|
15
|
+
| react-redux | `^7.2.4` | 可选 peer;`TableList` 表头会读 `state.controller.language` |
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i @wangcheng051/plugin-kit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`react` / `react-dom` / `antd` / `ag-grid-*` / `@ant-design/icons` 为 peerDependencies,
|
|
24
|
+
需由宿主项目自行安装;`react-redux` 为可选 peer,使用 `TableList` 时需确保应用被 `<Provider>` 包裹。
|
|
25
|
+
|
|
26
|
+
## 使用
|
|
27
|
+
|
|
28
|
+
### 引入样式(ag-grid v31 使用经典 CSS 主题)
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
// 本包自身的样式(CSS Modules 已编译,必须引入,否则表头/列设置弹层无样式)
|
|
32
|
+
import '@wangcheng051/plugin-kit/style.css';
|
|
33
|
+
|
|
34
|
+
// ag-grid 的样式由宿主引入
|
|
35
|
+
import 'ag-grid-community/styles/ag-grid.css';
|
|
36
|
+
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
|
37
|
+
import 'antd/dist/reset.css';
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> ag-grid v31 尚未提供新的 Theming API(v32+ 才有),只能通过 CSS 主题类名切换。
|
|
41
|
+
> 可选主题:`alpine`(默认)、`balham`、`material`、`quartz`、`classic`。
|
|
42
|
+
|
|
43
|
+
### TableList
|
|
44
|
+
|
|
45
|
+
```jsx
|
|
46
|
+
import { TableList, formatMoney, formatPercent } from '@wangcheng051/plugin-kit';
|
|
47
|
+
|
|
48
|
+
const columnDefs = [
|
|
49
|
+
{ field: 'name', cnDisplay: '客户名称', enDisplay: 'Customer', width: 240, pinned: 'left' },
|
|
50
|
+
{ field: 'owner', cnDisplay: '负责人', enDisplay: 'Owner', width: 100 },
|
|
51
|
+
{
|
|
52
|
+
field: 'amount', cnDisplay: '合同金额', enDisplay: 'Amount', width: 140,
|
|
53
|
+
render: ({ value }) => formatMoney(value),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
field: 'rate', cnDisplay: '毛利率', enDisplay: 'Gross Rate', width: 110,
|
|
57
|
+
render: ({ value }) => formatPercent(value),
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
// 容器需要有确定高度(表格按 100% 高度撑满)
|
|
62
|
+
<div style={{ height: 420 }}>
|
|
63
|
+
<TableList columnDefs={columnDefs} tableData={list} loading={loading} />
|
|
64
|
+
</div>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**列配置**:
|
|
68
|
+
|
|
69
|
+
| 字段 | 类型 | 说明 |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| `field` | string | 取值字段(同时作为 ag-grid 列 id) |
|
|
72
|
+
| `cnDisplay` / `enDisplay` | string | 中文 / 英文表头(由 `state.controller.language` 切换) |
|
|
73
|
+
| `key` | string | 合计行取值字段,缺省用 `field` |
|
|
74
|
+
| `lockPosition` | boolean | 该列不参与底部合计 |
|
|
75
|
+
| `width` / `minWidth` | number | 列宽 |
|
|
76
|
+
| `render` | function | 自定义单元格渲染 `({ value, data, ...cellParams }) => ReactNode` |
|
|
77
|
+
| 其他 | - | 其余字段透传给 ag-grid `ColDef`(`pinned`、`hide`、`sortable` 等) |
|
|
78
|
+
|
|
79
|
+
**TableList 属性**:`columnDefs` `tableData` `loading` `pagination` `customBottomTotal`(底部合计行)
|
|
80
|
+
`onChange`(排序 / 拖拽 / 筛选回调)`tableRef` `reset`(透传给 `AgGridReact`)`customColumn`
|
|
81
|
+
`filterSearchRender` `filterKey` `setfilterKey`。
|
|
82
|
+
|
|
83
|
+
> 表头渲染依赖 `react-redux`:组件内部读取 `state.controller.language`,
|
|
84
|
+
> 宿主未接 redux 时请用 `ConfigProvider` 或自行替换 `headerComponent`。
|
|
85
|
+
|
|
86
|
+
### useTableModule
|
|
87
|
+
|
|
88
|
+
列配置的获取、保存、排序分页与 session 持久化由 `useTableModule` 统一管理,
|
|
89
|
+
业务接口全部通过参数注入(`tableRequest` / `getColConfigRequest` / `saveColConfigRequest`),
|
|
90
|
+
插件包不依赖任何业务工程。返回 `TableListRender`、`SettingTableRender`、`getTableData` 等能力。
|
|
91
|
+
|
|
92
|
+
### 主题
|
|
93
|
+
|
|
94
|
+
```jsx
|
|
95
|
+
import { ConfigProvider, crmTheme } from '@wangcheng051/plugin-kit';
|
|
96
|
+
|
|
97
|
+
<ConfigProvider theme={crmTheme}>
|
|
98
|
+
<App />
|
|
99
|
+
</ConfigProvider>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 工具函数
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
import { formatMoney, formatNumber, formatPercent, get, groupBy, cx } from '@wangcheng051/plugin-kit';
|
|
106
|
+
|
|
107
|
+
formatMoney(12345.6); // '¥12,345.60'
|
|
108
|
+
formatMoney(-100); // '-¥100.00'
|
|
109
|
+
formatNumber(1234567); // '1,234,567'
|
|
110
|
+
formatPercent(0.1234); // '12.34%'
|
|
111
|
+
get({ a: { b: 1 } }, 'a.b'); // 1
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 开发
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm install
|
|
118
|
+
|
|
119
|
+
npm run dev # 启动 demo(http://127.0.0.1:5178)
|
|
120
|
+
npm run build # 构建库产物到 dist/(ESM + CJS + UMD + 类型声明)
|
|
121
|
+
npm run build:demo # 构建 demo
|
|
122
|
+
|
|
123
|
+
npm run verify:types # 类型声明一致性校验(src 导出 vs types/index.d.ts)
|
|
124
|
+
npm run verify:dist # 产物消费验证(导出符号 / 外部依赖 / 行为)
|
|
125
|
+
npm run smoke # 渲染冒烟测试(捕获运行时错误)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 发布
|
|
129
|
+
|
|
130
|
+
包名:`@wangcheng051/plugin-kit`(scoped,MIT 协议)。
|
|
131
|
+
|
|
132
|
+
### 一次性准备
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# 1. 注册 / 登录 npmjs 账号
|
|
136
|
+
npm login
|
|
137
|
+
|
|
138
|
+
# 2. 确认当前身份
|
|
139
|
+
npm whoami
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
> `npm login` 会要求输入密码 / OTP,**只能在终端交互式完成**,脚本无法代劳。
|
|
143
|
+
|
|
144
|
+
### 发布到公共 npmjs
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# 预演:检查远端版本占用 + 包内容完整性,不实际上传
|
|
148
|
+
npm run publish:public
|
|
149
|
+
|
|
150
|
+
# 确认无误后真实发布
|
|
151
|
+
npm run publish:public:confirm
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
首次发布时 npm 会发一封确认邮件到注册邮箱,**必须点击邮件中的验证链接**,否则该 scope 下的包无法被他人安装。
|
|
155
|
+
|
|
156
|
+
#### 账号开启 2FA 时(必然遇到的 403)
|
|
157
|
+
|
|
158
|
+
npm 账号启用 2FA 后,`npm publish` 会直接报:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
npm error 403 Forbidden - PUT https://registry.npmjs.org/@crm%2fplugin-kit
|
|
162
|
+
npm error Two-factor authentication or granular access token with bypass 2fa enabled is required
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
两种解法,**推荐第一种**:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# 方案 1:Granular Access Token(勾选 bypass 2FA,长期可用)
|
|
169
|
+
# npmjs → Access Tokens → Generate New Token → Granular → 权限选 Read and write
|
|
170
|
+
NPM_TOKEN=npm_xxxxxxxx npm run publish:public:confirm
|
|
171
|
+
|
|
172
|
+
# 方案 2:一次性验证码(30 秒过期)
|
|
173
|
+
NPM_OTP=123456 npm run publish:public:confirm
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
脚本已把「校验」和「上传」拆开:先用约 1~2 分钟跑完 `prepublishOnly`,再以 `--ignore-scripts` 上传,
|
|
177
|
+
这样 OTP 不会在构建期间过期。凭据均通过环境变量传入,不落命令行、不打印到日志。
|
|
178
|
+
|
|
179
|
+
### 发布到公司私有源
|
|
180
|
+
|
|
181
|
+
私有源地址通过环境变量传入,不写入任何配置文件:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# 预演
|
|
185
|
+
NPM_PRIVATE_REGISTRY=https://npm.internal.example.com/ npm run publish:private
|
|
186
|
+
|
|
187
|
+
# 真实发布(带 token)
|
|
188
|
+
NPM_PRIVATE_REGISTRY=https://npm.internal.example.com/ \
|
|
189
|
+
NPM_PRIVATE_TOKEN=xxxxxxxx \
|
|
190
|
+
npm run publish:private:confirm
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- `NPM_PRIVATE_TOKEN` 会写入一个临时 `.npmrc`,发布结束立即删除,不进命令行、不进 git
|
|
194
|
+
- 不传 `NPM_PRIVATE_TOKEN` 时,复用本机 `~/.npmrc` 中已配置的私有源凭据
|
|
195
|
+
- 脚本会在临时 `.npmrc` 中写入 `@crm:registry=...`,让 `@crm` scope 自动路由到私有源
|
|
196
|
+
|
|
197
|
+
### 发布流程说明
|
|
198
|
+
|
|
199
|
+
`prepublishOnly` 钩子会在每次 `npm publish` 时自动执行:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
verify:types → build(内含 check-types + vite build)→ copy-types → verify:dist → smoke → test
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
任一环节失败都会中止发布,避免把坏产物推上去。
|
|
206
|
+
|
|
207
|
+
`scripts/publish.mjs` 会先单独跑一遍 `prepublishOnly`,再执行带 `--ignore-scripts` 的 `npm publish`,
|
|
208
|
+
两者等价,但 OTP 不会被 1~2 分钟的构建耗时拖到过期。确实需要跳过校验时加 `--skip-checks`。
|
|
209
|
+
|
|
210
|
+
### 版本号与不可覆盖
|
|
211
|
+
|
|
212
|
+
npm **不允许覆盖已发布的版本号**。每次发新版本前先提升版本号:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npm version patch # 0.1.0 -> 0.1.1
|
|
216
|
+
npm version minor # 0.1.0 -> 0.2.0
|
|
217
|
+
npm version major # 0.1.0 -> 1.0.0
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
发布脚本会在上传前自动检查远端是否已存在同版本,存在则直接中止。
|
|
221
|
+
|
|
222
|
+
### 消费方安装
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm i @wangcheng051/plugin-kit
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`react` / `react-dom` / `antd` / `ag-grid-*` / `@ant-design/icons` 均为 peerDependencies,需由宿主项目自行安装(`react-redux` 为可选 peer)。
|
|
229
|
+
|
|
230
|
+
### 私有源的消费方配置
|
|
231
|
+
|
|
232
|
+
消费方需要把 `@crm` scope 指向私有源,在项目根目录的 `.npmrc` 中添加:
|
|
233
|
+
|
|
234
|
+
```ini
|
|
235
|
+
@crm:registry=https://npm.internal.example.com/
|
|
236
|
+
//npm.internal.example.com/:_authToken=your-token
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
## 目录结构
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
src/
|
|
244
|
+
├── index.js # 统一导出
|
|
245
|
+
├── table/
|
|
246
|
+
│ └── renderers/ # 单元格渲染器集合
|
|
247
|
+
├── components/ # CRM 业务列表组件(TableList / useTableModule 等)
|
|
248
|
+
├── theme/
|
|
249
|
+
│ ├── antd.js # antd 主题 token
|
|
250
|
+
│ └── agGrid.js # ag-grid 主题与行高预设
|
|
251
|
+
└── utils/ # 格式化等通用工具
|
|
252
|
+
|
|
253
|
+
types/index.d.ts # 供 TS 使用方的手写类型声明
|
|
254
|
+
scripts/check-types.mjs # 校验类型声明与源码导出是否一致
|
|
255
|
+
examples/demo/ # Vite demo 工程
|
|
256
|
+
jsconfig.json # JS 项目的编辑器配置(非 tsconfig)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
> **关于 `types/index.d.ts`**:本包是纯 JS 工程,声明文件为手写(构建时由
|
|
260
|
+
> `scripts/copy-types.mjs` 拷到 `dist/index.d.ts`)。它不会随源码自动更新,
|
|
261
|
+
> 但 `npm run build` / `npm run verify:types` 会校验「源码导出 ↔ 声明」是否一致,
|
|
262
|
+
> 新增或删除导出后不同步更新会直接构建失败。
|
|
263
|
+
|
|
264
|
+
> **关于 tsconfig.json**:本项目是纯 JS/JSX 工程,不使用 TypeScript。
|
|
265
|
+
> 请勿添加 `tsconfig.json` —— 编辑器会据此把 `.jsx` 按 TS 严格模式校验,
|
|
266
|
+
> 而 `@types/react@17`(react-redux 7 的传递依赖)与 antd 5.29 的类型定义
|
|
267
|
+
> (按 React 19 编写)不兼容,会产生大量与运行时无关的类型报错。
|
|
268
|
+
> 需要类型提示请使用 `jsconfig.json`。
|
|
269
|
+
|
|
270
|
+
## 已知限制
|
|
271
|
+
|
|
272
|
+
- **ag-grid 社区版**:不含列工具面板、SetFilter、图表等企业特性,列设置面板需自行实现。
|
|
273
|
+
- **Node ESM 直引**:`ag-grid-react` v31 的 ESM 产物 import 了 `react-dom/server`,
|
|
274
|
+
而 React 17 未声明 `package.json` 的 `exports` 映射,Node ESM 下无法解析该子路径。
|
|
275
|
+
浏览器与 Vite / Webpack 等打包环境不受影响。
|
|
276
|
+
- **UMD 产物**:需自行引入 antd、ag-grid 等 peer 依赖的全局变量。
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),S=require("antd"),ve=require("@ant-design/icons"),se=require("react-redux"),_e=require("ag-grid-react");function Re(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,o.get?o:{enumerable:!0,get:()=>e[n]})}}return r.default=e,Object.freeze(r)}const $=Re(ve);function j(e){return e==null||e===""||typeof e=="number"&&Number.isNaN(e)?!0:Array.isArray(e)?e.length===0:!1}function le(e,r,n){if(!e||!r)return n;const o=String(r).split(".");let a=e;for(let s=0;s<o.length;s+=1){if(a==null)return n;a=a[o[s]]}return a===void 0?n:a}function Y(e,r=0){if(j(e))return"-";const n=Number(e);return Number.isNaN(n)?"-":n.toLocaleString("zh-CN",{minimumFractionDigits:r,maximumFractionDigits:r})}function ae(e,r={}){const{digits:n=2,symbol:o="¥",showSymbol:a=!0,showZeroZero:s=!1}=r;if(j(e))return"-";const m=Number(e);if(Number.isNaN(m))return"-";const v=Y(Math.abs(m),n),N=a?o:"";return m<0?`-${N}${v}`:`${N}${v}`}function ie(e,r=2){if(j(e))return"-";const n=Number(e);return Number.isNaN(n)?"-":`${Y(n*100,r)}%`}function Te(e,r){const n={};return(e||[]).forEach(o=>{const a=typeof r=="function"?r(o):le(o,r);n[a]||(n[a]=[]),n[a].push(o)}),n}function we(e){const r={};return Object.keys(e||{}).forEach(n=>{j(e[n])||(r[n]=e[n])}),r}function Ne(e,r=300){let n=null;return function(...a){n&&clearTimeout(n),n=setTimeout(()=>{n=null,e.apply(this,a)},r)}}function xe(...e){return e.filter(Boolean).join(" ")}function ue(e=[],r="value"){return new Map((e||[]).map(n=>[(n==null?void 0:n[r])??(n==null?void 0:n.id),n]))}function D(e,r=new WeakMap){if(e===null||typeof e!="object")return e;if(r.has(e))return r.get(e);if(Array.isArray(e)){const o=[];return r.set(e,o),e.forEach((a,s)=>{o[s]=D(a,r)}),o}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e.source,e.flags);const n={};return r.set(e,n),Object.keys(e).forEach(o=>{n[o]=D(e[o],r)}),n}const{Text:P}=S.Typography;function Me({value:e}){return e==null||e===""?t.createElement(P,{type:"secondary"},"-"):t.createElement("span",null,String(e))}function ke({value:e,digits:r=2,showSymbol:n=!0}){if(e==null||e==="")return t.createElement(P,{type:"secondary"},"-");const o=Number(e);return Number.isNaN(o)?t.createElement(P,{type:"secondary"},"-"):t.createElement("span",{style:{color:o<0?"#ff4d4f":void 0}},ae(o,{digits:r,showSymbol:n}))}function Ae({value:e,digits:r=0,percent:n=!1}){if(e==null||e==="")return t.createElement(P,{type:"secondary"},"-");const o=Number(e);return Number.isNaN(o)?t.createElement(P,{type:"secondary"},"-"):t.createElement("span",null,n?ie(o,r):Y(o,r))}function De({value:e,color:r,options:n}){if(e==null||e==="")return t.createElement(P,{type:"secondary"},"-");let o=r,a=e;if(n&&n.length){const s=n.find(m=>String(m.value)===String(e));s&&(a=s.label,o=o??s.color)}return t.createElement(S.Tag,{color:o||"default"},a)}function Be({value:e,length:r=30}){if(e==null||e==="")return t.createElement(P,{type:"secondary"},"-");const n=String(e);return n.length<=r?t.createElement("span",null,n):t.createElement(S.Tooltip,{title:n},t.createElement(P,{ellipsis:!0,style:{maxWidth:240}},n))}function Le({value:e,onClick:r}){return e==null||e===""?t.createElement(P,{type:"secondary"},"-"):t.createElement("a",{onClick:()=>r&&r(e)},String(e))}function He({value:e,actions:r=[]}){return t.createElement("span",null,r.map(n=>t.createElement("a",{key:n.key,style:{marginRight:8},onClick:()=>n.onClick&&n.onClick(n)},n.text)))}const Oe={token:{colorPrimary:"#1677ff",colorSuccess:"#52c41a",colorWarning:"#faad14",colorError:"#ff4d4f",colorInfo:"#1677ff",borderRadius:6,fontSize:14,controlHeight:32,wireframe:!1},components:{Table:{headerBg:"#fafafa",headerColor:"#262626",rowHoverBg:"#f5f5f5",borderColor:"#f0f0f0"},Layout:{headerBg:"#ffffff",headerHeight:56,bodyBg:"#f0f2f5"},Card:{headerBg:"transparent"},Menu:{itemBorderRadius:6}}},Pe={success:{color:"success",text:"成功"},warning:{color:"warning",text:"警告"},error:{color:"error",text:"异常"},processing:{color:"processing",text:"处理中"},info:{color:"processing",text:"进行中"},default:{color:"default",text:"未知"}},Ie={1:"success",0:"default",true:"success",false:"default"},de=["alpine","balham","material","quartz","classic"],ee="alpine";function qe(e=ee,r){return[`ag-theme-${de.includes(e)?e:ee}`,r].filter(Boolean).join(" ")}const ze={compact:28,normal:36,relaxed:48},fe=$.default&&typeof $.default=="object"?$.default:$,Ge=$.SearchOutlined||fe.SearchOutlined,Ke=$.SettingOutlined||fe.SettingOutlined,$e="_poper_cidv4_2",Ue="_antTable_cidv4_6",Fe="_detailTable_cidv4_10",We="_opts_cidv4_10",je="_commonDetail_cidv4_18",Je="_title_cidv4_18",Ze="_searchAndAdd_cidv4_25",Qe="_addIcons_cidv4_25",Ye="_noteTitle_cidv4_31",Xe="_customHead_cidv4_40",Ve="_sortNames_cidv4_43",et="_customSort_cidv4_48",tt="_customUnSort_cidv4_53",nt="_active_cidv4_56",rt="_inactive_cidv4_59",ot="_popoverContext_cidv4_63",ct="_contextRender_cidv4_68",st="_contextRenderFooter_cidv4_71",T={poper:$e,antTable:Ue,detailTable:Fe,opts:We,commonDetail:je,title:Je,searchAndAdd:Ze,addIcons:Qe,noteTitle:Ye,customHead:Xe,sortNames:Ve,customSort:et,customUnSort:tt,active:nt,inactive:rt,popoverContext:ot,contextRender:ct,contextRenderFooter:st},me=({onChange:e=()=>{},columRef:r})=>{const{language:n}=se.useSelector(u=>u.controller),[o,a]=t.useState(!1),[s,m]=t.useState(D(r.current));t.useEffect(()=>{const u=r==null?void 0:r.current;!u||!u.length||o||m(D(u))},[r==null?void 0:r.current,o]);const v=()=>{e({column:s,optType:"mergeColum"}),a(!1)},N=u=>{s[u].visible=!s[u].visible,m([...s])},x=()=>{m(D(r.current))};return React.createElement("div",null,React.createElement(S.Popover,{placement:"bottomLeft",trigger:"click",className:T.poper,open:!!o,onOpenChange:u=>{a(u)},content:React.createElement(React.Fragment,null,React.createElement("div",{style:{padding:"10px 10px",maxHeight:"300px",overflowY:"auto",position:"relative",minWidth:178}},React.createElement("div",{style:{borderBottom:"1px solid rgba(0, 0, 0, 0.06)",paddingBottom:"10px"}},n?"Custom List":"自定义列表"),s.map((u,_)=>React.createElement("div",{style:{height:"32px",display:"flex",alignItems:"center"},key:u+_},React.createElement(S.Checkbox,{color:"primary",checked:u.visible,disabled:u.disabled,onChange:B=>N(_)}),React.createElement("span",{style:{position:"relative",top:"2px",marginLeft:"8px"}},(n?u.enDisplay:u.cnDisplay)||u.field)))),React.createElement("div",{style:{minWidth:120,display:"flex",justifyContent:"space-between",alignItems:"center",paddingTop:5,paddingBottom:5,boxShadow:" 0 -1px 2px 0 rgba(0, 0, 0, 0.05)"}},React.createElement(S.Button,{onClick:v,type:"primary"},n?"Save":"保存"),React.createElement(S.Button,{onClick:()=>a(!1)},n?"Cancel":"取消")))},React.createElement(Ke,{onClick:()=>x()})))},te={fill:"currentColor",viewBox:"0 0 1024 1024",version:"1.1",xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16"},ge=e=>t.createElement("svg",{...te,...e,t:"1688438905306","p-id":"2388"},t.createElement("path",{d:"M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z","p-id":"2389"})),he=e=>t.createElement("svg",{...te,...e,t:"1688438923470","p-id":"2523"},t.createElement("path",{d:"M804.571 402.286c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z","p-id":"2524"})),pe=e=>t.createElement("svg",{...te,...e,t:"1688438886160","p-id":"2253"},t.createElement("path",{d:"M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z m0-219.428c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z","p-id":"2254"})),ye=e=>{const[r,n]=t.useState("inactive"),[o,a]=t.useState("inactive"),[s,m]=t.useState("inactive"),v=t.useRef(null),[N,x]=t.useState(!1),[u,_]=t.useState(null),B=()=>{e.showColumnMenu(v.current)};t.useEffect(()=>{var g;const c=Array.isArray(e.filterKey)?e.filterKey:[];_(((g=ue(c,"field").get(e.field))==null?void 0:g.value)??null)},[e.filterKey,e.field]);const E=()=>{const c=e.column.getSort();n(c==="asc"?"active":"inactive"),a(c==="desc"?"active":"inactive"),m(c?"inactive":"active")},R=(c,g)=>{e.setSort(c,g.shiftKey)};t.useEffect(()=>{const c=e.column;if(!(!c||typeof c.addEventListener!="function"))return c.addEventListener("sortChanged",E),E(),()=>{c.removeEventListener("sortChanged",E)}},[e.column]),e.enableFilterButton&&`${e.menuIcon}`;let I=null;e.enableSorting&&(I=t.createElement("div",{className:T.sortNames},t.createElement("div",{onClick:c=>R("asc",c),onTouchEnd:c=>R("asc",c),className:`${T.customSort} ${T[r]}`},t.createElement(ge,null)),t.createElement("div",{onClick:c=>R("desc",c),onTouchEnd:c=>R("desc",c),className:`${T.customSort} ${T[o]}`},t.createElement(he,null)),t.createElement("div",{onClick:c=>R("",c),onTouchEnd:c=>R("",c),className:`${T.customSort} ${T.customUnSort} ${T[s]}`},t.createElement(pe,null))));const G={width:"100%"},U=t.useMemo(()=>{var g,p;let c=((g=e.filterSearchRender[e.field])==null?void 0:g.render)||S.Input;return t.createElement(c,{...((p=e.filterSearchRender[e.field])==null?void 0:p.tPropty)||{},value:u,onChange:d=>{_(d.target?d.target.value:d)},style:G})},[e.field,u]);let q=null;return e.search&&(q=t.createElement("div",null,t.createElement(S.Popover,{arrow:!1,open:N,trigger:"click",overlayClassName:T.popoverContext,onOpenChange:c=>x(c),placement:"bottom",content:t.createElement("div",{className:T.contextRender},U,t.createElement("div",{className:T.contextRenderFooter},t.createElement(S.Button,{type:"primary",onClick:()=>{const c=e.filterKey.filter(p=>p.field!=e.field);u!=null&&u.length&&c.push({field:e.field,value:u});const g=c!=null&&c.length?c:[];e.onSearch(g),e.setfilterKey(g),x(!1)}},e.language?"Search":"搜索"),t.createElement(S.Button,{style:{marginLeft:10},onClick:()=>{const c=e.filterKey.filter(p=>p.field!=e.field),g=c!=null&&c.length?c:[];x(!1),e.setfilterKey(g),_(null),e.onSearch(g)}},e.language?"Reset":"重置")))},t.createElement(Ge,{style:{color:u?"#1890ff":"rgba(0, 0, 0, 0.25)",marginLeft:10,cursor:"pointer"}})))),t.createElement("div",{className:T.customHead},t.createElement("div",{className:"customHeaderLabel"},e.displayName),I,q)},Ce=({columnDefs:e=[],loading:r,customBottomTotal:n=!1,onChange:o=()=>{},tableRef:a,tableData:s,pagination:m=!1,reset:v={},customColumn:N=[],filterSearchRender:x={},setfilterKey:u,filterKey:_})=>{const B=t.useMemo(()=>({width:"100%",height:"100%",position:"relative"}),[]),E=t.useMemo(()=>({height:"100%",width:"100%"}),[]),R=se.useSelector(l=>l.controller.language),I=t.useMemo(()=>{const l=m&&typeof m=="object"?m.total:void 0;return typeof l=="number"&&!Number.isNaN(l)?l:Array.isArray(s)?s.length:0},[m,s]),G=t.useMemo(()=>{let l={};return e.map((i,z)=>{if(z==0)l[i.field]="Total",l.fromData="total";else{let A=i.lockPosition?"":0;s.map(L=>{let W=i.field!=i.key&&i.key?i.key:i.field,J=["jobCurrency","industries","jobSalaryRange"];!isNaN(Number(L[W]))&&!J.includes(i.field)&&(A+=Number(L[W]))}),l[i.field]=typeof A=="number"&&A>0?A:"--"}}),[l]},[s,e]),U={visible:!0,sortable:!0,active:!1,unSortIcon:!0,minWidth:200,comparator:(l,i,z,A,L)=>0,headerComponent:ye},q=t.useMemo(()=>({width:170,lockPinned:!0}),[]),c=t.useCallback(l=>{a&&(a.current=l)},[]),g=l=>{var L;const{isNotTip:i,render:z}=l.colDef||{},A=((L=l.data)==null?void 0:L.fromData)==="total";return z&&!A?z(l):t.createElement(S.Tooltip,{title:i?"":l.value||"",arrow:!0,placement:"top"},typeof l.value=="number"||l.value?l.value:"--")},p=t.useCallback(l=>{const{sortModel:i}=l.api.getState().sort||{};console.log(i,"sortModel"),o({sort:i?i[0]:null,optType:"sort"})},[]),d=l=>{o({column:l.api.getColumnDefs().filter(i=>i.field).map(i=>({...i,pinned:void 0,field:i.field,hide:i.hide,visible:i.visible}))})},F=(l,i)=>{o({optType:"mergeColum",pagination:{page:l,size:i}})};return t.createElement("div",{style:B},r?t.createElement("div",{className:"loadingContent"},t.createElement(S.Spin,null)):null,t.createElement("div",{style:E,className:"ag-theme-alpine AgGridReact"},t.createElement(_e.AgGridReact,{rowData:s,pinnedBottomRowData:n?G:[],defaultColDef:q,suppressRowTransform:!0,onSortChanged:p,onDragStopped:d,suppressDragLeaveHidesColumns:!0,suppressMovableColumns:!1,...v,columnDefs:[...e.map(l=>({...U,...l,headerName:R?l.enDisplay:l.cnDisplay,cellRenderer:g,headerComponentParams:{onSearch:i=>{console.log(i,"搜索"),o({filter:i||{}})},setfilterKey:u,filterKey:_,language:R,filterSearchRender:x,...l}})),...N],icons:{sortAscending:`<span style="font-size: inherit;color: rgb(24, 144, 255);vertical-align:-webkit-baseline-middle">
|
|
2
|
+
<svg t="1688438905306" fill="currentColor" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2388" width="16" height="16"><path d="M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z" p-id="2389"></path></svg>
|
|
3
|
+
</span>`,sortDescending:`<span style="font-size: inherit;color:rgb(24, 144, 255);vertical-align:-webkit-baseline-middle">
|
|
4
|
+
<svg t="1688438923470" fill="currentColor" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2523" width="16" height="16"><path d="M804.571 402.286c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z" p-id="2524"></path></svg>
|
|
5
|
+
</span>`,sortUnSort:`<span style="font-size: inherit;color: rgb(153, 153, 153);vertical-align:-webkit-baseline-middle">
|
|
6
|
+
<svg t="1688438886160" fill="currentColor" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2253" width="16" height="16"><path d="M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z m0-219.428c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z" p-id="2254"></path></svg>
|
|
7
|
+
</span>`},onGridReady:c})),m?t.createElement(S.Pagination,{total:I,onChange:F,...m}):null)},lt=(e={},r={})=>{var oe;const{sessionKey:n,renderKey:o,setParamsList:a,configKey:s,tableUrl:m,tableRequest:v,getColConfigRequest:N,saveColConfigRequest:x}={...r,...e},u=typeof window<"u"&&!!window.sessionStorage,_=t.useCallback(f=>{if(u)try{window.sessionStorage.setItem(n,JSON.stringify(f))}catch(y){console.warn("[useTableModule] sessionStorage 写入失败:",y)}},[n,u]),B=t.useCallback(()=>{if(!u)return null;try{const f=window.sessionStorage.getItem(n);return f?JSON.parse(f):null}catch(f){return console.warn("[useTableModule] sessionStorage 读取失败:",f),null}},[n,u]),E=t.useRef([]),[R,I]=t.useState([]),[G,U]=t.useState([]),[q,c]=t.useState(void 0),[g,p]=t.useState(!0),d=t.useRef(B()||{}),[F,l]=t.useState(((oe=B())==null?void 0:oe.filter)||[]),i=t.useRef(0),z=t.useRef(v);z.current=v;const A=t.useRef(m);A.current=m;const L=t.useRef(a);L.current=a;const W=t.useRef(o);W.current=o;const J=t.useRef(N);J.current=N;const ne=t.useRef(x);ne.current=x;const Z=t.useCallback(()=>{const{sort:f}=d.current,y=E.current.map(C=>({...C,sort:f&&f.colId==C.field?f.sort:void 0}));I(D(y))},[]),X=t.useCallback(()=>{const f=ne.current;if(!f){console.warn("[useTableModule] 未注入 saveColConfigRequest,跳过列配置保存");return}const y={subcategory:s,userConfig:{pageConfig:{pageSize:d.current.size?d.current.size:null},columnConfig:E.current}},C=f(y);C&&typeof C.catch=="function"&&C.catch(M=>console.error("[useTableModule] 列配置保存失败:",M))},[s]),H=t.useCallback(()=>{const f=z.current;if(!f){console.warn("[useTableModule] 未注入 tableRequest,跳过列表加载"),p(!1);return}i.current+=1;const y=i.current,C=L.current,M=C?C(d.current):d.current;return p(!0),f(M,A.current).then(O=>{if(y!==i.current)return;const b=O==null?void 0:O.response,w=Array.isArray(b)?b:(b==null?void 0:b.data)||[],k=Array.isArray(b)||b==null?void 0:b.total;typeof k=="number"&&!Number.isNaN(k)&&c(k);const V=w.map(h=>({...h,...h._source||{}}));U(V),p(!1)},O=>{y===i.current&&(console.error("[useTableModule] 列表加载失败:",O),p(!1))})},[]),Q=t.useCallback(f=>{const{column:y,optType:C,sort:M,pagination:O,filter:b}=f;let w=[];if(y){const k=new Map(y.map(h=>[h.field,h]));w=E.current.map(h=>{const K=k.get(h.field);if(!K)return{...h};const ce=K.visible!==void 0?K.visible:!K.hide;return{...h,hide:!ce,visible:ce}});const V=new Set(E.current.map(h=>h.field));y.forEach(h=>{if(!V.has(h.field)){const K=h.visible!==void 0?h.visible:!h.hide;w.push({...h,hide:!K,visible:K})}}),E.current=w,X()}C=="mergeColum"&&I(D(w!=null&&w.length?w:E.current)),C=="sort"&&(d.current={...d.current,sort:M},_(d.current),Z(),H()),O&&(d.current={...d.current,...O},_(d.current),H()),b&&(d.current={...d.current,filter:b},d.current.page&&d.current.page>1&&(d.current.page=1),_(d.current),H())},[_,X,Z,H]),re=t.useCallback(()=>{const f=J.current;if(!f){console.warn("[useTableModule] 未注入 getColConfigRequest,跳过列配置加载"),p(!1);return}const{sort:y}=d.current,C=W.current;f(s).then(({response:M})=>{var w;const b=(((w=M==null?void 0:M.userConfig)==null?void 0:w.columnConfig)||[]).map(k=>({...k,hide:!k.visible,visible:k.visible,sort:y&&y.colId==k.field?y.sort:void 0,render:C?C[k.field]:void 0}));I(D(b)),E.current=D(b),H()},M=>{console.error("[useTableModule] 列配置加载失败:",M),p(!1)})},[s,H]),be=t.useCallback(()=>{const f=B()||{};d.current=f,l(f.filter||[]),Z(),H()},[B,Z,H]);t.useEffect(()=>{s&&re()},[s]);const Se=t.useCallback((f={})=>React.createElement(me,{columRef:E,onChange:Q,...f}),[Q]),Ee=t.useCallback((f={})=>React.createElement(Ce,{filterKey:F,setfilterKey:l,loading:g,columnDefs:R,pagination:{current:d.current.page,pageSize:d.current.size,total:q},onChange:Q,tableData:G,...f}),[F,g,R,G,q,Q]);return{SettingTableRender:Se,TableListRender:Ee,getTableData:H,getColConfig:re,saveColConfig:X,resetSesstion:be,tableData:G,setloading:p,loading:g,columnDefs:R,paramsCurrent:d,total:q,filterKey:F}},at={width:"100%"},it=({dataIndex:e,language:r,onChange:n,value:o,...a})=>{const s=t.useMemo(()=>React.createElement(S.Input,{value:o!=null&&o.length?o:null,style:at,...a,onChange:m=>{n(m.target.value)}}),[e,o]);return React.createElement("div",{style:{marginBottom:8}},s)};exports.AG_GRID_THEMES=de;exports.ActionCell=He;exports.CustomHeader=ye;exports.DEFAULT_AG_GRID_THEME=ee;exports.DICT_COLOR_MAP=Ie;exports.EllipsisCell=Be;exports.LinkCell=Le;exports.MayList=ue;exports.MoneyCell=ke;exports.NumberCell=Ae;exports.OtherSlot=it;exports.ROW_HEIGHT_PRESETS=ze;exports.STATUS_PRESETS=Pe;exports.SettingTable=me;exports.SortAscending=ge;exports.SortDescending=he;exports.SortUnSort=pe;exports.TableList=Ce;exports.TagCell=De;exports.TextCell=Me;exports.agGridClass=qe;exports.crmTheme=Oe;exports.cx=xe;exports.debounce=Ne;exports.deepClone=D;exports.formatMoney=ae;exports.formatNumber=Y;exports.formatPercent=ie;exports.get=le;exports.groupBy=Te;exports.isEmpty=j;exports.omitEmpty=we;exports.useTableModule=lt;
|
|
8
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/utils/index.js","../src/table/renderers/index.jsx","../src/theme/antd.js","../src/theme/agGrid.js","../src/components/antdIcons.js","../src/components/tableComponent/settingTableCol.jsx","../src/components/icon.jsx","../src/components/tableComponent/CustomHeader.jsx","../src/components/tableComponent/tableList.jsx","../src/components/tableComponent/useTable.module.jsx","../src/components/tableComponent/slotComponent.jsx"],"sourcesContent":["/**\n * 通用工具函数\n */\n\n/** 空值判断:null / undefined / '' / NaN */\nexport function isEmpty(value) {\n if (value === null || value === undefined || value === '') return true;\n if (typeof value === 'number' && Number.isNaN(value)) return true;\n if (Array.isArray(value)) return value.length === 0;\n return false;\n}\n\n/** 安全取值:path 支持 'a.b.c' 形式 */\nexport function get(obj, path, defaultValue) {\n if (!obj || !path) return defaultValue;\n const keys = String(path).split('.');\n let cur = obj;\n for (let i = 0; i < keys.length; i += 1) {\n if (cur === null || cur === undefined) return defaultValue;\n cur = cur[keys[i]];\n }\n return cur === undefined ? defaultValue : cur;\n}\n\n/** 数字千分位格式化 */\nexport function formatNumber(value, digits = 0) {\n if (isEmpty(value)) return '-';\n const num = Number(value);\n if (Number.isNaN(num)) return '-';\n return num.toLocaleString('zh-CN', {\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n });\n}\n\n/**\n * 金额格式化(人民币)\n * @param {number|string} value 金额\n * @param {object} options\n * @param {number} options.digits 小数位数,默认 2\n * @param {string} options.symbol 货币符号,默认 ¥\n * @param {boolean} options.showSymbol 是否显示符号,默认 true\n * @param {boolean} options.showZeroZero 负数是否保留符号位(-0.00),默认 false\n */\nexport function formatMoney(value, options = {}) {\n const { digits = 2, symbol = '¥', showSymbol = true, showZeroZero = false } = options;\n if (isEmpty(value)) return '-';\n const num = Number(value);\n if (Number.isNaN(num)) return '-';\n const abs = formatNumber(Math.abs(num), digits);\n const prefix = showSymbol ? symbol : '';\n if (num < 0) {\n const body = showZeroZero ? abs : abs;\n return `-${prefix}${body}`;\n }\n return `${prefix}${abs}`;\n}\n\n/** 百分比格式化,0.1234 -> '12.34%' */\nexport function formatPercent(value, digits = 2) {\n if (isEmpty(value)) return '-';\n const num = Number(value);\n if (Number.isNaN(num)) return '-';\n return `${formatNumber(num * 100, digits)}%`;\n}\n\n/** 数组按键分组,返回 { key: item[] } */\nexport function groupBy(list, keyFn) {\n const result = {};\n (list || []).forEach((item) => {\n const key = typeof keyFn === 'function' ? keyFn(item) : get(item, keyFn);\n if (!result[key]) result[key] = [];\n result[key].push(item);\n });\n return result;\n}\n\n/** 过滤对象中的空值字段 */\nexport function omitEmpty(obj) {\n const result = {};\n Object.keys(obj || {}).forEach((key) => {\n if (!isEmpty(obj[key])) result[key] = obj[key];\n });\n return result;\n}\n\n/** 防抖 */\nexport function debounce(fn, wait = 300) {\n let timer = null;\n return function debounced(...args) {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n fn.apply(this, args);\n }, wait);\n };\n}\n\n/** 类名拼接 */\nexport function cx(...args) {\n return args.filter(Boolean).join(' ');\n}\n\n/**\n * 按 key 生成 Map,便于 O(1) 查找。\n * key 优先取 obj[key],取不到时回退到 obj.id。\n */\nexport function MayList(objectsArray = [], key = 'value') {\n return new Map(\n (objectsArray || []).map((obj) => {\n const mapKey = obj?.[key] ?? obj?.id;\n return [mapKey, obj];\n }),\n );\n}\n\n/**\n * 深拷贝(保留函数引用)。\n *\n * 与 lodash.cloneDeep 的关键差异:遇到函数时直接返回原引用而不复制。\n * 列配置里含有 render 这类 React 组件函数,\n * 用 structuredClone 会直接抛 DataCloneError。\n *\n * @param {*} value 待拷贝的值\n * @param {WeakMap} [seen] 循环引用检测\n */\nexport function deepClone(value, seen = new WeakMap()) {\n // 基本类型与函数直接返回\n if (value === null || typeof value !== 'object') return value;\n\n // 循环引用保护\n if (seen.has(value)) return seen.get(value);\n\n if (Array.isArray(value)) {\n const arr = [];\n seen.set(value, arr);\n value.forEach((item, i) => {\n arr[i] = deepClone(item, seen);\n });\n return arr;\n }\n\n if (value instanceof Date) return new Date(value.getTime());\n if (value instanceof RegExp) return new RegExp(value.source, value.flags);\n\n // React 组件等函数对象已在上面的 typeof 判断中返回原引用\n\n const obj = {};\n seen.set(value, obj);\n Object.keys(value).forEach((key) => {\n obj[key] = deepClone(value[key], seen);\n });\n return obj;\n}\n","import React from 'react';\nimport { Tag, Typography, Tooltip } from 'antd';\nimport { formatMoney, formatNumber, formatPercent } from '../../utils';\n\nconst { Text } = Typography;\n\n/**\n * 单元格渲染器集合\n *\n * ag-grid 的 cellRenderer 既可以是 React 组件,也可以是函数。\n * 这里统一提供 React 组件形式,可通过 columnDef.cellRenderer 引用。\n */\n\n/** 文本渲染(默认) */\nexport function TextCell({ value }) {\n if (value === null || value === undefined || value === '') return <Text type=\"secondary\">-</Text>;\n return <span>{String(value)}</span>;\n}\n\n/** 金额渲染(负数标红) */\nexport function MoneyCell({ value, digits = 2, showSymbol = true }) {\n if (value === null || value === undefined || value === '') {\n return <Text type=\"secondary\">-</Text>;\n }\n const num = Number(value);\n if (Number.isNaN(num)) return <Text type=\"secondary\">-</Text>;\n return (\n <span style={{ color: num < 0 ? '#ff4d4f' : undefined }}>\n {formatMoney(num, { digits, showSymbol })}\n </span>\n );\n}\n\n/** 数字渲染(自动千分位) */\nexport function NumberCell({ value, digits = 0, percent = false }) {\n if (value === null || value === undefined || value === '') {\n return <Text type=\"secondary\">-</Text>;\n }\n const num = Number(value);\n if (Number.isNaN(num)) return <Text type=\"secondary\">-</Text>;\n return <span>{percent ? formatPercent(num, digits) : formatNumber(num, digits)}</span>;\n}\n\n/** 标签渲染 */\nexport function TagCell({ value, color, options }) {\n if (value === null || value === undefined || value === '') {\n return <Text type=\"secondary\">-</Text>;\n }\n let tagColor = color;\n let text = value;\n\n if (options && options.length) {\n const hit = options.find((o) => String(o.value) === String(value));\n if (hit) {\n text = hit.label;\n tagColor = tagColor ?? hit.color;\n }\n }\n return <Tag color={tagColor || 'default'}>{text}</Tag>;\n}\n\n/** 长文本省略 + tooltip */\nexport function EllipsisCell({ value, length = 30 }) {\n if (value === null || value === undefined || value === '') {\n return <Text type=\"secondary\">-</Text>;\n }\n const str = String(value);\n if (str.length <= length) return <span>{str}</span>;\n return (\n <Tooltip title={str}>\n <Text ellipsis style={{ maxWidth: 240 }}>{str}</Text>\n </Tooltip>\n );\n}\n\n/** 链接单元格 */\nexport function LinkCell({ value, onClick }) {\n if (value === null || value === undefined || value === '') {\n return <Text type=\"secondary\">-</Text>;\n }\n return (\n <a onClick={() => onClick && onClick(value)}>{String(value)}</a>\n );\n}\n\n/** 操作列渲染(按钮组) */\nexport function ActionCell({ value, actions = [] }) {\n return (\n <span>\n {actions.map((action) => (\n <a\n key={action.key}\n style={{ marginRight: 8 }}\n onClick={() => action.onClick && action.onClick(action)}\n >\n {action.text}\n </a>\n ))}\n </span>\n );\n}\n","/**\n * antd 5 主题配置\n *\n * 说明:antd 5 使用 CSS-in-JS,主题通过 ConfigProvider 的 token 注入,\n * 宿主应用只需在根节点包一层 <ConfigProvider theme={crmTheme}> 即可。\n */\nexport const crmTheme = {\n token: {\n colorPrimary: '#1677ff',\n colorSuccess: '#52c41a',\n colorWarning: '#faad14',\n colorError: '#ff4d4f',\n colorInfo: '#1677ff',\n borderRadius: 6,\n fontSize: 14,\n controlHeight: 32,\n wireframe: false,\n },\n components: {\n Table: {\n headerBg: '#fafafa',\n headerColor: '#262626',\n rowHoverBg: '#f5f5f5',\n borderColor: '#f0f0f0',\n },\n Layout: {\n headerBg: '#ffffff',\n headerHeight: 56,\n bodyBg: '#f0f2f5',\n },\n Card: {\n headerBg: 'transparent',\n },\n Menu: {\n itemBorderRadius: 6,\n },\n },\n};\n\n/** 状态 -> 颜色 预设,供 StatusTag / 表格状态列复用 */\nexport const STATUS_PRESETS = {\n success: { color: 'success', text: '成功' },\n warning: { color: 'warning', text: '警告' },\n error: { color: 'error', text: '异常' },\n processing: { color: 'processing', text: '处理中' },\n info: { color: 'processing', text: '进行中' },\n default: { color: 'default', text: '未知' },\n};\n\n/** 字典状态常见色值映射 */\nexport const DICT_COLOR_MAP = {\n 1: 'success',\n 0: 'default',\n true: 'success',\n false: 'default',\n};\n","/**\n * ag-grid 31 主题配置\n *\n * ag-grid v31 使用「经典 CSS 主题」机制(新的 Theming API 从 v32 才提供)。\n * 宿主应用需要引入基础样式与所选主题样式:\n *\n * import 'ag-grid-community/styles/ag-grid.css';\n * import 'ag-grid-community/styles/ag-theme-alpine.css';\n *\n * 本包不主动 import 这些 CSS,避免与宿主应用的主题选择冲突;\n * 请在宿主应用中自行 import 上述样式。\n */\n\n/** v31 可用的经典主题名 */\nexport const AG_GRID_THEMES = ['alpine', 'balham', 'material', 'quartz', 'classic'];\n\n/** 默认主题 */\nexport const DEFAULT_AG_GRID_THEME = 'alpine';\n\n/**\n * 生成 ag-grid 容器所需的 className\n * @param {string} theme 主题名,如 alpine\n * @param {string} extra 额外 class\n */\nexport function agGridClass(theme = DEFAULT_AG_GRID_THEME, extra) {\n const name = AG_GRID_THEMES.includes(theme) ? theme : DEFAULT_AG_GRID_THEME;\n return [`ag-theme-${name}`, extra].filter(Boolean).join(' ');\n}\n\n/** 行高预设(compact / normal / relaxed) */\nexport const ROW_HEIGHT_PRESETS = {\n compact: 28,\n normal: 36,\n relaxed: 48,\n};\n","/**\r\n * @ant-design/icons 的导入兼容层。\r\n *\r\n * 该包的 package.json 同时提供 main(CJS) 与 module(ESM):\r\n * - webpack / vite / rollup 优先取 module,加载 es/index.js;\r\n * - Node ESM 因无 exports 字段回退到 main,加载 lib/index.js。\r\n *\r\n * 两个产物的 default 语义完全不同:\r\n * - es/index.js 的 `export { default } from \"./components/Icon\"` 意味着\r\n * default 就是 Icon 组件本身,不是命名空间 —— 所以\r\n * `import icons from '@ant-design/icons'` 之后取 `icons.SearchOutlined`\r\n * 在 webpack/vite 下永远是 undefined,渲染会抛 \"Element type is invalid\";\r\n * - lib/index.js(CJS)的 default 才是包含全部图标的 module.exports。\r\n *\r\n * 因此统一用命名空间导入,并兼容 Node 下只有 default 的情况。\r\n */\r\nimport * as iconsNs from '@ant-design/icons';\r\n\r\nconst iconSet =\r\n iconsNs.default && typeof iconsNs.default === 'object' ? iconsNs.default : iconsNs;\r\n\r\nexport const SearchOutlined = iconsNs.SearchOutlined || iconSet.SearchOutlined;\r\nexport const SettingOutlined = iconsNs.SettingOutlined || iconSet.SettingOutlined;\r\n\r\nexport default iconSet;\r\n","import { Checkbox, Popover, Button } from 'antd'\nimport { SettingOutlined } from '../antdIcons'\nimport { deepClone } from '../../utils'\nimport { useState, useEffect } from 'react'\nimport { useSelector } from 'react-redux'\nimport Styles from './style/index.module.scss'\nconst SettingTable = ({ onChange = () => {}, columRef }) => {\n const { language } = useSelector((state) => state.controller)\n const [settingStatus, setSettingStatus] = useState(false)\n const [headerCloumsList, setHeaderCloumsList] = useState(\n deepClone(columRef.current)\n )\n\n // 列配置是异步加载的,首屏时 columRef.current 还是空数组。\n // 需要在其变化时同步列表,否则弹层里会没有任何列可选。\n useEffect(() => {\n const current = columRef?.current;\n if (!current || !current.length) return;\n // 弹层打开时以用户正在编辑的内容为准,不要被后台刷新覆盖\n if (!settingStatus) {\n setHeaderCloumsList(deepClone(current))\n }\n }, [columRef?.current, settingStatus])\n\n const saveQuit = () => {\n // 修改列配置\n onChange({\n column: headerCloumsList,\n optType:\"mergeColum\"\n })\n setSettingStatus(false)\n }\n const changeCheck = (index) => {\n // 修改表头显隐\n headerCloumsList[index].visible = !headerCloumsList[index].visible\n setHeaderCloumsList([...headerCloumsList])\n }\n const openInitHeadList = () => {\n setHeaderCloumsList(deepClone(columRef.current))\n // 只负责刷新数据,开关状态交给 Popover 的 onOpenChange 统一处理。\n // 此前这里也 setSettingStatus,与 onOpenChange 形成双重 toggle,\n // 导致弹层状态被翻转两次而永远打不开。\n }\n return (\n <div>\n <Popover\n placement=\"bottomLeft\"\n trigger=\"click\"\n className={Styles.poper}\n // overlayInnerStyle={{\n // padding:0\n // }}\n open={Boolean(settingStatus)}\n onOpenChange={(open) => {\n setSettingStatus(open)\n }}\n content={\n <>\n <div\n style={{\n padding: '10px 10px',\n maxHeight: '300px',\n overflowY: 'auto',\n position: 'relative',\n minWidth: 178,\n }}>\n <div\n style={{\n borderBottom: '1px solid rgba(0, 0, 0, 0.06)',\n paddingBottom: '10px',\n }}>\n {language ? 'Custom List' : '自定义列表'}\n </div>\n {headerCloumsList.map((item, index) => {\n return (\n <div\n style={{\n height: '32px',\n display: 'flex',\n alignItems: 'center',\n }}\n key={item + index}>\n <Checkbox\n color=\"primary\"\n checked={item.visible}\n disabled = {item.disabled}\n onChange={(e) => changeCheck(index)}\n />\n <span\n style={{\n position: 'relative',\n top: '2px',\n marginLeft: '8px',\n }}>\n {(language ? item.enDisplay : item.cnDisplay) ||\n item.field}\n </span>\n </div>\n )\n })}\n </div>\n <div\n style={{\n minWidth: 120,\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n paddingTop: 5,\n paddingBottom: 5,\n boxShadow: ' 0 -1px 2px 0 rgba(0, 0, 0, 0.05)',\n }}>\n <Button onClick={saveQuit} type=\"primary\">\n {language ? 'Save' : '保存'}\n </Button>\n <Button onClick={() => setSettingStatus(false)}>\n {language ? 'Cancel' : '取消'}\n </Button>\n </div>\n </>\n }>\n <SettingOutlined onClick={() => openInitHeadList()}></SettingOutlined>\n </Popover>\n </div>\n )\n}\nexport default SettingTable\n","/**\n * 表格排序图标\n *\n * 自包含实现(原先依赖 CRM 主工程的 app/components/icon),\n * 避免插件包反向依赖业务工程。\n *\n * 注意:不使用 @ant-design/icons 的 Icon 包装组件 —— 它同时提供 CJS(main)\n * 与 ESM(module) 产物,两种产物下 default 的语义不一致(见 components/antdIcons.js),\n * 且在 SSR/Node 下具名导入不可靠;直接渲染 svg 更轻也更稳。\n */\nimport React from 'react';\n\nconst svgProps = {\n fill: 'currentColor',\n viewBox: '0 0 1024 1024',\n version: '1.1',\n xmlns: 'http://www.w3.org/2000/svg',\n width: '16',\n height: '16',\n};\n\n/** 升序(箭头向上) */\nexport const SortAscending = (props) => (\n <svg {...svgProps} {...props} t=\"1688438905306\" p-id=\"2388\">\n <path\n d=\"M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z\"\n p-id=\"2389\"\n />\n </svg>\n);\n\n/** 降序(箭头向下) */\nexport const SortDescending = (props) => (\n <svg {...svgProps} {...props} t=\"1688438923470\" p-id=\"2523\">\n <path\n d=\"M804.571 402.286c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z\"\n p-id=\"2524\"\n />\n </svg>\n);\n\n/** 未排序(双向箭头) */\nexport const SortUnSort = (props) => (\n <svg {...svgProps} {...props} t=\"1688438886160\" p-id=\"2253\">\n <path\n d=\"M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z m0-219.428c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z\"\n p-id=\"2254\"\n />\n </svg>\n);\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\r\nimport Styles from './style/index.module.scss';\r\nimport { Input, Popover, Button } from 'antd';\r\nimport { SearchOutlined } from '../antdIcons';\r\nimport { MayList } from '../../utils';\r\nimport { SortAscending, SortDescending, SortUnSort } from '../icon';\r\n\r\nexport default (props) => {\r\n const [ascSort, setAscSort] = useState('inactive');\r\n const [descSort, setDescSort] = useState('inactive');\r\n const [noSort, setNoSort] = useState('inactive');\r\n const refButton = useRef(null);\r\n const [open, setopen] = useState(false);\r\n\r\n const [valueDefs, setvalueDefs] = useState(null)\r\n const onMenuClicked = () => {\r\n props.showColumnMenu(refButton.current);\r\n };\r\n // 注意:filterKey 是数组,之前的依赖写成 props.filterKey?.field 恒为 undefined,\r\n // 导致外部筛选值变化时输入框不回显。改为依赖整个 filterKey。\r\n useEffect(() => {\r\n const arr = Array.isArray(props.filterKey) ? props.filterKey : [];\r\n setvalueDefs(MayList(arr, 'field').get(props.field)?.value ?? null)\r\n }, [props.filterKey, props.field])\r\n \r\n const onSortChanged = () => {\r\n const sort = props.column.getSort();\r\n setAscSort(sort === 'asc' ? 'active' : 'inactive');\r\n setDescSort(sort === 'desc' ? 'active' : 'inactive');\r\n setNoSort(!sort ? 'active' : 'inactive');\r\n };\r\n\r\n const onSortRequested = (order, event) => {\r\n props.setSort(order, event.shiftKey);\r\n };\r\n\r\n // 监听列排序变化,并在卸载时解绑,否则会泄漏并对已卸载组件 setState\r\n useEffect(() => {\r\n const column = props.column;\r\n if (!column || typeof column.addEventListener !== 'function') return;\r\n column.addEventListener('sortChanged', onSortChanged);\r\n onSortChanged();\r\n return () => {\r\n column.removeEventListener('sortChanged', onSortChanged);\r\n };\r\n }, [props.column]);\r\n\r\n let menu = null;\r\n if (props.enableFilterButton) {\r\n menu = (\r\n <div ref={refButton} className=\"customHeaderMenuButton\" onClick={() => onMenuClicked()}>\r\n <i className={`fa ${props.menuIcon}`}></i>\r\n </div>\r\n );\r\n }\r\n\r\n let sort = null;\r\n if (props.enableSorting) {\r\n // 三个按钮的图标与行为此前是错位的:\r\n // 升序图标配 desc、取消图标配 desc,且 touchEnd 的参数与 onClick 不一致。\r\n // 现按图标语义对齐,并保证 click / touchEnd 传入相同的排序方向。\r\n sort = (\r\n <div className={Styles.sortNames}>\r\n <div\r\n onClick={(event) => onSortRequested('asc', event)}\r\n onTouchEnd={(event) => onSortRequested('asc', event)}\r\n className={`${Styles.customSort} ${Styles[ascSort]}`}\r\n >\r\n <SortAscending />\r\n </div>\r\n <div\r\n onClick={(event) => onSortRequested('desc', event)}\r\n onTouchEnd={(event) => onSortRequested('desc', event)}\r\n className={`${Styles.customSort} ${Styles[descSort]}`}\r\n >\r\n <SortDescending />\r\n </div>\r\n <div\r\n onClick={(event) => onSortRequested('', event)}\r\n onTouchEnd={(event) => onSortRequested('', event)}\r\n className={`${Styles.customSort} ${Styles.customUnSort} ${Styles[noSort]}`}\r\n >\r\n <SortUnSort />\r\n </div>\r\n </div>\r\n );\r\n }\r\n const defaultStyle = {\r\n width: '100%',\r\n };\r\n const context = useMemo(() => {\r\n // 注意搜索字段field 有冲突的话 请重新自定义\r\n let Render = props.filterSearchRender[props.field]?.render || Input;\r\n \r\n return (\r\n <Render\r\n {... (props.filterSearchRender[props.field]?.tPropty||{})}\r\n value={valueDefs}\r\n onChange={(e) => {\r\n setvalueDefs(e.target?e.target.value:e)\r\n \r\n }}\r\n style={defaultStyle}\r\n />\r\n );\r\n }, [props.field,valueDefs]);\r\n\r\n \r\n let search = null;\r\n if (props.search) {\r\n search = (\r\n <div>\r\n <Popover\r\n arrow={false}\r\n open={open}\r\n trigger=\"click\"\r\n overlayClassName={Styles.popoverContext}\r\n onOpenChange={(e) => setopen(e)}\r\n placement=\"bottom\"\r\n content={\r\n <div className={Styles.contextRender}>\r\n \r\n {context}\r\n <div className={Styles.contextRenderFooter}>\r\n <Button\r\n type=\"primary\"\r\n onClick={() => {\r\n const filterKeyArrary = props.filterKey.filter(i => i.field != props.field);\r\n if (valueDefs?.length) {\r\n filterKeyArrary.push({\r\n field: props.field,\r\n value: valueDefs\r\n })\r\n }\r\n const values = filterKeyArrary?.length ? filterKeyArrary : []\r\n props.onSearch(values);\r\n props.setfilterKey(values);\r\n setopen(false);\r\n }}\r\n >\r\n {props.language ? 'Search' : '搜索'}\r\n </Button>\r\n <Button\r\n style={{ marginLeft: 10 }}\r\n onClick={() => {\r\n const filterKeyArrary = props.filterKey.filter(i => i.field != props.field);\r\n const values = filterKeyArrary?.length ? filterKeyArrary : []\r\n\r\n setopen(false);\r\n props.setfilterKey(values);\r\n setvalueDefs(null)\r\n props.onSearch(values);\r\n }}\r\n >\r\n {props.language ? 'Reset' : '重置'}\r\n </Button>\r\n </div>\r\n </div>\r\n }\r\n >\r\n <SearchOutlined style={{ color: valueDefs ? '#1890ff' : 'rgba(0, 0, 0, 0.25)', marginLeft: 10, cursor: 'pointer' }} />\r\n </Popover>\r\n </div>\r\n );\r\n }\r\n return (\r\n <div className={Styles.customHead}>\r\n {/* {menu} */}\r\n <div className=\"customHeaderLabel\">{props.displayName}</div>\r\n {sort}\r\n {search}\r\n </div>\r\n );\r\n};\r\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { AgGridReact } from 'ag-grid-react';\r\n\r\n// 注意:不要在这里 import 'ag-grid-community/styles/ag-grid.css'。\r\n// ag-grid 是 peerDependency,其样式子路径若被保留为外部 import,\r\n// 消费方用 Node CJS require 本包时会因加载 CSS 文件而直接语法报错。\r\n// 正确做法是使用方自行引入(见 README「引入样式」章节):\r\n// import 'ag-grid-community/styles/ag-grid.css';\r\n// import 'ag-grid-community/styles/ag-theme-alpine.css';\r\n\r\nimport './style/styles.css';\r\nimport { Pagination, Spin, Tooltip } from 'antd';\r\nimport { useSelector } from 'react-redux';\r\nimport CustomHeader from './CustomHeader';\r\n\r\n\r\n/**\r\n *\r\n * @columnDefs 表头\r\n * @customBottomTotal 是否开启底部统计\r\n * @customColumn 自定义表头\r\n * @pagination 是否分页配置\r\n * @reset ag tabel拓展配置列如checkbox\r\n * @filterSearchRender 搜索组件\r\n */\r\n\r\nconst TableList = ({ columnDefs = [],loading, customBottomTotal = false, onChange = () => {}, tableRef, tableData,pagination=false,reset={} ,\r\ncustomColumn=[],filterSearchRender={},setfilterKey,filterKey} ) => {\r\n // useEffect(() => {\r\n // console.log(columnDefs,\"columnDefs32333\");\r\n // }, [JSON.stringify(columnDefs)])\r\n\r\n const containerStyle = useMemo(() => ({ width: '100%', height: '100%',position:\"relative\" }), []);\r\n const gridStyle = useMemo(() => ({ height: '100%', width: '100%' }), []);\r\n // const [rowData, setRowData] = useState([])\r\n const language = useSelector((state) => state.controller.language);\r\n // 分页总数:优先取业务传入的 total,其次取分页对象上的 total,\r\n // 最后兜底为当前页条数(避免出现写死的假总数)\r\n const total = useMemo(() => {\r\n const fromPagination = pagination && typeof pagination === 'object' ? pagination.total : undefined;\r\n if (typeof fromPagination === 'number' && !Number.isNaN(fromPagination)) return fromPagination;\r\n return Array.isArray(tableData) ? tableData.length : 0;\r\n }, [pagination, tableData]);\r\n const pinnedBottomRowData = useMemo(() => {\r\n let objTotal = {};\r\n columnDefs.map((i, index) => {\r\n if (index == 0) {\r\n objTotal[i.field] = 'Total';\r\n objTotal['fromData'] = 'total';\r\n } else {\r\n let total = i.lockPosition ? '' : 0;\r\n tableData.map((item) => {\r\n let key = i.field != i.key && i.key ? i.key : i.field;\r\n let disableTotal = ['jobCurrency', 'industries', 'jobSalaryRange'];\r\n if (!isNaN(Number(item[key])) && !disableTotal.includes(i.field)) {\r\n total += Number(item[key]);\r\n }\r\n });\r\n objTotal[i.field] = typeof total == 'number' && total > 0 ? total : '--';\r\n }\r\n });\r\n return [objTotal];\r\n // columnDefs 变化时也要重算,否则列显隐/排序调整后合计行与表格不一致\r\n }, [tableData, columnDefs]);\r\n const defaultCol = {\r\n visible: true,\r\n sortable: true,\r\n active: false,\r\n unSortIcon: true,\r\n minWidth:200,\r\n comparator: (valueA, valueB, nodeA, nodeB, isDescending) => {\r\n // console.log(valueA,valueB,nodeA,nodeB,isDescending,\"sort\",nodeA.gridApi.getSortModel());\r\n return 0;\r\n },\r\n headerComponent: CustomHeader\r\n // suppressMovable: !isDrag,\r\n };\r\n const defaultColDef = useMemo(() => {\r\n return {\r\n width: 170,\r\n lockPinned: true,\r\n };\r\n }, []);\r\n\r\n const onGridReady = useCallback((params) => {\r\n tableRef && (tableRef.current = params);\r\n // fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')\r\n // .then((resp) => resp.json())\r\n // .then((data) => setRowData(data))\r\n }, []);\r\n const getCellParams = (params) => {\r\n const { isNotTip, render } = params.colDef || {};\r\n // params.data 在加载占位行等场景下可能为 undefined,直接取 .fromData 会抛错\r\n const isTotalRow = params.data?.fromData === 'total';\r\n return render && !isTotalRow ? (\r\n render(params)\r\n ) : (\r\n <Tooltip title={isNotTip ? '' : params.value || ''} arrow placement=\"top\">\r\n {typeof params.value == 'number' || params.value ? params.value : '--'}\r\n </Tooltip>\r\n );\r\n };\r\n // ag-grid v31 已移除 frameworkComponents,单元格渲染通过 cellRenderer 直接传组件/函数\r\n // (下方 columnDefs 中的 cellRenderer:getCellParams 即为 v31 正确写法)\r\n\r\n // 排序监听\r\n const sortChanged = useCallback((params) => {\r\n // console.log(params.api,\"params.api.getSortModel()\");\r\n const { sortModel } = params.api.getState().sort || {}\r\n console.log(sortModel,\"sortModel\");\r\n onChange({\r\n sort: sortModel ? sortModel[0] : null,\r\n optType: 'sort',\r\n });\r\n }, []);\r\n // 获取拖拽后的数据\r\n const onDragStopped = (params) => {\r\n onChange({\r\n column: params.api\r\n .getColumnDefs()\r\n .filter((item) => item.field)\r\n .map((item) => {\r\n return {\r\n ...item,\r\n pinned: undefined,\r\n field: item.field,\r\n hide: item.hide,\r\n visible: item.visible,\r\n };\r\n }),\r\n });\r\n };\r\n// 分页\r\nconst handleChangePage = (page,size)=>{\r\n onChange({\r\n optType:\"mergeColum\",\r\n pagination:{\r\n page,size\r\n }\r\n })\r\n}\r\n return (\r\n <div style={containerStyle}>\r\n {loading?<div className={'loadingContent'}>\r\n <Spin />\r\n </div>:null}\r\n <div style={gridStyle} className={'ag-theme-alpine AgGridReact'}>\r\n <AgGridReact\r\n rowData={tableData}\r\n pinnedBottomRowData={customBottomTotal ? pinnedBottomRowData : []}\r\n defaultColDef={defaultColDef}\r\n suppressRowTransform={true}\r\n onSortChanged={sortChanged}\r\n onDragStopped={onDragStopped}\r\n suppressDragLeaveHidesColumns={true}//脱离区域是否可以拖拽\r\n suppressMovableColumns={false}\r\n {...reset}\r\n // 和apn 写法不同注意!!!\r\n columnDefs={[...columnDefs.map((item) => {\r\n return {\r\n ...defaultCol,\r\n ...item,\r\n headerName:!language ? item.cnDisplay : item.enDisplay,\r\n // apn写法\r\n // cellRenderer:\"getCellParams\",\r\n // crm写法\r\n cellRenderer:getCellParams,\r\n headerComponentParams:{\r\n onSearch:(e)=>{\r\n console.log(e,\"搜索\");\r\n \r\n onChange({\r\n filter:e||{}\r\n })\r\n },\r\n setfilterKey,\r\n filterKey,\r\n language,\r\n filterSearchRender,\r\n ...item\r\n }\r\n };\r\n }),...customColumn]}\r\n icons={{\r\n sortAscending: `<span style=\"font-size: inherit;color: rgb(24, 144, 255);vertical-align:-webkit-baseline-middle\">\r\n <svg t=\"1688438905306\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2388\" width=\"16\" height=\"16\"><path d=\"M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z\" p-id=\"2389\"></path></svg>\r\n </span>`,\r\n sortDescending: `<span style=\"font-size: inherit;color:rgb(24, 144, 255);vertical-align:-webkit-baseline-middle\">\r\n <svg t=\"1688438923470\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2523\" width=\"16\" height=\"16\"><path d=\"M804.571 402.286c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z\" p-id=\"2524\"></path></svg>\r\n </span>`,\r\n sortUnSort: `<span style=\"font-size: inherit;color: rgb(153, 153, 153);vertical-align:-webkit-baseline-middle\">\r\n <svg t=\"1688438886160\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"2253\" width=\"16\" height=\"16\"><path d=\"M804.571 621.714a36.206 36.206 0 0 1-10.861 25.71l-256 256c-6.84 6.839-16.019 10.862-25.71 10.862s-18.87-3.987-25.71-10.862l-256-256a36.425 36.425 0 0 1-10.861-25.71c0-20.004 16.566-36.571 36.571-36.571h512c20.005 0 36.571 16.567 36.571 36.571z m0-219.428c0 20.004-16.566 36.571-36.571 36.571H256c-20.005 0-36.571-16.567-36.571-36.571a36.206 36.206 0 0 1 10.861-25.71l256-256c6.84-6.839 16.019-10.862 25.71-10.862s18.87 3.987 25.71 10.862l256 256a36.425 36.425 0 0 1 10.861 25.71z\" p-id=\"2254\"></path></svg>\r\n </span>`,\r\n }}\r\n onGridReady={onGridReady}\r\n >\r\n </AgGridReact>\r\n </div>\r\n {pagination?<Pagination total={total} onChange={handleChangePage} {...pagination} />:null}\r\n </div>\r\n );\r\n};\r\nexport default TableList;\r\n","import { useState, useRef, useEffect, useCallback } from 'react';\nimport SettingTable from './settingTableCol';\nimport TableList from './tableList';\nimport { deepClone } from '../../utils';\n\n/**\n * CRM 列表 Hook\n *\n * 所有与业务耦合的接口均通过 props 注入,插件包本身不依赖任何业务工程:\n * @param {object} tProps\n * @param {string} tProps.sessionKey sessionStorage 存储 key\n * @param {object} tProps.renderKey 自定义单元格渲染,如 { companyName: (params) => node }\n * @param {Function} tProps.setParamsList 自定义请求参数转换,默认原样返回\n * @param {string} tProps.configKey 列配置的业务标识\n * @param {string} tProps.tableUrl 列表接口地址\n * @param {Function} tProps.tableRequest 列表接口请求方法 (params, url) => Promise<{response}>\n * @param {Function} tProps.getColConfigRequest 查询列配置接口 (configKey) => Promise<{response}>\n * @param {Function} tProps.saveColConfigRequest 保存列配置接口 (params) => void|Promise\n *\n * 依赖顺序说明(重要):\n * 本文件内各函数互相调用,定义顺序必须保持单向依赖,否则会触发 const 的\n * 暂时性死区(TDZ)报错:\n * checkHeadCols / saveColConfig / getTableData → handleColumn → getColConfig\n * 同时,所有可能由调用方以内联函数形式传入的值(tableRequest 等)\n * 都通过 ref 读取,不进 useCallback 依赖数组 —— 否则 callback 身份每渲染都变,\n * 会连带 useEffect 无限触发,造成请求死循环。\n */\nconst useTableModule = (tProps = {}, defaultProps = {}) => {\n // 保存到session里面的key\n const {\n sessionKey,\n renderKey,\n setParamsList,\n configKey,\n tableUrl,\n tableRequest,\n getColConfigRequest,\n saveColConfigRequest,\n } = { ...defaultProps, ...tProps };\n\n // sessionStorage 在 SSR / 测试环境下可能不存在\n const canUseSession = typeof window !== 'undefined' && !!window.sessionStorage;\n\n const saveSesstion = useCallback(\n (params) => {\n if (!canUseSession) return;\n try {\n window.sessionStorage.setItem(sessionKey, JSON.stringify(params));\n } catch (err) {\n // 隐私模式 / 超配额时写入会抛错,不应阻断业务流程\n console.warn('[useTableModule] sessionStorage 写入失败:', err);\n }\n },\n [sessionKey, canUseSession],\n );\n\n const getSesstion = useCallback(() => {\n if (!canUseSession) return null;\n try {\n const raw = window.sessionStorage.getItem(sessionKey);\n return raw ? JSON.parse(raw) : null;\n } catch (err) {\n // 数据损坏时不能抛错阻断渲染\n console.warn('[useTableModule] sessionStorage 读取失败:', err);\n return null;\n }\n }, [sessionKey, canUseSession]);\n\n const columRef = useRef([]);\n const [columnDefs, setColumnDefs] = useState([]);\n // tableDataList\n const [tableData, setTableData] = useState([]);\n // 分页总条数\n const [total, setTotal] = useState(undefined);\n // table列表loading\n const [loading, setloading] = useState(true);\n // 请求列表的参数\n const paramsCurrent = useRef(getSesstion() || {});\n // 是否还有搜索条件\n const [filterKey, setfilterKey] = useState(getSesstion()?.filter || []);\n // 请求序号,用于丢弃过期响应,避免竞态导致旧数据覆盖新数据\n const requestIdRef = useRef(0);\n\n /* ---------------------------------------------------------------- *\n * 调用方传入的函数/对象通过 ref 持有,避免进入依赖数组导致死循环\n * ---------------------------------------------------------------- */\n const tableRequestRef = useRef(tableRequest);\n tableRequestRef.current = tableRequest;\n const tableUrlRef = useRef(tableUrl);\n tableUrlRef.current = tableUrl;\n const setParamsListRef = useRef(setParamsList);\n setParamsListRef.current = setParamsList;\n const renderKeyRef = useRef(renderKey);\n renderKeyRef.current = renderKey;\n const getColConfigRequestRef = useRef(getColConfigRequest);\n getColConfigRequestRef.current = getColConfigRequest;\n const saveColConfigRequestRef = useRef(saveColConfigRequest);\n saveColConfigRequestRef.current = saveColConfigRequest;\n\n /* ---------------------------------------------------------------- *\n * 1. checkHeadCols —— 无外部依赖\n * ---------------------------------------------------------------- */\n const checkHeadCols = useCallback(() => {\n const { sort } = paramsCurrent.current;\n const NewArr = columRef.current.map((item) => {\n return {\n ...item,\n sort: sort && sort.colId == item.field ? sort.sort : undefined,\n };\n });\n setColumnDefs(deepClone(NewArr));\n }, []);\n\n /* ---------------------------------------------------------------- *\n * 2. saveColConfig —— 依赖 checkHeadCols 之外无\n * ---------------------------------------------------------------- */\n const saveColConfig = useCallback(() => {\n const request = saveColConfigRequestRef.current;\n if (!request) {\n console.warn('[useTableModule] 未注入 saveColConfigRequest,跳过列配置保存');\n return;\n }\n const params = {\n subcategory: configKey,\n userConfig: {\n pageConfig: {\n pageSize: paramsCurrent.current.size ? paramsCurrent.current.size : null,\n },\n columnConfig: columRef.current,\n },\n };\n const res = request(params);\n // 保存失败不应阻断表格交互\n if (res && typeof res.catch === 'function') {\n res.catch((err) => console.error('[useTableModule] 列配置保存失败:', err));\n }\n }, [configKey]);\n\n /* ---------------------------------------------------------------- *\n * 3. getTableData —— 列表数据请求\n * ---------------------------------------------------------------- */\n const getTableData = useCallback(() => {\n const request = tableRequestRef.current;\n if (!request) {\n console.warn('[useTableModule] 未注入 tableRequest,跳过列表加载');\n setloading(false);\n return;\n }\n // 标记本次请求序号,响应回来时若不是最新的一次则丢弃\n requestIdRef.current += 1;\n const currentId = requestIdRef.current;\n\n const transform = setParamsListRef.current;\n const newParams = transform ? transform(paramsCurrent.current) : paramsCurrent.current;\n setloading(true);\n return request(newParams, tableUrlRef.current).then(\n (res) => {\n // 已有更新的请求发出,丢弃本次过期响应\n if (currentId !== requestIdRef.current) return;\n const response = res?.response;\n // 接口可能返回 { response: { data: [], total } } 或 { response: [] } 两种结构\n const rows = Array.isArray(response) ? response : response?.data || [];\n // 总条数用于分页展示,缺失时保持为 undefined 由 TableList 兜底\n const totalCount = Array.isArray(response) ? undefined : response?.total;\n if (typeof totalCount === 'number' && !Number.isNaN(totalCount)) {\n setTotal(totalCount);\n }\n const newData = rows.map((item) => {\n return {\n ...item,\n ...(item._source || {}),\n };\n });\n setTableData(newData);\n setloading(false);\n },\n (err) => {\n if (currentId !== requestIdRef.current) return;\n console.error('[useTableModule] 列表加载失败:', err);\n // 失败时也要关掉 loading,否则界面永久卡在加载态\n setloading(false);\n },\n );\n }, []);\n\n /* ---------------------------------------------------------------- *\n * 4. handleColumn —— 表头变更统一入口\n * ---------------------------------------------------------------- */\n const handleColumn = useCallback(\n (params) => {\n const { column, optType, sort, pagination, filter } = params;\n let arrHead = [];\n if (column) {\n // 拖拽 / 自定义列显隐\n // 注意:column 里的顺序即最终顺序,需要按 column 的顺序重建,\n // 同时保留 columRef.current 中未被 column 覆盖的列,避免丢列。\n const columnMap = new Map(column.map((i) => [i.field, i]));\n arrHead = columRef.current.map((k) => {\n const matched = columnMap.get(k.field);\n if (!matched) return { ...k };\n const visible = matched.visible !== undefined ? matched.visible : !matched.hide;\n return { ...k, hide: !visible, visible };\n });\n\n // column 中存在但 columRef.current 中没有的列(新列),追加到末尾\n const existingFields = new Set(columRef.current.map((k) => k.field));\n column.forEach((i) => {\n if (!existingFields.has(i.field)) {\n const visible = i.visible !== undefined ? i.visible : !i.hide;\n arrHead.push({ ...i, hide: !visible, visible });\n }\n });\n\n columRef.current = arrHead;\n\n // 保持列配置\n saveColConfig();\n }\n if (optType == 'mergeColum') {\n // 合并表头\n setColumnDefs(deepClone(arrHead?.length ? arrHead : columRef.current));\n }\n if (optType == 'sort') {\n // 排序 注意 field 对应的是 colId\n paramsCurrent.current = {\n ...paramsCurrent.current,\n sort: sort,\n };\n\n saveSesstion(paramsCurrent.current);\n // 重新请求列表\n checkHeadCols();\n getTableData();\n }\n if (pagination) {\n // 分页\n paramsCurrent.current = {\n ...paramsCurrent.current,\n ...pagination,\n };\n saveSesstion(paramsCurrent.current);\n getTableData();\n }\n if (filter) {\n // 高级搜索\n paramsCurrent.current = {\n ...paramsCurrent.current,\n filter,\n };\n // 换筛选条件后回到第一页,否则可能停留在越界页码上导致空列表\n if (paramsCurrent.current.page && paramsCurrent.current.page > 1) {\n paramsCurrent.current.page = 1;\n }\n saveSesstion(paramsCurrent.current);\n getTableData();\n }\n },\n [saveSesstion, saveColConfig, checkHeadCols, getTableData],\n );\n\n /* ---------------------------------------------------------------- *\n * 5. getColConfig —— 列配置加载\n * ---------------------------------------------------------------- */\n const getColConfig = useCallback(() => {\n const request = getColConfigRequestRef.current;\n if (!request) {\n console.warn('[useTableModule] 未注入 getColConfigRequest,跳过列配置加载');\n setloading(false);\n return;\n }\n const { sort } = paramsCurrent.current;\n const currentRenderKey = renderKeyRef.current;\n request(configKey).then(\n ({ response }) => {\n const columnConfig = response?.userConfig?.columnConfig || [];\n const newArr = columnConfig.map((item) => {\n return {\n ...item,\n hide: !item.visible,\n visible: item.visible,\n sort: sort && sort.colId == item.field ? sort.sort : undefined,\n render: currentRenderKey ? currentRenderKey[item.field] : undefined,\n };\n });\n setColumnDefs(deepClone(newArr));\n columRef.current = deepClone(newArr);\n getTableData();\n },\n (err) => {\n console.error('[useTableModule] 列配置加载失败:', err);\n setloading(false);\n },\n );\n }, [configKey, getTableData]);\n\n /* ---------------------------------------------------------------- *\n * 6. resetSesstion —— 重置搜索条件\n * ---------------------------------------------------------------- */\n const resetSesstion = useCallback(() => {\n const session = getSesstion() || {};\n paramsCurrent.current = session;\n setfilterKey(session.filter || []);\n checkHeadCols();\n // 重置后必须重新拉数据,否则表格仍显示旧的筛选结果\n getTableData();\n }, [getSesstion, checkHeadCols, getTableData]);\n\n // 仅在 configKey 变化时加载一次列配置。\n // 依赖里若放入 getColConfigRequest(调用方常传内联函数,身份每渲染都变)\n // 会造成无限请求循环,因此请求函数通过 ref 读取。\n useEffect(() => {\n if (configKey) {\n // 交给 getColConfig 内部判断接口是否注入,未注入时它会给出提示并关闭 loading\n getColConfig();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [configKey]);\n\n const SettingTableRender = useCallback(\n (props = {}) => {\n return <SettingTable columRef={columRef} onChange={handleColumn} {...props}></SettingTable>;\n },\n [handleColumn],\n );\n\n const TableListRender = useCallback(\n (props = {}) => {\n return (\n <TableList\n filterKey={filterKey}\n setfilterKey={setfilterKey}\n loading={loading}\n columnDefs={columnDefs}\n pagination={{\n current: paramsCurrent.current.page,\n pageSize: paramsCurrent.current.size,\n total,\n }}\n onChange={handleColumn}\n tableData={tableData}\n {...props}\n />\n );\n },\n [filterKey, loading, columnDefs, tableData, total, handleColumn],\n );\n\n return {\n SettingTableRender,\n TableListRender,\n // 需要单独回调的就抛出去,特殊场景多个列表使用,平常用url回调一次\n getTableData, //获取列表数据\n getColConfig, //获取配置接口\n saveColConfig, //保存配置接口\n resetSesstion,\n tableData,\n setloading,\n // 原实现漏掉了 loading / columnDefs / paramsCurrent / total,\n // 使用方无法感知加载态与分页总数,这里补齐。\n loading,\n columnDefs,\n paramsCurrent,\n total,\n filterKey,\n };\n};\nexport default useTableModule;\n","import { Input } from 'antd';\r\nimport { useMemo } from 'react';\r\n\r\nconst defaultStyle = {\r\n width: '100%',\r\n};\r\n\r\n/**\r\n * 列表页自定义搜索插槽\r\n *\r\n * @param dataIndex 字段名\r\n * @param language 是否英文\r\n * @param onChange 值变化回调\r\n * @param value 当前值\r\n */\r\nconst OtherSlot = ({ dataIndex, language, onChange, value, ...reset }) => {\r\n const slotOther = useMemo(() => {\r\n return (\r\n <Input\r\n value={value?.length ? value : null}\r\n style={defaultStyle}\r\n {...reset}\r\n onChange={(e) => {\r\n onChange(e.target.value);\r\n }}\r\n ></Input>\r\n );\r\n // dataIndex / value 变化时重建;其余字段由调用方通过 reset 透传\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [dataIndex, value]);\r\n return (\r\n <div\r\n style={{\r\n marginBottom: 8,\r\n }}\r\n >\r\n {slotOther}\r\n </div>\r\n );\r\n};\r\nexport default OtherSlot;\r\n"],"names":["isEmpty","value","get","obj","path","defaultValue","keys","cur","i","formatNumber","digits","num","formatMoney","options","symbol","showSymbol","showZeroZero","abs","prefix","formatPercent","groupBy","list","keyFn","result","item","key","omitEmpty","debounce","fn","wait","timer","args","cx","MayList","objectsArray","deepClone","seen","arr","Text","Typography","TextCell","React","MoneyCell","NumberCell","percent","TagCell","color","tagColor","text","hit","o","Tag","EllipsisCell","length","str","Tooltip","LinkCell","onClick","ActionCell","actions","action","crmTheme","STATUS_PRESETS","DICT_COLOR_MAP","AG_GRID_THEMES","DEFAULT_AG_GRID_THEME","agGridClass","theme","extra","ROW_HEIGHT_PRESETS","iconSet","iconsNs","SearchOutlined","SettingOutlined","SettingTable","onChange","columRef","language","useSelector","state","settingStatus","setSettingStatus","useState","headerCloumsList","setHeaderCloumsList","useEffect","current","saveQuit","changeCheck","index","openInitHeadList","Popover","Styles","open","Checkbox","e","Button","svgProps","SortAscending","props","SortDescending","SortUnSort","CustomHeader","ascSort","setAscSort","descSort","setDescSort","noSort","setNoSort","refButton","useRef","setopen","valueDefs","setvalueDefs","onMenuClicked","_a","onSortChanged","sort","onSortRequested","order","event","column","defaultStyle","context","useMemo","Render","Input","_b","search","filterKeyArrary","values","TableList","columnDefs","loading","customBottomTotal","tableRef","tableData","pagination","reset","customColumn","filterSearchRender","setfilterKey","filterKey","containerStyle","gridStyle","total","fromPagination","pinnedBottomRowData","objTotal","disableTotal","defaultCol","valueA","valueB","nodeA","nodeB","isDescending","defaultColDef","onGridReady","useCallback","params","getCellParams","isNotTip","render","isTotalRow","sortChanged","sortModel","onDragStopped","handleChangePage","page","size","Spin","AgGridReact","Pagination","useTableModule","tProps","defaultProps","sessionKey","renderKey","setParamsList","configKey","tableUrl","tableRequest","getColConfigRequest","saveColConfigRequest","canUseSession","saveSesstion","err","getSesstion","raw","setColumnDefs","setTableData","setTotal","setloading","paramsCurrent","requestIdRef","tableRequestRef","tableUrlRef","setParamsListRef","renderKeyRef","getColConfigRequestRef","saveColConfigRequestRef","checkHeadCols","NewArr","saveColConfig","request","res","getTableData","currentId","transform","newParams","response","rows","totalCount","newData","handleColumn","optType","filter","arrHead","columnMap","k","matched","visible","existingFields","getColConfig","currentRenderKey","newArr","resetSesstion","session","SettingTableRender","TableListRender","OtherSlot","dataIndex","slotOther"],"mappings":"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"}
|