@go-wind/admin-react 0.1.0 → 0.3.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.
@@ -0,0 +1,31 @@
1
+ import type { ThHTMLAttributes } from 'react';
2
+ /** 拖拽调整列宽的下限(px),防止把一列拖没 */
3
+ export declare const MIN_COLUMN_WIDTH = 60;
4
+ /**
5
+ * ListTable 经 column.onHeaderCell 注入、随 rc-table 的 additionalProps 铺到表头 th 上的
6
+ * 拖拽参数。只有这些键会被本组件摘走,其余属性原样透传给 <th>(含排序注入的 onClick)。
7
+ */
8
+ export interface ResizableCellProps {
9
+ 'data-resize-key'?: string;
10
+ onResizeStart?: (info: {
11
+ key: string;
12
+ width: number;
13
+ allWidths: Record<string, number>;
14
+ containerWidth: number;
15
+ }) => void;
16
+ onResize?: (key: string, width: number) => void;
17
+ onResizeEnd?: () => void;
18
+ onResizeReset?: () => void;
19
+ resizing?: boolean;
20
+ resizeTitle?: string;
21
+ }
22
+ type HeaderCellProps = ResizableCellProps & ThHTMLAttributes<HTMLTableCellElement>;
23
+ /**
24
+ * 表头单元格的列宽拖拽把手。热区是列右缘的隐形 span:pointerdown 起 pointer capture 全程
25
+ * 接管指针(移出表头也不丢事件),按下时把当前表头行所有列的渲染宽度上报给 ListTable 做
26
+ * 「首拖锁定」,移动中持续回报新宽度,双击把手恢复自适应。
27
+ *
28
+ * 不引第三方库:react-resizable 年久失修不兼容 React 19,指针事件自持足够。
29
+ */
30
+ export declare function ResizableHeaderCell(props: HeaderCellProps): import("react").JSX.Element;
31
+ export default ResizableHeaderCell;
@@ -0,0 +1,25 @@
1
+ import type { TableProps } from 'antd';
2
+ import type { ProColumns } from '@ant-design/pro-components';
3
+ export interface TableSkeletonProps<RecordType extends Record<string, any>> {
4
+ columns?: ProColumns<RecordType>[];
5
+ rows: number;
6
+ size?: TableProps<RecordType>['size'];
7
+ bordered?: boolean;
8
+ /**
9
+ * 横向 scroll:决定骨架的列宽能否与真实表格逐列对齐。
10
+ * 纵向 scroll:真实表格有它就必须一起接——那层限高 `.ant-table-body` 是分页器落点的决定者,
11
+ * 骨架少了它就只能按 rows 撑高,首屏→数据到位会让分页器整段跳动。
12
+ */
13
+ scrollX?: number | string | true;
14
+ scrollY?: number | string;
15
+ pagination?: TableProps<RecordType>['pagination'];
16
+ }
17
+ /**
18
+ * 列表首屏骨架。
19
+ *
20
+ * 直接用 antd Table 当量具:表头底色、列宽、边框、字号、暗色 token 全部由页面自己的
21
+ * columns 与组件主题供给,占位条只替换单元格 render——自画一份灰块会跟真实表格对不齐,
22
+ * 尤其在有 fixed 列 / scroll.x / bordered 的页面上。
23
+ */
24
+ export declare function TableSkeleton<RecordType extends Record<string, any>>({ columns, rows, size, bordered, scrollX, scrollY, pagination, }: TableSkeletonProps<RecordType>): import("react").JSX.Element;
25
+ export default TableSkeleton;
@@ -0,0 +1,20 @@
1
+ import type { ProTableProps } from '@ant-design/pro-components';
2
+ import './list-table.css';
3
+ type ListTableProps<RecordType extends Record<string, any>, Params extends Record<string, any> = Record<string, any>> = ProTableProps<RecordType, Params>;
4
+ /**
5
+ * 列表页统一表格:在 ProTable 之上补四件页面各自都没有的事——首屏骨架屏(按页面 columns 生成,
6
+ * 受偏好设置 transition.loading 控制)、快响应不闪的 Spin(delay)、请求失败的错误态与重试、
7
+ * 以及**高度自动撑满**。
8
+ *
9
+ * 高度契约(2026-10-22 起):页面不传 scroll.y 时,本组件自动接管撑满——内部测量容器
10
+ * (.listtable-fill)+ useProTableScrollY 把分页器钉在容器底,要求外层是 ContentContainer
11
+ * 这类 flex 列容器(非 flex 父级时自动退回自然高度,Drawer 内嵌表等场景不误伤)。
12
+ * 页面显式传了 scroll.y 则完全尊重(历史页面的手写样板照常工作,新页面不要再写)。
13
+ * 页面只需:<ContentContainer><ListTable …/></ContentContainer>。
14
+ *
15
+ * 页面把 `<ProTable>` 换成 `<ListTable>` 即可,request / columns / actionRef 用法不变。
16
+ */
17
+ export declare function ListTable<RecordType extends Record<string, any>, Params extends Record<string, any> = Record<string, any>>(props: ListTableProps<RecordType, Params> & {
18
+ striped?: boolean;
19
+ }): import("react").JSX.Element;
20
+ export default ListTable;
@@ -0,0 +1,35 @@
1
+ import type { PaginationQuery } from '../../transport/rest/pagination';
2
+ /**
3
+ * 列表导出按钮(CSV / Excel 下拉):内置分页聚合(默认上限 1 万行),
4
+ * 按 ProColumns(dataIndex/title,自动剔除 hideInTable 与操作列)生成文件并触发下载。
5
+ * fetcher 契约与审计导出一致:(query: PaginationQuery) => Promise<{ items, total }>。
6
+ *
7
+ * serverExport 提供时追加「服务端全量 (XLSX)」项:由后端生成(上限远大于客户端
8
+ * 聚合),query 经 PaginationQuery 同源序列化透传——导出的即当前搜索看到的。
9
+ * 仅接入与该列表读接口同权限语义的 :export 锚点(平台闸/租户视角由后端定)。
10
+ */
11
+ export interface TableExportServerExport {
12
+ /** 后端 :export 锚点(如 'admin/v1/ai/usage-logs:export') */
13
+ url: string;
14
+ /** 构造带当前搜索条件的查询(分页缺省=后端统一控行数) */
15
+ buildQuery: () => PaginationQuery;
16
+ }
17
+ export interface TableExportButtonProps {
18
+ fetcher: (query: PaginationQuery) => Promise<{
19
+ items?: any[];
20
+ total?: number | string;
21
+ }>;
22
+ /** ProColumns[](或 {title, dataIndex}[]),自动过滤出可导出列 */
23
+ columns: any[];
24
+ filename?: string;
25
+ maxRows?: number;
26
+ /**
27
+ * 强制附加的查询条件(与页面 request 闭包同源注入,如收件箱的 recipient_user_id)。
28
+ * 导出走本组件自己的聚合查询、不经过表格 request,页面在闭包里塞的隐式过滤
29
+ * 这里感知不到;不传会把隐私过滤一起丢掉,导出范围越权扩大。
30
+ */
31
+ params?: Record<string, any>;
32
+ /** 可选:服务端全量导出锚点与查询构造(不提供则菜单不含该项) */
33
+ serverExport?: TableExportServerExport;
34
+ }
35
+ export default function TableExportButton({ fetcher, columns, filename, maxRows, params, serverExport, }: TableExportButtonProps): import("react").JSX.Element;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 表格通用默认配置(自 go-wind-admin 的 config/constants.TABLE 迁入——
3
+ * ListTable 的默认分页/高度/滚动参数,宿主可在组件 props 层覆盖具体值)。
4
+ */
5
+ export declare const TABLE: {
6
+ /** 默认每页条数 */
7
+ readonly DEFAULT_PAGE_SIZE: 20;
8
+ /** 每页条数选项 */
9
+ readonly PAGE_SIZE_OPTIONS: readonly ["10", "20", "50", "100"];
10
+ /** 最大每页条数 */
11
+ readonly MAX_PAGE_SIZE: 100;
12
+ /** 表格组件内部高度 */
13
+ readonly COMPONENT_HEIGHTS: {
14
+ /** 工具栏高度 */
15
+ readonly TOOLBAR: 50;
16
+ /** 分页器高度 */
17
+ readonly PAGINATION: 50;
18
+ /** 表头高度 */
19
+ readonly HEADER: 50;
20
+ /** 搜索表单高度(展开时) */
21
+ readonly SEARCH_FORM: 80;
22
+ };
23
+ /** 表格滚动配置 */
24
+ readonly SCROLL_CONFIG: {
25
+ /** 默认最小高度 */
26
+ readonly MIN_HEIGHT: 300;
27
+ /** 额外边距 */
28
+ readonly OFFSET: 16;
29
+ };
30
+ };
package/dist/env.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  export declare function configureAdminRuntime(options?: {
2
2
  isDev?: boolean;
3
+ apiBaseUrl?: string;
3
4
  }): void;
