| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633 | import React, { Component } from 'react'import { connect } from 'react-redux'import {Map, OpenData, View, Image, Text} from '@tarojs/components'import Taro from '@tarojs/taro';import {AtIcon, AtModal} from "taro-ui";import dayjs from 'dayjs';import Skeleton from 'taro-skeleton'import HistoricalClock from '../../components/historicalClock';import ImagePicker from '../../components/common/imagePicker';import { add, minus, asyncAdd } from '../../actions/counter'import {getPublicReleaseList,publicReleaseClockIn} from '../../utils/servers/servers';import './index.less'import switchIocn from '../../image/switch.png';import Location from '../../image/location.png';import PunchRange from '../../image/punchRange.png';import 'taro-ui/dist/style/components/noticebar.scss';import 'taro-ui/dist/style/components/icon.scss';import 'taro-ui/dist/style/components/list.scss';import {getClockState} from "../../utils/tools";const QQMapWX = require('../../components/common/mapSDK/qqmap-wx-jssdk.min.js');@connect(({ counter }) => ({  counter}), (dispatch) => ({  add () {    dispatch(add())  },  dec () {    dispatch(minus())  },  asyncAdd () {    dispatch(asyncAdd())  }}))class PunchClocks extends Component {  constructor(props) {    super(props);    this.state={      imgs:[],      nowTime:'00:00:00',      newArrder:{},      addressLatitude:'',      addressLongitude:'',      distance:'',      dtails:{},      loading:true    }    this.onChange = this.onChange.bind(this);    this.getSpacing = this.getSpacing.bind(this);    this.getPublicReleaseList = this.getPublicReleaseList.bind(this);    this.publicReleaseClockIn = this.publicReleaseClockIn.bind(this);    this.refresh = this.refresh.bind(this);    this.getDtails = this.getDtails.bind(this);  }  nowTime = null;  wxConfig= null;  mapCtx = Taro.createMapContext('map');  qqmapsdk = new QQMapWX({    key: 'AWBBZ-GRAC2-JFYUO-CLA7I-JAHXK-YFFGT'  });  componentDidMount(){    this.getDtails();  }  getDtails(){    this.getPublicReleaseList(()=>{      Taro.startLocationUpdate({        success:()=>{          Taro.onLocationChange((v)=>{            this.getSpacing(v.latitude,v.longitude)          })        },        fail:(err)=>{          console.log(err,'err')          Taro.getSetting({            success:(res)=>{              if (!res.authSetting['scope.userLocation']) {                Taro.authorize({                  scope: 'scope.userLocation',                  success:()=>{                  },                  fail:()=>{                    this.setState({                      isOpened:true                    })                  }                })              }            }          })          this.setState({            loading:false          })        }      })    });  }  componentWillMount() {    this.wxConfig = Taro.getStorageSync('wxConfig');    //获得当前位置    Taro.getLocation({      type: 'gcj02',      isHighAccuracy:true,      success: (res)=> {        const latitude = res.latitude        const longitude = res.longitude        this.setState({          newArrder:{            latitude,            longitude          },        })      }    })    this.nowTime = setInterval(()=>{      this.setState({        nowTime:dayjs().format('HH:mm:ss')      })    },1000)    Taro.eventCenter.on('punchClockComponentDidShow', () => {      if(Object.keys(this.state.dtails).length === 0){        this.getDtails();      }    })    Taro.eventCenter.on('GoPunchIn', (arg) => {      this.setState({        dtails:arg,        addressLatitude:parseFloat(arg.latitude),        addressLongitude:parseFloat(arg.longitude),      },()=>{        Taro.showToast({title:'切换成功'});        Taro.startLocationUpdate({          success:()=>{            Taro.onLocationChange((v)=>{              this.getSpacing(v.latitude,v.longitude)            })          },          fail:()=>{            this.setState({              loading:false            })          }        })      })    })  }  componentDidHide() {    Taro.offLocationChange();    this.nowTime && this.nowTime.clearTimeout();  }  publicReleaseClockIn(){    if(this.state.dtails.status === 3){      Taro.hideLoading()      Taro.showToast({title:'申请已撤销,无法打卡',icon:'none'});      return ;    }    if(Object.keys(this.state.dtails).length === 0){      Taro.hideLoading()      Taro.showToast({title:'暂无公出申请,无法打卡',icon:'none'});      return ;    }    if(isNaN(parseInt(this.state.distance))){      Taro.hideLoading()      Taro.showToast({title:'定位错误,请联系管理员',icon:'none'})      return ;    }    if(dayjs().isBefore(this.state.dtails.releaseStarts) || dayjs().isAfter(this.state.dtails.releaseEnds)){      Taro.hideLoading()      Taro.showToast({title:'当前时间不在打卡时间范围内,无法打卡',icon:'none'})      return ;    }    if(!(this.state.distance <=this.wxConfig.clockInRange && this.state.distance >= 0)){      Taro.hideLoading()      Taro.showToast({title:'当前位置未处于可打卡范围,无法打卡',icon:'none'})      return ;    }    if(this.state.imgs.length === 0){      Taro.hideLoading()      Taro.showToast({title:'请上传打卡照片',icon:'none'})      return ;    }    publicReleaseClockIn({      id:this.state.dtails.id,      photoUrl:this.state.imgs.join(',')    }).then(v=>{      Taro.hideLoading()      if(v.error.length === 0){        Taro.showToast({title:'打卡成功',icon:'none'});        this.imagePicker.clear();        this.state.dtails.clockIn = 1;        this.setState({          dtails:this.state.dtails,          imgs:[]        })      }else{        Taro.showToast({title:v.error[0].message,icon:'none'})      }    }).catch(()=>{      Taro.hideLoading()      Taro.showToast({        title:'系统错误,请稍后再试',        icon:'none'      })    })  }  getPublicReleaseList(fn){    this.setState({      loading:true    })    getPublicReleaseList({      type:0,      clockTime:dayjs().format('YYYY-MM-DD HH:mm:ss')    }).then(v=>{      if(v.error.length === 0){        if(v.data.list.length === 0){          getPublicReleaseList({            type:0,          }).then(value=>{            if(value.error.length === 0){              if(value.data.list.length === 0){                this.setState({                  dtails: {},                  loading:false                })              }else{                this.setState({                  dtails:value.data.list[0],                  addressLatitude:value.data.list[0].latitude,                  addressLongitude:value.data.list[0].longitude,                },()=>{                  fn();                })              }            }else{              this.setState({                loading:false              })              Taro.showToast({                title:v.error[0].message,                icon:'none'              })            }          }).catch(()=>{            this.setState({              loading:false            })            Taro.showToast({              title:'系统错误,请稍后再试',              icon:'none'            })          })        }else{          this.setState({            dtails:v.data.list[0],            addressLatitude:v.data.list[0].latitude,            addressLongitude:v.data.list[0].longitude,          },()=>{            fn();          })        }      }else{        this.setState({          loading:false        })        Taro.showToast({          title:v.error[0].message,          icon:'none'        })      }    }).catch((err)=>{      console.log(err)      this.setState({        loading:false      })      Taro.showToast({        title:'系统错误,请稍后再试',        icon:'none'      })    })  }  getSpacing(latitude,longitude){    let _this = this;    this.qqmapsdk.calculateDistance({      mode:'straight',      from: {        latitude: this.state.addressLatitude,        longitude: this.state.addressLongitude,      },      to: [        {          latitude,          longitude,        }      ],      success: function(res) {//成功后的回调        _this.setState({          distance:res.result.elements[0].distance,          loading:false        })      },      fail: function(error) {        _this.setState({          loading:false        })        console.error(error);      },      complete: function(res) {      }    });  }  onChange(value,type){    let arr = this.state.imgs.concat([]);    if(type === 'add'){      arr.push(value)    }else if(type === 'remove'){      arr.splice(value,1)    }    this.setState({      imgs: arr,    })  }  refresh(){    this.getPublicReleaseList(()=>{      Taro.startLocationUpdate({        success:()=>{          Taro.onLocationChange((v)=>{            this.getSpacing(v.latitude,v.longitude)          })        }      })    });  }  render () {    const {dtails} = this.state;    return (      <View className='punchClock'>        <View className='header'>          <Skeleton            title            avatar            row={1}            animateName='elastic'            avatarShape='square'            loading={this.state.loading}          >            <View className='headerContent'>              <View className='userAvatarUrl'>                <OpenData type='userAvatarUrl'/>              </View>              <View className='infor'>                <View className='name'>                  {                    Object.keys(this.state.dtails).length <= 0 ?                      Taro.getStorageSync('userInfor').name:                      dtails.aname                  }                </View>                <View className='address'>                  公出企业:                  <View className='nickname'>                    {                      Object.keys(this.state.dtails).length <= 0 ?                        '无':                        dtails.nickname                    }                  </View>                </View>              </View>              {                Object.keys(this.state.dtails).length <= 0 ?                  <View onClick={this.refresh} className='state' style={{                    alignSelf: 'center',                    textAlign:'center',                    color:'#b6b5b5',                    fontSize:'11px'                  }}>                    <AtIcon value='reload' size='20'/>                    <View>刷新</View>                  </View> :                  <View className='state' style={{                    color:getClockState(dtails.status).color                  }}>                    <View style={{textAlign:'right'}}>                      {                        getClockState(dtails.status).title                      }                    </View>                    <View className='switchContent' onClick={()=>{                      Taro.switchTab({                        url: '/pages/examine/index',                      })                    }}>                      <View className='switchTitle'>切换打卡</View>                      <Image src={switchIocn} className='switchItem'/>                    </View>                  </View>              }            </View>          </Skeleton>        </View>        {          Object.keys(this.state.dtails).length <= 0 ?            <View className='content'>              <View className='punchClockContent'  onClick={this.publicReleaseClockIn} style={{                boxShadow:  '1px 1px 15px 1px #acb8ad',                background: '#828e83',                marginTop: '85px',              }}>                <View className='punchClockTitle'>公出打卡</View>                <View className='punchClockTime'>{this.state.nowTime}</View>              </View>              <View className='noData'>                <View className='tipsNoData'>                  暂无公出申请                </View>                <View className='goOut' onClick={()=>{                  Taro.switchTab({                    url: '/pages/applyDepart/index',                  })                }}>                  点击前往申请公出                </View>              </View>            </View>:            <View>              <View className='content'>                <View className='timeContent'>                  <View className='timeItem'>                    <View className='timeTitle'>公出开始时间</View>                    <View className='timeValue'>{dtails.releaseStarts}</View>                  </View>                  <View className='timeItem'>                    <View className='timeTitle'>公出结束时间</View>                    <View className='timeValue'>{dtails.releaseEnds}</View>                  </View>                </View>                <View className='photographContent'>                  <View className='photographTitle'>打卡拍照<Text className='tips'>〔可以上传多张〕</Text></View>                  <AtIcon onClick={()=>{                    Taro.chooseImage({                      count: 1,                      sizeType: ['compressed'],                      sourceType: ['camera'],                      success:(res)=> {                        // tempFilePath可以作为img标签的src属性显示图片                        const tempFilePaths = res.tempFilePaths                        this.imagePicker.onImgChange([{url:tempFilePaths[0]}],'add',0,'camera')                      }                    })                  }} value='camera' size='25' color='#4395ff'/>                </View>                <View style={{alignSelf:'flex-start',width:'100%'}}>                  <ImagePicker ref={ref => this.imagePicker = ref} url='/api/admin/release/upload' showAddBtn={false} onChange={this.onChange}/>                </View>                <View className='punchClockContent' onClick={()=>{                  let _this = this;                  Taro.showLoading({title:'加载中...'})                  Taro.getSetting({                    success:(res)=>{                      if (!res.authSetting['scope.userLocation']) {                        Taro.authorize({                          scope: 'scope.userLocation',                          success:()=>{                            _this.publicReleaseClockIn();                          },                          fail:()=>{                            Taro.hideLoading()                            this.setState({                              isOpened:true                            })                          }                        })                      }else{                        _this.publicReleaseClockIn();                      }                    }                  })                }} style={{                  boxShadow:                    (!isNaN(parseInt(this.state.distance)))                    && this.state.distance <=this.wxConfig.clockInRange && this.state.distance >= 0 &&                    !(dayjs().isBefore(this.state.dtails.releaseStarts) || dayjs().isAfter(this.state.dtails.releaseEnds)) &&                    dtails.status !== 3                      ? (dtails.clockIn === 1 ? '1px 1px 15px 1px #3f82e8' : '1px 1px 15px 1px #659268') : '1px 1px 15px 1px #828e83',                  background: (!isNaN(parseInt(this.state.distance)))                  &&                  this.state.distance <=this.wxConfig.clockInRange &&                  this.state.distance >= 0 &&                  !(dayjs().isBefore(this.state.dtails.releaseStarts) || dayjs().isAfter(this.state.dtails.releaseEnds))&&                  dtails.status !== 3                    ? (dtails.clockIn === 1 ? '#3f82e8' : '#72cb78') : '#828e83'                }}>                  <View className='punchClockTitle'>                    {                      dtails.clockIn === 1 ?                        '刷新打卡' : '公出打卡'                    }                  </View>                  <View className='punchClockTime'>{this.state.nowTime}</View>                </View>                <View className='map'>                  <View className='locationContent'>                    <View className='location' onClick={()=>{                      this.mapCtx.moveToLocation();                    }}>                      <Image src={Location} className='locationIcon'/>                    </View>                    <View className='punchRange' onClick={()=>{                      this.mapCtx.moveToLocation({                        latitude: this.state.addressLatitude,                        longitude: this.state.addressLongitude,                      });                    }}>                      <Image src={PunchRange} className='punchRangeIcon'/>                    </View>                  </View>                  <Map                    id='map'                    {...this.state.newArrder}                    circles={[                      {                        latitude: this.state.addressLatitude,                        longitude: this.state.addressLongitude,                        color: '#c92ddc82',                        fillColor: '#c92ddc82',                        radius: this.wxConfig.clockInRange,                        strokeWidth: 1                      }                    ]}                    showLocation                  />                </View>                <View className='tips'>紫色区域为可打卡区域</View>              </View>              <View className='content' onClick={()=>{                this.setState({                  historicalIsOpened:true                })              }}>                <View className='history'>                  <View>查看公出申请日志</View>                  <AtIcon value='chevron-right' size='20' color='#767272'/>                </View>              </View>            </View>        }        <AtModal          isOpened={this.state.isOpened}          title='提醒'          cancelText='取消'          confirmText='确认'          onClose={()=>{            this.setState({              isOpened:false,            })          }}          onCancel={()=>{            this.setState({              isOpened:false,            })          }}          onConfirm={()=>{            this.setState({              isOpened:false,            },()=>{              Taro.openSetting({                success:(value)=> {                  if(value.authSetting['scope.userLocation']){                    Taro.getLocation({                      type: 'gcj02',                      isHighAccuracy:true,                      success: (res)=> {                        const latitude = res.latitude                        const longitude = res.longitude                        this.setState({                          newArrder:{                            latitude,                            longitude                          },                        })                      }                    })                    this.getDtails();                  }                }              })            })          }}          content='您拒绝了定位权限,请先前往设置打开定位权限'        />        {this.state.historicalIsOpened ? <HistoricalClock          id={dtails.id}          isOpened={this.state.historicalIsOpened}          onClose={()=>{            this.setState({              historicalIsOpened:false            })          }}        /> : null}      </View>    )  }}export default PunchClocks
 |