add-record.vue 11.4 KB
<template>
  <view class="u-page">
    <view class="work-order-form-content commonPageLRpadding">
      <up-form
          label-position="left"
          :model="workOrderForm"
          ref="workOrderFormRef"
          labelWidth="160rpx"
      >
        <!-- 1. 工单位置(地图选择) -->
        <up-form-item
            label="工单位置"
            prop="workLocation"
            border-bottom
            required
            @click="chooseWorkLocation(); hideKeyboard()"
        >
          <up-input
              v-model="workOrderForm.workLocation"
              border="none"
              readonly
              suffix-icon="map-fill"
              placeholder="点击选择工单位置"
          ></up-input>
        </up-form-item>

        <!-- 2. 道路名称(下拉框) -->
        <up-form-item
            label="道路名称"
            prop="roadName"
            border-bottom
            required
            @click="workOrderForm.workLocation ? (showRoadName = true, hideKeyboard()) : uni.showToast({title: '请先选择工单位置', icon: 'none'})"
        >
          <up-input
              v-model="workOrderForm.roadName"
              disabled
              disabled-color="#ffffff"
              placeholder="请先选择工单位置"
              border="none"
              :placeholder-style="workOrderForm.workLocation ? '' : 'color:#999;'"
          ></up-input>
          <template #right>
            <up-icon name="arrow-right" size="16" :color="workOrderForm.workLocation ? '#333' : '#999'"></up-icon>
          </template>
        </up-form-item>

        <!-- 3. 工单名称(下拉框) -->
        <up-form-item
            label="工单名称"
            prop="orderName"
            border-bottom
            required
            @click="showOrderName = true; hideKeyboard()"
        >
          <up-input
              v-model="workOrderForm.orderName"
              disabled
              disabled-color="#ffffff"
              placeholder="请选择工单名称"
              border="none"
          ></up-input>
          <template #right>
            <up-icon name="arrow-right" size="16"></up-icon>
          </template>
        </up-form-item>

        <!-- 4. 情况描述(文本域) -->
        <up-form-item
            label="情况描述"
            prop="problemDesc"
            required
        >
          <up-textarea
              placeholder="请输入情况描述(最多200字)"
              v-model="workOrderForm.problemDesc"
              count
              maxlength="200"
              rows="4"
              @blur="() => workOrderFormRef.value?.validateField('problemDesc')"
          ></up-textarea>
        </up-form-item>

        <!-- 问题照片(复用公共上传) -->
        <up-form-item label="问题照片" prop="problemImgs" required>
          <up-upload
              :file-list="problemImgs.imgList"
              @after-read="problemImgs.uploadImgs"
              @delete="problemImgs.deleteImg"
              multiple
              :max-count="problemImgs.uploadConfig.maxCount"
              :upload-text="problemImgs.uploadConfig.uploadText"
              :sizeType="problemImgs.uploadConfig.sizeType"
          ></up-upload>
        </up-form-item>

        <!-- 完成照片(复用公共上传) -->
        <up-form-item label="完成照片" prop="completeImgs" required class="mt-20">
          <up-upload
              :file-list="completeImgs.imgList"
              @after-read="completeImgs.uploadImgs"
              @delete="completeImgs.deleteImg"
              multiple
              :max-count="completeImgs.uploadConfig.maxCount"
              :upload-text="completeImgs.uploadConfig.uploadText"
              :sizeType="completeImgs.uploadConfig.sizeType"
          ></up-upload>
        </up-form-item>

        <!-- 处理结果(不必填) -->
        <up-form-item label="处理结果" prop="handleResult" class="mt-20">
          <up-textarea
              placeholder="请输入处理结果描述(最多200字,选填)"
              v-model="workOrderForm.handleResult"
              count
              maxlength="200"
              rows="4"
              @blur="() => workOrderFormRef.value?.validateField('handleResult')"
          ></up-textarea>
        </up-form-item>
      </up-form>
    </view>

    <!-- 底部提交按钮 -->
    <view class="fixed-bottom-btn-wrap">
      <up-button
          type="primary"
          text="提交工单"
          @click="submitWorkOrder"
      ></up-button>
    </view>

    <!-- 道路名称下拉弹窗 -->
    <up-action-sheet
        :show="showRoadName"
        :actions="roadNameList"
        title="请选择道路名称"
        @close="showRoadName = false"
        @select="handleRoadNameSelect"
    ></up-action-sheet>

    <!-- 工单名称下拉弹窗 -->
    <up-action-sheet
        :show="showOrderName"
        :actions="orderNameList"
        title="请选择工单名称"
        @close="showOrderName = false"
        @select="handleOrderNameSelect"
    ></up-action-sheet>
  </view>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { onReady, onShow } from '@dcloudio/uni-app' // 从uni-app导入小程序生命周期
import type { UniFormRef } from '@/uni_modules/uview-plus/types'
import { useUploadImgs } from '@/common/utils/useUploadImgs' // 引入公共上传逻辑
import { getRoadListByLatLng } from '@/api/common'
import { createQuick } from '@/api/quick-order/quick-order'

// 表单Ref
const workOrderFormRef = ref<UniFormRef>(null)

// ========== 复用公共上传逻辑 ==========
// 1. 问题照片配置
const problemImgs = useUploadImgs({
  maxCount: 3, // 可自定义数量
  uploadText: '选择问题照片',
  sizeType: ['compressed'],
  formRef: workOrderFormRef,
  fieldName: 'problemImgs'
})

// 2. 完成照片配置
const completeImgs = useUploadImgs({
  maxCount: 3,
  uploadText: '选择完成照片',
  sizeType: ['compressed'],
  formRef: workOrderFormRef,
  fieldName: 'completeImgs'
})

