Files
taimed-international-app/pages/user/feedback/index.vue

360 lines
7.8 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="feedback-page">
<!-- 自定义导航栏 -->
<nav-bar :title="$t('user.feedback')"></nav-bar>
<view class="feedback-content">
<view class="feedback-form">
<!-- 问题类型 -->
<view class="form-item">
<text class="label required">{{ $t('user.issueType') }}</text>
<wd-select-picker
v-model="form.type"
type="radio"
style="border-bottom: 1px solid #ddd;"
:columns="issueTypeOptions"
:placeholder="$t('common.pleaseSelect')"
:show-confirm="false"
/>
</view>
<!-- 账号 -->
<view class="form-item">
<text class="label required">{{ $t('user.account') }}</text>
<wd-input
v-model="form.account"
:placeholder="$t('user.account')"
/>
</view>
<!-- 订单编号条件显示 -->
<view v-if="form.type === '3'" class="form-item">
<text class="label required">{{ $t('user.orderSn') }}</text>
<wd-input
v-model="form.relation"
type="number"
:placeholder="$t('user.pleaseInputOrderSn')"
@input="handleRelationInput"
/>
</view>
<!-- 问题描述 -->
<view class="form-item">
<text class="label required">{{ $t('user.description') }}</text>
<wd-textarea
v-model="form.content"
auto-height
:placeholder="$t('user.pleaseInputDescription')"
:maxlength="200"
show-word-limit
/>
</view>
<!-- 联系电话 -->
<view class="form-item">
<text class="label required">{{ $t('user.contactPhone') }}</text>
<wd-input
v-model="form.contactInformation"
type="number"
:placeholder="$t('user.pleaseInputPhone')"
/>
</view>
<!-- 截图上传 -->
<view class="form-item">
<text class="label">{{ $t('user.screenshots') }}</text>
<wd-upload
:fileList="imageList"
:limit="4"
action="https://global.nuttyreading.com/oss/fileoss"
@change="handleChangeImage"
/>
<text class="tip-text">{{ $t('user.maxImagesCount') }}</text>
</view>
<!-- 提交按钮 -->
<view class="submit-button">
<wd-button
type="success"
block
@click="handleSubmit"
>
{{ $t('common.submit') }}
</wd-button>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useUserStore } from '@/stores/user'
import { submitFeedback } from '@/api/modules/user'
import type { IFeedbackForm } from '@/types/user'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const userStore = useUserStore()
// 问题类型选项
const issueTypeOptions = computed(() => [
{ label: t('user.issueTypeAccount'), value: '1' },
{ label: t('user.issueTypePayment'), value: '2' },
{ label: t('user.issueTypeOrder'), value: '3' },
{ label: t('user.issueTypeContent'), value: '4' },
{ label: t('user.issueTypeSuggestion'), value: '5' },
{ label: t('user.issueTypeBug'), value: '6' },
{ label: t('user.issueTypeOther'), value: '7' }
])
// 表单数据
const form = ref<IFeedbackForm>({
type: '',
account: userStore.userInfo.email || userStore.userInfo.phone || '',
relation: '',
content: '',
contactInformation: '',
image: ''
})
// 图片列表
const imageList = ref<any[]>([])
// 错误状态
const relationError = ref(false)
/**
* 处理订单编号输入
*/
const handleRelationInput = () => {
relationError.value = false
}
/**
* 上传前检查
*/
const beforeUpload = async (file: any) => {
// TODO: 检查相机和存储权限
// 检查文件大小
if (file.size > 5 * 1024 * 1024) {
uni.showToast({
title: '图片大小不能超过5MB',
icon: 'none'
})
return false
}
return true
}
/**
* 上传文件变化
*/
const imageUrl = ref<any[]>([])
const handleChangeImage = ({ fileList }: any) => {
console.log('上传文件变化:', fileList)
imageUrl.value = []
fileList.forEach((file:any) => {
imageUrl.value.push(JSON.parse(file.response).url)
})
console.log('图片列表:', imageUrl.value)
// this.fileList = fileList
}
/**
* 表单验证
*/
const validateForm = (): boolean => {
// 验证问题类型
if (!form.value.type) {
uni.showToast({
title: t('common.pleaseSelect') + t('user.issueType'),
icon: 'none'
})
return false
}
// 验证账号
if (!form.value.account) {
uni.showToast({
title: t('user.pleaseInput') + t('user.account'),
icon: 'none'
})
return false
}
// 验证订单编号(当类型为订单相关时)
if (form.value.type === '3') {
if (!form.value.relation) {
relationError.value = true
uni.showToast({
title: t('user.pleaseInputOrderSn'),
icon: 'none'
})
return false
}
}
// 验证问题描述
if (!form.value.content) {
uni.showToast({
title: t('user.pleaseInputDescription'),
icon: 'none'
})
return false
}
// 验证联系电话
if (!form.value.contactInformation) {
uni.showToast({
title: t('user.pleaseInputPhone'),
icon: 'none'
})
return false
}
return true
}
/**
* 提交反馈
*/
const handleSubmit = async () => {
// 表单验证
if (!validateForm()) {
return
}
try {
// 处理图片
if (imageUrl.value.length > 0) {
form.value.image = imageUrl.value.join(',')
}
// 提交反馈
await submitFeedback(form.value)
uni.showModal({
title: t('global.tips'),
content: t('user.feedbackSuccess'),
showCancel: false,
confirmText: t('common.confirm'),
success: () => {
// 清空表单
imageList.value = []
imageUrl.value = []
form.value = {
type: '',
account: userStore.userInfo.email || userStore.userInfo.phone || '',
relation: '',
content: '',
contactInformation: '',
image: ''
}
// 返回上一页
uni.navigateBack({
delta: 1
})
}
})
} catch (error) {
console.error('提交反馈失败:', error)
uni.showToast({
title: t('user.feedbackFailed'),
icon: 'none'
})
}
}
</script>
<style lang="scss" scoped>
$theme-color: #54a966;
.feedback-page {
min-height: 100vh;
background-color: #f7faf9;
}
.custom-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
background-color: #fff;
border-bottom: 1rpx solid #e5e5e5;
.navbar-content {
display: flex;
align-items: center;
justify-content: center;
height: 44px;
position: relative;
.navbar-left {
position: absolute;
left: 10px;
display: flex;
align-items: center;
padding: 10rpx;
}
.navbar-title {
font-size: 16px;
font-weight: 700;
color: #333;
}
}
}
.feedback-content {
padding: 20rpx;
}
.feedback-form {
background: #fff;
border-radius: 15rpx;
padding: 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.form-item {
margin-bottom: 30rpx;
.label {
display: block;
font-size: 30rpx;
color: #333;
font-weight: bold;
margin-bottom: 15rpx;
&.required::before {
content: '*';
color: red;
margin-right: 5rpx;
}
}
.error-text {
display: block;
font-size: 24rpx;
color: red;
margin-top: 10rpx;
}
.tip-text {
display: block;
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
}
.submit-button {
margin-top: 50rpx;
}
</style>