feat: 高级搜索-默认搜索条件和搜索条件下拉数据分情况显示

This commit is contained in:
teukkk 2024-09-05 19:11:42 +08:00 committed by Craftsman
parent bb2a6ab074
commit 8da2ebc414
7 changed files with 77 additions and 53 deletions

View File

@ -13,7 +13,7 @@
<div class="one-line-text"> {{ formModel.name }}</div>
</a-tooltip>
<MsIcon
v-if="formModel?.internalViewKey !== 'ALL_DATA'"
v-if="!isInternalViews(formModel?.id)"
type="icon-icon_edit_outlined"
class="min-w-[16px] cursor-pointer hover:text-[rgb(var(--primary-5))]"
@click="showNameInput"
@ -51,7 +51,7 @@
{{ t(option.title as string) }}
</a-option>
<a-divider
v-if="(props?.customList || [])?.length && (props.configList || []).length - 1 === currentOptionsIndex"
v-if="(props?.customList || [])?.length && (currentConfigList || []).length - 1 === currentOptionsIndex"
class="!my-1"
/>
</div>
@ -100,10 +100,11 @@
allow-search
:placeholder="t('common.pleaseSelect')"
:disabled="isValueDisabled(item)"
:options="props.memberOptions"
multiple
:search-keys="['label']"
:max-tag-count="1"
v-bind="{
options: props.memberOptions,
multiple: true,
}"
/>
<MsSelect
v-else-if="item.type === FilterType.SELECT"
@ -197,7 +198,7 @@
<a-button type="primary" @click="handleFilter">{{ t('common.filter') }}</a-button>
<a-button class="mr-[16px]" @click="handleReset">{{ t('common.reset') }}</a-button>
<MsButton
v-if="formModel?.internalViewKey !== 'ALL_DATA'"
v-if="!isInternalViews(formModel?.id)"
type="text"
:loading="saveLoading"
class="!text-[var(--color-text-1)]"
@ -205,7 +206,12 @@
>
{{ t('common.save') }}
</MsButton>
<MsButton v-if="formModel?.id" type="text" class="!text-[var(--color-text-1)]" @click="handleToSaveAs">
<MsButton
v-if="formModel?.id && !isInternalViews(formModel?.id)"
type="text"
class="!text-[var(--color-text-1)]"
@click="handleToSaveAs"
>
{{ t('advanceFilter.saveAsView') }}
</MsButton>
</div>
@ -240,8 +246,8 @@
import { SelectValue } from '@/models/projectManagement/menuManagement';
import { FilterType, OperatorEnum, ViewTypeEnum } from '@/enums/advancedFilterEnum';
import { operatorOptionsMap } from './index';
import { ConditionsItem, FilterForm, FilterFormItem, FilterResult } from './type';
import { getAllDataDefaultConditions, internalViewsHiddenConditionsMap, operatorOptionsMap } from './index';
import { ConditionsItem, FilterForm, FilterFormItem, FilterResult, ViewItem } from './type';
const props = defineProps<{
configList: FilterFormItem[]; //
@ -250,6 +256,7 @@
currentView: string; //
allViewNames: string[];
canNotAddView: boolean;
internalViews: ViewItem[]; //
memberOptions: { label: string; value: string }[];
}>();
const emit = defineEmits<{
@ -268,12 +275,26 @@
};
const formModel = ref<FilterForm>(cloneDeep(defaultFormModel));
const savedFormModel = ref(cloneDeep(formModel.value));
const currentConfigList = computed<FilterFormItem[]>(() =>
props.configList.filter(
(item) => !(internalViewsHiddenConditionsMap[props.currentView] ?? []).includes(item.dataIndex as string)
)
);
function isInternalViews(id?: string): boolean {
return props.internalViews.some((item) => item.id === id);
}
function getListItemByDataIndex(dataIndex: string) {
return [...props.configList, ...(props.customList || [])].find((item) => item.dataIndex === dataIndex);
return [...currentConfigList.value, ...(props.customList || [])].find((item) => item.dataIndex === dataIndex);
}
async function getUserViewDetail(id: string) {
try {
const res = await getViewDetail(props.viewType, id);
//
if (res?.id === 'all_data') {
res.conditions = [...getAllDataDefaultConditions(props.viewType)];
}
const list: FilterFormItem[] = (res.conditions ?? [])?.map((item: ConditionsItem) => {
const listItem = getListItemByDataIndex(item.name ?? '') as FilterFormItem;
return {
@ -289,6 +310,15 @@
console.log(error);
}
}
watch(
() => visible.value,
async (val) => {
//
if (!val && formModel.value?.id !== props.currentView) {
await getUserViewDetail(props.currentView);
}
}
);
const isShowNameInput = ref(false);
const viewNameInputRef = ref<InstanceType<typeof ViewNameInput>>();
@ -319,7 +349,7 @@
const otherDataIndices = formModel.value.list
.filter((listItem) => listItem.dataIndex !== currentDataIndex)
.map((item: FilterFormItem) => item.dataIndex);
return [...props.configList, ...(props.customList || [])]
return [...currentConfigList.value, ...(props.customList || [])]
.filter(({ dataIndex }) => !otherDataIndices.includes(dataIndex))
.map((item) => ({ ...item, label: t(item.title as string) }));
};
@ -392,20 +422,12 @@
}
watch(
() => props.currentView,
async (val) => {
async (val, oldValue) => {
await getUserViewDetail(val);
if (!oldValue.length) return;
handleFilter();
}
);
watch(
() => visible.value,
async (val) => {
//
if (!val && formModel.value?.id !== props.currentView) {
await getUserViewDetail(props.currentView);
}
}
);
//
function resetToNewViewForm() {
@ -424,6 +446,7 @@
};
savedFormModel.value = cloneDeep(formModel.value);
}
//
const saveLoading = ref(false);
function realSaveView() {
@ -460,6 +483,7 @@
realSaveView();
}
}
//
const isSaveAsView = ref(false);
const saveAsViewForm = ref({ name: '' });

