展品维保小程序前端代码接口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

646 lines
17 KiB

<template>
<view class="repair-submit">
<!-- 导航栏 -->
<!-- <uv-navbar title="报修提交" :border="false" bg-color="#ffffff" title-color="#333333" /> -->
<!-- 报修基本信息 -->
<view class="repair-info">
<view class="info-header">
<view class="red-line"></view>
<text class="info-title">报修基本信息</text>
</view>
<!-- 报修日期 -->
<view class="form-item">
<text class="label">报修日期</text>
<text class="value">{{ repairDate }}</text>
</view>
<!-- 故障紧急程度 -->
<view class="form-item " @click="showUrgencyPicker">
<text class="label">故障紧急程度</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !urgencyLevel }">{{ urgencyLevel || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 故障情况 -->
<view class="form-item form-item-header">
<text class="label active">故障情况</text>
</view>
<!-- 故障情况选择 -->
<view class="form-item" @click="showFaultPicker">
<text class="label">故障情况</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !faultSituation }">{{ faultSituation || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 故障情况描述 -->
<view class="form-item">
<text class="label">故障情况描述</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="faultDescription"
placeholder="请对故障情况进行描述"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 故障图片 -->
<view class="form-item">
<text class="label">故障图片</text>
</view>
<view class="image-upload">
<view v-for="(img, index) in imageList" :key="index" class="image-item">
<image :src="img" mode="aspectFill" @click="previewImage(img)"></image>
<view class="delete-btn" @click="deleteImage(index)">
<uv-icon name="close" size="12" color="#fff"></uv-icon>
</view>
</view>
<view class="upload-btn" @click="uploadImage">
<uv-icon name="camera" size="34" color="#C70019"></uv-icon>
</view>
</view>
<!-- 故障首次发生时间 -->
<view class="form-item" @click="showTimePicker">
<text class="label">故障首次发生时间</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !firstOccurTime }">{{ firstOccurTime || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 发生频率 -->
<view class="form-item">
<text class="label">发生频率</text>
<view class="radio-options">
<view
v-for="(item, index) in frequencyOptions"
:key="index"
class="radio-item"
:class="{ active: frequency === item.value }"
@click="selectFrequency(item.value)"
>
<view class="radio-dot" :class="{ active: frequency === item.value }"></view>
<text :class="{ active: frequency === item.value }">{{ item.label }}</text>
</view>
</view>
</view>
<!-- 请描述与故障设备发生主要故障的具体条件 -->
<!-- <view class="form-item">
<text class="label">请描述与故障设备发生主要故障的具体条件</text>
</view> -->
<view class="textarea-container">
<uv-textarea
v-model="faultCondition"
placeholder="请填写说明故障发生频率的触发条件"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 是否影响使用 -->
<view class="form-item" @click="showImpactPicker">
<text class="label">是否影响使用</text>
<view class="select-area">
<text class="value" :class="{ placeholder: !impactUsage }">{{ impactUsage || '请选择' }}</text>
<uv-icon name="arrow-down" size="18" color="#000"></uv-icon>
</view>
</view>
<!-- 采取的临时措施 -->
<!-- 故障情况 -->
<view class="form-item form-item-header">
<text class="label active">采取的临时措施</text>
</view>
<!-- <view class="form-item">
<text class="label">是否采取临时措施</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="temporaryMeasures"
placeholder="如有采取临时措施请填写措施说明"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view> -->
<!-- 是否采取的对措施 -->
<view class="form-item">
<text class="label">是否采取的对措施</text>
<view class="radio-options">
<view
class="radio-item"
:class="{ active: hasTakenMeasures === true }"
@click="selectMeasures(true)"
>
<view class="radio-dot" :class="{ active: hasTakenMeasures === true }"></view>
<text :class="{ active: hasTakenMeasures === true }">是</text>
</view>
<view
class="radio-item"
:class="{ active: hasTakenMeasures === false }"
@click="selectMeasures(false)"
>
<view class="radio-dot" :class="{ active: hasTakenMeasures === false }"></view>
<text :class="{ active: hasTakenMeasures === false }">否</text>
</view>
</view>
</view>
<view class="textarea-container">
<uv-textarea
v-model="temporaryMeasures"
placeholder="如有采取临时措施请填写措施说明"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
<!-- 是否影响体验 -->
<view class="form-item">
<text class="label">是否影响体验</text>
<view class="radio-options">
<view
class="radio-item"
:class="{ active: impactExperience === true }"
@click="selectExperience(true)"
>
<view class="radio-dot" :class="{ active: impactExperience === true }"></view>
<text :class="{ active: impactExperience === true }">是</text>
</view>
<view
class="radio-item"
:class="{ active: impactExperience === false }"
@click="selectExperience(false)"
>
<view class="radio-dot" :class="{ active: impactExperience === false }"></view>
<text :class="{ active: impactExperience === false }">否</text>
</view>
</view>
</view>
<!-- 备注 -->
<view class="form-item">
<text class="label">备注</text>
</view>
<view class="textarea-container">
<uv-textarea
v-model="remark"
placeholder="备注"
:maxlength="200"
:show-confirm-bar="false"
height="60"
border="none"
:custom-style="{ backgroundColor: '#f5f5f5' }"
></uv-textarea>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-container">
<uv-button
type="primary"
text="立即提交"
:custom-style="{ backgroundColor: '#C70019', borderRadius: '25px' }"
@click="submitRepair"
></uv-button>
</view>
<!-- 选择器 -->
<uv-picker
confirm-color="#C70019"
ref="urgencyPicker"
:columns="urgencyColumns"
@confirm="confirmUrgency"
@cancel="cancelUrgency"
></uv-picker>
<uv-picker
confirm-color="#C70019"
ref="faultPicker"
:columns="faultColumns"
@confirm="confirmFault"
@cancel="cancelFault"
></uv-picker>
<uv-picker
confirm-color="#C70019"
ref="timePicker"
:columns="timeColumns"
@confirm="confirmTime"
@cancel="cancelTime"
></uv-picker>
<uv-picker
confirm-color="#C70019"
ref="impactPicker"
:columns="impactColumns"
@confirm="confirmImpact"
@cancel="cancelImpact"
></uv-picker>
</view>
</template>
<script>
export default {
data() {
return {
// 表单数据
repairDate: '2025/03/31',
urgencyLevel: '',
faultSituation: '',
faultDescription: '',
imageList: [],
firstOccurTime: '',
frequency: '',
faultCondition: '',
impactUsage: '',
temporaryMeasures: '',
hasTakenMeasures: null,
impactExperience: null,
remark: '',
// 选择器显示状态(保留用于其他可能的用途)
// showUrgency: false,
// showFault: false,
// showTime: false,
// showImpact: false,
// 频率选项
frequencyOptions: [
{ label: '持续性问题', value: 'continuous' },
{ label: '间歇性问题', value: 'intermittent' }
],
// 选择器数据
urgencyColumns: [['一般', '紧急', '非常紧急']],
faultColumns: [['硬件故障', '软件故障', '网络故障', '其他']],
timeColumns: [['今天', '昨天', '一周内', '一个月内', '更早']],
impactColumns: [['是', '否']]
}
},
methods: {
// 显示紧急程度选择器
showUrgencyPicker() {
this.$refs.urgencyPicker.open()
},
// 确认紧急程度
confirmUrgency(e) {
this.urgencyLevel = e.value[0]
},
// 取消紧急程度选择
cancelUrgency() {
// 取消操作
},
// 显示故障情况选择器
showFaultPicker() {
this.$refs.faultPicker.open()
},
// 确认故障情况
confirmFault(e) {
this.faultSituation = e.value[0]
},
// 取消故障情况选择
cancelFault() {
// 取消操作
},
// 显示时间选择器
showTimePicker() {
this.$refs.timePicker.open()
},
// 确认时间
confirmTime(e) {
this.firstOccurTime = e.value[0]
},
// 取消时间选择
cancelTime() {
// 取消操作
},
// 显示影响使用选择器
showImpactPicker() {
this.$refs.impactPicker.open()
},
// 确认影响使用
confirmImpact(e) {
this.impactUsage = e.value[0]
},
// 取消影响使用选择
cancelImpact() {
// 取消操作
},
// 选择频率
selectFrequency(value) {
this.frequency = value
},
// 选择是否采取措施
selectMeasures(value) {
this.hasTakenMeasures = value
},
// 选择是否影响体验
selectExperience(value) {
this.impactExperience = value
},
// 上传图片
async uploadImage() {
try {
const result = await this.$utils.chooseAndUpload()
if (result && result.success) {
console.log(result);
this.imageList.push(result.url)
}
} catch (error) {
console.error('头像上传失败:', error)
uni.showToast({
title: '头像上传失败',
icon: 'error'
})
}
},
// 删除图片
deleteImage(index) {
this.imageList.splice(index, 1)
},
// 预览图片
previewImage(url) {
uni.previewImage({
urls: this.imageList,
current: url
})
},
// 提交报修
submitRepair() {
// 表单验证
if (!this.urgencyLevel) {
uni.showToast({ title: '请选择故障紧急程度', icon: 'none' })
return
}
if (!this.faultSituation) {
uni.showToast({ title: '请选择故障情况', icon: 'none' })
return
}
if (!this.faultDescription.trim()) {
uni.showToast({ title: '请填写故障情况描述', icon: 'none' })
return
}
// 提交数据
const formData = {
repairDate: this.repairDate,
urgencyLevel: this.urgencyLevel,
faultSituation: this.faultSituation,
faultDescription: this.faultDescription,
imageList: this.imageList,
firstOccurTime: this.firstOccurTime,
frequency: this.frequency,
faultCondition: this.faultCondition,
impactUsage: this.impactUsage,
temporaryMeasures: this.temporaryMeasures,
hasTakenMeasures: this.hasTakenMeasures,
impactExperience: this.impactExperience,
remark: this.remark
}
console.log('提交数据:', formData)
uni.showToast({ title: '提交成功', icon: 'success' })
// 返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
}
}
</script>
<style lang="scss" scoped>
.repair-submit {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 200rpx;
}
.repair-info {
margin: 18rpx;
background: #ffffff;
border-radius: 15rpx;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
padding: 40rpx;
.info-header {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.red-line {
width: 9rpx;
height: 33rpx;
background-color: $primary-color;
margin-right: 7rpx;
border-radius: 5rpx;
}
.info-title {
font-size: 30rpx;
font-weight: bold;
color: $primary-text-color;
}
}
.form-item-header {
border-bottom: none;
margin-top: 20rpx;
}
.form-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
border-bottom: 2rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 30rpx;
color: $primary-text-color;
flex-shrink: 0;
&.active {
font-weight: bold;
}
}
.value {
font-size: 30rpx;
color: $secondary-text-color;
&.placeholder {
color: $secondary-text-color;
}
}
.select-area {
display: flex;
align-items: center;
gap: 16rpx;
}
}
.textarea-container {
// margin: 16rpx 0 32rpx 0;
// background-color: #f5f5f5;
border-radius: 8rpx;
// padding: 16rpx;
}
.image-upload {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
margin: 16rpx 0;
.upload-btn {
width: 160rpx;
height: 160rpx;
border: 2rpx dashed $primary-color;
// border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}
.image-item {
position: relative;
width: 160rpx;
height: 160rpx;
image {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.delete-btn {
position: absolute;
top: -12rpx;
right: -12rpx;
width: 40rpx;
height: 40rpx;
background-color: #ff4757;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.hint-text {
font-size: 24rpx;
color: #999;
margin-top: 16rpx;
}
.form-item .radio-options {
display: flex;
gap: 60rpx;
.radio-item {
display: flex;
align-items: center;
gap: 16rpx;
.radio-dot {
width: 32rpx;
height: 32rpx;
border: 4rpx solid #ddd;
border-radius: 50%;
position: relative;
&.active {
border-color: $primary-color;
color: $primary-color;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
background-color: $primary-color;
border-radius: 50%;
}
}
}
text {
font-size: 30rpx;
color: $secondary-text-color;
&.active {
color: $primary-color;
}
}
}
}
}
.submit-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 32rpx;
background-color: #fff;
border-top: 2rpx solid #f0f0f0;
}
</style>