feat: add AddChannelDialog component and integrate channel settings in TaskCenter

This commit is contained in:
duanshuwen
2026-04-15 23:02:43 +08:00
parent 0191969a1b
commit ad898b757a
3 changed files with 203 additions and 2 deletions

View File

@@ -5,9 +5,13 @@
</div>
<div class="grid grid-cols-2 gap-4 max-[800px]:grid-cols-1">
<div v-for="item in taskList" :key="item.id" class="flex gap-3 items-start p-3.5
<div v-for="item in taskList" :key="item.id" class="relative flex gap-3 items-start p-3.5
rounded-[10px] border border-[#dfeaf6] dark:border-[#2a2a2d] bg-white dark:bg-[#1f1f22] cursor-pointer hover:bg-[#F5F7FA] dark:hover:bg-[#2a2a2d]"
@click="handleTaskItem(item)">
<Settings v-if="item.type === 'channel'"
class="absolute top-2 right-2 w-4 h-4 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 cursor-pointer"
@click.stop="handleChannelSetting" />
<div class="w-11 h-11 bg-[#EFF6FF] dark:bg-[#222225] rounded-lg
border border-dashed border-[#9fc0e8] dark:border-gray-700
flex items-center justify-center
@@ -30,6 +34,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import { Settings } from '@lucide/vue'
import { taskCenterList, taskCenterItem } from '@constant/taskCenterList'
import { channels } from '@constant/channel'
import emitter from '@utils/emitter'
@@ -40,11 +45,14 @@ const taskList = computed(() => taskCenterList)
const handleTaskItem = (item: taskCenterItem) => {
// 一键打开各渠道
if (item.type === 'channel') {
window.api.openChannel(channels)
window.api.openChannel(channels.value)
return
}
// 操作房型
emitter.emit('OPERATION_CHANNEL', item)
}
// 渠道设置
const handleChannelSetting = () => emitter.emit('ADD_CHANNEL')
</script>

View File

@@ -0,0 +1,185 @@
<template>
<el-dialog v-model="isVisible" width="480" align-center class="dark-dialog">
<template #title>
<span>添加渠道</span>
</template>
<el-form :model="form" :rules="rules" ref="formRef" label-position="top" class="pl-4 pr-4 pt-4 dark-form">
<el-form-item prop="channelName">
<template #label>
<span>渠道名称</span>
</template>
<el-input v-model="form.channelName" placeholder="请输入渠道名称" />
</el-form-item>
<el-form-item prop="channelUrl">
<template #label>
<span>渠道链接</span>
</template>
<el-input v-model="form.channelUrl" placeholder="请输入渠道链接" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button class="cancel-btn" @click="cancel">取消</el-button>
<el-button type="primary" @click="confirm">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const isVisible = ref(false)
const formRef = ref()
const form = ref({
channelName: '',
channelUrl: ''
})
const rules = ref({
channelName: [
{ required: true, message: '请输入渠道名称', trigger: 'blur' },
],
channelUrl: [
{ required: true, message: '请输入渠道链接', trigger: 'blur' },
]
})
const open = () => {
isVisible.value = true
}
const close = () => {
isVisible.value = false
}
const reset = () => {
form.value.channelName = ''
form.value.channelUrl = ''
formRef.value?.resetFields()
}
const cancel = () => {
close()
reset()
}
const confirm = () => {
formRef.value.validate((valid: boolean) => {
if (!valid) {
return
}
close()
reset()
})
}
defineExpose({
open,
close,
})
</script>
<style scoped>
.dark-dialog {
background-color: #F4F3EB !important;
border-radius: 20px !important;
overflow: hidden;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15) !important;
}
.dark .dark-dialog {
background-color: #1f1f22 !important;
}
.dark-dialog :deep(.el-dialog__header) {
margin-right: 0;
padding: 20px 24px 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.dark .dark-dialog :deep(.el-dialog__header) {
border-bottom-color: rgba(255, 255, 255, 0.06);
}
.dark-dialog :deep(.el-dialog__title) {
font-size: 18px;
font-weight: 600;
color: #171717;
}
.dark .dark-dialog :deep(.el-dialog__title) {
color: #f3f4f6;
}
.dark-dialog :deep(.el-dialog__body) {
padding: 0 !important;
}
.dark-form :deep(.el-form-item__label) {
font-weight: 500;
color: #4B4B4B !important;
}
.dark .dark-form :deep(.el-form-item__label) {
color: #9ca3af !important;
}
.dark-form :deep(.el-input__wrapper) {
background-color: #EDECE4 !important;
border-radius: 12px !important;
box-shadow: none !important;
border: 1px solid transparent !important;
}
.dark .dark-form :deep(.el-input__wrapper) {
background-color: #222225 !important;
}
.dark-form :deep(.el-input__wrapper.is-focus) {
border-color: #3B6DE8 !important;
}
.dark-form :deep(.el-input__inner) {
color: #171717 !important;
}
.dark .dark-form :deep(.el-input__inner) {
color: #f3f4f6 !important;
}
.dark-form :deep(.el-input__inner::placeholder) {
color: #99A0AE !important;
}
.dark .dark-form :deep(.el-input__inner::placeholder) {
color: #6b7280 !important;
}
.dialog-footer {
padding: 16px 24px 20px;
display: flex;
justify-content: flex-end;
gap: 12px;
}
.cancel-btn {
background-color: #EDECE4 !important;
border-color: transparent !important;
color: #4B4B4B !important;
}
.cancel-btn:hover {
background-color: #E5E4DC !important;
color: #171717 !important;
}
.dark .cancel-btn {
background-color: #222225 !important;
color: #9ca3af !important;
}
.dark .cancel-btn:hover {
background-color: #2a2a2d !important;
color: #f3f4f6 !important;
}
</style>

View File

@@ -10,6 +10,8 @@
</div>
<TaskOperationDialog ref="taskOperationDialog" />
<AddChannelDialog ref="addChannelDialog" />
</layout>
</template>
@@ -17,6 +19,7 @@
import { ref, onMounted, onBeforeUnmount } from 'vue'
import TaskList from '../../components/TaskList/index.vue'
import TaskOperationDialog from './components/TaskOperationDialog.vue'
import AddChannelDialog from './components/AddChannelDialog.vue'
import ChatHistory from './ChatHistory.vue'
import ChatBox from './ChatBox.vue'
import TaskCenter from './TaskCenter.vue'
@@ -27,6 +30,7 @@ import emitter from '@src/utils/emitter'
const chatStore = useChatStore()
const providerStore = useProviderStore()
const taskOperationDialog = ref()
const addChannelDialog = ref()
onMounted(async () => {
await providerStore.init()
@@ -49,4 +53,8 @@ const handleSelectChat = (conversationId: string) => {
emitter.on('OPERATION_CHANNEL', (item: any) => {
taskOperationDialog.value?.open(item)
})
emitter.on('ADD_CHANNEL', () => {
addChannelDialog.value?.open()
})
</script>