一系列优化

master
LiuJiaNan 2025-12-24 15:45:07 +08:00
parent 74c64385fe
commit e4e0cf1de9
32 changed files with 671 additions and 486 deletions

View File

@ -5,7 +5,7 @@ import type { BasicCascaderProps } from "../Basic";
* *
*/ */
export interface AreaCascaderProps extends Omit<BasicCascaderProps, "options" | "placeholder" | "nameKey" | "idKey" | "childrenKey"> { export interface AreaCascaderProps extends Omit<BasicCascaderProps, "options" | "placeholder" | "nameKey" | "idKey" | "childrenKey"> {
/** 占位符,默认"属地" */ /** 占位符,默认 "属地" */
placeholder?: string; placeholder?: string;
} }

View File

@ -5,7 +5,7 @@ import type { BasicCascaderProps } from "../Basic";
* *
*/ */
export interface IndustryCascaderProps extends Omit<BasicCascaderProps, "options" | "placeholder" | "nameKey" | "idKey" | "childrenKey"> { export interface IndustryCascaderProps extends Omit<BasicCascaderProps, "options" | "placeholder" | "nameKey" | "idKey" | "childrenKey"> {
/** 占位符,默认"行业类型" */ /** 占位符,默认 "行业类型" */
placeholder?: string; placeholder?: string;
} }

View File

