LpRealName/pages/realName/workbench/dailyPlanManagement/upload.vue

418 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<u-navbar class="u-navbar" title="完成情况上传" placeholder @leftClick="leftClick" leftIconColor="#fff"
bgColor="#00337A" :titleStyle="{ color: '#FFF', fontSize: '32rpx' }" />
<!-- Project Header -->
<view class="project-header">
<text class="project-title">{{proName}}</text>
<!-- <view class="completion-rates">
<text>作业计划完成率70%</text>
<text>月作业计划完成率70%</text>
</view> -->
</view>
<!-- Total Plan Input -->
<view class="total-plan">
<text>计划作业人数</text>
<text>{{planWorkNum}}</text>
</view>
<!-- Project Table -->
<view class="table-container">
<view class="table-header">
<text class="col-index">序号</text>
<text class="col-name">项目名称</text>
<text class="col-desc">项目描述</text>
<text class="col-completion">本日计划完成量</text>
<text class="col-completion">本日实际完成量</text>
</view>
<view class="table-body">
<view v-for="(item, index) in tableData" :key="index" class="table-row">
<text class="col-index">{{ index + 1 }}</text>
<text class="col-name">{{ item.taskName }}</text>
<view class="col-desc">
<text>{{ item.taskContent }}</text>
</view>
<view class="col-completion">
<text>{{ item.completeNumDay }}</text>
</view>
<view class="col-completion">
<input type="number" v-model="item.actualCompleteNumDay" class="completion-input" />
<input type="hidden" name="dayContentId" :value="item.dayContentId" class="hidden-input">
</view>
</view>
</view>
</view>
<!-- Image Upload Section -->
<view class="image-upload-section">
<text class="upload-title">* 当天作业人员合照</text>
<view class="upload-area" @tap="chooseImage">
<image v-if="imageUrl" :src="imageUrl" mode="aspectFit" class="preview-image"></image>
<text v-else class="upload-text">点击上传图片</text>
</view>
<text v-if="uploadStatus" :class="['upload-status', uploadStatus === 'success' ? 'success' : 'error']">
{{ uploadStatusText }}
</text>
</view>
<!-- Save Button -->
<view class="save-button-container">
<button type="primary" @click="saveData">保存</button>
</view>
</view>
</template>
<script>
import config from '@/config'
export default {
onLoad(options) {
this.dayId = decodeURIComponent(options.dayId);
this.proName = decodeURIComponent(options.proName);
this.id = decodeURIComponent(options.id);
this.getListTable()
},
data() {
return {
dayId: '',
proName: '',
id: '',
totalPlan: '',
tableData: [],
imageUrl: '',
uploadStatus: '',
uploadStatusText: '',
planWorkNum:'',
photoPath:''
}
},
methods: {
getListTable() {
let param = {
dayId: this.dayId,
id: this.id
}
uni.request({
url: config.lpBmwUrl + '/bmw/workPlanDay/getPlanDetailByIdEdit',
method: 'post',
data: JSON.stringify(param),
header: {
'content-type': 'application/json',
'Authorization': uni.getStorageSync('realNameToken')
},
success: res => {
console.log('日计划完成情况上传', res)
if (res.data.code == 200) {
this.tableData = res.data.data.contentList;
this.planWorkNum = res.data.data.planWorkNum
} else {
uni.$u.toast(res.data.msg);
}
},
fail: err => {
console.log(err)
}
})
},
chooseImage() {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePaths = res.tempFilePaths
this.imageUrl = tempFilePaths[0]
this.uploadImage(tempFilePaths[0])
}
})
},
uploadImage(filePath) {
this.uploadStatus = 'uploading'
this.uploadStatusText = '上传中...'
//上传考勤图片
uni.uploadFile({
url: config.realFileUrl + `file/upload`, //服务器地址
fileType: "image", //ZFB必填,不然报错
filePath: filePath, //这个就是我们上面拍照返回或者先中照片返回的数组
name: "imgFile",
formData: {
photoType: 'attendance',
},
success: (uploadFileRes) => {
if (uploadFileRes.statusCode == 200) {
this.photoPath=JSON.parse(uploadFileRes.data).data.url;
this.uploadStatus = 'success'
this.uploadStatusText = '上传成功'
} else {
uni.$u.toast('上传失败');
}
},
fail: err => {
uni.$u.toast('上传失败');
console.log(err)
}
});
},
saveData(){
if(this.photoPath == null || this.photoPath == ''){
uni.$u.toast('请上传图片');
return false;
}
let isValid = true;
let errorMessage = '';
this.tableData.forEach((item, index) => {
const actualCompleteNumDay = Number(item.actualCompleteNumDay) || 0;
console.log("actualCompleteNumDay",actualCompleteNumDay)
const completeNumDay = Number(item.completeNumDay);
console.log("completeNumDay",completeNumDay)
if (actualCompleteNumDay > completeNumDay) {
isValid = false;
errorMessage += `${index + 1} 行: 本日实际完成量 不能大于 本日计划完成量\n`;
}
});
if (!isValid) {
uni.showModal({
title: '验证错误',
content: errorMessage,
showCancel: false
});
return;
}
const members = this.tableData.map(item => ({
actualCompleteNumDay: item.actualCompleteNumDay,
dayContentId:item.dayContentId
}));
const incompleteTasks = this.tableData.filter(item => item.actualCompleteNumDay == null || item.actualCompleteNumDay < 0);
if (incompleteTasks.length > 0) {
uni.showToast({
icon: 'none',
title: '请确保所有任务都有有效的本日实际完成量'
});
return;
}
const allData = {
dayId: this.dayId,
path: this.photoPath,
contentList: members
}
console.log(allData)
uni.request({
url: config.lpBmwUrl + '/bmw/workPlanDay/upload',
method: 'post',
data: JSON.stringify(allData),
header: {
'content-type': 'application/json',
'Authorization': uni.getStorageSync('realNameToken')
},
success: res => {
console.log('日计划制定', res)
if (res.data.code == 200) {
// 模拟保存成功后提示用户
uni.showToast({
icon: 'success',
title: '保存成功',
duration: 2000, // 提示框显示时间,单位为毫秒
success: () => {
setTimeout(() => {
this.leftClick(); // 在提示框消失后返回上一级页面
}, 2000); // 确保与duration一致
}
});
} else {
uni.$u.toast(res.data.msg);
}
},
fail: err => {
console.log(err)
}
})
},
// 返回
leftClick() {
console.log('返回')
uni.navigateBack({
delta: 1 // 返回
});
}
}
}
</script>
<style>
.container {
padding: 30rpx;
background-color: #fff;
}
.project-header {
margin-bottom: 30rpx;
}
.project-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.completion-rates {
display: flex;
justify-content: space-between;
color: #666;
font-size: 28rpx;
}
.total-plan {
display: flex;
align-items: center;
margin-bottom: 30rpx;
font-size: 28rpx;
}
.total-input {
width: 200rpx;
height: 60rpx;
border: 1px solid #ddd;
padding: 0 20rpx;
margin-left: 20rpx;
}
.table-container {
border: 1px solid #ddd;
margin-bottom: 30rpx;
}
.table-header,
.table-row {
display: flex;
font-size: 24rpx;
padding: 15rpx 10rpx;
border-bottom: 1px solid #ddd;
align-items: center;
}
.table-header {
background-color: #f5f5f5;
font-weight: bold;
}
.table-body {
background-color: #fff;
}
.table-row:nth-child(even) {
background-color: #fafafa;
}
.table-row:last-child {
border-bottom: none;
}
.table-row>* {
display: flex;
align-items: center;
}
.col-index {
width: 60rpx;
flex-shrink: 0;
}
.col-name {
width: 140rpx;
flex-shrink: 0;
}
.col-desc {
flex: 1;
min-width: 200rpx;
flex-direction: column;
align-items: flex-start;
}
.col-completion {
width: 160rpx;
flex-shrink: 0;
box-sizing: border-box;
padding: 0 5rpx;
text-align: center;
justify-content: center;
}
.completion-input {
width: 100%;
height: 50rpx;
border: 1px solid #ddd;
padding: 0 5rpx;
box-sizing: border-box;
font-size: 24rpx;
}
input {
background-color: #fff;
}
.image-upload-section {
margin-top: 30rpx;
}
.upload-title {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.upload-area {
width: 100%;
height: 300rpx;
border: 2rpx dashed #ddd;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.upload-text {
color: #999;
font-size: 28rpx;
}
.preview-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.upload-status {
font-size: 24rpx;
margin-top: 10rpx;
}
.upload-status.success {
color: #52c41a;
}
.upload-status.error {
color: #ff4d4f;
}
/* 确保隐藏输入字段 */
.hidden-input {
display: none;
}
</style>