zhou zhou
10 小时以前 50e95b985a72fcec4a93a2470e9efdfb2620148a
rsf-design/src/views/system/ai-param/modules/ai-param-dialog.vue
@@ -19,14 +19,21 @@
      :show-submit="false"
    />
    <div v-if="showRuntimeSection" class="mt-2 rounded-2xl border border-[var(--art-border-color)] px-5 py-4">
    <div
      v-if="showRuntimeSection"
      class="mt-2 rounded-2xl border border-[var(--art-border-color)] px-5 py-4"
    >
      <div class="mb-3 flex items-center justify-between gap-4">
        <div>
          <h4 class="text-base font-semibold text-[var(--art-gray-900)]">运行时状态</h4>
          <p class="mt-1 text-sm text-[var(--art-gray-500)]">保存前可先执行草稿校验,运行时状态由后端真实返回。</p>
          <h4 class="text-base font-semibold text-[var(--art-gray-900)]">
            {{ t('pages.system.aiParam.dialog.runtimeTitle') }}
          </h4>
          <p class="mt-1 text-sm text-[var(--art-gray-500)]">
            {{ t('pages.system.aiParam.dialog.runtimeDescription') }}
          </p>
        </div>
        <ElButton v-if="!isReadonly" :loading="validateLoading" @click="handleValidateDraft">
          草稿校验
          {{ t('pages.system.aiParam.dialog.validateDraft') }}
        </ElButton>
      </div>