@ -19,9 +19,9 @@ export interface FormBuilderProps extends FormProps {
useAutoGenerateRequired?: boolean; useAutoGenerateRequired?: boolean;
/** 是否显示操作按钮区域,默认 true */ /** 是否显示操作按钮区域,默认 true */
showActionButtons?: boolean; showActionButtons?: boolean;
/** 提交按钮文字,默认"提交" */ /** 提交按钮文字,默认 "提交" */
submitButtonText?: string; submitButtonText?: string;
/** 取消按钮文字,默认"取消" */ /** 取消按钮文字,默认 "取消" */
cancelButtonText?: string; cancelButtonText?: string;
/** 是否显示提交按钮,默认 true */ /** 是否显示提交按钮,默认 true */
showSubmitButton?: boolean; showSubmitButton?: boolean;

View File

@ -51,25 +51,31 @@ const FormBuilder = (props) => {
/> />
</Row> </Row>
{showActionButtons && ( {showActionButtons && (
<Row gutter={gutter} style={{ marginTop: 24 }}> <>
<Col span={24} style={{ textAlign: "center" }}> <div style={{ height: "52px" }}></div>
{customActionButtons || ( <Row
<Space> gutter={gutter}
{showSubmitButton && ( style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", margin: "0px -44px", padding: "10px 0", position: "fixed", bottom: "0", width: "100%" }}
<Button type="primary" htmlType="submit"> >
{submitButtonText} <Col span={24} style={{ textAlign: "center" }}>
</Button> {customActionButtons || (
)} <Space>
{extraActionButtons} {showSubmitButton && (
{showCancelButton && ( <Button type="primary" htmlType="submit">
<Button onClick={handleCancel}> {submitButtonText}
{cancelButtonText} </Button>
</Button> )}
)} {extraActionButtons}
</Space> {showCancelButton && (
)} <Button onClick={handleCancel}>
</Col> {cancelButtonText}
</Row> </Button>
)}
</Space>
)}
</Col>
</Row>
</>
)} )}
</Form> </Form>
</Spin> </Spin>

View File

@ -21,9 +21,9 @@ export interface OptionItem {
* *
*/ */
export interface itemsFieldConfig { export interface itemsFieldConfig {
/** 值字段的键名,默认 'bianma' */ /** 值字段的键名,默认 'bianma' */
valueKey?: string; valueKey?: string;
/** 标签字段的键名,默认 'name' */ /** 标签字段的键名,默认 'name' */
labelKey?: string | ((item: Record<string, any>) => ReactNode); labelKey?: string | ((item: Record<string, any>) => ReactNode);
} }
@ -106,7 +106,7 @@ export interface FormOption<T extends keyof FORM_ITEM_RENDER_TYPE_MAP = keyof FO
formItemProps?: FormItemProps | ((formValues: FormValues) => FormItemProps); formItemProps?: FormItemProps | ((formValues: FormValues) => FormItemProps);
/** label 栅格配置,默认直接使用外层的 labelCol如果 span 等于 24是外层的 labelCol.span 一半 */ /** label 栅格配置,默认直接使用外层的 labelCol如果 span 等于 24是外层的 labelCol.span 一半 */
labelCol?: ColProps; labelCol?: ColProps;
/** wrapper 栅格配置,默认 24 - labelCol.span */ /** wrapper 栅格配置,默认 24 - labelCol.span */
wrapperCol?: ColProps; wrapperCol?: ColProps;
/** 是否应该更新(用于表单联动) */ /** 是否应该更新(用于表单联动) */
shouldUpdate?: boolean | ((prevValues: FormValues, nextValues: FormValues, info: { source?: string }) => boolean); shouldUpdate?: boolean | ((prevValues: FormValues, nextValues: FormValues, info: { source?: string }) => boolean);

View File

@ -1,4 +1,4 @@
import type { CSSProperties, FC, ReactNode } from "react"; import type { FC, ReactNode } from "react";
export interface HeaderBackProps { export interface HeaderBackProps {
/** 标题 */ /** 标题 */
@ -8,10 +8,8 @@ export interface HeaderBackProps {
goBack?: () => void; goBack?: () => void;
[key: string]: any; [key: string]: any;
}; };
/** 是否显示返回按钮,默认 true */ /** 是否显示返回按钮,默认 true */
previous?: boolean; previous?: boolean;
/** 自定义样式 */
style?: CSSProperties;
} }
/** 头部返回组件 */ /** 头部返回组件 */

View File

@ -6,10 +6,10 @@ import "./index.less";
* 头部返回组件 * 头部返回组件
*/ */
function HeaderBack(props) { function HeaderBack(props) {
const { title, history, previous = true, style = {} } = props; const { title, history, previous = true } = props;
return ( return (
<div className="header-back" style={style}> <div className="header-back">
<div className="action"> <div className="action">
{ {
previous previous

View File

@ -1,7 +1,7 @@
.header-back { .header-back {
padding: 10px 20px; padding: 10px 20px;
border-bottom: 1px solid #dcdfe6; border-bottom: 1px solid #dcdfe6;
margin-bottom: 10px; margin-bottom: 0;
position: sticky; position: sticky;
top: 0; top: 0;
background-color: #fff; background-color: #fff;

View File

@ -12,8 +12,6 @@ export interface HiddenInfoProps {
hiddenId?: string; hiddenId?: string;
/** hiddenId 的字段,默认 hiddenId */ /** hiddenId 的字段,默认 hiddenId */
hiddenIdKey?: string; hiddenIdKey?: string;
/** 是否显示头部的返回,默认 true */
isShowHeaderBack?: boolean;
/** 是否是过往记录,后端会返回详细的步骤信息,默认 false */ /** 是否是过往记录,后端会返回详细的步骤信息,默认 false */
history?: boolean; history?: boolean;
/** 获取数据 */ /** 获取数据 */

View File

@ -8,7 +8,6 @@ import useDownloadFile from "../../../hooks/useDownloadFile";
import useGetFile from "../../../hooks/useGetFile"; import useGetFile from "../../../hooks/useGetFile";
import useGetUrlQuery from "../../../hooks/useGetUrlQuery"; import useGetUrlQuery from "../../../hooks/useGetUrlQuery";
import { getFileName, getFileSuffix, getLabelName } from "../../../utils"; import { getFileName, getFileSuffix, getLabelName } from "../../../utils";
import HeaderBack from "../../HeaderBack";
import VideoIcon from "../../Icon/VideoIcon"; import VideoIcon from "../../Icon/VideoIcon";
import PreviewImg from "../../PreviewImg"; import PreviewImg from "../../PreviewImg";
import PreviewPdf from "../../PreviewPdf"; import PreviewPdf from "../../PreviewPdf";
@ -23,7 +22,6 @@ function HiddenInfo(props) {
idKey = "id", idKey = "id",
hiddenId = "", hiddenId = "",
hiddenIdKey = "hiddenId", hiddenIdKey = "hiddenId",
isShowHeaderBack = true,
history = false, history = false,
onGetData, onGetData,
} = props; } = props;
@ -116,386 +114,390 @@ function HiddenInfo(props) {
return ( return (
<div> <div>
{isShowHeaderBack && <HeaderBack title="查看" />}
<Spin spinning={loading || downloadFileLoading}> <Spin spinning={loading || downloadFileLoading}>
<div style={{ padding: 20 }}> <Divider orientation="left">隐患信息</Divider>
<Divider orientation="left">隐患信息</Divider> <Descriptions
<Descriptions bordered
bordered column={1}
column={1} styles={{ label: { width: 200 } }}
styles={{ label: { width: 200 } }} items={[
items={[ { label: "隐患来源", children: getLabelName({ list: HIDDEN_SOURCE_ENUM, status: info.source }) },
{ label: "隐患来源", children: getLabelName({ list: HIDDEN_SOURCE_ENUM, status: info.source }) }, { label: "隐患类型", children: info.hiddenTypeName },
{ label: "隐患类型", children: info.hiddenTypeName }, { label: "隐患级别", children: info.hiddenLevelName },
{ label: "隐患级别", children: info.hiddenLevelName }, { label: "隐患状态", children: getLabelName({ list: HIDDEN_STATE_ENUM, status: info.state }) },
{ label: "隐患状态", children: getLabelName({ list: HIDDEN_STATE_ENUM, status: info.state }) }, { label: "隐患描述", children: info.hiddenDesc },
{ label: "隐患描述", children: info.hiddenDesc }, ...(info.hiddenPartName ? [{ label: "隐患部位", children: info.hiddenPartName }] : []),
...(info.hiddenPartName ? [{ label: "隐患部位", children: info.hiddenPartName }] : []), ...(
...( (info.source === 2 || info.source === 3) && (info.hiddenCheckListCO && Object.keys(info.hiddenCheckListCO).length > 0)
(info.source === 2 || info.source === 3) && (info.hiddenCheckListCO && Object.keys(info.hiddenCheckListCO).length > 0) ? [
? [ { label: "风险点(单元)", children: info.hiddenCheckListCO.listRiskPoints },
{ label: "风险点(单元)", children: info.hiddenCheckListCO.listRiskPoints }, { label: "辨识部位", children: info.hiddenCheckListCO.identifiedLocations },
{ label: "辨识部位", children: info.hiddenCheckListCO.identifiedLocations }, { label: "存在风险", children: info.hiddenCheckListCO.existingRisks },
{ label: "存在风险", children: info.hiddenCheckListCO.existingRisks }, { label: "风险分级", children: info.hiddenCheckListCO.riskLevel },
{ label: "风险分级", children: info.hiddenCheckListCO.riskLevel }, { label: "隐患清单", children: info.hiddenCheckListCO.listName },
{ label: "隐患清单", children: info.hiddenCheckListCO.listName }, { label: "检查内容", children: info.hiddenCheckListCO.inspectionContent },
{ label: "检查内容", children: info.hiddenCheckListCO.inspectionContent }, ]
] : []
: [] ),
), ...(info.longitude
...(info.longitude ? [{ ? [{
label: "隐患上报位置(经纬度)", label: "隐患上报位置(经纬度)",
children: [info.longitude && `经度:${info.longitude}`, info.latitude && `纬度:${info.latitude}`].filter(Boolean).join(" "), children: [info.longitude && `经度:${info.longitude}`, info.latitude && `纬度:${info.latitude}`].filter(Boolean).join(" "),
}] : []), }]
...(info.positionDesc ? [{ label: "隐患位置描述", children: info.positionDesc }] : []), : []),
{ label: "隐患发现人", children: info.creatorName }, ...(info.positionDesc ? [{ label: "隐患位置描述", children: info.positionDesc }] : []),
{ label: "隐患发现时间", children: dayjs(info.hiddenFindTime).format("YYYY-MM-DD HH:mm:ss") }, { label: "隐患发现人", children: info.creatorName },
{ { label: "隐患发现时间", children: dayjs(info.hiddenFindTime).format("YYYY-MM-DD HH:mm:ss") },
label: "整改类型", {
children: getLabelName({ list: HIDDEN_RECTIFICATION_TYPE_ENUM, status: info.rectificationType }), label: "整改类型",
}, children: getLabelName({ list: HIDDEN_RECTIFICATION_TYPE_ENUM, status: info.rectificationType }),
{ },
label: "是否相关方", {
children: getLabelName({ label: "是否相关方",
list: [{ bianma: "1", name: "是" }, { bianma: "0", name: "否" }], children: getLabelName({
status: info.isRelated, list: [{ bianma: "1", name: "是" }, { bianma: "0", name: "否" }],
}), status: info.isRelated,
}, }),
...(info.isRelated === 1 ? [{ label:'相关方项目',children:info.projectName }] : []), },
{ label: "隐患图片", children: <PreviewImg files={hiddenImageFiles} /> }, ...(info.isRelated === 1 ? [{ label: "相关方项目", children: info.projectName }] : []),
...(hiddenVideoFiles.length > 0 { label: "隐患图片", children: <PreviewImg files={hiddenImageFiles} /> },
? [{ ...(hiddenVideoFiles.length > 0
label: "隐患视频", ? [{
children: ( label: "隐患视频",
<VideoIcon onClick={() => { children: (
setVideoModalOpen(true); <VideoIcon onClick={() => {
}} setVideoModalOpen(true);
/> }}
),
}]
: []),
]}
/>
{
(info.hiddenUserPresetsCO && Object.keys(info.hiddenUserPresetsCO).length > 0) && (
<>
<Divider orientation="left">整改信息发现人预填</Divider>
<Descriptions
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
{ label: `整改${info.isRelated === 1 ? "单位" : "部门"}`, children: info.hiddenUserPresetsCO.rectifyDeptName },
{ label: "整改人", children: info.hiddenUserPresetsCO.rectifyUserName },
...(info.rectificationType === 2
? [
{
label: "整改期限",
children: dayjs(info.hiddenUserPresetsCO.rectifyDeadline).format("YYYY-MM-DD"),
},
]
: []),
...(info.rectificationType === 1
? [
{ label: "验收部门", children: info.hiddenUserPresetsCO.checkDeptName },
{ label: "验收人", children: info.hiddenUserPresetsCO.checkUserName },
]
: []),
]}
/>
</>
)
}
{
(info.hiddenConfirmUserCO && info.hiddenConfirmUserCO.length > 0) && (
<>
<Divider orientation="left">隐患确认</Divider>
{
info.hiddenConfirmUserCO.map(item => (
<Descriptions
key={item.id}
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
...(item.hiddenLevelName ? [{ label: "隐患级别", children: item.hiddenLevelName }] : []),
...(item.userName ? [{ label: "隐患确认人", children: item.userName }] : []),
...(item.rectificationTime ? [{ label: "隐患确认时间", children: item.rectificationTime }] : []),
...(item.rectifyDeptName ? [{ label: `整改${info.isRelated === 1 ? "单位" : "部门"}`, children: item.rectifyDeptName }] : []),
...(item.rectifyUserName ? [{ label: "整改人", children: item.rectifyUserName }] : []),
...(item.rectificationDeadline ? [{ label: "整改完成期限", children: item.rectificationDeadline }] : []),
...(item.checkDeptName ? [{ label: "验收部门", children: item.checkDeptName }] : []),
...(item.checkUserName ? [{ label: "验收人", children: item.checkUserName }] : []),
...(item.repulseCause
? [
...(item.repulseCause ? [{ label: "打回意见", children: item.repulseCause }] : []),
...(item.rectificationTime ? [{ label: "打回时间", children: item.rectificationTime }] : []),
]
: []),
]}
/>
))
}
</>
)
}
{
info.hiddenExtensionList && info.hiddenExtensionList.length > 0 && (
<>
<Divider orientation="left">延期信息</Divider>
{
info.hiddenExtensionList.map(item => (
<Descriptions
key={item.id}
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
...(item.createTime ? [{ label: "申请延期日期", children: item.createTime }] : []),
...(item.delayTime ? [{ label: "延期日期", children: item.delayTime }] : []),
...(item.updateName ? [{ label: "审核人", children: item.updateName }] : []),
...(item.state === 3
? [
...(item.disposalPlan ? [{ label: "处置方案", children: item.disposalPlan }] : []),
...(item.disposalFile ? [{
label: "处置方案附件",
children: (
getFileSuffix(item.disposalFile) === "pdf"
? <PreviewPdf name={getFileName(item.disposalFile)} url={item.disposalFile} />
: (
<Space>
<span>{getFileName(item.disposalFile)}</span>
<Button
type="primary"
size="small"
onClick={() => downloadFile(item.disposalFile)}
>
下载
</Button>
</Space>
)
),
}] : []),
]
: []),
{
label: "延期审核状态",
children: (
<>
{item.state === 1 && <span>待审核</span>}
{item.state === 2 && <span>审批中</span>}
{item.state === 3 && <span>已通过</span>}
{item.state === 4 && <span>已拒绝</span>}
{item.state === 5 && <span>已撤回</span>}
</>
),
},
...((item.state === 3 || item.state === 4)
? [{
label: "延期审核时间",
children: item.updateTime,
}]
: []),
]}
/> />
), ),
) }]
} : []),
</> ]}
) />
} {
{ (info.hiddenUserPresetsCO && Object.keys(info.hiddenUserPresetsCO).length > 0) && (
info.hiddenSpecialList && info.hiddenSpecialList.length > 0 && ( <>
<> <Divider orientation="left">整改信息发现人预填</Divider>
<Divider orientation="left">特殊处置审核信息</Divider> <Descriptions
{ bordered
info.hiddenSpecialList.map(item => ( column={1}
<Descriptions styles={{ label: { width: 200 } }}
key={item.id} items={[
bordered { label: `整改${info.isRelated === 1 ? "单位" : "部门"}`, children: info.hiddenUserPresetsCO.rectifyDeptName },
column={1} { label: "整改人", children: info.hiddenUserPresetsCO.rectifyUserName },
styles={{ label: { width: 200 } }} ...(info.rectificationType === 2
items={[ ? [
...((item.state === 3 || item.state === 4)
? [
...(item.updateName ? [{ label: "审核人", children: item.updateName }] : []),
...(item.updateTime ? [{ label: "审核时间", children: item.updateTime }] : []),
]
: []),
{ label: "无法整改原因", children: item.examine },
...(item.state === 3
? [
...(item.disposalPlan ? [{ label: "处置方案", children: item.disposalPlan }] : []),
...(item.disposalFile ? [{
label: "处置方案附件",
children: (
getFileSuffix(item.disposalFile) === "pdf"
? <PreviewPdf name={getFileName(item.disposalFile)} url={item.disposalFile} />
: (
<Space>
<span>{getFileName(item.disposalFile)}</span>
<Button
type="primary"
size="small"
onClick={() => downloadFile(item.disposalFile)}
>
下载
</Button>
</Space>
)
),
}] : []),
{
label: "是否更换整改负责人",
children: item.rectifyUserCO && Object.keys(item.rectifyUserCO).length > 0 ? "是" : "否",
},
...(
item.rectifyUserCO && Object.keys(item.rectifyUserCO).length > 0
? [{ label: "整改负责人", children: item.rectifyUserCO.userName }]
: []),
]
: []),
{ {
label: "特殊处置审核状态", label: "整改期限",
children: ( children: dayjs(info.hiddenUserPresetsCO.rectifyDeadline).format("YYYY-MM-DD"),
<>
{item.state === 1 && <span>待审核</span>}
{item.state === 2 && <span>审批中</span>}
{item.state === 3 && <span>已通过</span>}
{item.state === 4 && <span>已拒绝</span>}
{item.state === 5 && <span>已撤回</span>}
</>
),
}, },
]} ]
/> : []),
), ...(info.rectificationType === 1
) ? [
} { label: "验收部门", children: info.hiddenUserPresetsCO.checkDeptName },
</> { label: "验收人", children: info.hiddenUserPresetsCO.checkUserName },
) ]
} : []),
{ ]}
(info.hiddenRectifyUserCO && info.hiddenRectifyUserCO.length > 0) && ( />
<> </>
<Divider orientation="left">整改信息</Divider> )
{ }
info.hiddenRectifyUserCO.map((item, index) => ( {
<Descriptions (info.hiddenConfirmUserCO && info.hiddenConfirmUserCO.length > 0) && (
key={item.id} <>
bordered <Divider orientation="left">隐患确认</Divider>
column={1} {
styles={{ label: { width: 200 } }} info.hiddenConfirmUserCO.map(item => (
items={[ <Descriptions
...(item.deptName ? [{ label: `整改${info.isRelated === 1 ? "单位" : "部门"}`, children: item.deptName }] : []), key={item.id}
...(item.userName ? [{ label: "整改人", children: item.userName }] : []), bordered
...(item.rectificationTime ? [{ label: "整改时间", children: item.rectificationTime }] : []), column={1}
...(item.descr ? [{ label: "整改描述", children: item.descr }] : []), styles={{ label: { width: 200 } }}
...(item.investmentFunds ? [{ label: "投入资金", children: `${item.investmentFunds}` }] : []), items={[
...(info.tempSafeMeasure ? [{ label: "临时安全措施", children: info.tempSafeMeasure }] : []), ...(item.hiddenLevelName ? [{ label: "隐患级别", children: item.hiddenLevelName }] : []),
{ label: "整改后图片", children: <PreviewImg files={afterRectificationImageFiles[index]} /> }, ...(item.userName ? [{ label: "隐患确认人", children: item.userName }] : []),
...(item.rectificationTime ? [{ label: "隐患确认时间", children: item.rectificationTime }] : []),
...(item.rectifyDeptName ? [{ label: `整改${info.isRelated === 1 ? "单位" : "部门"}`, children: item.rectifyDeptName }] : []),
...(item.rectifyUserName ? [{ label: "整改人", children: item.rectifyUserName }] : []),
...(item.rectificationDeadline ? [{ label: "整改完成期限", children: item.rectificationDeadline }] : []),
...(item.checkDeptName ? [{ label: "验收部门", children: item.checkDeptName }] : []),
...(item.checkUserName ? [{ label: "验收人", children: item.checkUserName }] : []),
...(item.repulseCause
? [
...(item.repulseCause ? [{ label: "打回意见", children: item.repulseCause }] : []),
...(item.rectificationTime ? [{ label: "打回时间", children: item.rectificationTime }] : []),
]
: []),
]}
/>
))
}
</>
)
}
{
info.hiddenExtensionList && info.hiddenExtensionList.length > 0 && (
<>
<Divider orientation="left">延期信息</Divider>
{
info.hiddenExtensionList.map(item => (
<Descriptions
key={item.id}
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
...(item.createTime ? [{ label: "申请延期日期", children: item.createTime }] : []),
...(item.delayTime ? [{ label: "延期日期", children: item.delayTime }] : []),
...(item.updateName ? [{ label: "审核人", children: item.updateName }] : []),
...(item.state === 3
? [
...(item.disposalPlan ? [{ label: "处置方案", children: item.disposalPlan }] : []),
...(item.disposalFile
? [{
label: "处置方案附件",
children: (
getFileSuffix(item.disposalFile) === "pdf"
? <PreviewPdf name={getFileName(item.disposalFile)} url={item.disposalFile} />
: (
<Space>
<span>{getFileName(item.disposalFile)}</span>
<Button
type="primary"
size="small"
onClick={() => downloadFile(item.disposalFile)}
>
下载
</Button>
</Space>
)
),
}]
: []),
]
: []),
{
label: "延期审核状态",
children: (
<>
{item.state === 1 && <span>待审核</span>}
{item.state === 2 && <span>审批中</span>}
{item.state === 3 && <span>已通过</span>}
{item.state === 4 && <span>已拒绝</span>}
{item.state === 5 && <span>已撤回</span>}
</>
),
},
...((item.state === 3 || item.state === 4)
? [{
label: "延期审核时间",
children: item.updateTime,
}]
: []),
]}
/>
),
)
}
</>
)
}
{
info.hiddenSpecialList && info.hiddenSpecialList.length > 0 && (
<>
<Divider orientation="left">特殊处置审核信息</Divider>
{
info.hiddenSpecialList.map(item => (
<Descriptions
key={item.id}
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
...((item.state === 3 || item.state === 4)
? [
...(item.updateName ? [{ label: "审核人", children: item.updateName }] : []),
...(item.updateTime ? [{ label: "审核时间", children: item.updateTime }] : []),
]
: []),
{ label: "无法整改原因", children: item.examine },
...(item.state === 3
? [
...(item.disposalPlan ? [{ label: "处置方案", children: item.disposalPlan }] : []),
...(item.disposalFile
? [{
label: "处置方案附件",
children: (
getFileSuffix(item.disposalFile) === "pdf"
? <PreviewPdf name={getFileName(item.disposalFile)} url={item.disposalFile} />
: (
<Space>
<span>{getFileName(item.disposalFile)}</span>
<Button
type="primary"
size="small"
onClick={() => downloadFile(item.disposalFile)}
>
下载
</Button>
</Space>
)
),
}]
: []),
{
label: "是否更换整改负责人",
children: item.rectifyUserCO && Object.keys(item.rectifyUserCO).length > 0 ? "是" : "否",
},
...(
item.rectifyUserCO && Object.keys(item.rectifyUserCO).length > 0
? [{ label: "整改负责人", children: item.rectifyUserCO.userName }]
: []),
]
: []),
{
label: "特殊处置审核状态",
children: (
<>
{item.state === 1 && <span>待审核</span>}
{item.state === 2 && <span>审批中</span>}
{item.state === 3 && <span>已通过</span>}
{item.state === 4 && <span>已拒绝</span>}
{item.state === 5 && <span>已撤回</span>}
</>
),
},
]}
/>
),
)
}
</>
)
}
{
(info.hiddenRectifyUserCO && info.hiddenRectifyUserCO.length > 0) && (
<>
<Divider orientation="left">整改信息</Divider>
{
info.hiddenRectifyUserCO.map((item, index) => (
<Descriptions
key={item.id}
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
...(item.deptName ? [{ label: `整改${info.isRelated === 1 ? "单位" : "部门"}`, children: item.deptName }] : []),
...(item.userName ? [{ label: "整改人", children: item.userName }] : []),
...(item.rectificationTime ? [{ label: "整改时间", children: item.rectificationTime }] : []),
...(item.descr ? [{ label: "整改描述", children: item.descr }] : []),
...(item.investmentFunds ? [{ label: "投入资金", children: `${item.investmentFunds}` }] : []),
...(info.tempSafeMeasure ? [{ label: "临时安全措施", children: info.tempSafeMeasure }] : []),
{ label: "整改后图片", children: <PreviewImg files={afterRectificationImageFiles[index]} /> },
{
label: "整改方案",
children: (
<>
{item.isRectificationScheme === 0 && <span></span>}
{item.isRectificationScheme === 1 && <span></span>}
</>
),
},
...((item.isRectificationScheme === 1 && item.hiddenSchemeCO && Object.keys(item.hiddenSchemeCO).length > 0)
? [
{ label: "治理标准", children: item.hiddenSchemeCO.governStanDards },
{ label: "治理方法", children: item.hiddenSchemeCO.governMethod },
{ label: "经费落实", children: item.hiddenSchemeCO.expenditure },
{ label: "负责人员", children: item.hiddenSchemeCO.principal },
{ label: "工时安排", children: item.hiddenSchemeCO.programming },
{ label: "时限要求", children: item.hiddenSchemeCO.timeLimitFor },
{ label: "工作要求", children: item.hiddenSchemeCO.jobRequireMent },
{ label: "其他事项", children: item.hiddenSchemeCO.otherBusiness },
{ label: "方案图片", children: <PreviewImg files={rectificationPlanImageFiles[index]} /> },
]
: []),
]}
/>
))
}
</>
)
}
{
(info.hiddenAcceptUserCO && info.hiddenAcceptUserCO.length > 0)
? (
info.isQualified === 1
? (
<>
<Divider orientation="left">验收信息</Divider>
{ {
label: "整改方案", children: ( info.hiddenAcceptUserCO.map((item, index) => (
<> <Descriptions
{item.isRectificationScheme === 0 && <span></span>} key={item.id}
{item.isRectificationScheme === 1 && <span></span>} bordered
</> column={1}
) styles={{ label: { width: 200 } }}
}, items={[
...((item.isRectificationScheme === 1 && item.hiddenSchemeCO && Object.keys(item.hiddenSchemeCO).length > 0) { label: "验收部门", children: item.deptName },
? [ { label: "验收人", children: item.userName },
{ label: "治理标准", children: item.hiddenSchemeCO.governStanDards }, { label: "验收时间", children: item.rectificationTime },
{ label: "治理方法", children: item.hiddenSchemeCO.governMethod }, ...(item.repulseCause ? [{ label: "验收打回意见", children: item.repulseCause }] : []),
{ label: "经费落实", children: item.hiddenSchemeCO.expenditure }, { label: "是否合格", children: item.rectificationTime ? "合格" : "" },
{ label: "负责人员", children: item.hiddenSchemeCO.principal }, ...(item.descr ? [{ label: "验收描述", children: item.descr }] : []),
{ label: "工时安排", children: item.hiddenSchemeCO.programming }, ...((acceptImageFiles[index] && acceptImageFiles[index].length > 0) ? [{ label: "验收图片", children: <PreviewImg files={acceptImageFiles[index]} /> }] : []),
{ label: "时限要求", children: item.hiddenSchemeCO.timeLimitFor }, ]}
{ label: "工作要求", children: item.hiddenSchemeCO.jobRequireMent }, />
{ label: "其他事项", children: item.hiddenSchemeCO.otherBusiness }, ))
{ label: "方案图片", children: <PreviewImg files={rectificationPlanImageFiles[index]} /> }, }
] </>
: []), )
]} : (
/> <>
)) <Divider orientation="left">验收打回信息</Divider>
} {
</> info.hiddenAcceptUserCO.map(item => (
) <Descriptions
} key={item.id}
{ bordered
(info.hiddenAcceptUserCO && info.hiddenAcceptUserCO.length > 0) column={1}
? ( styles={{ label: { width: 200 } }}
info.isQualified === 1 items={[
? ( { label: "验收部门", children: item.deptName },
<> { label: "验收人", children: item.userName },
<Divider orientation="left">验收信息</Divider> { label: "验收时间", children: item.rectificationTime },
{ { label: "验收打回意见", children: item.repulseCause },
info.hiddenAcceptUserCO.map((item, index) => ( ]}
<Descriptions />
key={item.id} ))
bordered }
column={1} </>
styles={{ label: { width: 200 } }} )
items={[ )
{ label: "验收部门", children: item.deptName }, : null
{ label: "验收人", children: item.userName }, }
{ label: "验收时间", children: item.rectificationTime }, {
...(item.repulseCause ? [{ label: "验收打回意见", children: item.repulseCause }] : []), (info.hiddenInspecCO && Object.keys(info.hiddenInspecCO).length > 0)
{ label: "是否合格", children: item.rectificationTime ? "合格" : "" }, ? (
...(item.descr ? [{ label: "验收描述", children: item.descr }] : []), <>
...((acceptImageFiles[index] && acceptImageFiles[index].length > 0) ? [{ label: "验收图片", children: <PreviewImg files={acceptImageFiles[index]} /> }] : []), <Divider orientation="left">安全环保验收信息</Divider>
]} <Descriptions
/> bordered
)) column={1}
} styles={{ label: { width: 200 } }}
</> items={[
) { label: "验收人", children: info.hiddenInspecCO.finalCheckOr },
: ( { label: "验收时间", children: info.hiddenInspecCO.finalCheckTime },
<> { label: "是否合格", children: info.hiddenInspecCO.finalCheck === 1 ? "合格" : "不合格" },
<Divider orientation="left">验收打回信息</Divider> { label: "验收描述", children: info.hiddenInspecCO.finalCheckDesc },
{ { label: "验收图片", children: <PreviewImg files={inspectionAcceptImageFiles} /> },
info.hiddenAcceptUserCO.map(item => ( ]}
<Descriptions />
key={item.id} </>
bordered )
column={1} : null
styles={{ label: { width: 200 } }} }
items={[
{ label: "验收部门", children: item.deptName },
{ label: "验收人", children: item.userName },
{ label: "验收时间", children: item.rectificationTime },
{ label: "验收打回意见", children: item.repulseCause },
]}
/>
))
}
</>
)
)
: null
}
{
(info.hiddenInspecCO && Object.keys(info.hiddenInspecCO).length > 0)
? (
<>
<Divider orientation="left">安全环保验收信息</Divider>
<Descriptions
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
{ label: "验收人", children: info.hiddenInspecCO.finalCheckOr },
{ label: "验收时间", children: info.hiddenInspecCO.finalCheckTime },
{ label: "是否合格", children: info.hiddenInspecCO.finalCheck === 1 ? "合格" : "不合格" },
{ label: "验收描述", children: info.hiddenInspecCO.finalCheckDesc },
{ label: "验收图片", children: <PreviewImg files={inspectionAcceptImageFiles} /> },
]}
/>
</>
)
: null
}
</div>
</Spin> </Spin>
{ {
videoModalOpen && ( videoModalOpen && (
@ -511,4 +513,6 @@ function HiddenInfo(props) {
); );
} }
HiddenInfo.displayName = "HiddenInfo";
export default HiddenInfo; export default HiddenInfo;

View File

@ -249,4 +249,6 @@ const MapSelector = (props) => {
); );
}; };
MapSelector.displayName = "MapSelector";
export default MapSelector; export default MapSelector;

