495 lines
15 KiB
Vue
495 lines
15 KiB
Vue
<template>
|
|
<view class="workbench-container">
|
|
<!-- 自定义导航栏 -->
|
|
<u-navbar
|
|
title="工作台"
|
|
:is-back="false"
|
|
:border-bottom="false"
|
|
:custom-style="{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }"
|
|
title-color="#fff"
|
|
>
|
|
<template #right>
|
|
<u-icon name="search" color="#fff" size="44" @click="showSearch"></u-icon>
|
|
</template>
|
|
</u-navbar>
|
|
|
|
<!-- 主体内容 -->
|
|
<view class="content">
|
|
<!-- 工作统计 -->
|
|
<view class="work-stats card">
|
|
<view class="section-title">
|
|
<text>工作统计</text>
|
|
<text class="date">{{ today }}</text>
|
|
</view>
|
|
<view class="stats-row">
|
|
<view
|
|
v-for="(item, index) in workStats"
|
|
:key="index"
|
|
class="stat-item"
|
|
@click="onStatClick(item)"
|
|
>
|
|
<view class="stat-icon" :style="{ background: item.color }">
|
|
<u-icon :name="item.icon" color="#fff" size="36"></u-icon>
|
|
</view>
|
|
<view class="stat-info">
|
|
<text class="stat-value">{{ item.value }}</text>
|
|
<text class="stat-label">{{ item.label }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 待办事项 -->
|
|
<view class="todo-section card">
|
|
<view class="section-title">
|
|
<text>待办事项</text>
|
|
<view class="badge" v-if="todoList.length > 0">{{ todoList.length }}</view>
|
|
</view>
|
|
<view class="todo-list" v-if="todoList.length > 0">
|
|
<view
|
|
v-for="(item, index) in todoList"
|
|
:key="index"
|
|
class="todo-item"
|
|
@click="onTodoClick(item)"
|
|
>
|
|
<view class="todo-left">
|
|
<view class="priority-dot" :class="item.priority"></view>
|
|
<view class="todo-content">
|
|
<text class="todo-title">{{ item.title }}</text>
|
|
<text class="todo-time">{{ item.deadline }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="todo-status" :class="item.status">
|
|
{{ getStatusText(item.status) }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-else class="empty-state">
|
|
<u-icon name="checkbox-mark" color="#c8c9cc" size="80"></u-icon>
|
|
<text>暂无待办事项</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 工作流程 -->
|
|
<view class="workflow-section card">
|
|
<view class="section-title">
|
|
<text>工作流程</text>
|
|
</view>
|
|
<view class="workflow-grid">
|
|
<view
|
|
v-for="(item, index) in workflowItems"
|
|
:key="index"
|
|
class="workflow-item"
|
|
@click="onWorkflowClick(item)"
|
|
>
|
|
<view class="workflow-icon" :style="{ background: item.color }">
|
|
<u-icon :name="item.icon" color="#fff" size="40"></u-icon>
|
|
</view>
|
|
<text class="workflow-text">{{ item.name }}</text>
|
|
<view class="workflow-badge" v-if="item.badge">{{ item.badge }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 快速操作 -->
|
|
<view class="quick-ops card">
|
|
<view class="section-title">
|
|
<text>快速操作</text>
|
|
</view>
|
|
<view class="ops-list">
|
|
<view
|
|
v-for="(item, index) in quickOps"
|
|
:key="index"
|
|
class="ops-item"
|
|
@click="onQuickOpClick(item)"
|
|
>
|
|
<view class="ops-left">
|
|
<u-icon :name="item.icon" :color="item.color" size="40"></u-icon>
|
|
<view class="ops-info">
|
|
<text class="ops-title">{{ item.title }}</text>
|
|
<text class="ops-desc">{{ item.desc }}</text>
|
|
</view>
|
|
</view>
|
|
<u-icon name="arrow-right" color="#c8c9cc" size="28"></u-icon>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'Workbench',
|
|
data() {
|
|
return {
|
|
today: '',
|
|
workStats: [
|
|
{ label: '今日任务', value: '8', icon: 'list', color: '#3c9cff' },
|
|
{ label: '已完成', value: '5', icon: 'checkmark', color: '#5ac725' },
|
|
{ label: '进行中', value: '2', icon: 'clock', color: '#f9ae3d' },
|
|
{ label: '待审批', value: '1', icon: 'eye', color: '#f56c6c' },
|
|
],
|
|
todoList: [
|
|
{
|
|
title: '审核学生请假申请',
|
|
deadline: '今天 18:00',
|
|
priority: 'high',
|
|
status: 'pending',
|
|
},
|
|
{
|
|
title: '提交月度工作报告',
|
|
deadline: '明天 12:00',
|
|
priority: 'medium',
|
|
status: 'in-progress',
|
|
},
|
|
{
|
|
title: '参加部门例会',
|
|
deadline: '2024-02-16 14:00',
|
|
priority: 'low',
|
|
status: 'pending',
|
|
},
|
|
],
|
|
workflowItems: [
|
|
{ name: '请假审批', icon: 'file-text', color: '#ff6b6b', badge: '3' },
|
|
{ name: '报销审批', icon: 'rmb-circle', color: '#4ecdc4', badge: '1' },
|
|
{ name: '采购审批', icon: 'shopping-cart', color: '#45b7d1' },
|
|
{ name: '合同审批', icon: 'file', color: '#f9ca24' },
|
|
],
|
|
quickOps: [
|
|
{
|
|
title: '创建任务',
|
|
desc: '快速创建新的工作任务',
|
|
icon: 'plus-circle',
|
|
color: '#3c9cff',
|
|
},
|
|
{
|
|
title: '工作日志',
|
|
desc: '记录今日工作内容',
|
|
icon: 'edit-pen',
|
|
color: '#5ac725',
|
|
},
|
|
{
|
|
title: '团队协作',
|
|
desc: '查看团队成员工作状态',
|
|
icon: 'account',
|
|
color: '#f9ae3d',
|
|
},
|
|
{
|
|
title: '数据统计',
|
|
desc: '查看工作效率统计',
|
|
icon: 'bar-chart',
|
|
color: '#f56c6c',
|
|
},
|
|
],
|
|
};
|
|
},
|
|
onLoad() {
|
|
this.initPage();
|
|
},
|
|
methods: {
|
|
// 初始化页面
|
|
initPage() {
|
|
this.setToday();
|
|
},
|
|
|
|
// 设置当前日期
|
|
setToday() {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
const day = String(now.getDate()).padStart(2, '0');
|
|
this.today = `${year}-${month}-${day}`;
|
|
},
|
|
|
|
// 获取状态文本
|
|
getStatusText(status) {
|
|
const statusMap = {
|
|
pending: '待处理',
|
|
'in-progress': '进行中',
|
|
completed: '已完成',
|
|
};
|
|
return statusMap[status] || '未知';
|
|
},
|
|
|
|
// 统计项点击
|
|
onStatClick(item) {
|
|
console.log('点击统计', item.label);
|
|
this.$u.toast(`查看${item.label}`);
|
|
},
|
|
|
|
// 待办事项点击
|
|
onTodoClick(item) {
|
|
console.log('点击待办', item.title);
|
|
this.$u.toast(`处理:${item.title}`);
|
|
},
|
|
|
|
// 工作流程点击
|
|
onWorkflowClick(item) {
|
|
console.log('点击工作流', item.name);
|
|
this.$u.toast(`打开${item.name}`);
|
|
},
|
|
|
|
// 快速操作点击
|
|
onQuickOpClick(item) {
|
|
console.log('点击快速操作', item.title);
|
|
this.$u.toast(item.title);
|
|
},
|
|
|
|
// 显示搜索
|
|
showSearch() {
|
|
this.$u.toast('搜索功能');
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.workbench-container {
|
|
background: #f5f5f5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.content {
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.section-title {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 30rpx;
|
|
|
|
text {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #303133;
|
|
}
|
|
|
|
.date {
|
|
font-size: 24rpx;
|
|
color: #909399;
|
|
}
|
|
|
|
.badge {
|
|
background: #f56c6c;
|
|
color: #fff;
|
|
font-size: 20rpx;
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 20rpx;
|
|
min-width: 32rpx;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
.work-stats {
|
|
.stats-row {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
|
|
.stat-item {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20rpx;
|
|
padding: 20rpx;
|
|
background: #fafafa;
|
|
border-radius: 12rpx;
|
|
|
|
.stat-icon {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
border-radius: 12rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.stat-info {
|
|
.stat-value {
|
|
display: block;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #303133;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 20rpx;
|
|
color: #909399;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.todo-section {
|
|
.todo-list {
|
|
.todo-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 30rpx 0;
|
|
border-bottom: 2rpx solid #f5f5f5;
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.todo-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20rpx;
|
|
flex: 1;
|
|
|
|
.priority-dot {
|
|
width: 12rpx;
|
|
height: 12rpx;
|
|
border-radius: 50%;
|
|
|
|
&.high {
|
|
background: #f56c6c;
|
|
}
|
|
|
|
&.medium {
|
|
background: #f9ae3d;
|
|
}
|
|
|
|
&.low {
|
|
background: #5ac725;
|
|
}
|
|
}
|
|
|
|
.todo-content {
|
|
.todo-title {
|
|
display: block;
|
|
font-size: 28rpx;
|
|
color: #303133;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.todo-time {
|
|
font-size: 24rpx;
|
|
color: #909399;
|
|
}
|
|
}
|
|
}
|
|
|
|
.todo-status {
|
|
font-size: 24rpx;
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 8rpx;
|
|
|
|
&.pending {
|
|
background: #fef0f0;
|
|
color: #f56c6c;
|
|
}
|
|
|
|
&.in-progress {
|
|
background: #fdf6ec;
|
|
color: #f9ae3d;
|
|
}
|
|
|
|
&.completed {
|
|
background: #f0f9ff;
|
|
color: #5ac725;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.empty-state {
|
|
text-align: center;
|
|
padding: 80rpx 0;
|
|
color: #c8c9cc;
|
|
|
|
text {
|
|
display: block;
|
|
margin-top: 20rpx;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.workflow-section {
|
|
.workflow-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 30rpx;
|
|
|
|
.workflow-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 16rpx;
|
|
position: relative;
|
|
|
|
.workflow-icon {
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
border-radius: 20rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.workflow-text {
|
|
font-size: 24rpx;
|
|
color: #303133;
|
|
text-align: center;
|
|
}
|
|
|
|
.workflow-badge {
|
|
position: absolute;
|
|
top: -10rpx;
|
|
right: 10rpx;
|
|
background: #f56c6c;
|
|
color: #fff;
|
|
font-size: 20rpx;
|
|
padding: 4rpx 8rpx;
|
|
border-radius: 10rpx;
|
|
min-width: 20rpx;
|
|
text-align: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.quick-ops {
|
|
.ops-list {
|
|
.ops-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 30rpx 0;
|
|
border-bottom: 2rpx solid #f5f5f5;
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.ops-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20rpx;
|
|
flex: 1;
|
|
|
|
.ops-info {
|
|
.ops-title {
|
|
display: block;
|
|
font-size: 28rpx;
|
|
color: #303133;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.ops-desc {
|
|
font-size: 24rpx;
|
|
color: #909399;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|