Files

372 lines
8.5 KiB
Vue
Raw Permalink 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">
<view class="label">
<text class="required">*</text>维修项目
</view>
<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="label">
<text class="required">*</text>问题描述
</view>
<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>
<!-- <uni-easyinput
v-model="form.desc"
placeholder="请描述你的问题"
type="textarea"
></uni-easyinput> -->
</view>
<!-- 手机号 -->
<view class="form-item">
<view class="label">
<text class="required">*</text>手机号
</view>
<uni-easyinput
type="number"
v-model="form.phone"
placeholder="请输入手机号"
:inputBorder="false"
maxlength="11"
></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 < 9">
<uni-icons type="plusempty" size="24"></uni-icons>
<!-- <text>上传照片</text> -->
</view>
</view>
</view>
<!-- 提交按钮 -->
<button class="submit-btn" @click="submitForm">提交</button>
<!-- 提交时遮罩,禁止页面点击 -->
<view class="submit-mask" v-if="submitting"></view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad,onShow ,onUnload} from '@dcloudio/uni-app'
import {addRepairList,uploadFile} from '../../api/api.js'
// 接收上个页面传的维修项目
const repairProject = ref('')
const repairId = ref('')
// 表单数据
const form = ref({
title: '',
desc: '',
phone: '',
images: [] // 图片列表
})
// 防止重复点击
const submitting = ref(false)
// ==========方法========
// 页面加载
onLoad((options) => {
// 第一次进入页面接收参数
if (options.category && options.project) {
repairProject.value = `${options.category}-${options.project}`
repairId.value = options.projectId
}
// 监听返回选择的项目
uni.$on('selectRepairProject', (data) => {
repairProject.value = `${data.category}-${data.project}`
repairId.value = data.projectId
})
})
// 页面卸载时移除监听
onUnload(() => {
uni.$off('selectRepairProject')
})
// 选择项目页
const goBackSelect = () => {
uni.navigateTo({
url: '/pageSubPack/fault-reporting/repairSelect'
})
}
// 选择图片
const chooseImage = () => {
// 计算还能选几张
const remainCount = 9 - form.value.images.length
if (remainCount <= 0) {
uni.showToast({
title: '最多只能上传9张图片',
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 uploadImages = async () => {
const uploadedUrls = []
for (const path of form.value.images) {
if (path.startsWith('http')) {
uploadedUrls.push(path)
continue
}
try {
// 从路径中提取文件名
const fileName = path.substring(path.lastIndexOf('/') + 1)
const res = await uploadFile(path, fileName)
uploadedUrls.push(res?.url || '')
} catch (err) {
uni.showToast({
title: err.msg || '图片上传失败',
icon: 'error'
})
}
}
return uploadedUrls
}
// 删除图片
const deleteImage = index => {
form.value.images.splice(index, 1)
}
// 表单提交
const submitForm = async () => {
// 防止重复提交
if (submitting.value) return
// 表单校验
if (!repairProject.value) {
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
}
// 提交数据
submitting.value = true
uni.showLoading({ title: '提交中...' ,mask:true})
try {
// 先上传图片
const imageUrls = await uploadImages()
const params = {
maintenanceItemId:repairId.value,
item: form.value.title,
problem: form.value.desc,
phone: form.value.phone,
problemImageUrl: imageUrls.join(','),
// projectType: '0',
problemStatus:'0'
}
const res = await addRepairList(params)
if (res.code === 200) {
uni.showToast({ title: '提交成功', icon: 'success' })
form.value = { title: '', desc: '', phone: '', images: [] }
repairProject.value = ''
// uni.navigateBack({ delta: 2 })
setTimeout(() => {
uni.switchTab({ url: '/pages/index/index' })
}, 1500)
} else {
uni.showToast({ title: res.msg || '提交失败', icon: 'none' })
}
} catch (e) {
uni.showToast({ title: e.msg || '网络异常', icon: 'none' })
} finally {
submitting.value = false
uni.hideLoading()
}
}
</script>
<style scoped>
.form-container {
padding: 30rpx 40rpx;
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: 180rpx;
font-size: 28rpx;
color: #333;
line-height: 80rpx;
}
.required {
color: red;
margin-right: 4rpx;
}
.value {
flex: 1;
font-size: 28rpx;
color: #666;
line-height: 80rpx;
text-align: right;
display: flex;
justify-content: space-between;
}
.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;
}
.input,
.textarea {
font-size: 14px;
width: 100%;
padding: 8px 0;
box-sizing: border-box;
}
.textarea {
resize: none;
}
.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;
/* background: #ff3b30; */
/* color: #fff; */
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-btn {
width: 100%;
background: #4d5dfa;
color: #fff;
border-radius: 6px;
height: 44px;
line-height: 44px;
font-size: 16px;
}
.submit-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
}
</style>