View File

@ -72,4 +72,6 @@ const Map = (props) => {
); );
}; };
Map.displayName = "Map";
export default Map; export default Map;

30
components/Page/index.d.ts vendored Normal file
View File

@ -0,0 +1,30 @@
import type { FC, ReactNode } from "react";
export interface PageProps {
/** 头部返回组件的标题 */
headerTitle?: ReactNode;
/** 历史记录对象,用于返回上一页,默认使用 window.history.back */
history?: {
goBack?: () => void;
[key: string]: any;
};
/** 是否显示头部组件,默认 true */
isShowHeader?: boolean;
/** 是否显示头部组件返回按钮,默认 true */
headerPrevious?: boolean;
/** 是否显示底部组件,默认 true */
isShowFooter?: boolean;
/** 是否显示头部和底部组件,默认 true */
isShowAllAction?: boolean;
/** 取消按钮文字,默认 "关闭" */
backButtonText?: string;
/** 自定义底部操作按钮组 */
customActionButtons?: ReactNode;
/** 额外底部操作按钮组 */
extraActionButtons?: ReactNode;
}
/** 页面布局组件 */
declare const Page: FC<PageProps>;
export default Page;

49
components/Page/index.js Normal file
View File

@ -0,0 +1,49 @@
import { Button, Space } from "antd";
import HeaderBack from "../HeaderBack";
/**
* 页面布局组件
*/
function Page(props) {
const {
headerTitle,
history,
isShowHeader = true,
headerPrevious = true,
isShowFooter = true,
isShowAllAction = true,
backButtonText = "关闭",
customActionButtons,
extraActionButtons,
} = props;
return (
<div className="page">
{(isShowAllAction && isShowHeader) && <HeaderBack title={headerTitle} history={history} previous={headerPrevious} />}
<div style={{ padding: 20 }}>
{props.children}
</div>
{
(isShowAllAction && isShowFooter) && (
<>
<div style={{ height: "52px" }}></div>
<div style={{ textAlign: "center", backgroundColor: "rgb(241, 241, 242)", margin: "0 -20px", padding: "10px 0", position: "fixed", bottom: "0", width: "100%" }}>
{customActionButtons || (
<Space>
{extraActionButtons}
<Button onClick={() => history?.goBack?.() || window.history.back()}>
{backButtonText}
</Button>
</Space>
)}
</div>
</>
)
}
</div>
);
}
Page.displayName = "Page";
export default Page;

