HW il y a 3 ans
Parent
commit
d05f401a33

+ 15 - 13
src/app.config.js

@@ -1,30 +1,32 @@
 export default {
   pages: [
+    'pages/punchClock/index',//打卡
     'pages/examine/index',//审核
+    'pages/egressDetails/index',//外出详情
     'pages/applyDepart/index',//申请外出
-    'pages/punchClock/index',//打卡
     'pages/login/index',//登录
     // 'pages/staffDistribution/index',//员工分布
-    // 'pages/outdoorActivities/index'//出差申报
   ],
   tabBar: {
     list: [
       {
+        iconPath: './image/punchClockUnSelect.png',
+        selectedIconPath: './image/punchClockSelect.png',
+        pagePath: 'pages/punchClock/index',
+        text: '打卡'
+      },
+      {
         iconPath: './image/examineUnSelect.png',
         selectedIconPath: './image/examineSelect.png',
         pagePath: 'pages/examine/index',
         text: '审核'
-      },{
-      iconPath: './image/punchClockUnSelect.png',
-      selectedIconPath: './image/punchClockSelect.png',
-      pagePath: 'pages/punchClock/index',
-      text: '打卡'
-    }, {
-      iconPath: './image/egressUnSelect.png',
-      selectedIconPath: './image/egressSelect.png',
-      pagePath: 'pages/applyDepart/index',
-      text: '申请外出'
-    }],
+      },
+      {
+        iconPath: './image/egressUnSelect.png',
+        selectedIconPath: './image/egressSelect.png',
+        pagePath: 'pages/applyDepart/index',
+        text: '申请外出'
+      }],
     'color': '#515151',
     'selectedColor': '#56abe4',
     'backgroundColor': '#fff',

+ 5 - 4
src/components/common/imagePicker/index.jsx

@@ -1,7 +1,7 @@
 import React,{Component} from "react";
 import Taro from '@tarojs/taro';
-import {View} from "@tarojs/components";
-import {AtImagePicker} from "taro-ui";
+import {Text, View} from "@tarojs/components";
+import {AtImagePicker } from "taro-ui";
 
 import './index.less';
 
@@ -22,7 +22,7 @@ class ImagePicker extends Component{
     this.onImageClick = this.onImageClick.bind(this);
   }
 
