| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <template>
- <view class="complaint-root">
- <!-- 1. 自定义导航栏 -->
- <view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
- <view class="nav-content">
- <view class="back-area" @click="goBack">
- <view class="back-arrow"></view>
- </view>
- <view class="nav-title">投诉与建议</view>
- <view class="right-placeholder"></view>
- </view>
- </view>
- <view class="scroll-container">
- <scroll-view scroll-y class="scroll-content" :show-scrollbar="false">
- <view class="form-body">
- <!-- 2. 类型选择 -->
- <view class="section-card">
- <view class="section-title">反馈类型</view>
- <view class="type-grid">
- <view
- class="type-item"
- v-for="item in types"
- :key="item.value"
- :class="{active: formData.type === item.value}"
- @click="formData.type = item.value">
- <text>{{item.label}}</text>
- </view>
- </view>
- </view>
- <!-- 3. 问题描述 -->
- <view class="section-card">
- <view class="section-title">反馈内容</view>
- <textarea
- class="content-input"
- v-model="formData.content"
- placeholder="请详细描述您遇到的问题或改进建议..."
- maxlength="500"></textarea>
- <view class="word-count">{{formData.content.length}}/500</view>
- </view>
- <!-- 4. 图片上传 -->
- <view class="section-card">
- <view class="section-title">上传图片 (最多6张)</view>
- <view class="upload-grid">
- <view class="img-item" v-for="(img, index) in formData.images" :key="index">
- <image :src="img" mode="aspectFill" @click="previewImage(index)"></image>
- <view class="del-btn" @click.stop="removeImage(index)">
- <view class="close-icon">×</view>
- </view>
- </view>
- <view class="add-btn" v-if="formData.images.length < 6" @click="chooseImage">
- <text class="add-icon">+</text>
- <text class="add-txt">添加图片</text>
- </view>
- </view>
- </view>
- </view>
-
- <view class="bottom-placeholder"></view>
- </scroll-view>
- </view>
- <!-- 5. 底部提交按钮 -->
- <view class="footer-bar">
- <button class="submit-btn" :disabled="!isFormValid" @click="handleSubmit">提交反馈</button>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- statusBarHeight: 20,
- types: [
- { label: '系统投诉', value: 'complaint' },
- { label: '改进建议', value: 'suggestion' },
- { label: '其他反馈', value: 'other' }
- ],
- formData: {
- type: 'complaint',
- content: '',
- images: []
- }
- }
- },
- computed: {
- isFormValid() {
- return this.formData.content && this.formData.content.trim().length >= 5;
- }
- },
- onLoad() {
- try {
- const info = uni.getSystemInfoSync();
- this.statusBarHeight = info.statusBarHeight || 20;
- } catch (e) {
- this.statusBarHeight = 20;
- }
- },
- methods: {
- goBack() { uni.navigateBack(); },
- chooseImage() {
- const count = 6 - this.formData.images.length;
- uni.chooseImage({
- count: count,
- sizeType: ['compressed'],
- success: (res) => {
- this.formData.images = [...this.formData.images, ...res.tempFilePaths];
- }
- });
- },
- removeImage(index) {
- this.formData.images.splice(index, 1);
- },
- previewImage(index) {
- uni.previewImage({
- urls: this.formData.images,
- current: index
- });
- },
- handleSubmit() {
- uni.showLoading({ title: '提交中' });
- setTimeout(() => {
- uni.hideLoading();
- uni.showToast({ title: '反馈成功' });
- setTimeout(() => {
- uni.navigateBack();
- }, 1500);
- }, 1000);
- }
- }
- }
- </script>
- <style scoped>
- .complaint-root { width: 100vw; height: 100vh; background: #f8fafb; display: flex; flex-direction: column; overflow: hidden; }
-
- .custom-navbar { background: #fff; width: 100%; flex-shrink: 0; border-bottom: 1rpx solid #f0f0f0; }
- .nav-content { height: 44px; display: flex; align-items: center; justify-content: space-between; padding: 0 30rpx; }
- .back-area { width: 60rpx; height: 44px; display: flex; align-items: center; }
- .back-arrow { width: 22rpx; height: 22rpx; border-left: 4rpx solid #333; border-bottom: 4rpx solid #333; transform: rotate(45deg); margin-left: 10rpx; }
- .nav-title { font-size: 34rpx; font-weight: bold; color: #333; }
- .right-placeholder { width: 60rpx; }
- .scroll-container { flex: 1; height: 0; width: 100%; position: relative; }
- .scroll-content { width: 100%; height: 100%; }
- .form-body { padding: 30rpx; }
- .section-card { background: #fff; border-radius: 24rpx; padding: 40rpx 30rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.02); }
- .section-title { font-size: 30rpx; font-weight: bold; color: #1a1a1a; margin-bottom: 30rpx; border-left: 8rpx solid #C1001C; padding-left: 20rpx; line-height: 1.2; }
- .type-grid { display: flex; gap: 20rpx; }
- .type-item { flex: 1; height: 80rpx; background: #f5f6f8; border-radius: 12rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; color: #666; border: 2rpx solid #f5f6f8; transition: all 0.2s; }
- .type-item.active { background: rgba(193, 0, 28, 0.05); color: #C1001C; border-color: #C1001C; font-weight: bold; }
- .content-input { width: 100%; height: 300rpx; background: #f9fafb; border-radius: 16rpx; padding: 24rpx; box-sizing: border-box; font-size: 30rpx; color: #333; }
- .word-count { text-align: right; font-size: 24rpx; color: #ccc; margin-top: 12rpx; }
- .upload-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20rpx; }
- .img-item { position: relative; width: 100%; padding-top: 100%; }
- .img-item image { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 16rpx; }
- .del-btn { position: absolute; top: -10rpx; right: -10rpx; width: 40rpx; height: 40rpx; background: rgba(0,0,0,0.5); border-radius: 50%; display: flex; align-items: center; justify-content: center; z-index: 10; }
- .close-icon { color: #fff; font-size: 30rpx; line-height: 1; }
-
- .add-btn { width: 100%; padding-top: 100%; border: 2rpx dashed #ddd; border-radius: 16rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; background: #fcfcfc; }
- .add-icon { position: absolute; top: 35%; left: 50%; transform: translateX(-50%); font-size: 60rpx; color: #bbb; }
- .add-txt { position: absolute; bottom: 20%; left: 50%; transform: translateX(-50%); font-size: 22rpx; color: #999; }
- .footer-bar { background: #fff; padding: 30rpx 40rpx calc(30rpx + env(safe-area-inset-bottom)); flex-shrink: 0; border-top: 1rpx solid #f0f0f0; }
- .submit-btn { width: 100%; height: 96rpx; background: #C1001C; color: #fff; border-radius: 48rpx; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: bold; border: none; }
- .submit-btn[disabled] { background: #edb3bb !important; color: rgba(255,255,255,0.6) !important; }
- .bottom-placeholder { height: 40rpx; }
- </style>
|