巡检-早于巡检时间,禁止提交

This commit is contained in:
Zy
2026-09-03 17:03:39 +08:00
parent 825220cd86
commit 0a68226c3b
3 changed files with 88 additions and 36 deletions

View File

@@ -5,8 +5,8 @@
<!-- 已选图片 --> <!-- 已选图片 -->
<view v-for="(img, index) in innerList" :key="index" class="image-item"> <view v-for="(img, index) in innerList" :key="index" class="image-item">
<image :src="img.url || img" class="img" mode="aspectFill" @tap="preview(index)"></image> <image :src="img.url || img" class="img" mode="aspectFill" @tap="preview(index)"></image>
<!-- 删除按钮 --> <!-- 删除按钮 禁用时隐藏 -->
<view class="delete-btn" @tap.stop="remove(index)"> <view v-if="!props.disabled" class="delete-btn" @tap.stop="remove(index)">
<uni-icons type="closeempty" size="16" color="#fff"></uni-icons> <uni-icons type="closeempty" size="16" color="#fff"></uni-icons>
</view> </view>
<!-- 上传状态 --> <!-- 上传状态 -->
@@ -14,19 +14,22 @@
<text>上传中...</text> <text>上传中...</text>
</view> </view>
</view> </view>
<!-- 添加按钮 --> <!-- 添加按钮 禁用或者达到上限不显示 -->
<view class="add-btn" @tap="choose" v-if="innerList.length < props.limit"> <view
class="add-btn"
:class="{ 'add-btn-disabled': props.disabled }"
@tap="choose"
v-if="innerList.length < props.limit"
>
<uni-icons color="#a6a6a6" type="plusempty" size="25"></uni-icons> <uni-icons color="#a6a6a6" type="plusempty" size="25"></uni-icons>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import baseUrl from '@/api/BaseUrl.js' import baseUrl from '@/api/BaseUrl.js'
import { requestAuth } from '@/utils/Auth.js' import { requestAuth } from '@/utils/Auth.js'
// ====================== // ======================
// Props(可配置) // Props(可配置)
// ====================== // ======================
@@ -65,19 +68,21 @@ const props = defineProps({
extraData: { extraData: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
},
// ✅ 新增:禁用组件
disabled: {
type: Boolean,
default: false
} }
}) })
// ====================== // ======================
// Emits // Emits
// ====================== // ======================
const emit = defineEmits(['update:modelValue', 'success', 'fail', 'remove']) const emit = defineEmits(['update:modelValue', 'success', 'fail', 'remove'])
// ====================== // ======================
// 内部数据 // 内部数据
// ====================== // ======================
const innerList = ref([]) const innerList = ref([])
// 监听外部数据变化 // 监听外部数据变化
watch( watch(
() => props.modelValue, () => props.modelValue,
@@ -91,13 +96,13 @@ watch(
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
) )
// ====================== // ======================
// 核心方法 // 核心方法
// ====================== // ======================
// 1. 选择图片 // 1. 选择图片
function choose() { function choose() {
// 禁用直接返回
if (props.disabled) return
uni.chooseImage({ uni.chooseImage({
count: props.limit - innerList.value.length, count: props.limit - innerList.value.length,
sourceType: props.sourceType, sourceType: props.sourceType,
@@ -146,13 +151,13 @@ function choose() {
} }
}) })
} }
// 2. 上传单张图片 // 2. 上传单张图片
async function uploadSingle(filePath) { async function uploadSingle(filePath) {
// 禁用不再新增上传
if (props.disabled) return
// 先添加到列表,标记为上传中 // 先添加到列表,标记为上传中
const tempItem = { url: filePath, uploading: true } const tempItem = { url: filePath, uploading: true }
innerList.value = [...innerList.value, tempItem] innerList.value = [...innerList.value, tempItem]
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
uni.uploadFile({ uni.uploadFile({
url: `${baseUrl}${props.uploadUrl}`, url: `${baseUrl}${props.uploadUrl}`,
@@ -167,7 +172,6 @@ async function uploadSingle(filePath) {
success: res => { success: res => {
try { try {
const data = JSON.parse(res.data) const data = JSON.parse(res.data)
// 假设后端返回格式:{ code: 200, url: "https://xxx.com/xxx.png" } // 假设后端返回格式:{ code: 200, url: "https://xxx.com/xxx.png" }
// 如果你的后端返回格式不同,请在这里修改 // 如果你的后端返回格式不同,请在这里修改
if (data.code === 200 || data.url) { if (data.code === 200 || data.url) {
@@ -201,9 +205,10 @@ async function uploadSingle(filePath) {
}) })
}) })
} }
// 3. 删除图片 // 3. 删除图片
function remove(index) { function remove(index) {
// 禁用禁止删除
if (props.disabled) return
const removed = innerList.value.splice(index, 1)[0] const removed = innerList.value.splice(index, 1)[0]
emit( emit(
'update:modelValue', 'update:modelValue',
@@ -211,8 +216,7 @@ function remove(index) {
) )
emit('remove', { index, url: removed.url }) emit('remove', { index, url: removed.url })
} }
// 4. 预览图片(预览保留,禁用也可以看)
// 4. 预览图片
function preview(index) { function preview(index) {
const urls = innerList.value.map(i => i.url).filter(Boolean) const urls = innerList.value.map(i => i.url).filter(Boolean)
if (urls.length <= 0) return if (urls.length <= 0) return
@@ -222,12 +226,10 @@ function preview(index) {
}) })
} }
</script> </script>
<style scoped> <style scoped>
.simple-uploader { .simple-uploader {
width: 100%; width: 100%;
} }
.image-list { .image-list {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
@@ -236,19 +238,16 @@ function preview(index) {
margin-right: 20rpx; margin-right: 20rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
} }
.image-item { .image-item {
position: relative; position: relative;
width: 160rpx; width: 160rpx;
height: 160rpx; height: 160rpx;
} }
.img { .img {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 8rpx; border-radius: 8rpx;
} }
.delete-btn { .delete-btn {
position: absolute; position: absolute;
top: 0rpx; top: 0rpx;
@@ -261,7 +260,6 @@ function preview(index) {
justify-content: center; justify-content: center;
z-index: 10; z-index: 10;
} }
.uploading-mask { .uploading-mask {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -276,7 +274,6 @@ function preview(index) {
color: #fff; color: #fff;
font-size: 24rpx; font-size: 24rpx;
} }
.add-btn { .add-btn {
width: 160rpx; width: 160rpx;
height: 160rpx; height: 160rpx;
@@ -285,4 +282,8 @@ function preview(index) {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.add-btn-disabled {
background-color: #eee;
opacity: 0.6;
}
</style> </style>

View File

@@ -77,6 +77,7 @@
file-field-name="file" file-field-name="file"
uploadUrl="/api/butler/file/uploadImage" uploadUrl="/api/butler/file/uploadImage"
@fail="onUploadFail" @fail="onUploadFail"
:disabled="disableUpload"
></filePicker> ></filePicker>
</view> </view>
<view class="filePickerbox showimagegrid" v-else> <view class="filePickerbox showimagegrid" v-else>
@@ -92,7 +93,14 @@
</view> </view>
</view> </view>
</uni-forms> </uni-forms>
<view class="submitbox" @tap="handleSubmit(ite)" v-if="!ite.complated"> <view
class="submitbox"
@tap="handleSubmit(ite)"
v-if="!ite.complated"
:class="{
disable: disableUpload
}"
>
<text>提交</text> <text>提交</text>
</view> </view>
<view class="line" v-if="ind + 1 < item.points.length"> </view> <view class="line" v-if="ind + 1 < item.points.length"> </view>
@@ -149,6 +157,26 @@ const rules = {
} }
} }
// 限制提交任务时间段 true 不可以提交 false 可以提交
const disableUpload = computed(() => {
if (info.value) {
const day = new Date()
const [start, end] = info.value.taskTime.split('-') ?? []
if (start && end) {
const startTime = day.toLocaleDateString() + ' ' + start + ':00'
const endTime = day.toLocaleDateString() + ' ' + end + ':00'
if (new Date(startTime).getTime() <= day.getTime()) {
return false
} else {
return true
}
} else {
return true
}
} else {
return true
}
})
function init() { function init() {
if (!taskid.value) return if (!taskid.value) return
getInspectionMain(taskid.value) getInspectionMain(taskid.value)
@@ -168,7 +196,6 @@ function init() {
files: ite.imgUrl ? ite.imgUrl.split(',') : [] files: ite.imgUrl ? ite.imgUrl.split(',') : []
} }
}) })
console.log(points)
return { return {
routeName: item.routeName, routeName: item.routeName,
routeId: item.routeId, routeId: item.routeId,
@@ -192,7 +219,6 @@ onLoad(options => {
}) })
// ---------------------------------------------- // ----------------------------------------------
function onUploadFail() { function onUploadFail() {
uni.showToast({ uni.showToast({
icon: 'error', icon: 'error',
@@ -200,14 +226,28 @@ function onUploadFail() {
}) })
} }
let isSubmit = false
/** 提交巡检点 检查情况 */ /** 提交巡检点 检查情况 */
function handleSubmit(item) { function handleSubmit(item) {
if (isSubmit) return
isSubmit = true
if (disableUpload.value) {
uni.showToast({
icon: 'none',
title: '不在任务时间段内',
mask: true
})
isSubmit = false
return
}
if (item.files.length <= 0) { if (item.files.length <= 0) {
uni.showToast({ uni.showToast({
icon: 'error', icon: 'error',
mask: true, mask: true,
title: '必须拍照' title: '必须拍照'
}) })
isSubmit = false
return return
} }
uni.showLoading({ uni.showLoading({
@@ -243,6 +283,7 @@ function handleSubmit(item) {
}) })
.finally(() => { .finally(() => {
uni.hideLoading() uni.hideLoading()
isSubmit = false
}) })
} }
@@ -393,6 +434,11 @@ function previewImages(images, currentIndex) {
color: #ffffff; color: #ffffff;
line-height: 80rpx; line-height: 80rpx;
margin-top: 40rpx; margin-top: 40rpx;
&.disable {
background-color: #ccc;
color: #fff;
}
} }
} }
</style> </style>

