feat: add AddChannelDialog component and integrate channel settings in TaskCenter
This commit is contained in:
@@ -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>
|
||||
|
||||
185
src/pages/home/components/AddChannelDialog.vue
Normal file
185
src/pages/home/components/AddChannelDialog.vue
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user