inspectionForm.vue 12.2 KB
<template>
  <view class="inspection-form">
    <view class="form-container">
      <view class="form-screenshot">
        <!-- <uv-image
					ref="screenshotRef"
					width="100%"
					src="https://cdn.uviewui.com/uview/album/1.jpg"
					mode="widthFix"
				></uv-image> -->
        <!-- <canvas ref="screenshotRef" style="width: 100%;" canvas-id="firstCanvas" id="firstCanvas"></canvas> -->
        <!-- <img
					ref="screenshotRef"
					:src="screenshotUrl"
					crossOrigin
					width="100%"
				></img> -->
        <InspectionPainter v-if="screenshotUrl" ref="inspectionPainterRef" :image-url="screenshotUrl" />
      </view>

      <uv-form labelPosition="left" :model="formModel" :rules="rules" :labelWidth="120" ref="formRef">
        <uv-form-item :label="t('app.inspection.templateName')" prop="templateName" borderBottom @click="showTemplateNameSelect">
          <uv-input v-model="templateName" disabled disabledColor="#ffffff" :placeholder="t('maintenance.common.input')" border="none">
          </uv-input>
          <template v-slot:right>
            <uv-icon name="arrow-right"></uv-icon>
          </template>
        </uv-form-item>

        <uv-form-item :label="t('VideoShopTour.questionnaire')" prop="problemList" @click="showProblemListSelect">
          <template v-slot:right>
            <view class="problemList-button">
              <uv-icon name="plus"></uv-icon>
            </view>
          </template>
        </uv-form-item>
        <view class="problem-list-container">
          <template v-if="problemInfoList.length > 0">
            <uv-tags v-for="item in problemInfoList" :key="item.id" :text="item.name" class="problem-tag" size="medium"
              shape="circle" plain :closable="true" bgColor="#F2F3F6" color="#6D778F" borderColor="#FFF"
              closePlace="right" @close="handleCloseProblem(item)"></uv-tags>
          </template>

          <view v-else class="problem-empoty">{{ t('app.inspection.noMoreQuestion') }}</view>
        </view>

        <uv-form-item :label="t('maintenance.common.remark')" prop="remark" labelPosition="top" borderBottom>
          <!-- <uv-input
						v-model="formModel.remark"
						placeholder="请输入备注信息"
						border="none"
						customStyle="background-color: #F2F3F6;height: 48px;padding: 0px 10px;margin-top: 10px;"
					>
					</uv-input> -->
          <uv-textarea v-model="formModel.remark" :placeholder="t('maintenance.common.input')" :height="48" border="none"
            placeholderStyle="font-size: 13px;" customStyle="background-color: #F2F3F6;margin-top: 10px;"></uv-textarea>
        </uv-form-item>
        <uv-form-item :label="t('app.inspection.needsRectificationOrNot')" prop="rectification" borderBottom>
          <uv-radio-group v-model="formModel.rectification" placement="row">
            <uv-radio name="1" :label="t('message.need')" style="margin-right: 20px;"></uv-radio>
            <uv-radio name="0" :label="t('message.noNeedTitle')"></uv-radio>
          </uv-radio-group>
        </uv-form-item>
        <uv-form-item v-if="formModel.rectification === '1'" :label="t('VideoShopTour.reformer')" prop="rectifiedPerson" borderBottom
          @click="showRectifiedPersonSelect">
          <uv-input v-model="rectifiedPerson" disabled disabledColor="#ffffff" :placeholder="t('maintenance.common.select')" border="none">
          </uv-input>
          <template v-slot:right>
            <uv-icon name="arrow-right"></uv-icon>
          </template>
        </uv-form-item>

        <uv-button type="primary" :text="t('button.submit')" customStyle="margin-top: 10px" @click="handleSubmit"></uv-button>
      </uv-form>

      <!-- 弹窗 -->
      <!-- 模板列表 -->
      <uv-action-sheet ref="templateSelectRef" :actions="templateOptions" :title="t('maintenance.common.select')" @select="setTemplateName">
      </uv-action-sheet>
      <!-- 问题列表 -->
      <!-- TODO: UI需要调整 -->
      <uv-action-sheet ref="problemSelectRef" class="inspection-problem-select" :actions="problemOptions" :title="t('maintenance.common.select')"
        :closeOnClickAction="true" @select="setProblemList">
      </uv-action-sheet>
      <!-- 整改人 -->
      <uv-action-sheet ref="rectifiedSelectRef" :actions="rectifiedPersonOptions" :title="t('maintenance.common.select')"
        @select="setRectifiedPerson">
      </uv-action-sheet>
    </view>
  </view>
