This commit is contained in:
huangchenhao 2025-11-14 17:53:44 +08:00
commit e18ccf03d5
3 changed files with 222 additions and 107 deletions

View File

@ -0,0 +1,172 @@
<template>
<div class="input-selet-comp" ref="inputSelectRef">
<div class="input-wrapper" :class="{ 'is-active': active }">
<div v-if="modelValue == null || modelValue === ''" class="placeholder">{{ placeholder }}</div>
<input :value="modelValue" ref="innerInputRef" class="inner-input" @click="show" @blur="deferClose"
@input="input" />
</div>
</div>
<div class="input-selet-options-popup" ref="popupRef" :style="optionsWrapperStyle"
v-if="options && options.length > 0">
<div class="options-wrapper">
<div class="option" v-for="(option, index) in options" :key="index" @click="changeValue(option)" :class="{'is-select' : option.value == modelValue }">
{{ option.label }}
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
const props = defineProps({
options: {
type: Array,
default: () => []
},
placeholder: {
type: String,
default: ''
},
modelValue: {
}
})
const emit = defineEmits(['update:modelValue']);
const optionsWrapperStyle = ref({})
const inputSelectRef = ref(null)
const innerInputRef = ref(null)
const popupRef = ref(null)
const active = ref(false)
const show = () => {
if (props.options && props.options.length > 0) {
const rect = inputSelectRef.value.getBoundingClientRect();
optionsWrapperStyle.value = {
left: rect.left + 'px',
top: rect.bottom + 'px',
transform: 'scaleY(1)',
width: rect.width + 'px',
}
const popupRect = popupRef.value.getBoundingClientRect();
//
if (rect.right + popupRect.width / 2 > window.innerWidth) {
optionsWrapperStyle.value.left = rect.right - popupRect.width + 'px';
}
active.value = true
}
}
const deferClose = () => {
setTimeout(() => {
close()
}, 100)
}
const close = () => {
if (props.options && props.options.length > 0) {
optionsWrapperStyle.value.transform = 'scaleY(0)';
}
active.value = false
}
const input = (event) => {
emit("update:modelValue", event.target.value)
}
const changeValue = (option) => {
emit("update:modelValue", option.value)
}
</script>
<style scoped lang="scss">
.input-selet-comp {
width: 100%;
.input-wrapper {
position: relative;
background-color: var(--el-input-bg-color, var(--el-fill-color-blank));
background-image: none;
border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;
padding: 1px 11px;
transform: translateZ(0);
transition: var(--el-transition-box-shadow);
&:hover {
box-shadow: 0 0 0 1px #c0c4cc inset;
}
&.is-active {
box-shadow: 0 0 0 1px #409eff inset;
}
}
.placeholder {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
padding: 1px 11px;
color: var(--el-text-color-placeholder);
}
.inner-input {
width: 100%;
outline: none;
border: none;
background: transparent;
padding: 0;
margin: 0;
}
}
.input-selet-options-popup {
position: fixed;
display: flex;
flex-direction: column;
margin: 0;
z-index: 10;
transform: scaleY(0);
transform-origin: center top;
transition: transform 0.2s;
&::before {
content: '';
display: inline-block;
height: 5px;
}
.options-wrapper {
display: flex;
flex-direction: column;
border-radius: 4px;
padding: 6px 0;
background: var(--el-bg-color-overlay);
border: 1px solid var(--el-border-color-light);
box-shadow: var(--el-box-shadow-light);
}
.option {
border-radius: 4px;
transition: background-color 0.2s;
white-space: nowrap;
color: var(--el-text-color-regular);
cursor: pointer;
font-size: var(--el-font-size-base);
height: 34px;
line-height: 34px;
overflow: hidden;
padding: 0 32px 0 20px;
&.is-select {
color: #409eff;
}
}
}
</style>

View File

