Files
sgxt_web/src/components/aboutTable/Search.vue

587 lines
15 KiB
Vue
Raw Normal View History

2025-04-12 14:54:02 +08:00
<template>
2025-04-23 14:23:27 +08:00
<div v-loading="loadingPage" class="pageSearch searchBox" :style="`margin-bottom: ${marginBottom}px;background-color: ${backgroundColor}`">
2025-04-12 14:54:02 +08:00
<div class="box">
<div v-for="(item, index) in getArr" :key="index" class="item">
<div class="label" v-if="item.label">{{ item.label }}</div>
<!-- select -->
<el-select
v-if="item.showType === 'select'"
v-model="searchObj[item.prop]"
:multiple="item.multiple"
:clearable="item.clearable"
:filterable="item.filterable"
:placeholder="item.placeholder"
collapse-tags
collapse-tags-tooltip
>
<el-option
v-for="obj in getOptions[item.prop]"
:key="obj.value"
:label="obj.label || obj.lable"
:value="obj.value"
/>
</el-select>
<!-- input -->
<el-input
v-else-if="item.showType === 'input'"
class="input"
v-model="searchObj[item.prop]"
:clearable="item.clearable"
:placeholder="item.placeholder"
/>
<!-- 日期段选择器 -->
<el-date-picker
v-else-if="item.showType === 'daterange'"
v-model="searchObj[item.prop]"
type="daterange"
unlink-panels
:range-separator="item.rangeSeparator"
:start-placeholder="item.startPlaceholder"
:end-placeholder="item.endPlaceholder"
:shortcuts="item.shortcuts"
:disabledDate="disabledDate"
value-format="YYYY-MM-DD"
/>
<el-date-picker
v-else-if="item.showType === 'date'"
v-model="searchObj[item.prop]"
type="date"
:placeholder="item.placeholder"
:disabled-date="disabledDate"
:shortcuts="item.shortcuts"
value-format="YYYY-MM-DD"
>
</el-date-picker>
2025-04-12 23:51:24 +08:00
2025-04-12 14:54:02 +08:00
<!-- checkbox -->
<template v-else-if="item.showType === 'department'">
2025-04-12 23:51:24 +08:00
<MOSTY.Department clearable v-model="item.ssbmdm" />
2025-04-12 14:54:02 +08:00
</template>
<!-- checkbox -->
<template v-else-if="item.showType === 'checkbox'">
<el-checkbox
v-if="item.showSelectAll"
v-model="item.checkAll"
:indeterminate="item.isIndeterminate"
2025-04-12 23:51:24 +08:00
@change="
(val) => {
handleCheckAllChange(val, item);
}
"
>全选</el-checkbox
>
2025-04-12 14:54:02 +08:00
<el-checkbox-group
v-model="searchObj[item.prop]"
2025-04-12 23:51:24 +08:00
@change="
(val) => {
handleCheckedCitiesChange(val, item);
}
"
>
2025-04-12 14:54:02 +08:00
<el-checkbox
v-for="obj in item.options"
:key="obj.value"
:label="obj.value"
>{{ obj.label }}</el-checkbox
>
</el-checkbox-group>
</template>
<!-- radio -->
<el-radio-group
v-else-if="item.showType === 'radio'"
v-model="searchObj[item.prop]"
2025-04-12 23:51:24 +08:00
@change="
(val) => {
handleRadioChange(val, item);
}
"
>
2025-04-12 14:54:02 +08:00
<el-radio
v-for="obj in item.options"
:key="obj.value"
:label="obj.value"
>{{ obj.label }}</el-radio
>
</el-radio-group>
<!-- 级联选择 -->
<el-cascader
v-else-if="item.showType === 'cascader'"
@change="changeca"
v-model="searchObj[item.prop]"
:props="item.props"
:show-all-levels="item.showAllLevels"
:clearable="item.clearable"
:options="getOptions[item.prop]"
:placeholder="item.placeholder"
/>
<div v-else-if="item.showType === 'defaultSlot'">
<slot name="defaultSlot"></slot>
</div>
</div>
<div class="flex">
<el-button type="primary" @click="submit">确定</el-button>
<el-button type="" @click="reset">重置</el-button>
<slot> </slot>
</div>
</div>
</div>
</template>
<script setup>
2025-04-12 23:51:24 +08:00
import {
ref,
reactive,
watch,
watchEffect,
nextTick,
getCurrentInstance,
toRefs
} from "vue";
2025-04-12 14:54:02 +08:00
import * as MOSTY from "@/components/MyComponents/index";
const { proxy } = getCurrentInstance();
const props = defineProps({
searchArr: {
type: Array,
default: () => {
return [
{
showType: "select",
prop: "selectKey",
options: [
{
value: 1,
label: "选择1"
}
],
defaultVal: "",
label: "选择",
dict: "" // 字典编码
},
{
showType: "input",
prop: "inputKey",
defaultVal: "",
label: "输入"
},
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "输入"
},
{
showType: "date",
prop: "date",
defaultVal: ""
},
{
showType: "checkbox",
prop: "checkboxKey1",
options: [
{
value: 1,
label: "选择1"
}
],
defaultVal: ""
},
{
showType: "cascader",
prop: "cascaderKey",
label: "级联选择",
checkStrictly: false, //点击任意选中
defaultVal: ""
},
{
showType: "radio",
defaultVal: ""
// prop: "cascaderKey",
// label: "级联选择",
// checkStrictly: false //点击任意选中
},
{
showType: "defaultTime",
prop: "timeField",
2025-04-12 23:51:24 +08:00
options: []
2025-04-12 14:54:02 +08:00
}
];
}
},
marginBottom: {
type: Number,
default: 15
},
backgroundColor: {
type: String,
default: "rgb(255, 255, 255, 1)"
}
});
let loadingPage = ref(false);
const isShowDate = ref(false);
const emit = defineEmits(["submit", "reset"]);
let searchObj = reactive({});
2025-04-12 23:51:24 +08:00
const timeConfig = reactive({
//时间字典筛选和自定义日期组件相关数据
typeValue: "01", //时间字典类型默认
timeArry: [] //时间筛选自定义默认值
});
2025-04-12 14:54:02 +08:00
//全所或自定义选择按钮
2025-04-12 23:51:24 +08:00
const slectType = ref("qs");
2025-04-12 14:54:02 +08:00
// select 的一些默认配置
const selectDefault = {
clearable: true, // 是否可以清空
filterable: true, // 是否可以筛选
multiple: false, // 是否多选
placeholder: "请选择"
};
// 重新定义下拉框的选项
let getOptions = reactive({});
// input 的一些默认配置
const inputDefault = {
clearable: true, // 是否可以清空
placeholder: "请输入"
};
const shortcuts = [
{
text: "今天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 0);
return [start, end];
}
},
{
text: "昨天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
end.setTime(end.getTime() - 3600 * 1000 * 24 * 1);
return [start, end];
}
},
{
text: "最近7天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
}
},
{
text: "最近30天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
}
},
{
text: "最近90天",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
}
}
];
// daterange 的一些默认配置
const daterangeDefault = {
rangeSeparator: "至",
startPlaceholder: "开始日期",
endPlaceholder: "结束日期",
shortcuts: [], // 快捷选择
defaultShortcuts: true // 是否显示快捷选择 如果要自定义快捷选择传入一个shortcuts就可以了
};
// date 的一些默认配置
const defaultDate = {
clearable: true, // 是否可以清空
placeholder: "请输入",
shortcuts: [], // 快捷选择
defaultShortcuts: true // 是否显示快捷选择 如果要自定义快捷选择传入一个shortcuts就可以了
};
const dateShortcuts = [
{
text: "今天",
value: new Date()
},
{
text: "昨天",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
return date;
}
},
{
text: "7天前",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
return date;
}
},
{
text: "30天前",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 30);
return date;
}
},
{
text: "90天前",
value: () => {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 90);
return date;
}
}
];
//自定义时间选择 item 配置项 value 选中的值
2025-04-12 23:51:24 +08:00
const screenSelect = (item, value) => {
if (value == "08") {
2025-04-12 14:54:02 +08:00
searchObj[item.prop] = value;
isShowDate.value = true;
2025-04-12 23:51:24 +08:00
} else {
2025-04-12 14:54:02 +08:00
timeConfig.typeValue = value;
searchObj[item.prop] = value;
submit();
}
2025-04-12 23:51:24 +08:00
};
2025-04-12 14:54:02 +08:00
//自定义时间确定时间
const chooseDateOk = (item) => {
timeConfig.typeValue = "08";
2025-04-12 23:51:24 +08:00
if (timeConfig.timeArry && timeConfig.timeArry.length) {
//选择了时间
2025-04-12 14:54:02 +08:00
searchObj[item.propStart] = timeConfig.timeArry[0];
searchObj[item.propEnd] = timeConfig.timeArry[1];
2025-04-12 23:51:24 +08:00
} else {
//清空了时间
2025-04-12 14:54:02 +08:00
searchObj[item.prop] = "01";
timeConfig.typeValue = "01";
}
isShowDate.value = false;
submit();
2025-04-12 23:51:24 +08:00
};
2025-04-12 14:54:02 +08:00
//全所-部门选择回调
const organizatioHland = (val) => {
2025-04-12 23:51:24 +08:00
let item = getArr.find((item) => item.showType == "qsOrZdy");
2025-04-12 14:54:02 +08:00
searchObj[item.propBm] = val?.data?.orgCode || "";
2025-04-12 23:51:24 +08:00
if (!val || val == "") {
//清空了部门选择后清空责任区ID
2025-04-12 14:54:02 +08:00
slectType.value = "qs";
delete searchObj[item.propZrq];
}
2025-04-12 23:51:24 +08:00
submit();
2025-04-12 14:54:02 +08:00
};
//全所-责任区回调
const zrqHland = (val) => {
2025-04-12 23:51:24 +08:00
let item = getArr.find((item) => item.showType == "qsOrZdy");
2025-04-12 14:54:02 +08:00
searchObj[item.propZrq] = val || ""; //责任区选择
submit();
};
//自定义时间取消事件
const popoverCancel = (item) => {
isShowDate.value = false;
2025-04-12 23:51:24 +08:00
};
2025-04-12 14:54:02 +08:00
// 设置不可选的日期
const disabledDate = (time) => {
return time.getTime() > Date.now();
};
// checkbox 的一些默认配置
const defaultCheckbox = reactive({
defaultVal: [],
checkAll: false, // 全选的值
isIndeterminate: false, // 控制全选按钮样式
showSelectAll: true // 是否显示全选
});
// 全选复选框的选中与不选中
const handleCheckAllChange = (val, obj) => {
searchObj[obj.prop] = val ? obj.checkboxValueArr : [];
obj.isIndeterminate = false;
};
// 单个复选框的选中与不选中
const handleCheckedCitiesChange = (value, obj) => {
const checkedCount = value.length;
obj.checkAll = checkedCount === obj.checkboxValueArr.length;
obj.isIndeterminate =
checkedCount > 0 && checkedCount < obj.checkboxValueArr.length;
};
//单选
const handleRadioChange = (val, obj) => {
console.log(val, obj);
};
// cascader 的一些默认配置
let defaultCascader = {
filterable: true, // 是否可以搜索
clearable: true, // 是否可以清空
placeholder: "请选择",
checkStrictly: true, // 控制是否父子联动(是否可以选择任意节点)
showAllLevels: false, // 是否显示完整路径
lazy: true, // 是否懒加载 当设置为false时就要传入options
portUrl: "", // 这里必须写 接口地址
props: {
label: "label",
value: "value",
children: "children"
},
options: []
};
// 在懒加载状态下cascader 的props的一些配置
const cascaderLazyProps = reactive({
value: "value",
label: "label",
lazy: true,
lazyLoad(node, resolve) {
// 这里要根据实际情况修改
const { level } = node;
let options = [];
switch (level) {
case 0:
options = [
{
value: 1,
label: "选择1",
leaf: false // 表示有下一级 必须有这个表示 不然获取不到值
},
{
value: 2,
label: "选择2",
leaf: false // 表示有下一级
},
{
value: 3,
label: "选择3",
leaf: false // 表示有下一级
},
{
value: 4,
label: "选择4",
leaf: true // 表示没有下一级了
}
];
break;
case 1:
options = [
{
value: 11,
label: "选择1_1",
leaf: true // 表示没有下一级了
},
{
value: 21,
label: "选择2_1",
leaf: true // 表示没有下一级了
},
{
value: 31,
label: "选择3_1",
leaf: true // 表示没有下一级了
},
{
value: 41,
label: "选择4_1",
leaf: true // 表示没有下一级了
}
];
}
resolve(options);
}
});
// 级联框选择
function changeca(v) {
console.log("vvvv", v);
}
// 获取到传过来的参数
let getArr = reactive([]);
const submit = () => {
emit("submit", searchObj);
};
const reset = () => {
getArr.forEach((item) => {
2025-04-12 23:51:24 +08:00
searchObj[item.prop] = item.defaultVal;
2025-04-12 14:54:02 +08:00
});
emit("submit", searchObj);
emit("reset", false);
};
let dataOptions = reactive([]); //时间字典筛选
watchEffect(() => {
loadingPage.value = true;
getArr = JSON.parse(JSON.stringify(props.searchArr));
getArr = getArr.map((item) => {
switch (item.showType) {
case "select":
item = { ...selectDefault, ...item };
item.options = reactive(item.options);
getOptions[item.prop] = item.options;
break;
case "input":
item = { ...inputDefault, ...item };
break;
case "daterange":
item = { ...daterangeDefault, ...item };
if (item.defaultShortcuts) {
item.shortcuts = shortcuts;
}
break;
case "date":
item = { ...defaultDate, ...item };
if (item.defaultShortcuts) {
item.shortcuts = dateShortcuts;
}
break;
case "checkbox":
item = reactive({ ...defaultCheckbox, ...item });
item.checkboxValueArr = item.options.map((obj) => {
return obj.value;
});
break;
case "cascader":
item = { ...defaultCascader, ...item };
if (item.lazy) {
cascaderLazyProps.checkStrictly = item.checkStrictly;
item.props = { ...cascaderLazyProps, ...(item.props || {}) };
delete item.options;
} else {
item.props = {
...defaultCascader.props,
...(item.props || {}),
...{ checkStrictly: item.checkStrictly }
};
getOptions[item.prop] = reactive(item.options);
}
break;
}
loadingPage.value = false;
2025-04-12 23:51:24 +08:00
searchObj[item.prop] = item.defaultVal;
2025-04-12 14:54:02 +08:00
return item;
});
});
</script>
2025-04-12 23:51:24 +08:00
<style lang="scss" scoped>
2025-04-12 14:54:02 +08:00
.pageSearch {
.box {
display: flex;
flex-wrap: wrap;
.item {
display: flex;
margin-right: 12px;
2025-04-12 14:54:02 +08:00
margin-bottom: 15px;
}
.label {
margin: auto;
margin-right: 5px;
white-space: nowrap;
color: #000;
}
}
}
2025-04-12 23:51:24 +08:00
</style>