<template>
  <div class="service-form" v-if="pageShow">
    <div class="step">
      <div class="step-item" :class="[currIndex > 0 ? 'active' : '']">
        <i class="line" :class="[currIndex > 1 ? 'line-active' : '']"></i>
        <span>1</span>
        <div>办理须知</div>
      </div>
      <div class="step-item" :class="[currIndex > 1 ? 'active' : '']">
        <i class="line" :class="[currIndex > 2 ? 'line-active' : '']"></i>
        <span>2</span>
        <div>资料上传</div>
      </div>
      <div class="step-item" :class="[currIndex > 2 ? 'active' : '']">
        <i class="line" :class="[currIndex > 3 ? 'line-active' : '']"></i>
        <span>3</span>
        <div>表单填写</div>
      </div>
      <div class="step-item" :class="[currIndex > 3 ? 'active' : '']">
        <span>4</span>
        <div>完成提交</div>
      </div>
    </div>
    <div class="step-item" v-if="currIndex === 2">
      <div class="service-upload">
        <div class="upload-item" v-for="(item, index) in info.processAnnexDefs" :key="index">
          <div class="upload-item__title">
            <i :style="{opacity: item.mustFill === '1' ? 1 : 0}">*</i>
            <h2>请上传{{ item.annexName }}</h2>
          </div>
          <div class="upload-item__wrapper" @click="upload(index)">
            <image v-if="item.src" mode="aspectFill" :src="item.src"/>
            <i v-if="!item.src" class="iconfont">&#xe72c;</i>
            <h2 v-if="!item.src">上传照片</h2>
          </div>
        </div>
      </div>
      <div class="service-example" v-if="exampleList.length">
        <h2>上传样例</h2>
        <div class="service-example__list">
          <div class="service-example__item" v-for="(item, index) in exampleList" :key="index">
            <image :src="item.exampleFile.url" mode="aspectFill" @click="preview(exampleList, item.exampleFile.url)"/>
            <h2>{{ item.annexName }}</h2>
          </div>
        </div>
      </div>
    </div>
    <div class="step-item" v-if="currIndex === 3">
      <div class="step-item__form">
        <h2>{{ info.tableInfo.tableName }}</h2>
        <div class="step-item__form--group" :style="{'margin-top': index === 0 ? '20px' : '50px'}"
             v-for="(item, index) in tableForm" :key="index">
          <div class="group-title">
            <span></span>
            <h3>{{ item[0].groupName }}</h3>
          </div>
          <view v-for="(field, i) in item" :key="i">
            <div class="form-item" v-if="field.fieldDataType === '1' || field.fieldDataType === '0'">
              <div class="form-title">
                <i :style="{opacity: field.mustFill === '1' ? 1 : 0}">*</i>
                <span>{{ field.fieldName }}{{ field.fieldNameSuffix || '' }}</span>
              </div>
              <div class="form-item__wrapper">
                <input placeholder="请输入" :maxlength="field.fieldLength ? field.fieldLength : -1"
                       v-model="field.fieldValue" :type="field.fieldDataType === '0' ? 'number' : 'text'">
              </div>
            </div>
            <div class="form-item" v-if="field.fieldDataType === '4'">
              <div class="form-title">
                <i :style="{opacity: field.mustFill === '1' ? 1 : 0}">*</i>
                <span>{{ field.fieldName }}</span>
              </div>
              <div class="form-check">
                <u-radio-group v-model="field.fieldValue">
                  <u-radio
                      v-for="(dict, j) in $dict.getDict(field.dictionaryCode)" :key="j"
                      :name="dict.dictValue">
                    {{ dict.dictName }}
                  </u-radio>
                </u-radio-group>
              </div>
            </div>
            <div class="form-item" v-if="field.fieldDataType === '5'">
              <div class="form-title">
                <i :style="{opacity: field.mustFill === '1' ? 1 : 0}">*</i>
                <span>{{ field.fieldName }}{{ field.fieldNameSuffix || '' }}</span>
              </div>
              <div class="form-check">
                <u-checkbox-group>
                  <u-checkbox
                      @change="e => checkChange(e, index, i, j)"
                      :data-index="index"
                      :data-i="i"
                      :data-j="j"
                      v-for="(dict, j) in field.dictionaryList"
                      :key="j"
                      v-model="dict.checked"
                      :name="dict.dictValue">
                    {{ dict.dictName }}
                  </u-checkbox>
                </u-checkbox-group>
              </div>
            </div>
            <div class="form-item" v-if="field.fieldDataType === '8'">
              <div class="form-title">
                <i :style="{opacity: field.mustFill === '1' ? 1 : 0}">*</i>
                <span>{{ field.fieldName }}{{ field.fieldNameSuffix || '' }}</span>
              </div>
              <div class="form-item__wrapper">
                <input placeholder="请选择" disabled :value="field.fieldValue || ''">
                <picker
                    mode="date"
                    :data-index="index"
                    :data-i="i"
                    @change="onDateChange">
                  <div class="form-item__choose" hover-class="text-hover">选择</div>
                </picker>
              </div>
            </div>
            <div class="form-item" v-if="field.fieldDataType === '9'">
              <div class="form-title">
                <i :style="{opacity: field.mustFill === '1' ? 1 : 0}">*</i>
                <span>{{ field.fieldName }}{{ field.fieldNameSuffix || '' }}</span>
              </div>
              <div class="form-item__wrapper">
                <input placeholder="请选择" disabled :value="field.fieldDictName || ''">
                <picker
                    range-key="dictName"
                    :range="$dict.getDict(field.dictionaryCode)"
                    :data-index="index"
                    :data-i="i"
                    :data-dict="field.dictionaryCode"
                    @change="onPickerChange">
                  <div class="form-item__choose" hover-class="text-hover">选择</div>
                </picker>
              </div>
            </div>
          </view>
        </div>
      </div>
    </div>
    <div class="service-btn" @click="next">{{ currIndex === 3 ? '签名并提交' : '下一步' }}</div>
    <u-popup v-model="isShow" mode="bottom" :mask-custom-style="{background: 'rgba(0, 0, 0, 0.2)'}" @close="clear">
      <div class="signature">
        <div class="signature-header">
          <div hover-class="text-hover" :hover-stay-time="100" @click="isShow = false, clear()">取消</div>
        </div>
        <div class="signature-canvas">
          <canvas
              class="handWriting"
              disable-scroll="true"
              @touchstart="uploadScaleStart"
              @touchmove="uploadScaleMove"
              @touchend="uploadScaleEnd"
              canvas-id="handWriting">
          </canvas>
        </div>
        <div class="signature-footer">
          <div class="signature-footer__left" @click="clear" hover-class="text-hover" :hover-stay-time="100">
            <i class="iconfont">&#xe72e;</i>
            <span>重新签名</span>
          </div>
          <div class="signature-btn" hover-class="text-hover" :hover-stay-time="100" @click="submitSignature">提交</div>
        </div>
      </div>
    </u-popup>
  </div>
