初始化

This commit is contained in:
2026-03-26 20:18:20 +08:00
commit 120a5b4dfd
368 changed files with 35926 additions and 0 deletions

View File

@@ -0,0 +1,203 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { dictStatusOptions } from '@/constants/business';
import { fetchCreateDictData, fetchUpdateDictData } from '@/service/api';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import { $t } from '@/locales';
defineOptions({ name: 'DictDataOperateModal' });
interface Props {
operateType: UI.TableOperateType;
rowData?: Api.Dict.DictData | null;
currentType?: Api.Dict.DictType | null;
}
const props = defineProps<Props>();
interface Emits {
(e: 'submitted'): void;
}
const emit = defineEmits<Emits>();
const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useForm();
const { defaultRequiredRule } = useFormRules();
const isEdit = computed(() => props.operateType === 'edit');
const submitting = ref(false);
const title = computed(() => {
const titleMap: Record<UI.TableOperateType, string> = {
add: $t('page.system.dict.addData'),
edit: $t('page.system.dict.editData')
};
return titleMap[props.operateType];
});
type Model = Api.Dict.SaveDictDataParams;
const model = ref(createDefaultModel());
const currentTypeName = computed(() => props.currentType?.name ?? '-');
const currentTypeCode = computed(() => props.currentType?.type ?? model.value.dictType ?? '-');
function createDefaultModel(): Model {
return {
label: '',
value: '',
dictType: '',
sort: 0,
status: 0,
remark: ''
};
}
type RuleKey = Extract<keyof Model, 'label' | 'value' | 'sort' | 'status'>;
const rules: Record<RuleKey, App.Global.FormRule> = {
label: defaultRequiredRule,
value: defaultRequiredRule,
sort: defaultRequiredRule,
status: defaultRequiredRule
};
function handleInitModel() {
model.value = createDefaultModel();
// 新增字典数据时默认继承左侧当前选中的字典类型。
const currentDictType = props.currentType?.type ?? '';
model.value.dictType = currentDictType;
if (isEdit.value && props.rowData) {
// 编辑时直接使用表格行数据回填,保持弹框打开速度。
Object.assign(model.value, {
label: props.rowData.label,
value: props.rowData.value,
dictType: props.rowData.dictType,
sort: props.rowData.sort,
status: props.rowData.status,
remark: props.rowData.remark ?? ''
});
}
}
function closeModal() {
visible.value = false;
}
async function handleSubmit() {
await validate();
// 右侧数据必须依附左侧字典类型,没有选中类型时不允许提交。
const dictType = model.value.dictType || props.currentType?.type;
if (!dictType) {
window.$message?.warning($t('page.system.dict.emptyType'));
return;
}
submitting.value = true;
const params: Api.Dict.SaveDictDataParams = {
...model.value,
dictType
};
const request =
isEdit.value && props.rowData
? fetchUpdateDictData({ id: props.rowData.id, ...params })
: fetchCreateDictData(params);
const { error } = await request;
submitting.value = false;
if (error) {
return;
}
window.$message?.success($t(isEdit.value ? 'common.updateSuccess' : 'common.addSuccess'));
closeModal();
emit('submitted');
}
watch(visible, value => {
if (value) {
handleInitModel();
restoreValidation();
}
});
</script>
<template>
<BusinessFormDialog
v-model="visible"
:title="title"
preset="md"
:confirm-loading="submitting"
:scrollbar="false"
@confirm="handleSubmit"
>
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
<ElRow :gutter="16">
<ElCol :span="12">
<ElFormItem :label="$t('page.system.dict.currentType')">
<ElInput :model-value="currentTypeName" disabled />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem :label="$t('page.system.dict.dictCode')">
<ElInput :model-value="currentTypeCode" disabled />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem :label="$t('page.system.dict.dictLabel')" prop="label">
<ElInput v-model="model.label" :placeholder="$t('page.system.dict.form.dictLabel')" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem :label="$t('page.system.dict.dictValue')" prop="value">
<ElInput v-model="model.value" :placeholder="$t('page.system.dict.form.dictValue')" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem :label="$t('page.system.dict.sort')" prop="sort">
<ElInputNumber
v-model="model.sort"
class="w-full"
:min="0"
:placeholder="$t('page.system.dict.form.sort')"
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem :label="$t('page.system.dict.dictStatus')" prop="status">
<ElRadioGroup v-model="model.status" class="business-form-radio-group">
<ElRadio v-for="{ label, value } in dictStatusOptions" :key="value" :value="value" :label="$t(label)" />
</ElRadioGroup>
</ElFormItem>
</ElCol>
<ElCol :span="24">
<ElFormItem :label="$t('page.system.dict.remark')" prop="remark">
<ElInput
v-model="model.remark"
type="textarea"
:rows="4"
:placeholder="$t('page.system.dict.form.remark')"
/>
</ElFormItem>
</ElCol>
</ElRow>
</ElForm>
</BusinessFormDialog>
</template>
<style scoped></style>