index.vue 7.6 KB
<template>
  <view class="min-h-screen bg-white flex flex-col">
    <view class="flex-1 px-4 py-6 overflow-auto">
      <!-- Feedback Section -->
      <view class="mb-6">
        <view class="text-lg font-medium mb-2">您的反馈</view>
        <view class="bg-white rounded-lg border border-gray-200 p-4">
          <textarea
            v-model="feedbackText"
            class="w-full text-gray-600 focus:outline-none resize-none"
            placeholder="请描述您遇到的问题或建议..."
            :rows="4"
          />
        </view>
      </view>

      <!-- Upload Screenshot Section -->
      <view class="mb-6">
        <view class="text-lg font-medium mb-2">上传截图 (可选)</view>

        <!-- 已上传图片显示 -->
        <view class="flex flex-wrap gap-2 mb-4">
          <view
            v-for="(item, index) in screenshots"
            :key="index"
            class="relative"
          >
            <image
              :src="item.url"
              class="w-24 h-24 rounded-lg object-cover"
              mode="aspectFill"
              @tap="() => previewImage(index)"
            />
            <view
              @click="() => deleteImage(index)"
              class="absolute -top-2 -right-2 w-4 h-4 bg-red-500 rounded-full flex items-center justify-center"
            >
              <view class="text-white text-xs">×</view>
            </view>
          </view>
          <!-- 上传按钮 -->
          <view
            v-if="screenshots.length < maxImages"
            class="w-24 h-24 border border-dashed border-gray-300 rounded-lg flex flex-col items-center justify-center"
            @click="chooseImage"
          >
            <view class="text-gray-400 mb-2">
              <Photograph size="24" />
            </view>
            <view class="text-center text-gray-400 text-xs">添加图片</view>
          </view>
        </view>

        <!-- 提示信息 -->
        <view class="text-xs text-gray-500 mt-2">
          <view>• 图片大小不能超过10MB</view>
          <view>• 最多只能上传3张图片</view>
          <view>• 当前已上传 {{ screenshots.length }}/{{ maxImages }} 张</view>
        </view>
      </view>

      <!-- Name Section -->
      <view class="mb-6">
        <view class="text-lg font-medium mb-2">您的姓名</view>
        <view class="bg-white rounded-lg border border-gray-200 p-4">
          <input
            type="text"
            v-model="name"
            class="w-full text-gray-600 focus:outline-none"
            placeholder="请输入您的姓名"
            :cursorSpacing="100"
          />
        </view>
      </view>

      <!-- Contact Section -->
      <view class="mb-10">
        <view class="text-lg font-medium mb-2">联系方式</view>
        <view class="bg-white rounded-lg border border-gray-200 p-4">
          <input
            type="text"
            v-model="contact"
            class="w-full text-gray-600 focus:outline-none"
            placeholder="请输入您的手机号或微信号"
            :cursorSpacing="100"
          />
        </view>
      </view>

      <!-- Submit Button -->
      <view
        @click="submitFeedback"
        class="w-full py-3 bg-blue-500 text-white text-lg font-medium rounded-lg flex items-center justify-center"
      >
        提交反馈
      </view>
    </view>

    <!-- Image Preview -->
    <nut-image-preview
      v-model:show="previewVisible"
      :images="previewImages"
      :init-no="0"
      @close="closePreview"
    />
  </view>
</template>

<script setup>
import { ref } from 'vue';
import Taro from '@tarojs/taro';
import { Photograph } from '@nutui/icons-vue-taro';
import BASE_URL from '@/utils/config';

const feedbackText = ref('');
const screenshots = ref([]);
const name = ref('');
const contact = ref('');
const previewVisible = ref(false);
const previewImages = ref([]);
const maxImages = 3;

/**
 * 显示提示信息
 */
const showToast = (message, type = 'success') => {
  Taro.showToast({
    title: message,
    icon: type,
    duration: 2000
  });
};

/**
 * 选择图片
 */
const chooseImage = () => {
  if (screenshots.value.length >= maxImages) {
    showToast(`最多只能上传${maxImages}张图片`, 'error');
    return;
  }

  const remainingCount = maxImages - screenshots.value.length;
  Taro.chooseImage({
    count: remainingCount,
    sizeType: ['compressed'],
    sourceType: ['album', 'camera'],
    success: function (res) {
      res.tempFilePaths.forEach(tempFilePath => {
        // 检查文件大小(10MB = 10 * 1024 * 1024 bytes)
        Taro.getFileInfo({
          filePath: tempFilePath,
          success: function (fileInfo) {
            if (fileInfo.size > 10 * 1024 * 1024) {
              showToast('图片大小不能超过10MB', 'error');
              return;
            }
            uploadImage(tempFilePath);
          },
          fail: function () {
            // 如果获取文件信息失败,直接上传
            uploadImage(tempFilePath);
          }
        });
      });
    },
    fail: function () {
      showToast('选择图片失败', 'error');
    }
  });
};

/**
 * 上传图片到服务器
 */
const uploadImage = (filePath) => {
  // 显示上传中提示
  Taro.showLoading({
    title: '上传中',
    mask: true
  });

  wx.uploadFile({
    url: BASE_URL + '/admin/?m=srv&a=upload&image_audit=1',
    filePath,
    name: 'file',
    header: {
      'content-type': 'multipart/form-data',
    },
    success: function (res) {
      let upload_data = JSON.parse(res.data);
      Taro.hideLoading({
        success: () => {
          if (upload_data.code === 0 && upload_data.data) {
            screenshots.value.push({
              url: upload_data.data.src,
              localPath: filePath
            });
            showToast('上传成功', 'success');
          } else {
            // 检查是否为审核不通过
            if (upload_data.code === 0 && !upload_data.data && upload_data.msg && upload_data.msg.includes('审核不通过')) {
              Taro.showModal({
                title: '温馨提示',
                content: '您上传的内容未通过审核',
                showCancel: false
              }).then(res => {
                if (res.confirm) {
                  // 点击了确认按钮
                }
              });
            } else {
              showToast('服务器错误,稍后重试!', 'error');
            }
          }
        },
      });
    },
    fail: function (res) {
      Taro.hideLoading({
        success: () => {
          showToast('上传失败,稍后重试!', 'error');
        }
      });
    }
  });
};

/**
 * 预览图片
 */
const previewImage = (index) => {
  previewImages.value = screenshots.value.map(item => ({ src: item.url }));
  previewVisible.value = true;
};

/**
 * 关闭预览
 */
const closePreview = () => {
  previewVisible.value = false;
};

/**
 * 删除图片
 */
const deleteImage = (index) => {
  screenshots.value.splice(index, 1);
  showToast('图片已删除', 'success');
};

/**
 * 提交反馈
 */
const submitFeedback = () => {
  if (!feedbackText.value) {
    showToast('请描述您遇到的问题或建议', 'none');
    return;
  }
  if (!name.value) {
    showToast('请输入您的姓名', 'none');
    return;
  }
  if (!contact.value) {
    showToast('请输入您的手机号或微信号', 'none');
    return;
  }

  // 在实际应用中,这里会处理提交逻辑,例如上传图片和发送数据到服务器
  showToast('提交成功');

  // 提交成功后清空表单
  feedbackText.value = '';
  screenshots.value = [];
  name.value = '';
  contact.value = '';
};
</script>

<style lang="less">
// 你可以在这里添加自定义样式
</style>