You need to sign in before continuing.
add-record.vue 10.5 KB
<template>
  <view class="u-page">
    <!-- 核心:将所有 up-form-item 包裹在同一个 up-form 内 -->
    <view class="inspect-form-content commonPageLRpadding">
      <up-form
          label-position="left"
          :model="inspectForm"
          ref="inspectFormRef"
          labelWidth="140rpx"
      >
        <!-- 1. 巡查描述(文本域) -->
        <up-form-item
            prop="content"
            class="form-item"
        >
          <up-textarea
              v-model="inspectForm.remark"
              placeholder="请输入巡查描述"
              maxlength="200"
              count
          ></up-textarea>
        </up-form-item>

        <!-- 2. 上传图片 -->
        <up-form-item
            label="上传图片"
            prop="images"
            required
            border-bottom
            class="form-item"
        >
          <up-upload
              :file-list="imagesList"
              @after-read="(event) => uploadImgs(event)"
              @delete="(event) => deleteImg(event)"
              @on-exceed="handleExceed"
              multiple
              :max-count="3"
              upload-text="选择图片"
              del-color="#ff4d4f"
              class="upload-wrap"
          ></up-upload>
        </up-form-item>

        <!-- 3. 完成进度(滑块) -->
        <up-form-item
            label="完成进度"
            prop="progress"
            required
            class="form-item"
        >
          <view class="progress-wrap">
            <up-slider
                v-model="inspectForm.progress"
                :min="initProgress"
                :max="100"

                active-color="#1989fa"
                inactive-color="#e5e5e5"
                block-size="24"
                class="progress-slider"
            ></up-slider>
            <view class="progress-value">{{ inspectForm.progress }}%</view>
            <view class="progress-tips" v-if="inspectForm.progress <= initProgress">
              进度低于等于{{ initProgress }}%,无法调整
            </view>
          </view>
        </up-form-item>

      </up-form>
    </view>

    <!-- 底部提交按钮 -->
    <view class="fixed-bottom-btn-wrap">
      <up-button
          type="primary"
          text="提交"
          @click="submitInspect"
          :style="{ width: '100%', height: '88rpx', fontSize: '32rpx', borderRadius: 0 }"
      ></up-button>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import type { UniFormRef } from '@/uni_modules/uview-plus/types'
// 定义ref供选项式API使用
const inspectFormRef = ref<UniFormRef>(null)
</script>

<script lang="ts">
import { uploadImages } from '@/common/utils/upload';
import { maintainCreate } from  "@/api/maintain-manage/maintain-manage";

