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
+440
View File
@@ -0,0 +1,440 @@
<template>
<view class="image-upload-container">
<!-- 顶部导航栏 -->
<view class="top-navbar">
<text class="cancel" @click="navigateBack">取消</text>
<text class="title">图片上传</text>
<text class="save" @click="submitUpload" :class="{ disabled: !canSubmit }">提交</text>
</view>
<!-- 内容区域 -->
<scroll-view class="content" scroll-y>
<!-- 部门信息 -->
<view class="dept-info">
<text class="label">所属部门</text>
<text class="value">{{ currentUser.department }}</text>
</view>
<!-- 图片选择区域 -->
<view class="section">
<text class="section-title">选择图片</text>
<view class="image-grid">
<view v-for="(image, index) in selectedImages" :key="index" class="image-item">
<image :src="image" mode="aspectFill"></image>
<view class="delete-btn" @click="removeImage(index)">
<u-icon name="close" size="28" color="#fff"></u-icon>
</view>
</view>
<view v-if="selectedImages.length < maxImages" class="add-image" @click="chooseImage">
<u-icon name="plus" size="60" color="#c0c4cc"></u-icon>
<text>添加图片</text>
</view>
</view>
<text class="hint">{{ selectedImages.length }}/{{ maxImages }} </text>
</view>
<!-- 表单信息 -->
<view class="section">
<text class="section-title">图片信息</text>
<!-- 标题 -->
<view class="form-item">
<text class="form-label">标题</text>
<u-input
v-model="formData.title"
placeholder="请输入图片标题"
border="bottom"
maxlength="50"
></u-input>
</view>
<!-- 标签 -->
<view class="form-item">
<text class="form-label">标签</text>
<view class="tags-container">
<view
v-for="tag in availableTags"
:key="tag.value"
class="tag"
:class="{ active: formData.tags.includes(tag.value) }"
@click="toggleTag(tag.value)"
>
{{ tag.label }}
</view>
</view>
</view>
<!-- 描述 -->
<view class="form-item">
<text class="form-label">描述</text>
<u-input
v-model="formData.description"
placeholder="请输入图片描述(选填)"
border="bottom"
type="textarea"
:rows="3"
maxlength="200"
></u-input>
</view>
<!-- 关联任务 -->
<view class="form-item">
<text class="form-label">关联任务</text>
<u-picker
v-model="showTaskPicker"
:columns="taskOptions"
@confirm="onTaskConfirm"
@cancel="showTaskPicker = false"
title="选择任务"
mode="selector"
@change="onTaskChange"
></u-picker>
<view class="task-select" @click="showTaskPicker = true">
<text v-if="formData.taskId" class="selected-task">{{ selectedTaskName }}</text>
<text v-else class="placeholder">请选择关联任务选填</text>
<u-icon name="arrow-right" size="20" color="#c0c4cc"></u-icon>
</view>
</view>
</view>
</scroll-view>
<!-- 上传进度弹窗 -->
<u-modal v-model="showUploadModal" show-cancel-button="false" :close-on-click-modal="false">
<view class="upload-modal">
<u-loading-icon size="60" color="#1989fa"></u-loading-icon>
<text class="upload-status">{{ uploadStatus }}</text>
<u-progress :percent="uploadProgress" :show-percent="true" height="10"></u-progress>
</view>
</u-modal>
</view>
</template>
<script>
export default {
data() {
return {
// 用户信息
currentUser: {
name: '张三',
department: '研发部'
},
// 表单数据
formData: {
title: '',
tags: [],
description: '',
taskId: ''
},
// 图片相关
selectedImages: [],
maxImages: 9,
// 任务选择器
showTaskPicker: false,
taskOptions: ['项目进度拍摄', '设备巡检', '活动照片收集', '其他任务'],
taskMap: {
'项目进度拍摄': '1',
'设备巡检': '2',
'活动照片收集': '3',
'其他任务': '4'
},
// 标签选项
availableTags: [
{ label: '工作进度', value: 'progress' },
{ label: '设备状态', value: 'equipment' },
{ label: '会议记录', value: 'meeting' },
{ label: '活动现场', value: 'activity' },
{ label: '产品展示', value: 'product' },
{ label: '其他', value: 'other' }
],
// 上传相关
showUploadModal: false,
uploadProgress: 0,
uploadStatus: '准备上传...'
}
},
computed: {
canSubmit() {
return this.selectedImages.length > 0 && this.formData.title.trim() !== ''
},
selectedTaskName() {
for (const [name, id] of Object.entries(this.taskMap)) {
if (id === this.formData.taskId) {
return name
}
}
return ''
}
},
methods: {
navigateBack() {
uni.navigateBack()
},
chooseImage() {
const remainingCount = this.maxImages - this.selectedImages.length
uni.chooseImage({
count: remainingCount,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePaths = res.tempFilePaths
this.selectedImages = [...this.selectedImages, ...tempFilePaths]
}
})
},
removeImage(index) {
this.selectedImages.splice(index, 1)
},
toggleTag(tagValue) {
const index = this.formData.tags.indexOf(tagValue)
if (index > -1) {
this.formData.tags.splice(index, 1)
} else {
this.formData.tags.push(tagValue)
}
},
onTaskConfirm(e) {
const name = this.taskOptions[e.index]
this.formData.taskId = this.taskMap[name]
},
onTaskChange(e) {
// 实时更新选中的任务名称
},
submitUpload() {
if (!this.canSubmit) return
// 显示上传进度弹窗
this.showUploadModal = true
this.uploadProgress = 0
this.uploadStatus = '正在上传...'
// 模拟上传过程
let progress = 0
const timer = setInterval(() => {
progress += 10
this.uploadProgress = progress
if (progress >= 100) {
clearInterval(timer)
this.uploadStatus = '上传成功!'
// 延迟关闭弹窗并返回
setTimeout(() => {
this.showUploadModal = false
this.$u.toast('上传成功')
// 返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1000)
}, 1500)
}
}, 300)
}
}
}
</script>
<style lang="scss" scoped>
.image-upload-container {
padding-top: 44px; // 适配顶部安全区域
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;
.cancel,
.save {
font-size: 32rpx;
color: #1989fa;
}
.save.disabled {
color: #c0c4cc;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
}
.content {
height: calc(100% - 44px);
padding: 20rpx;
}
.dept-info {
background-color: #ffffff;
padding: 20rpx 30rpx;
border-radius: 16rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
.label {
color: #606266;
}
.value {
color: #333;
font-weight: bold;
}
}
.section {
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
display: block;
}
// 图片网格样式
.image-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
margin-bottom: 15rpx;
.image-item {
position: relative;
image {
width: 100%;
aspect-ratio: 1;
border-radius: 8rpx;
}
.delete-btn {
position: absolute;
top: -15rpx;
right: -15rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
.add-image {
width: 100%;
aspect-ratio: 1;
border: 2rpx dashed #c0c4cc;
border-radius: 8rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text {
font-size: 24rpx;
color: #c0c4cc;
margin-top: 10rpx;
}
}
}
.hint {
font-size: 24rpx;
color: #909399;
text-align: right;
}
// 表单样式
.form-item {
margin-bottom: 30rpx;
&:last-child {
margin-bottom: 0;
}
.form-label {
font-size: 28rpx;
color: #606266;
margin-bottom: 10rpx;
display: block;
}
// 标签样式
.tags-container {
display: flex;
flex-wrap: wrap;
gap: 15rpx;
.tag {
padding: 10rpx 20rpx;
border: 2rpx solid #dcdfe6;
border-radius: 20rpx;
font-size: 24rpx;
color: #606266;
&.active {
border-color: #1989fa;
background-color: #ecf5ff;
color: #1989fa;
}
}
}
// 任务选择样式
.task-select {
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid #ebeef5;
.selected-task {
font-size: 28rpx;
color: #333;
}
.placeholder {
font-size: 28rpx;
color: #c0c4cc;
}
}
}
}
// 上传弹窗样式
.upload-modal {
padding: 40rpx 20rpx;
.upload-status {
display: block;
text-align: center;
font-size: 28rpx;
color: #606266;
margin: 20rpx 0;
}
:deep(.u-progress) {
margin-top: 20rpx;
}
}
}
</style>