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.
543 lines
14 KiB
543 lines
14 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="!isLocate"> |
|
<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> |
|
|
|
<cs-bottom-wrapper v-if="isLocate && isLeadLocate"> |
|
<view class="operation"> |
|
<view class="btn grey" v-if="list.length < 2">开始执法</view> |
|
<button class="btn green" v-else :loading="loading" @tap="goNext"> |
|
开始执法 |
|
</button> |
|
</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 { getMiniCode } from '@/utils/getCode.js' |
|
import { InspectionsApi } from '@/api/inspections/index.js' |
|
import { getEnterPrise } from '@/api/enterprise/index.js' |
|
import { getMiniCode as getMiniappCode } from '@/api/login.js' |
|
export default { |
|
data() { |
|
return { |
|
showModel: false, |
|
inspectionsId: '', |
|
miniCode: '', |
|
enterpriseGps: '', |
|
location: {}, |
|
distance: 10000, |
|
radius: 1000, // 打卡范围 |
|
showTip: false, |
|
list: [], |
|
loading: false, |
|
share: { |
|
title: '', |
|
path: '', |
|
imageUrl: '' |
|
}, |
|
isLeadLocate: false, |
|
isLocate: true, |
|
timer: null, |
|
time: 0 |
|
} |
|
}, |
|
async 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.aId |
|
this.enterpriseId = obj.bId |
|
} else { |
|
this.inspectionsId = res.inspectionsId |
|
this.enterpriseId = res.enterpriseId |
|
} |
|
this.share = { |
|
title: '', |
|
path: `/sub/task/locate?inspectionsId=${this.inspectionsId}&enterpriseId=${this.enterpriseId}`, |
|
imageUrl: |
|
'http://82.156.141.150:9001/api/v1/download-shared-object/aHR0cDovL2xvY2FsaG9zdDo5MDAwL2h1YW5iYW8vbWluaWFwcC9pbnZhdGUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUQxODY1RVA2NEczMEdEUUhDVTglMkYyMDI1MDIxOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMThUMDcyMDI0WiZYLUFtei1FeHBpcmVzPTQzMTk5JlgtQW16LVNlY3VyaXR5LVRva2VuPWV5SmhiR2NpT2lKSVV6VXhNaUlzSW5SNWNDSTZJa3BYVkNKOS5leUpoWTJObGMzTkxaWGtpT2lKQlJERTROalZGVURZMFJ6TXdSMFJSU0VOVk9DSXNJbVY0Y0NJNk1UY3pPVGt3TmpJME55d2ljR0Z5Wlc1MElqb2lZV1J0YVc0aWZRLmp6djBhdEY5QVBYXzVjYWg4c18yeXhVV3oxek9BekFzSVdzemVrUmZwcXlHd0RPWkptazlUSGJRUnBDdVNmLVMyU0otWTI1cldUd2hpNUlrY0xBSThRJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZ2ZXJzaW9uSWQ9bnVsbCZYLUFtei1TaWduYXR1cmU9MjcxZTkzOTE1MDkwYzUzYmRjYTg0MjQ1MTJhYjk3ZWQxZWMyN2QzM2MwM2U3NGUwYmRhNTBmYjQyNWI0N2MyOQ' |
|
} |
|
await this.init() |
|
}, |
|
onShareAppMessage() { |
|
return this.share |
|
}, |
|
onShareTimeline() { |
|
return this.share |
|
}, |
|
onShow() { |
|
this.useAuth() |
|
// this.refresh() |
|
// this.echoQueset() |
|
}, |
|
onHide() { |
|
this.timer && clearInterval(this.timer) |
|
}, |
|
onUnload() { |
|
this.timer && clearInterval(this.timer) |
|
}, |
|
onBackPress() { |
|
this.timer && clearInterval(this.timer) |
|
return false |
|
}, |
|
watch: { |
|
list: { |
|
handler: function (val) { |
|
if (val.length >= 2) { |
|
this.timer && clearInterval(this.timer) |
|
} |
|
}, |
|
immediate: true, |
|
deep: true |
|
} |
|
}, |
|
methods: { |
|
async init() { |
|
const res = await getMiniappCode({ |
|
scene: `aId=${this.inspectionsId}&bId=${this.enterpriseId}`, |
|
path: 'sub/task/locate', |
|
checkPath: false, |
|
envVersion: 'develop', |
|
isHyaline: true |
|
}) |
|
this.miniCode = `data:image/jpeg;base64,${res.data}` |
|
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.echoQueset() |
|
}, |
|
async getLocateList() { |
|
const res = await InspectionsApi.getLocate(this.inspectionsId) |
|
const locate = res.data.find(i => { |
|
return i.userId == this.$store.getters.userId |
|
}) |
|
if (locate) { |
|
// 签到状态 |
|
this.isLocate = true |
|
// 专管员签到状态 |
|
if (locate.isInspect) this.isLeadLocate = true |
|
} else { |
|
this.isLocate = false |
|
} |
|
this.list = res.data |
|
}, |
|
useAuth() { |
|
const that = this |
|
uni.getSetting({ |
|
success: res => { |
|
// 如果有授权直接获取位置,没有则拉起授权 |
|
res.authSetting['scope.userLocation'] |
|
? _getLocation() |
|
: _getAuth() |
|
}, |
|
fail: err => { |
|
uni.showToast({ |
|
icon: 'none', |
|
title: '获取设置失败' |
|
}) |
|
console.log(err) |
|
} |
|
}) |
|
/** |
|
* 打开微信设置 |
|
*/ |
|
function _getAuth() { |
|
uni.authorize({ |
|
scope: 'scope.userLocation', |
|
success: res => { |
|
_getLocation() |
|
}, |
|
fail: () => { |
|
that.showModel = true |
|
} |
|
}) |
|
} |
|
function _getLocation() { |
|
uni.getLocation({ |
|
type: 'gcj02', |
|
success: res => { |
|
console.log('location', res.latitude, res.longitude) |
|
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() |
|
} |
|
}) |
|
}, |
|
async getDistance() { |
|
if (this.enterpriseGps) { |
|
uni.showLoading({ |
|
title: '正在计算位置...' |
|
}) |
|
const that = this |
|
this.$map.calculateDistance({ |
|
mode: 'straight', |
|
form: this.location, |
|
to: this.enterpriseGps, |
|
success: res => { |
|
that.distance = res.result.elements[0].distance |
|
console.log('distance', that.distance) |
|
uni.hideLoading() |
|
}, |
|
fail: err => { |
|
console.log('获取定位失败', err) |
|
uni.hideLoading() |
|
} |
|
}) |
|
} else { |
|
await this.init() |
|
this.getDistance() |
|
} |
|
}, |
|
refresh() { |
|
this.getDistance() |
|
this.getLocateList() |
|
this.echoQueset() |
|
}, |
|
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() |
|
}, |
|
echoQueset() { |
|
const timeout = 3 * 60 * 1000 |
|
// const timeout = 10 * 1000 |
|
this.timer && clearInterval(this.timer) |
|
this.timer = setInterval(() => { |
|
this.getLocateList() |
|
this.time += 5000 |
|
if (this.time > timeout) { |
|
console.log('timeout') |
|
clearInterval(this.timer) |
|
uni.navigateBack({ |
|
delta: 1 |
|
}) |
|
} |
|
}, 5 * 1000) |
|
}, |
|
goNext() { |
|
InspectionsApi.beginEnforce({ |
|
inspectionsId: this.inspectionsId |
|
}).then(res => { |
|
uni.navigateBack({ |
|
delta: 1 |
|
}) |
|
}) |
|
} |
|
} |
|
} |
|
</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>
|
|
|