|
@@ -7,7 +7,13 @@
|
|
|
*
|
|
|
-->
|
|
|
<script setup lang="ts">
|
|
|
-import type { PropsParams, TableFieldInfo, TablePaginationSetting } from '@/types/table.ts'
|
|
|
+import type {
|
|
|
+ PropsParams,
|
|
|
+ QueryInfo,
|
|
|
+ SelectInfo,
|
|
|
+ TableFieldInfo,
|
|
|
+ TablePaginationSetting
|
|
|
+} from '@/types/table.ts'
|
|
|
import type { ReqConfig } from '@/types/dataAnalysis.ts'
|
|
|
import type { FormInstance } from 'element-plus'
|
|
|
import { FilterType } from '@/types/table.ts'
|
|
@@ -26,9 +32,18 @@ import FilterPopover from '../toolsBtn/FilterPopover.vue'
|
|
|
import RefreshBtn from '../toolsBtn/RefreshBtn.vue'
|
|
|
import TableFieldText from './TableFieldText.vue'
|
|
|
import axiosInstance from '@/utils/axios/axiosInstance.ts'
|
|
|
+import { isArray } from 'element-plus/es/utils/types.mjs'
|
|
|
|
|
|
type CustomFilterRef = InstanceType<typeof CustomFilter>
|
|
|
|
|
|
+interface SelectAllItem {
|
|
|
+ isCheckAll: boolean // 是否选中了所有
|
|
|
+ isIndeterminate: boolean // 是否是中间状态
|
|
|
+}
|
|
|
+
|
|
|
+// 所有选择框的全选按钮信息
|
|
|
+const filterFormCheckAllInfo = ref<Record<string, SelectAllItem>>({})
|
|
|
+
|
|
|
// 自定义筛选组件的ref
|
|
|
const customFilterRef = ref<CustomFilterRef>()
|
|
|
|
|
@@ -136,7 +151,14 @@ const inputFieldsList = computed(() => {
|
|
|
// 所有类型为select的表单控件信息
|
|
|
const selectFieldsList = computed(() => {
|
|
|
return props.queryInfo?.filter((item) => {
|
|
|
- return item.type === FilterType.SELECT
|
|
|
+ const isSelect = item.type === FilterType.SELECT || item.type === FilterType.MULTI_SELECT
|
|
|
+ if (isSelect && item.type === FilterType.MULTI_SELECT) {
|
|
|
+ filterFormCheckAllInfo.value[item.name] = {
|
|
|
+ isCheckAll: true,
|
|
|
+ isIndeterminate: false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return isSelect
|
|
|
})
|
|
|
})
|
|
|
|
|
@@ -571,6 +593,92 @@ const resetCustomFilterData = () => {
|
|
|
resetCustomFilterList(FormData)
|
|
|
}
|
|
|
|
|
|
+const isMultipleSelect = (item: QueryInfo): boolean => {
|
|
|
+ const options = item.otherOption
|
|
|
+ const formList = queryFormData[item.name]
|
|
|
+ let result = true
|
|
|
+ if (item.type !== FilterType.MULTI_SELECT) {
|
|
|
+ result = false
|
|
|
+ console.error('非多选类型')
|
|
|
+ }
|
|
|
+ if (!(options && isArray(options))) {
|
|
|
+ result = false
|
|
|
+ console.error('选项为空或非数组')
|
|
|
+ }
|
|
|
+ if (!(formList && isArray(formList))) {
|
|
|
+ result = false
|
|
|
+ console.error('表单数据为空或非数组')
|
|
|
+ }
|
|
|
+ return result
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 根据全选情况改变选择情况
|
|
|
+ *
|
|
|
+ * @param item 查询条件信息
|
|
|
+ * @param formList 表单数据
|
|
|
+ */
|
|
|
+const changeCheckAll = (item: QueryInfo) => {
|
|
|
+ if (!isMultipleSelect(item)) return
|
|
|
+ const options = item.otherOption as Array<SelectInfo>
|
|
|
+ const activeSelectInfo = filterFormCheckAllInfo.value[item.name]
|
|
|
+ const isCheckAll = activeSelectInfo.isCheckAll
|
|
|
+ const formList = queryFormData[item.name]
|
|
|
+
|
|
|
+ activeSelectInfo.isIndeterminate = false
|
|
|
+ if (isCheckAll) {
|
|
|
+ const valList = options.map((option) => {
|
|
|
+ return option.value
|
|
|
+ })
|
|
|
+ formList.splice(0, formList.length, ...valList)
|
|
|
+ } else {
|
|
|
+ formList.splice(0, formList.length)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 处理点击多选按钮事件。
|
|
|
+ *
|
|
|
+ * formData对应的值不为数组或不是多选类型则报错
|
|
|
+ *
|
|
|
+ * @param item 查询条件信息
|
|
|
+ */
|
|
|
+const handleCheckAll = (item: QueryInfo) => {
|
|
|
+ changeCheckAll(item)
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 处理选项改变
|
|
|
+ * 单选情况:不处理
|
|
|
+ * 多选情况:改变上方多选框状态
|
|
|
+ *
|
|
|
+ * @param item 查询条件信息
|
|
|
+ * @param val 目前选择的值
|
|
|
+ */
|
|
|
+const selectChange = (item: QueryInfo, val: any) => {
|
|
|
+ // 目前只处理数组
|
|
|
+ if (!isArray(val)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 不符合多选信息的不处理
|
|
|
+ if (!isMultipleSelect(item)) return
|
|
|
+ const activeCheckInfo = filterFormCheckAllInfo.value[item.name]
|
|
|
+ if (!activeCheckInfo) {
|
|
|
+ console.error('不存在的多选信息')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const options = item.otherOption as Array<SelectInfo>
|
|
|
+ const isSelectedAll = val.length === options.length
|
|
|
+
|
|
|
+ activeCheckInfo.isCheckAll = isSelectedAll
|
|
|
+
|
|
|
+ if (val.length === 0) {
|
|
|
+ activeCheckInfo.isIndeterminate = false
|
|
|
+ } else {
|
|
|
+ activeCheckInfo.isIndeterminate = !isSelectedAll
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// 定义暴露出去的方法
|
|
|
defineExpose({
|
|
|
getData,
|
|
@@ -654,12 +762,51 @@ onMounted(() => {
|
|
|
:key="item.name"
|
|
|
class="filterItem"
|
|
|
>
|
|
|
+ <template #label="{ label }">
|
|
|
+ <span class="selectLabelContainer">
|
|
|
+ <span class="selectLabel"> {{ label }}</span>
|
|
|
+ <span class="selectSupplement" v-if="item.supplementInfo">
|
|
|
+ <!-- <el-icon><QuestionFilled /></el-icon>
|
|
|
+ {{ item.supplementInfo }} -->
|
|
|
+ <el-popover placement="top" trigger="hover">
|
|
|
+ <p
|
|
|
+ style="
|
|
|
+ width: auto;
|
|
|
+ padding: 0 5px;
|
|
|
+ display: inline-block;
|
|
|
+ text-align: center;
|
|
|
+ color: black;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ item.supplementInfo }}
|
|
|
+ </p>
|
|
|
+ <template #reference>
|
|
|
+ <el-icon><QuestionFilled /></el-icon>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
<el-select
|
|
|
:empty-values="[undefined, null]"
|
|
|
v-model="queryFormData[item.name]"
|
|
|
:placeholder="item.placeholder"
|
|
|
:value-key="item.name"
|
|
|
+ collapse-tags
|
|
|
+ collapse-tags-tooltip
|
|
|
+ style="width: 240px"
|
|
|
+ :multiple="item.type === FilterType.MULTI_SELECT"
|
|
|
+ @change="selectChange(item, queryFormData[item.name])"
|
|
|
>
|
|
|
+ <template #header v-if="item.type === FilterType.MULTI_SELECT">
|
|
|
+ <el-checkbox
|
|
|
+ v-model="filterFormCheckAllInfo[item.name].isCheckAll"
|
|
|
+ :indeterminate="filterFormCheckAllInfo[item.name].isIndeterminate"
|
|
|
+ @change="handleCheckAll(item)"
|
|
|
+ >
|
|
|
+ 全部
|
|
|
+ </el-checkbox>
|
|
|
+ </template>
|
|
|
<el-option
|
|
|
v-for="val in item.otherOption"
|
|
|
:key="val.name"
|
|
@@ -981,6 +1128,16 @@ onMounted(() => {
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
+.selectLabelContainer,
|
|
|
+.selectSupplement {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.selectSupplement {
|
|
|
+ margin-left: 5px;
|
|
|
+}
|
|
|
+
|
|
|
.tableTools {
|
|
|
width: 98%;
|
|
|
display: flex;
|