View File

@@ -16,9 +16,7 @@
</view> </view>
<view class="flex justify-between"> <view class="flex justify-between">
<span class="subtitle">{{ data.desc }}</span> <span class="subtitle">{{ data.desc }}</span>
<span class="subtime" v-if="currentStep == index + 1">{{ <span class="subtime">{{ data.time }}</span>
repairInfo.updateTime
}}</span>
</view> </view>
</view> </view>
</template> </template>
@@ -150,10 +148,10 @@ import { getTicketMainById, shareRepairUser } from '@/api/ticket.js'
const currentStep = ref(2) const currentStep = ref(2)
// 步骤数据 // 步骤数据
const stepList = ref([ const stepList = ref([
{ title: '提交维修信息', desc: '等待提交报修' }, { title: '提交维修信息', desc: '等待提交报修', time: '' },
{ title: '待分配', desc: '等待物业派单中' }, { title: '待分配', desc: '等待物业派单中', time: '' },
{ title: '待解决', desc: '等待维修人员' }, { title: '待解决', desc: '等待维修人员', time: '' },
{ title: '维修完成', desc: '填写维修记录' } { title: '维修完成', desc: '填写维修记录', time: '' }
]) ])
// -------------------------------------- // --------------------------------------
const queryParams = ref({ const queryParams = ref({
@@ -231,18 +229,21 @@ function getTicketById() {
function handleStop(row) { function handleStop(row) {
// 0 已提交 1 已分配 2已解决 // 0 已提交 1 已分配 2已解决
let status = row.problemStatus let status = row.problemStatus
const repairInfo = row.repairProcessList[0]
currentStep.value = 0 currentStep.value = 0
// 维修步骤:0提交 1分配 2维修完成 / 待解决 3记录完成 完成 // 维修步骤:0提交 1分配 2维修完成 / 待解决 3记录完成 完成
if (status === '0') { if (status === '0') {
currentStep.value = 1 currentStep.value = 1
stepList.value[0].desc = '提交报修成功' stepList.value[0].desc = '提交报修成功'
stepList.value[0].time = repairInfo.submitTime
return return
} }
if (status === '1') { if (status === '1') {
currentStep.value = 2 currentStep.value = 2
stepList.value[0].time = repairInfo.submitTime
stepList.value[1].title = '已派单' stepList.value[1].title = '已派单'
stepList.value[1].desc = '物业已派单' stepList.value[1].desc = '物业已派单'
stepList.value[1].time = repairInfo.allocateTime
stepList.value[2].title = '待解决' stepList.value[2].title = '待解决'
stepList.value[2].desc = `维修人员(${row.repairName})维修中` stepList.value[2].desc = `维修人员(${row.repairName})维修中`
return return
@@ -250,10 +251,14 @@ function handleStop(row) {
if (status === '2') { if (status === '2') {
currentStep.value = 4 currentStep.value = 4
stepList.value[0].desc = '提交报修成功' stepList.value[0].desc = '提交报修成功'
stepList.value[0].time = repairInfo.submitTime
stepList.value[1].title = '已派单' stepList.value[1].title = '已派单'
stepList.value[1].desc = '物业已派单' stepList.value[1].desc = '物业已派单'
stepList.value[1].time = repairInfo.allocateTime
stepList.value[2].title = '已解决' stepList.value[2].title = '已解决'
stepList.value[2].desc = `维修人员(${row.repairName})已解决` stepList.value[2].desc = `维修人员(${row.repairName})已解决`
stepList.value[2].time = repairInfo.completeTime
stepList.value[3].time = repairInfo.completeTime
return return
} }
} }
@@ -346,7 +351,7 @@ function handlePrivew(items, index = 0) {
.subtime { .subtime {
font-weight: 400; font-weight: 400;
font-size: 22rpx; font-size: 22rpx;
color: #999999; color: rgba(77, 93, 250, 1);
line-height: 40rpx; line-height: 40rpx;
} }
} }