You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.4 KiB

1 year ago
<script lang="ts" setup>
import { PropType } from 'vue'
import dayjs from 'dayjs'
import { useDesign } from '@/hooks/web/useDesign'
import { propTypes } from '@/utils/propTypes'
import { useAppStore } from '@/store/modules/app'
import { DescriptionsSchema } from '@/types/descriptions'
const { t } = useI18n() // 国际化
1 year ago
defineOptions({ name: 'Descriptions' })
const appStore = useAppStore()
const mobile = computed(() => appStore.getMobile)
const attrs = useAttrs()
const slots = useSlots()
const height = ref('auto')
const isShow = ref(true)
1 year ago
const props = defineProps({
title: propTypes.string.def(''),
message: propTypes.string.def(''),
collapse: propTypes.bool.def(true),
columns: propTypes.number.def(1),
width: propTypes.string.def('50px'),
labelAlign: propTypes.string.def('right'),
labelClassName: propTypes.string.def(''),
schema: {
type: Array as PropType<DescriptionsSchema[]>,
default: () => []
},
data: {
type: Object as PropType<any>,
default: () => ({})
}
})
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('descriptions')
const getBindValue = computed(() => {
const delArr: string[] = ['title', 'message', 'collapse', 'schema', 'data', 'class']
const obj = { ...attrs, ...props }
for (const key in obj) {
if (delArr.indexOf(key) !== -1) {
delete obj[key]
}
}
return obj
})
const getBindItemValue = (item: DescriptionsSchema) => {
const delArr: string[] = ['field']
const obj = { ...item }
for (const key in obj) {
if (delArr.indexOf(key) !== -1) {
delete obj[key]
}
}
return obj
}
// 折叠
const show = ref(true)
const toggleClick = () => {
if (props.collapse) {
show.value = !unref(show)
}
}
const showAll = () =>{
if(isShow.value){
height.value ='200px'
}else{
height.value ='auto'
}
isShow.value = !isShow.value
}
</script>
<template>
<div
:class="[
prefixCls,
'bg-[var(--el-color-white)] dark:bg-[var(--el-bg-color)] dark:border-[var(--el-border-color)] dark:border-1px'
]"
>
<div
v-if="title"
:class="[
`${prefixCls}-header`,
'h-50px flex justify-between items-center b-b-1 border-solid border-[var(--el-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]'
]"
@click="toggleClick"
>
<div :class="[`${prefixCls}-header__title`, 'relative font-18px font-bold ml-10px']">
<div class="flex items-center">
{{ t(`ts.${title}`).replace('ts.', '') }}
1 year ago
<ElTooltip v-if="message" :content="message" placement="right">
<Icon class="ml-5px" icon="ep:warning" />
</ElTooltip>
</div>
</div>
<Icon v-if="collapse" :icon="show ? 'ep:arrow-down' : 'ep:arrow-up'" />
</div>
<ElCollapseTransition :style="{height: height,overflow: 'hidden'}">
<div v-show="show" :class="[`${prefixCls}-content`]">
<ElDescriptions
:column="props.columns"
:direction="mobile ? 'vertical' : 'horizontal'"
border
v-bind="getBindValue"
>
<template v-if="slots['extra']" #extra>
<slot name="extra"></slot>
</template>
<ElDescriptionsItem
1 year ago
v-for="item in schema"
:key="item.field"
v-bind="getBindItemValue(item)"
:label-align="labelAlign"
:label-class-name="labelClassName"
:width="width"
:span="item.span"
1 year ago
>
<template #label>
<slot
:name="`${item.field}-label`"
:row="{
label: item.label
}"
>{{ t(`ts.${item.label}`).replace('ts.', '') }}
1 year ago
</slot>
</template>
<template #default>
<slot v-if="item.dateFormat">
{{
data[item.field] !== null ? dayjs(data[item.field]).format(item.dateFormat) : ''
}}
</slot>
12 months ago
<slot v-else-if="item.valueFilter">
{{
item.valueFilter(data[item.field])
}}
</slot>
1 year ago
<slot v-else-if="item.dictType">
<div v-if="data[item.field]&&Array.isArray(data[item.field])" >
<DictTag :type="item.dictType" :value="cur" v-for="(cur,key) in data[item.field]" :key="key" style="margin-right: 6px;margin-bottom: 6px;"/>
</div>
<DictTag :type="item.dictType" :value="data[item.field] + ''" v-if="(data[item.field]||data[item.field]==0)&&!Array.isArray(data[item.field])"/>
1 year ago
</slot>
<slot v-else :name="item.field" :row="data">{{ data[item.field] }}</slot>
</template>
</ElDescriptionsItem>
</ElDescriptions>
</div>
</ElCollapseTransition>
<!-- <div class="flex align-center justify-center">
1 year ago
<el-button type="primary" class="mt-20px" @click="showAll">{{!isShow?'展开':'收起'}}</el-button>
</div> -->
1 year ago
</div>
</template>
<style lang="scss" scoped>
$prefix-cls: #{$namespace}-descriptions;
.#{$prefix-cls}-header {
&__title {
&::after {
position: absolute;
top: 3px;
left: -10px;
width: 4px;
height: 70%;
background: var(--el-color-primary);
content: '';
}
}
}
.#{$prefix-cls}-content {
:deep(.#{$elNamespace}-descriptions__cell) {
width: 0;
}
}
</style>