Browse Source

消息通知

HW 3 years ago
parent
commit
a9084d5da6

+ 13 - 8
src/app.jsx

@@ -19,9 +19,19 @@ class App extends Component {
 
   componentDidShow () {
     Taro.eventCenter.on('getStorageSync', () => {
-      this.getStorageSync();
+      let token = Taro.getStorageSync('token');
+      if(token){
+        this.getStorageSync();
+      }
     })
-    this.getStorageSync();
+    let token = Taro.getStorageSync('token');
+    if(token){
+      this.getStorageSync();
+    }
+  }
+
+  componentDidHide(){
+    Taro.closeSocket();
   }
 
   getStorageSync(){
@@ -39,15 +49,12 @@ class App extends Component {
     //连接成功
     Taro.onSocketOpen(function() {
       console.log('连接成功')
-      // Taro.sendSocketMessage({
-      //   data: 'stock',
-      // })
     })
 
     //接收数据
     Taro.onSocketMessage(function(data) {
       console.log(data,'接收数据')
-      Taro.eventCenter.trigger('GoPuncsshIn')
+      Taro.eventCenter.trigger('GoPuncsshIn',data)
     })
 
     //连接失败
@@ -61,8 +68,6 @@ class App extends Component {
     })
   }
 
-  componentDidHide () {}
-
   componentDidCatchError () {}
 
   // 在 App 类中的 render() 函数没有实际作用

+ 56 - 16
src/components/common/messageNoticebar/index.jsx

@@ -1,21 +1,26 @@
 import React,{Component} from "react";
-import {View} from '@tarojs/components'
+import {View,Text} from '@tarojs/components'
 import Taro from '@tarojs/taro';
-import { AtIcon  } from 'taro-ui'
+import { AtIcon,AtNoticebar  } from 'taro-ui'
 import './index.less';
+import  {getPublicReleaseUnread} from '../../../utils/servers/servers';
 
 import "taro-ui/dist/style/components/icon.scss";
+import "taro-ui/dist/style/components/noticebar.scss";
 
 class MessageNoticebar extends Component{
   constructor(props) {
     super(props);
     this.state={
-      animationData:{}
+      animationData:{},
+      isOpend:true,
+      str:''
     }
     this.onClose = this.onClose.bind(this);
+    this.getPublicReleaseUnread = this.getPublicReleaseUnread.bind(this);
   }
 
-  componentDidMount () {
+  componentWillMount () {
     let animation = Taro.createAnimation({
       duration: 1000,
       timingFunction: 'ease',
@@ -28,29 +33,64 @@ class MessageNoticebar extends Component{
     })
 
 
-    Taro.eventCenter.on('GoPuncsshIn', () => {
-      this.animation.translateX(-235).step()
-      this.setState({
-        animation: this.animation.export()
-      })
+    Taro.eventCenter.on('GoPuncsshIn', (data) => {
+      if(data.data === 'unread'){
+        this.getPublicReleaseUnread();
+      }
     })
   }
 
   onClose(){
-    this.animation.translateX(235).step()
+    this.animation.opacity(0).step()
     this.setState({
-      animation: this.animation.export()
+      animation: this.animation.export(),
+      isOpend:false,
+      str:''
+    })
+  }
+
+  getPublicReleaseUnread(){
+    getPublicReleaseUnread({}).then(v=>{
+      if(v.error.length === 0){
+        let str = '';
+        for(let i of v.data){
+          str+=i.content+'              '
+        }
+        this.setState({
+          str:str
+        },()=>{
+          this.animation.opacity(1).step()
+          this.setState({
+            animation: this.animation.export(),
+            isOpend:true
+          })
+        })
+      }else{
+        Taro.showToast({title:v.error[0].message,icon:'none'})
+      }
+    }).catch(()=>{
+      Taro.showToast({
+        title:'系统错误,请稍后再试',
+        icon:'none'
+      })
     })
   }
 
   render() {
     return (
       <View className='messageNoticebar' animation={this.state.animation}>
-        <View className='title'>
-          <View>消息通知</View>
-          <AtIcon value='close' size='10' onClick={this.onClose}/>
-        </View>
-        <View className='messageNoticebarContent'>内容1内容1内容1内容1内容1内容1内容1内容1内容1</View>
+        {this.state.isOpend ? <View className='content'>
+              <View style={{width:'100%'}}>
+                <AtNoticebar speed='50' icon='volume-plus' marquee>
+                  <Text decode>
+                    {this.state.str}
+                  </Text>
+                </AtNoticebar>
+              </View>
+              <View className='noticebar' onClick={this.onClose}>
+                <AtIcon value='close' size='10'/>
+              </View>
+        </View> : null}
       </View>
     )
   }

+ 13 - 16
src/components/common/messageNoticebar/index.less

@@ -1,25 +1,22 @@
 .messageNoticebar{
-  padding: 20px 35px;
-  background: #FFF;
   box-shadow: 1px 1px 14px -1px #767272;
-  border-top-left-radius: 30px;
-  border-bottom-left-radius: 30px;
   position: fixed;
-  right: -470px;
-  top: 30px;
+  left: 0;
+  right: 0;
+  top: 0;
   z-index: 99999;
-  .title{
+  opacity:0;
+  background: #FCF6ED;
+  .content{
     display: flex;
     flex-flow: row nowrap;
-    justify-content: space-between;
     align-items: center;
-    font-size: 30px;
-    font-weight: bolder;
-    padding-bottom: 20px;
-  }
-  .messageNoticebarContent{
-   font-size: 25px;
-   color: #767272;
-    width: 400px;
+    position: relative;
+    .noticebar{
+      position: absolute;
+      z-index: 1;
+      right: 20px;
+      bottom:15px
+    }
   }
 }

+ 7 - 1
src/components/common/userFloatingLayer/index.jsx

@@ -29,8 +29,14 @@ class UserFloatingLayer extends Component{
           <OpenData type='userAvatarUrl'/>
         </View>
         <View className='userNickName'>
-          <View className='welcome'>欢迎您</View>
           {this.state.userInfor.name}
+          <View className='welcome' onClick={()=>{
+            Taro.setStorageSync("token", "");
+            Taro.setStorageSync('userInfor', "");
+            Taro.navigateTo({
+              url: '/pages/login/index'
+            })
+          }}>退出</View>
         </View>
       </View>
     );

+ 3 - 2
src/components/common/userFloatingLayer/index.less

@@ -13,10 +13,11 @@
     border-radius: 100px;
     overflow: hidden;
     border: 1px #FFFFFF solid;
+    z-index: 2;
   }
   .userNickName{
     position: absolute;
-    z-index: -1;
+    z-index: 1;
     top: 0;
     left: 20px;
     padding: 20px 30px 20px 80px;
@@ -27,7 +28,7 @@
     display: flex;
     align-items: center;
     .welcome{
-      padding-right: 15px;
+      padding-left: 15px;
     }
   }
 }

+ 4 - 2
src/pages/applyDepart/index.jsx

@@ -1,4 +1,4 @@
-import { Component } from 'react'
+import React, { Component } from 'react'
 import { connect } from 'react-redux'
 import {View} from '@tarojs/components'
 import { AtSteps,AtTabs, AtTabsPane } from 'taro-ui'
@@ -16,6 +16,7 @@ import Result from './result';
 
 import './index.less'
 import Taro from '@tarojs/taro';
+import MessageNoticebar from "../../components/common/messageNoticebar";
 
 const items = [
   { 'title': '选择公出企业' },
@@ -40,7 +41,7 @@ class ApplyDepart extends Component {
   constructor(props) {
     super(props);
     this.state={
-      current:1,
+      current:0,
       enterpriseInfor:{},
       selectArrderLocation:{},
       resultState:0
@@ -90,6 +91,7 @@ class ApplyDepart extends Component {
   render () {
     return (
       <View className='applyDepart'>
+        <MessageNoticebar/>
         <UserFloatingLayer/>
         <View className='atStepsContent'>
           <AtSteps

+ 20 - 5
src/pages/egressDetails/index.jsx

@@ -21,6 +21,7 @@ import Reviewed from '../../image/reviewed.png';
 import ImagePicker from "../../components/common/imagePicker";
 
 import switchIocn from '../../image/switch.png';
+import MessageNoticebar from "../../components/common/messageNoticebar";
 
 class EgressDetails extends Component{
 
@@ -146,6 +147,7 @@ class EgressDetails extends Component{
     const {dtails} = this.state;
     return (
       <View className='egressDetails'>
+        <MessageNoticebar/>
         <View className='titleContent'>
           <View className='title'>{dtails.aname}提交的公出申请</View>
           <View className='address'>
@@ -201,7 +203,8 @@ class EgressDetails extends Component{
             <View className='timeContent'>
               <View className='time'>
                 <View className='num'>公出{dtails.duration}小时</View>
-                <View className='journal' onClick={()=>{
+                <View className='journal' onClick={(e)=>{
+                  e.stopPropagation();
                   this.setState({
                     isDetailedOpened:true
                   })
@@ -220,7 +223,11 @@ class EgressDetails extends Component{
               </View>
             </View>
           </View>
-          <AtModal isOpened={this.state.isDetailedOpened}>
+          <AtModal onClose={()=>{
+            this.setState({
+              isDetailedOpened:false
+            })
+          }} isOpened={this.state.isDetailedOpened}>
            <AtModalContent>
              {dtails.validDate ?  <AtCalendar
                   isSwiper={false}
@@ -261,6 +268,7 @@ class EgressDetails extends Component{
               <View className='item'>
                 <View className='title'>填写审批意见</View>
                 <AtTextarea
+                  disabled={dtails.status !== 1}
                   value={this.state.opinion}
                   onChange={(value)=>{
                     this.setState({
@@ -273,7 +281,7 @@ class EgressDetails extends Component{
               </View> : null
           }
           {
-            this.$instance.router.params.type === '1' ?
+            this.$instance.router.params.type === '1' && dtails.status === 1 ?
               <View className='operation'>
                 <AtButton type='secondary' circle loading={this.state.loading} onClick={()=>{
                   this.examinePublicRelease(0);
@@ -288,11 +296,18 @@ class EgressDetails extends Component{
               </View> : null
           }
         </View>
-        <View className='valueContent history' onClick={this.getListPublicReleaseLog}>
+        <View className='valueContent history' onClick={(e)=>{
+          e.stopPropagation();
+          this.getListPublicReleaseLog();
+        }}>
           查看TA的历史记录
           <AtIcon value='chevron-right' size='20' color='#767272'/>
         </View>
-        <AtModal isOpened={this.state.isOpened}>
+        <AtModal onClose={()=>{
+          this.setState({
+            isOpened:false
+          })
+        }} isOpened={this.state.isOpened}>
           <AtModalContent>
             <AtTimeline
               pending

+ 3 - 1
src/pages/examine/index.jsx

@@ -1,4 +1,4 @@
-import { Component } from 'react';
+import React, { Component } from 'react';
 import Taro from '@tarojs/taro';
 import { View } from '@tarojs/components'
 import { getPublicReleaseList } from '../../utils/servers/servers';
@@ -9,6 +9,7 @@ import './index.less';
 import 'taro-ui/dist/style/components/tabs.scss';
 
 import MyList from './myList';
+import MessageNoticebar from "../../components/common/messageNoticebar";
 
 class Examine extends Component {
 
@@ -137,6 +138,7 @@ class Examine extends Component {
   render () {
     return (
       <View className='indexPage'>
+        <MessageNoticebar/>
         <AtTabs current={this.state.current || 0} tabList={[{ title: '我的' }, { title: '审核' }]} onClick={(current)=>{
           this.setState({
             current

+ 4 - 1
src/pages/login/index.jsx

@@ -147,7 +147,10 @@ class Login extends Component {
                   url: '/pages/punchClock/index',
                 })
               }else{
-                Taro.showToast({title:v.error[0].message,icon:'none'})
+                Taro.showToast({
+                  title:v.error[0].message,
+                  icon:'none',
+                })
               }
             })
           },

+ 9 - 449
src/pages/punchClock/index.jsx

@@ -1,460 +1,20 @@
-import React, { Component } from 'react'
-import { connect } from 'react-redux'
-import {Map, OpenData, View, Image} from '@tarojs/components'
-import Taro from '@tarojs/taro';
-import {AtIcon} from "taro-ui";
-import dayjs from 'dayjs';
-import Skeleton from 'taro-skeleton'
+import React,{Component} from "react";
+import PunchClocks from './punchClocks';
+import MessageNoticebar from "../../components/common/messageNoticebar";
 
-import ImagePicker from '../../components/common/imagePicker';
-import MessageNoticebar from '../../components/common/messageNoticebar';
-
-import { add, minus, asyncAdd } from '../../actions/counter'
-
-import {getPublicReleaseList,publicReleaseClockIn} from '../../utils/servers/servers';
-
-import './index.less'
-
-import switchIocn from '../../image/switch.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';
-
-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 PunchClock extends Component {
+class PunchClock 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);
-  }
-
-  nowTime = null;
-
-  qqmapsdk = new QQMapWX({
-    key: 'AWBBZ-GRAC2-JFYUO-CLA7I-JAHXK-YFFGT'
-  });
-
-  componentWillUnmount() {
-    Taro.offLocationChange();
-    this.nowTime && this.nowTime.clearTimeout();
-  }
-
-  componentDidMount(){
-    this.getPublicReleaseList(()=>{
-      Taro.startLocationUpdate({
-        success:()=>{
-          Taro.onLocationChange((v)=>{
-            this.getSpacing(v.latitude,v.longitude)
-          })
-        },
-        fail:()=>{
-          this.setState({
-            loading:false
-          })
-        }
-      })
-    });
-  }
-
-  componentDidShow() {
-
-    //获得当前位置
-    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('GoPunchIn', (arg) => {
-      console.log(arg,'222')
-      this.setState({
-        dtails:arg,
-        addressLatitude:parseFloat(arg.latitude),
-        addressLongitude:parseFloat(arg.longitude),
-      },()=>{
-        Taro.startLocationUpdate({
-          success:()=>{
-            Taro.onLocationChange((v)=>{
-              this.getSpacing(v.latitude,v.longitude)
-            })
-          },
-          fail:()=>{
-            this.setState({
-              loading:false
-            })
-          }
-        })
-      })
-    })
-
-  }
-
-  publicReleaseClockIn(){
-    if(Object.keys(this.state.dtails).length === 0){
-      Taro.showToast({title:'暂无公出申请,无法打卡',icon:'none'})
-      return ;
-    }
-    if(isNaN(parseInt(this.state.distance))){
-      Taro.showToast({title:'定位错误,请联系管理员',icon:'none'})
-      return ;
-    }
-    if(!(this.state.distance <=50 && this.state.distance >= 0)){
-      Taro.showToast({title:'当前位置未处于可打卡范围,无法打卡',icon:'none'})
-      return ;
-    }
-    if(this.state.imgs.length === 0){
-      Taro.showToast({title:'请上传打卡照片',icon:'none'})
-      return ;
-    }
-    publicReleaseClockIn({
-      id:this.state.dtails.id,
-      photoUrl:this.state.imgs.join(',')
-    }).then(v=>{
-      if(v.error.length === 0){
-        Taro.showToast({title:'打卡成功',icon:'none'})
-      }else{
-        Taro.showToast({title:v.error[0].message,icon:'none'})
-      }
-    }).catch(()=>{
-      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) {
-        console.log(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;
+  render() {
     return (
-      <View className='punchClock'>
+      <>
         <MessageNoticebar/>
-          <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'>
-                    公出企业:
-                    {
-                      Object.keys(this.state.dtails).length <= 0 ?
-                      '无':
-                      dtails.nickname
-                    }
-                  </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:dtails.status === 0 ? '#f31212' :
-                        dtails.status === 1 ? '#1d4fea' :
-                          dtails.status === 2 ? '#767272' : ''
-                    }}>
-                      <View>
-                        {
-                          dtails.status === 0 ? '驳回' :
-                            dtails.status === 1 ? '审核中' :
-                              dtails.status === 2 ? '通过' : ''
-                        }
-                      </View>
-                      <Image src={switchIocn} className='switchItem' onClick={()=>{
-                        Taro.switchTab({
-                          url: '/pages/examine/index',
-                        })
-                      }}/>
-                    </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: '#acb8ad',
-                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 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'>打卡拍照</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={this.publicReleaseClockIn} style={{
-                boxShadow:  (!isNaN(parseInt(this.state.distance))) && this.state.distance <=50 && this.state.distance >= 0 ? '1px 1px 15px 1px #659268' : '1px 1px 15px 1px #acb8ad',
-                background: (!isNaN(parseInt(this.state.distance))) && this.state.distance <=50 && this.state.distance >= 0 ? '#72cb78' : '#acb8ad'
-              }}>
-                <View className='punchClockTitle'>公出打卡</View>
-                <View className='punchClockTime'>{this.state.nowTime}</View>
-              </View>
-              <View className='map'>
-                <Map
-                  {...this.state.newArrder}
-                  style={{
-                    height:'300px',
-                    width:'100%'
-                  }}
-                  circles={[
-                    {
-                      latitude: this.state.addressLatitude,
-                      longitude: this.state.addressLongitude,
-                      color: '#c92ddc82',
-                      fillColor: '#c92ddc82',
-                      radius: 50,
-                      strokeWidth: 1
-                    }
-                  ]}
-                  showLocation
-                  showCompass
-                />
-              </View>
-              <View className='tips'>紫色区域为可打卡区域</View>
-            </View>
-        }
-      </View>
+        <PunchClocks/>
+      </>
     )
   }
 }
 
-export default PunchClock
-
+export default PunchClock;

+ 454 - 0
src/pages/punchClock/punchClocks.jsx

@@ -0,0 +1,454 @@
+import React, { Component } from 'react'
+import { connect } from 'react-redux'
+import {Map, OpenData, View, Image} from '@tarojs/components'
+import Taro from '@tarojs/taro';
+import {AtIcon, AtNoticebar} from "taro-ui";
+import dayjs from 'dayjs';
+import Skeleton from 'taro-skeleton'
+
+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 'taro-ui/dist/style/components/noticebar.scss';
+import 'taro-ui/dist/style/components/icon.scss';
+import 'taro-ui/dist/style/components/list.scss';
+
+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);
+  }
+
+  nowTime = null;
+
+  qqmapsdk = new QQMapWX({
+    key: 'AWBBZ-GRAC2-JFYUO-CLA7I-JAHXK-YFFGT'
+  });
+
+  componentDidMount(){
+    this.getPublicReleaseList(()=>{
+      Taro.startLocationUpdate({
+        success:()=>{
+          Taro.onLocationChange((v)=>{
+            this.getSpacing(v.latitude,v.longitude)
+          })
+        },
+        fail:()=>{
+          this.setState({
+            loading:false
+          })
+        }
+      })
+    });
+  }
+
+  componentWillMount() {
+    //获得当前位置
+    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('GoPunchIn', (arg) => {
+      this.setState({
+        dtails:arg,
+        addressLatitude:parseFloat(arg.latitude),
+        addressLongitude:parseFloat(arg.longitude),
+      },()=>{
+        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(Object.keys(this.state.dtails).length === 0){
+      Taro.showToast({title:'暂无公出申请,无法打卡',icon:'none'})
+      return ;
+    }
+    if(isNaN(parseInt(this.state.distance))){
+      Taro.showToast({title:'定位错误,请联系管理员',icon:'none'})
+      return ;
+    }
+    if(!(this.state.distance <=50 && this.state.distance >= 0)){
+      Taro.showToast({title:'当前位置未处于可打卡范围,无法打卡',icon:'none'})
+      return ;
+    }
+    if(this.state.imgs.length === 0){
+      Taro.showToast({title:'请上传打卡照片',icon:'none'})
+      return ;
+    }
+    publicReleaseClockIn({
+      id:this.state.dtails.id,
+      photoUrl:this.state.imgs.join(',')
+    }).then(v=>{
+      if(v.error.length === 0){
+        Taro.showToast({title:'打卡成功',icon:'none'})
+      }else{
+        Taro.showToast({title:v.error[0].message,icon:'none'})
+      }
+    }).catch(()=>{
+      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) {
+        console.log(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'>
+                  公出企业:
+                  {
+                    Object.keys(this.state.dtails).length <= 0 ?
+                      '无':
+                      dtails.nickname
+                  }
+                </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:dtails.status === 0 ? '#f31212' :
+                      dtails.status === 1 ? '#1d4fea' :
+                        dtails.status === 2 ? '#767272' : ''
+                  }}>
+                    <View>
+                      {
+                        dtails.status === 0 ? '驳回' :
+                          dtails.status === 1 ? '审核中' :
+                            dtails.status === 2 ? '通过' : ''
+                      }
+                    </View>
+                    <Image src={switchIocn} className='switchItem' onClick={()=>{
+                      Taro.switchTab({
+                        url: '/pages/examine/index',
+                      })
+                    }}/>
+                  </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: '#acb8ad',
+                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 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'>打卡拍照</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={this.publicReleaseClockIn} style={{
+                boxShadow:  (!isNaN(parseInt(this.state.distance))) && this.state.distance <=50 && this.state.distance >= 0 ? '1px 1px 15px 1px #659268' : '1px 1px 15px 1px #acb8ad',
+                background: (!isNaN(parseInt(this.state.distance))) && this.state.distance <=50 && this.state.distance >= 0 ? '#72cb78' : '#acb8ad'
+              }}>
+                <View className='punchClockTitle'>公出打卡</View>
+                <View className='punchClockTime'>{this.state.nowTime}</View>
+              </View>
+              <View className='map'>
+                <Map
+                  {...this.state.newArrder}
+                  style={{
+                    height:'300px',
+                    width:'100%'
+                  }}
+                  circles={[
+                    {
+                      latitude: this.state.addressLatitude,
+                      longitude: this.state.addressLongitude,
+                      color: '#c92ddc82',
+                      fillColor: '#c92ddc82',
+                      radius: 50,
+                      strokeWidth: 1
+                    }
+                  ]}
+                  showLocation
+                  showCompass
+                />
+              </View>
+              <View className='tips'>紫色区域为可打卡区域</View>
+            </View>
+        }
+      </View>
+    )
+  }
+}
+
+export default PunchClocks

+ 2 - 2
src/utils/servers/baseUrl.js

@@ -2,10 +2,10 @@ const getBaseUrl = (url) => {
   let BASE_URL = '';
   if (process.env.NODE_ENV === 'development') {
     //开发环境 - 根据请求不同返回不同的BASE_URL
-    BASE_URL = 'http://172.16.0.188:8080'
+    BASE_URL = 'https://uat.jishutao.com'
   } else {
     // 生产环境
-    BASE_URL = 'http://172.16.0.188:8080'
+    BASE_URL = 'https://uat.jishutao.com'
   }
   return BASE_URL
 }

+ 8 - 1
src/utils/servers/servers.js

@@ -17,18 +17,20 @@ export const login = (res) => {
       if(msg.error.length === 0){
         Taro.setStorageSync('token', msg.token);
         Taro.setStorageSync('userInfor', msg.data);
+        Taro.hideLoading();
         Taro.showToast({title:'登录成功',icon:'success'})
         resolve(msg);
       }else{
+        Taro.hideLoading();
         Taro.showToast({title:msg.error[0].message,icon:'none'})
         reject();
       }
     }catch (err) {
       Taro.showToast({title:'系统错误,请稍后重试',icon:'none'});
+      Taro.hideLoading();
       reject();
       console.log(err,'login')
     }
-    Taro.hideLoading();
   })
 }
 
@@ -71,6 +73,11 @@ export const updatePublicRelease = (postData = {}) => {
   return HTTPREQUEST.post('/api/admin/release/updatePublicRelease', postData)
 }
 
+//外出未读
+export const getPublicReleaseUnread = (postData = {}) => {
+  return HTTPREQUEST.get('/api/admin/notice/publicReleaseUnread', postData)
+}
+
 //测试
 export const test = (postData = {}) => {
   return HTTPREQUEST.get('/open/getVCode', postData)