feat(产品需求、项目需求): 支持手动录入"来源业务编号",前端的sourceBizId改为sourceBizCode,也支持按"来源业务编号"搜索。
This commit is contained in:
@@ -210,7 +210,7 @@ type RequirementResponse = Omit<
|
|||||||
| 'proposerId'
|
| 'proposerId'
|
||||||
| 'currentHandlerUserId'
|
| 'currentHandlerUserId'
|
||||||
| 'implementProjectId'
|
| 'implementProjectId'
|
||||||
| 'sourceBizId'
|
| 'sourceBizCode'
|
||||||
| 'attachments'
|
| 'attachments'
|
||||||
> & {
|
> & {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
@@ -220,7 +220,7 @@ type RequirementResponse = Omit<
|
|||||||
currentHandlerUserId?: string | number | null;
|
currentHandlerUserId?: string | number | null;
|
||||||
implementProjectId?: string | number | null;
|
implementProjectId?: string | number | null;
|
||||||
implementProjectName?: string | null;
|
implementProjectName?: string | null;
|
||||||
sourceBizId?: string | number | null;
|
sourceBizCode?: string | null;
|
||||||
attachments?: AttachmentItemResponse[] | null;
|
attachments?: AttachmentItemResponse[] | null;
|
||||||
children?: RequirementResponse[];
|
children?: RequirementResponse[];
|
||||||
};
|
};
|
||||||
@@ -292,7 +292,7 @@ function normalizeRequirement(requirement: RequirementResponse): Api.Product.Req
|
|||||||
currentHandlerUserId: normalizeNullableStringId(requirement.currentHandlerUserId),
|
currentHandlerUserId: normalizeNullableStringId(requirement.currentHandlerUserId),
|
||||||
implementProjectId: normalizeNullableStringId(requirement.implementProjectId),
|
implementProjectId: normalizeNullableStringId(requirement.implementProjectId),
|
||||||
implementProjectName: requirement.implementProjectName ?? null,
|
implementProjectName: requirement.implementProjectName ?? null,
|
||||||
sourceBizId: normalizeNullableStringId(requirement.sourceBizId),
|
sourceBizCode: requirement.sourceBizCode ?? null,
|
||||||
attachments: normalizeAttachments(requirement.attachments),
|
attachments: normalizeAttachments(requirement.attachments),
|
||||||
children: requirement.children?.map(normalizeRequirement)
|
children: requirement.children?.map(normalizeRequirement)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1026,7 +1026,7 @@ const PROJECT_REQUIREMENT_PREFIX = `${WEB_SERVICE_PREFIX}/project/project/requir
|
|||||||
|
|
||||||
type ProjectRequirementResponse = Omit<
|
type ProjectRequirementResponse = Omit<
|
||||||
Api.Project.ProjectRequirement,
|
Api.Project.ProjectRequirement,
|
||||||
'id' | 'projectId' | 'parentId' | 'moduleId' | 'proposerId' | 'currentHandlerUserId' | 'sourceBizId' | 'attachments'
|
'id' | 'projectId' | 'parentId' | 'moduleId' | 'proposerId' | 'currentHandlerUserId' | 'sourceBizCode' | 'attachments'
|
||||||
> & {
|
> & {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
projectId: string | number;
|
projectId: string | number;
|
||||||
@@ -1034,7 +1034,7 @@ type ProjectRequirementResponse = Omit<
|
|||||||
moduleId: string | number;
|
moduleId: string | number;
|
||||||
proposerId: string | number;
|
proposerId: string | number;
|
||||||
currentHandlerUserId?: string | number | null;
|
currentHandlerUserId?: string | number | null;
|
||||||
sourceBizId?: string | number | null;
|
sourceBizCode?: string | null;
|
||||||
attachments?: AttachmentItemResponse[] | null;
|
attachments?: AttachmentItemResponse[] | null;
|
||||||
children?: ProjectRequirementResponse[];
|
children?: ProjectRequirementResponse[];
|
||||||
};
|
};
|
||||||
@@ -1090,7 +1090,7 @@ function normalizeProjectRequirement(requirement: ProjectRequirementResponse): A
|
|||||||
moduleId: normalizeStringId(requirement.moduleId),
|
moduleId: normalizeStringId(requirement.moduleId),
|
||||||
proposerId: normalizeStringId(requirement.proposerId),
|
proposerId: normalizeStringId(requirement.proposerId),
|
||||||
currentHandlerUserId: normalizeNullableStringId(requirement.currentHandlerUserId),
|
currentHandlerUserId: normalizeNullableStringId(requirement.currentHandlerUserId),
|
||||||
sourceBizId: normalizeNullableStringId(requirement.sourceBizId),
|
sourceBizCode: requirement.sourceBizCode ?? null,
|
||||||
attachments: normalizeAttachments(requirement.attachments),
|
attachments: normalizeAttachments(requirement.attachments),
|
||||||
progressRate: typeof requirement.progressRate === 'number' ? requirement.progressRate : 0,
|
progressRate: typeof requirement.progressRate === 'number' ? requirement.progressRate : 0,
|
||||||
children: requirement.children?.map(normalizeProjectRequirement)
|
children: requirement.children?.map(normalizeProjectRequirement)
|
||||||
|
|||||||
7
src/typings/api/product.d.ts
vendored
7
src/typings/api/product.d.ts
vendored
@@ -332,8 +332,8 @@ declare namespace Api {
|
|||||||
categoryName?: string | null;
|
categoryName?: string | null;
|
||||||
/** 需求来源类型 */
|
/** 需求来源类型 */
|
||||||
sourceType: RequirementSourceType;
|
sourceType: RequirementSourceType;
|
||||||
/** 需求来源业务ID */
|
/** 来源业务编号 */
|
||||||
sourceBizId?: string | null;
|
sourceBizCode?: string | null;
|
||||||
/** 优先级(0低 1中 2高 3紧急) */
|
/** 优先级(0低 1中 2高 3紧急) */
|
||||||
priority: RequirementPriority;
|
priority: RequirementPriority;
|
||||||
/** 优先级名称 */
|
/** 优先级名称 */
|
||||||
@@ -508,7 +508,7 @@ declare namespace Api {
|
|||||||
Pick<PageParams, 'pageNo' | 'pageSize'> &
|
Pick<PageParams, 'pageNo' | 'pageSize'> &
|
||||||
Pick<
|
Pick<
|
||||||
Requirement,
|
Requirement,
|
||||||
'moduleId' | 'category' | 'priority' | 'statusCode' | 'currentHandlerUserId' | 'sourceType'
|
'moduleId' | 'category' | 'priority' | 'statusCode' | 'currentHandlerUserId' | 'sourceBizCode'
|
||||||
> & {
|
> & {
|
||||||
productId: string;
|
productId: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -526,6 +526,7 @@ declare namespace Api {
|
|||||||
| 'attachments'
|
| 'attachments'
|
||||||
| 'category'
|
| 'category'
|
||||||
| 'priority'
|
| 'priority'
|
||||||
|
| 'sourceBizCode'
|
||||||
| 'proposerId'
|
| 'proposerId'
|
||||||
| 'proposerNickname'
|
| 'proposerNickname'
|
||||||
| 'currentHandlerUserId'
|
| 'currentHandlerUserId'
|
||||||
|
|||||||
7
src/typings/api/project.d.ts
vendored
7
src/typings/api/project.d.ts
vendored
@@ -1160,8 +1160,8 @@ declare namespace Api {
|
|||||||
categoryName?: string | null;
|
categoryName?: string | null;
|
||||||
/** 需求来源类型 */
|
/** 需求来源类型 */
|
||||||
sourceType: ProjectRequirementSourceType;
|
sourceType: ProjectRequirementSourceType;
|
||||||
/** 来源业务 ID */
|
/** 来源业务编号 */
|
||||||
sourceBizId?: string | null;
|
sourceBizCode?: string | null;
|
||||||
/** 优先级 */
|
/** 优先级 */
|
||||||
priority: ProjectRequirementPriority;
|
priority: ProjectRequirementPriority;
|
||||||
/** 优先级名称 */
|
/** 优先级名称 */
|
||||||
@@ -1285,7 +1285,7 @@ declare namespace Api {
|
|||||||
Pick<PageParams, 'pageNo' | 'pageSize'> &
|
Pick<PageParams, 'pageNo' | 'pageSize'> &
|
||||||
Pick<
|
Pick<
|
||||||
ProjectRequirement,
|
ProjectRequirement,
|
||||||
'moduleId' | 'parentId' | 'category' | 'priority' | 'statusCode' | 'currentHandlerUserId' | 'sourceType'
|
'moduleId' | 'parentId' | 'category' | 'priority' | 'statusCode' | 'currentHandlerUserId' | 'sourceBizCode'
|
||||||
> & {
|
> & {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -1303,6 +1303,7 @@ declare namespace Api {
|
|||||||
| 'attachments'
|
| 'attachments'
|
||||||
| 'category'
|
| 'category'
|
||||||
| 'priority'
|
| 'priority'
|
||||||
|
| 'sourceBizCode'
|
||||||
| 'proposerId'
|
| 'proposerId'
|
||||||
| 'proposerNickname'
|
| 'proposerNickname'
|
||||||
| 'currentHandlerUserId'
|
| 'currentHandlerUserId'
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import dayjs from 'dayjs';
|
|||||||
import {
|
import {
|
||||||
RDMS_REQ_CAN_DELETE_STATUS_DICT_CODE,
|
RDMS_REQ_CAN_DELETE_STATUS_DICT_CODE,
|
||||||
RDMS_REQ_CATEGORY_DICT_CODE,
|
RDMS_REQ_CATEGORY_DICT_CODE,
|
||||||
RDMS_REQ_PRIORITY_DICT_CODE,
|
RDMS_REQ_PRIORITY_DICT_CODE
|
||||||
RDMS_REQ_SOURCE_TYPE_DICT_CODE
|
|
||||||
} from '@/constants/dict';
|
} from '@/constants/dict';
|
||||||
import { getStatusTagType } from '@/constants/status-tag';
|
import { getStatusTagType } from '@/constants/status-tag';
|
||||||
import {
|
import {
|
||||||
@@ -25,7 +24,6 @@ import {
|
|||||||
import { useAuth } from '@/hooks/business/auth';
|
import { useAuth } from '@/hooks/business/auth';
|
||||||
import { useDict } from '@/hooks/business/dict';
|
import { useDict } from '@/hooks/business/dict';
|
||||||
import DictTag from '@/components/custom/dict-tag.vue';
|
import DictTag from '@/components/custom/dict-tag.vue';
|
||||||
import DictText from '@/components/custom/dict-text.vue';
|
|
||||||
import { useCurrentProduct } from '../shared/use-current-product';
|
import { useCurrentProduct } from '../shared/use-current-product';
|
||||||
import {
|
import {
|
||||||
ACTION_ICON_MAP,
|
ACTION_ICON_MAP,
|
||||||
@@ -181,7 +179,7 @@ const searchParams = reactive({
|
|||||||
priority: undefined as Api.Product.RequirementPriority | undefined,
|
priority: undefined as Api.Product.RequirementPriority | undefined,
|
||||||
statusCode: undefined as Api.Product.RequirementStatusCode | undefined,
|
statusCode: undefined as Api.Product.RequirementStatusCode | undefined,
|
||||||
currentHandlerUserId: undefined as string | undefined,
|
currentHandlerUserId: undefined as string | undefined,
|
||||||
sourceType: undefined as Api.Product.RequirementSourceType | undefined
|
sourceBizCode: undefined as string | undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
const createVisible = ref(false);
|
const createVisible = ref(false);
|
||||||
@@ -384,15 +382,15 @@ const columns = computed(() => [
|
|||||||
minWidth: 80,
|
minWidth: 80,
|
||||||
formatter: (row: Api.Product.Requirement) => row.category
|
formatter: (row: Api.Product.Requirement) => row.category
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
prop: 'sourceType',
|
// prop: 'sourceType',
|
||||||
label: '需求来源',
|
// label: '需求来源',
|
||||||
minWidth: 80,
|
// minWidth: 80,
|
||||||
align: 'center',
|
// align: 'center',
|
||||||
formatter: (row: Api.Product.Requirement) => (
|
// formatter: (row: Api.Product.Requirement) => (
|
||||||
<DictText dictCode={RDMS_REQ_SOURCE_TYPE_DICT_CODE} value={row.sourceType} />
|
// <DictText dictCode={RDMS_REQ_SOURCE_TYPE_DICT_CODE} value={row.sourceType} />
|
||||||
)
|
// )
|
||||||
},
|
// },
|
||||||
// {
|
// {
|
||||||
// prop: 'description',
|
// prop: 'description',
|
||||||
// label: '内容',
|
// label: '内容',
|
||||||
@@ -415,19 +413,15 @@ const columns = computed(() => [
|
|||||||
formatter: (row: Api.Product.Requirement) => getMemberLabel(row.currentHandlerUserId)
|
formatter: (row: Api.Product.Requirement) => getMemberLabel(row.currentHandlerUserId)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: 'sourceBizId',
|
prop: 'sourceBizCode',
|
||||||
label: '来源业务编号',
|
label: '来源业务编号',
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
formatter: (row: Api.Product.Requirement) => {
|
formatter: (row: Api.Product.Requirement) => {
|
||||||
if (!row.sourceBizId || row.sourceType === 'manual') {
|
if (!row.sourceBizCode) {
|
||||||
return '--';
|
return '--';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return row.sourceBizCode;
|
||||||
<ElButton link type="primary" class="requirement-source-link">
|
|
||||||
{row.sourceBizId}
|
|
||||||
</ElButton>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -649,7 +643,7 @@ async function loadTreeData() {
|
|||||||
priority: searchParams.priority,
|
priority: searchParams.priority,
|
||||||
statusCode: searchParams.statusCode,
|
statusCode: searchParams.statusCode,
|
||||||
currentHandlerUserId: searchParams.currentHandlerUserId,
|
currentHandlerUserId: searchParams.currentHandlerUserId,
|
||||||
sourceType: searchParams.sourceType
|
sourceBizCode: searchParams.sourceBizCode?.trim() || undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error || !data) {
|
if (error || !data) {
|
||||||
@@ -705,7 +699,7 @@ function handleResetSearch() {
|
|||||||
searchParams.priority = undefined;
|
searchParams.priority = undefined;
|
||||||
searchParams.statusCode = undefined;
|
searchParams.statusCode = undefined;
|
||||||
searchParams.currentHandlerUserId = undefined;
|
searchParams.currentHandlerUserId = undefined;
|
||||||
searchParams.sourceType = undefined;
|
searchParams.sourceBizCode = undefined;
|
||||||
pagination.pageNo = 1;
|
pagination.pageNo = 1;
|
||||||
reloadTable();
|
reloadTable();
|
||||||
}
|
}
|
||||||
@@ -1057,10 +1051,6 @@ onMounted(async () => {
|
|||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.requirement-source-link) {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-table__row[class*='el-table__row--level-']:not(.el-table__row--level-0) td:first-child .cell) {
|
:deep(.el-table__row[class*='el-table__row--level-']:not(.el-table__row--level-0) td:first-child .cell) {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ interface Model {
|
|||||||
moduleId: string | null;
|
moduleId: string | null;
|
||||||
category: string;
|
category: string;
|
||||||
priority: string | null;
|
priority: string | null;
|
||||||
|
sourceBizCode: string;
|
||||||
expectedTime: string | null;
|
expectedTime: string | null;
|
||||||
proposerId: string;
|
proposerId: string;
|
||||||
currentHandlerUserId: string;
|
currentHandlerUserId: string;
|
||||||
@@ -139,6 +140,7 @@ function createDefaultModel(): Model {
|
|||||||
moduleId: props.defaultModuleId || null,
|
moduleId: props.defaultModuleId || null,
|
||||||
category: '功能需求',
|
category: '功能需求',
|
||||||
priority: '3',
|
priority: '3',
|
||||||
|
sourceBizCode: '',
|
||||||
expectedTime: null,
|
expectedTime: null,
|
||||||
proposerId: '',
|
proposerId: '',
|
||||||
currentHandlerUserId: '',
|
currentHandlerUserId: '',
|
||||||
@@ -186,6 +188,7 @@ async function handleSubmit() {
|
|||||||
attachments: [...model.value.attachments],
|
attachments: [...model.value.attachments],
|
||||||
category: model.value.category,
|
category: model.value.category,
|
||||||
priority: Number(model.value.priority) as Api.Product.RequirementPriority,
|
priority: Number(model.value.priority) as Api.Product.RequirementPriority,
|
||||||
|
sourceBizCode: model.value.sourceBizCode.trim() || null,
|
||||||
expectedTime: model.value.expectedTime,
|
expectedTime: model.value.expectedTime,
|
||||||
proposerId: model.value.proposerId,
|
proposerId: model.value.proposerId,
|
||||||
proposerNickname,
|
proposerNickname,
|
||||||
@@ -315,6 +318,10 @@ watch(
|
|||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
|
<ElFormItem label="来源业务编号">
|
||||||
|
<ElInput v-model="model.sourceBizCode" clearable maxlength="128" placeholder="请输入来源业务编号" />
|
||||||
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label="提出人" prop="proposerId">
|
<ElFormItem label="提出人" prop="proposerId">
|
||||||
<ElSelect v-model="model.proposerId" class="w-full" filterable placeholder="请选择提出人">
|
<ElSelect v-model="model.proposerId" class="w-full" filterable placeholder="请选择提出人">
|
||||||
<ElOption v-for="item in allUserOptions" :key="item.id" :label="item.nickname" :value="item.id" />
|
<ElOption v-for="item in allUserOptions" :key="item.id" :label="item.nickname" :value="item.id" />
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ interface Model {
|
|||||||
moduleId: string | null;
|
moduleId: string | null;
|
||||||
category: string;
|
category: string;
|
||||||
priority: string | null;
|
priority: string | null;
|
||||||
|
sourceBizCode: string;
|
||||||
expectedTime: string | null;
|
expectedTime: string | null;
|
||||||
proposerId: string;
|
proposerId: string;
|
||||||
proposerNickname: string;
|
proposerNickname: string;
|
||||||
@@ -201,6 +202,7 @@ function createDefaultModel(): Model {
|
|||||||
moduleId: null,
|
moduleId: null,
|
||||||
category: '',
|
category: '',
|
||||||
priority: '3',
|
priority: '3',
|
||||||
|
sourceBizCode: '',
|
||||||
expectedTime: null,
|
expectedTime: null,
|
||||||
proposerId: '',
|
proposerId: '',
|
||||||
proposerNickname: '',
|
proposerNickname: '',
|
||||||
@@ -252,6 +254,7 @@ async function handleSubmit() {
|
|||||||
attachments: [...model.value.attachments],
|
attachments: [...model.value.attachments],
|
||||||
category: model.value.category,
|
category: model.value.category,
|
||||||
priority: Number(model.value.priority) as Api.Product.RequirementPriority,
|
priority: Number(model.value.priority) as Api.Product.RequirementPriority,
|
||||||
|
sourceBizCode: model.value.sourceBizCode.trim() || null,
|
||||||
expectedTime: model.value.expectedTime,
|
expectedTime: model.value.expectedTime,
|
||||||
proposerId: model.value.proposerId,
|
proposerId: model.value.proposerId,
|
||||||
proposerNickname: model.value.proposerNickname,
|
proposerNickname: model.value.proposerNickname,
|
||||||
@@ -317,6 +320,7 @@ function transformRequirementData(data: Api.Product.Requirement): typeof model.v
|
|||||||
moduleId: data.moduleId || null,
|
moduleId: data.moduleId || null,
|
||||||
category: data.category || '',
|
category: data.category || '',
|
||||||
priority: data.priority === null || data.priority === undefined ? null : String(data.priority),
|
priority: data.priority === null || data.priority === undefined ? null : String(data.priority),
|
||||||
|
sourceBizCode: data.sourceBizCode || '',
|
||||||
expectedTime: formatExpectedTime(data.expectedTime),
|
expectedTime: formatExpectedTime(data.expectedTime),
|
||||||
proposerId: data.proposerId || '',
|
proposerId: data.proposerId || '',
|
||||||
proposerNickname: data.proposerNickname || '',
|
proposerNickname: data.proposerNickname || '',
|
||||||
@@ -446,6 +450,17 @@ watch(
|
|||||||
<ReadonlyField :value="getCategoryLabel(model.category) || '--'" />
|
<ReadonlyField :value="getCategoryLabel(model.category) || '--'" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
|
<ElFormItem label="来源业务编号">
|
||||||
|
<ReadonlyField v-if="isViewMode" :value="model.sourceBizCode || '--'" />
|
||||||
|
<ElInput
|
||||||
|
v-else
|
||||||
|
v-model="model.sourceBizCode"
|
||||||
|
clearable
|
||||||
|
maxlength="128"
|
||||||
|
placeholder="请输入来源业务编号"
|
||||||
|
/>
|
||||||
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label="提出人" prop="proposerId">
|
<ElFormItem label="提出人" prop="proposerId">
|
||||||
<ReadonlyField :value="allUserLabelMap.get(model.proposerId) || '--'" />
|
<ReadonlyField :value="allUserLabelMap.get(model.proposerId) || '--'" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, h, onMounted, ref } from 'vue';
|
import { computed, h, onMounted, ref } from 'vue';
|
||||||
import { RDMS_REQ_SOURCE_TYPE_DICT_CODE } from '@/constants/dict';
|
// import { RDMS_REQ_SOURCE_TYPE_DICT_CODE } from '@/constants/dict';
|
||||||
import { fetchGetRequirementStatusDict } from '@/service/api';
|
import { fetchGetRequirementStatusDict } from '@/service/api';
|
||||||
import { useDict } from '@/hooks/business/dict';
|
// import { useDict } from '@/hooks/business/dict';
|
||||||
import TableSearchFields from '@/components/custom/table-search-fields.vue';
|
import TableSearchFields from '@/components/custom/table-search-fields.vue';
|
||||||
import MemberSelectOption from './member-select-option.vue';
|
import MemberSelectOption from './member-select-option.vue';
|
||||||
|
|
||||||
@@ -32,17 +32,15 @@ const emit = defineEmits<Emits>();
|
|||||||
const model = defineModel<Api.Product.RequirementSearchParams>('model', { required: true });
|
const model = defineModel<Api.Product.RequirementSearchParams>('model', { required: true });
|
||||||
|
|
||||||
const requirementStatusOptions = ref<Array<{ label: string; value: string }>>([]);
|
const requirementStatusOptions = ref<Array<{ label: string; value: string }>>([]);
|
||||||
|
// const { enabledDictData: sourceTypeDictData } = useDict(RDMS_REQ_SOURCE_TYPE_DICT_CODE);
|
||||||
const { enabledDictData: sourceTypeDictData } = useDict(RDMS_REQ_SOURCE_TYPE_DICT_CODE);
|
// const sourceTypeOptions = computed(() => {
|
||||||
|
// return sourceTypeDictData.value
|
||||||
const sourceTypeOptions = computed(() => {
|
// .filter(item => item.value !== 'product_requirement')
|
||||||
return sourceTypeDictData.value
|
// .map(item => ({
|
||||||
.filter(item => item.value !== 'product_requirement')
|
// label: item.label,
|
||||||
.map(item => ({
|
// value: item.value
|
||||||
label: item.label,
|
// }));
|
||||||
value: item.value
|
// });
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
const memberSelectOptions = computed(() => {
|
const memberSelectOptions = computed(() => {
|
||||||
return props.memberOptions.map(item => ({
|
return props.memberOptions.map(item => ({
|
||||||
@@ -105,12 +103,18 @@ const fields = computed(() => [
|
|||||||
dictCode: props.categoryDictCode,
|
dictCode: props.categoryDictCode,
|
||||||
placeholder: '筛选需求类型'
|
placeholder: '筛选需求类型'
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// key: 'sourceType',
|
||||||
|
// label: '需求来源',
|
||||||
|
// type: 'select' as const,
|
||||||
|
// placeholder: '筛选需求来源',
|
||||||
|
// options: sourceTypeOptions.value
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
key: 'sourceType',
|
key: 'sourceBizCode',
|
||||||
label: '需求来源',
|
label: '业务编号',
|
||||||
type: 'select' as const,
|
type: 'input' as const,
|
||||||
placeholder: '筛选需求来源',
|
placeholder: '输入来源业务编号'
|
||||||
options: sourceTypeOptions.value
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'currentHandlerUserId',
|
key: 'currentHandlerUserId',
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import dayjs from 'dayjs';
|
|||||||
import {
|
import {
|
||||||
RDMS_REQ_CAN_DELETE_STATUS_DICT_CODE,
|
RDMS_REQ_CAN_DELETE_STATUS_DICT_CODE,
|
||||||
RDMS_REQ_CATEGORY_DICT_CODE,
|
RDMS_REQ_CATEGORY_DICT_CODE,
|
||||||
RDMS_REQ_PRIORITY_DICT_CODE,
|
RDMS_REQ_PRIORITY_DICT_CODE
|
||||||
RDMS_REQ_SOURCE_TYPE_DICT_CODE
|
|
||||||
} from '@/constants/dict';
|
} from '@/constants/dict';
|
||||||
import { getStatusTagType } from '@/constants/status-tag';
|
import { getStatusTagType } from '@/constants/status-tag';
|
||||||
import {
|
import {
|
||||||
@@ -21,7 +20,6 @@ import {
|
|||||||
import { useAuth } from '@/hooks/business/auth';
|
import { useAuth } from '@/hooks/business/auth';
|
||||||
import { useDict } from '@/hooks/business/dict';
|
import { useDict } from '@/hooks/business/dict';
|
||||||
import DictTag from '@/components/custom/dict-tag.vue';
|
import DictTag from '@/components/custom/dict-tag.vue';
|
||||||
import DictText from '@/components/custom/dict-text.vue';
|
|
||||||
import { useCurrentProject } from '../../shared/use-current-project';
|
import { useCurrentProject } from '../../shared/use-current-project';
|
||||||
import {
|
import {
|
||||||
ACTION_ICON_MAP,
|
ACTION_ICON_MAP,
|
||||||
@@ -78,7 +76,7 @@ function createSearchParams(): Api.Project.ProjectRequirementSearchParams {
|
|||||||
priority: undefined,
|
priority: undefined,
|
||||||
statusCode: undefined,
|
statusCode: undefined,
|
||||||
currentHandlerUserId: undefined,
|
currentHandlerUserId: undefined,
|
||||||
sourceType: undefined
|
sourceBizCode: undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,15 +384,15 @@ const columns = computed(() => [
|
|||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
formatter: (row: Api.Project.ProjectRequirement) => row.categoryName || row.category || '--'
|
formatter: (row: Api.Project.ProjectRequirement) => row.categoryName || row.category || '--'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
prop: 'sourceType',
|
// prop: 'sourceType',
|
||||||
label: '需求来源',
|
// label: '需求来源',
|
||||||
minWidth: 110,
|
// minWidth: 110,
|
||||||
align: 'center',
|
// align: 'center',
|
||||||
formatter: (row: Api.Project.ProjectRequirement) => (
|
// formatter: (row: Api.Project.ProjectRequirement) => (
|
||||||
<DictText dictCode={RDMS_REQ_SOURCE_TYPE_DICT_CODE} value={row.sourceType} />
|
// <DictText dictCode={RDMS_REQ_SOURCE_TYPE_DICT_CODE} value={row.sourceType} />
|
||||||
)
|
// )
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
prop: 'proposerNickname',
|
prop: 'proposerNickname',
|
||||||
label: '提出人',
|
label: '提出人',
|
||||||
@@ -408,15 +406,15 @@ const columns = computed(() => [
|
|||||||
formatter: (row: Api.Project.ProjectRequirement) => getMemberLabel(row.currentHandlerUserId)
|
formatter: (row: Api.Project.ProjectRequirement) => getMemberLabel(row.currentHandlerUserId)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: 'sourceBizId',
|
prop: 'sourceBizCode',
|
||||||
label: '来源业务编号',
|
label: '来源业务编号',
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
formatter: (row: Api.Project.ProjectRequirement) => {
|
formatter: (row: Api.Project.ProjectRequirement) => {
|
||||||
if (!row.sourceBizId || row.sourceType === 'manual') {
|
if (!row.sourceBizCode) {
|
||||||
return '--';
|
return '--';
|
||||||
}
|
}
|
||||||
|
|
||||||
return row.sourceBizId;
|
return row.sourceBizCode;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -552,7 +550,7 @@ async function loadTreeData() {
|
|||||||
priority: searchParams.priority,
|
priority: searchParams.priority,
|
||||||
statusCode: searchParams.statusCode,
|
statusCode: searchParams.statusCode,
|
||||||
currentHandlerUserId: searchParams.currentHandlerUserId,
|
currentHandlerUserId: searchParams.currentHandlerUserId,
|
||||||
sourceType: searchParams.sourceType
|
sourceBizCode: searchParams.sourceBizCode?.trim() || undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error || !data) {
|
if (error || !data) {
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ interface Model {
|
|||||||
moduleId: string | null;
|
moduleId: string | null;
|
||||||
category: string;
|
category: string;
|
||||||
priority: string | null;
|
priority: string | null;
|
||||||
|
sourceBizCode: string;
|
||||||
expectedTime: string | null;
|
expectedTime: string | null;
|
||||||
proposerId: string;
|
proposerId: string;
|
||||||
currentHandlerUserId: string;
|
currentHandlerUserId: string;
|
||||||
@@ -141,6 +142,7 @@ function createDefaultModel(): Model {
|
|||||||
moduleId: props.defaultModuleId || null,
|
moduleId: props.defaultModuleId || null,
|
||||||
category: '功能需求',
|
category: '功能需求',
|
||||||
priority: '3',
|
priority: '3',
|
||||||
|
sourceBizCode: '',
|
||||||
expectedTime: null,
|
expectedTime: null,
|
||||||
proposerId: '',
|
proposerId: '',
|
||||||
currentHandlerUserId: '',
|
currentHandlerUserId: '',
|
||||||
@@ -202,6 +204,7 @@ async function handleSubmit() {
|
|||||||
attachments: [...model.value.attachments],
|
attachments: [...model.value.attachments],
|
||||||
category: model.value.category,
|
category: model.value.category,
|
||||||
priority: Number(model.value.priority) as Api.Project.ProjectRequirementPriority,
|
priority: Number(model.value.priority) as Api.Project.ProjectRequirementPriority,
|
||||||
|
sourceBizCode: model.value.sourceBizCode.trim() || null,
|
||||||
expectedTime: model.value.expectedTime,
|
expectedTime: model.value.expectedTime,
|
||||||
proposerId: model.value.proposerId,
|
proposerId: model.value.proposerId,
|
||||||
proposerNickname: proposer?.nickname || '',
|
proposerNickname: proposer?.nickname || '',
|
||||||
@@ -309,6 +312,10 @@ watch(
|
|||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
|
<ElFormItem label="来源业务编号">
|
||||||
|
<ElInput v-model="model.sourceBizCode" clearable maxlength="128" placeholder="请输入来源业务编号" />
|
||||||
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label="提出人" prop="proposerId">
|
<ElFormItem label="提出人" prop="proposerId">
|
||||||
<ElSelect v-model="model.proposerId" class="w-full" filterable placeholder="请选择提出人">
|
<ElSelect v-model="model.proposerId" class="w-full" filterable placeholder="请选择提出人">
|
||||||
<ElOption v-for="item in allUserOptions" :key="item.id" :label="item.nickname" :value="item.id" />
|
<ElOption v-for="item in allUserOptions" :key="item.id" :label="item.nickname" :value="item.id" />
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ interface Model {
|
|||||||
moduleId: string | null;
|
moduleId: string | null;
|
||||||
category: string;
|
category: string;
|
||||||
priority: string | null;
|
priority: string | null;
|
||||||
|
sourceBizCode: string;
|
||||||
expectedTime: string | null;
|
expectedTime: string | null;
|
||||||
proposerId: string;
|
proposerId: string;
|
||||||
proposerNickname: string;
|
proposerNickname: string;
|
||||||
@@ -181,6 +182,7 @@ function createDefaultModel(): Model {
|
|||||||
moduleId: null,
|
moduleId: null,
|
||||||
category: '',
|
category: '',
|
||||||
priority: '3',
|
priority: '3',
|
||||||
|
sourceBizCode: '',
|
||||||
expectedTime: null,
|
expectedTime: null,
|
||||||
proposerId: '',
|
proposerId: '',
|
||||||
proposerNickname: '',
|
proposerNickname: '',
|
||||||
@@ -201,6 +203,30 @@ function mapModuleTree(modules: Api.Project.ProjectRequirementModule[]): Require
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizePriorityValue(priority: Api.Project.ProjectRequirement['priority']) {
|
||||||
|
return priority === null || priority === undefined ? null : String(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformRequirementDetail(data: Api.Project.ProjectRequirement): Model {
|
||||||
|
return {
|
||||||
|
title: data.title || '',
|
||||||
|
description: data.description || null,
|
||||||
|
attachments: data.attachments ? [...data.attachments] : [],
|
||||||
|
reviewRequired: data.reviewRequired ?? 0,
|
||||||
|
moduleId: data.moduleId || null,
|
||||||
|
category: data.category || '',
|
||||||
|
priority: normalizePriorityValue(data.priority),
|
||||||
|
sourceBizCode: data.sourceBizCode || '',
|
||||||
|
expectedTime: formatExpectedTime(data.expectedTime),
|
||||||
|
proposerId: data.proposerId || '',
|
||||||
|
proposerNickname: data.proposerNickname || '',
|
||||||
|
currentHandlerUserId: data.currentHandlerUserId || '',
|
||||||
|
currentHandlerUserNickname: data.currentHandlerUserNickname || '',
|
||||||
|
sort: data.sort ?? 0,
|
||||||
|
lastStatusReason: data.lastStatusReason || ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function loadModuleTree() {
|
async function loadModuleTree() {
|
||||||
if (!props.projectId) {
|
if (!props.projectId) {
|
||||||
moduleTree.value = [];
|
moduleTree.value = [];
|
||||||
@@ -232,22 +258,7 @@ async function loadRequirementDetail() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
model.value = {
|
model.value = transformRequirementDetail(data);
|
||||||
title: data.title || '',
|
|
||||||
description: data.description || null,
|
|
||||||
attachments: data.attachments ? [...data.attachments] : [],
|
|
||||||
reviewRequired: data.reviewRequired ?? 0,
|
|
||||||
moduleId: data.moduleId || null,
|
|
||||||
category: data.category || '',
|
|
||||||
priority: data.priority === null || data.priority === undefined ? null : String(data.priority),
|
|
||||||
expectedTime: formatExpectedTime(data.expectedTime),
|
|
||||||
proposerId: data.proposerId || '',
|
|
||||||
proposerNickname: data.proposerNickname || '',
|
|
||||||
currentHandlerUserId: data.currentHandlerUserId || '',
|
|
||||||
currentHandlerUserNickname: data.currentHandlerUserNickname || '',
|
|
||||||
sort: data.sort ?? 0,
|
|
||||||
lastStatusReason: data.lastStatusReason || ''
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatExpectedTime(value?: string | number[] | null): string | null {
|
function formatExpectedTime(value?: string | number[] | null): string | null {
|
||||||
@@ -294,6 +305,7 @@ async function handleSubmit() {
|
|||||||
attachments: [...model.value.attachments],
|
attachments: [...model.value.attachments],
|
||||||
category: model.value.category,
|
category: model.value.category,
|
||||||
priority: Number(model.value.priority) as Api.Project.ProjectRequirementPriority,
|
priority: Number(model.value.priority) as Api.Project.ProjectRequirementPriority,
|
||||||
|
sourceBizCode: model.value.sourceBizCode.trim() || null,
|
||||||
expectedTime: model.value.expectedTime,
|
expectedTime: model.value.expectedTime,
|
||||||
proposerId: model.value.proposerId,
|
proposerId: model.value.proposerId,
|
||||||
proposerNickname: model.value.proposerNickname,
|
proposerNickname: model.value.proposerNickname,
|
||||||
@@ -401,6 +413,17 @@ watch(
|
|||||||
<ReadonlyField :value="getCategoryLabel(model.category) || '--'" />
|
<ReadonlyField :value="getCategoryLabel(model.category) || '--'" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
|
<ElFormItem label="来源业务编号">
|
||||||
|
<ReadonlyField v-if="isViewMode" :value="model.sourceBizCode || '--'" />
|
||||||
|
<ElInput
|
||||||
|
v-else
|
||||||
|
v-model="model.sourceBizCode"
|
||||||
|
clearable
|
||||||
|
maxlength="128"
|
||||||
|
placeholder="请输入来源业务编号"
|
||||||
|
/>
|
||||||
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label="提出人" prop="proposerId">
|
<ElFormItem label="提出人" prop="proposerId">
|
||||||
<ReadonlyField :value="allUserLabelMap.get(model.proposerId) || '--'" />
|
<ReadonlyField :value="allUserLabelMap.get(model.proposerId) || '--'" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, h, onMounted, ref } from 'vue';
|
import { computed, h, onMounted, ref } from 'vue';
|
||||||
import { RDMS_REQ_SOURCE_TYPE_DICT_CODE } from '@/constants/dict';
|
// import { RDMS_REQ_SOURCE_TYPE_DICT_CODE } from '@/constants/dict';
|
||||||
import { fetchGetProjectRequirementStatusDict } from '@/service/api';
|
import { fetchGetProjectRequirementStatusDict } from '@/service/api';
|
||||||
import { useDict } from '@/hooks/business/dict';
|
// import { useDict } from '@/hooks/business/dict';
|
||||||
import TableSearchFields from '@/components/custom/table-search-fields.vue';
|
import TableSearchFields from '@/components/custom/table-search-fields.vue';
|
||||||
import MemberSelectOption from './member-select-option.vue';
|
import MemberSelectOption from './member-select-option.vue';
|
||||||
|
|
||||||
@@ -32,15 +32,13 @@ const emit = defineEmits<Emits>();
|
|||||||
const model = defineModel<Api.Project.ProjectRequirementSearchParams>('model', { required: true });
|
const model = defineModel<Api.Project.ProjectRequirementSearchParams>('model', { required: true });
|
||||||
|
|
||||||
const requirementStatusOptions = ref<Array<{ label: string; value: string }>>([]);
|
const requirementStatusOptions = ref<Array<{ label: string; value: string }>>([]);
|
||||||
|
// const { enabledDictData: sourceTypeDictData } = useDict(RDMS_REQ_SOURCE_TYPE_DICT_CODE);
|
||||||
const { enabledDictData: sourceTypeDictData } = useDict(RDMS_REQ_SOURCE_TYPE_DICT_CODE);
|
// const sourceTypeOptions = computed(() => {
|
||||||
|
// return sourceTypeDictData.value.map(item => ({
|
||||||
const sourceTypeOptions = computed(() => {
|
// label: item.label,
|
||||||
return sourceTypeDictData.value.map(item => ({
|
// value: item.value
|
||||||
label: item.label,
|
// }));
|
||||||
value: item.value
|
// });
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
const memberSelectOptions = computed(() => {
|
const memberSelectOptions = computed(() => {
|
||||||
return props.memberOptions.map(item => ({
|
return props.memberOptions.map(item => ({
|
||||||
@@ -103,12 +101,18 @@ const fields = computed(() => [
|
|||||||
dictCode: props.categoryDictCode,
|
dictCode: props.categoryDictCode,
|
||||||
placeholder: '筛选需求类型'
|
placeholder: '筛选需求类型'
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// key: 'sourceType',
|
||||||
|
// label: '需求来源',
|
||||||
|
// type: 'select' as const,
|
||||||
|
// placeholder: '筛选需求来源',
|
||||||
|
// options: sourceTypeOptions.value
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
key: 'sourceType',
|
key: 'sourceBizCode',
|
||||||
label: '需求来源',
|
label: '业务编号',
|
||||||
type: 'select' as const,
|
type: 'input' as const,
|
||||||
placeholder: '筛选需求来源',
|
placeholder: '输入来源业务编号'
|
||||||
options: sourceTypeOptions.value
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'currentHandlerUserId',
|
key: 'currentHandlerUserId',
|
||||||
|
|||||||
Reference in New Issue
Block a user