2026-04-25 21:36:44 +08:00
|
|
|
|
<script setup lang="ts">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
import { LeftOutlined, LinkOutlined } from '@ant-design/icons-vue'
|
2026-05-20 02:16:45 +08:00
|
|
|
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
2026-05-01 20:39:09 +08:00
|
|
|
|
import { message } from 'ant-design-vue'
|
|
|
|
|
|
import { computed, reactive, watch } from 'vue'
|
|
|
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
|
|
|
|
|
|
|
|
import KnowledgeGroupSelect from '@/components/KnowledgeGroupSelect.vue'
|
2026-05-20 02:16:45 +08:00
|
|
|
|
import { articlesApi, brandsApi } from '@/lib/api'
|
2026-05-01 20:39:09 +08:00
|
|
|
|
import { formatError } from '@/lib/errors'
|
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
const queryClient = useQueryClient()
|
|
|
|
|
|
const { t } = useI18n()
|
2026-04-25 21:36:44 +08:00
|
|
|
|
|
|
|
|
|
|
const form = reactive({
|
2026-05-01 20:39:09 +08:00
|
|
|
|
source_url: '',
|
|
|
|
|
|
source_title: '',
|
|
|
|
|
|
locale: 'zh-CN',
|
|
|
|
|
|
brand_name: '',
|
|
|
|
|
|
region: '',
|
2026-04-25 21:36:44 +08:00
|
|
|
|
keywords: [] as string[],
|
2026-05-01 20:39:09 +08:00
|
|
|
|
preserve_points: '',
|
|
|
|
|
|
avoid_points: '',
|
|
|
|
|
|
extra_requirements: '',
|
2026-04-25 21:36:44 +08:00
|
|
|
|
enable_web_search: false,
|
|
|
|
|
|
knowledge_group_ids: [] as number[],
|
2026-05-01 20:39:09 +08:00
|
|
|
|
})
|
2026-04-25 21:36:44 +08:00
|
|
|
|
|
2026-05-20 02:16:45 +08:00
|
|
|
|
const brandsQuery = useQuery({
|
|
|
|
|
|
queryKey: ['brands'],
|
|
|
|
|
|
queryFn: () => brandsApi.list(),
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const brandNameOptions = computed(() =>
|
|
|
|
|
|
(brandsQuery.data.value ?? []).map((item) => ({
|
|
|
|
|
|
label: item.name,
|
|
|
|
|
|
value: item.name,
|
|
|
|
|
|
})),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const selectedBrand = computed(
|
|
|
|
|
|
() => brandsQuery.data.value?.find((item) => item.name === form.brand_name.trim()) ?? null,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const questionsQuery = useQuery({
|
|
|
|
|
|
queryKey: computed(() => ['brands', selectedBrand.value?.id, 'questions', 'imitation']),
|
|
|
|
|
|
enabled: computed(() => Boolean(selectedBrand.value?.id)),
|
|
|
|
|
|
queryFn: () => brandsApi.listQuestions(selectedBrand.value?.id as number),
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const keywordOptions = computed(() =>
|
|
|
|
|
|
(questionsQuery.data.value ?? []).map((item) => ({
|
|
|
|
|
|
label: item.question_text,
|
|
|
|
|
|
value: item.question_text,
|
|
|
|
|
|
})),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-05-01 20:39:09 +08:00
|
|
|
|
const canSubmit = computed(
|
2026-05-20 02:16:45 +08:00
|
|
|
|
() =>
|
|
|
|
|
|
form.source_url.trim().length > 0 &&
|
|
|
|
|
|
form.brand_name.trim().length > 0 &&
|
|
|
|
|
|
!generateMutation.isPending.value,
|
2026-05-01 20:39:09 +08:00
|
|
|
|
)
|
2026-04-25 21:36:44 +08:00
|
|
|
|
|
|
|
|
|
|
const generateMutation = useMutation({
|
|
|
|
|
|
mutationFn: () =>
|
|
|
|
|
|
articlesApi.generateImitation({
|
|
|
|
|
|
source_url: form.source_url.trim(),
|
|
|
|
|
|
source_title: form.source_title.trim(),
|
|
|
|
|
|
locale: form.locale,
|
|
|
|
|
|
brand_name: form.brand_name.trim(),
|
|
|
|
|
|
region: form.region.trim(),
|
|
|
|
|
|
keywords: form.keywords.map((item) => item.trim()).filter(Boolean),
|
|
|
|
|
|
preserve_points: form.preserve_points.trim(),
|
|
|
|
|
|
avoid_points: form.avoid_points.trim(),
|
|
|
|
|
|
extra_requirements: form.extra_requirements.trim(),
|
|
|
|
|
|
enable_web_search: form.enable_web_search,
|
|
|
|
|
|
web_search_limit: form.enable_web_search ? 5 : undefined,
|
|
|
|
|
|
knowledge_group_ids: form.knowledge_group_ids,
|
|
|
|
|
|
}),
|
|
|
|
|
|
onSuccess: async () => {
|
|
|
|
|
|
await Promise.all([
|
2026-05-01 20:39:09 +08:00
|
|
|
|
queryClient.invalidateQueries({ queryKey: ['articles'] }),
|
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: ['workspace'] }),
|
|
|
|
|
|
])
|
|
|
|
|
|
message.info(t('imitation.create.queued'))
|
|
|
|
|
|
await router.replace({ name: 'articles-imitations' })
|
2026-04-25 21:36:44 +08:00
|
|
|
|
},
|
|
|
|
|
|
onError: (error) => {
|
2026-05-01 20:39:09 +08:00
|
|
|
|
message.error(formatError(error) || t('imitation.create.submitError'))
|
2026-04-25 21:36:44 +08:00
|
|
|
|
},
|
2026-05-01 20:39:09 +08:00
|
|
|
|
})
|
2026-04-25 21:36:44 +08:00
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => [route.query.source_url, route.query.source_title],
|
|
|
|
|
|
([sourceURL, sourceTitle]) => {
|
2026-05-01 20:39:09 +08:00
|
|
|
|
form.source_url = normalizeQueryValue(sourceURL)
|
|
|
|
|
|
form.source_title = normalizeQueryValue(sourceTitle)
|
2026-04-25 21:36:44 +08:00
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true },
|
2026-05-01 20:39:09 +08:00
|
|
|
|
)
|
2026-04-25 21:36:44 +08:00
|
|
|
|
|
|
|
|
|
|
function normalizeQueryValue(value: unknown): string {
|
2026-05-01 20:39:09 +08:00
|
|
|
|
const raw = Array.isArray(value) ? value[0] : value
|
|
|
|
|
|
return String(raw ?? '').trim()
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function goBack(): void {
|
2026-05-01 20:39:09 +08:00
|
|
|
|
void router.push({ name: 'articles-imitations' })
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function submit(): void {
|
|
|
|
|
|
if (!form.source_url.trim()) {
|
2026-05-01 20:39:09 +08:00
|
|
|
|
message.warning(t('imitation.create.sourceURLRequired'))
|
|
|
|
|
|
return
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
2026-05-20 02:16:45 +08:00
|
|
|
|
if (!form.brand_name.trim()) {
|
|
|
|
|
|
message.warning(t('imitation.create.brandNameRequired'))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-05-01 20:39:09 +08:00
|
|
|
|
generateMutation.mutate()
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="imitation-generate-page">
|
|
|
|
|
|
<header class="imitation-generate-page__header">
|
|
|
|
|
|
<div class="imitation-generate-page__header-left">
|
|
|
|
|
|
<a-button type="text" shape="circle" @click="goBack">
|
|
|
|
|
|
<template #icon><LeftOutlined /></template>
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
<div class="imitation-generate-page__title-box">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<h2>{{ t('imitation.create.title') }}</h2>
|
|
|
|
|
|
<p>{{ t('imitation.create.subtitle') }}</p>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
|
|
<main class="imitation-generate-page__main">
|
|
|
|
|
|
<section class="imitation-generate-page__step">
|
|
|
|
|
|
<div class="imitation-generate-page__step-line">
|
|
|
|
|
|
<span>1</span>
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<strong>{{ t('imitation.create.settingsSection') }}</strong>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section class="imitation-generate-page__section">
|
|
|
|
|
|
<div class="imitation-generate-page__section-head">
|
|
|
|
|
|
<div>
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<h3>{{ t('imitation.create.sourceSection') }}</h3>
|
|
|
|
|
|
<p>{{ t('route.imitationCreate.description') }}</p>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field-grid">
|
|
|
|
|
|
<div class="imitation-generate-page__field imitation-generate-page__field--wide">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label class="required-asterisk">{{ t('imitation.create.sourceURL') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-input
|
|
|
|
|
|
v-model:value="form.source_url"
|
|
|
|
|
|
:placeholder="t('imitation.create.sourceURLPlaceholder')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #prefix><LinkOutlined /></template>
|
|
|
|
|
|
</a-input>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.sourceTitle') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-input
|
|
|
|
|
|
v-model:value="form.source_title"
|
|
|
|
|
|
:placeholder="t('imitation.create.sourceTitlePlaceholder')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.language') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="form.locale"
|
|
|
|
|
|
:options="[
|
|
|
|
|
|
{ label: t('templates.wizard.localeOptions.zh'), value: 'zh-CN' },
|
|
|
|
|
|
{ label: t('templates.wizard.localeOptions.en'), value: 'en-US' },
|
|
|
|
|
|
]"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section class="imitation-generate-page__section">
|
|
|
|
|
|
<div class="imitation-generate-page__section-head">
|
|
|
|
|
|
<div>
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<h3>{{ t('imitation.create.settingsSection') }}</h3>
|
|
|
|
|
|
<p>{{ t('templates.wizard.hints.keyPoints') }}</p>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__capability-card">
|
|
|
|
|
|
<div class="imitation-generate-page__capability-row">
|
|
|
|
|
|
<div class="imitation-generate-page__capability-copy">
|
|
|
|
|
|
<div class="imitation-generate-page__capability-label">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
{{ t('imitation.create.enableWebSearch') }}
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="imitation-generate-page__capability-hint">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
{{ t('imitation.create.webSearchHint') }}
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<a-switch
|
|
|
|
|
|
v-model:checked="form.enable_web_search"
|
|
|
|
|
|
:checked-children="t('common.yes')"
|
|
|
|
|
|
:un-checked-children="t('common.no')"
|
|
|
|
|
|
:disabled="generateMutation.isPending.value"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__capability-knowledge">
|
|
|
|
|
|
<label class="imitation-generate-page__capability-label">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
{{ t('imitation.create.knowledgeBase') }}
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</label>
|
|
|
|
|
|
<KnowledgeGroupSelect
|
|
|
|
|
|
v-model="form.knowledge_group_ids"
|
|
|
|
|
|
:disabled="generateMutation.isPending.value"
|
|
|
|
|
|
:placeholder="t('imitation.create.knowledgeBasePlaceholder')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<p class="imitation-generate-page__capability-hint">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
{{ t('imitation.create.knowledgeBaseHint') }}
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field-grid">
|
|
|
|
|
|
<div class="imitation-generate-page__field">
|
2026-05-20 02:16:45 +08:00
|
|
|
|
<label class="required-asterisk">{{ t('imitation.create.brandName') }}</label>
|
|
|
|
|
|
<a-auto-complete
|
2026-05-01 20:39:09 +08:00
|
|
|
|
v-model:value="form.brand_name"
|
2026-05-20 02:16:45 +08:00
|
|
|
|
allow-clear
|
|
|
|
|
|
:options="brandNameOptions"
|
2026-05-01 20:39:09 +08:00
|
|
|
|
:placeholder="t('imitation.create.brandNamePlaceholder')"
|
|
|
|
|
|
/>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.region') }}</label>
|
|
|
|
|
|
<a-input
|
|
|
|
|
|
v-model:value="form.region"
|
|
|
|
|
|
:placeholder="t('imitation.create.regionPlaceholder')"
|
|
|
|
|
|
/>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field imitation-generate-page__field--wide">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.keywords') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="form.keywords"
|
|
|
|
|
|
mode="tags"
|
|
|
|
|
|
style="width: 100%"
|
2026-05-20 02:16:45 +08:00
|
|
|
|
:options="keywordOptions"
|
2026-04-25 21:36:44 +08:00
|
|
|
|
:placeholder="t('imitation.create.keywordsPlaceholder')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.preservePoints') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-textarea
|
|
|
|
|
|
v-model:value="form.preserve_points"
|
|
|
|
|
|
:rows="4"
|
|
|
|
|
|
:placeholder="t('imitation.create.preservePointsPlaceholder')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.avoidPoints') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-textarea
|
|
|
|
|
|
v-model:value="form.avoid_points"
|
|
|
|
|
|
:rows="4"
|
|
|
|
|
|
:placeholder="t('imitation.create.avoidPointsPlaceholder')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="imitation-generate-page__field imitation-generate-page__field--wide">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<label>{{ t('imitation.create.extraRequirements') }}</label>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-textarea
|
|
|
|
|
|
v-model:value="form.extra_requirements"
|
|
|
|
|
|
:rows="5"
|
|
|
|
|
|
:placeholder="t('imitation.create.extraRequirementsPlaceholder')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</main>
|
|
|
|
|
|
|
|
|
|
|
|
<footer class="imitation-generate-page__footer">
|
2026-05-01 20:39:09 +08:00
|
|
|
|
<a-button @click="goBack">{{ t('imitation.create.backToList') }}</a-button>
|
2026-04-25 21:36:44 +08:00
|
|
|
|
<a-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
:disabled="!canSubmit"
|
|
|
|
|
|
:loading="generateMutation.isPending.value"
|
|
|
|
|
|
@click="submit"
|
|
|
|
|
|
>
|
2026-05-01 20:39:09 +08:00
|
|
|
|
{{ t('imitation.actions.submit') }}
|
2026-04-25 21:36:44 +08:00
|
|
|
|
</a-button>
|
|
|
|
|
|
</footer>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.imitation-generate-page {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
min-height: calc(100vh - 120px);
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__header {
|
|
|
|
|
|
z-index: 10;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
padding: 16px 32px;
|
|
|
|
|
|
border-bottom: 1px solid #edf2f7;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__header-left {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__title-box {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__title-box h2 {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
color: #111827;
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__title-box p {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
color: #6d7c94;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__main {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
max-width: 1160px;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
padding: 24px 32px 96px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__step {
|
|
|
|
|
|
padding-bottom: 24px;
|
|
|
|
|
|
border-bottom: 1px solid #edf2f7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__step-line {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
color: #111827;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__step-line::before,
|
|
|
|
|
|
.imitation-generate-page__step-line::after {
|
|
|
|
|
|
width: min(320px, 28vw);
|
|
|
|
|
|
height: 1px;
|
|
|
|
|
|
background: #dbe4ef;
|
2026-05-01 20:39:09 +08:00
|
|
|
|
content: '';
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__step-line span {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
width: 22px;
|
|
|
|
|
|
height: 22px;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
|
background: #1677ff;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__step-line strong {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__section {
|
|
|
|
|
|
padding: 32px 0;
|
|
|
|
|
|
border-bottom: 1px solid #edf2f7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__section:last-child {
|
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__section-head {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__section-head h3 {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
color: #111827;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__section-head h3::before {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
width: 4px;
|
|
|
|
|
|
height: 16px;
|
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
|
background: #111827;
|
2026-05-01 20:39:09 +08:00
|
|
|
|
content: '';
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__section-head p {
|
|
|
|
|
|
margin: 6px 0 0 16px;
|
|
|
|
|
|
color: #667085;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
line-height: 1.7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__field-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
|
gap: 18px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-card {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
border: 1px solid #e6edf5;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
background: #fafcff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-copy {
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-label {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
margin: 0 0 8px;
|
|
|
|
|
|
color: #111827;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-hint {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
color: #667085;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-knowledge {
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__field {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__field--wide {
|
|
|
|
|
|
grid-column: 1 / -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__field > label {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
color: #1f2937;
|
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__field > label::after {
|
2026-05-01 20:39:09 +08:00
|
|
|
|
content: ':';
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.required-asterisk::before {
|
|
|
|
|
|
margin-right: 4px;
|
|
|
|
|
|
color: #ff4d4f;
|
2026-05-01 20:39:09 +08:00
|
|
|
|
content: '*';
|
2026-04-25 21:36:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__footer {
|
|
|
|
|
|
position: sticky;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
padding: 16px 32px;
|
|
|
|
|
|
border-top: 1px solid #edf2f7;
|
|
|
|
|
|
background: rgba(255, 255, 255, 0.96);
|
|
|
|
|
|
backdrop-filter: blur(8px);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 900px) {
|
|
|
|
|
|
.imitation-generate-page__field-grid {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__capability-row {
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.imitation-generate-page__step-line::before,
|
|
|
|
|
|
.imitation-generate-page__step-line::after {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|