| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- <template>
- <div>
- <el-form :model="queryForm" label-width="auto" :inline="true" ref="formRef">
- <div class="select-group">
- <el-form-item label="问题来源:" prop="queryParam.source">
- <el-select
- v-model="queryForm.queryParam.source"
- placeholder="全部"
- clearable
- @change="handleSelectChange"
- >
- <el-option
- v-for="item in sourceOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="类型:" prop="queryParam.issueTypeList">
- <el-cascader
- v-model="issueTypeValue"
- :options="options"
- :props="issueMainTypeProp"
- clearable
- collapse-tags
- :show-all-levels="false"
- popper-class="special-cascader"
- :disabled="typeDisable"
- @change="handleIssueMainTypeChange"
- />
- </el-form-item>
- <el-form-item label="地点:" prop="queryParam.workspaceId">
- <el-cascader
- v-model="workLocation"
- :options="locationOptions"
- :props="locationProp"
- clearable
- collapse-tags
- :show-all-levels="false"
- popper-class="special-cascader"
- @change="handleCascaderChange"
- />
- </el-form-item>
- <el-form-item label="处理状态:" prop="queryParam.issueState">
- <el-select v-model="tempState" clearable @change="handleIssueStateChange">
- <el-option
- v-for="item in issueStateOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="生效状态:" prop="queryParam.hide">
- <el-select v-model="queryForm.queryParam.hide" clearable>
- <el-option
- v-for="item in hideStateOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="日期:">
- <el-date-picker
- v-model="dateRange"
- type="daterange"
- range-separator="~"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- clearable
- unlink-panels
- value-format="YYYY-MM-DD HH:mm:ss"
- :default-time="defaultTime"
- @change="handleDateChange"
- />
- </el-form-item>
- </div>
- <div class="btn-group">
- <el-form-item>
- <el-button class="search-btn" type="primary" @click="handleSearch">查询</el-button>
- <el-button class="reset-btn" @click="handleReset">重置</el-button>
- <el-button class="reset-btn" @click="handleExport" v-if="!isShowTab">导出</el-button>
- </el-form-item>
- </div>
- </el-form>
- </div>
- </template>
- <script setup lang="ts">
- import type { FormInstance } from 'element-plus';
- import { reactive, ref } from 'vue';
- import { sourceOptions, hideStateOptions, issueStateOptions } from './constant.question';
- import { TableQueryForm } from '@/api/datamanagement/alert-default';
- interface Props {
- isShowTab: boolean; // true展示数据,false默认数据
- aiOptions: Array<any>;
- manualOptions: Array<any>;
- locationOptions: Array<any>;
- }
- const props = defineProps<Props>();
- const emits = defineEmits(['onSearch', 'onReset', 'onExport']);
- const formRef = ref<FormInstance>();
- const queryForm = reactive<TableQueryForm>({
- pageNumber: 1,
- pageSize: 10,
- queryParam: {},
- });
- type MainOption = {
- value: number;
- label: string;
- children: {
- value: number;
- label: string;
- }[];
- };
- const options = ref<MainOption[]>([]);
- const typeDisable = ref(true);
- const issueTypeValue = ref([]); // 问题类型,级联选择器
- const issueMainTypeProp = { multiple: true, expandTrigger: 'hover' as const };
- const workShopIds = ref([]);
- const workLocation = ref([]); // 级联选择器,为二维数组(提取workspaceId)
- const locationProp = { multiple: true, expandTrigger: 'hover' as const }; // 级联选择器(打开多选)
- const tempState = ref(''); // 状态,字符串转number[]
- const dateRange = ref([]); // 时间段,拆分成startTime/endTime
- const defaultTime = ref<[Date, Date]>([
- new Date(2000, 1, 1, 0, 0, 0),
- new Date(2000, 2, 1, 23, 59, 59),
- ]);
- const handleSearch = () => {
- emits('onSearch', queryForm);
- };
- const handleReset = () => {
- workShopIds.value = [];
- issueTypeValue.value = [];
- typeDisable.value = true;
- workLocation.value = [];
- tempState.value = '';
- dateRange.value = [];
- Reflect.deleteProperty(queryForm.queryParam, 'startTime');
- Reflect.deleteProperty(queryForm.queryParam, 'endTime');
- Reflect.deleteProperty(queryForm.queryParam, 'issueMainTypeList');
- Reflect.deleteProperty(queryForm.queryParam, 'issueTypeList');
- formRef.value?.resetFields();
- emits('onReset', queryForm);
- };
- const handleExport = () => {
- emits('onExport', queryForm, workShopIds.value);
- };
- const handleSelectChange = () => {
- if (Number(queryForm.queryParam.source) === 1) {
- typeDisable.value = false;
- options.value = props.aiOptions;
- } else if (Number(queryForm.queryParam.source) === 2) {
- typeDisable.value = false;
- options.value = props.manualOptions;
- } else {
- typeDisable.value = true;
- options.value = [];
- queryForm.queryParam.issueMainTypeList = undefined;
- queryForm.queryParam.issueTypeList = undefined;
- }
- };
- const handleIssueMainTypeChange = () => {
- if (issueTypeValue.value.length !== 0) {
- const arrMain = [];
- const arrSub = [];
- issueTypeValue.value.forEach((item) => {
- arrMain.push(item[0]);
- arrSub.push(item[1]);
- });
- queryForm.queryParam.issueMainTypeList = [...new Set(arrMain)];
- queryForm.queryParam.issueTypeList = arrSub;
- } else {
- Reflect.deleteProperty(queryForm.queryParam, 'issueMainTypeList');
- Reflect.deleteProperty(queryForm.queryParam, 'issueTypeList');
- }
- };
- const handleCascaderChange = () => {
- if (workLocation.value.length !== 0) {
- const arr = [];
- workShopIds.value = [];
- workLocation.value.forEach((item) => {
- arr.push(item[1]);
- workShopIds.value.push(item[0]);
- });
- queryForm.queryParam.workspaceId = arr;
- workShopIds.value = [...new Set(workShopIds.value)];
- } else {
- Reflect.deleteProperty(queryForm.queryParam, 'workspaceId');
- }
- };
- const handleIssueStateChange = () => {
- if (tempState.value) queryForm.queryParam.issueState = JSON.parse(tempState.value);
- else Reflect.deleteProperty(queryForm.queryParam, 'issueState');
- };
- const handleDateChange = () => {
- if (dateRange.value != null) {
- queryForm.queryParam.startTime = dateRange.value[0];
- queryForm.queryParam.endTime = dateRange.value[1];
- } else {
- Reflect.deleteProperty(queryForm.queryParam, 'startTime');
- Reflect.deleteProperty(queryForm.queryParam, 'endTime');
- }
- };
- // TODO: cascader点击任意位置选中,DOM方式实现一级,CSS方式无法穿透
- // TODO: el-cascader组件需添加 @expand-change="handleLocationExpandChange"(当前暂时删除)
- // const curLocationLevel = ref(0);
- // const handleLocationExpandChange = (event) => {
- // curLocationLevel.value = event.length;
- // nextTick(() => {
- // setCascaderDomEvent();
- // });
- // };
- // const setCascaderDomEvent = () => {
- // const cascaderDom = document.querySelectorAll('.special-cascader .el-cascader-menu__list');
- // if (cascaderDom.length >= curLocationLevel.value - 1) {
- // const optionDom = cascaderDom[curLocationLevel.value] as Element;
- // optionDom.querySelectorAll('.el-cascader-node__label').forEach((label: Element) => {
- // const nextDom = label.nextElementSibling;
- // label.addEventListener('click', cascaderCheckEvent);
- // if (!nextDom) {
- // (label as HTMLElement).style.cursor = 'pointer';
- // }
- // });
- // }
- // if (curLocationLevel.value) {
- // const optionDom = cascaderDom[curLocationLevel.value - 1] as Element;
- // optionDom.querySelectorAll('.el-cascader-node__label').forEach((label: Element) => {
- // const nextDom = label.nextElementSibling;
- // label.addEventListener('click', cascaderCheckEvent);
- // if (!nextDom) {
- // (label as HTMLElement).style.cursor = 'pointer';
- // }
- // });
- // }
- // };
- // const cascaderCheckEvent = (event: MouseEvent) => {
- // // 查找对应的输入框
- // let brother = (event.target as HTMLElement).previousElementSibling; // 获取前一个兄弟元素
- // const input = brother?.querySelector('input[type="checkbox"], input[type="radio"]'); // 支持复选框和单选框
- // if (input) {
- // (input as HTMLInputElement).click(); // 模拟点击复选框
- // }
- // // 如果有子菜单,展开/收起子菜单
- // const childMenu = (event.target as HTMLElement).nextElementSibling;
- // if (childMenu && childMenu.classList.contains('el-cascader-menu__list')) {
- // // 这里可以根据需求添加展开/收起的逻辑
- // }
- // };
- </script>
- <style scoped lang="less">
- .el-form {
- display: flex;
- justify-content: space-between;
- }
- :deep(.el-form--inline .el-form-item) {
- margin-right: 10px;
- }
- :deep(.el-form-item__label) {
- padding-left: 10px;
- }
- .select-group {
- flex: 1;
- }
- .btn-group {
- .search-btn {
- width: 65px;
- height: 32px;
- background: #1890ff;
- border-radius: 2px;
- }
- .reset-btn {
- width: 65px;
- height: 32px;
- border-radius: 2px;
- border: 1px solid #1890ff;
- color: #1890ff;
- }
- }
- .el-select {
- --el-select-width: 215px;
- }
- </style>
|