zy-react-library 2.2.3 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Descriptions/index.d.ts +31 -0
- package/components/Descriptions/index.js +1 -0
- package/components/Excel/index.d.ts +3 -3
- package/components/Excel/index.js +1 -1
- package/components/FilePreview/index.d.ts +38 -0
- package/components/FilePreview/index.js +1 -0
- package/components/PreviewExcel/index.d.ts +3 -3
- package/components/PreviewPdf/index.d.ts +2 -2
- package/components/PreviewWord/index.d.ts +3 -3
- package/components/Word/index.d.ts +3 -3
- package/components/Word/index.js +1 -1
- package/hooks/useDownloadBlob/index.d.ts +31 -2
- package/hooks/useUrlQueryCriteria/index.d.ts +20 -8
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DescriptionsProps as AntDescriptionsProps, DescriptionsItemType } from "antd/es/descriptions";
|
|
2
|
+
import type { ReactElement, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
export type DescriptionDataIndex = string | number | (string | number)[];
|
|
5
|
+
|
|
6
|
+
export interface DescriptionItem<DataSource = Record<string, any>> extends Omit<DescriptionsItemType, "children"> {
|
|
7
|
+
/** 数据字段,支持嵌套路径 */
|
|
8
|
+
dataIndex?: DescriptionDataIndex;
|
|
9
|
+
/** 当前字段为空时展示的内容,默认继承组件 emptyText */
|
|
10
|
+
emptyText?: ReactNode;
|
|
11
|
+
/** 是否隐藏当前项 */
|
|
12
|
+
hidden?: boolean | ((dataSource: DataSource) => boolean);
|
|
13
|
+
/** 自定义字段内容 */
|
|
14
|
+
render?: (value: any, dataSource: DataSource, index: number) => ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface DescriptionsProps<DataSource = Record<string, any>> extends Omit<AntDescriptionsProps, "items"> {
|
|
18
|
+
/** 详情数据,默认 {} */
|
|
19
|
+
dataSource?: DataSource;
|
|
20
|
+
/** 字段配置,默认 [] */
|
|
21
|
+
items?: DescriptionItem<DataSource>[];
|
|
22
|
+
/** 空值展示内容,默认 "-" */
|
|
23
|
+
emptyText?: ReactNode;
|
|
24
|
+
/** 是否加载中,默认 false */
|
|
25
|
+
loading?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 配置式详情展示组件
|
|
30
|
+
*/
|
|
31
|
+
export default function Descriptions<DataSource = Record<string, any>>(props: DescriptionsProps<DataSource>): ReactElement;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Spin as e,Descriptions as t}from"antd";import{get as r}from"lodash-es";import{isEmpty as n}from"../../utils/index.js";import{jsx as i}from"react/jsx-runtime";const o=o=>{const{dataSource:s={},items:a=[],emptyText:l="-",loading:m=!1,column:d=2,styles:c,...p}=o,u=a.map((e,t)=>{const{dataIndex:i,hidden:o,render:a,emptyText:m,...d}=e;if("function"==typeof o?o(s):o)return null;const c=((e,t)=>{if(void 0!==t)return r(e,t)})(s,i),p=a?a(c,s,t):c;return{...d,key:d.key??(Array.isArray(i)?i.join("."):i)??t,children:n(p)?m??l:p}}).filter(Boolean);return i(e,{spinning:m,children:i(t,{...p,column:d,items:u,styles:{...c,label:{width:200,...c?.label}}})})};o.displayName="Descriptions";export{o as default};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CSSProperties, FC, ReactNode } from "react";
|
|
2
2
|
|
|
3
3
|
export interface ExcelProps {
|
|
4
|
-
/**
|
|
4
|
+
/** 是否显示弹窗,默认 false */
|
|
5
5
|
visible?: boolean;
|
|
6
6
|
/** 关闭回调 */
|
|
7
7
|
onCancel?: () => void;
|
|
@@ -9,9 +9,9 @@ export interface ExcelProps {
|
|
|
9
9
|
file?: string;
|
|
10
10
|
/** xlsx 文件名 */
|
|
11
11
|
name?: string;
|
|
12
|
-
/**
|
|
12
|
+
/** 是否内联展示,默认 false */
|
|
13
13
|
inline?: boolean;
|
|
14
|
-
/**
|
|
14
|
+
/** 弹窗标题,默认 "Excel预览" */
|
|
15
15
|
title?: string;
|
|
16
16
|
/** 内联模式下的样式 */
|
|
17
17
|
style?: CSSProperties;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Modal as e,Button as t,message as r,Spin as n}from"antd";import
|
|
1
|
+
import{Modal as e,Button as t,message as r,Spin as n}from"antd";import i from"exceljs";import{useRef as o,useState as l,useEffect as c}from"react";import a from"x-data-spreadsheet";import u from"../../hooks/useDownloadFile/index.js";import{getFileUrl as s}from"../../utils/index.js";import"x-data-spreadsheet/dist/xspreadsheet.css";import{jsx as d}from"react/jsx-runtime";function h(h){const{visible:x=!1,onCancel:p,file:w,name:v,inline:g=!1,title:y="Excel预览",style:C={},extraButtons:E}=h,k=o(null),I=o(null),T=o(!1),b=s(),[j,S]=l(!1),{downloadFile:D}=u();c(()=>{if(!x&&!g||!w)return;T.current=!1;const e=setTimeout(()=>{(async()=>{S(!0),k.current.innerHTML="";try{const e=await fetch(w.includes(b)?w:b+w);if(!e.ok)return void r.error("加载 Excel 文件失败");const t=await e.arrayBuffer(),n=new i.Workbook;if(await n.xlsx.load(t),T.current)return;new a(k.current,{mode:"read",showToolbar:!1,showContextmenu:!1,view:{height:()=>k.current?.clientHeight||520,width:()=>k.current?.clientWidth||800}}).loadData(function(e){const t=[];return e.worksheets.forEach(e=>{t.push(function(e){const t={name:e.name,rows:{},cols:{len:e.columnCount||26},merges:e.model?.merges||[]};return e.columns.forEach((e,r)=>{e.width&&(t.cols[r]={width:Math.round(8*e.width)})}),e.eachRow({includeEmpty:!0},(e,r)=>{const n={cells:{}};e.height&&(n.height=Math.round(1.4*e.height)),e.eachCell({includeEmpty:!0},(e,t)=>{n.cells[t-1]={text:m(e)}}),t.rows[r-1]=n}),(t.merges||[]).forEach(e=>{const r=function(e){const[t,r=t]=e.split(":"),n=f(t),i=f(r);return{sri:n.rowIndex,sci:n.colIndex,eri:i.rowIndex,eci:i.colIndex}}(e),n=t.rows[r.sri]?.cells?.[r.sci];n&&(n.merge=[r.eri-r.sri,r.eci-r.sci])}),t}(e))}),t.length>0?t:[{name:"Sheet1",rows:{}}]}(n))}catch{r.error("加载 Excel 文件失败"),p&&p()}finally{T.current||S(!1)}})()},100);return()=>{T.current=!0,k.current&&(k.current.innerHTML=""),e&&clearTimeout(e)}},[x,g,w]);const M=()=>d(n,{spinning:j,children:d("div",{style:{height:"72vh",overflow:"hidden",...C},children:d("div",{ref:k,style:{width:"100%",height:"100%"}})})});return g?M():d("div",{ref:I,children:d(e,{style:{top:100,maxWidth:"calc(100vw - 32px)",paddingBottom:24},open:x,mask:{closable:!1},width:1e3,title:y,onCancel:()=>{p()},getContainer:!1,footer:[d(t,{onClick:()=>{p()},children:"关闭"},"cancel"),d(t,{type:"primary",onClick:()=>{D({url:w,name:v})},children:"下载"},"download"),...E||[]],children:M()})})}function m(e){if(null===e.value||void 0===e.value)return"";if(e.formula)return null===e.result||void 0===e.result?`=${e.formula}`:String(e.result);if(e.text)return e.text;if(e.value instanceof Date)return e.value.toLocaleDateString();if("object"==typeof e.value){if(e.value.text)return e.value.text;if(e.value.richText)return e.value.richText.map(e=>e.text).join("");if(void 0!==e.value.result)return String(e.value.result)}return String(e.value)}function f(e){const t=/^([A-Z]+)(\d+)$/i.exec(e);return t?{rowIndex:Number(t[2])-1,colIndex:(r=t[1],r.toUpperCase().split("").reduce((e,t)=>26*e+t.charCodeAt(0)-64,0)-1)}:{rowIndex:0,colIndex:0};var r}h.displayName="Excel";export{h as default};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import type { ExcelProps } from "../Excel";
|
|
3
|
+
import type { PdfProps } from "../Pdf";
|
|
4
|
+
import type { PreviewImgProps } from "../PreviewImg";
|
|
5
|
+
import type { VideoProps } from "../Video";
|
|
6
|
+
import type { WordProps } from "../Word";
|
|
7
|
+
|
|
8
|
+
export interface FilePreviewComponentProps {
|
|
9
|
+
/** 图片组件参数 */
|
|
10
|
+
image?: Omit<PreviewImgProps, "files">;
|
|
11
|
+
/** PDF 组件参数 */
|
|
12
|
+
pdf?: Omit<PdfProps, "file" | "name" | "visible" | "onCancel">;
|
|
13
|
+
/** Word 组件参数 */
|
|
14
|
+
word?: Omit<WordProps, "file" | "name" | "visible" | "onCancel">;
|
|
15
|
+
/** Excel 组件参数 */
|
|
16
|
+
excel?: Omit<ExcelProps, "file" | "name" | "visible" | "onCancel">;
|
|
17
|
+
/** 视频组件参数 */
|
|
18
|
+
video?: Omit<VideoProps, "source" | "title" | "visible" | "onCancel">;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FilePreviewProps {
|
|
22
|
+
/** 文件列表,和 name、url 冲突 */
|
|
23
|
+
files?: { filePath?: string; fileName?: string; name?: string; [key: string]: string }[];
|
|
24
|
+
/** 文件名字段名,传入 files 时优先查找 name、fileName */
|
|
25
|
+
nameKey?: string;
|
|
26
|
+
/** 文件路径字段名,传入 files 时优先查找 filePath、url */
|
|
27
|
+
urlKey?: string;
|
|
28
|
+
/** 单个文件名,和 files 冲突 */
|
|
29
|
+
name?: string;
|
|
30
|
+
/** 单个文件路径,和 files 冲突 */
|
|
31
|
+
url?: string;
|
|
32
|
+
/** 各底层预览组件的额外参数 */
|
|
33
|
+
componentProps?: FilePreviewComponentProps;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare const FilePreview: FC<FilePreviewProps>;
|
|
37
|
+
|
|
38
|
+
export default FilePreview;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Space as e,Button as i}from"antd";import{useState as r}from"react";import{getFileName as l}from"../../utils/index.js";import n from"../Excel/index.js";import m from"../Pdf/index.js";import o from"../PreviewImg/index.js";import t from"../Video/index.js";import a from"../Word/index.js";import{jsxs as d,Fragment as p,jsx as s}from"react/jsx-runtime";const c=c=>{const{files:u=[],nameKey:f="",urlKey:x="",name:v,url:g,componentProps:h={}}=c,[y,j]=r(null),w=u.length>0?u.map(e=>{const i=e.filePath||e.url||e[x];return{name:e.name||e.fileName||e[f]||l(i),url:i}}).filter(e=>e.url):v&&g?[{name:v,url:g}]:[],b=()=>{j(null)};return 0===w.length?null:d(p,{children:[s(e,{direction:"vertical",children:w.map(r=>{const l=(e=>{const i=e.url.split(/[?#]/)[0],r=i.slice(i.lastIndexOf(".")+1).toLowerCase();return["jpg","jpeg","png","gif","webp","bmp","svg"].includes(r)?"image":"pdf"===r?"pdf":"docx"===r?"word":"xlsx"===r?"excel":["mp4","webm","m3u8"].includes(r)?"video":void 0})(r),n=`${r.name}-${r.url}`;return"image"===l?s(e,{children:s(o,{...h.image,files:[r.url]})},n):d(e,{children:[s("span",{children:r.name}),l?s(i,{type:"primary",size:"small",onClick:()=>((e,i)=>{j({...e,type:i})})(r,l),children:"预览"}):s("span",{children:"暂不支持预览"})]},n)})}),"pdf"===y?.type&&s(m,{...h.pdf,visible:!0,file:y.url,name:y.name,onCancel:b}),"word"===y?.type&&s(a,{...h.word,visible:!0,file:y.url,name:y.name,onCancel:b}),"excel"===y?.type&&s(n,{...h.excel,visible:!0,file:y.url,name:y.name,onCancel:b}),"video"===y?.type&&s(t,{...h.video,visible:!0,source:y.url,title:y.name,onCancel:b})]})};c.displayName="FilePreview";export{c as default};
|
|
@@ -2,10 +2,10 @@ import type { FC } from "react";
|
|
|
2
2
|
|
|
3
3
|
export interface PreviewExcelProps {
|
|
4
4
|
/** 文件列表,和 name、url 冲突 */
|
|
5
|
-
files?: { filePath?: string; fileName?: string; name?: string;
|
|
6
|
-
/** 文件名字段名,传入 files
|
|
5
|
+
files?: { filePath?: string; fileName?: string; name?: string; [key: string]: string }[];
|
|
6
|
+
/** 文件名字段名,传入 files 时优先查找 name、fileName */
|
|
7
7
|
nameKey?: string;
|
|
8
|
-
/** 文件路径字段名,传入 files
|
|
8
|
+
/** 文件路径字段名,传入 files 时优先查找 filePath、url */
|
|
9
9
|
urlKey?: string;
|
|
10
10
|
/** 单个文件名,和 files 冲突 */
|
|
11
11
|
name?: string;
|
|
@@ -3,9 +3,9 @@ import type { FC } from "react";
|
|
|
3
3
|
export interface PreviewPdfProps {
|
|
4
4
|
/** 文件列表,和 name、url 冲突 */
|
|
5
5
|
files?: { filePath?: string; fileName?: string; name?: string; [key: string]: string }[];
|
|
6
|
-
/** 文件名字段名,传入 files
|
|
6
|
+
/** 文件名字段名,传入 files 时优先查找 name、fileName */
|
|
7
7
|
nameKey?: string;
|
|
8
|
-
/** 文件路径字段名,传入 files
|
|
8
|
+
/** 文件路径字段名,传入 files 时优先查找 filePath、url */
|
|
9
9
|
urlKey?: string;
|
|
10
10
|
/** 单个文件名,和 files 冲突 */
|
|
11
11
|
name?: string;
|
|
@@ -2,10 +2,10 @@ import type { FC } from "react";
|
|
|
2
2
|
|
|
3
3
|
export interface PreviewWordProps {
|
|
4
4
|
/** 文件列表,和 name、url 冲突 */
|
|
5
|
-
files?: { filePath?: string; fileName?: string; name?: string;
|
|
6
|
-
/** 文件名字段名,传入 files
|
|
5
|
+
files?: { filePath?: string; fileName?: string; name?: string; [key: string]: string }[];
|
|
6
|
+
/** 文件名字段名,传入 files 时优先查找 name、fileName */
|
|
7
7
|
nameKey?: string;
|
|
8
|
-
/** 文件路径字段名,传入 files
|
|
8
|
+
/** 文件路径字段名,传入 files 时优先查找 filePath、url */
|
|
9
9
|
urlKey?: string;
|
|
10
10
|
/** 单个文件名,和 files 冲突 */
|
|
11
11
|
name?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CSSProperties, FC, ReactNode } from "react";
|
|
2
2
|
|
|
3
3
|
export interface WordProps {
|
|
4
|
-
/**
|
|
4
|
+
/** 是否显示弹窗,默认 false */
|
|
5
5
|
visible?: boolean;
|
|
6
6
|
/** 关闭回调 */
|
|
7
7
|
onCancel?: () => void;
|
|
@@ -9,9 +9,9 @@ export interface WordProps {
|
|
|
9
9
|
file?: string;
|
|
10
10
|
/** docx 文件名 */
|
|
11
11
|
name?: string;
|
|
12
|
-
/**
|
|
12
|
+
/** 是否内联展示,默认 false */
|
|
13
13
|
inline?: boolean;
|
|
14
|
-
/**
|
|
14
|
+
/** 弹窗标题,默认 "Word预览" */
|
|
15
15
|
title?: string;
|
|
16
16
|
/** 内联模式下的样式 */
|
|
17
17
|
style?: CSSProperties;
|
package/components/Word/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Modal as r,Button as e,message as n,Spin as t}from"antd";import{renderAsync as i}from"docx-preview";import{useRef as o,useState as a,useEffect as l}from"react";import c from"../../hooks/useDownloadFile/index.js";import{getFileUrl as d}from"../../utils/index.js";import{jsx as u}from"react/jsx-runtime";function s(s){const{visible:f=!1,onCancel:m,file:p,name:h,inline:w=!1,title:g="Word预览",style:
|
|
1
|
+
import{Modal as r,Button as e,message as n,Spin as t}from"antd";import{renderAsync as i}from"docx-preview";import{useRef as o,useState as a,useEffect as l}from"react";import c from"../../hooks/useDownloadFile/index.js";import{getFileUrl as d}from"../../utils/index.js";import{jsx as u}from"react/jsx-runtime";function s(s){const{visible:f=!1,onCancel:m,file:p,name:h,inline:w=!1,title:g="Word预览",style:v={},extraButtons:x}=s,y=o(null),k=o(null),W=o(!1),C=d(),[b,T]=a(!1),{downloadFile:j}=c();l(()=>{if(!f&&!w||!p)return;W.current=!1;const r=setTimeout(()=>{(async()=>{T(!0),y.current.innerHTML="";try{const r=await fetch(p.includes(C)?p:C+p);if(!r.ok)return void n.error("加载 Word 文件失败");const e=await r.arrayBuffer();if(W.current)return;await i(e,y.current,null,{className:"docx-preview",inWrapper:!0,ignoreWidth:!1,ignoreHeight:!1,breakPages:!0})}catch{n.error("加载 Word 文件失败"),m&&m()}finally{W.current||T(!1)}})()},100);return()=>{W.current=!0,y.current&&(y.current.innerHTML=""),r&&clearTimeout(r)}},[f,w,p]);const B=()=>u(t,{spinning:b,children:u("div",{style:{height:"72vh",overflowY:"auto",padding:"24px",background:"#f5f5f5",...v},children:u("div",{ref:y})})});return w?B():u("div",{ref:k,children:u(r,{style:{top:100,maxWidth:"calc(100vw - 32px)",paddingBottom:24},open:f,mask:{closable:!1},width:900,title:g,onCancel:()=>{m()},getContainer:!1,footer:[u(e,{onClick:()=>{m()},children:"关闭"},"cancel"),u(e,{type:"primary",onClick:()=>{j({url:p,name:h})},children:"下载"},"download"),...x||[]],children:B()})})}s.displayName="Word";export{s as default};
|
|
@@ -1,8 +1,37 @@
|
|
|
1
|
+
/** 常见下载文件 MIME 类型,同时允许传入其他合法 MIME 字符串 */
|
|
2
|
+
export type DownloadBlobMimeType
|
|
3
|
+
= | "application/pdf"
|
|
4
|
+
| "application/msword"
|
|
5
|
+
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
6
|
+
| "application/vnd.ms-excel"
|
|
7
|
+
| "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
8
|
+
| "application/vnd.ms-powerpoint"
|
|
9
|
+
| "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
10
|
+
| "text/csv"
|
|
11
|
+
| "text/plain"
|
|
12
|
+
| "application/json"
|
|
13
|
+
| "application/zip"
|
|
14
|
+
| "application/x-rar-compressed"
|
|
15
|
+
| "application/x-7z-compressed"
|
|
16
|
+
| "application/gzip"
|
|
17
|
+
| "image/jpeg"
|
|
18
|
+
| "image/png"
|
|
19
|
+
| "image/gif"
|
|
20
|
+
| "image/webp"
|
|
21
|
+
| "image/svg+xml"
|
|
22
|
+
| "image/bmp"
|
|
23
|
+
| "audio/mpeg"
|
|
24
|
+
| "audio/wav"
|
|
25
|
+
| "video/mp4"
|
|
26
|
+
| "video/webm"
|
|
27
|
+
| "application/octet-stream"
|
|
28
|
+
| (string & {});
|
|
29
|
+
|
|
1
30
|
interface UseDownloadBlobOptions {
|
|
2
31
|
/** 下载文件的自定义文件名(不含后缀),默认为当前时间戳 */
|
|
3
32
|
name?: string;
|
|
4
|
-
/** Blob 对象的 MIME 类型,默认为
|
|
5
|
-
type?:
|
|
33
|
+
/** Blob 对象的 MIME 类型,默认为 application/vnd.ms-excel 类型 */
|
|
34
|
+
type?: DownloadBlobMimeType;
|
|
6
35
|
/** 请求时携带的查询参数对象 */
|
|
7
36
|
params?: Record<string, any>;
|
|
8
37
|
}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
export type SetUrlCriteriaQueryFunction = (searchForm: Record<string, any>, pagination: Record<string, any>) => void;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
export type SetUrlCriteriaQueryFunction = (searchForm: Record<string, any>, pagination: Record<string, any>) => void;
|
|
2
|
+
|
|
3
|
+
/** URL 中存储字段名列表的参数名,同时允许传入自定义参数名 */
|
|
4
|
+
export type UrlCriteriaKeysKey
|
|
5
|
+
= | "searchFormKeys"
|
|
6
|
+
| "paginationKeys"
|
|
7
|
+
| (string & {});
|
|
8
|
+
|
|
9
|
+
/** URL 中存储字段值列表的参数名,同时允许传入自定义参数名 */
|
|
10
|
+
export type UrlCriteriaValuesKey
|
|
11
|
+
= | "searchFormValues"
|
|
12
|
+
| "paginationValues"
|
|
13
|
+
| (string & {});
|
|
14
|
+
|
|
15
|
+
export type GetUrlCriteriaQueryFunction = (keysStr: UrlCriteriaKeysKey, valuesStr: UrlCriteriaValuesKey) => Record<string, any>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 处理搜索条件缓存到 URL
|
|
19
|
+
*/
|
|
20
|
+
export default function useUrlQueryCriteria(): { setUrlCriteriaQuery: SetUrlCriteriaQueryFunction; getUrlCriteriaQuery: GetUrlCriteriaQueryFunction };
|