204 lines
6.8 KiB
Vue
204 lines
6.8 KiB
Vue
|
|
<script setup lang="ts">
|
||
|
|
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 { getPreviousManagerRoleOptions, shouldRequireManagerHandover } from '../shared';
|
||
|
|
|
||
|
|
defineOptions({ name: 'MemberOperateDialog' });
|
||
|
|
|
||
|
|
type OperateMode = 'create' | 'edit';
|
||
|
|
|
||
|
|
interface Props {
|
||
|
|
mode: OperateMode;
|
||
|
|
member: Api.Product.ProductMember | null;
|
||
|
|
currentManager: Api.Product.ProductMember | null;
|
||
|
|
roleOptions: Api.SystemManage.RoleSimple[];
|
||
|
|
userOptions: Api.SystemManage.UserSimple[];
|
||
|
|
}
|
||
|
|
|
||
|
|
interface SubmitPayload {
|
||
|
|
mode: OperateMode;
|
||
|
|
memberId?: string;
|
||
|
|
managerChanged: boolean;
|
||
|
|
payload: Api.Product.CreateProductMemberParams | Api.Product.UpdateProductMemberParams;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface Emits {
|
||
|
|
(e: 'submit', payload: SubmitPayload): void;
|
||
|
|
}
|
||
|
|
|
||
|
|
const props = defineProps<Props>();
|
||
|
|
const emit = defineEmits<Emits>();
|
||
|
|
|
||
|
|
const visible = defineModel<boolean>('visible', {
|
||
|
|
default: false
|
||
|
|
});
|
||
|
|
|
||
|
|
const { formRef, validate } = useForm();
|
||
|
|
const { createRequiredRule } = useFormRules();
|
||
|
|
|
||
|
|
interface Model {
|
||
|
|
userId: string;
|
||
|
|
roleId: string;
|
||
|
|
remark: string;
|
||
|
|
reason: string;
|
||
|
|
previousManagerRoleId: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
const model = reactive<Model>({
|
||
|
|
userId: '',
|
||
|
|
roleId: '',
|
||
|
|
remark: '',
|
||
|
|
reason: '',
|
||
|
|
previousManagerRoleId: ''
|
||
|
|
});
|
||
|
|
|
||
|
|
const dialogTitle = computed(() => (props.mode === 'create' ? '新增团队成员' : '调整成员角色'));
|
||
|
|
const selectedUserId = computed(() => (props.mode === 'create' ? model.userId : props.member?.userId || ''));
|
||
|
|
const showManagerHandover = computed(() => {
|
||
|
|
return (
|
||
|
|
shouldRequireManagerHandover(model.roleId, props.currentManager) &&
|
||
|
|
Boolean(selectedUserId.value) &&
|
||
|
|
selectedUserId.value !== props.currentManager?.userId
|
||
|
|
);
|
||
|
|
});
|
||
|
|
const previousManagerRoleOptions = computed(() =>
|
||
|
|
getPreviousManagerRoleOptions(props.roleOptions, props.currentManager?.roleId || '')
|
||
|
|
);
|
||
|
|
const userLabelMap = computed(() => new Map(props.userOptions.map(item => [item.id, item.nickname])));
|
||
|
|
|
||
|
|
const rules = computed(
|
||
|
|
() =>
|
||
|
|
({
|
||
|
|
userId: props.mode === 'create' ? [createRequiredRule('请选择成员用户')] : [],
|
||
|
|
roleId: [createRequiredRule('请选择角色')],
|
||
|
|
previousManagerRoleId: showManagerHandover.value ? [createRequiredRule('请选择原产品经理交接后角色')] : []
|
||
|
|
}) satisfies Record<string, App.Global.FormRule[]>
|
||
|
|
);
|
||
|
|
|
||
|
|
async function handleConfirm() {
|
||
|
|
await validate();
|
||
|
|
|
||
|
|
const sharedPayload = {
|
||
|
|
roleId: model.roleId,
|
||
|
|
remark: model.remark.trim() || null,
|
||
|
|
previousManagerUserId: showManagerHandover.value ? props.currentManager?.userId || null : null,
|
||
|
|
previousManagerRoleId: showManagerHandover.value ? model.previousManagerRoleId : null
|
||
|
|
};
|
||
|
|
|
||
|
|
if (props.mode === 'create') {
|
||
|
|
emit('submit', {
|
||
|
|
mode: 'create',
|
||
|
|
managerChanged: showManagerHandover.value,
|
||
|
|
payload: {
|
||
|
|
userId: model.userId,
|
||
|
|
roleId: sharedPayload.roleId,
|
||
|
|
remark: sharedPayload.remark,
|
||
|
|
previousManagerUserId: sharedPayload.previousManagerUserId,
|
||
|
|
previousManagerRoleId: sharedPayload.previousManagerRoleId
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
emit('submit', {
|
||
|
|
mode: 'edit',
|
||
|
|
memberId: props.member?.id,
|
||
|
|
managerChanged: showManagerHandover.value,
|
||
|
|
payload: {
|
||
|
|
roleId: sharedPayload.roleId,
|
||
|
|
remark: sharedPayload.remark,
|
||
|
|
reason: model.reason.trim() || null,
|
||
|
|
previousManagerUserId: sharedPayload.previousManagerUserId,
|
||
|
|
previousManagerRoleId: sharedPayload.previousManagerRoleId
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
watch(
|
||
|
|
() => visible.value,
|
||
|
|
async value => {
|
||
|
|
if (!value) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
model.userId = props.mode === 'create' ? '' : props.member?.userId || '';
|
||
|
|
model.roleId = props.mode === 'create' ? '' : props.member?.roleId || '';
|
||
|
|
model.remark = props.mode === 'create' ? '' : props.member?.remark || '';
|
||
|
|
model.reason = '';
|
||
|
|
model.previousManagerRoleId = '';
|
||
|
|
|
||
|
|
await nextTick();
|
||
|
|
formRef.value?.clearValidate();
|
||
|
|
}
|
||
|
|
);
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<BusinessFormDialog v-model="visible" :title="dialogTitle" preset="lg" @confirm="handleConfirm">
|
||
|
|
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
|
||
|
|
<BusinessFormSection title="成员信息">
|
||
|
|
<ElRow :gutter="16">
|
||
|
|
<ElCol :span="12">
|
||
|
|
<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>
|
||
|
|
</ElFormItem>
|
||
|
|
<ElFormItem v-else label="成员用户">
|
||
|
|
<ElInput :model-value="member?.userNickname || userLabelMap.get(member?.userId || '') || ''" readonly />
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<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" />
|
||
|
|
</ElSelect>
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="24">
|
||
|
|
<ElFormItem label="备注">
|
||
|
|
<ElInput
|
||
|
|
v-model="model.remark"
|
||
|
|
type="textarea"
|
||
|
|
:rows="3"
|
||
|
|
maxlength="500"
|
||
|
|
show-word-limit
|
||
|
|
placeholder="请输入备注"
|
||
|
|
/>
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
</ElRow>
|
||
|
|
</BusinessFormSection>
|
||
|
|
|
||
|
|
<BusinessFormSection v-if="mode === 'edit'" title="角色调整说明">
|
||
|
|
<ElFormItem label="变更原因">
|
||
|
|
<ElInput
|
||
|
|
v-model="model.reason"
|
||
|
|
type="textarea"
|
||
|
|
:rows="3"
|
||
|
|
maxlength="500"
|
||
|
|
show-word-limit
|
||
|
|
placeholder="请输入变更原因"
|
||
|
|
/>
|
||
|
|
</ElFormItem>
|
||
|
|
</BusinessFormSection>
|
||
|
|
|
||
|
|
<BusinessFormSection v-if="showManagerHandover" title="产品经理交接">
|
||
|
|
<ElAlert
|
||
|
|
:title="`当前产品经理 ${currentManager?.userNickname || currentManager?.userId || ''} 将完成交接,请选择其交接后角色。`"
|
||
|
|
type="warning"
|
||
|
|
:closable="false"
|
||
|
|
class="mb-16px"
|
||
|
|
/>
|
||
|
|
<ElFormItem label="原产品经理交接后角色" prop="previousManagerRoleId">
|
||
|
|
<ElSelect v-model="model.previousManagerRoleId" class="w-full" placeholder="请选择原产品经理交接后角色">
|
||
|
|
<ElOption v-for="item in previousManagerRoleOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||
|
|
</ElSelect>
|
||
|
|
</ElFormItem>
|
||
|
|
</BusinessFormSection>
|
||
|
|
</ElForm>
|
||
|
|
</BusinessFormDialog>
|
||
|
|
</template>
|