You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							464 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
	
	
							464 lines
						
					
					
						
							11 KiB
						
					
					
				<template> | 
						|
  <view class="view-container"> | 
						|
    <view class="box"> | 
						|
      <view class="header"> | 
						|
        <view class="wd-font-800">执法签到</view> | 
						|
        <view class="refresh" @tap="refresh"> | 
						|
          <image | 
						|
            src="/static/images/icon/refresh.png" | 
						|
            mode="aspectFit" | 
						|
            style="width: 16px; height: 16px" | 
						|
          ></image> | 
						|
          刷新 | 
						|
        </view> | 
						|
      </view> | 
						|
      <view class="row codeview"> | 
						|
        <image :src="miniCode" mode="aspectFill" class="code"></image> | 
						|
        <view class="info"> | 
						|
          <view class=""> | 
						|
            <view class="wd-font-800">执法协同人员请</view> | 
						|
            <view class="wd-font-800">扫描二维码签到</view> | 
						|
            <view class="wd-font-800 wd-mt-8" style="color: #f8285a"> | 
						|
              (要求2人以上) | 
						|
            </view> | 
						|
          </view> | 
						|
          <view | 
						|
            class="wd-font-800" | 
						|
            style="color: #17c653; text-decoration: underline" | 
						|
            @tap="showTip = true" | 
						|
          > | 
						|
            无法正常签到? | 
						|
          </view> | 
						|
        </view> | 
						|
      </view> | 
						|
      <view class="row" v-if="list.length == 0"> | 
						|
        <view class="emty"> | 
						|
          <image | 
						|
            class="image" | 
						|
            src="/static/images/emty.png" | 
						|
            mode="aspectFill" | 
						|
          ></image> | 
						|
          <text class="wd-text-14" style="color: #99a1b7"> | 
						|
            暂无处理结果 | 
						|
          </text> | 
						|
        </view> | 
						|
      </view> | 
						|
      <view class="locate-record row" v-for="item in list" :key="item.id"> | 
						|
        <view class="info"> | 
						|
          <u-avatar | 
						|
            :src="item.avtar" | 
						|
            size="40px" | 
						|
            shape="circle" | 
						|
          ></u-avatar> | 
						|
          <view> | 
						|
            <view style="margin-bottom: 4px"> | 
						|
              <text style="font-weight: 800">{{ item.realName }}</text> | 
						|
              <text style="font-size: 13px; color: #4b5675"> | 
						|
                {{ item.deptName }} | 
						|
              </text> | 
						|
            </view> | 
						|
            <view style="font-size: 13px; color: #4b5675"> | 
						|
              {{ $util.formatDate(item.time, 'YYYY年M月D日 hh:mm') }} | 
						|
            </view> | 
						|
          </view> | 
						|
        </view> | 
						|
        <view class="wd-flex wd-flex-center" style="gap: 4px"> | 
						|
          <u-icon | 
						|
            name="checkmark-circle-fill" | 
						|
            size="16" | 
						|
            color="#17C653" | 
						|
          ></u-icon> | 
						|
          <text class="wd-text-13">已签到</text> | 
						|
        </view> | 
						|
      </view> | 
						|
    </view> | 
						|
 | 
						|
    <cs-bottom-wrapper v-if="showBtn"> | 
						|
      <view class="operation"> | 
						|
        <button | 
						|
          class="btn green" | 
						|
          v-if="distance < radius" | 
						|
          @tap="locate" | 
						|
          :loading="loading" | 
						|
        > | 
						|
          确认签到 | 
						|
        </button> | 
						|
        <view class="btn grey" v-else>不在签到范围</view> | 
						|
      </view> | 
						|
    </cs-bottom-wrapper> | 
						|
 | 
						|
    <u-modal | 
						|
      :show="showTip" | 
						|
      width="295px" | 
						|
      closeOnClickOverlay | 
						|
      @close="showTip = false" | 
						|
    > | 
						|
      <view class="tip"> | 
						|
        <view class="header"> | 
						|
          <view>如无法签到 请确认以下</view> | 
						|
          <view>功能是否正常启用?</view> | 
						|
        </view> | 
						|
        <view class="info"> | 
						|
          <view class="msg"> | 
						|
            <u-icon name="wifi" color="#17C653" size="20"></u-icon> | 
						|
            开启手机设置GPS定位功能 | 
						|
          </view> | 
						|
          <view class="msg"> | 
						|
            <u-icon name="wifi" color="#17C653" size="20"></u-icon> | 
						|
            开启手机授权微信定位功能 | 
						|
          </view> | 
						|
          <view class="msg"> | 
						|
            <u-icon name="wifi" color="#17C653" size="20"></u-icon> | 
						|
            开启右上角小程序定位功能 | 
						|
          </view> | 
						|
        </view> | 
						|
      </view> | 
						|
      <template #confirmButton> | 
						|
        <view class="wd-flex wd-flex-center"> | 
						|
          <view class="confirm-btn" @tap="showTip = false">确认</view> | 
						|
        </view> | 
						|
      </template> | 
						|
    </u-modal> | 
						|
 | 
						|
    <van-action-sheet :show="showModel"> | 
						|
      <view class="model-view"> | 
						|
        <image | 
						|
          class="image" | 
						|
          src="/static/images/task/position.png" | 
						|
          mode="aspectFill" | 
						|
        ></image> | 
						|
        <view class="open-setting" @tap="openSetting()">开启定位</view> | 
						|
      </view> | 
						|
    </van-action-sheet> | 
						|
  </view> | 
						|
