feat(collaboration): 添加完整协同办公模块及设备管理和文档协同页面
- 新增现代化企业协同办公系统,包含概览仪表板、项目管理、任务看板和文档协同 - 使用Vue 3、TypeScript、Nuxt.js及Ant Design Vue实现前端结构和交互 - 设计响应式布局、渐变背景及毛玻璃视觉效果,优化移动端体验 - 创建设备管理页面,实现设备台账、巡检、维修和报警管理 - 新建文档协同页面,支持文档搜索、筛选、分类显示及多种视图切换 - 配置协同办公导航及布局文件,完善模块化和组件化架构 - 修复管理页语法错误,完善演示数据和统计信息展示 - 提供新建、导入、分享、重命名和删除文档等核心操作功能 - 添加设备健康度及维修记录展示模块,方便车间设备管理和维护 - 更新.gitignore忽略输出目录,提升项目环境整洁性
This commit is contained in:
348
app/pages/device.vue
Normal file
348
app/pages/device.vue
Normal file
@@ -0,0 +1,348 @@
|
||||
<template>
|
||||
<div class="flex min-h-screen bg-gradient-to-br from-gray-50 to-gray-100">
|
||||
<!-- 左侧导航 -->
|
||||
<aside class="w-64 fixed h-full text-white flex flex-col sidebar">
|
||||
<div class="p-6 border-b border-white/10">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center">
|
||||
<BlockOutlined class="text-xl" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="font-bold text-lg">DEMO演示系统</h1>
|
||||
<p class="text-xs text-white/70">ERP 管理平台</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="flex-1 py-6 px-3">
|
||||
<div class="space-y-1">
|
||||
<NuxtLink to="/" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<HomeOutlined class="text-base" /><span>工作台</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/device" class="sidebar-item active flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<SettingOutlined class="text-base" /><span>设备管理</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/procurement" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<ShoppingCartOutlined class="text-base" /><span>采购管理</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/warehouse" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<InboxOutlined class="text-base" /><span>仓储物流</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/finance" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<WalletOutlined class="text-base" /><span>财务管理</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/hr" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<TeamOutlined class="text-base" /><span>人力资源</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/office" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<ProjectOutlined class="text-base" /><span>协同办公</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="mt-8 pt-6 border-t border-white/10">
|
||||
<p class="px-4 text-xs text-white/50 mb-3">个人</p>
|
||||
<a href="#" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<UserOutlined class="text-base" /><span>个人信息</span>
|
||||
</a>
|
||||
<a href="#" class="sidebar-item flex items-center gap-3 px-4 py-3 rounded-xl cursor-pointer">
|
||||
<SettingOutlined class="text-base" /><span>系统设置</span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="p-4 border-t border-white/10">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center">
|
||||
<UserOutlined />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium">管理员</p>
|
||||
<p class="text-xs text-white/70">超级管理员</p>
|
||||
</div>
|
||||
<button class="text-white/70 hover:text-white"><LogoutOutlined /></button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<main class="flex-1 ml-64">
|
||||
<header class="bg-white/85 backdrop-blur-xl sticky top-0 z-50 px-8 py-4 border-b border-white/30">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="relative w-96">
|
||||
<a-input v-model:value="searchKeyword" placeholder="搜索设备名称、编号、位置..." size="large">
|
||||
<template #prefix><SearchOutlined class="text-gray-400" /></template>
|
||||
</a-input>
|
||||
</div>
|
||||
<div class="flex items-center gap-6">
|
||||
<button class="text-gray-500 hover:text-purple-600 transition-colors">
|
||||
<FullscreenOutlined class="text-lg" />
|
||||
</button>
|
||||
<a-badge count="3" :offset="[-2, 2]">
|
||||
<BellOutlined class="text-gray-500 hover:text-purple-600 transition-colors text-lg cursor-pointer" />
|
||||
</a-badge>
|
||||
<div class="flex items-center gap-3 pl-6 border-l border-gray-200">
|
||||
<a-avatar class="bg-gradient-to-br from-purple-500 to-pink-500">A</a-avatar>
|
||||
<div>
|
||||
<p class="font-medium text-gray-800">Admin</p>
|
||||
<p class="text-xs text-gray-500">超级管理员</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="p-8">
|
||||
<!-- 页面标题 -->
|
||||
<div class="mb-8">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<NuxtLink to="/" class="text-gray-500 hover:text-purple-600 transition-colors">
|
||||
<ArrowLeftOutlined />
|
||||
</NuxtLink>
|
||||
<h2 class="text-3xl font-bold text-gray-800">设备管理</h2>
|
||||
</div>
|
||||
<p class="text-gray-500">管理设备台账、巡检记录、维修保养及设备报警</p>
|
||||
</div>
|
||||
|
||||
<!-- 数据概览 -->
|
||||
<div class="grid grid-cols-4 gap-6 mb-8">
|
||||
<div class="stat-card blue bg-white rounded-2xl p-6 card-hover shadow-sm">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center">
|
||||
<ToolOutlined class="text-blue-600 text-xl" />
|
||||
</div>
|
||||
<span class="text-green-500 text-sm font-medium flex items-center gap-1"><ArrowUpOutlined /> 4%</span>
|
||||
</div>
|
||||
<h3 class="text-3xl font-bold text-gray-800 mb-1">128</h3>
|
||||
<p class="text-gray-500 text-sm">设备总数</p>
|
||||
</div>
|
||||
<div class="stat-card green bg-white rounded-2xl p-6 card-hover shadow-sm">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center">
|
||||
<CheckCircleOutlined class="text-green-600 text-xl" />
|
||||
</div>
|
||||
<span class="text-green-500 text-sm font-medium">正常运行</span>
|
||||
</div>
|
||||
<h3 class="text-3xl font-bold text-gray-800 mb-1">115</h3>
|
||||
<p class="text-gray-500 text-sm">运行中</p>
|
||||
</div>
|
||||
<div class="stat-card orange bg-white rounded-2xl p-6 card-hover shadow-sm">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="w-12 h-12 bg-orange-100 rounded-xl flex items-center justify-center">
|
||||
<AlertOutlined class="text-orange-600 text-xl" />
|
||||
</div>
|
||||
<span class="text-red-500 text-sm font-medium">需处理</span>
|
||||
</div>
|
||||
<h3 class="text-3xl font-bold text-gray-800 mb-1">7</h3>
|
||||
<p class="text-gray-500 text-sm">待维修</p>
|
||||
</div>
|
||||
<div class="stat-card purple bg-white rounded-2xl p-6 card-hover shadow-sm">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center">
|
||||
<ClockCircleOutlined class="text-purple-600 text-xl" />
|
||||
</div>
|
||||
<span class="text-blue-500 text-sm font-medium">本月计划</span>
|
||||
</div>
|
||||
<h3 class="text-3xl font-bold text-gray-800 mb-1">6</h3>
|
||||
<p class="text-gray-500 text-sm">维保中</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div class="bg-white/85 backdrop-blur-xl rounded-2xl p-4 mb-8 shadow-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex gap-3">
|
||||
<a-button type="primary" class="bg-gradient-to-r from-purple-600 to-purple-700 border-0">
|
||||
<PlusOutlined />新增设备
|
||||
</a-button>
|
||||
<a-button><ExportOutlined class="text-green-500" />导出台账</a-button>
|
||||
<a-button><ScanOutlined class="text-blue-500" />扫码查询</a-button>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<a-button><FilterOutlined class="text-gray-500" />筛选</a-button>
|
||||
<a-select v-model:value="filterStatus" class="w-32">
|
||||
<a-select-option value="">全部状态</a-select-option>
|
||||
<a-select-option value="running">运行中</a-select-option>
|
||||
<a-select-option value="repair">维修中</a-select-option>
|
||||
<a-select-option value="maintain">保养中</a-select-option>
|
||||
<a-select-option value="idle">闲置</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 标签页 -->
|
||||
<div class="bg-white/85 backdrop-blur-xl rounded-2xl p-2 mb-8 inline-flex shadow-sm">
|
||||
<a-segmented v-model:value="activeTab" :options="tabOptions" />
|
||||
</div>
|
||||
|
||||
<!-- 设备列表 -->
|
||||
<div class="bg-white/85 backdrop-blur-xl rounded-2xl overflow-hidden mb-8 shadow-sm">
|
||||
<div class="p-6 border-b border-gray-100">
|
||||
<h3 class="font-bold text-lg text-gray-800 flex items-center gap-2">
|
||||
<UnorderedListOutlined class="text-purple-500" />
|
||||
设备台账
|
||||
<a-tag color="purple">128</a-tag>
|
||||
</h3>
|
||||
</div>
|
||||
<a-table :dataSource="deviceData" :columns="columns" :pagination="false">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'device'">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-xl flex items-center justify-center" :class="record.iconBg">
|
||||
<ToolOutlined :class="record.iconColor" />
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-medium text-gray-800">{{ record.name }}</p>
|
||||
<p class="text-xs text-gray-500">{{ record.code }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag :color="getStatusColor(record.status)">
|
||||
<template v-if="record.status === 'running'"><CheckCircleOutlined /> 运行中</template>
|
||||
<template v-else-if="record.status === 'repair'"><AlertOutlined /> 维修中</template>
|
||||
<template v-else-if="record.status === 'maintain'"><ToolOutlined /> 保养中</template>
|
||||
<template v-else-if="record.status === 'idle'"><PauseCircleOutlined /> 闲置</template>
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'health'">
|
||||
<a-progress :percent="record.health" :stroke-color="record.health > 80 ? '#52c41a' : record.health > 60 ? '#faad14' : '#ff4d4f'" size="small" />
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<a-button type="text" size="small" class="text-blue-600"><EyeOutlined /></a-button>
|
||||
<a-button type="text" size="small" class="text-green-600"><EditOutlined /></a-button>
|
||||
<a-button type="text" size="small" class="text-orange-600"><ToolOutlined /></a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<div class="p-6 border-t border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-sm text-gray-500">显示 1-6 条,共 128 条</p>
|
||||
<a-pagination v-model:current="currentPage" :total="128" :pageSize="6" show-less-items />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部 -->
|
||||
<div class="grid grid-cols-2 gap-6">
|
||||
<!-- 维修记录 -->
|
||||
<div class="bg-white/85 backdrop-blur-xl rounded-2xl p-6 card-hover shadow-sm">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="font-bold text-lg text-gray-800 flex items-center gap-2">
|
||||
<AlertOutlined class="text-red-500" />最近维修记录
|
||||
</h3>
|
||||
<button class="text-purple-600 text-sm font-medium hover:underline">查看全部</button>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<div v-for="r in repairRecords" :key="r.id" class="flex items-center gap-4 p-3 bg-gray-50 rounded-xl">
|
||||
<div class="w-10 h-10 bg-red-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<ToolOutlined class="text-red-600" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-medium text-gray-800">{{ r.device }}</p>
|
||||
<p class="text-xs text-gray-500">{{ r.desc }}</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-sm font-medium" :class="r.done ? 'text-green-600' : 'text-orange-500'">
|
||||
{{ r.done ? '已完成' : '处理中' }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-400">{{ r.date }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 设备健康度 -->
|
||||
<div class="bg-white/85 backdrop-blur-xl rounded-2xl p-6 card-hover shadow-sm">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="font-bold text-lg text-gray-800 flex items-center gap-2">
|
||||
<LineChartOutlined class="text-purple-500" />车间设备健康度
|
||||
</h3>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div v-for="w in workshopHealth" :key="w.name">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-sm text-gray-600">{{ w.name }}</span>
|
||||
<span class="text-sm font-medium text-gray-800">{{ w.health }}%</span>
|
||||
</div>
|
||||
<a-progress :percent="w.health" :stroke-color="w.color" :show-info="false" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import {
|
||||
HomeOutlined, SettingOutlined, ShoppingCartOutlined, InboxOutlined, WalletOutlined,
|
||||
TeamOutlined, ProjectOutlined, UserOutlined, LogoutOutlined, SearchOutlined,
|
||||
FullscreenOutlined, BellOutlined, ArrowLeftOutlined, ArrowUpOutlined,
|
||||
PlusOutlined, ExportOutlined, FilterOutlined, UnorderedListOutlined,
|
||||
CheckCircleOutlined, ClockCircleOutlined, AlertOutlined, PauseCircleOutlined,
|
||||
EyeOutlined, EditOutlined, ToolOutlined, LineChartOutlined, BlockOutlined, ScanOutlined,
|
||||
} from '@ant-design/icons-vue'
|
||||
|
||||
definePageMeta({ layout: 'blank' })
|
||||
|
||||
const searchKeyword = ref('')
|
||||
const currentPage = ref(1)
|
||||
const activeTab = ref('设备台账')
|
||||
const filterStatus = ref('')
|
||||
const tabOptions = ['设备台账', '巡检管理', '维修工单', '保养计划', '设备报警']
|
||||
|
||||
const columns = [
|
||||
{ title: '设备信息', key: 'device' },
|
||||
{ title: '类型', dataIndex: 'type', key: 'type' },
|
||||
{ title: '所在位置', dataIndex: 'location', key: 'location' },
|
||||
{ title: '状态', key: 'status' },
|
||||
{ title: '健康度', key: 'health', width: 160 },
|
||||
{ title: '下次保养', dataIndex: 'nextMaintain', key: 'nextMaintain' },
|
||||
{ title: '操作', key: 'action', align: 'center' },
|
||||
]
|
||||
|
||||
const deviceData = [
|
||||
{ key: '1', name: '数控车床 CNC-001', code: 'SB-2021-001', type: '加工设备', location: '1号车间A区', status: 'running', health: 92, nextMaintain: '2026-05-15', iconBg: 'bg-blue-100', iconColor: 'text-blue-600' },
|
||||
{ key: '2', name: '注塑机 ZS-008', code: 'ZS-2020-008', type: '生产设备', location: '2号车间B区', status: 'repair', health: 45, nextMaintain: '维修中', iconBg: 'bg-red-100', iconColor: 'text-red-600' },
|
||||
{ key: '3', name: '空压机 KY-003', code: 'KY-2022-003', type: '辅助设备', location: '动力房', status: 'maintain', health: 78, nextMaintain: '保养中', iconBg: 'bg-orange-100', iconColor: 'text-orange-600' },
|
||||
{ key: '4', name: '激光切割机 JG-002', code: 'JG-2023-002', type: '加工设备', location: '3号车间', status: 'running', health: 88, nextMaintain: '2026-04-30', iconBg: 'bg-green-100', iconColor: 'text-green-600' },
|
||||
{ key: '5', name: '传送带 CS-012', code: 'CS-2019-012', type: '物流设备', location: '仓储区', status: 'idle', health: 65, nextMaintain: '2026-04-20', iconBg: 'bg-gray-100', iconColor: 'text-gray-600' },
|
||||
{ key: '6', name: '焊接机器人 HR-005', code: 'HR-2023-005', type: '自动化设备', location: '4号车间', status: 'running', health: 97, nextMaintain: '2026-06-01', iconBg: 'bg-purple-100', iconColor: 'text-purple-600' },
|
||||
]
|
||||
|
||||
const repairRecords = [
|
||||
{ id: 1, device: '注塑机 ZS-008', desc: '液压系统泄漏,更换密封件', done: false, date: '2026-04-08' },
|
||||
{ id: 2, device: '空压机 KY-003', desc: '定期保养,更换滤芯', done: false, date: '2026-04-07' },
|
||||
{ id: 3, device: '传送带 CS-011', desc: '皮带磨损,已更换新品', done: true, date: '2026-04-05' },
|
||||
{ id: 4, device: 'CNC-003 主轴', desc: '主轴轴承异响,已更换', done: true, date: '2026-04-03' },
|
||||
]
|
||||
|
||||
const workshopHealth = [
|
||||
{ name: '1号车间', health: 95, color: { from: '#52c41a', to: '#38ef7d' } },
|
||||
{ name: '2号车间', health: 72, color: { from: '#faad14', to: '#ffd666' } },
|
||||
{ name: '3号车间', health: 88, color: { from: '#667eea', to: '#764ba2' } },
|
||||
{ name: '4号车间', health: 96, color: { from: '#11998e', to: '#38ef7d' } },
|
||||
{ name: '动力区', health: 61, color: { from: '#f5576c', to: '#f093fb' } },
|
||||
]
|
||||
|
||||
const getStatusColor = (status: string) => {
|
||||
const m: Record<string, string> = { running: 'success', repair: 'error', maintain: 'warning', idle: 'default' }
|
||||
return m[status] || 'default'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sidebar { background: linear-gradient(180deg, #667eea 0%, #764ba2 100%); }
|
||||
.sidebar-item { color: white; }
|
||||
.sidebar-item:hover, .sidebar-item.active { background: rgba(255,255,255,0.2); }
|
||||
.card-hover { transition: all 0.3s cubic-bezier(0.4,0,0.2,1); }
|
||||
.card-hover:hover { transform: translateY(-4px); box-shadow: 0 20px 40px rgba(0,0,0,0.1); }
|
||||
.stat-card { position: relative; overflow: hidden; }
|
||||
.stat-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; }
|
||||
.stat-card.blue::before { background: linear-gradient(90deg, #667eea, #764ba2); }
|
||||
.stat-card.green::before { background: linear-gradient(90deg, #11998e, #38ef7d); }
|
||||
.stat-card.orange::before { background: linear-gradient(90deg, #f093fb, #f5576c); }
|
||||
.stat-card.purple::before { background: linear-gradient(90deg, #a8edea, #fed6e3); }
|
||||
</style>
|
||||
Reference in New Issue
Block a user