</template>

<script>
import {mapState} from 'vuex'
import Handwriting from '@/utils/signature.js'

export default {
  name:"serviceForm",
  data() {
    return {
      pageShow: false,
      currIndex: 2,
      isShow: false,
      id: '',
      list: [],
      handwriting: '',
      isHasSignature: false,
      tableForm: [],
      info: {},
      isTouch: false,
      fileManage: null
    }
  },

  computed: {
    ...mapState(['user']),

    exampleList() {
      if (!this.info.processAnnexDefs) {
        return []
      }

      return JSON.parse(JSON.stringify(this.info.processAnnexDefs)).filter(v => v.exampleFileId)
    }
  },

  onLoad(query) {
    this.id = query.id
    this.getInfo(query.id)
  },

  onReady() {
  },

  methods: {
    clear() {
      this.isTouch = false
      this.handwriting.retDraw()
    },

    uploadScaleStart(event) {
      this.handwriting.uploadScaleStart(event)
    },

    uploadScaleMove(event) {
      this.isTouch = true
      this.handwriting.uploadScaleMove(event)
    },

    uploadScaleEnd(event) {
      this.handwriting.uploadScaleEnd(event)
    },

    submitSignature() {
      if (!this.isTouch) {
        return this.$toast('签名不能为空')
      }

      this.handwriting.saveCanvas().then(res => {
        uni.getFileSystemManager().readFile({
          filePath: res,
          encoding: 'base64',
          success: res => {
            this.$loading()
            this.$instance.post(`/app/syssignaccount/xcx-draw-sign?openId=${this.user.openId}`, res.data, {
              headers: {
                'Content-Type': 'application/json'
              }
            }).then(res => {
              if (res.code === 0) {
                this.signatureId = res.data
                this.isShow = false
                this.$toast('签名成功')

                this.$nextTick(() => {
                  this.submitForm()
                })
              }
            })
          },
          fail: () => {
            this.$toast('签名生成失败')
          }
        })
      }).catch(() => {
        this.$toast('签名绘制失败')
      })
    },

    IdCard(UUserCard, num) {
      if (num == 1) {
        return UUserCard.substring(6, 10) + '-' + UUserCard.substring(10, 12) + '-' + UUserCard.substring(12, 14)
      }
      if (num == 2) {
        if (parseInt(UUserCard.substr(16, 1)) % 2 == 1) {
          return '1'
        } else {
          return '0'
        }
      }
      if (num == 3) {
        var myDate = new Date()
        var month = myDate.getMonth() + 1
        var day = myDate.getDate()
        var age = myDate.getFullYear() - UUserCard.substring(6, 10) - 1;
        if (UUserCard.substring(10, 12) < month || UUserCard.substring(10, 12) == month && UUserCard.substring(12, 14) <= day) {
          age++
        }

        return age
      }
    },

    getInfo(id) {
      this.$loading()
      this.$instance.post(`/app/approval-process-def/info-id?id=${id}`,).then(res => {
        if (res.code === 0) {
          this.$hideLoading()
          this.info = res.data
          uni.setNavigationBarTitle({
            title: res.data.processName
          })
          this.isHasSignature = !!res.data.tableInfo.tableFieldInfos.filter(v => v.fieldType === '1').length
          const groupFormIds = this.unique(res.data.tableInfo.tableFieldInfos.filter(v => v.fieldType !== '1').map(v => v.groupIndex))
          const dictKeys = res.data.tableInfo.tableFieldInfos.filter(v => !!v.dictionaryCode).map(v => v.dictionaryCode)
          this.$dict.load(dictKeys).then(() => {
            this.tableForm = groupFormIds.map(index => {
              return res.data.tableInfo.tableFieldInfos.filter(v => v.fieldType !== '1' && v.groupIndex === index).map(item => {
                if (item.dictionaryCode) {
                  item.dictionaryList = this.$dict.getDict(item.dictionaryCode)
                }

                if (item.fieldDbName === 'name') {
                  item.fieldValue = this.user.realName || ''
                }

                if (item.fieldDbName === 'phone') {
                  item.fieldValue = this.user.phone || ''
                }

                // if (item.fieldDbName === 'sex') {
                //   item.fieldValue = this.IdCard(this.user.idNumber, 2)
                // }

                if (item.fieldDbName === 'id_number') {
                  item.fieldValue = this.user.idNumber || ''
                }

                if (item.fieldDbName === 'age') {
                  item.fieldValue = this.IdCard(this.user.idNumber, 3)
                }

                if (item.fieldDbName === 'birthday') {
                  item.fieldValue = this.IdCard(this.user.idNumber, 1)
                }

                return item
              })
            })
          })
          this.pageShow = true
        }
      })
    },

    checkChange(e, index, i) {
      this.$forceUpdate()

      this.$nextTick(() => {
        const value = this.tableForm[index][i].dictionaryList.filter(v => v.checked).map(v => v.dictValue).join(',')

        this.$set(this.tableForm[index][i], 'fieldValue', value)
      })
    },

    onDateChange(e) {
      const index = e.target.dataset.index
      const i = e.target.dataset.i
      const value = e.detail.value.split('-')

      this.$set(this.tableForm[index][i], 'fieldValue', `${value[0]}年${value[1]}月${value[2]}日`)
    },

    onPickerChange(e) {
      const index = e.target.dataset.index
      const i = e.target.dataset.i
      const dict = e.target.dataset.dict
      const value = e.detail.value
      const key = this.$dict.getLabel(dict, value)

      this.$set(this.tableForm[index][i], 'fieldValue', value)
      this.$set(this.tableForm[index][i], 'fieldDictName', key)
    },

    preview(list, url) {
      const imgs = list.map(v => v.exampleFile.url)
      uni.previewImage({
        current: url,
        urls: imgs
      })
    },

    /**
     * 数组去重
     */
    unique(arr) {
      return arr.filter((item, index) => {
        return arr.indexOf(item, 0) === index
      })
    },

    /**
     * 图片上传
     */
    upload(index) {
      uni.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        sourceType: ['album', 'camera'],
        success: res => {
          const path = res.tempFilePaths[0]
          this.$loading()
          uni.uploadFile({
            url: this.$instance.baseURL + '/admin/file/add',
            filePath: path,
            name: 'file',
            header: {
              'Content-Type': 'multipart/form-data',
              Authorization: uni.getStorageSync('token')
            },
            success: res => {
              const data = JSON.parse(res.data)

              if (data.code === 0) {
                this.$set(this.info.processAnnexDefs[index], 'src', data.data[0].split(';')[0])
                this.$set(this.info.processAnnexDefs[index], 'annexFileId', data.data[0].split(';')[1])
              } else {
                this.$toast(data.msg)
              }
            },
            complete: () => {
              this.$hideLoading()
            }
          })
        }
      })
    },

    next() {
      if (this.currIndex === 2) {
        for (let item of this.info.processAnnexDefs) {
          if (item.mustFill === '1' && !item.annexFileId) {
            return this.$toast(`请上传${item.annexName}`)
          }
        }
        this.currIndex = 3
      } else if (this.currIndex === 3) {
        this.submitForm()
      }
    },

    submitForm() {
      let list = []
      let signature = ''

      if (this.isHasSignature) {
        signature = {
          ...this.info.tableInfo.tableFieldInfos.filter(v => v.fieldType === '1')[0],
          fieldValue: this.signatureId
        }
      }

      this.tableForm.forEach(item => {
        item.forEach(form => {
          list.push(form)
        })
      })

      for (let item of list) {
        if (item.mustFill === '1' && !item.fieldValue) {
          return this.$toast(`${item.fieldDataType === '0' || item.fieldDataType === '1' ? '请输入' : '请选择'}${item.fieldName}`)
        }

        if (item.mustFill === '1' && item.verifyType) {
          // const reg = item.verifyType === '0' ? new RegExp('(^\d{15}$)|(^\d{17}(\d|X|x)$)')  : new RegExp('^1[0-9]{10,10}$')
          const reg = item.verifyType === '0' ? /(^\d{15}$)|(^\d{17}(\d|X|x)$)/ : /^1[0-9]{10,10}$/

          if (!reg.test(item.fieldValue)) {
            return this.$toast(`请输入正确的${item.fieldName}`)
          }
        }
      }

      if (signature) {
        list.push(signature)
      }

      if (this.isHasSignature && !this.signatureId) {
        this.handwriting = new Handwriting({
          lineColor: this.lineColor,
          slideValue: this.slideValue,
          canvasName: 'handWriting'
        })

        this.$nextTick(() => {
          this.isShow = true
        })

        return false
      }

      const annexs = this.info.processAnnexDefs.map(item => {
        return {
          annexFileId: item.annexFileId,
          emptyFileId: item.emptyFileId,
          exampleFileId: item.exampleFileId,
          processAnnexDefId: item.id,
          annexName: item.annexName
        }
      }).filter(v => !!v.annexFileId)

      const processNodeList = this.info.processNodeList
      let tableInfo = this.info.tableInfo
      tableInfo.tableFieldInfos = list

      this.$loading()
      this.$instance.post(`/app/approv-alapply-info/add`, {
        processNodeList,
        annexs,
        tableInfo,
        tableId: this.info.tableId,
        processDefId: this.info.id,
        processDefName: this.info.processName
      }).then(res => {
        if (res.code === 0) {
          this.$toast('申请成功')
          uni.reLaunch({
            url: `./serviceResult?title=${this.info.processName}`
          })
        } else {
          this.$hideLoading()
        }
      }).catch(() => {
        this.$hideLoading()
      })
    }
  }
}
</script>