</template>

<script setup>
  import {
    ref,
  } from 'vue';
  import {
    onLoad
  } from '@dcloudio/uni-app';
  import {
    doInspectionFormListApi,
    doRectifiedPersonListApi,
    doInspectionFormDetailApi,
    doInspectionFormSaveApi
  } from '@/api';
  import {
    getStageObj
  } from '@/utils'
  import {
    getImagePath,
    getFormParams,
    getSops,
    getImageBinary
  } from './utils'
  import InspectionPainter from './components/inspection-painter.vue';
  import {
    t
  } from '@/plugins/index.js'

  // 登录功能
  const formModel = ref({
    templateNameId: undefined, // 模版名称
    problemList: [], // 问题id列表,提交时赋值
    remark: '',
    rectification: '1', // 是否需要整改
    rectifiedPersonId: '',
  })
  const rules = {}

  // 数据源
  const templateOptions = ref([])
  const rectifiedPersonOptions = ref([])
  const problemOptions = ref([])
  // 回显数据
  const templateName = ref('')
  const problemInfoList = ref([])
  const rectifiedPerson = ref('')

  // const ref 
  function hideKeyboard() {
    uni.hideKeyboard()
  }

  // 模版
  const templateSelectRef = ref(null)

  function showTemplateNameSelect() {
    templateSelectRef.value.open();
    hideKeyboard();
  }

  function setTemplateName(e) {
    console.log('setTemplateName', e)
    templateName.value = e.name
    formModel.value.templateNameId = e.value

    // 联动巡检详情
    problemInfoList.value = []
    formModel.value.problemList = []
    setProblemOptions(e.value)
  }

  // 问题项
  const problemSelectRef = ref(null)

  function showProblemListSelect() {
    problemSelectRef.value.open();
    hideKeyboard();
  }

  function setProblemList(e) {
    console.log('setProblemList', e)
    if (!formModel.value.problemList.includes(e.value)) {
      problemInfoList.value.push(e)
      formModel.value.problemList.push(e.value)
    }
  }

  function handleCloseProblem(data) {
    console.log('handleCloseProblem', data)
    problemInfoList.value = problemInfoList.value.filter(item => item.value !== data.value)
    formModel.value.problemList = formModel.value.problemList.filter(item => item !== data.value)
  }

  // 整改人
  const rectifiedSelectRef = ref(null)

  function showRectifiedPersonSelect() {
    rectifiedSelectRef.value.open();
    hideKeyboard();
  }

  function setRectifiedPerson(e) {
    console.log('setRectifiedPerson', e)
    formModel.value.rectifiedPersonId = e.loginName
    rectifiedPerson.value = e.name
  }

  const screenshotRef = ref(null)
  // const screenshotUrl = ref('https://store.keliuyun.com/images/patrol/screenshot/20250530/83115120-2850-4d9d-8ff2-5a4a001bb347.jpg')
  const screenshotUrl = ref('')
  const inspectionPainterRef = ref(null)
  const gateId = ref()
  const mallId = ref()
  // 提交表单
  async function handleSubmit() {
    console.log('handleSubmit', inspectionPainterRef.value)
    // const strBase64 = await getImageBase64(screenshotRef.value)
    // const strBase64 = await getImageBase(screenshotUrl.value)
    // const strBase64 = false
    // const strBase64 = await inspectionPainterRef.value.getCanvasBase64H5()
    const strBase64 = await inspectionPainterRef.value.getCanvasBase64()

    if (strBase64) {
      // 数据全法性验证
      if (problemInfoList.value.length === 0) {
        uni.showToast({
          icon: 'error',
          title: t('app.inspection.plzSelectQuestion')
        })
        return
      }

      const storeInfo = getStageObj('store')
      const params = {
        // true表示测试数据
        ...getFormParams(false, gateId.value, mallId.value),

        patrolType: 1,
        remark: formModel.value.remark,
        handler: (formModel.value.rectification === '1' ? formModel.value.rectifiedPersonId : ''), // 是否有整改人
        // pic: strBase64, // 二进制图片数据
        picBase64: strBase64,

        sops: JSON.stringify(getSops(problemInfoList.value)), // 问题项
      }
      console.log('params', params)

      /* uni.showToast({icon: 'success', title: '提交成功'})
      uni.redirectTo({
      	url: `/pages/inspection/inspectionRecord`,
      }) */
      doInspectionFormSaveApi(params).then(res => {
        console.log('doInspectionFormSaveApi', res)
        uni.showToast({
          icon: 'success',
          title: t('message.submitSuccess')
        })
        setTimeout(()=>{
          uni.redirectTo({
            url: `/subPackages/accountGroup/pages/inspection/inspectionRecord`,
          })
        },500)
      })
    } else {
      uni.showToast({
        icon: 'error',
        title: t('app.inspection.getImgInfoError')// '获取图片信息失败'
      })
    }
  }

  function setProblemOptions(id) {
    // 请求成功后,联动获取整改单详情
    doInspectionFormDetailApi({
      id
    }).then(res => {
      console.log('doInspectionFormDetailApi', res)
      if (res.data) {
        problemOptions.value = res.data.sopProjects.map(item => {
          return {
            name: item.name,
            value: item.id,
            score: item.score,
            status: 0, // 提交巡检单,默认都是有问题的,故为0
          }
        })
      }
    })
  }

  function initPage(restaurantId) {
    const storeInfo = getStageObj('store')
    if (storeInfo) {
      const formParams = {
        // TODO: account 暂时写死
        accountId: storeInfo.accountId,
        // accountId: 337,
        pageSize: 999,
      }
      const rectifiedParams = {
        restaurantId, // 餐厅id
      }
      Promise.all([
        doInspectionFormListApi(formParams),
        doRectifiedPersonListApi(rectifiedParams),
      ]).then(([formRes, rectifiedRes]) => {
        console.log('initPage', formRes, rectifiedRes)
        if (formRes.data && formRes.data.list) {
          templateOptions.value = formRes.data.list.map(item => {
            return {
              name: item.name,
              value: item.id,
            }
          })
        }
        // 若有数据,默认选中第一项
        if (templateOptions.value.length > 0) {
          const targetItem = templateOptions.value[0]
          formModel.templateNameId = targetItem.value
          templateName.value = targetItem.name

          setProblemOptions(targetItem.value)
        }

        if (rectifiedRes.data) {
          rectifiedPersonOptions.value = rectifiedRes.data.map(item => {
            return {
              name: item.realName,
              value: item.id,
              loginName: item.loginName,
            }
          })
        }
      })
    }
  }

  const painterInfo = ref(null)

  onLoad((options) => {
    uni.setNavigationBarTitle({
      title: t('VideoShopTour.videoPatrol')
    })
    console.log('onLoad', options)
    // const restaurantId = 9217
    const restaurantId = options.restaurantId
    screenshotUrl.value = `https://store.keliuyun.com/images/${options.pic}`
    gateId.value = options.gateId
    mallId.value = options.mallId
    initPage(restaurantId)
    // initPainter(screenshotUrl.value)
  })
</script>

<style lang="scss" scoped>
  .inspection-form {
    background-color: #FFF;
    padding: 10px 10px 10px 10px;
  }

  .form-container {
    .problemList-button {
      width: 60px;
      height: 24px;
      background-color: #F2F3F6;
      /* text-align: center; */
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 30px;
    }

    .problem-list-container {
      display: flex;
      flex-wrap: wrap;
      border-bottom: 1px solid #e8e8e9;

      .problem-tag {
        margin-bottom: 10px;
        margin-right: 10px;
      }
    }

    .problem-empoty {
      height: 40px;
      line-height: 40px;
      width: 100%;
      text-align: center;
    }
  }
</style>

<style lang="scss">
  ::v-deep(.uv-action-sheet__item-wrap){
    max-height: 300px;
    overflow-y: auto;
  }
  .inspection-problem-select {
    background-color: #FFF;
    max-height: 40vh;
    overflow-y: auto;
    .uv-action-sheet__item-wrap {
      max-height: 60vh;
      overflow-y: auto;
    }
  }
</style>