💥 feat(模块): 添加了个很棒的功能

This commit is contained in:
ylj20011123 2025-06-27 17:11:05 +08:00
parent 492ca057cb
commit 7c7f6abdac
4 changed files with 1052 additions and 610 deletions

View File

@ -19,6 +19,7 @@
"numeral": "^2.0.6",
"qrcode": "^1.5.4",
"qs": "^6.14.0",
"react-html-table-to-excel": "^2.0.0",
"umi": "^4.3.24",
"xlsx": "^0.18.5",
"xlsx-style-fixed": "^0.0.4"

View File

@ -3,18 +3,21 @@ import { ActionType, FormInstance, ProTable } from "@ant-design/pro-components";
import { useRef, useState } from "react";
import { connect } from "umi";
import moment from "moment";
import { Button, Drawer, Image, message, Popconfirm, Space } from "antd";
import { Button, Drawer, Image, message, Popconfirm, Space, Spin } from "antd";
import { handleGetServerpartDDL } from "@/components/leftSelectTree/service";
import LeftSelectTree from "@/components/leftSelectTree/leftSelectTree";
import RecordDetail from "../record/components/recordDetail";
import { handleDeleteRecord, handleGetRecordTreeList, handleUpdateExtend } from "../record/service";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
const ErrorRecord: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const recordDetailRef = useRef<any>()
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
// 显示的附件数据
const [showImgList, setShowImgList] = useState<string[]>([])
// 预览图片
@ -33,6 +36,15 @@ const ErrorRecord: React.FC<{ currentUser: any }> = (props) => {
score: { show: false }
})
const [collapsible, setCollapsible] = useState<boolean>(false)
// 显示详情抽屉
const [showDetailStatus, setShowDetailStatus] = useState<boolean>(false)
// 详情抽屉的点击行数据
const [currentStatusRow, setCurrentStatusRow] = useState<any>()
// 是否显示打印的表格
const [showExportTable, setShowExportTable] = useState<boolean>(false)
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
const columns: any = [
// {
@ -274,6 +286,42 @@ const ErrorRecord: React.FC<{ currentUser: any }> = (props) => {
}
]
const exportTable = (e) => {
e.stopPropagation(); // 防止Collapse组件收起
const main = document.getElementsByClassName(`saleReportHideBox${printIndex}`)[0]
const thead = main.querySelector('thead').cloneNode(true); // 深克隆DOM节点
const tbody = main.querySelector('tbody').cloneNode(true); // 深克隆DOM节点
const container = document.querySelector('#hiddenBox');
// 加个标题
const tableTop = document.createElement('div')
tableTop.innerText = `异常统计表`
tableTop.setAttribute('style', 'font-size:20px;font-weight:600;display:flex;width:100%;justify-content: center;text-align: center;');
// 加个时间
const tableTime = document.createElement('div')
tableTime.innerText = `${moment().format('YYYY-MM-DD')}`
tableTop.setAttribute('style', 'font-size:14px;display:flex;width:100%;justify-content: flex-start;text-align: center;');
const tempTable = document.createElement('table');
tempTable.appendChild(tableTop)
tempTable.appendChild(tableTime)
tempTable.appendChild(thead);
tempTable.appendChild(tbody);
tempTable.setAttribute('id', 'table-to-xls-saleRankReport'); // 给table添加id值与按钮上的table字段对应
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
setShowLoading(false)
downloadBtnRef.current.handleDownload();
setShowExportTable(false)
tempTable.remove() // 防止重复打印一个内容
}
// 删除记录
const deleteRecord = async (id: any) => {
const data = await handleDeleteRecord({ id: id })
@ -283,220 +331,400 @@ const ErrorRecord: React.FC<{ currentUser: any }> = (props) => {
}
}
const exportColumns: any = [
{
title: "片区",
dataIndex: "SPRegionTypeName",
align: 'center'
},
{
title: "服务区",
dataIndex: "ServerPartName",
align: 'center'
},
{
title: "巡查点位",
dataIndex: "placeName",
align: 'center'
},
{
title: "考核子类",
dataIndex: "takeTheNuclearExam",
align: 'center'
},
{
title: "考核结果",
dataIndex: "assessmentResults",
align: 'center'
},
{
title: "巡查人员",
dataIndex: "userName",
align: 'center'
},
{
title: "巡查时间",
dataIndex: "createdAt",
align: 'center'
},
{
title: "巡查状态",
dataIndex: "errorStatus",
align: 'center'
},
]
return (
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
// width: "100%",
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
expandable={{
expandRowByClick: true
}}
rowKey={(record) => {
return `${record?.id}-${record?.code}-${record?.templateId}`
}}
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>}
search={{ span: 6 }}
request={async (params) => {
// selectedId
console.log('params', params);
console.log('selectedId', selectedId);
if (!(selectedId && selectedId.length > 0)) {
return
}
const req: any = {
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
// startTime: params?.search_months ? `${moment(params?.search_months).startOf('M').format('YYYY-MM-DD')}` : "",
// endTime: params?.search_months ? `${moment(params?.search_months).endOf('M').format('YYYY-MM-DD')}` : "",
// serverPartId: params?.serverPartId ? params?.serverPartId : undefined,
extend: params?.errorStatus ? [{
key: "situation",
value: '1'
},
{
key: "errorStatus",
value: params?.errorStatus
}
] : [{
key: "situation",
value: '1'
}]
}
console.log('req', req);
const data = await handleGetRecordTreeList(req)
console.log('data', data);
if (data && data.length > 0) {
return { data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
>
</ProTable>
</div>
<div>
{
showImgList && showImgList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
setImagePreviewVisible(vis)
},
current: previewIndex
showLoading ?
<div
style={{
width: '100%',
height: '100%',
background: 'rgba(0,0,0,0.1)',
position: 'fixed',
zIndex: 5,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '15px 20px 10px',
background: '#fff',
borderRadius: '8px',
width: '200px'
}}>
{
showImgList.map((n) =>
<Image src={n} key={n} />
)
}
</Image.PreviewGroup>
</div>
<Spin />
<span style={{ marginLeft: '5px' }}>...</span>
</div>
</div> : ''
}
<Drawer
title={false}
closeIcon={false}
onClose={() => {
setShowDetail(false)
setShowAbnormal(false)
}}
open={showDetail}
destroyOnClose
width={'60%'}
footer={showAbnormal && currentRow?.errorStatus !== 2 ? <div style={{ width: "100%", boxSizing: 'border-box', padding: "0 24px", display: 'flex', justifyContent: 'flex-end' }}>
<Button type="primary" onClick={() => {
console.log('recordDetailRef.current?.formRes.errorStatus', recordDetailRef.current?.formRes.errorStatus);
if (recordDetailRef.current?.formRes.errorStatus === 0) {
recordDetailRef.current?.errorStatusFormRef.current?.validateFields().then(async (res: any) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
let personObj: any = {}
let personList: any = recordDetailRef.current?.selectPersonList
if (personList && personList.length > 0) {
personList.forEach((item: any) => {
if (item.STAFF_ID === res.personIndex) {
personObj = item
}
})
}
console.log('personObj', personObj);
const req = {
...extendObj,
// person: personObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
personId: personObj.STAFF_ID,
personMemberShipId: personObj.MEMBERSHIP_ID,
personMemberShipName: personObj.MEMBERSHIP_NAME,
personName: personObj.STAFF_NAME,
errorStatus: 1,
suggestion: res.suggestion,
suggestTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 选处理人的时间
// suggestPerson: {
// STAFF_NAME: currentUser.adminName,
// STAFF_ID: currentUser.id,
// MEMBERSHIP_NAME: currentUser.adminName,
// MEMBERSHIP_ID: currentUser.id,
// },
suggestMemberShipId: currentUser.id,
suggestMemberShipName: currentUser.adminName,
suggestPersonId: currentUser.id,
suggestPersonName: currentUser.adminName,
};
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
setShowAbnormal(false)
actionRef.current?.reload()
setCurrentRow(undefined)
} else {
message.error(data.Result_Desc)
}
})
}
if (recordDetailRef.current?.formRes.errorStatus === 1) {
recordDetailRef.current?.errorStatusFormReflast.current?.validateFields().then(async (res: any) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
console.log('recordDetailRef.current?.fileList', recordDetailRef.current?.fileList);
let fileList: any = []
if (recordDetailRef.current?.fileList && recordDetailRef.current?.fileList.length > 0) {
recordDetailRef.current?.fileList.forEach((item: any) => {
// fileList.push(item.url)
fileList.push({
keyName: item.id,
imageUrl: item.url
})
// keyName: item.id,
// imageUrl: subItem
})
}
console.log('fileList', fileList);
const req = {
...extendObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
feedbackImgList: fileList,
feedbackContent: res.feedbackContent,
feedbackTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 反馈时间
errorStatus: 2,
};
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
setShowAbnormal(false)
actionRef.current?.reload()
setCurrentRow(undefined)
} else {
message.error(data.Result_Desc)
}
})
}
}}></Button>
</div> : false
<div className={`saleReportHideBox${printIndex}`} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
columns={exportColumns}
dataSource={reqDetailList}
pagination={false}
expandable={{
defaultExpandAllRows: true
}}
/> : ''
}
>
<RecordDetail onRef={recordDetailRef} parentRow={currentRow} show={showDetail} showError={showAbnormal} />
</Drawer >
</div >
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} currentUser={currentUser} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
// width: "100%",
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
expandable={{
expandRowByClick: true
}}
rowKey={(record) => {
return `${record?.id}-${record?.code}-${record?.templateId}`
}}
scroll={{ x: "100%", y: 'calc(100vh - 400px)' }}
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>}
search={{ span: 6 }}
request={async (params) => {
// selectedId
console.log('params', params);
console.log('selectedId', selectedId);
if (!(selectedId && selectedId.length > 0)) {
return
}
const req: any = {
serverPartIds: selectedId && selectedId.length > 0 ? selectedId : [],
// startTime: params?.search_months ? `${moment(params?.search_months).startOf('M').format('YYYY-MM-DD')}` : "",
// endTime: params?.search_months ? `${moment(params?.search_months).endOf('M').format('YYYY-MM-DD')}` : "",
// serverPartId: params?.serverPartId ? params?.serverPartId : undefined,
extend: params?.errorStatus ? [{
key: "situation",
value: '1'
},
{
key: "errorStatus",
value: params?.errorStatus
}
] : [{
key: "situation",
value: '1'
}]
}
console.log('req', req);
const data = await handleGetRecordTreeList(req)
console.log('data', data);
if (data && data.length > 0) {
// 处理数据
let exportData: any[] = []
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((child: any) => {
let childrenText: string = ''
let childrenRes: string = ''
if (child.questionResponses && child.questionResponses.length > 0) {
child.questionResponses.forEach((questionItem: any) => {
if (questionItem.score === 0) {
if (childrenText) {
childrenText += `,${questionItem.question.title}`
} else {
childrenText = `${questionItem.question.title}`
}
if (childrenRes) {
childrenRes += `,${questionItem.choiceResponse[0]}`
} else {
childrenRes = `${questionItem.choiceResponse[0]}`
}
}
})
}
exportData.push({
SPRegionTypeName: item.name,
ServerPartName: subItem.name,
placeName: child.template.title || '-',
takeTheNuclearExam: childrenText, // 考核子类
assessmentResults: childrenRes,// 考核结果
userName: child?.userName || "",// 巡查人员
createdAt: moment(child?.createdAt).format('YYYY-MM-DD HH:mm:ss'), // 巡查时间
errorStatus: child.errorStatus === 0
? "待处理"
: child.errorStatus === 1
? "处理中"
: child.errorStatus === 2
? "已处理"
: "-"// 处理状态
})
})
}
})
}
})
setReqDetailList(exportData)
return { data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-saleRankReport"
filename={`异常统计表`}
sheet="sheet1"
/>
</span>,
<Button
key="new"
type="primary"
onClick={(e) => {
if (reqDetailList && reqDetailList.length > 0) {
setShowLoading(true)
setTimeout(() => {
setShowExportTable(true)
setTimeout(() => {
exportTable(e)
}, 100)
}, 100)
} else {
message.error('暂无数据可导出!')
}
}}
>
excel
</Button>
]
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
>
</ProTable>
</div>
{
showImgList && showImgList.length > 0 && <div style={{ display: 'none' }}>
<Image.PreviewGroup
preview={{
visible: imagePreviewVisible,
onVisibleChange: vis => {
setImagePreviewVisible(vis)
},
current: previewIndex
}}>
{
showImgList.map((n) =>
<Image src={n} key={n} />
)
}
</Image.PreviewGroup>
</div>
}
<Drawer
title={false}
closeIcon={false}
onClose={() => {
setShowDetail(false)
setShowAbnormal(false)
}}
open={showDetail}
destroyOnClose
width={'60%'}
footer={showAbnormal && currentRow?.errorStatus !== 2 ? <div style={{ width: "100%", boxSizing: 'border-box', padding: "0 24px", display: 'flex', justifyContent: 'flex-end' }}>
<Button type="primary" onClick={() => {
console.log('recordDetailRef.current?.formRes.errorStatus', recordDetailRef.current?.formRes.errorStatus);
if (recordDetailRef.current?.formRes.errorStatus === 0) {
recordDetailRef.current?.errorStatusFormRef.current?.validateFields().then(async (res: any) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
let personObj: any = {}
let personList: any = recordDetailRef.current?.selectPersonList
if (personList && personList.length > 0) {
personList.forEach((item: any) => {
if (item.STAFF_ID === res.personIndex) {
personObj = item
}
})
}
console.log('personObj', personObj);
const req = {
...extendObj,
// person: personObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
personId: personObj.STAFF_ID,
personMemberShipId: personObj.MEMBERSHIP_ID,
personMemberShipName: personObj.MEMBERSHIP_NAME,
personName: personObj.STAFF_NAME,
errorStatus: 1,
suggestion: res.suggestion,
suggestTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 选处理人的时间
// suggestPerson: {
// STAFF_NAME: currentUser.adminName,
// STAFF_ID: currentUser.id,
// MEMBERSHIP_NAME: currentUser.adminName,
// MEMBERSHIP_ID: currentUser.id,
// },
suggestMemberShipId: currentUser.id,
suggestMemberShipName: currentUser.adminName,
suggestPersonId: currentUser.id,
suggestPersonName: currentUser.adminName,
};
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
setShowAbnormal(false)
actionRef.current?.reload()
setCurrentRow(undefined)
} else {
message.error(data.Result_Desc)
}
})
}
if (recordDetailRef.current?.formRes.errorStatus === 1) {
recordDetailRef.current?.errorStatusFormReflast.current?.validateFields().then(async (res: any) => {
console.log('res', res);
let extendObj = JSON.parse(recordDetailRef.current?.formRes.extend)
console.log('recordDetailRef.current?.fileList', recordDetailRef.current?.fileList);
let fileList: any = []
if (recordDetailRef.current?.fileList && recordDetailRef.current?.fileList.length > 0) {
recordDetailRef.current?.fileList.forEach((item: any) => {
// fileList.push(item.url)
fileList.push({
keyName: item.id,
imageUrl: item.url
})
// keyName: item.id,
// imageUrl: subItem
})
}
console.log('fileList', fileList);
const req = {
...extendObj,
questionnaireResponsesId: recordDetailRef.current?.formRes.id,
feedbackImgList: fileList,
feedbackContent: res.feedbackContent,
feedbackTime: moment().format('YYYY-MM-DD HH:mm:ss'), // 反馈时间
errorStatus: 2,
};
const data = await handleUpdateExtend(req)
if (data.Result_Code === 100) {
message.success('提交成功')
setShowDetail(false)
setShowAbnormal(false)
actionRef.current?.reload()
setCurrentRow(undefined)
} else {
message.error(data.Result_Desc)
}
})
}
}}></Button>
</div> : false
}
>
<RecordDetail onRef={recordDetailRef} parentRow={currentRow} show={showDetail} showError={showAbnormal} />
</Drawer >
</div >
</div>
)
}

File diff suppressed because it is too large Load Diff

View File

@ -9548,6 +9548,13 @@ react-helmet-async@1.3.0:
react-fast-compare "^3.2.0"
shallowequal "^1.1.0"
react-html-table-to-excel@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/react-html-table-to-excel/-/react-html-table-to-excel-2.0.0.tgz#c5b183121e4a07b47ce936337150dabb60f6012e"
integrity sha512-afvcCtQWZPfen3D+UFu9YMHleQqpVm3manmiWaxr0wv76hx+BkQ0/nkOI1UyQs29pzAUWtZDiD9Eu/MqsDOEJw==
dependencies:
prop-types "^15.5.10"
react-intl@3.12.1:
version "3.12.1"
resolved "https://registry.npmmirror.com/react-intl/-/react-intl-3.12.1.tgz#e9a783ea20302e9da25e4eda59e5593a43d2ec80"
@ -10485,7 +10492,16 @@ string-convert@^0.2.0:
resolved "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -10583,7 +10599,14 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@ -11436,7 +11459,7 @@ word@~0.3.0:
resolved "https://registry.npmmirror.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@ -11454,6 +11477,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"