Files
cn-rdms-web/src/views/product/setting/modules/member-operate-dialog.vue

204 lines
6.8 KiB
Vue
Raw Normal View History

<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>