Files
shanxia2.0/web-admin/src/components/business/system-view-dialog/ViewKvTableCell.vue
T
2026-08-08 20:43:48 +08:00

133 lines
3.3 KiB
Vue

<template>
<div class="view-kv-table-cell">
<el-tag v-if="field.tagType" :type="field.tagType" size="small" class="view-kv-tag">{{
formatViewValue(field.value)
}}</el-tag>
<ul v-else-if="field.items?.length" class="view-plain-list">
<li v-for="(item, idx) in field.items" :key="idx">{{ item }}</li>
</ul>
<span v-else :class="{ 'money-display': field.money, 'danger-display': field.danger, 'muted-display': isMuted }">{{
formatViewValue(field.value)
}}</span>
<el-button
v-if="showMapBtn"
link
type="primary"
size="small"
class="view-kv-field-link"
title="在高德地图查看"
@click="openAmapLocation"
>
<el-icon><Location /></el-icon>
</el-button>
<el-button
v-if="showViewBtn"
link
type="primary"
size="small"
class="view-kv-field-link"
:title="viewBtnTitle"
@click="handleView"
>
<el-icon :size="16"><View /></el-icon>
</el-button>
</div>
</template>
<script setup lang="ts">
import { computed, inject } from 'vue'
import { Location, View } from '@element-plus/icons-vue'
import type { ViewField } from './types'
import { formatViewValue } from './types'
import { buildAmapLocationUrl } from '@/utils/amap/navigation'
const VIEW_KV_FIELD_VIEW_KEY = 'viewKvFieldView'
const props = defineProps<{
field: ViewField
}>()
const onFieldView = inject<((field: ViewField) => void) | undefined>(VIEW_KV_FIELD_VIEW_KEY)
const isMuted = computed(
() => !props.field.money && !props.field.danger && formatViewValue(props.field.value) === '—'
)
const showViewBtn = computed(() => {
if (!props.field.viewTarget || !props.field.viewId || !onFieldView) return false
if (props.field.viewTarget !== 'customer' && formatViewValue(props.field.value) === '—') {
return false
}
return true
})
const viewBtnTitle = computed(() => {
if (props.field.viewTarget === 'customer') return '查看客户'
if (props.field.viewTarget === 'opportunity') return '查看商机'
if (props.field.viewTarget === 'quote') return '查看报价单'
return '查看'
})
const amapLocationUrl = computed(() => {
if (!props.field.showMapLink) return null
return buildAmapLocationUrl({
lng: props.field.mapLng,
lat: props.field.mapLat,
name: props.field.mapName,
address: formatViewValue(props.field.value) === '—' ? undefined : String(props.field.value ?? '')
})
})
const showMapBtn = computed(() => Boolean(amapLocationUrl.value))
function handleView() {
onFieldView?.(props.field)
}
function openAmapLocation() {
const url = amapLocationUrl.value
if (!url) return
window.open(url, '_blank', 'noopener,noreferrer')
}
</script>
<style scoped lang="scss">
.view-kv-table-cell {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
}
.view-kv-tag {
font-weight: 600;
}
.view-kv-field-link {
margin: 0;
padding: 0 4px;
height: auto;
font-weight: 500;
}
.view-plain-list {
margin: 0;
padding-left: 1.15em;
list-style: disc;
li + li {
margin-top: 4px;
}
}
.muted-display {
color: var(--text-muted, #64748b);
font-weight: 600;
}
.danger-display {
color: #dc2626;
font-weight: 600;
}
</style>