Files
ys-app/src/pages/business/polling/problemReport.vue

415 lines
12 KiB
Vue
Raw Normal View History

2025-11-20 17:45:41 +08:00
<template>
<view class="con-body">
<view class="con-bg">
<!-- 头部 -->
<customHeader ref="customHeaderRef" title="问题上报"
:leftFlag="true" :rightFlag="false"
></customHeader>
<!-- 高度来避免头部遮挡 -->
<view class="top-height"></view>
2025-11-27 18:18:19 +08:00
<!-- 下拉刷新 -->
<mescroll-uni ref="mescrollRef" @init="mescrollInit"
:down="downOption" @down="downCallback"
:fixed="false" class="scroll-h"
>
<view class="white-bg">
<view class="red-title">问题{{optionObj.groupName}}</view>
<view class="report-list">
<view class="report-pro">问题项</view>
<view class="report-right">
<view class="r-list" v-for="(item, index) in optionObj.pointList" :key="index" @click="handleRound(item)">
<view class="r-left" :class="{'r-red':item.active}">
<view>{{String(index+1).padStart(2, '0')+'.'}}</view>
<view>{{ item.pointName }}</view>
</view>
<view class="r-right">
<view class="r-r-round" :class="{active:item.active}"></view>
</view>
2025-11-20 17:45:41 +08:00
</view>
</view>
</view>
2025-11-27 18:18:19 +08:00
<view class="report-border"></view>
<view class="report-list">
<view class="report-pro">提交人</view>
<view class="report-right">{{optionObj.createUserName?optionObj.createUserName:realname}}</view>
</view>
<view class="report-border"></view>
<view class="report-list" style="display:block;">
问题描述
<textarea class="r-input textarea" v-model="optionObj.problemDesc" auto-height
placeholder="请输入问题项描述" placeholder-class="place-input"
></textarea>
</view>
<view class="report-border"></view>
<view class="report-list" style="display:block;">
<view class="r-title">问题点位照片或视频 <text>*</text></view>
<view class="img-flex">
<view class="img-show" v-for="(item,index) in imgArr" :key="index">
<img :src="item" />
</view>
<view class="img-show" v-for="(item,index) in videoArr" :key="index">
<video :src="item" controls></video>
</view>
<!-- #ifdef APP-PLUS -->
<view class="img-con" @click="chooseMedia">
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
</view>
<!-- #endif -->
<!-- #ifndef APP-PLUS -->
<view class="img-con">
<img :src="'static/images/polling/icon-AddPorV.png'" class="img-pic" />
</view>
<!-- #endif -->
2025-11-20 17:45:41 +08:00
</view>
</view>
2025-11-27 18:18:19 +08:00
<view class="btn-submit">
<button type="primary" @click="handleSubmit">{{problemId?'修改问题跟踪表':'生成问题跟踪表'}}</button>
</view>
2025-11-20 17:45:41 +08:00
</view>
2025-11-27 18:18:19 +08:00
</mescroll-uni>
2025-11-20 17:45:41 +08:00
</view>
</view>
</template>
<script setup>
import { ref,onMounted,onUnmounted,nextTick,computed,reactive } from 'vue'
import { onLoad,onHide} from '@dcloudio/uni-app';
import customHeader from '@/components/customHeader.vue';
import MescrollUni from 'mescroll-uni/mescroll-uni.vue';
import { getUserInfo } from '@/api/auth.js'
2025-11-27 18:18:19 +08:00
import { problemDetail,problemAdd,problemEdit,minioUpload } from '@/api/polling.js'
import {compressImageUni,getMinioThumbUrl} from '@/utils/common.js'
import {showAlert,showLoading,hideLoading} from '@/utils/message.js'
2025-11-20 17:45:41 +08:00
2025-11-27 18:18:19 +08:00
let taskId = ref('');//任务id
let groupId = ref('');//组id
let problemId = ref('');//问题id
2025-11-20 17:45:41 +08:00
let realname = ref('');
let desc = ref('');//描述
onLoad(async option => {
// console.log(option)
2025-11-27 18:18:19 +08:00
taskId.value = option.taskId;
groupId.value = option.groupId;
problemId.value = option.problemId;
2025-11-20 17:45:41 +08:00
let userinfo = await getUserInfo({});
realname.value = userinfo.realname
})
// 查询列表
let list = ref([]);
let optionObj = ref({})
2025-11-27 18:18:19 +08:00
// 下拉刷新
const mescrollRef = ref(null);
const mescrollInit = (mescroll) => {
mescrollRef.value = mescroll;
};
const downOption = ref({
auto: true,
textInOffset: '下拉刷新',
textOutOffset: '释放更新',
textLoading: '刷新中...'
});
// 下拉刷新
const downCallback = async (mescroll) => {
try {
getList();
} catch (error) {
mescroll.endErr();
} finally {
mescroll.endSuccess();
}
}
2025-11-20 17:45:41 +08:00
// 获取数据列表
2025-11-27 18:18:19 +08:00
const getList = async () => {
let param = {
taskId:problemId.value?undefined:taskId.value,
groupId:problemId.value?undefined:groupId.value,
problemId:problemId.value
2025-11-20 17:45:41 +08:00
}
2025-11-27 18:18:19 +08:00
let res = await problemDetail(param);
let data = res||{};
let pointIds = data.pointId.split(",");
data.pointList.forEach(item2=>{
item2.active=false;
for (let i = 0; i < pointIds.length; i++) {
if(item2.pointId == pointIds[i]){
item2.active=true;
break;
}
}
})
optionObj.value = data;
2025-11-20 17:45:41 +08:00
}
// 图片或视频
2025-11-27 18:18:19 +08:00
let mediaArr = ref([]);//传给后台的地址
let imgArr=ref([]);//图片 后台返回的
let videoArr = ref([]);//视频 后台返回的
2025-11-20 17:45:41 +08:00
const chooseMedia = () => {
uni.chooseMedia({
count: 9,
mediaType: ['image', 'video'], // 指定可选择图片和视频
sourceType: ['album', 'camera'],
2025-11-27 18:18:19 +08:00
maxDuration: 60, // 拍摄视频最长拍摄时间
2025-11-20 17:45:41 +08:00
camera: 'back',
success: (res) => {
console.log(res)
2025-11-27 18:18:19 +08:00
res.tempFiles.forEach(async file => {
// tempFilePath
2025-11-21 18:25:05 +08:00
console.log(`文件类型: ${file.fileType}, 文件路径: ${file.tempFilePath}`);
2025-11-27 18:18:19 +08:00
let compressImg = file.tempFilePath;
// 图片进行压缩
2025-11-21 18:25:05 +08:00
if (file.fileType === 'image') {
2025-11-27 18:18:19 +08:00
// #ifdef APP-PLUS
// 压缩图片
compressImg = await compressImageUni(file.tempFilePath);
// #endif
2025-11-20 17:45:41 +08:00
}
2025-11-27 18:18:19 +08:00
// 执行上传
let param = {
filePath: compressImg,
name: 'file',
formData: {
directory:'polling'
},
}
minioUpload(param).then(res=>{
let data = res.data;
mediaArr.value.push(data.fileName);
if (file.fileType === 'image') {// 图片
imgArr.value.push(data.fileUrl)
} else if (file.type === 'video') {// 视频
videoArr.value.push(data.fileUrl)
}
})
2025-11-20 17:45:41 +08:00
});
}
});
}
2025-11-21 18:25:05 +08:00
// 红点点击
const handleRound=(item)=>{
item.active=!item.active
}
2025-11-20 17:45:41 +08:00
// 提交
const handleSubmit=()=>{
2025-11-27 18:18:19 +08:00
let pointIds = [];
optionObj.value.pointList.forEach(item => {
if(item.active){
pointIds.push(item.pointId)
}
});
showLoading("加载中...")
if(problemId.value){
let param = {
problemId:problemId.value,
pointId:pointIds.join(","),
problemVedio:mediaArr.value.join(","),
problemDesc:optionObj.problemDesc
}
console.log("problemEdit=>",param)
problemEdit(param).then(res=>{
showAlert("新增上报问题成功")
}).finally(()=>{
hideLoading();
})
}else{
let param = {
taskId:taskId.value,
groupId:groupId.value,
pointId:pointIds.join(","),
problemVedio:mediaArr.value.join(","),
problemDesc:optionObj.problemDesc
}
console.log("problemAdd=>",param)
problemAdd(param).then(res=>{
showAlert("编辑上报问题成功")
}).finally(()=>{
hideLoading();
})
}
2025-11-20 17:45:41 +08:00
}
</script>
<style scoped>
2025-11-27 18:18:19 +08:00
.scroll-h{
/* #ifdef APP-PLUS */
height:calc(100vh - 78px) !important;
/* #endif */
/* #ifndef APP-PLUS */
height: calc(100vh - 58px) !important;
/* #endif */
}
:deep(.mescroll-upwarp){
display: none !important;
}
2025-11-20 17:45:41 +08:00
.white-bg{
width: 680rpx;
padding: 15rpx 30rpx 40rpx 40rpx;
margin-bottom: 0;
border-radius: 8px 8px 0 0;
}
.white-bg .red-title{
margin-bottom:30rpx;
color:#FF2B44;
font-size:38rpx;
}
.report-border{
border-bottom:1px solid #E7E7E7;
width:710rpx;
height: 1px;
margin:20rpx 0;
}
.report-list{
display: flex;
font-size:28rpx;
}
.report-list .r-title{
position: relative;
}
.report-list text{
color:#FF2B44;
font-size:28rpx;
}
.report-list .report-pro{
font-size:28rpx;
width:16%;
/* margin-right:30rpx; */
}
.report-list .report-right{
width:84%;
color:#919191;
font-size:28rpx;
}
.report-list .r-input{
border:1px solid #E7E7E7;
border-radius: 10rpx;
width:620rpx;
padding:15rpx 25rpx;
margin:20rpx 0 30rpx;
}
.report-list .place-input{
color:#BFBFBF;
font-size:28rpx;
}
.report-list .textarea{
min-height: 120rpx;
}
.report-list .r-list{
padding: 10rpx 0;
}
.report-list .r-list:first-child{
padding-top:0;
}
.report-list .r-left{
display: flex;
2025-11-27 18:18:19 +08:00
align-items: center;
2025-11-21 18:25:05 +08:00
width:90%;
2025-11-20 17:45:41 +08:00
font-size:28rpx;
color:#919191;
}
.report-list .r-left view:first-child{
margin-right: 10rpx;
}
.report-list .r-left.r-red{
color: #FF2B44;
font-size: 28rpx;
}
.report-list .r-right{
display: flex;
font-size:30rpx;
align-items: center;
justify-content: center;
}
.report-list .r-r-round{
width:35rpx;
height:35rpx;
border:1px solid #BDBDBD;
border-radius: 50%;
}
.report-list .r-r-round.active{
border:1px solid #FF2B44;
background-color: #FF2B44;
position: relative;
}
.report-list .r-r-round.active::after{
content:"!";
position: absolute;
top:0;
left:0;
color:#fff;
text-align: center;
width:35rpx;
height:35rpx;
/* #ifndef APP-PLUS */
line-height: 30rpx;
/* #endif */
/* #ifdef APP-PLUS */
2025-11-21 18:25:05 +08:00
height:33rpx;
padding-top:2rpx;
2025-11-20 17:45:41 +08:00
/* #endif */
}
2025-11-21 18:25:05 +08:00
.report-list .img-flex{
display: flex;
flex-flow:row wrap;
margin-bottom:30rpx;
}
.report-list .img-show img,
.report-list .img-show video{
width:210rpx;
height: 140rpx;
}
.report-list .img-show :deep(.uni-video-cover-play-button){
width:64rpx;
height: 64rpx;
line-height: 64rpx;
font-size:60rpx;
}
2025-11-20 17:45:41 +08:00
.report-list .img-con{
background-color: #EEEEEE;
width:210rpx;
height: 140rpx;
text-align: center;
color:#919191;
font-size: 24rpx;
}
.report-list .img-con .img-pic{
width:76rpx;
height: 76rpx;
margin-top:30rpx;
}
.report-list .img-show,
.report-list .img-con{
width: calc(100% / 3 - 10px); /* 减去一些间隙以避免溢出 */
2025-11-21 18:25:05 +08:00
margin:20rpx 20rpx 0 0;
2025-11-20 17:45:41 +08:00
}
.btn-submit{
width:400rpx;
margin:90rpx auto;
}
.btn-submit uni-button[type='primary']{
background-color: #05A3F4;
border-radius: 40rpx;
line-height: 2.2;
}
.btn-submit uni-button:after{
border-color:#05A3F4;
}
</style>