// ========== 页面数据 ==========
const showRoadName = ref(false)
const showOrderName = ref(false)
const roadNameList = ref<any[]>([])
const orderNameList = ref<any[]>([])

// 工单表单数据
const workOrderForm = reactive({
  roadId: 0,
  roadName: '',
  workLocation: '',
  orderName: '',
  problemDesc: '',
  handleResult: '',
  lat: 0,
  lon: 0
})

// 表单校验规则
const workOrderFormRules = reactive({
  workLocation: [
    { type: 'string', required: true, message: '请选择工单位置', trigger: ['change', 'blur'] }
  ],
  roadName: [
    { type: 'string', required: true, message: '请选择道路名称', trigger: ['change', 'blur'] }
  ],
  orderName: [
    { type: 'string', required: true, message: '请选择工单名称', trigger: ['change', 'blur'] }
  ],
  problemDesc: [
    { type: 'string', required: true, message: '请输入情况描述', trigger: ['change', 'blur'] },
    { type: 'string', min: 3, max: 200, message: '情况描述需3-200字', trigger: ['change', 'blur'] }
  ],
  problemImgs: [problemImgs.imgValidateRule], // 复用校验规则
  completeImgs: [completeImgs.imgValidateRule] // 复用校验规则
})

// ========== 生命周期 ==========
onReady(() => {
  // 设置表单校验规则
  workOrderFormRef.value?.setRules(workOrderFormRules)
  console.log('工单表单规则初始化完成')
})

onShow(() => {
  console.log(uni.$dict.getDictLabel('ai_image_status', 20))
  console.log(uni.$dict.getDictSimpleList('work_name'))
  orderNameList.value = uni.$dict.transformLabelValueToNameValue(uni.$dict.getDictSimpleList('work_name'))
  console.log(orderNameList.value)
})

// ========== 方法 ==========
/**
 * 返回上一页
 */
const navigateBack = () => {
  uni.navigateBack()
}

/**
 * 隐藏键盘
 */
const hideKeyboard = () => {
  uni.hideKeyboard()
}

/**
 * 选择工单位置
 */
const chooseWorkLocation = async () => {
  uni.chooseLocation({
    success: async (res) => {
      workOrderForm.roadName = ''
      workOrderForm.roadId = 0
      roadNameList.value = []

      workOrderForm.workLocation = res.name
      workOrderForm.lat = res.latitude
      workOrderForm.lon = res.longitude

      workOrderFormRef.value?.validateField('workLocation')
      workOrderFormRef.value?.validateField('roadName')

      try {
        uni.showLoading({ title: '获取道路名称中...' })
        const roadRes = await getRoadListByLatLng({
          companyCode: 'sls',
          latitude: res.latitude,
          longitude: res.longitude
        })
        uni.hideLoading()

        if (Array.isArray(roadRes)) {
          roadNameList.value = roadRes.map((item) => ({
            name: item.roadName || '',
            code: item.roadCode || '',
            id: item.roadId || 0
          }))
        } else {
          roadNameList.value = [{ name: '未查询到道路名称', code: '', id: 0 }]
          uni.showToast({ title: '未查询到该位置的道路信息', icon: 'none' })
        }
      } catch (err) {
        uni.hideLoading()
        console.error('获取道路名称失败:', err)
        uni.showToast({ title: '获取道路名称失败,请重试', icon: 'none' })
        roadNameList.value = [{ name: '获取失败,请重新选择位置', code: '', id: 0 }]
      }
    },
    fail: (err) => {
      console.error('选择位置失败:', err)
      uni.showToast({ title: '选择位置失败:' + err.errMsg, icon: 'none' })
    }
  })
}

/**
 * 选择道路名称
 */
const handleRoadNameSelect = (e: any) => {
  console.log('选择道路名称:', e)
  workOrderForm.roadName = e.name
  workOrderForm.roadId = e.code
  showRoadName.value = false
  workOrderFormRef.value?.validateField('roadName')
}

/**
 * 选择工单名称
 */
const handleOrderNameSelect = (e: any) => {
  console.log(e)
  workOrderForm.orderName = e.name
  showOrderName.value = false
  workOrderFormRef.value?.validateField('orderName')
}

/**
 * 提交工单
 */
const submitWorkOrder = async () => {
  try {
    // 表单校验
    await workOrderFormRef.value?.validate()

    const submitData = {
      roadId: workOrderForm.roadId,
      roadName: workOrderForm.roadName,
      imgs: problemImgs.getSuccessImgUrls(), // 复用获取成功URL方法
      longRangeImgList: completeImgs.getSuccessImgUrls(), // 复用获取成功URL方法
      remark: workOrderForm.problemDesc,
      handleResult: workOrderForm.handleResult,
      latLonType: 2,
      lat: workOrderForm.lat,
      lon: workOrderForm.lon,
      lonLatAddress: workOrderForm.workLocation,
      pressingType: 2,
      orderName: workOrderForm.orderName,
      sourceId: 1,
      sourceName: '园林',
      thirdWorkNo: ''
    }

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

    // 调用提交接口
    const res = await createQuick(submitData)

    uni.hideLoading()
    uni.showToast({
      title: '工单提交成功',
      icon: 'success',
      duration: 1000
    })

    // 延迟跳转
    setTimeout(() => {
      uni.redirectTo({
        url: '/pages-sub/daily/quick-order/index'
      })
    }, 1000)
  } catch (error) {
    uni.hideLoading()

    if (!Array.isArray(error)) {
      console.error('工单提交失败:', error)
      uni.showToast({
        title: '提交失败,请重试',
        icon: 'none',
        duration: 2000
      })
    }
  }
}
</script>

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

// 工单表单内容容器
.work-order-form-content {
  background: #fff;
}

.fixed-bottom-btn-wrap {
  padding: 20rpx;
  background: #fff;
}
</style>