Files
geo/apps/admin-web/src/views/CustomGenerateView.vue
T
root 765dae4bf1
Frontend CI / Frontend (push) Successful in 5m6s
Backend CI / Backend (push) Successful in 16m45s
fix task article link drawer
2026-05-14 21:14:27 +08:00

190 lines
4.5 KiB
Vue

<script setup lang="ts">
import { ClockCircleOutlined, ThunderboltOutlined } from '@ant-design/icons-vue'
import { ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import CustomArticleTab from '@/components/CustomArticleTab.vue'
import InstantGenerateModal from '@/components/InstantGenerateModal.vue'
import InstantTaskTab from '@/components/InstantTaskTab.vue'
import PromptRuleTab from '@/components/PromptRuleTab.vue'
import ScheduleTaskModal from '@/components/ScheduleTaskModal.vue'
import ScheduleTaskTab from '@/components/ScheduleTaskTab.vue'
const { t } = useI18n()
const route = useRoute()
const router = useRouter()
const customTabs = ['articles', 'instantTasks', 'scheduleTasks', 'promptRules'] as const
type CustomTab = (typeof customTabs)[number]
const activeTab = ref<CustomTab>(normalizeCustomTab(route.query.tab))
const instantModalOpen = ref(false)
const scheduleModalOpen = ref(false)
function normalizeCustomTab(value: unknown): CustomTab {
const tab = Array.isArray(value) ? value[0] : value
return customTabs.includes(tab as CustomTab) ? (tab as CustomTab) : 'articles'
}
watch(
() => route.query.tab,
(tab) => {
const normalized = normalizeCustomTab(tab)
if (activeTab.value !== normalized) {
activeTab.value = normalized
}
},
)
watch(
activeTab,
(tab) => {
if (route.query.tab === tab) {
return
}
void router.replace({
name: 'articles-custom',
query: {
...route.query,
tab,
},
})
},
{ immediate: true },
)
function openInstantModal(): void {
instantModalOpen.value = true
}
function openScheduleModal(): void {
scheduleModalOpen.value = true
}
</script>
<template>
<div class="custom-view">
<section class="custom-view__cards">
<div class="custom-view__card custom-view__card--instant" @click="openInstantModal">
<div class="custom-view__card-icon custom-view__card-icon--instant">
<ThunderboltOutlined />
</div>
<div>
<h4>{{ t('custom.cards.instantTitle') }}</h4>
<p>{{ t('custom.cards.instantDesc') }}</p>
</div>
</div>
<div class="custom-view__card custom-view__card--schedule" @click="openScheduleModal">
<div class="custom-view__card-icon custom-view__card-icon--schedule">
<ClockCircleOutlined />
</div>
<div>
<h4>{{ t('custom.cards.scheduleTitle') }}</h4>
<p>{{ t('custom.cards.scheduleDesc') }}</p>
</div>
</div>
</section>
<section class="custom-view__tabs-card">
<a-tabs v-model:activeKey="activeTab">
<a-tab-pane key="articles" :tab="t('custom.tabs.articles')">
<CustomArticleTab />
</a-tab-pane>
<a-tab-pane key="instantTasks" :tab="t('custom.tabs.instantTasks')">
<InstantTaskTab />
</a-tab-pane>
<a-tab-pane key="scheduleTasks" :tab="t('custom.tabs.scheduleTasks')">
<ScheduleTaskTab />
</a-tab-pane>
<a-tab-pane key="promptRules" :tab="t('custom.tabs.promptRules')">
<PromptRuleTab />
</a-tab-pane>
</a-tabs>
</section>
<InstantGenerateModal v-model:open="instantModalOpen" />
<ScheduleTaskModal v-model:open="scheduleModalOpen" />
</div>
</template>
<style scoped>
.custom-view {
display: flex;
flex-direction: column;
gap: 22px;
}
.custom-view__cards {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.custom-view__card {
display: flex;
align-items: center;
gap: 16px;
padding: 20px 24px;
background: #fff;
border: 1px solid #e6edf5;
border-radius: 12px;
cursor: pointer;
transition:
transform 0.2s,
box-shadow 0.2s;
}
.custom-view__card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05);
}
.custom-view__card h4 {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: #141414;
}
.custom-view__card p {
margin: 0;
font-size: 13px;
color: #8c8c8c;
}
.custom-view__card-icon {
flex-shrink: 0;
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
}
.custom-view__card-icon--instant {
background: #fff7e6;
color: #fa8c16;
}
.custom-view__card-icon--schedule {
background: #e6f7ff;
color: #1677ff;
}
.custom-view__tabs-card {
padding: 24px;
background: #fff;
border: 1px solid #e6edf5;
border-radius: 12px;
}
@media (max-width: 720px) {
.custom-view__cards {
grid-template-columns: 1fr;
}
}
</style>