View File

@ -9,7 +9,7 @@ export interface PdfProps {
visible?: boolean; visible?: boolean;
/** 关闭弹窗的方法 */ /** 关闭弹窗的方法 */
onCancel?: () => void; onCancel?: () => void;
/** 是否使用内联模式true为不使用弹窗默认false */ /** 是否使用内联模式true为不使用弹窗默认 false */
inline?: boolean; inline?: boolean;
/** 内联模式下的样式 */ /** 内联模式下的样式 */
style?: CSSProperties; style?: CSSProperties;

View File

@ -110,14 +110,16 @@ function Pdf(props) {
> >
关闭 关闭
</Button>, </Button>,
!loading && <Button !loading && (
key="fullScreen" <Button
onClick={() => { key="fullScreen"
isFullscreen ? exitFullscreen() : enterFullscreen(); onClick={() => {
}} isFullscreen ? exitFullscreen() : enterFullscreen();
> }}
{isFullscreen ? "退出全屏" : "全屏"} >
</Button>, {isFullscreen ? "退出全屏" : "全屏"}
</Button>
),
<Button key="download" type="primary" onClick={onDownloadFile}>下载</Button>, <Button key="download" type="primary" onClick={onDownloadFile}>下载</Button>,
]} ]}
> >
@ -127,4 +129,6 @@ function Pdf(props) {
); );
} }
Pdf.displayName = "Pdf";
export default Pdf; export default Pdf;

