Files
cn-rdms-web/src/views/personal-center/overtime-application/modules/overtime-application-action-dialog.vue

122 lines
2.7 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';
defineOptions({ name: 'OvertimeApplicationActionDialog' });
type ActionType = 'approve' | 'reject' | 'cancel';
interface Props {
actionType: ActionType;
loading?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
loading: false
});
const emit = defineEmits<{
submit: [reason: string | null];
}>();
const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate } = useForm();
const { createRequiredRule } = useFormRules();
const model = reactive({
reason: ''
});
const title = computed(() => {
const map: Record<ActionType, string> = {
approve: '通过加班申请',
reject: '退回加班申请',
cancel: '撤销加班申请'
};
return map[props.actionType];
});
const reasonLabel = computed(() => {
const map: Record<ActionType, string> = {
approve: '审核意见',
reject: '退回原因',
cancel: '撤销原因'
};
return map[props.actionType];
});
const reasonRequired = computed(() => props.actionType === 'reject');
const reasonPlaceholder = computed(() => {
if (reasonRequired.value) {
return `请输入${reasonLabel.value}`;
}
return props.actionType === 'cancel' ? '可填写撤销原因' : '可填写审核意见';
});
const rules = computed(() => ({
reason: reasonRequired.value
? [
createRequiredRule(`请输入${reasonLabel.value}`),
{
validator: (_rule, value: string, callback) => {
if (!value?.trim()) {
callback(new Error(`请输入${reasonLabel.value}`));
return;
}
callback();
},
trigger: 'blur'
}
]
: []
}));
async function handleSubmit() {
await validate();
emit('submit', model.reason.trim() || null);
}
watch(
() => visible.value,
async value => {
if (value) {
model.reason = '';
await nextTick();
formRef.value?.clearValidate();
}
}
);
</script>
<template>
<BusinessFormDialog
v-model="visible"
:title="title"
preset="sm"
:confirm-loading="props.loading"
@confirm="handleSubmit"
>
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top" :validate-on-rule-change="false">
<ElFormItem :label="reasonLabel" prop="reason">
<ElInput
v-model="model.reason"
type="textarea"
:rows="5"
maxlength="1000"
show-word-limit
:placeholder="reasonPlaceholder"
/>
</ElFormItem>
</ElForm>
</BusinessFormDialog>
</template>