This commit is contained in:
lcw
2026-04-28 11:26:26 +08:00
parent 9fa073546b
commit cd8347d3d1
120 changed files with 8751 additions and 3896 deletions

View File

@ -1,91 +1,38 @@
<template>
<section class="query-wrap">
<div class="query-title">{{ title }}</div>
<div class="query-grid">
<div class="query-title" @click="toggleCollapse">
<span class="title-text">{{ title }}</span>
<el-icon class="collapse-icon" :class="{ 'is-collapsed': isCollapsed }">
<ArrowDown />
</el-icon>
</div>
<div class="query-grid" v-show="!isCollapsed">
<div v-for="field in renderFields" :key="field.key" class="query-cell">
<div class="cell-label">{{ field.label }}</div>
<div
class="cell-control"
:class="{ 'is-checkbox': field.type === 'checkbox' }"
>
<el-input
clearable
v-if="field.type === 'input'"
v-model="formState[field.key]"
class="control-input"
:placeholder="field.placeholder || ''"
/>
<el-input
clearable
v-else-if="field.type === 'number'"
v-model="formState[field.key]"
class="control-input"
type="number"
:placeholder="field.placeholder || ''"
/>
<el-select
clearable
v-else-if="field.type === 'select'"
v-model="formState[field.key]"
class="control-select"
:placeholder="field.placeholder || '请选择'"
:multiple="field.multiple || false"
collapse-tags
collapse-tags-tooltip
>
<el-option
v-for="item in field.options || []"
:key="item.value ?? item"
:label="item.label ?? item"
:value="item.value ?? item"
/>
<div class="cell-control" :class="{ 'is-checkbox': field.type === 'checkbox' }">
<el-input clearable v-if="field.type === 'input'" v-model="formState[field.key]" class="control-input"
:placeholder="field.placeholder || ''" />
<el-input clearable v-else-if="field.type === 'number'" v-model="formState[field.key]" class="control-input"
type="number" :placeholder="field.placeholder || ''" />
<el-select clearable v-else-if="field.type === 'select'" v-model="formState[field.key]" class="control-select"
:placeholder="field.placeholder || '请选择'" :multiple="field.multiple || false" collapse-tags
collapse-tags-tooltip>
<el-option v-for="item in field.options || []" :key="item.value ?? item" :label="item.label ?? item"
:value="item.value ?? item" />
</el-select>
<el-date-picker
clearable
v-else-if="field.type === 'date'"
v-model="formState[field.key]"
class="control-date"
type="date"
:placeholder="field.placeholder || '请选择日期'"
value-format="YYYY-MM-DD"
/>
<el-date-picker
clearable
v-else-if="field.type === 'datetime'"
v-model="formState[field.key]"
class="control-date"
type="datetime"
:placeholder="field.placeholder || '请选择时间'"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-date-picker
clearable
v-else-if="field.type === 'daterange'"
v-model="formState[field.key]"
class="control-date"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
/>
<el-date-picker
clearable
v-else-if="field.type === 'datetimerange'"
v-model="formState[field.key]"
class="control-date"
type="datetimerange"
range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-date-picker clearable v-else-if="field.type === 'date'" v-model="formState[field.key]"
class="control-date" type="date" :placeholder="field.placeholder || '请选择日期'" value-format="YYYY-MM-DD" />
<el-date-picker clearable v-else-if="field.type === 'datetime'" v-model="formState[field.key]"
class="control-date" type="datetime" :placeholder="field.placeholder || '请选择时间'"
value-format="YYYY-MM-DD HH:mm:ss" />
<el-date-picker clearable v-else-if="field.type === 'daterange'" v-model="formState[field.key]"
class="control-date" type="daterange" range-separator="" start-placeholder="开始日期" end-placeholder="结束日期"
value-format="YYYY-MM-DD" />
<el-date-picker clearable v-else-if="field.type === 'datetimerange'" v-model="formState[field.key]"
class="control-date" type="datetimerange" range-separator="" start-placeholder="开始时间"
end-placeholder="结束时间" value-format="YYYY-MM-DD HH:mm:ss" />
<template v-else-if="field.type === 'department'">
<MOSTY.Department
clearable
v-model="formState[field.key]"
class="control-select"
/>
<MOSTY.Department clearable v-model="formState[field.key]" class="control-select" />
</template>
<div v-else-if="field.type === 'checkbox'" class="checkbox-wrap">
<el-checkbox v-model="formState[field.key]" />
@ -104,8 +51,7 @@
<el-button size="small" type="primary" @click="handleSearch">{{
searchText
}}</el-button>
<el-button size="small" type="button" @click="handleReset"
>重置
<el-button size="small" type="button" @click="handleReset">重置
</el-button>
</div>
</div>
@ -113,7 +59,8 @@
</template>
<script setup>
import { computed, reactive, watch } from "vue";
import { computed, reactive, ref, watch } from "vue";
import { ArrowDown } from '@element-plus/icons-vue';
import * as MOSTY from "@/components/MyComponents/index";
const props = defineProps({
title: {
@ -132,15 +79,33 @@ const props = defineProps({
type: Array,
default: () => []
},
defaultCollapsed: {
type: Boolean,
default: true
},
collapsedHeight: {
type: Number,
default: 34
},
expandedHeight: {
type: Number,
default: 276
}
});
const emit = defineEmits(['update:modelValue',"search", "submit", "reset"]);
const emit = defineEmits(['update:modelValue', "search", "submit", "reset", "collapse"]);
const formState = reactive({});
const isCollapsed = ref(props.defaultCollapsed);
watch(()=>formState,val=>{
emit('update:modelValue',val)
},{immediate:true})
const toggleCollapse = () => {
isCollapsed.value = !isCollapsed.value;
emit('collapse', isCollapsed.value);
};
watch(() => formState, val => {
emit('update:modelValue', val)
}, { immediate: true })
const renderFields = computed(() => {
@ -236,7 +201,9 @@ watch(
defineExpose({
formState,
handleSearch,
handleReset
handleReset,
isCollapsed,
collapsedHeight: props.collapsedHeight
});
</script>
@ -244,22 +211,46 @@ defineExpose({
.query-wrap {
border: 1px solid #b8d3ff;
background: #fff;
overflow: hidden;
display: flex;
flex-direction: column;
}
.query-title {
height: 32px;
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
line-height: 32px;
padding-left: 10px;
padding: 0 10px;
font-size: 16px;
font-weight: 700;
color: #0d2148;
border-bottom: 1px solid #b8d3ff;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
user-select: none;
.title-text {
flex: 1;
}
.collapse-icon {
font-size: 16px;
color: #0d2148;
transition: transform 0.3s;
&.is-collapsed {
transform: rotate(-90deg);
}
}
}
.query-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
flex: 1;
align-content: start;
}
.query-cell {
@ -366,6 +357,7 @@ defineExpose({
.query-action {
height: 36px;
flex-shrink: 0;
display: flex;
// justify-content: flex-end;
justify-content: space-between;

View File

@ -7,9 +7,9 @@
:align="selectionColumnAlign" />
<el-table-column v-for="column in columns" :key="column.prop || column.label || column.type" :prop="column.prop"
:type="column.type" :label="column.label" :width="column.width" :min-width="column.minWidth"
:align="column.align" :show-overflow-tooltip="true">
:align="column.align" :show-overflow-tooltip="isColumnOverflow(column)">
<template v-if="column.slotName" #default="scope">
<slot v-if="column.slotName" :name="column.slotName" :row="scope.row" :column="column"
<slot :name="column.slotName" :row="scope.row" :column="column"
:$index="scope.$index">
{{ column.prop ? scope.row[column.prop] : '' }}
</slot>
@ -87,6 +87,15 @@ const onSelectionChange = (selection) => {
emit('selection-change', selection)
emit('row-change', selection[0] || null)
}
// 判断列是否需要overflow tooltip只有当列有值时才启用
const isColumnOverflow = (column) => {
if (!column.prop) return false
return props.data.some(row => {
const val = row[column.prop]
return val !== undefined && val !== null && val !== ''
})
}
</script>
<style scoped lang="scss">