4
5
  /** 宿主是否处于开发环境(用于 dev-only 诊断告警,生产恒为 false) */
5
6
  export declare function isDevMode(): boolean;
7
+ /**
8
+ * 宿主 API 基址(原 transport 的 VITE_API_URL,serverExportFile 拼绝对下载地址用;
9
+ * 开发态为 '/' 相对路径走代理,生产态为独立 API 域)。缺省空串 = 同源相对路径。
10
+ */
11
+ export declare function getApiBaseUrl(): string;
@@ -0,0 +1,3 @@
1
+ type CopyHandler = (text: string) => Promise<boolean>;
2
+ export declare function useClipboard(): [boolean, string, CopyHandler];
3
+ export {};
@@ -0,0 +1,10 @@
1
+ import * as echarts from 'echarts/core';
2
+ import type { BarSeriesOption, GaugeSeriesOption, LineSeriesOption, PictorialBarSeriesOption, PieSeriesOption, RadarSeriesOption, ScatterSeriesOption } from 'echarts/charts';
3
+ import type { DatasetComponentOption, GridComponentOption, LegendComponentOption, TitleComponentOption, ToolboxComponentOption, TooltipComponentOption } from 'echarts/components';
4
+ export type ECOption = echarts.ComposeOption<BarSeriesOption | LineSeriesOption | PieSeriesOption | ScatterSeriesOption | PictorialBarSeriesOption | RadarSeriesOption | GaugeSeriesOption | TitleComponentOption | LegendComponentOption | TooltipComponentOption | GridComponentOption | ToolboxComponentOption | DatasetComponentOption>;
5
+ /**
6
+ * 使用Echarts
7
+ * @param options - 绘制echarts的参数
8
+ * @param data - 数据
9
+ */
10
+ export declare const useEcharts: (options: echarts.EChartsCoreOption, data?: unknown) => readonly [import("react").RefObject<HTMLDivElement | null>, import("react").RefObject<echarts.ECharts | null>];
@@ -0,0 +1,13 @@
1
+ interface Options {
2
+ ArrowUp?: () => void;
3
+ ArrowDown?: () => void;
4
+ ArrowLeft?: () => void;
5
+ ArrowRight?: () => void;
6
+ Enter?: () => void;
7
+ }
8
+ /**
9
+ * 键盘按键事件
10
+ * @param options
11
+ */
12
+ export declare function useKeyStroke(options: Options): readonly [(even: KeyboardEvent) => void];
13
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 页面级全屏:元素 fullscreen + 进入时补页面底色(fullscreen 元素默认透出 UA 黑底)。
3
+ * 退出(含 ESC)由 fullscreenchange 事件驱动清理内联底色。
4
+ */
5
+ export declare function usePageFullscreen<T extends HTMLElement>(): {
6
+ rootRef: import("react").RefObject<T | null>;
7
+ isFullscreen: boolean;
8
+ toggle: () => void;
9
+ };
@@ -0,0 +1,20 @@
1
+ interface Option {
2
+ content: string;
3
+ height: number;
4
+ width: number;
5
+ rotate: number;
6
+ color: string;
7
+ fontSize: number;
8
+ opacity: number;
9
+ }
10
+ /**
11
+ * 水印
12
+ *
13
+ * @deprecated 此 hook 当前在全项目内无任何调用方,且实现存在隐患:
14
+ * 1) 未监听 window resize,窗口尺寸变化后水印不会重绘;
15
+ * 2) 尺寸基于 document.body 计算,body 高度为 0 时(如路由切换瞬间)覆盖不全;
16
+ * 3) 作为普通函数而非 React hook,调用方需自行管理生命周期。
17
+ * 启用前请先补全上述问题,否则按需删除。
18
+ */
19
+ export declare function useWatermark(): readonly [(options: Option) => void, () => void];
20
+ export {};
@@ -4,8 +4,8 @@ import { type SupportedLocale } from '../../locales';
4
4
  * 文案 = 包内置框架命名空间(coreResources)+ 宿主业务命名空间合并后传入。
