gtsoft-snail-job-admin/src/views/dictionary/modules/dictionary-operate-drawer.vue
2025-03-11 20:31:38 +08:00

191 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { useClipboard } from '@vueuse/core';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import OperateDrawer from '@/components/common/operate-drawer.vue';
import { $t } from '@/locales';
import { fetchAddNamespace, fetchEditNamespace } from '@/service/api';
import { useAuthStore } from '@/store/modules/auth';
import { translateOptions } from '@/utils/common';
import { fetchAddCategory } from '@/service/api'
// import { categoryTypeOptions } from '@/constants/business';
// 定义组件选项
defineOptions({
name: 'CategoryOperateDrawer'
});
interface Props {
/** the type of operation */
operateType: NaiveUI.TableOperateType;
/** the edit row data */
rowData?: Api.Category.Category | null;
}
const props = defineProps<Props>();
interface Emits {
(e: 'submitted'): void;
}
const emit = defineEmits<Emits>();
// 使用剪贴板功能
const { copy, isSupported } = useClipboard();
// 使用全局状态
const authStore = useAuthStore();
// 定义抽屉的可见性
const visible = defineModel<boolean>('visible', {
default: false
});
// 定义表单引用和验证
// restoreValidation重置表单验证状态
const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules();
// 动态标题
const title = computed(() => {
const titles: Record<NaiveUI.TableOperateType, string> = {
add: $t('page.category.addCategory'),
edit: $t('page.category.editCategory')
};
return titles[props.operateType];
});
const model: Api.Category.Model = reactive(createDefaultModel());
function updateModel(categoryName: string, categoryType: string, parentId: number) {
model.name = categoryName;
model.type = categoryType;
model.parent = parentId.toString(); // 确保类型匹配
}
function createDefaultModel(): Api.Category.Model {
return {
id: 0,
name: '',
type: '',
parent: ''
};
}
// 定义表单验证规则
type RuleKey = Extract<keyof Api.Category.Model, App.Global.FormRule>;
const rules: Record<RuleKey, App.Global.FormRule> = {
name: defaultRequiredRule,
type: defaultRequiredRule,
parent: defaultRequiredRule
};
// 监听抽屉的可见性,当抽屉打开时,更新表单模型
function handleUpdateModelWhenEdit() {
if (props.operateType === 'add') {
const parentId = props.rowData!.parentId;
updateModel('', '网站', parentId);
return;
}
if (props.operateType === 'edit' && props.rowData) {
const { categoryName, categoryType, parentId } = props.rowData;
updateModel(categoryName, categoryType, parentId);
console.log(model);
}
}
// 关闭抽屉
function closeDrawer() {
visible.value = false;
}
// 提交表单
async function handleSubmit() {
await validate();
// request
if (props.operateType === 'add') {
const res = await fetchAddCategory(model);
console.log(res);
if (res.error) return;
window.$message?.success($t('common.addSuccess'));
}
// if (props.operateType === 'edit') {
// const { type, name, parentId } = model;
// const { error } = await fetchEditNamespace({ type, name, parentId });
// if (error) return;
// window.$message?.success($t('common.updateSuccess'));
// }
// await authStore.getUserInfo();
closeDrawer();
emit('submitted');
}
// 监听抽屉的可见性, 如果抽屉可见,更新表单模型并重置验证状态
watch(visible, () => {
if (visible.value) {
handleUpdateModelWhenEdit();
restoreValidation();
}
});
async function handleCopy(source: string) {
if (!isSupported) {
window.$message?.error('您的浏览器不支持 Clipboard API');
return;
}
if (!source) {
return;
}
await copy(source);
window.$message?.success('复制成功');
}
const categoryTypeOptions = [
{ label: '1', value: '网站' },
{ label: '2', value: '文献' }
];
</script>
<template>
<OperateDrawer v-model="visible" :title="title" @submitted="handleSubmit">
<NForm ref="formRef" :model="model" :rules="rules">
<NFormItem :label="$t('page.category.form.categoryName')" path="name">
<NInputGroup>
<NInput v-model:value="model.name" :placeholder="$t('page.category.form.name')" />
<NTooltip v-if="props.operateType === 'edit'" trigger="hover">
<template #trigger>
<NButton type="default" ghost @click="handleCopy(model.name)">
<icon-ic:round-content-copy class="text-icon" />
</NButton>
</template>
复制
</NTooltip>
</NInputGroup>
</NFormItem>
<NFormItem :label="$t('page.category.form.categoryType')" path="type">
<NSelect v-model:value="model.type" :placeholder="$t('page.category.form.categoryType')"
:options="categoryTypeOptions" clearable />
</NFormItem>
<!-- <NFormItem :label="$t('page.category.form.categoryType')" path="type">
<NSelect v-model:value="model.type" :placeholder="$t('page.category.form.categoryType')"
:options="translateOptions(categoryTypeOptions)" clearable />
</NFormItem> -->
<NFormItem :label="$t('page.category.form.categoryParentName')" path="parent">
<NInput v-model:value="model.parent" :placeholder="$t('page.category.form.categoryType')" :disabled="true" />
</NFormItem>
</NForm>
<!-- 按钮 -->
<template #footer>
<NSpace :size="16">
<NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
<NButton type="primary" @click="handleSubmit">{{ $t('common.save') }}</NButton>
</NSpace>
</template>
</OperateDrawer>
</template>
<style scoped></style>