<style scoped lang="scss">
.signature {
  background: #fff;

  .signature-header {
    height: 120px;
    line-height: 120px;
    padding: 0 32px;

    div {
      color: #000000;
      font-size: 30px;
    }
  }

  .signature-canvas {
    width: 686px;
    height: 464px;
    margin: 0 auto 40px;
    background: #FAFAFA;
    border-radius: 8px;
    border: 1px solid #DDDDDD;

    canvas {
      width: 100%;
      height: 100%;
    }
  }

  .signature-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 128px;
    padding: 0 32px;
    border-top: 1px solid #DDDDDD;

    .signature-footer__left {
      display: flex;
      align-items: center;

      i {
        margin-right: 4px;
        font-size: 32px;
        color: #4E8EEE;
      }

      span {
        color: #4E8EEE;
        font-size: 28px;
      }
    }

    .signature-btn {
      width: 192px;
      height: 80px;
      line-height: 80px;
      text-align: center;
      color: #fff;
      font-size: 32px;
      background: #197DF0;
      border-radius: 4px;
    }
  }
}

.service-form {
  min-height: 100vh;
  padding-bottom: 124px;
  box-sizing: border-box;
  background-color: #fff;
}

.upload-item__title {
  display: flex;
  position: relative;
  align-items: center;
  left: -16px;

  i {
    font-size: 32px;
    color: #FF4466;
  }
}

