index.vue 5.45 KB
<template>
  <view class="u-page">
    <!-- 表单容器:统一label单位为rpx -->
    <up-form
        :model="form"
        ref="uFormRef"
        :rules="rules"
        label-position="left"
    >
      <!-- 1. 文本域(必填,无label但保留必填验证) -->
      <up-form-item
          prop="content"
          class="form-item"
      >
        <up-textarea
            v-model="form.content"
            placeholder="请输入巡查描述"
            maxlength="200"
            :show-word-limit="true"
            border
            :count="true"
            class="textarea"
        ></up-textarea>
      </up-form-item>

      <!-- 2. 上传图片:修复labelWidth单位为rpx -->
      <up-form-item
          prop="images"
          class="form-item"
          required
          label="上传图片"
          label-width="140rpx"
      >
        <up-upload
            v-model="form.images"
            :action="uploadUrl"
            :max-count="3"
            :multiple="true"
            @after-read="handleAfterRead"
            @delete="handleDelete"
            @on-exceed="handleExceed"
            upload-text="选择图片"
            del-color="#ff4d4f"
            class="upload-wrap"
        ></up-upload>
        <view class="tips">(最少1张,最多3张)</view>
      </up-form-item>

      <!-- 3. 转为工单:修复radio绑定 + labelWidth单位 -->
      <up-form-item
          prop="isWorkOrder"
          class="form-item"
          required
          label="转为工单"
          label-width="140rpx"
      >
        <up-radio-group
            v-model="form.isWorkOrder"
            active-color="#1989fa"
            direction="row"
            class="radio-group"
        >
          <!-- 修复:radio绑定value而非name -->
          <up-radio
              :custom-style="{marginRight: '40rpx'}"
              v-for="(item, index) in radioList"
              :label="item.label"
              :name="item.value"
          >
            {{ item.label }}
          </up-radio>
        </up-radio-group>
      </up-form-item>
    </up-form>

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

<script setup>
import { ref, reactive } from 'vue';
// 表单数据
const form = reactive({
  content: '',       // 文本域内容
  images: [],        // 上传图片列表
  isWorkOrder: '1'    // 是否转为工单 1:是 2:否
});
// 图片上传地址
const uploadUrl = ref('');
// 单选列表
const radioList = ref([
  {label: '是', value: '1'},
  {label: '否', value: '2'}
]);
// 校验规则
const rules = reactive({
  content: [
    {required: true, message: '请输入巡查描述', trigger: ['blur', 'change']},
    {max: 200, message: '内容不能超过200字', trigger: ['blur', 'change']}
  ],
  images: [
    {
      validator: (rule, value, callback) => {
        if (value.length < 1) callback(new Error('最少需要上传1张图片'));
        else if (value.length > 3) callback(new Error('最多只能上传3张图片'));
        else callback();
      },
      trigger: ['change']
    }
  ],
  isWorkOrder: [
    {required: true, message: '请选择是否转为工单', trigger: ['change']}
  ]
});
// 表单引用
const uFormRef = ref(null);
// 图片上传/删除/超出处理
const handleAfterRead = (event) => {
  const {file} = event;
  setTimeout(() => {
    form.images.push({url: file.url, name: file.name || 'image.png', status: 'success'});
    uFormRef.value.validateField('images');
  }, 500);
};
const handleDelete = (index) => {
  form.images.splice(index, 1);
  uFormRef.value.validateField('images');
};
const handleExceed = () => uni.$u.toast('最多只能上传3张图片', 'none');
// 提交方法
const submit = () => {
  uFormRef.value.validate().then(valid => {
    if (valid) {
      uni.showLoading({title: '提交中...'});
      setTimeout(() => {
        uni.hideLoading();
        uni.$u.toast('提交成功');
        uFormRef.value.resetFields();
        form.images = [];
      }, 1500);
    }
  }).catch(() => uni.$u.toast('表单验证失败,请检查必填项', 'none'));
};
</script>

<style scoped lang="scss">
// 基础布局:避免内容重叠
.u-page {
  padding: 20rpx;
}

// 表单项样式:分隔区域,避免label和内容重叠
.form-item {
  background-color: #fff;
  border-radius: 12rpx;
  padding:0 30rpx;
  margin-bottom: 20rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
  position: relative; // 为文本域必填*号定位
}

// 文本域样式
.textarea {
  margin-bottom: 10rpx;
}

// 上传区域样式
.upload-wrap {
  margin-top: 10rpx;
}

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

// ========== 核心:修复必填*号显示 ==========
// 1. 放大+高亮uView默认必填*号
:deep(.up-form-item__required) {
  color: #ff4d4f !important; // 醒目红色
  font-size: 28rpx !important; // 放大字号
  font-weight: bold !important; // 加粗
  margin-left: 5rpx !important; // 与label保持间距
}




// 底部按钮样式
.submit-btn-wrap {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 999;
  padding: 0;
  background-color: #f8f8f8;
  /* #ifdef MP-WEIXIN */
  //padding-bottom: constant(safe-area-inset-bottom);
  //padding-bottom: env(safe-area-inset-bottom);
  /* #endif */
}

</style>