Files
cn-rdms-web/src/views/product/requirement/modules/requirement-search.vue
dk 13b74cfe97 feat(新增需求评审功能): 新增需求评审功能。
feat(动态切换对象域下的对象):对象域下的对象可以动态切换。
fix(产品需求、项目需求): 按照会议意见修改诸多细节。
fix(产品对象域的概览界面): 把假数据换成真实的需求统计数据。
2026-05-22 14:05:25 +08:00

131 lines
3.1 KiB
Vue

<script setup lang="ts">
import { computed, h, onMounted, ref } from 'vue';
import { RDMS_REQ_SOURCE_TYPE_DICT_CODE } from '@/constants/dict';
import { fetchGetRequirementStatusDict } from '@/service/api';
import { useDict } from '@/hooks/business/dict';
import TableSearchFields from '@/components/custom/table-search-fields.vue';
import MemberSelectOption from './member-select-option.vue';
defineOptions({ name: 'RequirementSearch' });
interface MemberUserOption {
id: string;
nickname: string;
roleName?: string;
}
interface Props {
memberOptions: MemberUserOption[];
categoryDictCode: string;
priorityDictCode: string;
}
const props = defineProps<Props>();
interface Emits {
(e: 'reset'): void;
(e: 'search'): void;
}
const emit = defineEmits<Emits>();
const model = defineModel<Api.Product.RequirementSearchParams>('model', { required: true });
const requirementStatusOptions = ref<Array<{ label: string; value: string }>>([]);
const { enabledDictData: sourceTypeDictData } = useDict(RDMS_REQ_SOURCE_TYPE_DICT_CODE);
const sourceTypeOptions = computed(() => {
return sourceTypeDictData.value
.filter(item => item.value !== 'product_requirement')
.map(item => ({
label: item.label,
value: item.value
}));
});
const memberSelectOptions = computed(() => {
return props.memberOptions.map(item => ({
label: item.nickname,
value: item.id,
roleName: item.roleName
}));
});
function renderMemberOption(option: { label: string; value: string | number; roleName?: string }) {
return h(MemberSelectOption, {
nickname: option.label,
roleName: option.roleName || ''
});
}
async function loadStatusOptions() {
const { error, data } = await fetchGetRequirementStatusDict();
if (error || !data) {
requirementStatusOptions.value = [];
return;
}
requirementStatusOptions.value = data.map(item => ({
label: item.statusName,
value: item.statusCode
}));
}
onMounted(async () => {
await loadStatusOptions();
});
const fields = computed(() => [
{
key: 'title',
label: '需求名称',
type: 'input' as const,
placeholder: '输入需求名称'
},
{
key: 'priority',
label: '优先级',
type: 'dict' as const,
dictCode: props.priorityDictCode,
placeholder: '筛选优先级'
},
{
key: 'statusCode',
label: '状态',
type: 'select' as const,
placeholder: '筛选状态',
options: requirementStatusOptions.value
},
{
key: 'category',
label: '需求类型',
type: 'dict' as const,
dictCode: props.categoryDictCode,
placeholder: '筛选需求类型'
},
{
key: 'sourceType',
label: '需求来源',
type: 'select' as const,
placeholder: '筛选需求来源',
options: sourceTypeOptions.value
},
{
key: 'currentHandlerUserId',
label: '负责人',
type: 'select' as const,
placeholder: '筛选负责人',
options: memberSelectOptions.value,
renderOption: renderMemberOption
}
]);
</script>
<template>
<TableSearchFields v-model="model" :fields="fields" :columns="4" @search="emit('search')" @reset="emit('reset')" />
</template>
<style scoped></style>