2064af17创建于 2025年1月20日历史提交
<template>
  <div class="create-wrapper">
    <el-form :model="form" ref="ruleFormRef" :rules="rules" label-width="auto" class="my-form">
      <el-form-item prop="name" :label="$t('common.name')" class="form-item-line1">
        <el-input v-model="form.name" />
      </el-form-item>
      <el-form-item prop="code" :label="$t('snippets.name')">
        <AceEditor ref="editorRef" type="form" :readOnly="false" width="100%" height="400px" />
      </el-form-item>
      <el-form-item prop="description" :label="$t('common.description')">
        <el-input v-model="form.description" type="textarea" :rows="2" resize="none" />
      </el-form-item>
    </el-form>
    <div class="button-wrapper">
      <el-button v-if="props.type == 'create'" @click="handleCancel">
        {{ $t('button.cancel') }}
      </el-button>
      <el-button v-if="props.type == 'edit'" type="primary" @click="handleDelelte">
        {{ $t('button.delete') }}
      </el-button>
      <el-button v-if="props.type == 'edit'" type="primary" @click="handleCopy">
        {{ $t('button.copy') }}
      </el-button>
      <el-button v-if="props.type == 'edit'" type="primary" @click="handleExport">
        {{ $t('button.exportToTerminal') }}
      </el-button>
      <el-button type="primary" @click="handleSave">
        {{ $t('button.save') }}
      </el-button>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus';
  import AceEditor from '@/components/AceEditor.vue';
  import { useI18n } from 'vue-i18n';
  import { loadingInstance, copyToClickBoard } from '@/utils';
  import { createSqlCodeApi, updateSqlCodeApi, getSqlCodeApi, deleteSqlCodeApi } from '@/api/snippets';

  const { t } = useI18n();
  const loading = ref(null);
  const props = withDefaults(
    defineProps<{
      type: 'create' | 'edit';
      codeId?: number | string;
      code?: string;
    }>(),
    {
      type: 'create',
    },
  );
  const ruleFormRef = ref<FormInstance>();
  const editorRef = ref();
  const form = reactive({
    name: '',
    code: '',
    description: '',
  });
  const rules = reactive<FormRules>({
    name: [{ required: true, message: t('rules.empty', [t('common.name')]), trigger: 'blur' }],
    code: [{ required: true, message: t('rules.empty', [t('snippets.name')]), trigger: 'blur' }],
  });

  const toggleSnippetsList = inject<() => void>('toggleSnippetsList');

  const getData = async () => {
    const res = await getSqlCodeApi({
      id: props.codeId,
    });
    Object.assign(form, {
      name: res.name,
      description: res.description,
    });
    editorRef.value.setValue(res.code);
  };

  const handleCopy = () => {
    const code = editorRef.value.getValue();
    if (code) {
      copyToClickBoard(editorRef.value.getValue());
      ElMessage.success(t('message.copySuccess'));
    } else {
      ElMessage.error(t('rules.empty', [t('snippets.name')]));
    }
  };

  const handleDelelte = () => {
    ElMessageBox.confirm(t('message.deleteSnippet'), t('common.warning'), {
      type: 'warning',
    })
      .then(async () => {
        await deleteSqlCodeApi({ id: props.codeId });
        ElMessage({
          type: 'success',
          message: t('message.deleteSuccess'),
        });
        handleCancel();
      })
      .catch(() => ({}));
  };

  const handleImportFile = inject<(data: string) => void>('handleImportFile');
  const handleExport = () => {
    const code = editorRef.value.getValue();
    if (code) {
      handleImportFile(editorRef.value.getValue());
    } else {
      ElMessage.error(t('rules.empty', [t('snippets.name')]));
    }
  };

  const handleCancel = () => {
    ruleFormRef.value.resetFields();
    editorRef.value.setValue('');
    toggleSnippetsList();
  };
  const handleSave = () => {
    const api = {
      create: createSqlCodeApi,
      edit: updateSqlCodeApi,
    };
    form.code = editorRef.value.getValue();
    ruleFormRef.value.validate((valid) => {
      if (valid) {
        loading.value = loadingInstance();
        try {
          api[props.type]({
            id: props.type == 'edit' ? props.codeId : undefined,
            name: form.name,
            code: form.code,
            description: form.description,
          }).then(() => {
            if (props.type === 'create') {
              ElMessage.success(`${t('message.success')}`);
            } else if (props.type === 'edit') {
              ElMessage.success(`${t('message.editSuccess')}`);
            }
            handleCancel();
          });
        } finally {
          loading.value.close();
        }
      }
    });
  };
  onMounted(() => {
    if (props.type == 'create' && props.code) {
      editorRef.value.setValue(props.code);
    }
    if (props.type == 'edit') {
      nextTick(async () => {
        getData();
      });
    }
  });
</script>
<style lang="scss" scoped>
  .create-wrapper {
    display: flex;
    flex-direction: column;
    height: 100%;
  }
  .my-form {
    flex: 1;
  }
  .button-wrapper {
    text-align: center;
  }
</style>