feat(动态切换对象域下的对象):对象域下的对象可以动态切换。 fix(产品需求、项目需求): 按照会议意见修改诸多细节。 fix(产品对象域的概览界面): 把假数据换成真实的需求统计数据。
131 lines
3.1 KiB
Vue
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>
|