feat(projects): 新增项目、执行、任务等功能

This commit is contained in:
2026-05-09 11:30:34 +08:00
parent f4f43814b3
commit 824392b564
106 changed files with 13060 additions and 1049 deletions

View File

@@ -423,7 +423,9 @@ watch(
:member="selectedMember"
:current-manager="currentManager"
:role-options="roleOptions"
:user-options="userOptions"
:user-options="
userOptions.filter(user => !members.some(member => member.status === 0 && member.userId === user.id))
"
@submit="handleSubmitMemberOperate"
/>
<MemberRemoveDialog

View File

@@ -95,7 +95,7 @@ watch(
<BusinessFormDialog
v-model="visible"
title="编辑基础信息"
preset="lg"
preset="sm"
:confirm-disabled="confirmDisabled"
@confirm="handleConfirm"
>
@@ -103,12 +103,42 @@ watch(
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
<ElRow :gutter="16">
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem label="产品编码">
<ElInput :model-value="baseInfo?.code || ''" readonly class="base-info-dialog__readonly-input" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem label="产品名称" prop="name">
<ElInput v-if="baseInfoEditable" v-model="model.name" maxlength="128" placeholder="请输入产品名称" />
<ElInput
v-else
:model-value="model.name"
readonly
class="base-info-dialog__readonly-input"
placeholder="未获取到产品名称"
/>
</ElFormItem>
</ElCol>
<ElCol :span="24">
<ElFormItem label="产品方向" prop="directionCode">
<DictSelect
v-if="baseInfoEditable"
v-model="model.directionCode"
:dict-code="RDMS_OBJECT_DIRECTION_DICT_CODE"
filterable
placeholder="请选择产品方向"
/>
<ElInput
v-else
:model-value="directionDisplayName"
readonly
class="base-info-dialog__readonly-input"
placeholder="未获取到产品方向"
/>
</ElFormItem>
</ElCol>
<ElCol :span="24">
<ElFormItem>
<template #label>
<span class="business-form-label-with-tip">
@@ -131,36 +161,6 @@ watch(
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="产品名称" prop="name">
<ElInput v-if="baseInfoEditable" v-model="model.name" maxlength="128" placeholder="请输入产品名称" />
<ElInput
v-else
:model-value="model.name"
readonly
class="base-info-dialog__readonly-input"
placeholder="未获取到产品名称"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="产品方向" prop="directionCode">
<DictSelect
v-if="baseInfoEditable"
v-model="model.directionCode"
:dict-code="RDMS_OBJECT_DIRECTION_DICT_CODE"
filterable
placeholder="请选择产品方向"
/>
<ElInput
v-else
:model-value="directionDisplayName"
readonly
class="base-info-dialog__readonly-input"
placeholder="未获取到产品方向"
/>
</ElFormItem>
</ElCol>
<ElCol :span="24">
<ElFormItem label="产品描述">
<ElInput

View File

@@ -3,6 +3,7 @@ import { computed, nextTick, reactive, watch } from 'vue';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import BusinessFormSection from '@/components/custom/business-form-section.vue';
import BusinessUserSelect from '@/components/custom/business-user-select.vue';
import { getPreviousManagerRoleOptions, shouldRequireManagerHandover } from '../shared';
defineOptions({ name: 'MemberOperateDialog' });
@@ -136,21 +137,24 @@ watch(
</script>
<template>
<BusinessFormDialog v-model="visible" :title="dialogTitle" preset="lg" @confirm="handleConfirm">
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
<BusinessFormDialog v-model="visible" :title="dialogTitle" preset="sm" @confirm="handleConfirm">
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top" :validate-on-rule-change="false">
<BusinessFormSection title="成员信息">
<ElRow :gutter="16">
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem v-if="mode === 'create'" label="成员用户" prop="userId">
<ElSelect v-model="model.userId" class="w-full" filterable placeholder="请选择成员用户">
<ElOption v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />
</ElSelect>
<BusinessUserSelect v-model="model.userId" :options="userOptions" placeholder="请选择成员用户" />
</ElFormItem>
<ElFormItem v-else label="成员用户">
<ElInput :model-value="member?.userNickname || userLabelMap.get(member?.userId || '') || ''" readonly />
<ElInput
:model-value="member?.userNickname || userLabelMap.get(member?.userId || '') || ''"
readonly
class="member-operate-dialog__readonly-input"
placeholder="未获取到成员用户"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem label="目标角色" prop="roleId">
<ElSelect v-model="model.roleId" class="w-full" placeholder="请选择角色">
<ElOption v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" />
@@ -201,3 +205,22 @@ watch(
</ElForm>
</BusinessFormDialog>
</template>
<style scoped>
:deep(.member-operate-dialog__readonly-input .el-input__wrapper) {
background: linear-gradient(180deg, rgb(241 245 249 / 98%), rgb(226 232 240 / 94%)), rgb(241 245 249);
box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
cursor: default;
}
:deep(.member-operate-dialog__readonly-input .el-input__wrapper:hover),
:deep(.member-operate-dialog__readonly-input.is-focus .el-input__wrapper) {
box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
}
:deep(.member-operate-dialog__readonly-input .el-input__inner) {
color: rgb(51 65 85 / 96%);
cursor: default;
-webkit-text-fill-color: rgb(51 65 85 / 96%);
}
</style>

View File

@@ -134,7 +134,7 @@ function getMemberStatusTagType(status: Api.Product.ProductMemberStatus) {
:disabled="row.status !== 0 || row.managerFlag"
@click="emit('edit', row)"
>
调整角色
编辑
</ElButton>
<ElButton
v-auth="{ code: 'project:product:update', source: 'object' }"