zhwl-miniapp/pages/my/complaintForm.vue
2025-06-26 12:38:35 +08:00

508 lines
13 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="container">
<view class="form-box">
<view class="tips">
此投诉为本小程序自有投诉渠道非微信官方投诉渠道我们会在第一时间为您处理您可以在我的投诉中查看处理进度
</view>
<view class="item-box" v-if="configData">
<view class="label"><text class="asterisk">*</text>投诉景区</view>
<view class="code-box">
<view class="uni-list-cell-db">
<picker class="picker" disabled :value="scenicIndex" :range="scenicRange">
<view class="uni-input">{{configData.scenic.scenicName}}</view>
</picker>
</view>
</view>
</view>
<view class="item-box">
<view class="label"><text class="asterisk">*</text>投诉类型</view>
<view class="code-box">
<view class="uni-list-cell-db">
<picker class="picker" @change="bindPickerChange" :value="typeIndex" :range="typeRange">
<view class="uni-input" v-if="comData.type">{{typeRange[typeIndex]}}</view>
<view class="input-placeholder" v-if="!comData.type">请选择投诉类型</view>
<uni-icons class="icon" type="right"></uni-icons>
</picker>
</view>
</view>
</view>
<view class="item-box">
<view class="label"><text class="asterisk">*</text>投诉内容</view>
<view class="textarea-box">
<u--textarea v-model="comData.content" placeholder="请详细填写内容,以便我们提供更好的帮助" count maxlength="500" ></u--textarea>
</view>
</view>
<view class="item-box">
<view class="label">
上传照片
<text class="text">不超过5张</text>
</view>
<view class="upload-box">
<u-upload
:fileList="fileList"
@afterRead="afterRead"
@delete="deletePic"
name="1"
multiple
:maxCount="5"
:previewFullImage="true"
@on-list-change="onListChange($event)"
>
<view class="sh-box">
<image class="sh-img" src="https://common/upload-icon.png"></image>
</view>
</u-upload>
</view>
</view>
</view>
<view class="list-box">
<view class="list-item">
<view class="label"><text class="asterisk">*</text>联系人</view>
<input type="text" v-model="comData.linkperson" class="weui-input" placeholder-class="input-placeholder" placeholder="请输入姓名" />
</view>
<view class="list-item">
<view class="label"><text class="asterisk">*</text>联系手机</view>
<input type="number" v-model="comData.linktel" class="weui-input" placeholder-class="input-placeholder" placeholder="请输入手机号" />
</view>
</view>
<view class="btn" @click="submit">提交</view>
<uni-popup class="popupRefund" ref="popup" background-color="#fff">
<view class="popup-content">
<image class="bgImg" src="https://common/refundPopup.png" mode=""></image>
<view class="con">
<view class="title">温馨提示</view>
<view class="text">确认提交吗?</view>
<view class="btn-box">
<view class="close" @click="close">我再想想</view>
<view class="save" @click="onRefund">确认</view>
</view>
</view>
</view>
</uni-popup>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import _config from '../../common/http/config.js'
export default {
data() {
return {
paddingTop: 0,
bottomHight: 0,
styles: {},
bgColor: '#FFF',
menuIndex: '0',
scenicList: [],
scenicRange: [],
scenicIndex: 0,
typeList: [],
typeRange: [],
typeIndex: 0,
comData: {
scenicId: '',
type: '',
content: '',
image: '',
linkperson: '',
linktel: ''
},
fileList: [],
configData: null
};
},
mounted() {
this.configData = uni.getStorageSync('configData');
this.comData.scenicId = this.$scenicId;
this.common()
this.paddingTop = uni.upx2px(88);
let app = uni.getSystemInfoSync();
this.bottomHight = app.safeAreaInsets.bottom //屏幕底部安全距离
console.log('屏幕底部安全距离', this.bottomHight) //34
},
methods: {
tabMenu (index) {
this.menuIndex = index;
},
async common() {
const params = {
dictType: 'report_type'
}
let info = await this.$http.common(params)
if (info.code === 200) {
this.typeList = info.data
this.typeList.forEach((e) => {
this.typeRange.push(e.dictLabel)
})
} else {
uni.$u.toast(info.msg);
}
},
bindPickerChange(e) {
this.typeIndex = e.detail.value
this.comData.type = this.typeList[this.typeIndex].dictValue
},
// 删除图片
deletePic(event) {
this.fileList.splice(event.index, 1)
},
// 新增图片
async afterRead(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this.fileList.length
lists.map((item) => {
this.fileList.push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url)
let item = this.fileList[fileListLen]
this.fileList.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: JSON.parse(result).fileName
}))
fileListLen++
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: _config.url + '/app/common/upload', // 仅为示例,非真实的接口地址
filePath: url,
header: { token: uni.getStorageSync("ztc_token") },
name: 'file',
formData: {
user: 'test'
},
success: (res) => {
setTimeout(() => {
resolve(res.data)
}, 1000)
}
});
})
},
submit() {
let commonReg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/
if (!this.comData.type) {
this.$refs.uToast.show({
type: 'error',
message: '请选择投诉类型',
icon: false,
duration: 2000
})
return
}
if (!this.comData.content) {
this.$refs.uToast.show({
type: 'error',
message: '请输入投诉内容',
icon: false,
duration: 2000
})
return
}
if (!this.comData.linkperson) {
this.$refs.uToast.show({
type: 'error',
message: '请输入姓名',
icon: false,
duration: 2000
})
return
}
if (this.comData.linktel) {
if (!commonReg.test(this.comData.linktel)) {
this.$refs.uToast.show({
type: 'error',
message: '请输入正确的手机号码',
icon: false,
duration: 2000
})
return
}
} else if (!this.comData.linktel) {
this.$refs.uToast.show({
type: 'error',
message: '请输入手机号码',
icon: false,
duration: 2000
})
return
}
this.$refs.popup.open('center')
},
close() {
this.$refs.popup.close()
},
async onRefund() {
if (this.fileList.length) {
let image = []
this.fileList.forEach((e) => {
image.push(e.url)
})
this.comData.image = image.join(',')
}
const params = this.comData
let info = await this.$http.addReport(params)
if (info.code === 200) {
uni.showToast({
title: '提交成功',
mask: true
})
setTimeout(() => {
uni.navigateBack()
}, 500)
} else {
uni.$u.toast(info.msg);
}
}
}
}
</script>
<style lang="scss" scoped>
.container {
padding-bottom: 50rpx;
.form-box {
background: #FFFFFF;
border-radius: 10rpx;
padding: 30rpx 27rpx;
margin: 110rpx 32rpx 24rpx;
.tips {
background: rgba(250,170,44,0.1);
border-radius: 10rpx;
padding: 24rpx 22rpx;
font-weight: 500;
font-size: 28rpx;
color: #FAAA2C;
line-height: 33rpx;
margin-bottom: 17rpx;
}
.item-box {
border-bottom: 1rpx solid #E8E8E8;
&:last-child {
border-bottom: none;
}
.label {
font-weight: bold;
font-size: 32rpx;
color: #333333;
margin-top: 24rpx;
.asterisk {
color: #dd524d;
font-weight: 700;
}
}
.code-box {
flex: 1;
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
margin: 40rpx 0 30rpx;
.uni-list-cell-db {
width: 100%;
.picker {
width: 100%;
position: relative;
.uni-input {
flex: 1;
display: inline-block;
}
.input-placeholder {
flex: 1;
display: inline-block;
}
.icon {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
/deep/.uniui-right {
font-size: 34rpx !important;
color: #999999 !important;
}
}
}
}
}
/deep/.input-placeholder {
font-weight: 400;
font-size: 28rpx;
color: #999999!important;
}
.uni-input {
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.textarea-box {
margin: 24rpx 0 40rpx;
/deep/.u-textarea {
background: #F7F8FA;
border-radius: 10rpx;
padding: 30rpx 26rpx;
.input-placeholder {
font-weight: 500;
font-size: 28rpx;
color: #999999;
}
.u-textarea__field {
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.u-textarea__count {
background-color: #F7F8FA !important;
}
}
}
.upload-box {
margin-bottom: 24rpx;
/deep/.u-upload__wrap {
.u-upload__wrap__preview {
margin: 23rpx 58rpx 0 0;
&:nth-child(3n) {
margin-right: 0;
}
.u-upload__wrap__preview__image {
width: 172rpx !important;
height: 172rpx !important;
border-radius: 10rpx;
}
}
}
.sh-box {
width: 172rpx;
height: 172rpx;
border-radius: 10rpx;
margin: 23rpx 0 0 0;
background-color: #DEF4F0;
position: relative;
.sh-img {
width: 52rpx;
height: 44rpx;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
}
}
}
.list-box {
background: #FFFFFF;
border-radius: 10rpx;
margin: 0 32rpx;
padding: 0 32rpx;
.list-item {
display: flex;
align-items: center;
flex-direction: row;
height: 99rpx;
border-bottom: 1rpx solid #E8E8E8;
&:last-child {
border: none;
}
.label {
width: 157rpx;
font-weight: bold;
font-size: 28rpx;
color: #333333;
.asterisk {
color: #dd524d;
font-weight: 700;
}
}
/deep/.weui-input {
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
/deep/.input-placeholder {
font-weight: 400;
font-size: 28rpx;
color: #999999!important;
}
}
}
.btn {
width: 630rpx;
height: 90rpx;
background: #01BE69;
border-radius: 61rpx;
line-height: 90rpx;
text-align: center;
font-weight: 800;
font-size: 32rpx;
color: #FFFFFF;
margin: 68rpx auto 0;
}
.popupRefund {
.popup-content {
position: relative;
.bgImg {
width: 595rpx;
height: 397rpx;
}
.con {
position: absolute;
width: 510rpx;
top: 64rpx;
left: 50%;
transform: translateX(-50%);
.title {
font-weight: 800;
font-size: 40rpx;
color: #000000;
text-align: center;
}
.text {
margin-top: 32rpx;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 44rpx;
text-align: center;
}
.btn-box {
margin-top: 90rpx;
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-around;
.close {
width: 236rpx;
height: 77rpx;
border-radius: 10rpx;
border: 1rpx solid #666666;
line-height: 77rpx;
text-align: center;
font-weight: 400;
font-size: 30rpx;
color: #666666;
}
.save {
width: 240rpx;
height: 80rpx;
background: #01BE69;
border-radius: 10rpx;
line-height: 80rpx;
text-align: center;
font-weight: 500;
font-size: 30rpx;
color: #FFFFFF;
}
}
}
}
}
}
</style>