Files
dafuweng-saiadmin6.x/saiadmin-artd/src/components/sai/sa-dict/index.vue
2026-03-19 15:40:06 +08:00

126 lines
3.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 字典组件 -->
<template>
<div class="sa-dict-wrapper">
<template v-if="render === 'tag'">
<ElTag
v-for="(item, index) in normalizedValues"
:key="index"
:size="size"
:style="{
backgroundColor: getColor(getData(item)?.color, 'bg'),
borderColor: getColor(getData(item)?.color, 'border'),
color: getColor(getData(item)?.color, 'text')
}"
:round="round"
class="mr-1 last:mr-0"
>
{{ getDisplayLabel(item) }}
</ElTag>
</template>
<template v-else>
<span v-for="(item, index) in normalizedValues" :key="index">
{{ getDisplayLabel(item) }}{{ index < normalizedValues.length - 1 ? '' : '' }}
</span>
</template>
</div>
</template>
<script setup lang="ts">
import { useDictStore } from '@/store/modules/dict'
import { useI18n } from 'vue-i18n'
defineOptions({ name: 'SaDict' })
interface Props {
/** 字典类型 */
dict: string
/** 字典值(支持字符串或数组) */
value: string | string[] | number | number[]
/** 渲染方式 */
render?: string
/** 标签大小 */
size?: 'large' | 'default' | 'small'
/** 是否圆角 */
round?: boolean
}
const props = withDefaults(defineProps<Props>(), {
render: 'tag',
size: 'default',
round: false
})
const dictStore = useDictStore()
const { t, te, locale } = useI18n()
// 统一处理 value转换为数组格式
const normalizedValues = computed(() => {
if (Array.isArray(props.value)) {
return props.value.map((v) => String(v))
}
return props.value !== undefined && props.value !== null && props.value !== ''
? [String(props.value)]
: []
})
// 根据值获取字典数据
const getData = (value: string) => dictStore.getDataByValue(props.dict, value)
const getDisplayLabel = (value: string) => {
// 让显示在切换语言时可响应更新
locale.value
const key = `dict.${props.dict}.${value}`
if (te(key)) return t(key)
return getData(value)?.label || value
}
const getColor = (color: string | undefined, type: 'bg' | 'border' | 'text') => {
// 如果没有指定颜色,使用默认主色调
if (!color) {
const colors = {
bg: 'var(--el-color-primary-light-9)',
border: 'var(--el-color-primary-light-8)',
text: 'var(--el-color-primary)'
}
return colors[type]
}
// 如果是 hex 颜色,转换为 RGB
let r, g, b
if (color.startsWith('#')) {
const hex = color.slice(1)
r = parseInt(hex.slice(0, 2), 16)
g = parseInt(hex.slice(2, 4), 16)
b = parseInt(hex.slice(4, 6), 16)
} else if (color.startsWith('rgb')) {
const match = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/)
if (match) {
r = parseInt(match[1])
g = parseInt(match[2])
b = parseInt(match[3])
} else {
return color
}
} else {
return color
}
// 根据类型返回不同的颜色变体
switch (type) {
case 'bg':
// 背景色 - 更浅的版本
return `rgba(${r}, ${g}, ${b}, 0.1)`
case 'border':
// 边框色 - 中等亮度
return `rgba(${r}, ${g}, ${b}, 0.3)`
case 'text':
// 文字色 - 原始颜色
return `rgb(${r}, ${g}, ${b})`
default:
return color
}
}
</script>