-  onImgChange(files, operationType, index){
+  onImgChange(files, operationType, index, type){
     const BASE_URL = getBaseUrl(this.props.url);
     let token = Taro.getStorageSync('token');
     let _this = this;
@@ -34,7 +34,7 @@ class ImagePicker extends Component{
       })
     }else{
       let fileArr = this.state.files.concat([]);
-      let arr = files.splice(fileArr.length,files.length - fileArr.length)
+      let arr = type === 'camera' ? files : files.splice(fileArr.length,files.length - fileArr.length)
       for(let i = 0;i<arr.length;i++){
         const uploadTask = Taro.uploadFile({
           url: BASE_URL + this.props.url, //仅为示例,非真实的接口地址
@@ -118,6 +118,7 @@ class ImagePicker extends Component{
         <AtImagePicker
           multiple
           mode='center'
+          showAddBtn={this.props.showAddBtn}
           files={this.state.files}
           onChange={this.onImgChange}
           onFail={this.onFail}

Fichier diff supprimé car celui-ci est trop grand
+ 1 - 0
src/components/common/mapSDK/qqmap-wx-jssdk.min.js


BIN
src/image/passed.png


BIN
src/image/rejected.png


BIN
src/image/reviewed.png


+ 2 - 1
src/pages/applyDepart/publicContent.jsx

@@ -126,7 +126,7 @@ class PublicContent extends Component{
       userName: this.props.selectArrderLocation.name,
       longitude: this.props.selectArrderLocation.longitude,
       latitude: this.props.selectArrderLocation.latitude,
-      annexUrl: annexUrl || undefined,
+      annexUrl: annexUrl || '',
       duration: this.state.totalDuration
     }).then(v=>{
       this.setState({
@@ -328,6 +328,7 @@ class PublicContent extends Component{
           <View className='formName'>附件:</View>
           <View className='formValue' style={{paddingTop:'10px',textAlign:'left'}}>
             <ImagePicker
+              showAddBtn={true}
               ref={ref => this.imagePickerRef = ref}
               url='/api/admin/release/upload'
               onChange={this.onChange}

+ 3 - 0
src/pages/egressDetails/index.config.js

@@ -0,0 +1,3 @@
+export default {
+  navigationBarTitleText: '详情',
+}

+ 176 - 0
src/pages/egressDetails/index.jsx

@@ -0,0 +1,176 @@
+import React,{Component} from "react";
+import { View,Image } from '@tarojs/components'
+import Taro, { getCurrentInstance } from "@tarojs/taro";
+import {AtButton, AtIcon, AtTextarea} from 'taro-ui'
+import {examinePublicRelease} from '../../utils/servers/servers';
+import './index.less';
+
+import 'taro-ui/dist/style/components/icon.scss';
+import 'taro-ui/dist/style/components/textarea.scss'
+
+import Rejected from '../../image/rejected.png';
+import Passed from '../../image/passed.png';
+import Reviewed from '../../image/reviewed.png';
+
+class EgressDetails extends Component{
+
+  $instance = getCurrentInstance()
+
+  constructor(props) {
+    super(props);
+    this.state={
+      dtails:{},
+      remarks:''
+    }
+    this.examinePublicRelease= this.examinePublicRelease.bind(this);
+  }
+
+  componentDidShow() {
+    this.setState({
+      dtails:JSON.parse(this.$instance.router.params.dtails),
+      remarks:JSON.parse(this.$instance.router.params.dtails).remarks
+    })
+  }
+
+  examinePublicRelease(status){
+    if(!this.state.remarks){
+      Taro.showToast({title:'请填写审批意见',icon:'none'})
+      return;
+    }
+    examinePublicRelease({
+      status,
+      remarks:this.state.remarks,
+      id:this.state.dtails.id
+    }).then(v=>{
+      if(v.error.length === 0){
+        Taro.showToast({title:status===0?'驳回成功':'通过成功',icon:'none'});
+        this.state.dtails.status=status;
+        this.setState({
+          dtails:this.state.dtails
+        })
+      }else{
+        Taro.showToast({title:v.error[0].message,icon:'none'})
+      }
+    }).catch(()=>{
+      Taro.showToast({title:'系统错误,请稍后再试',icon:'none'})
+    })
+  }
+
+  render() {
+    const {dtails} = this.state;
+    //aname: "营销员"
+    // createTimes: "2021-06-07 14:40:46"
+    // id: "11"
+    // nickname: "1111111111"
+    // releaseEnds: "2021-06-13 15:40:00"
+    // releaseStarts: "2021-06-07 14:40:00"
+    // status: 1
+    // userName: "肯德基(西客站餐厅)"
+    return (
+      <View className='egressDetails'>
+        <View className='titleContent'>
+          <View className='title'>{dtails.aname}提交的外出申请</View>
+          <View className='address'>
+            <AtIcon value='map-pin' size='15' color='#767272'/>
+            公出企业:{dtails.nickname}
+          </View>
+          <View className='state' style={{
+            color:dtails.status === 0 ? '#f31212' :
+              dtails.status === 1 ? '#1d4fea' :
+                dtails.status === 2 ? '#767272' : ''
+          }}>
+            {
+              dtails.status === 0 ? '驳回' :
+                dtails.status === 1 ? '发起' :
+                  dtails.status === 2 ? '通过' : ''
+            }
+          </View>
+          <Image src={
+            dtails.status === 0 ? Rejected :
+              dtails.status === 1 ? Reviewed :
+                dtails.status === 2 ? Passed : ''} className='startIcon'/>
+        </View>
+        <View className='valueContent'>
+          {/*<View className='item'>*/}
+          {/*  <View className='title'>外出编号</View>*/}
+          {/*  <View className='value'>20212584646465495462</View>*/}
+          {/*</View>*/}
+          {/*<View className='item'>*/}
+          {/*  <View className='title'>企业类型</View>*/}
+          {/*  <View className='value'>稀有企业</View>*/}
+          {/*</View>*/}
+          {/*<View className='item'>*/}
+          {/*  <View className='title'>审核人</View>*/}
+          {/*  <View className='value'>营销经理</View>*/}
+          {/*</View>*/}
+          <View className='item'>
+            <View className='title'>公出地点:</View>
+            <View className='value'>{dtails.userName}</View>
+            <View className='timeContent'>
+              <View className='time'>
+                <View className='num'>外出1.5小时</View>
+                <View className='journal'>明细</View>
+              </View>
+              <View className='timeAxis'>
+                <View className='startTime'>
+                  <View className='circle'/>
+                  {dtails.releaseStarts}
+                </View>
+                <View className='axis'/>
+                <View className='endTime'>
+                  <View className='circle'/>
+                  {dtails.releaseEnds}
+                </View>
+              </View>
+            </View>
+          </View>
+          <View className='item'>
+            <View className='title'>申请时间</View>
+            <View className='value'>{dtails.createTimes}</View>
+          </View>
+          <View className='item'>
+            <View className='title'>外出原因</View>
+            <View className='value'>振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权振权</View>
+          </View>
+          {
+            this.$instance.router.params.type === '1' ?
+              <View className='item'>
+                <View className='title'>填写审批意见</View>
+                <AtTextarea
+                  value={this.state.remarks}
+                  onChange={(value)=>{
+                    this.setState({
+                      remarks:value
+                    })
+                  }}
+                  maxLength={200}
+                  placeholder='请填写审批意见'
+                />
+              </View> : null
+          }
+          {
+            this.$instance.router.params.type === '1' ?
+              <View className='operation'>
+                <AtButton type='secondary' circle loading={this.state.loading} onClick={()=>{
+                  this.examinePublicRelease(0);
+                }}>
+                  驳回
+                </AtButton>
+                <AtButton type='primary' loading={this.state.loading} circle onClick={()=>{
+                  this.examinePublicRelease(2);
+                }}>
+                  同意
+                </AtButton>
+              </View> : null
+          }
+        </View>
+        {/*<View className='valueContent history'>*/}
+        {/*  查看TA的历史记录*/}
+        {/*  <AtIcon value='chevron-right' size='30' color='#767272'/>*/}
+        {/*</View>*/}
+      </View>
+    )
+  }
+}
+
+export default EgressDetails;

+ 109 - 0
src/pages/egressDetails/index.less

@@ -0,0 +1,109 @@
+.egressDetails{
+  min-height: 100vh;
+  background: #F5F5F5;
+  padding-bottom: 30px;
+  .titleContent{
+    position: relative;
+    background: white;
+    padding: 20px 30px;
+    border-bottom: 1px #dadada solid;
+    .title{
+      font-weight: bolder;
+      padding-bottom: 20px;
+    }
+    .address{
+      font-size: 25px;
+      color: #767272;
+      padding-bottom: 20px;
+    }
+    .state{
+      font-size: 30px;
+      color: #767272;
+    }
+    .startIcon{
+      width: 180px;
+      height: 180px;
+      position: absolute;
+      right: 55px;
+      bottom: -65px;
+    }
+  }
+  .valueContent{
+    margin: 20px;
+    padding: 30px;
+    background: white;
+    border-radius: 30px;
+    .item{
+      padding-bottom: 30px;
+      .title{
+        color: #b7acac;
+        font-size: 27px;
+        padding-bottom: 10px;
+      }
+      .value{
+        color: #000000;
+        font-size: 30px;
+      }
+      .timeContent{
+        background: rgba(0,51,255,.09);
+        border-radius: 30px;
+        padding: 30px;
+        margin-top: 45px;
+        .time{
+          display: flex;
+          flex-flow: row nowrap;
+          justify-content: space-between;
+          align-items: center;
+          .num{
+            font-size: 30px;
+          }
+          .journal{
+            font-size: 28px;
+            color: #007aff;
+          }
+        }
+        .timeAxis{
+          display: flex;
+          flex-flow: column nowrap;
+          padding-top: 30px;
+          .startTime{
+            display: flex;
+            align-items: center;
+            color: #b7acac;
+            font-size: 25px;
+          }
+          .axis{
+            width: 1px;
+            height: 40px;
+            border-left: 1px #b7acac solid;
+            margin-left: 11px;
+          }
+          .endTime{
+            display: flex;
+            align-items: center;
+            color: #b7acac;
+            font-size: 25px;
+          }
+          .circle{
+            margin-right: 15px;
+            width: 20px;
+            height: 20px;
+            border-radius: 30px;
+            border: 1px #b7acac solid;
+          }
+        }
+      }
+    }
+  }
+  .history{
+    display: flex;
+    flex-flow: row nowrap;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 35px;
+  }
+  .operation{
+    display: flex;
+    flex-flow: row nowrap;
+  }
+}

+ 3 - 1
src/pages/examine/index.config.js

@@ -1,3 +1,5 @@
 export default {
-  navigationBarTitleText: '审核'
+  navigationBarTitleText: '审核',
+  enablePullDownRefresh: true,
+  onReachBottomDistance: 50,
 }

+ 150 - 23
src/pages/examine/index.jsx

@@ -1,49 +1,176 @@
-import { Component } from 'react'
-import { connect } from 'react-redux'
-import {View} from '@tarojs/components'
+import { Component } from 'react';
+import Taro from '@tarojs/taro';
+import { View } from '@tarojs/components'
+import { getPublicReleaseList } from '../../utils/servers/servers';
+import { AtTabs, AtTabsPane } from 'taro-ui';
 
-import { add, minus, asyncAdd } from '../../actions/counter'
+import ListBottomStart  from '../../components/common/listBottomStart';
 
-import './index.less'
+import './index.less';
 
+import 'taro-ui/dist/style/components/tabs.scss';
+
+import MyList from './myList';
 
-@connect(({ counter }) => ({
-  counter
-}), (dispatch) => ({
-  add () {
-    dispatch(add())
-  },
-  dec () {
-    dispatch(minus())
-  },
-  asyncAdd () {
-    dispatch(asyncAdd())
-  }
-}))
 class Examine extends Component {
+
   constructor(props) {
     super(props);
     this.state={
+      current:0,
 
+      list: [],
+      pageNo: 1,
+      listState: 'LOADING',
+
+      examinelist: [],
+      examinePageNo: 1,
+      examineListState: 'LOADING',
     }
+    this.getPublicReleaseList= this.getPublicReleaseList.bind(this);
+    this.getMyList= this.getMyList.bind(this);
+    this.getExamineList= this.getExamineList.bind(this);
+  }
+
+  componentDidShow() {
+
+  }
+
+  async componentDidMount() {
+    await this.getPublicReleaseList();
   }
 
-  componentDidShow () {
+  onPullDownRefresh(){
+    this.getPublicReleaseList();
+  }
 
+  onReachBottom(){
+    this.getPublicReleaseList(true);
   }
 
-  componentDidMount() {
+  async getPublicReleaseList (lv){
+    if(this.state.current === 0){
+      await this.getMyList(lv ? this.state.pageNo + 1 : 1)
+    } else if(this.state.current === 1){
+      await this.getExamineList(lv ? this.state.examinePageNo + 1 : 1)
+    }
+  }
 
+  async getMyList(pageNo){
+    this.setState({
+      listState: 'LOADING'
+    })
+    let msg = await getPublicReleaseList({
+      pageNo: pageNo,
+      pageSize: 10,
+      type:0,
+    });
+    if(msg.error.length === 0){
+      if(msg.data.totalCount === 0){
+        this.setState({
+          listState: 'NO_DATA'
+        })
+      }else if(msg.data.totalCount === this.state.list.length && pageNo !== 1){
+        Taro.showToast({title:'没有更多数据了',icon:'none'});
+        this.setState({
+          listState: 'NO_MORE_DATA'
+        })
+      }else{
+        this.setState({
+          list:pageNo === 1 ? msg.data.list : this.state.list.concat(msg.data.list),
+          pageNo: msg.data.pageNo
+        },()=>{
+          if(msg.data.totalCount === this.state.list.length){
+            this.setState({
+              listState: 'NO_MORE_DATA'
+            })
+          }
+        })
+      }
+    }else{
+      Taro.showToast({title:msg.error[0].message,icon:'none'});
+      this.setState({
+        listState: msg.error[0].field === '403' ? 'NO_DATA' : 'RELOAD'
+      })
+    }
+    Taro.stopPullDownRefresh();
+  }
+
+  async getExamineList(pageNo){
+    this.setState({
+      examineListState: 'LOADING'
+    })
+    let msg = await getPublicReleaseList({
+      pageNo: pageNo,
+      pageSize: 10,
+      type:1,
+    });
+    if(msg.error.length === 0){
+      if(msg.data.totalCount === 0){
+        this.setState({
+          examineListState: 'NO_DATA'
+        })
+      }else if(msg.data.totalCount === this.state.examinelist.length && pageNo !== 1){
+        Taro.showToast({title:'没有更多数据了',icon:'none'});
+        this.setState({
+          examineListState: 'NO_MORE_DATA'
+        })
+      }else{
+        this.setState({
+          examinelist:pageNo === 1 ? msg.data.list : this.state.examinelist.concat(msg.data.list),
+          examinePageNo: msg.data.pageNo
+        },()=>{
+          if(msg.data.totalCount === this.state.examinelist.length){
+            this.setState({
+              examineListState: 'NO_MORE_DATA'
+            })
+          }
+        })
+      }
+    }else{
+      Taro.showToast({title:msg.error[0].message,icon:'none'});
+      this.setState({
+        examineListState: msg.error[0].field === '403' ? 'NO_DATA' : 'RELOAD'
+      })
+    }
+    Taro.stopPullDownRefresh();
   }
 
   render () {
     return (
-      <View>
-        1
+      <View className='indexPage'>
+        <AtTabs current={this.state.current || 0} tabList={[{ title: '我的' }, { title: '审核' }]} onClick={(current)=>{
+          this.setState({
+            current
+          },()=>{
+            if((current === 0 && this.state.pageNo === 1) || (current === 1 && this.state.examinePageNo === 1)){
+              this.getPublicReleaseList();
+            }
+
+          })
+        }}>
+          <AtTabsPane current={this.state.current} index={0} >
+            <MyList
+              type={0}
+              list={this.state.list}
+              listState={this.state.listState}
+              onRefresh={()=>{
+                this.getPublicReleaseList(true);
+              }}/>
+          </AtTabsPane>
+          <AtTabsPane current={this.state.current} index={1}>
+            <MyList
+              type={1}
+              list={this.state.examinelist}
+              listState={this.state.examineListState}
+              onRefresh={()=>{
+                this.getPublicReleaseList(true);
+              }}/>
+          </AtTabsPane>
+        </AtTabs>
       </View>
     )
   }
 }
 
 export default Examine
-

+ 59 - 0
src/pages/examine/index.less

@@ -0,0 +1,59 @@
+.indexPage{
+  position: relative;
+  z-index: 1;
+  padding-bottom: 52px;
+  background: #F5F5F5;
+  min-height: 100vh;
+  .list{
+    padding: 20px 23px 0 23px;
+    .item{
+      border-radius: 6px;
+      padding: 31px;
+      background: #FFFFFF;
+      display: flex;
+      flex-flow: row nowrap;
+      margin-bottom: 17px;
+      .infor{
+        width: 100%;
+        .title{
+          display: flex;
+          flex-flow: row nowrap;
+          justify-content: space-between;
+          align-items: center;
+          padding-bottom: 20px;
+          .aname{
+            flex: 1;
+            padding-right: 20px;
+            font-weight: bolder;
+          }
+          .createTimes{
+            font-size: 20px;
+            color: #999999;
+            white-space: nowrap;
+          }
+        }
+        .userName{
+          font-size: 25px;
+          color: #999999;
+          padding-bottom: 15px;
+        }
+        .releaseStarts{
+          font-size: 25px;
+          color: #999999;
+          padding-bottom: 15px;
+        }
+        .releaseEnds{
+          font-size: 25px;
+          color: #999999;
+          display: flex;
+          flex-flow: row nowrap;
+          align-items: center;
+          justify-content: space-between;
+          .status{
+            font-size: 28px;
+          }
+        }
+      }
+    }
+  }
+}

+ 68 - 0
src/pages/examine/myList.jsx

@@ -0,0 +1,68 @@
+import { Component } from 'react';
+import Taro from '@tarojs/taro';
+import { View } from '@tarojs/components'
+
+import ListBottomStart  from '../../components/common/listBottomStart';
+
+import './index.less';
+
+class MyList extends Component {
+
+  constructor(props) {
+    super(props);
+  }
+
+  render () {
+    return (
+      <View className='indexPage'>
+        <View className='list'>
+          {
+            this.props.list.map((v,k)=>(
+              <View key={k} className='item' onClick={()=>{
+                console.log('/pages/egressDetails/index?type='+this.props.type+'&id='+v.id)
+                Taro.navigateTo({
+                  url:'/pages/egressDetails/index?type='+this.props.type+'&dtails='+JSON.stringify(v)
+                })
+              }}>
+                <View className='infor'>
+                  <View className='title'>
+                    <View className='aname'>{v.aname}提交的外出申请</View>
+                    <View className='createTimes'>{v.createTimes}</View>
+                  </View>
+                  <View className='userName'>
+                    外出地点:
+                    {v.userName}
+                  </View>
+                  <View className='releaseStarts'>
+                    开始时间:{v.releaseStarts}
+                  </View>
+                  <View className='releaseEnds'>
+                    结束时间:{v.releaseEnds}
+                    <View className='status' style={{
+                      color:v.status === 0 ? '#f31212' :
+                        v.status === 1 ? '#1d4fea' :
+                          v.status === 2 ? '#34de38' : ''
+                    }}>
+                      {
+                        v.status === 0 ? '驳回' :
+                          v.status === 1 ? '发起' :
+                            v.status === 2 ? '通过' : ''
+                      }
+                    </View>
+                  </View>
+                </View>
+              </View>
+            ))
+          }
+          <ListBottomStart
+            state={this.props.listState}
+            reload={()=>{
+              this.props.onRefresh
+            }}/>
+        </View>
+      </View>
+    )
+  }
+}
+
+export default MyList

+ 0 - 3
src/pages/outdoorActivities/index.config.js

@@ -1,3 +0,0 @@
-export default {
-  navigationBarTitleText: '首页'
-}

+ 0 - 86
src/pages/outdoorActivities/index.jsx

@@ -1,86 +0,0 @@
-import { Component } from 'react';
-import Taro from '@tarojs/taro';
-import { connect } from 'react-redux';
-import {View} from '@tarojs/components';
-
-import 'taro-ui/dist/style/components/icon.scss';
-import './index.less';
-
-import { add, minus, asyncAdd } from '../../actions/counter';
-
-
-@connect(({ counter }) => ({
-  counter
-}), (dispatch) => ({
-  add () {
-    dispatch(add())
-  },
-  dec () {
-    dispatch(minus())
-  },
-  asyncAdd () {
-    dispatch(asyncAdd())
-  }
-}))
-class Index extends Component {
-  constructor(props) {
-    super(props);
-    this.state={
-      selectArrderName:''
-    }
-    this.selectArrder = this.selectArrder.bind(this);
-  }
-
-  componentDidShow () {
-    const chooseLocation = requirePlugin('chooseLocation');
-    const location = chooseLocation.getLocation();
-    // address: "北京市丰台区莲花池东路"
-    // city: "北京市"
-    // district: "丰台区"
-    // latitude: 39.896316
-    // longitude: 116.32346
-    // name: "北京西站"
-    // province: "北京市"
-    if(location){
-      this.setState({
-        selectArrderName: location.name
-      })
-    }
-    console.log(location);
-  }
-
-  componentDidMount() {
-
-  }
-
-  selectArrder(){
-    const key = 'BP4BZ-JQJED-5DG4N-H6JND-KC5PK-D2BDL'; //使用在腾讯位置服务申请的key
-    const referer = '科德高企培育'; //调用插件的app的名称
-    const location = JSON.stringify({
-      latitude: 39.89631551,
-      longitude: 116.323459711
-    });
-    const category = '生活服务,娱乐休闲';
-
-    Taro.navigateTo({
-      url: 'plugin://chooseLocation/index?key=' + key + '&referer=' + referer + '&location=' + location + '&category=' + category
-    });
-  }
-
-  render () {
-    return (
-      <View className='outdoorActivities'>
-          <View className='formItem'>
-            <View className='formLabel'>出差地点:</View>
-            <View className='formValue' onClick={this.selectArrder}>
-              <View className='selectArrderName'>{this.state.selectArrderName}</View>
-              <View className='at-icon at-icon-chevron-right'/>
-            </View>
-          </View>
-      </View>
-    )
-  }
-}
-
-export default Index
-

+ 0 - 29
src/pages/outdoorActivities/index.less

@@ -1,29 +0,0 @@
-.outdoorActivities{
-  .formItem{
-    display: flex;
-    flex-flow: row nowrap;
-    align-items: center;
-    justify-content: space-between;
-    border-bottom: 1px #767272 solid;
-    padding: 30px;
-    .formLabel{
-      white-space: nowrap;
-      padding-right: 40px;
-    }
-    .formValue{
-      flex: 1;
-      display: flex;
-      flex-flow: row nowrap;
-      align-items: center;
-      justify-content: flex-end;
-      .selectArrderName{
-        width: 472px;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        white-space: nowrap;
-        padding-right: 10px;
-        text-align: right;
-      }
-    }
-  }
-}

+ 311 - 6
src/pages/punchClock/index.jsx

@@ -1,10 +1,23 @@
-import { Component } from 'react'
+import React, { Component } from 'react'
 import { connect } from 'react-redux'
-import {View} from '@tarojs/components'
+import {Map, OpenData, View} from '@tarojs/components'
+import Taro from '@tarojs/taro';
+import moment from 'moment';
+
+import ImagePicker from '../../components/common/imagePicker';
 
 import { add, minus, asyncAdd } from '../../actions/counter'
 
+import {getPublicReleaseList,publicReleaseClockIn} from '../../utils/servers/servers';
+
 import './index.less'
+import {AtIcon} from "taro-ui";
+
+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 }) => ({
@@ -24,11 +37,203 @@ class PunchClock extends Component {
   constructor(props) {
     super(props);
     this.state={
-
+      imgs:[],
+      nowTime:'00:00:00',
+      newArrder:{},
+      addressLatitude:'',
+      addressLongitude:'',
+      distance:'',
+      dtails:{}
     }
+    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.nowTime = null;
   }
 
+  qqmapsdk = new QQMapWX({
+    key: 'AWBBZ-GRAC2-JFYUO-CLA7I-JAHXK-YFFGT'
+  });
+
   componentDidShow () {
+    //获得当前位置
+    Taro.getLocation({
+      type: 'gcj02',
+      isHighAccuracy:true,
+      success: (res)=> {
+        const latitude = res.latitude
+        const longitude = res.longitude
+        this.setState({
+          newArrder:{
+            latitude,
+            longitude
+          },
+        })
+      }
+    })
+
+    this.getPublicReleaseList(()=>{
+      Taro.startLocationUpdate({
+        success:()=>{
+          Taro.onLocationChange((v)=>{
+            console.log(1111111)
+            this.getSpacing(v.latitude,v.longitude)
+          })
+        }
+      })
+    });
+
+    this.nowTime = setInterval(()=>{
+      this.setState({
+        nowTime:moment().format('HH:mm:ss')
+      })
+    },1000)
+
+    // let token = Taro.getStorageSync('token');
+    //   //建立连接
+    //   Taro.connectSocket({
+    //     header:{
+    //       'token': token,
+    //     },
+    //     url: "wss://uat.jishutao.com/websocket",
+    //   //  172.16.0.188:8080
+    //   //  uat.jishutao.com
+    //   })
+    //
+    //   //连接成功
+    //   Taro.onSocketOpen(function() {
+    //     Taro.sendSocketMessage({
+    //       data: 'stock',
+    //     })
+    //   })
+    //
+    //   //接收数据
+    //   Taro.onSocketMessage(function(data) {
+    //     console.log(data,'接收数据')
+    //   })
+    //
+    //   //连接失败
+    //   Taro.onSocketError(function() {
+    //     console.log('websocket连接失败!');
+    //   })
+  }
+
+  publicReleaseClockIn(){
+    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){
+    getPublicReleaseList({
+      type:0,
+      clockTime:moment().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: {}
+                })
+              }else{
+                this.setState({
+                  dtails:value.data.list[0],
+                  addressLatitude:value.data.list[0].latitude,
+                  addressLongitude:value.data.list[0].longitude,
+                },()=>{
+                  fn();
+                })
+              }
+            }else{
+              Taro.showToast({
+                title:v.error[0].message
+              })
+            }
+          }).catch(()=>{
+            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,
+          })
+        }
+      }else{
+        Taro.showToast({
+          title:v.error[0].message
+        })
+      }
+    }).catch(()=>{
+      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
+        })
+      },
+      fail: function(error) {
+        console.error(error);
+      },
+      complete: function(res) {
+        console.log(res);
+      }
+    });
+  }
+
+  componentWillUnmount() {
+    this.nowTime && this.nowTime.clearTimeout();
 
   }
 
@@ -36,11 +241,111 @@ class PunchClock extends Component {
 
   }
 
+  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,
+    })
+  }
+
   render () {
+    const {dtails} = this.state;
     return (
-      <View>
-        1
-      </View>
+        Object.keys(dtails).length === 0 ?
+          <View>
+            暂无任何公出申请
+          </View>:
+          <View className='punchClock'>
+            <View className='header'>
+              <View className='userAvatarUrl'>
+                <OpenData type='userAvatarUrl'/>
+              </View>
+              <View className='infor'>
+                <View className='name'>
+                  {dtails.aname}
+                </View>
+                <View className='address'>
+                  公出企业:{dtails.nickname}
+                </View>
+              </View>
+              <View className='state' style={{
+                color:dtails.status === 0 ? '#f31212' :
+                  dtails.status === 1 ? '#1d4fea' :
+                    dtails.status === 2 ? '#767272' : ''
+              }}>
+                {
+                  dtails.status === 0 ? '驳回' :
+                    dtails.status === 1 ? '发起' :
+                      dtails.status === 2 ? '通过' : ''
+                }
+              </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>
+
     )
   }
 }

