<script lang="ts" setup>
|
import { computed, ref } from 'vue';
|
|
import { ExclamationCircleFilled } from '@ant-design/icons-vue';
|
|
const props = defineProps({
|
errorList: { type: Array as PropType<any[]>, default: () => [] },
|
});
|
const emit = defineEmits(['select']);
|
const visible = ref<boolean>(false);
|
defineExpose({ setVisible });
|
|
const getErrorList = computed(() => convertArrayToTree(props.errorList));
|
|
/**
|
* 将errorList转成树
|
* @param list errorList
|
*/
|
function convertArrayToTree(list) {
|
const newList: any[] = [];
|
list.map((item) => {
|
const index = newList.findIndex((o) => o.id === item.id);
|
if (index === -1) {
|
newList.push({ title: item.title, id: item.id, children: [{ errorInfo: item.errorInfo }] });
|
} else {
|
newList[index].children.push({ errorInfo: item.errorInfo });
|
}
|
return item;
|
});
|
return newList;
|
}
|
function handleSelect(id) {
|
setVisible(false);
|
emit('select', id);
|
}
|
function setVisible(data) {
|
visible.value = !!data;
|
}
|
</script>
|
<template>
|
<a-popover
|
v-model:open="visible"
|
trigger="click"
|
placement="bottom"
|
overlay-class-name="error-contain jnpf-flow-common-popover"
|
:bordered="false"
|
arrow-point-at-center
|
v-if="getErrorList.length">
|
<template #content>
|
<div class="w-[355px]">
|
<div class="error-title"><ExclamationCircleFilled class="error-icon" />内容不完善,校验失败!</div>
|
<div class="error-content">
|
<div class="error-item" v-for="(item, index) in getErrorList" :key="index">
|
<div class="error-sub-item error-top">
|
<div class="title" :title="item.title">{{ item.title }}</div>
|
<div>
|
<span>{{ item.children.length }}</span>
|
项
|
</div>
|
</div>
|
<div class="error-sub-item error-bottom" v-for="(child, childIndex) in item.children" :key="childIndex">
|
<div class="title" :title="child.errorInfo">{{ child.errorInfo }}</div>
|
<div class="write" v-if="item?.id" @click="handleSelect(item.id)">去填写</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<a-button shape="round" class="error-tips-button">
|
{{ getErrorList.length || 0 }}项不完善<i class="icon-ym icon-ym-unfold font ml-[5px] text-[10px]"></i>
|
</a-button>
|
</a-popover>
|
</template>
|
<style lang="scss">
|
.error-tips-button {
|
display: flex;
|
align-items: center;
|
|
&:hover i {
|
color: var(--primary-color);
|
}
|
|
i {
|
color: var(--text-color-label);
|
}
|
}
|
|
.error-contain {
|
.ant-popover-inner {
|
padding: unset !important;
|
overflow: hidden;
|
border-radius: 8px;
|
}
|
|
.ant-popover-arrow::before {
|
background: #fdc6c6 !important;
|
}
|
|
.error-title {
|
display: flex;
|
align-items: center;
|
height: 46px;
|
padding: 0 26px;
|
font-size: 16px;
|
font-weight: bold;
|
color: var(--text-color-base);
|
background: linear-gradient(26deg, #fceaea 0%, #fdc6c6 100%);
|
|
.error-icon {
|
margin-right: 4px;
|
color: var(--error-color);
|
}
|
}
|
|
.error-content {
|
max-height: 300px;
|
padding: 8px 26px;
|
overflow: auto;
|
|
.error-item {
|
display: flex;
|
flex-direction: column;
|
|
.error-sub-item {
|
display: flex;
|
justify-content: space-between;
|
line-height: 35px;
|
|
.title {
|
flex: 1;
|
min-width: 0;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
}
|
|
.error-top {
|
.title {
|
font-weight: bold;
|
}
|
|
span {
|
color: var(--error-color);
|
}
|
}
|
|
.error-bottom {
|
.title {
|
color: var(--text-color-label);
|
}
|
|
.write {
|
flex-shrink: 0;
|
margin-left: 10px;
|
color: var(--primary-color);
|
cursor: pointer;
|
}
|
}
|
}
|
}
|
}
|
</style>
|