Files
hzdyjs/mobile/pages/workbench/workbench.vue
T
2025-06-26 18:30:03 +08:00

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>