style: 更新多个组件以使用分段控件替代按钮组
This commit is contained in:
parent
edc4caaf9c
commit
be40799af9
@ -350,9 +350,7 @@ def check_and_migrate(db_path: str):
|
||||
logger.warning(f" - {issue}")
|
||||
|
||||
if os.path.exists(db_path):
|
||||
logger.info(
|
||||
"建议运行迁移脚本: docker exec api-dev python /app/scripts/migrate_user_soft_delete.py"
|
||||
)
|
||||
logger.info("建议运行迁移脚本: docker exec api-dev python /app/scripts/migrate_user_soft_delete.py")
|
||||
|
||||
migrator = DatabaseMigrator(db_path)
|
||||
|
||||
|
||||
@ -234,7 +234,7 @@
|
||||
<a-modal
|
||||
v-model:open="toolsModalOpen"
|
||||
title="选择工具"
|
||||
:width="600"
|
||||
:width="800"
|
||||
:footer="null"
|
||||
:maskClosable="false"
|
||||
class="tools-modal"
|
||||
@ -569,7 +569,7 @@ watch(() => props.isOpen, (newVal) => {
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@padding-bottom: 40px;
|
||||
@padding-bottom: 0px;
|
||||
.agent-config-sidebar {
|
||||
position: relative;
|
||||
width: 0;
|
||||
@ -642,7 +642,7 @@ watch(() => props.isOpen, (newVal) => {
|
||||
|
||||
.sidebar-footer {
|
||||
position: sticky;
|
||||
bottom: 16px;
|
||||
bottom: 0px;
|
||||
padding: 12px 0;
|
||||
border-top: 1px solid var(--gray-100);
|
||||
background: #fff;
|
||||
@ -1159,4 +1159,4 @@ watch(() => props.isOpen, (newVal) => {
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -9,36 +9,10 @@
|
||||
<div class="task-center">
|
||||
<div class="task-toolbar">
|
||||
<div class="task-filter-group">
|
||||
<a-button-group>
|
||||
<a-button
|
||||
:type="isActiveFilter('all') ? 'primary' : 'default'"
|
||||
@click="setFilter('all')"
|
||||
>
|
||||
全部
|
||||
<span class="filter-count">{{ totalCount }}</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
:type="isActiveFilter('active') ? 'primary' : 'default'"
|
||||
@click="setFilter('active')"
|
||||
>
|
||||
进行中
|
||||
<span class="filter-count">{{ inProgressCount }}</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
:type="isActiveFilter('success') ? 'primary' : 'default'"
|
||||
@click="setFilter('success')"
|
||||
>
|
||||
已完成
|
||||
<span class="filter-count">{{ completedCount }}</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
:type="isActiveFilter('failed') ? 'primary' : 'default'"
|
||||
@click="setFilter('failed')"
|
||||
>
|
||||
失败
|
||||
<span class="filter-count">{{ failedCount }}</span>
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
<a-segmented
|
||||
v-model:value="statusFilter"
|
||||
:options="taskFilterOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="task-toolbar-actions">
|
||||
<a-button
|
||||
@ -135,7 +109,6 @@ import { computed, h, onBeforeUnmount, watch, ref } from 'vue'
|
||||
import { Modal } from 'ant-design-vue'
|
||||
import { useTaskerStore } from '@/stores/tasker'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ReloadOutlined } from '@ant-design/icons-vue'
|
||||
import { formatFullDateTime, formatRelative, parseToShanghai } from '@/utils/time'
|
||||
|
||||
const taskerStore = useTaskerStore()
|
||||
@ -146,6 +119,48 @@ const tasks = computed(() => sortedTasks.value)
|
||||
const loadingState = computed(() => Boolean(loading.value))
|
||||
const lastErrorState = computed(() => lastError.value)
|
||||
const statusFilter = ref('all')
|
||||
const inProgressCount = computed(
|
||||
() => tasks.value.filter((task) => ACTIVE_CLASS_STATUSES.has(task.status)).length
|
||||
)
|
||||
const completedCount = computed(() => tasks.value.filter((task) => task.status === 'success').length)
|
||||
const failedCount = computed(
|
||||
() => tasks.value.filter((task) => FAILED_STATUSES.has(task.status)).length
|
||||
)
|
||||
const totalCount = computed(() => tasks.value.length)
|
||||
const taskFilterOptions = computed(() => [
|
||||
{
|
||||
label: () =>
|
||||
h('span', { class: 'task-filter-option' }, [
|
||||
'全部',
|
||||
h('span', { class: 'filter-count' }, totalCount.value)
|
||||
]),
|
||||
value: 'all'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h('span', { class: 'task-filter-option' }, [
|
||||
'进行中',
|
||||
h('span', { class: 'filter-count' }, inProgressCount.value)
|
||||
]),
|
||||
value: 'active'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h('span', { class: 'task-filter-option' }, [
|
||||
'已完成',
|
||||
h('span', { class: 'filter-count' }, completedCount.value)
|
||||
]),
|
||||
value: 'success'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h('span', { class: 'task-filter-option' }, [
|
||||
'失败',
|
||||
h('span', { class: 'filter-count' }, failedCount.value)
|
||||
]),
|
||||
value: 'failed'
|
||||
}
|
||||
])
|
||||
|
||||
const filteredTasks = computed(() => {
|
||||
const list = tasks.value
|
||||
@ -321,22 +336,6 @@ function canCancel(task) {
|
||||
return ['pending', 'running', 'queued'].includes(task.status) && !task.cancel_requested
|
||||
}
|
||||
|
||||
const inProgressCount = computed(
|
||||
() => tasks.value.filter((task) => ACTIVE_CLASS_STATUSES.has(task.status)).length
|
||||
)
|
||||
const completedCount = computed(() => tasks.value.filter((task) => task.status === 'success').length)
|
||||
const failedCount = computed(
|
||||
() => tasks.value.filter((task) => FAILED_STATUSES.has(task.status)).length
|
||||
)
|
||||
const totalCount = computed(() => tasks.value.length)
|
||||
|
||||
function setFilter(value) {
|
||||
statusFilter.value = value
|
||||
}
|
||||
|
||||
function isActiveFilter(value) {
|
||||
return statusFilter.value === value
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.task-center {
|
||||
@ -365,13 +364,7 @@ function isActiveFilter(value) {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.task-filter-group :deep(.ant-btn) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.filter-count {
|
||||
:deep(.filter-count) {
|
||||
margin-left: 2px;
|
||||
font-size: 12px;
|
||||
color: #94a3b8;
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
:footer="null"
|
||||
>
|
||||
<a-space style="margin-bottom: 16px">
|
||||
<a-radio-group v-model:value="feedbackFilter" @change="loadFeedbacks">
|
||||
<a-radio-button value="all">全部</a-radio-button>
|
||||
<a-radio-button value="like">点赞</a-radio-button>
|
||||
<a-radio-button value="dislike">点踩</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-segmented
|
||||
v-model:value="feedbackFilter"
|
||||
:options="feedbackOptions"
|
||||
@change="loadFeedbacks"
|
||||
/>
|
||||
</a-space>
|
||||
|
||||
<!-- 卡片列表 -->
|
||||
@ -92,7 +92,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { LikeOutlined, DislikeOutlined, ClockCircleOutlined } from '@ant-design/icons-vue'
|
||||
import { dashboardApi } from '@/apis/dashboard_api'
|
||||
@ -113,6 +113,11 @@ const modalVisible = ref(false)
|
||||
const feedbacks = ref([])
|
||||
const loadingFeedbacks = ref(false)
|
||||
const feedbackFilter = ref('all')
|
||||
const feedbackOptions = [
|
||||
{ label: '全部', value: 'all' },
|
||||
{ label: '点赞', value: 'like' },
|
||||
{ label: '点踩', value: 'dislike' }
|
||||
]
|
||||
|
||||
// 显示模态框
|
||||
const show = () => {
|
||||
|
||||
@ -18,19 +18,19 @@
|
||||
<h3>检索配置</h3>
|
||||
<div class="section">
|
||||
<div class="card card-select">
|
||||
<span class="label">对话模型</span>
|
||||
<span class="label">{{ items?.default_model?.des || '默认对话模型' }}</span>
|
||||
<ModelSelectorComponent
|
||||
@select-model="handleChatModelSelect"
|
||||
:model_name="configStore.config?.model_name"
|
||||
:model_provider="configStore.config?.model_provider"
|
||||
:model_spec="configStore.config?.default_model"
|
||||
placeholder="请选择默认模型"
|
||||
/>
|
||||
</div>
|
||||
<div class="card card-select">
|
||||
<span class="label">{{ items?.fast_model.des }}</span>
|
||||
<ModelSelectorComponent
|
||||
@select-model="handleFastModelSelect"
|
||||
:model_name="fastModelName"
|
||||
:model_provider="fastModelProvider"
|
||||
:model_spec="configStore.config?.fast_model"
|
||||
placeholder="请选择模型"
|
||||
/>
|
||||
</div>
|
||||
<div class="card card-select">
|
||||
@ -109,8 +109,8 @@
|
||||
<span class="label">{{ items?.content_guard_llm_model.des }}</span>
|
||||
<ModelSelectorComponent
|
||||
@select-model="handleContentGuardModelSelect"
|
||||
:model_name="contentGuardModelName"
|
||||
:model_provider="contentGuardModelProvider"
|
||||
:model_spec="configStore.config?.content_guard_llm_model"
|
||||
placeholder="请选择模型"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -251,45 +251,22 @@ const updateWindowWidth = () => {
|
||||
state.windowWidth = window?.innerWidth || 0
|
||||
}
|
||||
|
||||
const handleChatModelSelect = ({ provider, name }) => {
|
||||
configStore.setConfigValues({
|
||||
model_provider: provider,
|
||||
model_name: name,
|
||||
})
|
||||
const handleChatModelSelect = (spec) => {
|
||||
if (typeof spec === 'string' && spec) {
|
||||
configStore.setConfigValue('default_model', spec)
|
||||
}
|
||||
}
|
||||
|
||||
const fastModelProvider = computed(() => {
|
||||
const fastModel = configStore.config?.fast_model
|
||||
if (!fastModel) return ''
|
||||
return fastModel.split('/')[0]
|
||||
})
|
||||
|
||||
const fastModelName = computed(() => {
|
||||
const fastModel = configStore.config?.fast_model
|
||||
if (!fastModel) return ''
|
||||
const parts = fastModel.split('/')
|
||||
return parts.slice(1).join('/')
|
||||
})
|
||||
|
||||
const handleFastModelSelect = ({ provider, name }) => {
|
||||
configStore.setConfigValue('fast_model', `${provider}/${name}`)
|
||||
const handleFastModelSelect = (spec) => {
|
||||
if (typeof spec === 'string' && spec) {
|
||||
configStore.setConfigValue('fast_model', spec)
|
||||
}
|
||||
}
|
||||
|
||||
const contentGuardModelProvider = computed(() => {
|
||||
const contentGuardModel = configStore.config?.content_guard_llm_model
|
||||
if (!contentGuardModel) return ''
|
||||
return contentGuardModel.split('/')[0]
|
||||
})
|
||||
|
||||
const contentGuardModelName = computed(() => {
|
||||
const contentGuardModel = configStore.config?.content_guard_llm_model
|
||||
if (!contentGuardModel) return ''
|
||||
const parts = contentGuardModel.split('/')
|
||||
return parts.slice(1).join('/')
|
||||
})
|
||||
|
||||
const handleContentGuardModelSelect = ({ provider, name }) => {
|
||||
configStore.setConfigValue('content_guard_llm_model', `${provider}/${name}`)
|
||||
const handleContentGuardModelSelect = (spec) => {
|
||||
if (typeof spec === 'string' && spec) {
|
||||
configStore.setConfigValue('content_guard_llm_model', spec)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -381,7 +358,7 @@ const openLink = (url) => {
|
||||
|
||||
.setting-container {
|
||||
--setting-header-height: 55px;
|
||||
max-width: 870px;
|
||||
max-width: 1054px;
|
||||
}
|
||||
|
||||
.setting-header {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user