.step-item__form {
  padding-top: 40px;

  .step-item__form--group {
    margin-top: 50px;
  }

  .group-title {
    display: flex;
    align-items: center;
    padding: 0 32px;

    span {
      width: 4px;
      height: 32px;
      margin-right: 6px;
      background: #1365DD;
    }

    h3 {
      color: #333333;
      font-size: 32px;
      font-weight: 600;
    }
  }

  & > h2 {
    padding: 0 32px;
    color: #333333;
    font-size: 34px;
    font-weight: 600;
  }

  .form-title {
    display: flex;
    align-items: center;
    width: 100%;

    span {
      font-size: 32px;
      color: #333;
      font-weight: 600;
    }

    i {
      margin-right: 2px;
      color: #FF4466;
      font-size: 32px;
    }
  }

  .form-check {
    margin-left: 16px;
    margin-top: 20px;
    overflow: hidden;
  }

  .form-item {
    padding: 40px 0 0 0;
    margin: 0 32px 0 16px;

    .form-item__wrapper {
      display: flex;
      align-items: center;
      height: 70px;
      margin-left: 16px;
      padding-bottom: 12px;
      border-bottom: 1px solid #DDDDDD;
    }

    input {
      flex: 1;
      line-height: 70px;
      padding-right: 20px;
      box-sizing: border-box;
    }

    .form-item__choose {
      color: #4292F3;
      font-size: 32px;
    }
  }
}