View File

@ -1,4 +1,4 @@
import { FilterType, OperatorEnum } from '@/enums/advancedFilterEnum';
import { FilterType, OperatorEnum, ViewTypeEnum } from '@/enums/advancedFilterEnum';
export { default as MsAdvanceFilter } from './index.vue';
@ -167,26 +167,18 @@ export const CustomTypeMaps: Record<string, any> = {
},
};
export const defaultFormModelList = [
{
dataIndex: 'id',
title: 'caseManagement.featureCase.tableColumnID',
type: FilterType.INPUT,
operator: OperatorEnum.CONTAINS,
value: '',
},
{
dataIndex: 'name',
label: 'common.name',
type: FilterType.INPUT,
operator: OperatorEnum.CONTAINS,
value: '',
},
{
dataIndex: 'moduleId',
label: 'common.belongModule',
type: FilterType.TREE_SELECT,
operator: OperatorEnum.BELONG_TO,
value: '',
},
// 全部数据默认显示搜索条件ID、名称、模块
// TODO lmy 计划详情功能用例增加:测试点;接口定义、计划详情接口用例增加:协议;
export function getAllDataDefaultConditions(viewType: ViewTypeEnum) {
const conditions = [
{ name: 'id', operator: OperatorEnum.CONTAINS },
{ name: 'name', operator: OperatorEnum.CONTAINS },
{ name: 'moduleId', operator: OperatorEnum.BELONG_TO },
];
return conditions;
}
// 系统视图对应不显示的第一列下拉条件
export const internalViewsHiddenConditionsMap: Record<string, string[]> = {
my_create: ['createUser'],
};

View File

@ -113,11 +113,13 @@
</MsTag>
</div>
</div>
<!-- TODO lmy 高级搜索全部覆盖后将此代码删除?? ViewTypeEnum.FUNCTIONAL_CASE -->
<FilterDrawer
ref="filterDrawerRef"
v-model:visible="visible"
:current-view="currentView"
:view-type="props.viewType as ViewTypeEnum"
:view-type="props.viewType ?? ViewTypeEnum.FUNCTIONAL_CASE"
:internal-views="internalViews"
:all-view-names="allViewNames"
:config-list="props.filterConfigList"
:custom-list="props.customFieldsConfigList"
@ -159,7 +161,7 @@
const emit = defineEmits<{
(e: 'keywordSearch', value: string | undefined): void; // keyword TODO: v-model:keyword
(e: 'advSearch', value: FilterResult): void; //
(e: 'advSearch', value: FilterResult, viewId: string): void; //
(e: 'refresh', value: FilterResult): void;
}>();
@ -273,7 +275,7 @@
//
isAdvancedSearchMode.value = currentView.value !== internalViews.value[0].id || haveConditions;
filterResult.value = filter;
emit('advSearch', filter);
emit('advSearch', filter, currentView.value);
};
const handleRefresh = () => {

View File

@ -84,7 +84,6 @@ export interface ViewDetail extends ViewParams {
userId?: string;
viewType?: string;
internal?: boolean; // 是否为内置视图
internalViewKey?: string;
createTime?: number;
updateTime?: number;
}

View File

@ -89,6 +89,8 @@ export default function useTableProps<T>(
const keyword = ref('');
// 高级筛选
const advanceFilter = reactive<FilterResult>({ searchMode: 'AND', conditions: [] });
// 视图Id
const viewId = ref('');
// 表格请求参数集合
const tableQueryParams = ref<TableQueryParams>({});
@ -165,9 +167,10 @@ export default function useTableProps<T>(
};
// 设置 advanceFilter
const setAdvanceFilter = (v: FilterResult) => {
const setAdvanceFilter = (v: FilterResult, id: string) => {
advanceFilter.searchMode = v.searchMode;
advanceFilter.conditions = v.conditions;
viewId.value = id;
// 基础筛选都清空
loadListParams.value.filter = {};
keyword.value = '';
@ -234,6 +237,7 @@ export default function useTableProps<T>(
pageSize: currentPageSize,
sort: sortItem.value,
keyword: keyword.value,
viewId: viewId.value,
combineSearch: advanceFilter,
...loadListParams.value,
filter: {
@ -608,6 +612,7 @@ export default function useTableProps<T>(
propsRes,
propsEvent,
advanceFilter,
viewId,
setProps,
setLoading,
loadList,

View File

@ -936,6 +936,7 @@
const {
propsRes,
propsEvent,
viewId,
advanceFilter,
loadList,
setLoadListParams,
@ -985,6 +986,7 @@
return {
keyword: keyword.value,
filter: propsRes.value.filter,
viewId: viewId.value,
combineSearch: advanceFilter,
};
});
@ -1625,12 +1627,12 @@
}
}
//
const handleAdvSearch = async (filter: FilterResult) => {
const handleAdvSearch = async (filter: FilterResult, id: string) => {
resetSelector();
emit('setActiveFolder');
keyword.value = '';
await getLoadListParams(); //
setAdvanceFilter(filter);
setAdvanceFilter(filter, id);
loadList();
};
//

View File

@ -223,7 +223,7 @@
const currentProjectId = computed(() => appStore.currentProjectId);
const scrollWidth = ref<number>(3400);
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setAdvanceFilter, setKeyword } = useTable(
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setKeyword } = useTable(
getRecycleListRequest,
{
tableKey: TableKeyEnum.CASE_MANAGEMENT_RECYCLE_TABLE,