@ -13,18 +13,12 @@
</el-col>
<el-col :span="8">
<el-form-item label="设备大类" prop="sbdl">
<el-select v-model="form.sbdl" placeholder="请选择">
<el-option label="示例大类1" value="dl1" />
<el-option label="示例大类2" value="dl2" />
</el-select>
<InputSelect v-model="form.sbdl" placeholder="请选择" :options="options['sbdl']" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备类型" prop="sblx">
<el-select v-model="form.sblx" placeholder="请选择">
<el-option label="示例类型1" value="lx1" />
<el-option label="示例类型2" value="lx2" />
</el-select>
<InputSelect v-model="form.sblx" placeholder="请选择" :options="options['sblx']" />
</el-form-item>
</el-col>
</el-row>
@ -57,7 +51,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="购买费用(万元)" prop="gmfy">
<el-input-number v-model="form.gmfy" :min="1" :max="10" controls-position="right" />
<el-input-number v-model="form.gmfy" :min="0" controls-position="right" />
</el-form-item>
</el-col>
<el-col :span="8">
@ -98,6 +92,7 @@
<script setup>
import { ref, computed } from "vue";
import InputSelect from "@/component/InputSelect/InputSelect.vue";
const props = defineProps({
detailData: {
@ -115,6 +110,18 @@ const props = defineProps({
}
});
const options = ref({
'sbdl': [
{ label: "示例大类1", value: "示例大类1" },
{ label: "示例大类2", value: "示例大类2" },
],
"sblx": [
{ label: "示例类型1", value: "示例类型1" },
{ label: "示例类型2", value: "示例类型2" },
]
})
const stationName = computed(() => {
return props.yhzData ? props.yhzData.rawName : ''
})

View File

@ -11,37 +11,25 @@
</template>
<div v-if="equipment" class="drawer-content">
<!-- 基础信息 -->
<div class="info-box">
<div class="info-title-block">
<span class="title-text">基础信息</span>
</div>
<div class="info-content-block flex">
<div class="left-wrapper">
<div class="info-item-list-wrapper">
<div class="info-item" v-for="(item, index) in showDataConfig['基础信息']" :key="index">
<div class="label">{{ item.label }}</div>
<div class="value">{{ equipment[item.name] }}</div>
</div>
</div>
<div class="basic-info-area">
<DetailInfoBox :data="equipment" :title="'基础信息'" :dataConfig="showDataConfig['基础信息']" />
<div class="right-wrapper">
<div>
<el-tag v-if="equipment.sbzt === '完好'" type="success" size="small">完好</el-tag>
<el-tag v-if="equipment.sbzt === '损坏'" type="danger" size="small">损坏</el-tag>
<el-tag v-if="equipment.sbzt === '报废'" type="danger" size="small">报废</el-tag>
</div>
<div class="right-wrapper">
<div>
<el-tag v-if="equipment.sbzt === '完好'" type="success" size="small">完好</el-tag>
<el-tag v-if="equipment.sbzt === '损坏'" type="danger" size="small">损坏</el-tag>
<el-tag v-if="equipment.sbzt === '报废'" type="danger" size="small">报废</el-tag>
</div>
<div class="photo-block">
<el-image v-if="defaultPhoto" style="width: 100%; height: 100%" :src="defaultPhoto" :zoom-rate="1.2"
:max-scale="7" :min-scale="0.2" :preview-src-list="photos" show-progress :initial-index="4"
fit="cover" />
<div v-else class="no-photo">
<span>暂无图片</span>
</div>
<div class="photo-block">
<el-image v-if="defaultPhoto" style="width: 100%; height: 100%" :src="defaultPhoto" :zoom-rate="1.2"
:max-scale="7" :min-scale="0.2" :preview-src-list="photos" show-progress :initial-index="4"
fit="cover" />
<div v-else class="no-photo">
<span>暂无图片</span>
</div>
</div>
</div>
</div>
<!-- 设备位置 -->
<DetailInfoBox class="detail-info-box" :data="equipment" :title="'设备位置'" :dataConfig="showDataConfig['设备位置']" />
@ -117,7 +105,7 @@ const showDataConfig = ref({
{ "label": "设备管理人员", "name": "glry" },
{ "label": "操作员", "name": "czy" },
{
"label": "购置日期", "name": "gzrq",
"label": "购置日期", "name": "gzrq",
"value": (item) => {
return item.gzrq ? formatDate(item.gzrq) : ''
}
@ -171,81 +159,29 @@ defineExpose({
}
}
.info-box {
width: 100%;
.basic-info-area {
position: relative;
.info-title-block {
margin: 10px 0;
.title-text {
font-size: 16px;
font-weight: 600;
}
}
.info-content-block {
width: 100%;
padding: 15px;
background-color: #fff;
border-radius: 6px;
.info-item-list-wrapper {
display: grid;
width: 100%;
row-gap: 15px;
.info-item {
display: flex;
align-items: center;
width: 100%;
.label {
display: flex;
align-items: center;
font-size: 14px;
margin-right: 10px;
line-height: 14px;
white-space: nowrap;
&::after {
content: ":"
}
}
.value {
line-height: 14px;
font-size: 14px;
white-space: nowrap;
}
}
}
}
.info-content-block.flex {
.right-wrapper {
position: absolute;
top: 45px;
right: 50px;
display: flex;
justify-content: space-between;
gap: 30px;
.right-wrapper {
display: flex;
gap: 30px;
.photo-block {
width: 150px;
height: 167px;
.photo-block {
width: 150px;
height: 167px;
.no-photo {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #f5f5f5;
border-radius: 6px;
color: #999;
}
.no-photo {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #f5f5f5;
border-radius: 6px;
color: #999;
}
}
}