.service-btn {
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 11;
  width: 100%;
  height: 114px;
  line-height: 114px;
  text-align: center;
  color: #fff;
  font-size: 34px;
  background-color: #197DF0;
}

.service-example {
  margin-top: 64px;
  margin-bottom: 20px;

  & > h2 {
    padding: 0 32px;
    color: #333333;
    font-size: 30px;
  }

  .service-example__list {
    display: flex;
    flex-wrap: wrap;
    padding: 0 32px;

    .service-example__item {
      width: 215px;
      margin-top: 24px;
      margin-right: 24px;

      &:nth-of-type(3n) {
        margin-right: 0;
      }

      image {
        width: 216px;
        height: 136px;
        margin-bottom: 16px;
      }

      h2 {
        color: #333333;
        font-size: 30px;
      }

      &:last-child {
        margin-right: 0;
      }
    }
  }
}

.service-upload {
  margin-top: 40px;
  padding: 0 32px;

  .upload-item {
    margin-bottom: 64px;

    &:last-child {
      margin-bottom: 0;
    }

    & > h2 {
      color: #333333;
      font-size: 30px;
    }

    .upload-item__wrapper {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      width: 310px;
      height: 180px;
      margin-top: 48px;
      border-radius: 8px;
      border: 2px dashed #AAA8A8;

      image {
        width: 100%;
        height: 100%;
      }

      i {
        margin-bottom: 8px;
        color: #E4E4E4;
        font-size: 68px;
      }

      h2 {
        color: #666666;
        font-size: 28px;
      }
    }
  }
}

.step {
  display: flex;
  align-items: center;
  height: 176px;
  background: #FFFFFF;
  box-shadow: 0 8px 4px 0 rgba(0, 0, 0, 0.05);

  .step-item {
    position: relative;
    flex: 1;
    text-align: center;

    .line {
      position: absolute;
      top: 20px;
      left: 70%;
      width: 120px;
      height: 2px;
      background: #CCCCCC;

      &.line-active {
        background: #467DFE;
      }
    }

    &.active {
      div {
        font-weight: 600;
        color: #467DFE;
      }

      span {
        background: #467DFE;
      }
    }

    div {
      font-size: 26px;
      color: #999999;
    }

    span {
      display: block;
      width: 40px;
      height: 40px;
      line-height: 40px;
      margin: 0 auto 18px;
      text-align: center;
      color: #fff;
      font-size: 26px;
      border-radius: 50%;
      background: #D0D1D6;
    }
  }
}
</style>
