Files
property-resident-side/property-uniapp-project/pageSubPack/online-repair/publicRepair.vue
2026-08-03 14:20:17 +08:00

362 lines
8.7 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="form-container">
<!-- 维修项目展示 -->
<view class="form-item">
<text class="label">维修项目</text>
<view class="value" @click="goBackSelect">
<view>
<text v-if="!repairProject">请选择项目</text>
{{ repairProject }}
</view>
<uni-icons type="arrowright" size="16"></uni-icons>
</view>
</view>
<!-- 标题输入 -->
<view class="form-item">
<text class="label">标题</text>
<uni-easyinput v-model="form.title" placeholder="请输入内容最多30个字符" :inputBorder="false" maxlength="30"></uni-easyinput>
</view>
<!-- 问题描述 -->
<view class="form-item-wenti">
<text class="label">问题描述</text>
<view class="textarea-wrap">
<textarea v-model="form.desc" placeholder="请描述你的问题最多200字" maxlength="200" class="desc-textarea" />
<text class="char-count">{{ form.desc.length }}/200</text>
</view>
</view>
<!-- 手机号 -->
<view class="form-item">
<text class="label">手机号</text>
<uni-easyinput type="number" v-model="form.phone" placeholder="请输入手机号" :inputBorder="false"></uni-easyinput>
</view>
<!-- 图片上传 -->
<view class="form-item-wenti">
<text class="label">问题照片</text>
<view class="upload-wrap">
<!-- 已上传图片 -->
<view class="upload-item" v-for="(img, index) in form.images" :key="index">
<image :src="img" mode="aspectFill" class="upload-img"></image>
<image src="https://wuyeadmin.bugtc.com/images/imgs/delete.png" class="upload-delete" @click="deleteImage(index)"></image>
<!-- <uni-icons type="close" size="16" @click="deleteImage(index)"></uni-icons> -->
</view>
<!-- 上传按钮 -->
<view class="upload-btn" @click="chooseImage" v-if="form.images.length < 3">
<uni-icons type="plusempty" size="24"></uni-icons>
<!-- <text>上传照片</text> -->
</view>
</view>
</view>
<!-- 提交按钮 -->
<button class="submit-btn" :disabled="submitting" @click="submitForm">{{ submitting ? '提交中...' : '提交' }}</button>
<!-- 提交中遮罩 -->
<view class="submit-mask" v-if="submitting" @touchmove.stop.prevent></view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import{onLoad,onUnload} from "@dcloudio/uni-app"
import { addQueryRepair, uploadFile } from '../api/api.js'
import { getUserProfile } from '../api/apiSub.js'
// 接收上个页面传的维修项目
const repairProject = ref('')
const projectId = ref('')
// 提交状态锁
const submitting = ref(false)
// 表单数据
const form = ref({
title: '',
desc: '',
phone: '',
images: [] // 图片列表
})
// 页面加载
onLoad((options) => {
// 第一次进入页面接收参数
if (options.category && options.project) {
repairProject.value = `${options.category}-${options.project}`
projectId.value = options.projectId
form.value.title = `${options.category}-${options.project}`
}
// ✅ 监听返回选择的项目
uni.$on('selectRepairProject', (data) => {
repairProject.value = `${data.category}-${data.project}`
projectId.value = data.projectId
form.value.title = `${data.category}-${data.project}`
})
// 自动获取当前登录用户手机号
getUserProfile().then(res => {
if (res.code === 200 && res.data && res.data.phone) {
form.value.phone = res.data.phone
}
})
})
// ✅ 页面卸载时移除监听(必须加)
onUnload(() => {
uni.$off('selectRepairProject')
})
// 返回选择项目页
const goBackSelect = () => {
uni.navigateTo({
url:"/pageSubPack/online-repair/repairSelect"
})
// uni.navigateBack({
// delta: 1
// })
}
// 选择图片
const chooseImage = () => {
// 计算还能选几张
const remainCount = 3 - form.value.images.length;
if (remainCount <= 0) {
uni.showToast({
title: '最多只能上传3张图片',
icon: 'none'
})
return;
}
uni.chooseImage({
count: remainCount, // 动态限制可选数量
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePaths = res.tempFilePaths
form.value.images = [...form.value.images, ...tempFilePaths]
}
})
}
// 删除图片
const deleteImage = (index) => {
form.value.images.splice(index, 1)
}
// 上传图片
const uploadImages = async () => {
const uploadedUrls = []
for (const path of form.value.images) {
if (path.startsWith('http')) {
uploadedUrls.push(path)
continue
}
try {
const res = await uploadFile(path)
// 根据后端实际返回结构调整字段名
uploadedUrls.push(res.url || '')
} catch (err) {
uni.showToast({
title:e.msg || '图片上传失败',
icon:'error'
})
}
}
return uploadedUrls
}
// 表单提交
const submitForm = async () => {
// 表单校验
if (!repairProject.value) {
uni.showToast({ title: '请选择维修项目', icon: 'none' })
return
}
if (!form.value.title) {
uni.showToast({ title: '请输入问题标题', icon: 'none' })
return
}
// if (!form.value.desc) {
// uni.showToast({ title: '请输入问题描述', icon: 'none' })
// return
// }
if (!/^1[3-9]\d{9}$/.test(form.value.phone)) {
uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
return
}
const villageId = uni.getStorageSync('currentVillageId')
if (!villageId || villageId === '0') {
uni.showToast({ title: '请先选择小区', icon: 'none' })
return
}
submitting.value = true
uni.showLoading({ title: '提交中...' ,mask:true})
try {
// 先上传图片
const imageUrls = await uploadImages()
const userId = uni.getStorageSync('userId')
const params = {
villageId,
maintenanceItemId:projectId.value,
item: form.value.title,
problem: form.value.desc,
residentId:userId,//人员id
// repairTypeName: repairProject.value,
phone: form.value.phone,
problemImageUrl: imageUrls.join(','),
projectType: '0',
problemStatus:''
}
const res = await addQueryRepair(params)
if (res.code === 200) {
uni.hideLoading();
uni.showToast({ title: '提交成功', icon: 'success' })
// const tempProjectId = projectId.value
form.value = { title: '', desc: '', phone: '', images: [] }
repairProject.value = ''
// uni.navigateBack({ delta: 2 })
setTimeout(() => {
uni.navigateTo({ url: '/pageSubPack/online-repair/onlineRepair' })
}, 1500)
} else {
submitting.value = false
uni.showToast({ title: res.msg || '提交失败', icon: 'none' })
}
} catch (e) {
submitting.value = false
uni.showToast({ title: '网络异常', icon: 'none' })
} finally {
uni.hideLoading()
}
}
</script>
<style scoped>
.form-container {
padding: 15px;
background: #fff;
min-height: 100vh;
}
.form-item-wenti {
margin-bottom: 20px;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
.form-item {
display: flex;
margin-bottom: 30rpx;
align-items: flex-start;
border-bottom: 1px solid #eee;
}
.label {
width: 140rpx;
font-size: 28rpx;
color: #333;
line-height: 80rpx;
}
.value {
flex: 1;
font-size: 28rpx;
color: #666;
line-height: 80rpx;
text-align: right;
display: flex;
justify-content: space-between;
}
.input, .textarea {
font-size: 14px;
width: 100%;
padding: 8px 0;
box-sizing: border-box;
}
.textarea {
resize: none;
}
.textarea-wrap {
flex: 1;
position: relative;
}
.desc-textarea {
width: 100%;
height: 160rpx;
font-size: 28rpx;
padding: 10rpx 0;
box-sizing: border-box;
border: 1px solid #eee;
border-radius: 4px;
padding: 5px;
}
.char-count {
position: absolute;
right: 10rpx;
bottom: 10rpx;
font-size: 24rpx;
color: #999;
}
.upload-wrap {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 8px;
}
.upload-item {
position: relative;
width: 80px;
height: 80px;
}
.upload-item .upload-img{
width: 100%;
height: 100%;
border-radius: 4px;
}
.upload-item .upload-delete{
position: absolute;
top: -5px;
right: -5px;
width: 32rpx;
height: 32rpx;
border-radius: 3rpx;
padding: 2px;
}
.upload-btn {
width: 80px;
height: 80px;
/* border: 1px dashed #ccc; */
background-color: #f3f3f3;
border-radius: 4px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #999;
font-size: 12px;
}
/* 提交中遮罩 */
.submit-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 9999;
}
.submit-btn {
width: 100%;
background: #007aff;
color: #fff;
border-radius: 6px;
height: 44px;
line-height: 44px;
font-size: 16px;
}
</style>