+ 115 - 0
src/pages/punchClock/index.less

@@ -0,0 +1,115 @@
+.punchClock{
+  position: relative;
+  background: #F5F5F5;
+  min-height: 100vh;
+  padding: 25px;
+  .header{
+    background: #FFFFFF;
+    padding: 30px;
+    border-radius: 30px;
+    margin-bottom: 20px;
+    display: flex;
+    flex-flow: row nowrap;
+    align-items: center;
+    .userAvatarUrl{
+      width: 100px;
+      height: 100px;
+      border-radius: 20px;
+      overflow: hidden;
+    }
+    .infor{
+      padding-left: 15px;
+      .name{
+        font-size: 28px;
+        padding-bottom: 18px;
+      }
+      .address{
+        font-size: 25px;
+        color: #8e8d8d;
+      }
+    }
+    .state{
+      margin-left: auto;
+      font-size: 25px;
+      align-self: flex-start;
+    }
+  }
+  .content{
+    background: #FFFFFF;
+    padding: 30px;
+    border-radius: 30px;
+    margin-bottom: 20px;
+    display: flex;
+    flex-flow: column nowrap;
+    align-items: center;
+    .timeContent{
+      width: 100%;
+      padding-top: 20px;
+      display: flex;
+      flex-flow: row nowrap;
+      justify-content: space-between;
+      padding-bottom: 30px;
+      .timeItem{
+        background: #eae8e8;
+        padding: 20px;
+        border-radius: 20px;
+        .timeTitle{
+          font-size: 30px;
+          padding-bottom: 8px;
+        }
+        .timeValue{
+          font-size: 27px;
+          color: #767272;
+        }
+      }
+    }
+    .map{
+      height:600px;
+      width:100%;
+      border-radius: 20px;
+      overflow: hidden;
+    }
+    .tips{
+      color: #999999;
+      font-size: 18px;
+      padding-top: 10px;
+      align-self: flex-start;
+    }
+    .punchClockContent{
+      width: 250px;
+      height: 250px;
+      border-radius: 250px;
+      margin-top: 45px;
+      display: flex;
+      flex-flow: column nowrap;
+      justify-content: center;
+      align-items: center;
+      margin-bottom: 75px;
+      .punchClockTitle{
+        color: white;
+        font-size: 35px;
+        padding-bottom: 8px;
+      }
+      .punchClockTime{
+        color: #e8e6e6;
+        font-size: 25px;
+      }
+    }
+    .photographContent{
+      display: flex;
+      flex-flow: row nowrap;
+      align-items: center;
+      justify-content: space-between;
+      width: 100%;
+      padding-left: 20px;
+      padding-right: 20px;
+      padding-bottom: 25px;
+      .photographTitle{
+        font-size: 30px;
+      }
+      .photograph{
+
+      }
+    }
+  }
+}

+ 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://uat.jishutao.com'
+    BASE_URL = 'http://172.16.0.188:8080'
   } else {
     // 生产环境
-    BASE_URL = 'http://uat.jishutao.com'
+    BASE_URL = 'http://172.16.0.188:8080'
   }
   return BASE_URL
 }

+ 12 - 0
src/utils/servers/servers.js

@@ -44,6 +44,18 @@ export const setOpenId = (postData = {}) => {
   return HTTPREQUEST.post('/api/admin/setOpenId', postData)
 }
 
+export const getPublicReleaseList = (postData = {}) => {
+  return HTTPREQUEST.get('/api/admin/release/listPublicRelease', postData)
+}
+
+export const publicReleaseClockIn = (postData = {}) => {
+  return HTTPREQUEST.post('/api/admin/release/publicReleaseClockIn', postData)
+}
+
+export const examinePublicRelease = (postData = {}) => {
+  return HTTPREQUEST.post('/api/admin/release/examinePublicRelease', postData)
+}
+
 //测试
 export const test = (postData = {}) => {
   return HTTPREQUEST.get('/open/getVCode', postData)