5
5
  */
6
6
  export interface InitI18nOptions {
7
- /** 合并后的完整语言资源(语言 -> 命名空间 -> 文案) */
8
- resources: Record<string, Record<string, Record<string, unknown>>>;
7
+ /** 合并后的完整语言资源(语言 -> 命名空间 -> 文案;i18next Resource 兼容形状) */
8
+ resources: Record<string, unknown>;
9
9
  /** 全部命名空间列表(一般取 merged['zh-CN'] 的键) */
10
10
  namespaces: string[];
11
11
  /** 支持的语言列表(默认 zh-CN/en-US) */
package/dist/index.d.ts CHANGED
@@ -30,5 +30,15 @@ export * from './hooks/useTokenRefresh';
30
30
  export * from './hooks/useTitle';
31
31
  export * from './hooks/useTime';
32
32
  export * from './hooks/useProTableScrollY';
33
+ export * from './hooks/useClipboard';
34
+ export * from './hooks/useKeyStroke';
35
+ export * from './hooks/usePageFullscreen';
36
+ export * from './hooks/useEcharts';
37
+ export * from './hooks/useWatermark';
33
38
  export * from './utils';
39
+ export * from './constants';
40
+ export * from './components/ListTable';
41
+ export * from './utils/export-table';
42
+ export * from './transport/rest/server-export';
43
+ export { default as TableExportButton } from './components/TableExportButton';
34
44
  export { default as ThemeLoading } from './components/Loading';
@@ -1,4 +1,4 @@
1
- import { t as e } from "./rolldown-runtime-BbCBk-LD.js";
1
+ import { t as e } from "./rolldown-runtime-DkdWOuC0.js";
2
2
  // ../../node_modules/.pnpm/nprogress@0.2.0/node_modules/nprogress/nprogress.js
3
3
  var t = /* @__PURE__ */ e(((e, t, n) => {
4
4
  (function(n, r) {
@@ -156,4 +156,4 @@ var t = /* @__PURE__ */ e(((e, t, n) => {
156
156
  }));
157
157
  export default t();
158
158
 
159
- //# sourceMappingURL=nprogress-CwfUlis6.js.map
159
+ //# sourceMappingURL=nprogress-BVDIj-o2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nprogress-CwfUlis6.js","names":["__commonJSMin","require_nprogress","factory","exports","this$1","NProgress","Settings","key","value","options","started","clamp","n","progress","bar","speed","ease","queue","css","barPositionCSS","next","work","force","amount","initial","current","$promise","perc","fromStart","toBarPerc","parent","spinner","removeElement","addClass","removeClass","bodyStyle","vendorPrefix","min","max","barCSS","pending","fn","cssPrefixes","cssProps","camelCase","string","letter","getVendorProp","style","name","i","capName","vendorName","getStyleProp","applyCss","prop","args","properties","element","hasClass","classList","oldList","newList"],"sources":["../../../node_modules/.pnpm/nprogress@0.2.0/node_modules/nprogress/nprogress.js"],"sourcesContent":["/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress\n * @license MIT */\n\n;(function(root, factory) {\n\n if (typeof define === 'function' && define.amd) {\n define(factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.NProgress = factory();\n }\n\n})(this, function() {\n var NProgress = {};\n\n NProgress.version = '0.2.0';\n\n var Settings = NProgress.settings = {\n minimum: 0.08,\n easing: 'ease',\n positionUsing: '',\n speed: 200,\n trickle: true,\n trickleRate: 0.02,\n trickleSpeed: 800,\n showSpinner: true,\n barSelector: '[role=\"bar\"]',\n spinnerSelector: '[role=\"spinner\"]',\n parent: 'body',\n template: '<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>'\n };\n\n /**\n * Updates configuration.\n *\n * NProgress.configure({\n * minimum: 0.1\n * });\n */\n NProgress.configure = function(options) {\n var key, value;\n for (key in options) {\n value = options[key];\n if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;\n }\n\n return this;\n };\n\n /**\n * Last number.\n */\n\n NProgress.status = null;\n\n /**\n * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.\n *\n * NProgress.set(0.4);\n * NProgress.set(1.0);\n */\n\n NProgress.set = function(n) {\n var started = NProgress.isStarted();\n\n n = clamp(n, Settings.minimum, 1);\n NProgress.status = (n === 1 ? null : n);\n\n var progress = NProgress.render(!started),\n bar = progress.querySelector(Settings.barSelector),\n speed = Settings.speed,\n ease = Settings.easing;\n\n progress.offsetWidth; /* Repaint */\n\n queue(function(next) {\n // Set positionUsing if it hasn't already been set\n if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();\n\n // Add transition\n css(bar, barPositionCSS(n, speed, ease));\n\n if (n === 1) {\n // Fade out\n css(progress, { \n transition: 'none', \n opacity: 1 \n });\n progress.offsetWidth; /* Repaint */\n\n setTimeout(function() {\n css(progress, { \n transition: 'all ' + speed + 'ms linear', \n opacity: 0 \n });\n setTimeout(function() {\n NProgress.remove();\n next();\n }, speed);\n }, speed);\n } else {\n setTimeout(next, speed);\n }\n });\n\n return this;\n };\n\n NProgress.isStarted = function() {\n return typeof NProgress.status === 'number';\n };\n\n /**\n * Shows the progress bar.\n * This is the same as setting the status to 0%, except that it doesn't go backwards.\n *\n * NProgress.start();\n *\n */\n NProgress.start = function() {\n if (!NProgress.status) NProgress.set(0);\n\n var work = function() {\n setTimeout(function() {\n if (!NProgress.status) return;\n NProgress.trickle();\n work();\n }, Settings.trickleSpeed);\n };\n\n if (Settings.trickle) work();\n\n return this;\n };\n\n /**\n * Hides the progress bar.\n * This is the *sort of* the same as setting the status to 100%, with the\n * difference being `done()` makes some placebo effect of some realistic motion.\n *\n * NProgress.done();\n *\n * If `true` is passed, it will show the progress bar even if its hidden.\n *\n * NProgress.done(true);\n */\n\n NProgress.done = function(force) {\n if (!force && !NProgress.status) return this;\n\n return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);\n };\n\n /**\n * Increments by a random amount.\n */\n\n NProgress.inc = function(amount) {\n var n = NProgress.status;\n\n if (!n) {\n return NProgress.start();\n } else {\n if (typeof amount !== 'number') {\n amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);\n }\n\n n = clamp(n + amount, 0, 0.994);\n return NProgress.set(n);\n }\n };\n\n NProgress.trickle = function() {\n return NProgress.inc(Math.random() * Settings.trickleRate);\n };\n\n /**\n * Waits for all supplied jQuery promises and\n * increases the progress as the promises resolve.\n *\n * @param $promise jQUery Promise\n */\n (function() {\n var initial = 0, current = 0;\n\n NProgress.promise = function($promise) {\n if (!$promise || $promise.state() === \"resolved\") {\n return this;\n }\n\n if (current === 0) {\n NProgress.start();\n }\n\n initial++;\n current++;\n\n $promise.always(function() {\n current--;\n if (current === 0) {\n initial = 0;\n NProgress.done();\n } else {\n NProgress.set((initial - current) / initial);\n }\n });\n\n return this;\n };\n\n })();\n\n /**\n * (Internal) renders the progress bar markup based on the `template`\n * setting.\n */\n\n NProgress.render = function(fromStart) {\n if (NProgress.isRendered()) return document.getElementById('nprogress');\n\n addClass(document.documentElement, 'nprogress-busy');\n \n var progress = document.createElement('div');\n progress.id = 'nprogress';\n progress.innerHTML = Settings.template;\n\n var bar = progress.querySelector(Settings.barSelector),\n perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),\n parent = document.querySelector(Settings.parent),\n spinner;\n \n css(bar, {\n transition: 'all 0 linear',\n transform: 'translate3d(' + perc + '%,0,0)'\n });\n\n if (!Settings.showSpinner) {\n spinner = progress.querySelector(Settings.spinnerSelector);\n spinner && removeElement(spinner);\n }\n\n if (parent != document.body) {\n addClass(parent, 'nprogress-custom-parent');\n }\n\n parent.appendChild(progress);\n return progress;\n };\n\n /**\n * Removes the element. Opposite of render().\n */\n\n NProgress.remove = function() {\n removeClass(document.documentElement, 'nprogress-busy');\n removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');\n var progress = document.getElementById('nprogress');\n progress && removeElement(progress);\n };\n\n /**\n * Checks if the progress bar is rendered.\n */\n\n NProgress.isRendered = function() {\n return !!document.getElementById('nprogress');\n };\n\n /**\n * Determine which positioning CSS rule to use.\n */\n\n NProgress.getPositioningCSS = function() {\n // Sniff on document.body.style\n var bodyStyle = document.body.style;\n\n // Sniff prefixes\n var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :\n ('MozTransform' in bodyStyle) ? 'Moz' :\n ('msTransform' in bodyStyle) ? 'ms' :\n ('OTransform' in bodyStyle) ? 'O' : '';\n\n if (vendorPrefix + 'Perspective' in bodyStyle) {\n // Modern browsers with 3D support, e.g. Webkit, IE10\n return 'translate3d';\n } else if (vendorPrefix + 'Transform' in bodyStyle) {\n // Browsers without 3D support, e.g. IE9\n return 'translate';\n } else {\n // Browsers without translate() support, e.g. IE7-8\n return 'margin';\n }\n };\n\n /**\n * Helpers\n */\n\n function clamp(n, min, max) {\n if (n < min) return min;\n if (n > max) return max;\n return n;\n }\n\n /**\n * (Internal) converts a percentage (`0..1`) to a bar translateX\n * percentage (`-100%..0%`).\n */\n\n function toBarPerc(n) {\n return (-1 + n) * 100;\n }\n\n\n /**\n * (Internal) returns the correct CSS for changing the bar's\n * position given an n percentage, and speed and ease from Settings\n */\n\n function barPositionCSS(n, speed, ease) {\n var barCSS;\n\n if (Settings.positionUsing === 'translate3d') {\n barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };\n } else if (Settings.positionUsing === 'translate') {\n barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };\n } else {\n barCSS = { 'margin-left': toBarPerc(n)+'%' };\n }\n\n barCSS.transition = 'all '+speed+'ms '+ease;\n\n return barCSS;\n }\n\n /**\n * (Internal) Queues a function to be executed.\n */\n\n var queue = (function() {\n var pending = [];\n \n function next() {\n var fn = pending.shift();\n if (fn) {\n fn(next);\n }\n }\n\n return function(fn) {\n pending.push(fn);\n if (pending.length == 1) next();\n };\n })();\n\n /**\n * (Internal) Applies css properties to an element, similar to the jQuery \n * css method.\n *\n * While this helper does assist with vendor prefixed property names, it \n * does not perform any manipulation of values prior to setting styles.\n */\n\n var css = (function() {\n var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],\n cssProps = {};\n\n function camelCase(string) {\n return string.replace(/^-ms-/, 'ms-').replace(/-([\\da-z])/gi, function(match, letter) {\n return letter.toUpperCase();\n });\n }\n\n function getVendorProp(name) {\n var style = document.body.style;\n if (name in style) return name;\n\n var i = cssPrefixes.length,\n capName = name.charAt(0).toUpperCase() + name.slice(1),\n vendorName;\n while (i--) {\n vendorName = cssPrefixes[i] + capName;\n if (vendorName in style) return vendorName;\n }\n\n return name;\n }\n\n function getStyleProp(name) {\n name = camelCase(name);\n return cssProps[name] || (cssProps[name] = getVendorProp(name));\n }\n\n function applyCss(element, prop, value) {\n prop = getStyleProp(prop);\n element.style[prop] = value;\n }\n\n return function(element, properties) {\n var args = arguments,\n prop, \n value;\n\n if (args.length == 2) {\n for (prop in properties) {\n value = properties[prop];\n if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);\n }\n } else {\n applyCss(element, args[1], args[2]);\n }\n }\n })();\n\n /**\n * (Internal) Determines if an element or space separated list of class names contains a class name.\n */\n\n function hasClass(element, name) {\n var list = typeof element == 'string' ? element : classList(element);\n return list.indexOf(' ' + name + ' ') >= 0;\n }\n\n /**\n * (Internal) Adds a class to an element.\n */\n\n function addClass(element, name) {\n var oldList = classList(element),\n newList = oldList + name;\n\n if (hasClass(oldList, name)) return; \n\n // Trim the opening space.\n element.className = newList.substring(1);\n }\n\n /**\n * (Internal) Removes a class from an element.\n */\n\n function removeClass(element, name) {\n var oldList = classList(element),\n newList;\n\n if (!hasClass(element, name)) return;\n\n // Replace the class name.\n newList = oldList.replace(' ' + name + ' ', ' ');\n\n // Trim the opening and closing spaces.\n element.className = newList.substring(1, newList.length - 1);\n }\n\n /**\n * (Internal) Gets a space separated list of the class names on the element. \n * The list is wrapped with a single space on each end to facilitate finding \n * matches within the list.\n */\n\n function classList(element) {\n return (' ' + (element.className || '') + ' ').replace(/\\s+/gi, ' ');\n }\n\n /**\n * (Internal) Removes an element from the DOM.\n */\n\n function removeElement(element) {\n element && element.parentNode && element.parentNode.removeChild(element);\n }\n\n return NProgress;\n});\n\n"],"ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"nprogress-BVDIj-o2.js","names":["__commonJSMin","require_nprogress","factory","exports","this$1","NProgress","Settings","key","value","options","started","clamp","n","progress","bar","speed","ease","queue","css","barPositionCSS","next","work","force","amount","initial","current","$promise","perc","fromStart","toBarPerc","parent","spinner","removeElement","addClass","removeClass","bodyStyle","vendorPrefix","min","max","barCSS","pending","fn","cssPrefixes","cssProps","camelCase","string","letter","getVendorProp","style","name","i","capName","vendorName","getStyleProp","applyCss","prop","args","properties","element","hasClass","classList","oldList","newList"],"sources":["../../../node_modules/.pnpm/nprogress@0.2.0/node_modules/nprogress/nprogress.js"],"sourcesContent":["/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress\n * @license MIT */\n\n;(function(root, factory) {\n\n if (typeof define === 'function' && define.amd) {\n define(factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.NProgress = factory();\n }\n\n})(this, function() {\n var NProgress = {};\n\n NProgress.version = '0.2.0';\n\n var Settings = NProgress.settings = {\n minimum: 0.08,\n easing: 'ease',\n positionUsing: '',\n speed: 200,\n trickle: true,\n trickleRate: 0.02,\n trickleSpeed: 800,\n showSpinner: true,\n barSelector: '[role=\"bar\"]',\n spinnerSelector: '[role=\"spinner\"]',\n parent: 'body',\n template: '<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>'\n };\n\n /**\n * Updates configuration.\n *\n * NProgress.configure({\n * minimum: 0.1\n * });\n */\n NProgress.configure = function(options) {\n var key, value;\n for (key in options) {\n value = options[key];\n if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;\n }\n\n return this;\n };\n\n /**\n * Last number.\n */\n\n NProgress.status = null;\n\n /**\n * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.\n *\n * NProgress.set(0.4);\n * NProgress.set(1.0);\n */\n\n NProgress.set = function(n) {\n var started = NProgress.isStarted();\n\n n = clamp(n, Settings.minimum, 1);\n NProgress.status = (n === 1 ? null : n);\n\n var progress = NProgress.render(!started),\n bar = progress.querySelector(Settings.barSelector),\n speed = Settings.speed,\n ease = Settings.easing;\n\n progress.offsetWidth; /* Repaint */\n\n queue(function(next) {\n // Set positionUsing if it hasn't already been set\n if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();\n\n // Add transition\n css(bar, barPositionCSS(n, speed, ease));\n\n if (n === 1) {\n // Fade out\n css(progress, { \n transition: 'none', \n opacity: 1 \n });\n progress.offsetWidth; /* Repaint */\n\n setTimeout(function() {\n css(progress, { \n transition: 'all ' + speed + 'ms linear', \n opacity: 0 \n });\n setTimeout(function() {\n NProgress.remove();\n next();\n }, speed);\n }, speed);\n } else {\n setTimeout(next, speed);\n }\n });\n\n return this;\n };\n\n NProgress.isStarted = function() {\n return typeof NProgress.status === 'number';\n };\n\n /**\n * Shows the progress bar.\n * This is the same as setting the status to 0%, except that it doesn't go backwards.\n *\n * NProgress.start();\n *\n */\n NProgress.start = function() {\n if (!NProgress.status) NProgress.set(0);\n\n var work = function() {\n setTimeout(function() {\n if (!NProgress.status) return;\n NProgress.trickle();\n work();\n }, Settings.trickleSpeed);\n };\n\n if (Settings.trickle) work();\n\n return this;\n };\n\n /**\n * Hides the progress bar.\n * This is the *sort of* the same as setting the status to 100%, with the\n * difference being `done()` makes some placebo effect of some realistic motion.\n *\n * NProgress.done();\n *\n * If `true` is passed, it will show the progress bar even if its hidden.\n *\n * NProgress.done(true);\n */\n\n NProgress.done = function(force) {\n if (!force && !NProgress.status) return this;\n\n return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);\n };\n\n /**\n * Increments by a random amount.\n */\n\n NProgress.inc = function(amount) {\n var n = NProgress.status;\n\n if (!n) {\n return NProgress.start();\n } else {\n if (typeof amount !== 'number') {\n amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);\n }\n\n n = clamp(n + amount, 0, 0.994);\n return NProgress.set(n);\n }\n };\n\n NProgress.trickle = function() {\n return NProgress.inc(Math.random() * Settings.trickleRate);\n };\n\n /**\n * Waits for all supplied jQuery promises and\n * increases the progress as the promises resolve.\n *\n * @param $promise jQUery Promise\n */\n (function() {\n var initial = 0, current = 0;\n\n NProgress.promise = function($promise) {\n if (!$promise || $promise.state() === \"resolved\") {\n return this;\n }\n\n if (current === 0) {\n NProgress.start();\n }\n\n initial++;\n current++;\n\n $promise.always(function() {\n current--;\n if (current === 0) {\n initial = 0;\n NProgress.done();\n } else {\n NProgress.set((initial - current) / initial);\n }\n });\n\n return this;\n };\n\n })();\n\n /**\n * (Internal) renders the progress bar markup based on the `template`\n * setting.\n */\n\n NProgress.render = function(fromStart) {\n if (NProgress.isRendered()) return document.getElementById('nprogress');\n\n addClass(document.documentElement, 'nprogress-busy');\n \n var progress = document.createElement('div');\n progress.id = 'nprogress';\n progress.innerHTML = Settings.template;\n\n var bar = progress.querySelector(Settings.barSelector),\n perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),\n parent = document.querySelector(Settings.parent),\n spinner;\n \n css(bar, {\n transition: 'all 0 linear',\n transform: 'translate3d(' + perc + '%,0,0)'\n });\n\n if (!Settings.showSpinner) {\n spinner = progress.querySelector(Settings.spinnerSelector);\n spinner && removeElement(spinner);\n }\n\n if (parent != document.body) {\n addClass(parent, 'nprogress-custom-parent');\n }\n\n parent.appendChild(progress);\n return progress;\n };\n\n /**\n * Removes the element. Opposite of render().\n */\n\n NProgress.remove = function() {\n removeClass(document.documentElement, 'nprogress-busy');\n removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');\n var progress = document.getElementById('nprogress');\n progress && removeElement(progress);\n };\n\n /**\n * Checks if the progress bar is rendered.\n */\n\n NProgress.isRendered = function() {\n return !!document.getElementById('nprogress');\n };\n\n /**\n * Determine which positioning CSS rule to use.\n */\n\n NProgress.getPositioningCSS = function() {\n // Sniff on document.body.style\n var bodyStyle = document.body.style;\n\n // Sniff prefixes\n var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :\n ('MozTransform' in bodyStyle) ? 'Moz' :\n ('msTransform' in bodyStyle) ? 'ms' :\n ('OTransform' in bodyStyle) ? 'O' : '';\n\n if (vendorPrefix + 'Perspective' in bodyStyle) {\n // Modern browsers with 3D support, e.g. Webkit, IE10\n return 'translate3d';\n } else if (vendorPrefix + 'Transform' in bodyStyle) {\n // Browsers without 3D support, e.g. IE9\n return 'translate';\n } else {\n // Browsers without translate() support, e.g. IE7-8\n return 'margin';\n }\n };\n\n /**\n * Helpers\n */\n\n function clamp(n, min, max) {\n if (n < min) return min;\n if (n > max) return max;\n return n;\n }\n\n /**\n * (Internal) converts a percentage (`0..1`) to a bar translateX\n * percentage (`-100%..0%`).\n */\n\n function toBarPerc(n) {\n return (-1 + n) * 100;\n }\n\n\n /**\n * (Internal) returns the correct CSS for changing the bar's\n * position given an n percentage, and speed and ease from Settings\n */\n\n function barPositionCSS(n, speed, ease) {\n var barCSS;\n\n if (Settings.positionUsing === 'translate3d') {\n barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };\n } else if (Settings.positionUsing === 'translate') {\n barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };\n } else {\n barCSS = { 'margin-left': toBarPerc(n)+'%' };\n }\n\n barCSS.transition = 'all '+speed+'ms '+ease;\n\n return barCSS;\n }\n\n /**\n * (Internal) Queues a function to be executed.\n */\n\n var queue = (function() {\n var pending = [];\n \n function next() {\n var fn = pending.shift();\n if (fn) {\n fn(next);\n }\n }\n\n return function(fn) {\n pending.push(fn);\n if (pending.length == 1) next();\n };\n })();\n\n /**\n * (Internal) Applies css properties to an element, similar to the jQuery \n * css method.\n *\n * While this helper does assist with vendor prefixed property names, it \n * does not perform any manipulation of values prior to setting styles.\n */\n\n var css = (function() {\n var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],\n cssProps = {};\n\n function camelCase(string) {\n return string.replace(/^-ms-/, 'ms-').replace(/-([\\da-z])/gi, function(match, letter) {\n return letter.toUpperCase();\n });\n }\n\n function getVendorProp(name) {\n var style = document.body.style;\n if (name in style) return name;\n\n var i = cssPrefixes.length,\n capName = name.charAt(0).toUpperCase() + name.slice(1),\n vendorName;\n while (i--) {\n vendorName = cssPrefixes[i] + capName;\n if (vendorName in style) return vendorName;\n }\n\n return name;\n }\n\n function getStyleProp(name) {\n name = camelCase(name);\n return cssProps[name] || (cssProps[name] = getVendorProp(name));\n }\n\n function applyCss(element, prop, value) {\n prop = getStyleProp(prop);\n element.style[prop] = value;\n }\n\n return function(element, properties) {\n var args = arguments,\n prop, \n value;\n\n if (args.length == 2) {\n for (prop in properties) {\n value = properties[prop];\n if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);\n }\n } else {\n applyCss(element, args[1], args[2]);\n }\n }\n })();\n\n /**\n * (Internal) Determines if an element or space separated list of class names contains a class name.\n */\n\n function hasClass(element, name) {\n var list = typeof element == 'string' ? element : classList(element);\n return list.indexOf(' ' + name + ' ') >= 0;\n }\n\n /**\n * (Internal) Adds a class to an element.\n */\n\n function addClass(element, name) {\n var oldList = classList(element),\n newList = oldList + name;\n\n if (hasClass(oldList, name)) return; \n\n // Trim the opening space.\n element.className = newList.substring(1);\n }\n\n /**\n * (Internal) Removes a class from an element.\n */\n\n function removeClass(element, name) {\n var oldList = classList(element),\n newList;\n\n if (!hasClass(element, name)) return;\n\n // Replace the class name.\n newList = oldList.replace(' ' + name + ' ', ' ');\n\n // Trim the opening and closing spaces.\n element.className = newList.substring(1, newList.length - 1);\n }\n\n /**\n * (Internal) Gets a space separated list of the class names on the element. \n * The list is wrapped with a single space on each end to facilitate finding \n * matches within the list.\n */\n\n function classList(element) {\n return (' ' + (element.className || '') + ' ').replace(/\\s+/gi, ' ');\n }\n\n /**\n * (Internal) Removes an element from the DOM.\n */\n\n function removeElement(element) {\n element && element.parentNode && element.parentNode.removeChild(element);\n }\n\n return NProgress;\n});\n\n"],"ignoreList":[0],"mappings":"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"}
@@ -15,5 +15,8 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
15
15
  }, l = (e, t, n) => (c(e, t, "default"), n && c(n, t, "default")), u = (n, r, o) => (o = n == null ? {} : e(i(n)), c(r || !n || !n.__esModule || !a.call(n, "default") ? t(o, "default", {
16
16
  value: n,
17
17
  enumerable: !0
18
- }) : o, n));
19
- export { u as i, s as n, l as r, o as t };
18
+ }) : o, n)), d = /* @__PURE__ */ ((e) => typeof require < "u" ? require : typeof Proxy < "u" ? new Proxy(e, { get: (e, t) => (typeof require < "u" ? require : e)[t] }) : e)(function(e) {
19
+ if (typeof require < "u") return require.apply(this, arguments);
20
+ throw Error("Calling `require` for \"" + e + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
21
+ });
22
+ export { u as a, d as i, s as n, l as r, o as t };
@@ -0,0 +1,7 @@
1
+ import type { PaginationQuery } from './pagination';
2
+ /**
3
+ * 服务端全量导出(XLSX,后端统一行数上限):query 走 PaginationQuery 的
4
+ * 同源序列化(contains 转换/租户字段清理与列表页一致),导出的即当前搜索看到的。
5
+ * 仅接入与各列表读接口同权限语义的 :export 锚点。
6
+ */
7
+ export declare function serverExportFile(url: string, query: PaginationQuery): Promise<void>;
@@ -0,0 +1,28 @@
1
+ import { PaginationQuery } from '../transport/rest/pagination';
2
+ /**
3
+ * 审计日志导出(客户端聚合实现):
4
+ * 按当前搜索条件分页拉取(上限 maxRows),生成 CSV 或 XLSX(exceljs)触发下载。
5
+ * 上限保护:1 万行足够日常审计查阅;全量归档走后端 JSONL 审计归档任务。
6
+ */
7
+ export interface ExportColumn {
8
+ key: string;
9
+ title: string;
10
+ }
11
+ export interface ExportAuditOptions {
12
+ fetcher: (query: PaginationQuery) => Promise<{
13
+ items?: any[];
14
+ total?: number | string;
15
+ }>;
16
+ filename: string;
17
+ columns: ExportColumn[];
18
+ /** 当前 ProTable 搜索参数(不含分页字段) */
19
+ params?: Record<string, any>;
20
+ maxRows?: number;
21
+ }
22
+ export type AuditExportFormat = 'csv' | 'xlsx';
23
+ /** 执行导出:分页拉全量(受限)→ 按格式生成 → 下载。返回导出行数供提示。 */
24
+ export declare function exportAuditLogs(options: ExportAuditOptions, format: AuditExportFormat): Promise<number>;
25
+ /** @deprecated 使用 exportAuditLogs(options, format) */
26
+ export declare function exportAuditLogsToCsv(options: ExportAuditOptions): Promise<number>;
27
+ /** 页面级导出处理器:包装错误提示与行数反馈 */
28
+ export declare function handleAuditExport(options: ExportAuditOptions, successHint?: (count: number) => void): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-wind/admin-react",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "React 19 admin shell mechanisms extracted from go-wind-admin: axios transport (token rotation/captcha headers), SSE client, auth store with injectable AuthGateway, route factory (frontend/backend access modes), access control, i18n engine, theme/preferences, query client, generic hooks & utils.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,18 +41,24 @@
41
41
  "@microsoft/fetch-event-source": "^2.0.1",
42
42
  "axios": "^1.16.1",
43
43
  "dayjs": "^1.11.20",
44
+ "echarts": "^6.1.0",
45
+ "exceljs": "^4.4.0",
46
+ "lodash": "^4.17.21",
44
47
  "nprogress": "^0.2.0"
45
48
  },
46
49
  "devDependencies": {
47
50
  "@ant-design/icons": "^5.6.1",
48
51
  "@ant-design/pro-components": "^2.8.10",
49
52
  "@tanstack/react-query": "^5.100.11",
53
+ "@testing-library/react": "^16.3.2",
54
+ "@types/lodash": "^4.17.21",
50
55
  "@types/nprogress": "^0.2.3",
51
56
  "@types/react": "^19.2.15",
52
57
  "@types/react-dom": "^19.2.3",
53
58
  "@vitejs/plugin-react": "^5.1.2",
54
59
  "antd": "^6.4.3",
55
60
  "i18next": "^26.2.0",
61
+ "jsdom": "^29.1.1",
56
62
  "less": "^4.6.4",
57
63
  "react": "^19.2.6",
58
64
  "react-dom": "^19.2.6",
@@ -60,6 +66,7 @@
60
66
  "react-router-dom": "^6.26.0",
61
67
  "typescript": "^5.9.3",
62
68
  "vite": "^8.0.0",
69
+ "vitest": "^4.1.6",
63
70
  "zustand": "^5.0.13"
64
71
  },
65
72
  "publishConfig": {
@@ -68,6 +75,7 @@
68
75
  },
69
76
  "scripts": {
70
77
  "build": "vite build && tsc -p tsconfig.build.json && node ../../scripts/flatten-dts.mjs",
71
- "typecheck": "tsc --noEmit"
78
+ "typecheck": "tsc --noEmit",
79
+ "test": "vitest run"
72
80
  }
73
81
  }