feat(home): 实现首页消息、流程和项目管理界面
- 添加 MessageDetail 和 MessageList 组件用于消息管理 - 添加 WorkflowDetail 和 WorkflowList 组件用于流程管理 - 添加 ProjectDetail 和 ProjectList 组件用于项目管理 - 实现 FunctionNav 导航组件支持功能切换 - 创建 FeatureList 组件展示不同功能列表 - 开发 OperationSpace 组件提供操作空间详情展示 - 集成所有组件到 Home 主页面布局 - 添加 lucide 图标样式类定义 - 实现 useHome 组合式 API 提供数据管理和状态控制
This commit is contained in:
+5
-1
@@ -4,4 +4,8 @@
|
||||
|
||||
@utility input {
|
||||
@apply w-full outline-none ;
|
||||
}
|
||||
}
|
||||
|
||||
.lucide {
|
||||
@apply my-1.5 size-4;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<h3 class="font-bold text-lg">{{ item.title }}</h3>
|
||||
<p class="text-sm text-base-content/70 mt-1">{{ item.time }}</p>
|
||||
</div>
|
||||
|
||||
<div class="card bg-base-200">
|
||||
<div class="card-body p-4">
|
||||
<p class="text-sm">{{ item.content }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<button @click="emit('action', 'reply', item.id)" class="btn btn-sm btn-primary">
|
||||
回复
|
||||
</button>
|
||||
<button @click="emit('action', 'markRead', item.id)" class="btn btn-sm btn-outline">
|
||||
标记已读
|
||||
</button>
|
||||
<button @click="emit('action', 'delete', item.id)" class="btn btn-sm btn-ghost text-error">
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Message } from '@/composables/useHome'
|
||||
|
||||
defineProps<{
|
||||
item: Message
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
action: [action: string, id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<ul class="list bg-base-100 rounded-box shadow-md">
|
||||
<li class="p-4 pb-2 text-xs opacity-60 tracking-wide flex items-center justify-between">
|
||||
<span class="mr-auto">本周任务</span>
|
||||
<button class="cursor-pointer" title="新增">
|
||||
<SquarePlus />
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li class="list-row" v-for="item in items" :class="{
|
||||
'bg-primary': selectedId == item.id
|
||||
}" @click="emit('select', item.id)">
|
||||
<div class="list-col-grow">
|
||||
<div>{{ item.title }}</div>
|
||||
<div class="text-xs uppercase font-semibold opacity-60">{{ item.content }}</div>
|
||||
</div>
|
||||
<button class="btn btn-square btn-ghost">
|
||||
<Trash></Trash>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Message } from '@/composables/useHome'
|
||||
import { Trash, SquarePlus } from 'lucide-vue-next';
|
||||
|
||||
defineProps<{
|
||||
items: Message[]
|
||||
selectedId: number | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<h3 class="font-bold text-lg">{{ item.name }}</h3>
|
||||
<div class="flex gap-2 mt-2">
|
||||
<span class="badge badge-sm" :class="{
|
||||
'badge-info': item.status === '进行中',
|
||||
'badge-ghost': item.status === '规划中',
|
||||
'badge-success': item.status === '已完成',
|
||||
'badge-warning': item.status === '已暂停'
|
||||
}">
|
||||
{{ item.status }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-base-200">
|
||||
<div class="card-body p-4 space-y-3">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-sm text-base-content/70">项目负责人</span>
|
||||
<span class="text-sm font-medium">{{ item.manager }}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex justify-between text-xs mb-1">
|
||||
<span class="text-base-content/70">当前进度</span>
|
||||
<span class="font-medium">{{ item.progress }}%</span>
|
||||
</div>
|
||||
<progress class="progress progress-primary w-full" :value="item.progress" max="100"></progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<button @click="emit('action', 'view', item.id)" class="btn btn-sm btn-outline">
|
||||
查看详情
|
||||
</button>
|
||||
<button @click="emit('action', 'edit', item.id)" class="btn btn-sm btn-primary">
|
||||
编辑项目
|
||||
</button>
|
||||
<button @click="emit('action', 'addMember', item.id)" class="btn btn-sm btn-secondary">
|
||||
添加成员
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Project } from '@/composables/useHome'
|
||||
|
||||
defineProps<{
|
||||
item: Project
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
action: [action: string, id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<ul class="list bg-base-100 rounded-box shadow-md">
|
||||
<li class="p-4 pb-2 text-xs opacity-60 tracking-wide flex items-center justify-between">
|
||||
<span class="mr-auto">项目列表</span>
|
||||
<button class="cursor-pointer" title="新增">
|
||||
<SquarePlus />
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li class="list-row" v-for="item in items" :class="{
|
||||
'bg-primary': selectedId == item.id
|
||||
}" @click="emit('select', item.id)">
|
||||
<div class="list-col-grow">
|
||||
<div>{{ item.name }}</div>
|
||||
<div class="text-xs uppercase font-semibold opacity-60">{{ item.manager }}</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="badge badge-sm" :class="{
|
||||
'badge-info': item.status === '进行中',
|
||||
'badge-ghost': item.status === '规划中',
|
||||
'badge-success': item.status === '已完成',
|
||||
'badge-warning': item.status === '已暂停'
|
||||
}">
|
||||
{{ item.status }}
|
||||
</span>
|
||||
<progress class="progress progress-primary w-24" :value="item.progress" max="100"></progress>
|
||||
</div>
|
||||
<button class="btn btn-square btn-ghost">
|
||||
<Trash></Trash>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Project } from '@/composables/useHome'
|
||||
import { Trash, SquarePlus } from 'lucide-vue-next';
|
||||
|
||||
defineProps<{
|
||||
items: Project[]
|
||||
selectedId: number | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<h3 class="font-bold text-lg">{{ item.name }}</h3>
|
||||
<div class="flex gap-2 mt-2">
|
||||
<span class="badge badge-sm" :class="{
|
||||
'badge-info': item.status === '进行中',
|
||||
'badge-success': item.status === '已完成',
|
||||
'badge-ghost': item.status === '草稿',
|
||||
'badge-warning': item.status === '已暂停'
|
||||
}">
|
||||
{{ item.status }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-base-200">
|
||||
<div class="card-body p-4 space-y-2">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-sm text-base-content/70">创建人</span>
|
||||
<span class="text-sm font-medium">{{ item.creator }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-sm text-base-content/70">创建时间</span>
|
||||
<span class="text-sm font-medium">{{ item.createTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<button @click="emit('action', 'edit', item.id)" class="btn btn-sm btn-primary">
|
||||
编辑流程
|
||||
</button>
|
||||
<button @click="emit('action', 'view', item.id)" class="btn btn-sm btn-outline">
|
||||
查看流程图
|
||||
</button>
|
||||
<button @click="emit('action', 'start', item.id)" class="btn btn-sm btn-success" :disabled="item.status !== '草稿'">
|
||||
启动流程
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Workflow } from '@/composables/useHome'
|
||||
|
||||
defineProps<{
|
||||
item: Workflow
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
action: [action: string, id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<ul class="list bg-base-100 rounded-box shadow-md">
|
||||
<li class="p-4 pb-2 text-xs opacity-60 tracking-wide flex items-center justify-between">
|
||||
<span class="mr-auto">流程列表</span>
|
||||
<button class="cursor-pointer" title="新增">
|
||||
<SquarePlus />
|
||||
</button>
|
||||
</li>
|
||||
<li class="list-row" v-for="item in items" :class="{
|
||||
'bg-primary': selectedId == item.id
|
||||
}" @click="emit('select', item.id)">
|
||||
<div class="list-col-grow">
|
||||
<div>{{ item.name }}</div>
|
||||
<div class="text-xs uppercase font-semibold opacity-60">{{ item.creator }}</div>
|
||||
</div>
|
||||
<span class="badge badge-sm" :class="{
|
||||
'badge-info': item.status === '进行中',
|
||||
'badge-success': item.status === '已完成',
|
||||
'badge-ghost': item.status === '草稿',
|
||||
'badge-warning': item.status === '已暂停'
|
||||
}">
|
||||
{{ item.status }}
|
||||
</span>
|
||||
<button class="btn btn-square btn-ghost">
|
||||
<Trash></Trash>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Workflow } from '@/composables/useHome'
|
||||
import { Trash, SquarePlus } from 'lucide-vue-next';
|
||||
|
||||
defineProps<{
|
||||
items: Workflow[]
|
||||
selectedId: number | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<section class="card bg-base-100 shadow-sm h-full overflow-hidden">
|
||||
<div class="card-body p-0 h-full">
|
||||
<MessageList
|
||||
v-if="currentFunction === 'message'"
|
||||
:items="messages"
|
||||
:selected-id="selectedMessageId"
|
||||
@select="emit('selectMessage', $event)"
|
||||
/>
|
||||
|
||||
<WorkflowList
|
||||
v-else-if="currentFunction === 'workflow'"
|
||||
:items="workflows"
|
||||
:selected-id="selectedWorkflowId"
|
||||
@select="emit('selectWorkflow', $event)"
|
||||
/>
|
||||
|
||||
<ProjectList
|
||||
v-else
|
||||
:items="projects"
|
||||
:selected-id="selectedProjectId"
|
||||
@select="emit('selectProject', $event)"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FunctionType, Message, Workflow, Project } from '@/composables/useHome'
|
||||
import MessageList from '../common/MessageList.vue'
|
||||
import WorkflowList from '../common/WorkflowList.vue'
|
||||
import ProjectList from '../common/ProjectList.vue'
|
||||
|
||||
defineProps<{
|
||||
currentFunction: FunctionType
|
||||
messages: Message[]
|
||||
workflows: Workflow[]
|
||||
projects: Project[]
|
||||
selectedMessageId: number | null
|
||||
selectedWorkflowId: number | null
|
||||
selectedProjectId: number | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
selectMessage: [id: number]
|
||||
selectWorkflow: [id: number]
|
||||
selectProject: [id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<ul class="menu w-full grow">
|
||||
<!-- List item -->
|
||||
<li v-for="item in buttons" class="mb-1">
|
||||
<button class="is-drawer-close:tooltip is-drawer-close:tooltip-right" :class="{
|
||||
'bg-primary': currentFunction == item.type
|
||||
}" :data-tip="item.label" @click="emit('select', item.type)">
|
||||
<component :is="item.icon"></component>
|
||||
<span class="is-drawer-close:hidden">{{ item.label }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FunctionType } from '@/composables/useHome'
|
||||
import { Mail, Workflow, FolderKanban } from 'lucide-vue-next'
|
||||
|
||||
defineProps<{
|
||||
currentFunction: FunctionType
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [func: FunctionType]
|
||||
}>()
|
||||
|
||||
const buttons = [
|
||||
{ type: 'message' as FunctionType, label: '消息列表', icon: Mail },
|
||||
{ type: 'workflow' as FunctionType, label: '流程设计', icon: Workflow },
|
||||
{ type: 'project' as FunctionType, label: '项目管理', icon: FolderKanban },
|
||||
] as const
|
||||
</script>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<section class="card bg-base-100 shadow-sm h-full overflow-hidden">
|
||||
<div class="card-body p-4">
|
||||
<h2 class="font-bold text-base mb-3">操作空间</h2>
|
||||
|
||||
<div class="overflow-y-auto h-[calc(100%-40px)]">
|
||||
<!-- 空状态 -->
|
||||
<div
|
||||
v-if="!selectedMessage && !selectedWorkflow && !selectedProject"
|
||||
class="flex flex-col items-center justify-center h-full text-base-content/50"
|
||||
>
|
||||
<div class="text-4xl mb-2">👈</div>
|
||||
<p class="text-sm">请从列表中选择一个项目查看详情</p>
|
||||
</div>
|
||||
|
||||
<!-- 消息详情 -->
|
||||
<MessageDetail
|
||||
v-if="currentFunction === 'message' && selectedMessage"
|
||||
:item="selectedMessage"
|
||||
@action="(action, id) => emit('messageAction', action, id)"
|
||||
/>
|
||||
|
||||
<!-- 流程详情 -->
|
||||
<WorkflowDetail
|
||||
v-else-if="currentFunction === 'workflow' && selectedWorkflow"
|
||||
:item="selectedWorkflow"
|
||||
@action="(action, id) => emit('workflowAction', action, id)"
|
||||
/>
|
||||
|
||||
<!-- 项目详情 -->
|
||||
<ProjectDetail
|
||||
v-else-if="currentFunction === 'project' && selectedProject"
|
||||
:item="selectedProject"
|
||||
@action="(action, id) => emit('projectAction', action, id)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FunctionType, Message, Workflow, Project } from '@/composables/useHome'
|
||||
import MessageDetail from '../common/MessageDetail.vue'
|
||||
import WorkflowDetail from '../common/WorkflowDetail.vue'
|
||||
import ProjectDetail from '../common/ProjectDetail.vue'
|
||||
|
||||
defineProps<{
|
||||
currentFunction: FunctionType
|
||||
selectedMessage: Message | undefined
|
||||
selectedWorkflow: Workflow | undefined
|
||||
selectedProject: Project | undefined
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
messageAction: [action: string, id: number]
|
||||
workflowAction: [action: string, id: number]
|
||||
projectAction: [action: string, id: number]
|
||||
}>()
|
||||
</script>
|
||||
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
|
||||
|
||||
<div class="drawer lg:drawer-open">
|
||||
<input id="my-drawer-4" type="checkbox" class="drawer-toggle" />
|
||||
<div class="drawer-content flex flex-col">
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar w-full bg-base-300">
|
||||
<label for="my-drawer-4" aria-label="打开侧边栏" class="btn btn-square btn-ghost">
|
||||
<!-- Sidebar toggle icon -->
|
||||
<PanelLeftOpen class="[.drawer-toggle:checked~.drawer-content_.navbar_&]:hidden" />
|
||||
<PanelLeftClose class="[.drawer-toggle:checked~.drawer-content_.navbar_&]:block hidden" />
|
||||
</label>
|
||||
<div class="px-4">{{ currentFunction }}</div>
|
||||
</nav>
|
||||
<!-- Page content here -->
|
||||
<div class="p-4 flex-1 flex flex-row gap-1">
|
||||
<div class="col-span-5 min-w-[300px]">
|
||||
<FeatureList :current-function="currentFunction" :messages="messages" :workflows="workflows"
|
||||
:projects="projects" :selected-message-id="selectedMessageId" :selected-workflow-id="selectedWorkflowId"
|
||||
:selected-project-id="selectedProjectId" @select-message="selectMessage" @select-workflow="selectWorkflow"
|
||||
@select-project="selectProject" />
|
||||
</div>
|
||||
|
||||
<!-- 右侧操作空间 -->
|
||||
<div class="col-span-5 flex-1">
|
||||
<OperationSpace :current-function="currentFunction" :selected-message="selectedMessage"
|
||||
:selected-workflow="selectedWorkflow" :selected-project="selectedProject"
|
||||
@message-action="handleMessageAction" @workflow-action="handleWorkflowAction"
|
||||
@project-action="handleProjectAction" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="drawer-side is-drawer-close:overflow-visible">
|
||||
<label for="my-drawer-4" aria-label="close sidebar" class="drawer-overlay"></label>
|
||||
<div class="flex min-h-full flex-col items-start bg-base-200 is-drawer-close:w-14 is-drawer-open:w-64">
|
||||
<!-- Sidebar content here -->
|
||||
<FunctionNav :current-function="currentFunction" @select="selectFunction" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useHome } from '@/composables/useHome'
|
||||
import FunctionNav from './FunctionNav.vue'
|
||||
import FeatureList from './FeatureList.vue'
|
||||
import OperationSpace from './OperationSpace.vue'
|
||||
import { PanelLeftClose, PanelLeftOpen } from 'lucide-vue-next'
|
||||
|
||||
const {
|
||||
currentFunction,
|
||||
messages,
|
||||
workflows,
|
||||
projects,
|
||||
selectedMessageId,
|
||||
selectedWorkflowId,
|
||||
selectedProjectId,
|
||||
selectedMessage,
|
||||
selectedWorkflow,
|
||||
selectedProject,
|
||||
selectFunction,
|
||||
selectMessage,
|
||||
selectWorkflow,
|
||||
selectProject,
|
||||
handleMessageAction,
|
||||
handleWorkflowAction,
|
||||
handleProjectAction,
|
||||
} = useHome()
|
||||
</script>
|
||||
@@ -0,0 +1,137 @@
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
export type FunctionType = 'message' | 'workflow' | 'project'
|
||||
|
||||
export interface Message {
|
||||
id: number
|
||||
title: string
|
||||
content: string
|
||||
time: string
|
||||
unread?: boolean
|
||||
}
|
||||
|
||||
export interface Workflow {
|
||||
id: number
|
||||
name: string
|
||||
status: '进行中' | '已完成' | '草稿' | '已暂停'
|
||||
creator: string
|
||||
createTime: string
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
id: number
|
||||
name: string
|
||||
status: '进行中' | '规划中' | '已完成' | '已暂停'
|
||||
progress: number
|
||||
manager: string
|
||||
}
|
||||
|
||||
export function useHome() {
|
||||
const currentFunction = ref<FunctionType>('message')
|
||||
const selectedMessageId = ref<number | null>(null)
|
||||
const selectedWorkflowId = ref<number | null>(null)
|
||||
const selectedProjectId = ref<number | null>(null)
|
||||
|
||||
// 模拟数据
|
||||
const messages= ref<Message[]>([
|
||||
{ id: 1, title: '系统通知', content: '欢迎使用角色管理系统,祝您工作顺利!', time: '2026-03-10 10:00', unread: true },
|
||||
{ id: 2, title: '任务提醒', content: '您有一个待处理的任务需要在今天完成。', time: '2026-03-10 11:30', unread: true },
|
||||
{ id: 3, title: '审批请求', content: '新的流程审批等待您的处理,请及时查看。', time: '2026-03-10 14:20', unread: false },
|
||||
{ id: 4, title: '会议通知', content: '明天上午 10 点召开项目进度会议,请准时参加。', time: '2026-03-10 15:00', unread: false },
|
||||
])
|
||||
|
||||
const workflows = ref<Workflow[]>([
|
||||
{ id: 1, name: '请假审批流程', status: '进行中', creator: '张三', createTime: '2026-03-09' },
|
||||
{ id: 2, name: '采购申请流程', status: '已完成', creator: '李四', createTime: '2026-03-08' },
|
||||
{ id: 3, name: '项目立项流程', status: '草稿', creator: '王五', createTime: '2026-03-10' },
|
||||
{ id: 4, name: '费用报销流程', status: '进行中', creator: '赵六', createTime: '2026-03-07' },
|
||||
])
|
||||
|
||||
const projects = ref<Project[]>([
|
||||
{ id: 1, name: 'ERP 系统升级', status: '进行中', progress: 65, manager: '张三' },
|
||||
{ id: 2, name: 'CRM 客户管理系统', status: '规划中', progress: 20, manager: '李四' },
|
||||
{ id: 3, name: '数据分析平台', status: '已完成', progress: 100, manager: '王五' },
|
||||
{ id: 4, name: '移动办公 APP', status: '进行中', progress: 45, manager: '赵六' },
|
||||
])
|
||||
|
||||
// 计算属性:获取当前选中的项目
|
||||
const selectedMessage = computed(() =>
|
||||
messages.value.find(m => m.id === selectedMessageId.value)
|
||||
)
|
||||
|
||||
const selectedWorkflow = computed(() =>
|
||||
workflows.value.find(w => w.id === selectedWorkflowId.value)
|
||||
)
|
||||
|
||||
const selectedProject = computed(() =>
|
||||
projects.value.find(p => p.id === selectedProjectId.value)
|
||||
)
|
||||
|
||||
// 切换功能
|
||||
const selectFunction = (func: FunctionType) => {
|
||||
currentFunction.value = func
|
||||
// 清空其他选中项
|
||||
selectedMessageId.value = null
|
||||
selectedWorkflowId.value = null
|
||||
selectedProjectId.value = null
|
||||
}
|
||||
|
||||
// 选择列表项
|
||||
const selectMessage = (id: number) => {
|
||||
selectedMessageId.value = id
|
||||
// 标记为已读
|
||||
const msg = messages.value.find(m => m.id === id)
|
||||
if (msg) msg.unread = false
|
||||
}
|
||||
|
||||
const selectWorkflow = (id: number) => {
|
||||
selectedWorkflowId.value = id
|
||||
}
|
||||
|
||||
const selectProject = (id: number) => {
|
||||
selectedProjectId.value = id
|
||||
}
|
||||
|
||||
// 操作处理函数
|
||||
const handleMessageAction = (action: string, messageId: number) => {
|
||||
console.log(`处理消息 ${messageId}: ${action}`)
|
||||
// TODO: 实现具体业务逻辑
|
||||
}
|
||||
|
||||
const handleWorkflowAction = (action: string, workflowId: number) => {
|
||||
console.log(`处理流程 ${workflowId}: ${action}`)
|
||||
// TODO: 实现具体业务逻辑
|
||||
}
|
||||
|
||||
const handleProjectAction = (action: string, projectId: number) => {
|
||||
console.log(`处理项目 ${projectId}: ${action}`)
|
||||
// TODO: 实现具体业务逻辑
|
||||
}
|
||||
|
||||
return {
|
||||
// 状态
|
||||
currentFunction,
|
||||
selectedMessageId,
|
||||
selectedWorkflowId,
|
||||
selectedProjectId,
|
||||
|
||||
// 数据
|
||||
messages,
|
||||
workflows,
|
||||
projects,
|
||||
|
||||
// 计算属性
|
||||
selectedMessage,
|
||||
selectedWorkflow,
|
||||
selectedProject,
|
||||
|
||||
// 方法
|
||||
selectFunction,
|
||||
selectMessage,
|
||||
selectWorkflow,
|
||||
selectProject,
|
||||
handleMessageAction,
|
||||
handleWorkflowAction,
|
||||
handleProjectAction,
|
||||
}
|
||||
}
|
||||
+2
-37
@@ -1,42 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { RouterLink } from 'vue-router'
|
||||
import HomePage from '@/components/home/index.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="container">
|
||||
<h1>Home Page</h1>
|
||||
<p>Welcome to the home page!</p>
|
||||
<nav>
|
||||
<RouterLink to="/">Home</RouterLink> |
|
||||
<RouterLink to="/about">About</RouterLink>
|
||||
<RouterLink to="/login">登录</RouterLink>
|
||||
</nav>
|
||||
</main>
|
||||
<HomePage />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
margin: 0;
|
||||
padding-top: 10vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
nav {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: none;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user