zhou zhou
18 小时以前 5454bbe86b1a22e9f05b6bc43f7ed7e9d6c4dc14
rsf-design/src/views/system/config/modules/config-dialog.vue
@@ -17,7 +17,47 @@
      label-width="100px"
      :show-reset="false"
      :show-submit="false"
    />
    >
      <template #val>
        <div class="w-full">
          <ElInput
            v-model="form.val"
            clearable
            :placeholder="t('pages.system.config.placeholders.value')"
          />
          <div v-if="isProjectLogoConfig || isImageConfigValue(form.val)" class="mt-3">
            <div class="flex flex-wrap items-center gap-3">
              <ElUpload
                accept="image/*"
                :show-file-list="false"
                :before-upload="beforeLogoUpload"
                :http-request="handleLogoUpload"
              >
                <ElButton :loading="uploading">
                  {{ t('pages.system.config.actions.uploadLogo') }}
                </ElButton>
              </ElUpload>
              <span class="text-xs text-g-500">
                {{
                  isProjectLogoConfig
                    ? t('pages.system.config.messages.projectLogoHint', { flag: projectLogoFlag })
                    : t('pages.system.config.messages.imagePreviewHint')
                }}
              </span>
            </div>
            <ElImage
              v-if="isImageConfigValue(form.val)"
              :src="form.val"
              fit="contain"
              preview-teleported
              class="mt-3 h-24 w-24 rounded border border-[var(--art-border-color)] bg-[var(--art-main-bg-color)]"
            />
          </div>
        </div>
      </template>
    </ArtForm>
    <template #footer>
      <span class="dialog-footer">
@@ -29,9 +69,17 @@
</template>
<script setup>
  import { ElMessage } from 'element-plus'
  import ArtForm from '@/components/core/forms/art-form/index.vue'
  import { fetchUploadProjectLogo } from '@/api/system-manage'
  import { useI18n } from 'vue-i18n'
  import { buildConfigDialogModel, createConfigFormState, getConfigTypeOptions } from '../configPage.helpers'
  import {
    buildConfigDialogModel,
    createConfigFormState,
    getConfigTypeOptions,
    isImageConfigValue,
    PROJECT_LOGO_FLAG
  } from '../configPage.helpers'
  const props = defineProps({
    visible: { type: Boolean, default: false },
@@ -42,8 +90,11 @@
  const { t } = useI18n()
  const formRef = ref()
  const form = reactive(createConfigFormState())
  const uploading = ref(false)
  const isEdit = computed(() => Boolean(form.id))
  const isProjectLogoConfig = computed(() => String(form.flag || '').trim().toUpperCase() === PROJECT_LOGO_FLAG)
  const projectLogoFlag = PROJECT_LOGO_FLAG
  const dialogTitle = computed(() =>
    isEdit.value ? t('pages.system.config.dialog.titleEdit') : t('pages.system.config.dialog.titleCreate')
  )
@@ -144,6 +195,38 @@
    Object.assign(form, buildConfigDialogModel(props.configData))
  }
  function beforeLogoUpload(rawFile) {
    const isImageFile =
      String(rawFile?.type || '').startsWith('image/') || /\.(png|jpe?g|gif|bmp|webp|svg)$/i.test(rawFile?.name || '')
    if (!isImageFile) {
      ElMessage.error(t('pages.system.config.messages.uploadOnlyImage'))
      return false
    }
    const isLt5MB = Number(rawFile?.size || 0) / 1024 / 1024 < 5
    if (!isLt5MB) {
      ElMessage.error(t('pages.system.config.messages.uploadSizeLimit'))
      return false
    }
    return true
  }
  async function handleLogoUpload(option) {
    uploading.value = true
    try {
      const response = await fetchUploadProjectLogo(option.file)
      form.val = response?.url || ''
      option.onSuccess?.(response)
      ElMessage.success(t('pages.system.config.messages.uploadSuccess'))
    } catch (error) {
      option.onError?.(error)
      ElMessage.error(error?.message || t('pages.system.config.messages.uploadFailed'))
    } finally {
      uploading.value = false
    }
  }
  async function handleSubmit() {
    if (!formRef.value) return
    try {