This commit is contained in:
bwstudio
2025-10-22 08:19:00 +08:00
parent 467b04e5b0
commit 97fbfe08d7
6040 changed files with 529099 additions and 9685 deletions
+616
View File
@@ -0,0 +1,616 @@
<template>
<view class="dept-home-container">
<!-- 顶部导航栏 -->
<view class="top-navbar">
<text class="title">图片收集系统</text>
<view class="top-right">
<view class="dept-selector" @click="showDeptSelector">
<text class="current-dept">{{ currentDepartment.name }}</text>
<u-icon name="arrow-down" size="20" color="#606266"></u-icon>
</view>
<image class="avatar" src="@/static/common/user.svg" mode="aspectFit" @click="navigateTo('/pages/user-profile/user-profile')"></image>
</view>
</view>
<!-- 内容区域 -->
<scroll-view class="content" scroll-y enable-back-to-top>
<!-- 统计卡片 -->
<view class="section stats-section">
<view class="stats-cards">
<view class="stat-card">
<text class="stat-number">{{ totalTasks }}</text>
<text class="stat-label">总任务数</text>
</view>
<view class="stat-card">
<text class="stat-number">{{ pendingReviews }}</text>
<text class="stat-label">待审核</text>
</view>
<view class="stat-card">
<text class="stat-number">{{ completedTasks }}</text>
<text class="stat-label">已完成</text>
</view>
</view>
</view>
<!-- 任务完成率图表 -->
<view class="section chart-section">
<view class="section-header">
<text class="section-title">任务完成率</text>
</view>
<view class="chart-container">
<!-- 简单的饼图模拟 -->
<view class="pie-chart">
<view class="pie-slices">
<view class="pie-slice completed" :style="pieStyles.completed"></view>
<view class="pie-slice pending" :style="pieStyles.pending"></view>
<view class="pie-slice in-progress" :style="pieStyles.inProgress"></view>
</view>
<view class="pie-center">
<text class="completion-rate">{{ completionRate }}%</text>
<text class="completion-label">完成率</text>
</view>
<view class="pie-legend">
<view class="legend-item">
<view class="legend-color completed"></view>
<text>已完成</text>
</view>
<view class="legend-item">
<view class="legend-color pending"></view>
<text>待开始</text>
</view>
<view class="legend-item">
<view class="legend-color in-progress"></view>
<text>进行中</text>
</view>
</view>
</view>
</view>
</view>
<!-- 待审核图片 -->
<view class="section review-section">
<view class="section-header">
<text class="section-title">待审核图片</text>
<text class="more" @click="navigateTo('/pages/image-review/image-review')">查看全部</text>
</view>
<view class="review-list">
<view v-for="image in pendingImages" :key="image.id" class="review-item">
<image class="review-image" :src="image.url" mode="aspectFill"></image>
<view class="review-info">
<text class="image-title">{{ image.title }}</text>
<text class="uploader-info">{{ image.uploader }} | {{ image.time }}</text>
<text class="image-desc">{{ image.description }}</text>
</view>
<view class="review-actions">
<u-button class="approve-btn" size="mini" type="success" @click="approveImage(image.id)">通过</u-button>
<u-button class="reject-btn" size="mini" type="error" @click="rejectImage(image.id)">拒绝</u-button>
</view>
</view>
<view v-if="pendingImages.length === 0" class="empty-state">
<u-icon name="empty" size="80" color="#c0c4cc"></u-icon>
<text>暂无待审核图片</text>
</view>
</view>
</view>
<!-- 部门成员进度 -->
<view class="section members-section">
<view class="section-header">
<text class="section-title">部门成员进度</text>
</view>
<view class="members-list">
<view v-for="member in membersProgress" :key="member.id" class="member-item">
<view class="member-info">
<image class="member-avatar" :src="member.avatar" mode="aspectFit"></image>
<text class="member-name">{{ member.name }}</text>
<text class="member-progress">{{ member.progress }}%</text>
</view>
<view class="progress-bar">
<view class="progress-fill" :style="{ width: member.progress + '%' }"></view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 底部导航栏 -->
<view class="tab-bar">
<view class="tab-item active">
<u-icon name="home" size="44"></u-icon>
<text>首页</text>
</view>
<view class="tab-item" @click="navigateTo('/pages/image-review/image-review')">
<u-icon name="check-square" size="44"></u-icon>
<text>审核</text>
</view>
<view class="tab-item" @click="navigateTo('/pages/user-profile/user-profile')">
<u-icon name="user" size="44"></u-icon>
<text>我的</text>
</view>
</view>
<!-- 部门选择器弹窗 -->
<u-picker
v-model="showPicker"
:columns="departments"
@confirm="onDeptConfirm"
@cancel="showPicker = false"
title="选择部门"
mode="selector"
></u-picker>
</view>
</template>
<script>
export default {
data() {
return {
showPicker: false,
departments: ['研发部', '市场部', '行政部'],
currentDepartment: {
id: '1',
name: '研发部'
},
// 统计数据
totalTasks: 18,
pendingReviews: 7,
completedTasks: 12,
completionRate: 67,
// 饼图样式计算属性的依赖数据
completedPercent: 67,
pendingPercent: 20,
inProgressPercent: 13,
// 待审核图片
pendingImages: [
{
id: '1',
title: '项目原型图',
url: 'https://cdn.uviewui.com/uview/example/album1.jpg',
uploader: '张三',
time: '10:23',
description: '项目首页原型设计稿,包含主要功能模块'
},
{
id: '2',
title: '技术文档截图',
url: 'https://cdn.uviewui.com/uview/example/album2.jpg',
uploader: '李四',
time: '09:45',
description: 'API接口文档的关键部分截图'
},
{
id: '3',
title: '代码审查',
url: 'https://cdn.uviewui.com/uview/example/album3.jpg',
uploader: '王五',
time: '08:30',
description: '代码审查会议现场照片'
}
],
// 部门成员进度
membersProgress: [
{ id: '1', name: '张三', avatar: 'https://cdn.uviewui.com/uview/example/avatar1.jpg', progress: 95 },
{ id: '2', name: '李四', avatar: 'https://cdn.uviewui.com/uview/example/avatar2.jpg', progress: 80 },
{ id: '3', name: '王五', avatar: 'https://cdn.uviewui.com/uview/example/avatar3.jpg', progress: 75 },
{ id: '4', name: '赵六', avatar: 'https://cdn.uviewui.com/uview/example/avatar4.jpg', progress: 60 },
{ id: '5', name: '钱七', avatar: 'https://cdn.uviewui.com/uview/example/avatar5.jpg', progress: 45 }
]
}
},
computed: {
pieStyles() {
// 简化的饼图样式计算
return {
completed: {
clipPath: `polygon(50% 50%, 50% 0%, ${this.calculatePosition(this.completedPercent)})`,
backgroundColor: '#52c41a'
},
pending: {
clipPath: `polygon(50% 50%, ${this.calculatePosition(this.completedPercent)}, ${this.calculatePosition(this.completedPercent + this.pendingPercent)})`,
backgroundColor: '#faad14'
},
inProgress: {
clipPath: `polygon(50% 50%, ${this.calculatePosition(this.completedPercent + this.pendingPercent)}, 50% 0%)`,
backgroundColor: '#1989fa'
}
}
}
},
methods: {
navigateTo(url) {
uni.navigateTo({ url })
},
showDeptSelector() {
this.showPicker = true
},
onDeptConfirm(e) {
const index = e.index
this.currentDepartment = {
id: (index + 1).toString(),
name: this.departments[index]
}
// 模拟切换部门后更新数据
this.$u.toast(`已切换至${this.currentDepartment.name}`)
},
calculatePosition(percent) {
// 简化的饼图位置计算
const angle = (percent / 100) * Math.PI * 2
const x = 50 + 50 * Math.cos(angle - Math.PI / 2)
const y = 50 + 50 * Math.sin(angle - Math.PI / 2)
return `${x}% ${y}%`
},
approveImage(imageId) {
this.$u.toast('已通过审核')
// 模拟从列表中移除
const index = this.pendingImages.findIndex(item => item.id === imageId)
if (index > -1) {
this.pendingImages.splice(index, 1)
}
},
rejectImage(imageId) {
this.$u.toast('已拒绝')
// 模拟从列表中移除
const index = this.pendingImages.findIndex(item => item.id === imageId)
if (index > -1) {
this.pendingImages.splice(index, 1)
}
}
}
}
</script>
<style lang="scss" scoped>
.dept-home-container {
padding-top: 44px; // 适配顶部安全区域
padding-bottom: 120rpx; // 适配底部导航栏
height: 100vh;
box-sizing: border-box;
background-color: #f5f7fa;
.top-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 44px;
background-color: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
z-index: 999;
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.top-right {
display: flex;
align-items: center;
.dept-selector {
display: flex;
align-items: center;
margin-right: 20rpx;
.current-dept {
font-size: 28rpx;
color: #606266;
margin-right: 5rpx;
}
}
.avatar {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
}
}
}
.content {
height: calc(100% - 44px);
padding: 20rpx;
}
.section {
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.more {
font-size: 28rpx;
color: #1989fa;
}
}
// 统计卡片样式
&.stats-section {
.stats-cards {
display: flex;
justify-content: space-between;
.stat-card {
flex: 1;
text-align: center;
padding: 20rpx;
&:not(:last-child) {
border-right: 2rpx solid #f5f7fa;
}
.stat-number {
font-size: 40rpx;
font-weight: bold;
color: #1989fa;
display: block;
}
.stat-label {
font-size: 24rpx;
color: #606266;
margin-top: 10rpx;
display: block;
}
}
}
}
// 图表样式
&.chart-section {
.chart-container {
.pie-chart {
position: relative;
width: 100%;
padding-top: 100%;
.pie-slices {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
overflow: hidden;
}
.pie-slice {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.pie-center {
position: absolute;
top: 50%;
left: 50%;
width: 30%;
height: 30%;
background-color: #ffffff;
border-radius: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.completion-rate {
font-size: 36rpx;
font-weight: bold;
color: #1989fa;
}
.completion-label {
font-size: 24rpx;
color: #606266;
}
}
.pie-legend {
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
.legend-item {
display: flex;
align-items: center;
margin: 0 15rpx;
font-size: 24rpx;
color: #606266;
.legend-color {
width: 20rpx;
height: 20rpx;
border-radius: 50%;
margin-right: 10rpx;
&.completed {
background-color: #52c41a;
}
&.pending {
background-color: #faad14;
}
&.in-progress {
background-color: #1989fa;
}
}
}
}
}
}
}
// 待审核图片样式
&.review-section {
.review-list {
.review-item {
padding: 15rpx 0;
border-bottom: 2rpx solid #f5f7fa;
display: flex;
flex-direction: column;
&:last-child {
border-bottom: none;
}
.review-image {
width: 100%;
height: 300rpx;
border-radius: 8rpx;
margin-bottom: 20rpx;
}
.review-info {
margin-bottom: 20rpx;
.image-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.uploader-info {
font-size: 24rpx;
color: #909399;
margin-bottom: 10rpx;
display: block;
}
.image-desc {
font-size: 26rpx;
color: #606266;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
.review-actions {
display: flex;
justify-content: flex-end;
gap: 20rpx;
}
}
.empty-state {
text-align: center;
padding: 60rpx 0;
text {
display: block;
font-size: 28rpx;
color: #909399;
margin-top: 20rpx;
}
}
}
}
// 部门成员进度样式
&.members-section {
.members-list {
.member-item {
margin-bottom: 25rpx;
&:last-child {
margin-bottom: 0;
}
.member-info {
display: flex;
align-items: center;
margin-bottom: 10rpx;
.member-avatar {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
margin-right: 15rpx;
}
.member-name {
font-size: 28rpx;
color: #333;
flex: 1;
}
.member-progress {
font-size: 26rpx;
color: #1989fa;
font-weight: bold;
}
}
.progress-bar {
height: 10rpx;
background-color: #f5f7fa;
border-radius: 5rpx;
overflow: hidden;
.progress-fill {
height: 100%;
background-color: #1989fa;
border-radius: 5rpx;
}
}
}
}
}
}
.tab-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 120rpx;
background-color: #ffffff;
display: flex;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #909399;
&.active {
color: #1989fa;
}
text {
margin-top: 8rpx;
}
}
}
}
</style>