Files
cn-rdms-web/src/views/product/setting/modules/base-info-dialog.vue

219 lines
6.7 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { computed, nextTick, reactive, watch } from 'vue';
import { RDMS_OBJECT_DIRECTION_DICT_CODE } from '@/constants/dict';
import { useDict } from '@/hooks/business/dict';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import DictSelect from '@/components/custom/dict-select.vue';
import { getProductBaseInfoReadonlyMessage, isProductBaseInfoEditable } from '../shared';
defineOptions({ name: 'BaseInfoDialog' });
interface Props {
baseInfo: Api.Product.ProductSettingBaseInfo | null;
}
interface Emits {
(e: 'submit', payload: Api.Product.UpdateProductSettingBaseInfoParams): void;
}
const props = defineProps<Props>();
const emit = defineEmits<Emits>();
const visible = defineModel<boolean>('visible', {
default: false
});
const { getLabel: getDirectionLabel } = useDict(RDMS_OBJECT_DIRECTION_DICT_CODE);
const { formRef, validate } = useForm();
const { createRequiredRule } = useFormRules();
const model = reactive<Api.Product.UpdateProductSettingBaseInfoParams>({
directionCode: '',
name: '',
description: ''
});
const baseInfoEditable = computed(() => isProductBaseInfoEditable(props.baseInfo?.statusCode));
const readonlyMessage = computed(() => getProductBaseInfoReadonlyMessage(props.baseInfo?.statusCode));
const confirmDisabled = computed(() => {
if (!props.baseInfo) {
return true;
}
return !baseInfoEditable.value;
});
const directionDisplayName = computed(() => {
const directionCode = props.baseInfo?.directionCode;
if (!directionCode) {
return '';
}
return getDirectionLabel(directionCode, directionCode);
});
const rules = {
directionCode: [createRequiredRule('请选择产品方向')],
name: [createRequiredRule('请输入产品名称')]
} satisfies Record<string, App.Global.FormRule[]>;
async function handleConfirm() {
if (confirmDisabled.value) {
return;
}
await validate();
emit('submit', {
directionCode: model.directionCode,
name: model.name.trim(),
description: model.description?.trim() || null
});
}
watch(
() => visible.value,
async value => {
if (!value || !props.baseInfo) {
return;
}
model.directionCode = props.baseInfo.directionCode || '';
model.name = props.baseInfo.name || '';
model.description = props.baseInfo.description || '';
await nextTick();
formRef.value?.clearValidate();
}
);
</script>
<template>
<BusinessFormDialog
v-model="visible"
title="编辑基础信息"
preset="lg"
:confirm-disabled="confirmDisabled"
@confirm="handleConfirm"
>
<ElAlert v-if="readonlyMessage" :title="readonlyMessage" type="warning" :closable="false" class="mb-16px" />
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
<ElRow :gutter="16">
<ElCol :span="12">
<ElFormItem label="产品编码">
<ElInput :model-value="baseInfo?.code || ''" readonly class="base-info-dialog__readonly-input" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem>
<template #label>
<span class="business-form-label-with-tip">
<ElTooltip
content="如需调整产品经理,请到产品内的团队管理处处理。"
popper-class="business-form-label-tooltip"
placement="top-start"
>
<span class="business-form-label-tip">
<icon-fe:question />
</span>
</ElTooltip>
<span>产品经理</span>
</span>
</template>
<ElInput
:model-value="baseInfo?.managerUserNickname || baseInfo?.managerUserId || ''"
readonly
class="base-info-dialog__readonly-input"
/>
</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
v-if="baseInfoEditable"
v-model="model.description"
type="textarea"
:rows="4"
maxlength="500"
show-word-limit
placeholder="请输入产品描述"
/>
<ElInput
v-else
:model-value="model.description"
type="textarea"
:rows="4"
readonly
class="base-info-dialog__readonly-input"
placeholder="未填写产品描述"
/>
</ElFormItem>
</ElCol>
</ElRow>
</ElForm>
</BusinessFormDialog>
</template>
<style scoped>
:deep(.base-info-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(.base-info-dialog__readonly-input .el-textarea__inner) {
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;
resize: none;
}
:deep(.base-info-dialog__readonly-input .el-input__wrapper:hover),
:deep(.base-info-dialog__readonly-input.is-focus .el-input__wrapper),
:deep(.base-info-dialog__readonly-input .el-textarea__inner:hover),
:deep(.base-info-dialog__readonly-input .el-textarea__inner:focus) {
box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
}
:deep(.base-info-dialog__readonly-input .el-input__inner),
:deep(.base-info-dialog__readonly-input .el-textarea__inner) {
color: rgb(51 65 85 / 96%);
cursor: default;
-webkit-text-fill-color: rgb(51 65 85 / 96%);
}
</style>