@@ -39,14 +46,29 @@
      />
      <ElDescriptions :column="2" border>
        <ElDescriptionsItem label="校验状态">{{ form.validateStatus || '--' }}</ElDescriptionsItem>
        <ElDescriptionsItem label="最近校验耗时">
          {{ form.lastValidateElapsedMs !== null && form.lastValidateElapsedMs !== undefined ? `${form.lastValidateElapsedMs} ms` : '--' }}
        <ElDescriptionsItem :label="t('pages.system.aiParam.dialog.labels.validateStatus')">
          {{ form.validateStatus || '--' }}
        </ElDescriptionsItem>
        <ElDescriptionsItem label="最近校验时间">{{ form['lastValidateTime$'] || '--' }}</ElDescriptionsItem>
        <ElDescriptionsItem label="最近更新人">{{ form.updateBy || '--' }}</ElDescriptionsItem>
        <ElDescriptionsItem label="最近更新时间" :span="2">{{ form['updateTime$'] || '--' }}</ElDescriptionsItem>
        <ElDescriptionsItem label="最近校验信息" :span="2">
        <ElDescriptionsItem :label="t('pages.system.aiParam.dialog.labels.lastValidateElapsedMs')">
          {{
            form.lastValidateElapsedMs !== null && form.lastValidateElapsedMs !== undefined
              ? `${form.lastValidateElapsedMs} ms`
              : '--'
          }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('pages.system.aiParam.dialog.labels.lastValidateTime')">
          {{ form['lastValidateTime$'] || '--' }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('pages.system.aiParam.dialog.labels.updateBy')">
          {{ form.updateBy || '--' }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('pages.system.aiParam.dialog.labels.updateTime')" :span="2">
          {{ form['updateTime$'] || '--' }}
        </ElDescriptionsItem>
        <ElDescriptionsItem
          :label="t('pages.system.aiParam.dialog.labels.lastValidateMessage')"
          :span="2"
        >
          <div class="whitespace-pre-wrap break-all text-sm leading-6 text-[var(--art-gray-700)]">
            {{ form.lastValidateMessage || '--' }}
          </div>
@@ -56,14 +78,19 @@
    <template #footer>
      <span class="dialog-footer">
        <ElButton @click="handleCancel">{{ isReadonly ? '关闭' : '取消' }}</ElButton>
        <ElButton v-if="!isReadonly" type="primary" @click="handleSubmit">确定</ElButton>
        <ElButton @click="handleCancel">
          {{ isReadonly ? t('common.actions.close') : t('common.cancel') }}
        </ElButton>
        <ElButton v-if="!isReadonly" type="primary" @click="handleSubmit">
          {{ t('common.confirm') }}
        </ElButton>
      </span>
    </template>
  </ElDialog>
</template>
<script setup>
  import { useI18n } from 'vue-i18n'
  import ArtForm from '@/components/core/forms/art-form/index.vue'
  import { fetchValidateAiParamDraft } from '@/api/ai-config'
  import {
@@ -81,6 +108,7 @@
  })
  const emit = defineEmits(['submit', 'update:visible'])
  const { t } = useI18n()
  const formRef = ref()
  const form = reactive(createAiParamFormState())
  const validateLoading = ref(false)
@@ -89,9 +117,9 @@
  const isReadonly = computed(() => props.mode === 'show')
  const showRuntimeSection = computed(() => Boolean(form.id) || props.mode !== 'create')
  const dialogTitle = computed(() => {
    if (props.mode === 'edit') return '编辑 AI 参数'
    if (props.mode === 'show') return 'AI 参数详情'
    return '新建 AI 参数'
    if (props.mode === 'edit') return t('pages.system.aiParam.dialog.titleEdit')
    if (props.mode === 'show') return t('pages.system.aiParam.dialog.titleDetail')
    return t('pages.system.aiParam.dialog.titleCreate')
  })
  const validateAlertType = computed(() =>
@@ -112,69 +140,75 @@
  })
  const rules = computed(() => ({
    name: [{ required: true, message: '请输入参数名称', trigger: 'blur' }],
    providerType: [{ required: true, message: '请选择提供方类型', trigger: 'change' }],
    baseUrl: [{ required: true, message: '请输入基础地址', trigger: 'blur' }],
    apiKey: [{ required: true, message: '请输入 API Key', trigger: 'blur' }],
    model: [{ required: true, message: '请输入模型名称', trigger: 'blur' }]
    name: [{ required: true, message: t('pages.system.aiParam.dialog.validation.name'), trigger: 'blur' }],
    providerType: [
      {
        required: true,
        message: t('pages.system.aiParam.dialog.validation.providerType'),
        trigger: 'change'
      }
    ],
    baseUrl: [{ required: true, message: t('pages.system.aiParam.dialog.validation.baseUrl'), trigger: 'blur' }],
    apiKey: [{ required: true, message: t('pages.system.aiParam.dialog.validation.apiKey'), trigger: 'blur' }],
    model: [{ required: true, message: t('pages.system.aiParam.dialog.validation.model'), trigger: 'blur' }]
  }))
  const formItems = computed(() => [
    {
      label: '参数名称',
      label: t('pages.system.aiParam.dialog.labels.name'),
      key: 'name',
      type: 'input',
      props: {
        clearable: true,
        placeholder: '请输入参数名称',
        placeholder: t('pages.system.aiParam.dialog.placeholders.name'),
        disabled: isReadonly.value
      }
    },
    {
      label: '提供方类型',
      label: t('pages.system.aiParam.dialog.labels.providerType'),
      key: 'providerType',
      type: 'select',
      props: {
        options: getAiParamProviderOptions(),
        disabled: isReadonly.value,
        placeholder: '请选择提供方类型'
        placeholder: t('pages.system.aiParam.dialog.placeholders.providerType')
      }
    },
    {
      label: '基础地址',
      label: t('pages.system.aiParam.dialog.labels.baseUrl'),
      key: 'baseUrl',
      type: 'input',
      span: 24,
      props: {
        clearable: true,
        placeholder: '请输入兼容 OpenAI 的基础地址',
        placeholder: t('pages.system.aiParam.dialog.placeholders.baseUrl'),
        disabled: isReadonly.value
      }
    },
    {
      label: 'API Key',
      label: t('pages.system.aiParam.dialog.labels.apiKey'),
      key: 'apiKey',
      type: 'input',
      props: {
        clearable: true,
        placeholder: '请输入 API Key',
        placeholder: t('pages.system.aiParam.dialog.placeholders.apiKey'),
        disabled: isReadonly.value,
        type: isReadonly.value ? 'text' : 'password',
        showPassword: !isReadonly.value
      }
    },
    {
      label: '模型名称',
      label: t('pages.system.aiParam.dialog.labels.model'),
      key: 'model',
      type: 'input',
      props: {
        clearable: true,
        placeholder: '请输入模型名称',
        placeholder: t('pages.system.aiParam.dialog.placeholders.model'),
        disabled: isReadonly.value
      }
    },
    {
      label: 'Temperature',
      label: t('pages.system.aiParam.dialog.labels.temperature'),
      key: 'temperature',
      type: 'number',
      props: {
@@ -182,12 +216,12 @@
        max: 2,
        step: 0.1,
        precision: 2,
        placeholder: '请输入 temperature',
        placeholder: t('pages.system.aiParam.dialog.placeholders.temperature'),
        disabled: isReadonly.value
      }
    },
    {
      label: 'Top P',
      label: t('pages.system.aiParam.dialog.labels.topP'),
      key: 'topP',
      type: 'number',
      props: {
@@ -195,54 +229,54 @@
        max: 1,
        step: 0.1,
        precision: 2,
        placeholder: '请输入 topP',
        placeholder: t('pages.system.aiParam.dialog.placeholders.topP'),
        disabled: isReadonly.value
      }
    },
    {
      label: '最大 Token',
      label: t('pages.system.aiParam.dialog.labels.maxTokens'),
      key: 'maxTokens',
      type: 'number',
      props: {
        min: 1,
        step: 1,
        placeholder: '请输入最大 token',
        placeholder: t('pages.system.aiParam.dialog.placeholders.maxTokens'),
        disabled: isReadonly.value
      }
    },
    {
      label: '超时时间(ms)',
      label: t('pages.system.aiParam.dialog.labels.timeoutMs'),
      key: 'timeoutMs',
      type: 'number',
      props: {
        min: 1000,
        step: 1000,
        placeholder: '请输入超时时间',
        placeholder: t('pages.system.aiParam.dialog.placeholders.timeoutMs'),
        disabled: isReadonly.value
      }
    },
    {
      label: '流式响应',
      label: t('pages.system.aiParam.dialog.labels.streamingEnabled'),
      key: 'streamingEnabled',
      type: 'switch',
      props: {
        disabled: isReadonly.value,
        activeText: '开启',
        inactiveText: '关闭'
        activeText: t('common.status.enabled'),
        inactiveText: t('common.status.disabled')
      }
    },
    {
      label: '默认状态',
      label: t('pages.system.aiParam.dialog.labels.status'),
      key: 'status',
      type: 'select',
      props: {
        disabled: isReadonly.value,
        options: getAiParamStatusOptions(),
        placeholder: '请选择默认状态'
        placeholder: t('pages.system.aiParam.dialog.placeholders.status')
      }
    },
    {
      label: '备注',
      label: t('pages.system.aiParam.dialog.labels.memo'),
      key: 'memo',
      type: 'input',
      span: 24,
@@ -250,7 +284,7 @@
        disabled: isReadonly.value,
        type: 'textarea',
        rows: 3,
        placeholder: '请输入备注'
        placeholder: t('pages.system.aiParam.dialog.placeholders.memo')
      }
    }
  ])