235 lines
6.8 KiB
Vue
235 lines
6.8 KiB
Vue
|
|
<script setup lang="ts">
|
||
|
|
import { computed, nextTick, ref, watch } from 'vue';
|
||
|
|
import { OBJECT_STATUS_MODEL_OBJECT_TYPE_DICT_CODE } from '@/constants/dict';
|
||
|
|
import {
|
||
|
|
fetchCreateObjectStatusTransition,
|
||
|
|
fetchGetObjectStatusTransition,
|
||
|
|
fetchUpdateObjectStatusTransition
|
||
|
|
} from '@/service/api';
|
||
|
|
import { useDict } from '@/hooks/business/dict';
|
||
|
|
import { useForm, useFormRules } from '@/hooks/common/form';
|
||
|
|
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
|
||
|
|
import { statusOptions } from '../shared';
|
||
|
|
|
||
|
|
defineOptions({ name: 'StateTransitionOperateDialog' });
|
||
|
|
|
||
|
|
interface Props {
|
||
|
|
operateType: UI.TableOperateType;
|
||
|
|
rowData?: Api.Infra.ObjectStatusTransition | null;
|
||
|
|
currentStatus?: Api.Infra.ObjectStatusModel | null;
|
||
|
|
targetStatusOptions: Array<{ label: string; value: string }>;
|
||
|
|
}
|
||
|
|
|
||
|
|
const props = defineProps<Props>();
|
||
|
|
|
||
|
|
const emit = defineEmits<{
|
||
|
|
submitted: [transitionId: string];
|
||
|
|
}>();
|
||
|
|
|
||
|
|
const visible = defineModel<boolean>('visible', {
|
||
|
|
default: false
|
||
|
|
});
|
||
|
|
|
||
|
|
const { formRef, validate } = useForm();
|
||
|
|
const { createRequiredRule } = useFormRules();
|
||
|
|
const { getLabel: getObjectTypeLabel } = useDict(OBJECT_STATUS_MODEL_OBJECT_TYPE_DICT_CODE);
|
||
|
|
|
||
|
|
const detailLoading = ref(false);
|
||
|
|
const submitting = ref(false);
|
||
|
|
const isEdit = computed(() => props.operateType === 'edit');
|
||
|
|
|
||
|
|
const title = computed(() => {
|
||
|
|
const titleMap: Record<UI.TableOperateType, string> = {
|
||
|
|
add: '新增状态流转',
|
||
|
|
edit: '编辑状态流转'
|
||
|
|
};
|
||
|
|
|
||
|
|
return titleMap[props.operateType];
|
||
|
|
});
|
||
|
|
|
||
|
|
type Model = Api.Infra.SaveObjectStatusTransitionParams;
|
||
|
|
|
||
|
|
const model = ref(createDefaultModel());
|
||
|
|
|
||
|
|
const currentObjectTypeLabel = computed(() => getObjectTypeLabel(model.value.objectType));
|
||
|
|
|
||
|
|
const currentFromStatusLabel = computed(() => {
|
||
|
|
if (!props.currentStatus) {
|
||
|
|
return model.value.fromStatusCode || '--';
|
||
|
|
}
|
||
|
|
|
||
|
|
return `${props.currentStatus.statusName} (${props.currentStatus.statusCode})`;
|
||
|
|
});
|
||
|
|
|
||
|
|
function createDefaultModel(): Model {
|
||
|
|
return {
|
||
|
|
objectType: props.currentStatus?.objectType ?? 'product',
|
||
|
|
actionCode: '',
|
||
|
|
actionName: '',
|
||
|
|
fromStatusCode: props.currentStatus?.statusCode ?? '',
|
||
|
|
toStatusCode: '',
|
||
|
|
needReason: false,
|
||
|
|
status: 0,
|
||
|
|
remark: ''
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const rules = {
|
||
|
|
actionCode: createRequiredRule('请输入动作编码'),
|
||
|
|
actionName: createRequiredRule('请输入动作名称'),
|
||
|
|
toStatusCode: createRequiredRule('请选择目标状态'),
|
||
|
|
status: createRequiredRule('请选择配置状态')
|
||
|
|
} satisfies Record<string, App.Global.FormRule>;
|
||
|
|
|
||
|
|
function closeModal() {
|
||
|
|
visible.value = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
async function initModel() {
|
||
|
|
model.value = createDefaultModel();
|
||
|
|
|
||
|
|
if (!isEdit.value || !props.rowData) {
|
||
|
|
await nextTick();
|
||
|
|
formRef.value?.clearValidate();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
detailLoading.value = true;
|
||
|
|
|
||
|
|
const { error, data } = await fetchGetObjectStatusTransition(props.rowData.id);
|
||
|
|
|
||
|
|
detailLoading.value = false;
|
||
|
|
|
||
|
|
if (!error) {
|
||
|
|
model.value = {
|
||
|
|
objectType: data.objectType,
|
||
|
|
actionCode: data.actionCode,
|
||
|
|
actionName: data.actionName,
|
||
|
|
fromStatusCode: data.fromStatusCode,
|
||
|
|
toStatusCode: data.toStatusCode,
|
||
|
|
needReason: data.needReason,
|
||
|
|
status: data.status,
|
||
|
|
remark: data.remark ?? ''
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
await nextTick();
|
||
|
|
formRef.value?.clearValidate();
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleSubmit() {
|
||
|
|
await validate();
|
||
|
|
|
||
|
|
submitting.value = true;
|
||
|
|
|
||
|
|
const submitData: Api.Infra.SaveObjectStatusTransitionParams = {
|
||
|
|
...model.value,
|
||
|
|
objectType: props.currentStatus?.objectType ?? model.value.objectType,
|
||
|
|
fromStatusCode: props.currentStatus?.statusCode ?? model.value.fromStatusCode,
|
||
|
|
actionCode: model.value.actionCode.trim(),
|
||
|
|
actionName: model.value.actionName.trim(),
|
||
|
|
remark: model.value.remark?.trim() || null
|
||
|
|
};
|
||
|
|
|
||
|
|
let transitionId = props.rowData?.id ?? '';
|
||
|
|
|
||
|
|
if (isEdit.value && props.rowData) {
|
||
|
|
const { error } = await fetchUpdateObjectStatusTransition({ id: props.rowData.id, ...submitData });
|
||
|
|
|
||
|
|
submitting.value = false;
|
||
|
|
|
||
|
|
if (error) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
const { error, data } = await fetchCreateObjectStatusTransition(submitData);
|
||
|
|
|
||
|
|
submitting.value = false;
|
||
|
|
|
||
|
|
if (error) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
transitionId = data;
|
||
|
|
}
|
||
|
|
|
||
|
|
window.$message?.success(isEdit.value ? '修改成功' : '新增成功');
|
||
|
|
|
||
|
|
closeModal();
|
||
|
|
emit('submitted', transitionId);
|
||
|
|
}
|
||
|
|
|
||
|
|
watch(visible, value => {
|
||
|
|
if (value) {
|
||
|
|
initModel();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<BusinessFormDialog
|
||
|
|
v-model="visible"
|
||
|
|
:title="title"
|
||
|
|
preset="md"
|
||
|
|
:loading="detailLoading"
|
||
|
|
:confirm-loading="submitting"
|
||
|
|
@confirm="handleSubmit"
|
||
|
|
>
|
||
|
|
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
|
||
|
|
<ElRow :gutter="16">
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="对象类型">
|
||
|
|
<ElInput :model-value="currentObjectTypeLabel" readonly />
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="起始状态">
|
||
|
|
<ElInput :model-value="currentFromStatusLabel" readonly />
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="动作编码" prop="actionCode">
|
||
|
|
<ElInput v-model="model.actionCode" placeholder="请输入动作编码" />
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="动作名称" prop="actionName">
|
||
|
|
<ElInput v-model="model.actionName" placeholder="请输入动作名称" />
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="目标状态" prop="toStatusCode">
|
||
|
|
<ElSelect v-model="model.toStatusCode" class="w-full" placeholder="请选择目标状态">
|
||
|
|
<ElOption v-for="{ label, value } in targetStatusOptions" :key="value" :label="label" :value="value" />
|
||
|
|
</ElSelect>
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="配置状态" prop="status">
|
||
|
|
<ElRadioGroup v-model="model.status" class="business-form-radio-group">
|
||
|
|
<ElRadio v-for="{ label, value } in statusOptions" :key="value" :value="value">
|
||
|
|
{{ label }}
|
||
|
|
</ElRadio>
|
||
|
|
</ElRadioGroup>
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="12">
|
||
|
|
<ElFormItem label="必须填写原因" prop="needReason">
|
||
|
|
<div class="business-form-switch-field">
|
||
|
|
<ElSwitch v-model="model.needReason" />
|
||
|
|
<span class="ml-8px text-12px text-[#606266]">{{ model.needReason ? '是' : '否' }}</span>
|
||
|
|
</div>
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
<ElCol :span="24">
|
||
|
|
<ElFormItem label="备注" prop="remark">
|
||
|
|
<ElInput v-model="model.remark" type="textarea" :rows="4" placeholder="请输入备注" />
|
||
|
|
</ElFormItem>
|
||
|
|
</ElCol>
|
||
|
|
</ElRow>
|
||
|
|
</ElForm>
|
||
|
|
</BusinessFormDialog>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<style scoped></style>
|