View File

@ -12,7 +12,7 @@ const PreviewImg = (props) => {
return ( return (
<Image.PreviewGroup> <Image.PreviewGroup>
{ {
files.filter(Boolean).map((item) => ( files.filter(Boolean).map(item => (
<Image <Image
key={item[fileUrlKey] || item} key={item[fileUrlKey] || item}
src={item[fileUrlKey] ? fileUrl + item[fileUrlKey] : fileUrl + item} src={item[fileUrlKey] ? fileUrl + item[fileUrlKey] : fileUrl + item}
@ -27,4 +27,6 @@ const PreviewImg = (props) => {
); );
}; };
PreviewImg.displayName = "PreviewImg";
export default PreviewImg; export default PreviewImg;

View File

@ -81,4 +81,6 @@ const PreviewPdf = (props) => {
return null; return null;
}; };
PreviewPdf.displayName = "PreviewPdf";
export default PreviewPdf; export default PreviewPdf;

View File

@ -83,54 +83,56 @@ const Search = (props) => {
}; };
return ( return (
<Form <div className="search-layout card-layout">
form={form} <Form
labelCol={labelCol} form={form}
initialValues={values} labelCol={labelCol}
{...restProps} initialValues={values}
> {...restProps}
<Row className={classNameRef.current}> >
<FormItemsRenderer <Row className={classNameRef.current}>
options={options} <FormItemsRenderer
labelCol={labelCol} options={options}
span={6} labelCol={labelCol}
collapse={collapse} span={6}
useAutoGenerateRequired={false} collapse={collapse}
initialValues={values} useAutoGenerateRequired={false}
/> initialValues={values}
<Col span={showCollapseButton ? (collapse ? 6 : span) : span}> />
<Form.Item label=" " labelCol={{ span: 2 }} colon={false} style={{ textAlign: "right" }}> <Col span={showCollapseButton ? (collapse ? 6 : span) : span}>
{showSearchButton && ( <Form.Item label=" " labelCol={{ span: 2 }} colon={false} style={{ textAlign: "right" }}>
<Button type="primary" icon={<SearchIcon />} onClick={handleSubmit}> {showSearchButton && (
{searchText} <Button type="primary" icon={<SearchIcon />} onClick={handleSubmit}>
</Button> {searchText}
)} </Button>
{showResetButton && ( )}
<Button style={{ marginLeft: 8 }} icon={<ResetIcon />} onClick={handleReset}> {showResetButton && (
{resetText} <Button style={{ marginLeft: 8 }} icon={<ResetIcon />} onClick={handleReset}>
</Button> {resetText}
)} </Button>
{showCollapseButton && ( )}
<Button {showCollapseButton && (
type="link" <Button
icon={collapse ? <DownOutlined /> : <UpOutlined />} type="link"
onClick={toggleCollapse} icon={collapse ? <DownOutlined /> : <UpOutlined />}
style={{ marginLeft: 8 }} onClick={toggleCollapse}
> style={{ marginLeft: 8 }}
{collapse ? "展开" : "收起"} >
</Button> {collapse ? "展开" : "收起"}
)} </Button>
</Form.Item> )}
</Col>
{extraButtons && (
<Col span={24}>
<Form.Item label=" " colon={false} labelCol={{ span: 0 }}>
{extraButtons}
</Form.Item> </Form.Item>
</Col> </Col>
)} {extraButtons && (
</Row> <Col span={24}>
</Form> <Form.Item label=" " colon={false} labelCol={{ span: 0 }}>
{extraButtons}
</Form.Item>
</Col>
)}
</Row>
</Form>
</div>
); );
}; };

View File

@ -12,7 +12,7 @@ function PersonnelSelect(props) {
isNeedCorpInfoId = false, isNeedCorpInfoId = false,
isNeedDepartmentId = true, isNeedDepartmentId = true,
isNeedPostId = false, isNeedPostId = false,
extraParams= { extraParams = {
noMain: "", noMain: "",
eqEmploymentFlag: 1, eqEmploymentFlag: 1,
}, },

View File

@ -13,7 +13,7 @@ export interface SelectCreateOption {
export interface SelectCreateProps extends SelectProps { export interface SelectCreateProps extends SelectProps {
/** 选项列表 */ /** 选项列表 */
items: SelectCreateOption[]; items: SelectCreateOption[];
/** 是否显示删除图标,默认 true */ /** 是否显示删除图标,默认 true */
showDelete?: boolean; showDelete?: boolean;
/** 标签名称,用于占位符显示 */ /** 标签名称,用于占位符显示 */
label?: string; label?: string;

View File

@ -50,4 +50,6 @@ function SelectCreate(props) {
); );
} }
SelectCreate.displayName = "SelectCreate";
export default SelectCreate; export default SelectCreate;

View File

@ -12,9 +12,9 @@ export interface SignatureValue {
export interface SignatureProps { export interface SignatureProps {
/** 确认签字回调 */ /** 确认签字回调 */
onConfirm: (value: SignatureValue) => void; onConfirm: (value: SignatureValue) => void;
/** 签字区域宽度,默认 752 */ /** 签字区域宽度,默认 752 */
width?: number; width?: number;
/** 签字区域高度,默认 300 */ /** 签字区域高度,默认 300 */
height?: number; height?: number;
/** 回显的签字图片 */ /** 回显的签字图片 */
url?: string; url?: string;

View File

@ -89,4 +89,6 @@ function Signature(props) {
); );
} }
Signature.displayName = "Signature";
export default Signature; export default Signature;

View File

@ -5,7 +5,7 @@ import type { FC } from "react";
/** /**
* TablePro * TablePro
*/ */
export type TableProps<DataSource, U, ValueType> = Omit<AntdTableProps, 'columns'> & ProTableProps<DataSource, U, ValueType> & { export type TableProps<DataSource, U, ValueType> = Omit<AntdTableProps, "columns"> & ProTableProps<DataSource, U, ValueType> & {
/** 当一个路由下存在多个表格的情况下 需要给每一个表格设置一个唯一存储索引 若没有设置则使用默认索引,请注意缓存数据会被覆盖 */ /** 当一个路由下存在多个表格的情况下 需要给每一个表格设置一个唯一存储索引 若没有设置则使用默认索引,请注意缓存数据会被覆盖 */
storeIndex?: string; storeIndex?: string;
/** 是否禁用内容区滚动,默认 false */ /** 是否禁用内容区滚动,默认 false */
@ -14,9 +14,11 @@ export type TableProps<DataSource, U, ValueType> = Omit<AntdTableProps, 'columns
showIndexColumn?: boolean; showIndexColumn?: boolean;
/** 索引列是否固定,默认 left */ /** 索引列是否固定,默认 left */
indexColumnFixed?: "left" | "right" | boolean; indexColumnFixed?: "left" | "right" | boolean;
/** 是否使用居中布局,默认 true */ /** 列的对齐方式,默认 center */
useAlignCenter?: boolean; align?: "left" | "right" | "center";
} /** 超过宽度是否自动省略,默认 true */
ellipsis?: boolean;
};
/** /**
* *

View File

@ -1,28 +1,73 @@
import TablePro from "@cqsjjb/jjb-react-admin-component/Table"; import TablePro from "@cqsjjb/jjb-react-admin-component/Table";
import { getIndexColumn } from "../../utils/index"; import { getIndexColumn } from "../../utils/index";
import dayjs from 'dayjs';
import "./index.less"; import "./index.less";
const CLEANUP_INTERVAL_DAYS = 10; // 清理间隔天数
const LAST_CLEANUP_KEY = 'tableLocalStorageLastCleanup'; // 最后清理时间存储key
// 清理本地存储中特定后缀的key
function cleanupTableLocalStorage() {
const now = dayjs();
const lastCleanupStr = localStorage.getItem(LAST_CLEANUP_KEY);
const lastCleanup = lastCleanupStr ? dayjs(lastCleanupStr) : null;
// 如果没有上次清理时间或距离上次清理已超过10天
if (!lastCleanup || now.diff(lastCleanup, 'day') >= CLEANUP_INTERVAL_DAYS) {
// 查找并清理符合条件的key
const keysToRemove = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && (key.endsWith('#columnState') ||
key.endsWith('#size') ||
key.endsWith('#resizable'))) {
keysToRemove.push(key);
}
}
// 删除匹配的key
keysToRemove.forEach(key => {
localStorage.removeItem(key);
});
// 更新最后清理时间
localStorage.setItem(LAST_CLEANUP_KEY, now.toISOString());
}
}
function Table(props) { function Table(props) {
const { const {
columns = [], columns = [],
showIndexColumn = true, showIndexColumn = true,
useAlignCenter = true, ellipsis = true,
align = "center",
indexColumnFixed = "left", indexColumnFixed = "left",
rowKey = "id", rowKey = "id",
...restProps ...restProps
} = props; } = props;
function calcColumns() {
showIndexColumn && columns.unshift({...getIndexColumn(props.pagination), fixed: indexColumnFixed});
const setAlign = (column) => ({ // 组件初始化时执行清理
align: useAlignCenter ? "center" : "left", cleanupTableLocalStorage();
function settingColumns() {
showIndexColumn && columns.unshift({ ...getIndexColumn(props.pagination), fixed: indexColumnFixed });
const setAlign = column => ({
align,
ellipsis,
...column, ...column,
...(column.children ? { children: column.children.map(setAlign) } : {}) ...(column.children ? { children: column.children.map(setAlign) } : {}),
}); });
return columns.map(setAlign); return columns.map(setAlign);
} }
return <TablePro rowKey={rowKey} columns={calcColumns()} bordered {...restProps} />; return (
<div className="table-layout card-layout">
<TablePro rowKey={rowKey} columns={settingColumns()} bordered size="small" {...restProps} />
</div>
);
} }
Table.displayName = "Table";
export default Table; export default Table;

View File

@ -9,5 +9,6 @@
} }
.@{ant-prefix}-pro-table-list-toolbar-container { .@{ant-prefix}-pro-table-list-toolbar-container {
padding-block: 16px !important; padding-top: 26px !important;
padding-bottom: 16px;
} }

View File

@ -22,4 +22,6 @@ const TooltipPreviewImg = (props) => {
); );
}; };
TooltipPreviewImg.displayName = "TooltipPreviewImg";
export default TooltipPreviewImg; export default TooltipPreviewImg;

View File

@ -17,7 +17,7 @@ export interface UploadProps extends Omit<AntUploadProps, "fileList"> {
tipContent?: ReactNode; tipContent?: ReactNode;
/** listType 为 text 时上传按钮文本 */ /** listType 为 text 时上传按钮文本 */
uploadButtonText?: string; uploadButtonText?: string;
/** 要上传的文件类型,默认 image */ /** 要上传的文件类型,默认 image */
fileType?: "image" | "video" | "document"; fileType?: "image" | "video" | "document";
/** 获取上传过服务器删除的附件 */ /** 获取上传过服务器删除的附件 */
onGetRemoveFile?: (file: Omit<UploadFile, "originFileObj">) => void; onGetRemoveFile?: (file: Omit<UploadFile, "originFileObj">) => void;

View File

@ -132,7 +132,7 @@ const Upload = (props) => {
const handleBeforeUpload = (file, fileList) => { const handleBeforeUpload = (file, fileList) => {
if (beforeUpload) if (beforeUpload)
return beforeUpload(file, fileList) return beforeUpload(file, fileList);
return false; return false;
}; };
@ -196,7 +196,7 @@ const Upload = (props) => {
if (!file.originFileObj) if (!file.originFileObj)
onGetRemoveFile?.(file); onGetRemoveFile?.(file);
return onRemove?.(file); return onRemove?.(file);
} };
// 预览文件 // 预览文件
const handlePreview = (file) => { const handlePreview = (file) => {

31
css/common.less Normal file
View File

@ -0,0 +1,31 @@
.@{ant-prefix}-modal-header {
border-bottom: 1px solid #ccc !important;
margin: 0 -24px 15px -24px !important;
padding: 0 24px 15px 24px !important;
}
.@{ant-prefix}-modal-footer {
text-align: center !important;
}
.search-layout {
position: relative;
&::after {
content: '';
position: absolute;
bottom: -10px;
left: -20px;
right: -20px;
height: 10px;
background-color: rgb(241, 241, 242);
}
}
.table-layout {
}
.card-layout {
background-color: #fff;
border-radius: 6px;
}

View File

@ -8,6 +8,7 @@
"license": "MIT", "license": "MIT",
"files": [ "files": [
"components", "components",
"css",
"enum", "enum",
"hooks", "hooks",
"json", "json",