</template> | 
						|
 | 
						|
<script> | 
						|
import TencentMap from '@/static/js/qqmap-wx-jssdk.min.js' | 
						|
import { getMiniCode } from '@/utils/getCode.js' | 
						|
import { InspectionsApi } from '@/api/inspections/index.js' | 
						|
import { getEnterPrise } from '@/api/enterprise/index.js' | 
						|
export default { | 
						|
  data() { | 
						|
    return { | 
						|
      showModel: false, | 
						|
      inspectionsId: '', | 
						|
      miniCode: '', | 
						|
      enterpriseGps: '', | 
						|
      location: {}, | 
						|
      distance: '', | 
						|
      radius: 1000000, // 打卡范围 | 
						|
      showTip: false, | 
						|
      list: [], | 
						|
      loading: false, | 
						|
      share: { | 
						|
        title: '', | 
						|
        path: '', | 
						|
        imageUrl: '' | 
						|
      } | 
						|
    } | 
						|
  }, | 
						|
  computed: { | 
						|
    showBtn() { | 
						|
      return ( | 
						|
        this.list.findIndex(i => i.userId == this.$store.getters.userId) < | 
						|
        -1 | 
						|
      ) | 
						|
    } | 
						|
  }, | 
						|
  onLoad(res) { | 
						|
    if (res.scene) { | 
						|
      const data = decodeURIComponent(res.scene) | 
						|
      const obj = {} | 
						|
      data.split('&').forEach(i => { | 
						|
        const arr = i.split('=') | 
						|
        obj[arr[0]] = arr[1] | 
						|
      }) | 
						|
      this.inspectionsId = obj.inspectionsId | 
						|
      this.enterpriseId = obj.enterpriseId | 
						|
    } else { | 
						|
      this.inspectionsId = res.inspectionsId | 
						|
      this.enterpriseId = res.enterpriseId | 
						|
    } | 
						|
    this.share = { | 
						|
      title: '', | 
						|
      path: `/sub/task/locate?inspectionsId=${this.inspectionsId}&enterpriseId=${this.enterpriseId}`, | 
						|
      imageUrl: require('@/static/images/locateImage.png') | 
						|
    } | 
						|
    this.init() | 
						|
  }, | 
						|
  onReady() { | 
						|
    this.useAuth() | 
						|
  }, | 
						|
  onShareAppMessage() { | 
						|
    return this.share | 
						|
  }, | 
						|
  onShareTimeline() { | 
						|
    return this.share | 
						|
  }, | 
						|
  methods: { | 
						|
    async init() { | 
						|
      const miniCode = await getMiniCode({ | 
						|
        scene: `inspectionsId=${this.inspectionsId}&enterpriseId=${this.enterpriseId}`, | 
						|
        page: 'sub/task/locate', | 
						|
        check_path: false, | 
						|
        env_version: 'develop', | 
						|
        is_hyaline: true | 
						|
      }) | 
						|
      const enterprise = await getEnterPrise(this.enterpriseId) | 
						|
      this.enterprisesName = enterprise.data.enterprisesName | 
						|
      this.enterpriseGps = enterprise.data.gpsLocation | 
						|
      uni.setNavigationBarTitle({ | 
						|
        title: this.enterprisesName | 
						|
      }) | 
						|
      this.share.title = `执法签到-${this.enterprisesName}` | 
						|
      this.getLocateList() | 
						|
      this.miniCode = miniCode | 
						|
    }, | 
						|
    async getLocateList() { | 
						|
      const res = await InspectionsApi.getLocate(this.inspectionsId) | 
						|
      //找到专管员签到状态 | 
						|
      const isLead = res.data.findIndex(i => { | 
						|
        i.userId == this.$store.getters.userId && i.isInspect | 
						|
      }) | 
						|
      console.log(isLead) | 
						|
      this.list = res.data | 
						|
    }, | 
						|
    useAuth() { | 
						|
      const that = this | 
						|
      uni.getSetting({ | 
						|
        success: res => { | 
						|
          // 如果有授权直接获取位置,没有则拉起授权 | 
						|
          res.authSetting['scope.userLocation'] | 
						|
            ? _getLocation() | 
						|
            : _getAuth() | 
						|
        } | 
						|
      }) | 
						|
      /** | 
						|
       * 打开微信设置 | 
						|
       */ | 
						|
      function _getAuth() { | 
						|
        uni.authorize({ | 
						|
          scope: 'scope.userLocation', | 
						|
          success: res => { | 
						|
            _getLocation() | 
						|
          }, | 
						|
          fail: () => { | 
						|
            that.showModel = true | 
						|
          } | 
						|
        }) | 
						|
      } | 
						|
      function _getLocation() { | 
						|
        uni.getLocation({ | 
						|
          type: 'gcj02', | 
						|
          success: res => { | 
						|
            that.location = { | 
						|
              latitude: res.latitude, | 
						|
              longitude: res.longitude | 
						|
            } | 
						|
 | 
						|
            that.getDistance() | 
						|
          }, | 
						|
          fail: err => { | 
						|
            that.showTip = true | 
						|
            uni.showToast({ | 
						|
              icon: 'none', | 
						|
              title: '获取定位失败' | 
						|
            }) | 
						|
          } | 
						|
        }) | 
						|
      } | 
						|
    }, | 
						|
    openSetting() { | 
						|
      const that = this | 
						|
      uni.openSetting({ | 
						|
        success: res => { | 
						|
          that.showModel = false | 
						|
          that.useAuth() | 
						|
        } | 
						|
      }) | 
						|
    }, | 
						|
    getDistance() { | 
						|
      const that = this | 
						|
      const map = new TencentMap({ | 
						|
        key: 'PQ5BZ-GZ5C7-RTMXB-HSAPB-3TOAV-5CBLZ' | 
						|
      }) | 
						|
      map.calculateDistance({ | 
						|
        mode: 'straight', | 
						|
        form: this.location, | 
						|
        to: this.enterpriseGps, | 
						|
        success: res => { | 
						|
          that.distance = res.result.elements[0].distance | 
						|
        } | 
						|
      }) | 
						|
    }, | 
						|
    refresh() { | 
						|
      this.getDistance() | 
						|
      this.getLocateList() | 
						|
    }, | 
						|
    async locate() { | 
						|
      this.loading = true | 
						|
      const res = await InspectionsApi.locate({ | 
						|
        inspectionsId: this.inspectionsId | 
						|
      }) | 
						|
      this.loading = false | 
						|
      uni.showToast({ | 
						|
        icon: 'none', | 
						|
        title: res.data | 
						|
      }) | 
						|
      this.refresh() | 
						|
    } | 
						|
  } | 
						|
} | 
						|