export default {
  data() {
    return {
      // 图片列表
      imagesList: [],
      // 从URL获取的初始进度值
      initProgress: 0,
      // 巡查表单数据
      inspectForm: {
        remark: '',        // 巡查描述
        progress: 0         // 完成进度(0-100)
      },
      paramsOptins: {},     // 接受参数
      // 表单校验规则
      inspectFormRules: {
        images: [
          {
            required: true,
            message: '请上传图片',
            trigger: 'change',
            validator: (rule, value, callback) => {
              // 自定义校验规则:检查是否有成功上传的图片
              const hasSuccessImg = this.imagesList.some(item => item.status === 'success')
              const imgCount = this.imagesList.filter(item => item.status === 'success').length

              if (!hasSuccessImg || imgCount < 1) {
                callback(new Error('最少需要上传1张图片'))
              } else if (imgCount > 3) {
                callback(new Error('最多只能上传3张图片'))
              } else {
                callback()
              }
            }
          }
        ],
        progress: [
          {
            type: 'number',
            required: true,
            message: '请设置完成进度',
            trigger: ['change'],
            validator: (rule, value, callback) => {
              // 自定义校验:进度必须大于初始进度值
              if (value <= this.initProgress) {
                callback(new Error(`完成进度必须大于${this.initProgress}%`))
              } else {
                callback()
              }
            }
          }
        ]
      }
    }
  },
  onLoad(option) {
    console.log('页面参数:', option)
    this.paramsOptins = option

    // 从URL参数中获取进度值,默认0
    this.initProgress = option.progress ? Number(option.progress) : 0
    // 设置表单初始进度值
    this.inspectForm.progress = this.initProgress

    console.log('初始进度值:', this.initProgress)
  },
  onReady() {
    // 兼容微信小程序,通过setRules设置校验规则
    this.$refs.inspectFormRef.setRules(this.inspectFormRules)
    console.log('巡查表单规则初始化完成')
  },
  methods: {
    /**
     * 删除图片
     */
    deleteImg(event) {
      console.log('删除图片事件:', event)
      this.imagesList.splice(event.index, 1)
      // 删除图片后重新校验图片字段
      this.$refs.inspectFormRef.validateField('images')
      uni.showToast({ title: '图片删除成功', icon: 'success' })
    },

    /**
     * 上传图片
     */
    async uploadImgs(event) {
      console.log('上传图片事件:', event)
      const fileList = Array.isArray(event.file) ? event.file : [event.file]
      const targetImgList = this.imagesList

      const filePaths = fileList.map(item => item.url)
      const tempItems = fileList.map(item => ({
        ...item,
        status: 'uploading',
        message: '上传中'
      }))
      const startIndex = targetImgList.length
      targetImgList.push(...tempItems)

      try {
        const uploadResultUrls = await uploadImages({
          filePaths: filePaths,
          ignoreError: true
        })
        console.log('上传成功的URL列表:', uploadResultUrls)

        uploadResultUrls.forEach((url, index) => {
          if (targetImgList[startIndex + index]) {
            targetImgList.splice(startIndex + index, 1, {
              ...fileList[index],
              status: 'success',
              message: '',
              url: url
            })
          }
        })

        if (uploadResultUrls.length < fileList.length) {
          const failCount = fileList.length - uploadResultUrls.length
          for (let i = uploadResultUrls.length; i < fileList.length; i++) {
            if (targetImgList[startIndex + i]) {
              targetImgList.splice(startIndex + i, 1, {
                ...fileList[i],
                status: 'failed',
                message: '上传失败'
              })
            }
          }
          uni.showToast({ title: `成功上传${uploadResultUrls.length}张,失败${failCount}张`, icon: 'none' })
        } else {
          uni.showToast({ title: `成功上传${fileList.length}张图片`, icon: 'success' })
        }

        // 上传完成后重新校验图片字段
        this.$refs.inspectFormRef.validateField('images')
      } catch (err) {
        console.error('图片上传失败:', err)
        for (let i = 0; i < fileList.length; i++) {
          if (targetImgList[startIndex + i]) {
            targetImgList.splice(startIndex + i, 1, {
              ...fileList[i],
              status: 'failed',
              message: '上传失败'
            })
          }
        }
        uni.showToast({ title: '图片上传失败,请重试', icon: 'none' })

        // 上传失败后重新校验图片字段
        this.$refs.inspectFormRef.validateField('images')
      }
    },

    /**
     * 处理图片超出数量限制
     */
    handleExceed() {
      uni.showToast({ title: '最多只能上传3张图片', icon: 'none' })
    },

    /**
     * 提取图片URL数组
     */
    getImgUrlList(imgList) {
      return imgList.filter(item => item.status === 'success').map(item => item.url)
    },

    /**
     * 提交巡查表单
     */
    async submitInspect() {
      console.log('当前完成进度:', this.inspectForm.progress)
      try {
        // 先执行表单校验
        await this.$refs.inspectFormRef.validate()
        console.log('图片列表:', this.imagesList)

        // 构造提交数据
        const submitData = {
          // "batchNo": this.paramsOptins.batchNo,
          totalFinishPercent:this.inspectForm.progress,
          "planNo": this.paramsOptins.planNo,
          "imgHost": "1",
          "beginImg": this.getImgUrlList(this.imagesList),
          "commonUserList":[],
          // "userId": '',
          // "userName": '',
          "remark": this.inspectForm.remark // 备注中记录进度
        }

        // 显示加载中
        uni.showLoading({ title: '提交中...' })

        await maintainCreate(submitData)

        uni.hideLoading()
        uni.showToast({
          title: '提交成功',
          icon: 'success',
          duration: 1000
        })
        // uni.navigateTo({
        //   url: `/pages-sub/daily/maintain-manage/add-record?finishState=${item.finishState}&planNo=${item.planNo}&finishPercent=${item.finishPercent}`
        // })
        // 延迟跳转(等待提示框显示完成)
        setTimeout(() => {
          uni.redirectTo({
            url: '/pages-sub/daily/maintain-manage/road-detail-list'
          })
        }, 1000)

      } catch (error) {
        // 隐藏加载框
        uni.hideLoading()

        // 区分是表单校验失败还是接口调用失败
        if (Array.isArray(error)) {
          // 表单校验失败 - 静默处理(uView会自动提示)
        } else {
          // 接口调用失败
          console.error('巡查表单提交失败:', error)
          uni.showToast({
            title: '提交失败,请重试',
            icon: 'none',
            duration: 2000
          })
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
// 全局页面样式
.u-page {
  background-color: #f5f5f5;
  min-height: 100vh;
}

// 巡查表单内容容器
.inspect-form-content {
  background: #fff;
  padding: 20rpx;
  margin-bottom: 20rpx;
}

// 进度滑块样式
.progress-wrap {
  width: 100%;

  .progress-slider {
    margin: 20rpx 0;
  }

  .progress-value {
    text-align: right;
    font-size: 28rpx;
    color: #333;
    margin-bottom: 10rpx;
  }

  .progress-tips {
    font-size: 24rpx;
    color: #ff4d4f;
    margin-top: 10rpx;
  }
}

// 表单项目间距
.form-item {
  margin-bottom: 20rpx;
}


</style>