浏览代码

上传项目图片

xiaocao 7 月之前
父节点
当前提交
5076926a42
共有 1 个文件被更改,包括 629 次插入0 次删除
  1. 629 0
      src/pages/work/uploadProjectImage.vue

+ 629 - 0
src/pages/work/uploadProjectImage.vue

@@ -0,0 +1,629 @@
+<template>
+	<view class="upload-container">
+		<uni-forms ref="formRef" :model="formData" :rules="rules">
+			<uni-forms-item label="任务主题" name="projectName" required>
+				<uni-easyinput v-model="formData.projectName" placeholder="请输入任务主题"/>
+			</uni-forms-item>
+
+			<uni-forms-item label="工作类型" name="projectType" required>
+				<uni-data-select v-model="formData.projectType" :localdata="sys_work_type" placeholder="请选择工作类型"/>
+			</uni-forms-item>
+
+			<uni-forms-item label="协作人员" name="collaborator" required>
+				<uni-easyinput v-model="formData.collaborator" placeholder="请输入协作人员"/>
+			</uni-forms-item>
+
+			<uni-forms-item label="任务时间" name="projectTime">
+				<uni-datetime-picker v-model="formData.projectTime" end-placeholder="请选择结束时间" rangeSeparator="至"
+				                     start-placeholder="请选择开始时间" type="datetimerange"/>
+			</uni-forms-item>
+
+			<uni-forms-item label="优先级" name="projectGrade" required>
+				<uni-data-checkbox v-model="formData.projectGrade" :localdata="sys_sort_grade"/>
+			</uni-forms-item>
+
+			<uni-forms-item label="详细描述" name="content">
+				<uni-easyinput v-model="formData.content" :autoHeight="true" placeholder="请输入详细描述" type="textarea"/>
+			</uni-forms-item>
+
+			<!-- 	<uni-forms-item label="照片上传" name="accessory1">
+				<uni-file-picker v-model="imageValue" :limit="5" file-extname="png,jpg,mp4" file-mediatype="image"
+					mode="grid" @fail="fail" @progress="progress" @select="select" @success="success" />
+			</uni-forms-item> -->
+
+			<uni-forms-item label="图片上传" name="accessory2">
+				<!-- <uni-file-picker v-model="imageValue" :limit="5" file-extname="mp4" file-mediatype="video" mode="grid"
+					@fail="fail" @progress="progress" @select="select" @success="success" /> -->
+
+
+				<image-with-video v-model="mediaList" :maxCount="5" :token="token" :uploadUrl="uploadUrl" media="true"
+				                  mediaType="all" @backendData="handleBackendData" @change="handleMediaChange"/>
+
+			</uni-forms-item>
+
+
+			<uni-forms-item label="备注" name="remark">
+				<uni-easyinput v-model="formData.remark" :autoHeight="true" placeholder="请输入内容" type="textarea"/>
+			</uni-forms-item>
+
+
+		</uni-forms>
+
+		<view class="dialog-footer" style="text-align: center;">
+			<button :loading="buttonLoading" type="primary" @click="submitTaskForm">保存</button>
+		</view>
+	</view>
+</template>
+
+<script setup>
+import {
+	ref,
+	reactive,
+	computed
+} from 'vue'
+import {
+	onLoad
+} from '@dcloudio/uni-app'
+import {
+	useDict
+} from '@/common/useDict'
+import {
+	getTaskByDictType,
+	uploadFile,
+	addTask
+} from '@/api/oa/task'
+import ImageWithVideo from '@/components/imageWithVideo/imageWithVideo.vue'
+
+import config from '@/config.js';
+import useUserStore from '@/store/modules/user';
+
+const {
+	sys_work_type: originalWorkTypes,
+	sys_sort_grade: originalSortGrades
+} = useDict('sys_work_type', 'sys_sort_grade')
+
+const imageUrl = config.baseUrl
+const uploadUrl = config.baseUrl + config.apiPrefix + '/common/upload'
+const token = useUserStore().token
+
+
+// 将 label 转换为 text
+const sys_work_type = computed(() => {
+	return originalWorkTypes.value.map(item => ({
+		...item,
+		text: item.label // 将 label 赋值给 text
+	}))
+})
+
+const sys_sort_grade = computed(() => {
+	return originalSortGrades.value.map(item => ({
+		...item,
+		text: item.label // 将 label 赋值给 text
+	}))
+})
+
+// 项目状态数据
+const projectStatus = ref(null)
+const imageValue = ref([])
+const fileList5 = ref([])
+const mediaList = ref([]) // 媒体文件列表
+
+onLoad((options) => {
+
+	console.log("接收到的参数:", options)
+	//获取项目状态
+	if (options.projectId) {
+		getProjectStatus(options.projectId)
+	}
+	formData.projectId = options.projectId
+	formData.projectGrade = sys_sort_grade.value[2].value
+})
+
+async function getProjectStatus(projectId) {
+	try {
+		const res = await getTaskByDictType(projectId)
+		console.log("项目状态数据:", res)
+
+		if (res && res.data) {
+
+			// 根据返回的数据设置默认工作类型
+			// 找到当前活跃的任务类型(active字段对应的索引)
+			const activeIndex = res.data.active || 0
+			const taskList = res.data.taskList || []
+
+			if (taskList.length > 0 && taskList[activeIndex]) {
+				const activeTaskType = taskList[activeIndex].dictValue
+				console.log("设置默认工作类型:", activeTaskType)
+				formData.projectType = activeTaskType
+			}
+		}
+	} catch (error) {
+		console.error("获取项目状态失败:", error)
+		uni.showToast({
+			title: '获取项目状态失败',
+			icon: 'none'
+		})
+	}
+}
+
+// 不要再写 const sysWorkType = [...] 这些静态数据!
+
+// 获取今天的开始和结束时间
+const getTodayTimeRange = () => {
+	const today = new Date()
+	const startTime = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0) // 00:00
+	const endTime = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59) // 23:59
+
+	return [
+		startTime.toISOString().slice(0, 19).replace('T', ' '), // 格式化为 YYYY-MM-DD HH:mm:ss
+		endTime.toISOString().slice(0, 19).replace('T', ' ')
+	]
+}
+
+const formData = reactive({
+	projectName: '',
+	projectType: '',
+	collaborator: '',
+	// projectTime: getTodayTimeRange(), // 默认设置为今天的工作时间
+	projectGrade: '',
+	content: '',
+	remark: '',
+	accessory: '' // 改为字符串类型
+})
+
+const rules = {
+	projectName: {
+		required: true,
+		errorMessage: '请输入任务主题',
+		validateFunction: function (rule, value, data, callback) {
+			if (!value || value.trim() === '') {
+				callback('请输入任务主题')
+			}
+			return true
+		}
+	},
+	projectType: {
+		required: true,
+		errorMessage: '请选择工作类型',
+		validateFunction: function (rule, value, data, callback) {
+			if (!value || value === '') {
+				callback('请选择工作类型')
+			}
+			return true
+		}
+	},
+	collaborator: {
+		required: true,
+		errorMessage: '请输入协作人员',
+		validateFunction: function (rule, value, data, callback) {
+			if (!value || value.trim() === '') {
+				callback('请输入协作人员')
+			}
+			return true
+		}
+	},
+	projectGrade: {
+		required: true,
+		errorMessage: '请选择优先级',
+		validateFunction: function (rule, value, data, callback) {
+			if (!value || value === '') {
+				callback('请选择优先级')
+			}
+			return true
+		}
+	}
+}
+
+const buttonLoading = ref(false)
+const formRef = ref(null)
+
+// 手动验证表单数据
+const validateFormData = () => {
+	const errors = []
+
+	// 验证任务主题
+	if (!formData.projectName || formData.projectName.trim() === '') {
+		errors.push('请输入任务主题')
+	}
+
+	// 验证工作类型
+	if (!formData.projectType || formData.projectType === '') {
+		errors.push('请选择工作类型')
+	}
+
+	// 验证协作人员
+	if (!formData.collaborator || formData.collaborator.trim() === '') {
+		errors.push('请输入协作人员')
+	}
+
+	// 验证优先级
+	if (!formData.projectGrade || formData.projectGrade === '') {
+		errors.push('请选择优先级')
+	}
+
+	return errors
+}
+
+const submitTaskForm = async () => {
+	try {
+		buttonLoading.value = true
+
+		// 手动验证表单数据
+		const validationErrors = validateFormData()
+		if (validationErrors.length > 0) {
+			uni.showToast({
+				title: validationErrors[0],
+				icon: 'none'
+			})
+			return
+		}
+
+		// 表单验证
+		try {
+			await formRef.value.validate()
+		} catch (validateError) {
+			// 验证失败
+			console.log('表单验证失败:', validateError)
+			uni.showToast({
+				title: '请完善必填项信息',
+				icon: 'none'
+			})
+			return
+		}
+
+		console.log('表单数据:', formData)
+		console.log('媒体文件:', mediaList.value)
+
+		// 准备提交的数据
+		const submitData = {
+			...formData,
+			accessory: formData.accessory || ''
+		}
+
+		console.log('最终提交的数据:', submitData)
+		console.log('accessory字段:', submitData.accessory)
+
+		// 这里可以调用addTask API提交数据
+		const result = await addTask(submitData)
+
+		uni.showToast({
+			title: '提交成功',
+			icon: 'success'
+		})
+
+		// 提交成功后可以返回上一页
+		setTimeout(() => {
+			uni.navigateBack()
+		}, 1500)
+
+	} catch (err) {
+		console.log('提交失败:', err)
+		uni.showToast({
+			title: err.message || '提交失败',
+			icon: 'none'
+		})
+	} finally {
+		buttonLoading.value = false
+	}
+}
+
+// 处理媒体文件变化
+const handleMediaChange = (files) => {
+	console.log('媒体文件变化:', files)
+	mediaList.value = files
+
+	const backendUrls = files.map(item => {
+		if (item.backendData && item.backendData.fileName) {
+			return item.backendData.fileName
+		}
+		return item.url
+	}).filter(url => url !== '')
+
+	formData.accessory = backendUrls.join(',')
+
+	if (files.length > 0) {
+		uni.showToast({
+			title: `已选择 ${files.length} 个文件`,
+			icon: 'success',
+			duration: 2000
+		})
+	}
+
+	console.log('当前accessory数据:', formData.accessory)
+}
+
+// 处理后端数据事件
+const handleBackendData = (backendDataList) => {
+	console.log('后端数据:', backendDataList)
+
+	// 提取后端返回的URL
+	const backendUrls = backendDataList.map(item => {
+		if (item && item.fileName) {
+			return item.fileName
+		}
+		return ''
+	}).filter(url => url !== '')
+
+	if (backendUrls.length > 0) {
+		const currentAccessory = formData.accessory || ''
+
+		// 将新的URL添加到现有字符串中
+
+		formData.accessory = backendUrls.join(',')
+
+		console.log('新增后端URL:', backendUrls)
+		console.log('更新后的accessory:', formData.accessory)
+	}
+}
+
+// 文件上传相关方法
+const select = (e) => {
+	console.log('选择文件:', e)
+}
+
+const progress = (e) => {
+	console.log('上传进度:', e)
+}
+
+const success = (e) => {
+	console.log('上传成功:', e)
+}
+
+const fail = (e) => {
+	console.log('上传失败:', e)
+}
+</script>
+
+<style scoped>
+.upload-container {
+	padding: 20rpx;
+	background-color: #f5f5f5;
+	min-height: 100vh;
+}
+
+/* 表单样式优化 */
+:deep(.uni-forms) {
+	background: white;
+	border-radius: 12rpx;
+	padding: 30rpx;
+	margin-bottom: 20rpx;
+}
+
+.header {
+	text-align: center;
+	margin-bottom: 40rpx;
+}
+
+.title {
+	font-size: 36rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.section-title {
+	font-size: 28rpx;
+	color: #666;
+	margin-bottom: 20rpx;
+	display: block;
+}
+
+.type-selector {
+	background: white;
+	padding: 30rpx;
+	border-radius: 12rpx;
+	margin-bottom: 20rpx;
+}
+
+.type-buttons {
+	display: flex;
+	gap: 20rpx;
+}
+
+.type-btn {
+	flex: 1;
+	height: 80rpx;
+	border: 2rpx solid #e0e0e0;
+	background: white;
+	color: #666;
+	border-radius: 8rpx;
+	font-size: 28rpx;
+	transition: all 0.3s;
+}
+
+.type-btn.active {
+	background: #007aff;
+	color: white;
+	border-color: #007aff;
+}
+
+.upload-options {
+	background: white;
+	padding: 30rpx;
+	border-radius: 12rpx;
+	margin-bottom: 20rpx;
+}
+
+.option-buttons {
+	display: flex;
+	gap: 20rpx;
+}
+
+.option-btn {
+	flex: 1;
+	height: 120rpx;
+	background: #f8f9fa;
+	border: 2rpx solid #e0e0e0;
+	border-radius: 12rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	transition: all 0.3s;
+}
+
+.option-btn:active {
+	background: #e9ecef;
+	transform: scale(0.98);
+}
+
+.btn-icon {
+	font-size: 40rpx;
+	margin-bottom: 10rpx;
+}
+
+.btn-text {
+	font-size: 24rpx;
+	color: #666;
+}
+
+.preview-section {
+	background: white;
+	padding: 30rpx;
+	border-radius: 12rpx;
+	margin-bottom: 20rpx;
+}
+
+.preview-list {
+	display: flex;
+	flex-wrap: wrap;
+	gap: 20rpx;
+}
+
+.preview-item {
+	position: relative;
+	width: 200rpx;
+	height: 200rpx;
+	border-radius: 8rpx;
+	overflow: hidden;
+	background: #f8f9fa;
+}
+
+.preview-image,
+.preview-video {
+	width: 100%;
+	height: 100%;
+	object-fit: cover;
+}
+
+.delete-btn {
+	position: absolute;
+	top: 10rpx;
+	right: 10rpx;
+	width: 40rpx;
+	height: 40rpx;
+	background: rgba(0, 0, 0, 0.6);
+	border-radius: 50%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.delete-icon {
+	color: white;
+	font-size: 24rpx;
+	font-weight: bold;
+}
+
+.file-info {
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background: rgba(0, 0, 0, 0.7);
+	padding: 10rpx;
+}
+
+.file-name {
+	color: white;
+	font-size: 20rpx;
+	display: block;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.file-size {
+	color: #ccc;
+	font-size: 18rpx;
+	display: block;
+}
+
+.upload-section {
+	background: white;
+	padding: 30rpx;
+	border-radius: 12rpx;
+	margin-bottom: 20rpx;
+}
+
+.upload-btn {
+	width: 100%;
+	height: 80rpx;
+	background: #007aff;
+	color: white;
+	border-radius: 8rpx;
+	font-size: 28rpx;
+	border: none;
+}
+
+.upload-btn:disabled {
+	background: #ccc;
+}
+
+.progress-section {
+	background: white;
+	padding: 30rpx;
+	border-radius: 12rpx;
+}
+
+.progress-bar {
+	width: 100%;
+	height: 20rpx;
+	background: #e0e0e0;
+	border-radius: 10rpx;
+	overflow: hidden;
+	margin-bottom: 20rpx;
+}
+
+.progress-fill {
+	height: 100%;
+	background: #007aff;
+	transition: width 0.3s;
+}
+
+.progress-text {
+	text-align: center;
+	font-size: 24rpx;
+	color: #666;
+}
+
+/* 必填项红色星号样式 */
+:deep(.uni-forms-item__label) {
+	position: relative;
+}
+
+:deep(.uni-forms-item__label.required::before) {
+	content: '*';
+	color: #ff0000;
+	margin-right: 4rpx;
+}
+
+/* 调整表单标签宽度,防止文字换行 */
+:deep(.uni-forms-item) {
+	display: flex;
+	align-items: flex-start;
+}
+
+:deep(.uni-forms-item__label) {
+	min-width: 180rpx !important;
+	width: 180rpx !important;
+	flex-shrink: 0;
+	white-space: nowrap;
+	text-align: left;
+	padding-right: 20rpx;
+}
+
+:deep(.uni-forms-item__content) {
+	flex: 1;
+	min-width: 0;
+}
+</style>