</script> | 
						|
 | 
						|
<style lang="scss" scoped> | 
						|
.view-container { | 
						|
  height: 100vh; | 
						|
  padding: 12px; | 
						|
 | 
						|
  .box { | 
						|
    background-color: #fff; | 
						|
    border-radius: $cs-border-radius; | 
						|
    padding: 16px; | 
						|
    display: flex; | 
						|
    flex-flow: column nowrap; | 
						|
    gap: 12px; | 
						|
  } | 
						|
  .header { | 
						|
    display: flex; | 
						|
    align-items: center; | 
						|
    justify-content: space-between; | 
						|
    .refresh { | 
						|
      display: flex; | 
						|
      align-items: center; | 
						|
      gap: 4px; | 
						|
      color: $cs-color-main; | 
						|
      font-weight: bold; | 
						|
    } | 
						|
  } | 
						|
  .row { | 
						|
    border-radius: var(--Number-8px, 8px); | 
						|
    border: 1px solid var(--LightMode-Grey-Grey-100, #f9f9f9); | 
						|
    background: var(--LightMode-Light-Light, #fff); | 
						|
    padding: 16px; | 
						|
  } | 
						|
  .codeview { | 
						|
    display: flex; | 
						|
    justify-content: space-between; | 
						|
    .code { | 
						|
      width: 320rpx; | 
						|
      height: 320rpx; | 
						|
    } | 
						|
    .info { | 
						|
      display: flex; | 
						|
      flex-direction: column; | 
						|
      justify-content: space-between; | 
						|
      gap: 80rpx; | 
						|
    } | 
						|
  } | 
						|
} | 
						|
.locate-record { | 
						|
  display: flex; | 
						|
  justify-content: space-between; | 
						|
  .info { | 
						|
    display: flex; | 
						|
    justify-content: space-between; | 
						|
    align-items: center; | 
						|
    gap: 12px; | 
						|
  } | 
						|
} | 
						|
.emty { | 
						|
  display: flex; | 
						|
  flex-direction: column; | 
						|
  align-items: center; | 
						|
  gap: 12px; | 
						|
  padding: 24px 12px; | 
						|
  border-radius: 8px; | 
						|
  .image { | 
						|
    width: 64px; | 
						|
    height: 64px; | 
						|
  } | 
						|
} | 
						|
.operation { | 
						|
  padding: 12px; | 
						|
  display: flex; | 
						|
  align-items: center; | 
						|
  justify-content: center; | 
						|
  gap: 12px; | 
						|
  .btn { | 
						|
    flex: 1; | 
						|
    border-radius: 8px; | 
						|
    display: flex; | 
						|
    padding: 12px 0; | 
						|
    align-items: center; | 
						|
    justify-content: center; | 
						|
  } | 
						|
  .green { | 
						|
    background-color: $cs-color-main; | 
						|
    color: #fff; | 
						|
  } | 
						|
  .grey { | 
						|
    background: #f1f1f4; | 
						|
    color: #99a1b7; | 
						|
  } | 
						|
} | 
						|
.model-view { | 
						|
  height: 700rpx; | 
						|
  display: flex; | 
						|
  flex-direction: column; | 
						|
  align-items: center; | 
						|
  gap: 24px; | 
						|
  .image { | 
						|
    width: 470rpx; | 
						|
    height: 420rpx; | 
						|
  } | 
						|
  .open-setting { | 
						|
    padding: var(--Number-12px, 12px) var(--Number-48px, 48px); | 
						|
    gap: 10px; | 
						|
    border-radius: var(--Number-120px, 120px); | 
						|
    background: var(--LightMode-Success-Success, #17c653); | 
						|
    color: #fff; | 
						|
    font-size: 16px; | 
						|
    font-weight: 500; | 
						|
    /* Widget Shadow */ | 
						|
    box-shadow: 0px 3px 4px 0px rgba(0, 0, 0, 0.03); | 
						|
  } | 
						|
} | 
						|
.confirm-btn { | 
						|
  background-color: $cs-color-main; | 
						|
  padding: 12px 40px; | 
						|
  color: #fff; | 
						|
  font-size: 16px; | 
						|
  font-weight: 600; | 
						|
  border-radius: 120px; | 
						|
} | 
						|
.tip { | 
						|
  display: flex; | 
						|
  flex-flow: column nowrap; | 
						|
  gap: 24px; | 
						|
  .header { | 
						|
    display: flex; | 
						|
    flex-flow: column nowrap; | 
						|
    justify-content: center; | 
						|
    align-items: center; | 
						|
    color: #17c653; | 
						|
    font-style: italic; | 
						|
    font-weight: bold; | 
						|
  } | 
						|
  .info { | 
						|
    display: flex; | 
						|
    flex-flow: column nowrap; | 
						|
    justify-content: center; | 
						|
    align-items: center; | 
						|
    color: #071437; | 
						|
    gap: 16px; | 
						|
    .msg { | 
						|
      display: flex; | 
						|
      justify-content: center; | 
						|
      align-items: center; | 
						|
      gap: 4px; | 
						|
    } | 
						|
  } | 
						|
} | 
						|
</style>
 | 
						|
 |