【免费开放源码】审批类小程序项目实战(预约审批端)

第一节:什么构成了微信小程序、创建一个自己的小程序

第二节:微信开发者工具使用教程

第三节:深入了解并掌握小程序核心组件

第四节:初始化云函数和数据库

第五节:云数据库的增删改查

第六节:项目大纲以及制作登录、注册页面

第七节:制作活动申请页面

第八节:活动申请页面的补充

第九节:我的页面制作

第十节:活动详情页面制作

第十一节:活动历史页面制作

第十二节:预约老师页面制作

第十三节:预约历史页面制作

第十四节:活动审批端制作

第十五节:预约审批端制作

       

        这个项目是当时大一大二自学前端的时候做的一个算是比较大的项目,主体原型是汕头大学校团委微信小程序,该微信小程序使用微信原生语法和腾讯云开发框架开发,旨在简化汕头大学校团委的教师预约申请和活动申请的审批流程。因为一切的代码以及框架都是从零搭建的,经过了几个版本的迭代和摸爬滚打的探索,已经稳定运行了将近两年的时间。所以想写这个系列的文章,一方面是分享一些开发经历以及心得,另一方面是对学校组织贡献一点微薄之力~

        希望通过这个系列的博客,能够深入介绍“汕头大学校团委微信小程序”的开发过程、功能实现和技术细节,帮助更多的开发者和用户了解和使用该小程序。我们也欢迎更多的开发者为这个开源项目做出贡献,共同完善和优化这个项目。欢迎提交PR请求和留下你的问题。这个项目单纯为爱发电,所以不会有任何金钱相关的利益。如果这个项目对你有帮助,可以给我一个小星星吗?


前言

        上一节我们完成了活动审批端的搭建,这一节我们将要完成预约审批端的搭建,也就是本项目最后一个部分的搭建!我们先来看思维大纲~

        跟活动审批端同理,我们同样要在app.json文件中创建相关的页面。

        "pages/appointmentApproval/appointmentApproval",
        "pages/appointmentApproval2/appointmentApproval2",
        "pages/appointmentApproval3/appointmentApproval3",
        "pages/appointmentDetail/appointmentDetail"

         完成了上诉准备工作那么开始搭建吧~


成品图


核心思想

1.基本样式参照“我的”页面

2.导航栏参照活动审批端

3.需要老师版的预约详情页面

4.通过云开发来实现预约的审批(updata)

5.点击工具箱可实现一键导出预约信息的excel表格


实现步骤 

        该部分的难点在于如何一键导出预约信息的excel表格,其实node.js也支持这个功能,我们只需要稍加点改动就可以了。这里我直接将代码送上了~如果你对代码有疑问可以在底下留言。

        我们将按照思维大纲中 待审批——>已通过——>已驳回 的顺序来依次制作~


appointmentApproval.wxml

<view class="container">
       <view class="container_content">
              <view class="box">
                     <view class="mine_application">
                     <!-- 活动标题 -->
                            <view class="mine_application_title">
                            <view>待审批的预约</view><image src="../../icon/rank.png" style="width: 50px;height: 35px;position: absolute; right: 20px; top: 0px;" bindtap="up"></image>
                     </view>
                     <block wx:for="{{list}}"></block>
                     <!-- 活动内容 点击可跳转至详情页面 -->
                     <view class="mine_application_content" wx:for="{{list}}" >
                                   <view class="event" bindtap="goDetail" data-id="{{item._id}}">
                                          <view class="appointmentTime">{{item.appointment}}</view>
                                          <view class="appointmentInstitute">预约组织:{{item.g1_orderInstitute}}</view>
                                          <view class='appointmentTeacher'>预约老师:{{item.g1_orderTeacher}}</view>
                                          <view class="time">{{item.time}}</view>
                                          <view class="subscriber">申请人:{{item.subscriber}}</view>

                                   </view>
                                   <!-- 右上角的状态栏 -->
                                   <!-- 用条件渲染来展示多种样式的活动内容 -->
                                   <!-- 状态为3代表已结束,2为已驳回,1为已通过,0为审核中 -->
                                   <block wx:if="{{item.state==0}}">
                                   <!-- 审核中 -->
                                   <view class="state_0">
                                   <view class="state_content">审核中</view>
                                   </view>
                                   <!-- 活动下方的小点 -->
                                   <image src="../../icon/yellow.png" style="width: 11px;height: 11px;position: absolute;left: 15px;bottom: 15px;"></image>
                                   </block>





                                   <block wx:if="{{item.state==1}}">
                                   <!-- 已通过 -->
                                   <view class="state_1">
                                   <view class="state_content">已通过</view>
                                   </view>
                                   <!-- 活动下方的小点 -->
                                   <image src="../../icon/green.png" style="width: 11px;height: 11px;position: absolute;left: 15px;bottom: 15px;"></image>
                                   <view class="next_location" >
                                   <button class="button_detail" size="mini" bindtap="goNext" data-id="{{item._id}}">下一步 >
                                   </button>
                                   </view>
                                   </block>
                                   
                                   <block wx:if="{{item.state==2}}">
                                   <!-- 已驳回 -->
                                   <view class="state_2">
                                   <view class="state_content">已驳回</view>
                                   </view>
                                   <!-- 活动下方的小点 -->
                                   <image src="../../icon/red.png" style="width: 11px;height: 11px;position: absolute;left: 15px;bottom: 15px;"></image>
                                   <view class="reject_location">
                                   <button class="button_detail" size="mini">驳回详情 >
                                   </button>
                                   </view>
                                   </block>




                     </view>

                     </view>
              </view>
              <view class="tabar">
                     <view class='goApprovalButton' bindtap="goApprovalPage">
                            <image src="../../icon/approval.png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">待审批</view>
                     </view>
                     <view class="goPassButton" bindtap="goPassPage">
                            <image src="../../icon/pass(1).png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">已通过</view>
                     </view>
                     <view class="goRejectButton" bindtap="goRejectPage">
                            <image src="../../icon/reject(1).png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">已驳回</view>
                     </view>
              </view>
       </view>
</view>

appointmentApproval.wxss

.mine_application{
       margin-left: 15px;
       margin-right: 15px;
     }
     .mine_application_title{
       border-bottom: 5rpx solid #A6A6A6;
       font-size: 28px;
       font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
     }
  
     .mine_application_content{
            height: 250px;
            width: 100%;
            display: flex;
            position: relative;
            box-shadow: 16rpx 8rpx 24rpx rgba(212,48,48, 0.1);
            margin-top: 15px;
            border-radius: 15px;
  
     }
     .event{
            font-size: 20px;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            position: relative;
            margin:15px;
            width: 90%;
            flex: 1;
     }
     .appointmentTime{
            margin-top: 0px;
            font-size: 16px;
            color: black;
     }
     .state_0{
            float: right;
            width: 80px;
            height: 40px;
            background-color:#FFC300;
            border-radius: 0 15px 0 15px;
     }
     .state_content{
            position: relative;
            margin-top:10px ;
            margin-left: 15px;
            font-size: 12;
            color: white;
     }

    .appointmentInstitute{

         font-size: 20px;
         color:#FF5733;
         margin-top: 10px;
    }
    .appointmentTeacher{

       font-size: 20px;
       color:#611504;
       margin-top: 10px;
  }
  .time{
       margin-top: 10px;
       font-size: 18px;
       color: #A0A9BD;
  }
.goApprovalButton{
       position: absolute;
       bottom:0px ;
       left: 0%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
}
.goPassButton{
       position: absolute;
       bottom:0px ;
       left: 33.333%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
}

.goRejectButton{
       position: absolute;
       bottom:0px ;
       left: 66.666%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
       
}
.button_content{
       font-size: 15px;
       color: black;
}
.box{
       margin-bottom: 50px;
}
.container{
       position: relative;
}

.container_content{
       position: relative;
       min-height: 100vh;
       box-sizing: border-box;
       padding-bottom: 60rpx;
       padding-top: 0rpx;
}
.subscriber{
       font-size: 20px;
       font-weight: 100;
       color: rgb(23, 6, 175);
}
.tabar{
       width: 100%;
         text-align: center;
         letter-spacing: 4rpx;
         position: absolute;
         bottom: 0;
}

appointmentApproval.js

const db = wx.cloud.database()
Page({
       data: {
              list:[]

       },
       onLoad(options) {
              console.log("列表携带的值",options)
              db.collection("appointment")
                            .where({
                                 state:0,
                            })
                            .get()
                            .then(res=>{
                                   console.log('查询数据库成功',res.data)
                                   //将返回的res.data里面的值赋值给list
                                   this.setData({
                                          list :res.data,
                                   })
                                   console.log("这是list",this.data.list)
                            })

       },
       up(){
              db.collection("appointment")
              .where({
                   state:0,
              })
              .orderBy('rank','asc')
              .get()
                .then(res=>{
                  console.log('升序成功',res.data)
                  this.setData({
                    list:res.data
                  })
                })
                .catch(err=>{
                  console.log('升序失败')
                })
       },
       onPullDownRefresh() {

       },
       onReachBottom() {

       },
       goDetail(e){
              console.log("点击了详情页面,将展示活动的id ",e)
              wx.navigateTo({
              // 跳转到活动详情页面并携带活动id
                url: '/pages/appointmentDetail/appointmentDetail?id=' +e.currentTarget.dataset.id 
              })
       },

       // 前往待审批页面
       goApprovalPage(){
              wx.showToast({
                     title: '您已经在当前页面',
                     icon:'none'
                     })       
       },
       
       // 前往已通过页面
       goPassPage(){
              wx.redirectTo({
                     url: '../appointmentApproval3/appointmentApproval3',
                     })
       },

       // 前往已驳回页面
       goRejectPage(){
              wx.redirectTo({
                     url: '../appointmentApproval2/appointmentApproval2',
                     })
       },
})

appointmentApproval3.wxml

<view class="container">
       <view class="container_content">
              <view class="box">
                     <view class="mine_application">
                     <!-- 活动标题 -->
                            <view class="mine_application_title">
                            <view>已通过的预约历史</view><image src="../../icon/work-box.png" style="width: 40px;height: 40px;position: absolute; right: 20px; top: 0px;" bindtap="download"></image>
                            <image src="../../icon/guide.png" style="width: 40px;height:40px;position: absolute; right: 70px; top:0px;"bindtap="lookAll"></image>
                            </view>
                     <block wx:for="{{list}}"></block>
                     <!-- 活动内容 点击可跳转至详情页面 -->
                     <view class="mine_application_content" wx:for="{{list}}" >
                                   <view class="event" bindtap="goDetail" data-id="{{item._id}}">
                                          <view class="appointmentTime">{{item.appointment}}</view>
                                          <view class="appointmentInstitute">预约组织:{{item.g1_orderInstitute}}</view>
                                          <view class='appointmentTeacher'>预约老师:{{item.g1_orderTeacher}}</view>
                                          <view class="time">{{item.time}}</view>

                                   </view>
                                   <!-- 右上角的状态栏 -->
                                   <!-- 用条件渲染来展示多种样式的活动内容 -->
                                   <!-- 状态为3代表已结束,2为已驳回,1为已通过,0为审核中 -->
                                   <block wx:if="{{item.state==1}}">
                                   <!-- 已通过 -->
                                   <view class="state_1">
                                   <view class="state_content">已通过</view>
                                   </view>
                                   <!-- 活动下方的小点 -->
                                   <image src="../../icon/green.png" style="width: 11px;height: 11px;position: absolute;left: 15px;bottom: 15px;"></image>
                                   </block>
                                   
                                   <block wx:if="{{item.state==2}}">
                                   <!-- 已驳回 -->
                                   <view class="state_2">
                                   <view class="state_content">已驳回</view>
                                   </view>
                                   <!-- 活动下方的小点 -->
                                   <image src="../../icon/red.png" style="width: 11px;height: 11px;position: absolute;left: 15px;bottom: 15px;"></image>
                                   </block>




                     </view>

                     </view>
              </view>
              <view class="tabar">
                     <view class='goApprovalButton' bindtap="goApprovalPage">
                            <image src="../../icon/approval(1).png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">待审批</view>
                     </view>
                     <view class="goPassButton" bindtap="goPassPage">
                            <image src="../../icon/pass.png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">已通过</view>
                     </view>
                     <view class="goRejectButton" bindtap="goRejectPage">
                            <image src="../../icon/reject(1).png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">已驳回</view>
                     </view>
              </view>
       </view>
</view>

appointmentApproval3.wxss

.mine_application{
       margin-left: 15px;
       margin-right: 15px;
     }
     .mine_application_title{
       border-bottom: 5rpx solid #A6A6A6;
       font-size: 28px;
       font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
     }
  
     .mine_application_content{
            height: 250px;
            width: 100%;
            display: flex;
            position: relative;
            box-shadow: 16rpx 8rpx 24rpx rgba(212,48,48, 0.1);
            margin-top: 15px;
            border-radius: 15px;
  
     }
     .event{
            font-size: 20px;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            position: relative;
            margin:15px;
            width: 90%;
            flex: 1;
     }
     .appointmentTime{
            margin-top: 0px;
            font-size: 16px;
            color: black;
     }
     .state_1{
       width: 80px;
       height: 40px;
       background-color:#43CF7C;
       border-radius: 0 15px 0 15px;
       z-index: 2;
       flex-direction: row;
       position: relative;
       margin-left: 20px;
 }
     .state_content{
            position: relative;
            margin-top:10px ;
            margin-left: 15px;
            font-size: 12;
            color: white;
     }
    .appointmentInstitute{

         font-size: 20px;
         color:#FF5733;
         margin-top: 10px;
    }
    .appointmentTeacher{

       font-size: 20px;
       color:#611504;
       margin-top: 10px;
  }
  .time{
       margin-top: 10px;
       font-size: 18px;
       color: #A0A9BD;
  }
.goApprovalButton{
       position: absolute;
       bottom:0px ;
       left: 0%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
}
.goPassButton{
       position: absolute;
       bottom:0px ;
       left: 33.333%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
}

.goRejectButton{
       position: absolute;
       bottom:0px ;
       left: 66.666%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
       
}
.button_content{
       font-size: 15px;
       color: black;
}
.box{
       margin-bottom: 50px;
}
.container{
       position: relative;
}

.container_content{
       position: relative;
       min-height: 100vh;
       box-sizing: border-box;
       padding-bottom: 60rpx;
       padding-top: 0rpx;
}

/* 有无这个属性都行,之后可能会用到 */
.tabar{
       width: 100%;
         text-align: center;
         letter-spacing: 4rpx;
         position: absolute;
         bottom: 0;
}

appointmentApproval3.js

const db = wx.cloud.database()
const _ = db.command
const t = new Date().getTime().toString().slice(0, -3);
Page({
       data: {
              list:[],
              // fileUrl:'',

       },
       onLoad(options) {
             //调用云函数来突破返回数据库的条数只有20条的限制
             wx.cloud.callFunction({
              name:'getAll2'
       })
       .then(res=>{
              console.log('成功',res)
              this.setData({
               list :res.result.data,
              })
       })
       .catch(res=>{
              console.log("失败",res);
       })

       },
       onPullDownRefresh() {

       },
       onReachBottom() {

       },
       goDetail(e){
              console.log("点击了详情页面,将展示活动的id ",e)
              wx.navigateTo({
              // 跳转到活动详情页面并携带活动id
                url: '/pages/appointmentDetail/appointmentDetail?id=' +e.currentTarget.dataset.id 
              })
       },
       // 前往待审批页面
       goApprovalPage(){
              wx.redirectTo({
                     url: '../appointmentApproval/appointmentApproval',
                     })
       },
       // 前往已通过页面
       goPassPage(){
              wx.showToast({
                     title: '您已经在当前页面',
                     icon:'none'
                     })     
       },
       // 前往已驳回页面
       goRejectPage(){
              wx.redirectTo({
                     url: '../appointmentApproval2/appointmentApproval2',
                     })
       },
       //一键导出excel表格
       download(){
              let that = this
              wx.showModal({
                     title: '您是否需要导出已通过的预约',
                     content: '',
                     success (res) {
                            if (res.confirm){
                                   console.log('点击了一键导出excel')
                                    //引用了excel的云函数,调取了appointment里面的数据
                                   wx.cloud.callFunction({
                                   name:'excel',
                                   success(res) {
                                    console.log("读取成功", res.result.data)
                                    //将调取的数据存入函数里
                                          that.savaExcel(res.result.data)
                                   },
                                   })
                            }
                            else if (res.cancel) {
                            //取消绑定的操作
                            }
                     }
              })
                     
       },
       //把数据保存到excel里,并把excel保存到云存储
       savaExcel(userdata) {
       let that = this
       //调取getExcel云函数(核心)
       wx.cloud.callFunction({
         name: "getExcel",
         data: {
           userdata: userdata
         },
         success(res) {
           console.log("保存成功", res)
           //调取获取地址的函数
           that.getFileUrl(res.result.fileID)
         },
         fail(res) {
           console.log("保存失败", res)
         }
       })
     },
     //获取云存储文件下载地址,这个地址有效期一天
       getFileUrl(fileID) {
       
       let that = this;
       wx.cloud.getTempFileURL({
         fileList: [fileID],
         success: res => {
              // 这里的文件下载链接延迟很高,不能实时更新excel里面的数据,故采用文件下载链接拼接时间字符串的形式来达到可下载实时文件的目的
           console.log("文件下载链接", res.fileList[0].tempFileURL)
          // 这里就是拼接,方法来自  https://blog.csdn.net/sjn0503/article/details/74936613
           const finalUrl = `${res.fileList[0].tempFileURL}?${t}`
           console.log("实时文件下载链接",finalUrl)
           that.setData({
             fileUrl: finalUrl
           })
           //获取到文件下载链接后,使用showModal和setClipboardData来达到给用户复制地址的目的
           wx.showModal({
              title:'一键导出excel成功',
              content:finalUrl,
              showCancel:true,
              confirmText:'复制地址',
                     success(res){
                      if (res.confirm) {
                             wx.setClipboardData({
                               data: that.data.fileUrl,
                               success(res) {
                                 wx.getClipboardData({
                                   success(res) {
                                     console.log(res.data) // data
                                   }
                                 })
                               }
                             })
                           }
                     }
                   
              })
            
         },
       })
     },
})

其中在js中还用到了getAll2、excel、getExcel 三个云函数

getAll2.js

// 云函数入口文件
//获取所有已结束的活动
const cloud = require('wx-server-sdk')
let id=0;
// 云开发环境初始化
cloud.init({env: 'cloud1-0glmim4o153108f5'})
const db = cloud.database()
const _ = db.command
exports.main = async (event, context) => {
try{
       return await db.collection('appointment')
       .where(
              {
              state:1
              }
       )
       //给申请到的预约数据排序
       .orderBy('rank','asc')
       .get({
              success: function (res) {
              this.setData({
                     id:res._id
              })
              return res
              }
       })
}
catch(e){
       console.error(e)
}
}

excel.js

//这个函数是用来获取预约集合里面的数据的,并没有存储到excel里
// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
       env:'cloud1-0glmim4o153108f5'
})

// 云函数入口函数
exports.main = async (event, context) => {
       return await cloud.database().collection('appointment')
       .where({
              state:1,
         })
       .orderBy('rank','asc')
       .get()
}

getExcel.js

const cloud = require('wx-server-sdk')
cloud.init({
  env: "cloud1-0glmim4o153108f5"
})
//操作excel用的类库
const xlsx = require('node-xlsx');

// 云函数入口函数
exports.main = async(event, context) => {
  try {
    let {userdata} = event
    
    //1,定义excel表格名
    let dataCVS = '预约.xlsx'
    //2,定义存储数据的
    let alldata = [];
    let row = ['日期','时间段', '组织', '预约老师','预约事项','预约人','手机号']; //表属性
    alldata.push(row);

    for (let key in userdata) {
      let arr = [];
      arr.push(userdata[key].day);
      arr.push(userdata[key].hour);
      arr.push(userdata[key].g1_orderInstitute);
      arr.push(userdata[key].g1_orderTeacher);
      arr.push(userdata[key].content);
      arr.push(userdata[key].subscriber);
      arr.push(userdata[key].subscriberPhone);
      alldata.push(arr)
    }
    //3,把数据保存到excel里
    var buffer = await xlsx.build([{
      name: "mySheetName",
      data: alldata
    }]);
    //4,把excel文件保存到云存储里
    return await cloud.uploadFile({
      cloudPath: dataCVS,
      fileContent: buffer, //excel二进制文件
    })

  } catch (e) {
    console.error(e)
    return e
  }
}

appointmentApproval2.wxml

<view class="container">
       <view class="container_content">
              <view class="box">
                     <view class="mine_application">
                     <!-- 活动标题 -->
                            <view class="mine_application_title">
                            <view>已驳回的预约历史</view>
                     </view>
                     <block wx:for="{{list}}"></block>
                     <!-- 活动内容 点击可跳转至详情页面 -->
                     <view class="mine_application_content" wx:for="{{list}}" >
                                   <view class="event" bindtap="goDetail" data-id="{{item._id}}">
                                          <view class="appointmentTime">{{item.appointment}}</view>
                                          <view class="appointmentInstitute">预约组织:{{item.g1_orderInstitute}}</view>
                                          <view class='appointmentTeacher'>预约老师:{{item.g1_orderTeacher}}</view>
                                          <view class="time">{{item.time}}</view>
                                          <view class="subscriber">申请人:{{item.subscriber}}</view>

                                   </view>
                                   <!-- 右上角的状态栏 -->
                                   <!-- 用条件渲染来展示多种样式的活动内容 -->
                                   <!-- 状态为3代表已结束,2为已驳回,1为已通过,0为审核中 -->   
                                   <block wx:if="{{item.state==2}}">
                                   <!-- 已驳回 -->
                                   <view class="state_2">
                                   <view class="state_content">已驳回</view>
                                   </view>
                                   <!-- 活动下方的小点 -->
                                   <image src="../../icon/red.png" style="width: 11px;height: 11px;position: absolute;left: 15px;bottom: 15px;"></image>
                                   </block>




                     </view>

                     </view>
              </view>
              <view class="tabar">
                     <view class='goApprovalButton' bindtap="goApprovalPage">
                            <image src="../../icon/approval(1).png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">待审批</view>
                     </view>
                     <view class="goPassButton" bindtap="goPassPage">
                            <image src="../../icon/pass(1).png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">已通过</view>
                     </view>
                     <view class="goRejectButton" bindtap="goRejectPage">
                            <image src="../../icon/reject.png" style="width: 40px; height: 40px; margin-top: 5px;"></image>
                            <view class="button_content">已驳回</view>
                     </view>
              </view>
       </view>
</view>

appointmentApproval2.wxss

.mine_application{
       margin-left: 15px;
       margin-right: 15px;
     }
     .mine_application_title{
       border-bottom: 5rpx solid #A6A6A6;
       font-size: 28px;
       font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
     }
  
     .mine_application_content{
            height: 250px;
            width: 100%;
            display: flex;
            position: relative;
            box-shadow: 16rpx 8rpx 24rpx rgba(212,48,48, 0.1);
            margin-top: 15px;
            border-radius: 15px;
  
     }
     .event{
            font-size: 20px;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            position: relative;
            margin:15px;
            width: 90%;
            flex: 1;
     }
     .appointmentTime{
            margin-top: 0px;
            font-size: 16px;
            color: black;
     }
 .state_2{
       width: 80px;
       height: 40px;
       background-color:#FF5733;
       border-radius: 0 15px 0 15px;
       z-index: 2;
  
     }
     .state_content{
            position: relative;
            margin-top:10px ;
            margin-left: 15px;
            font-size: 12;
            color: white;
     }
    .appointmentInstitute{

         font-size: 20px;
         color:#FF5733;
         margin-top: 10px;
    }
    .appointmentTeacher{

       font-size: 20px;
       color:#611504;
       margin-top: 10px;
  }
  .time{
       margin-top: 10px;
       font-size: 18px;
       color: #A0A9BD;
  }
.goApprovalButton{
       position: absolute;
       bottom:0px ;
       left: 0%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
}
.goPassButton{
       position: absolute;
       bottom:0px ;
       left: 33.333%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
}

.goRejectButton{
       position: absolute;
       bottom:0px ;
       left: 66.666%;
       color:#FFFFFF;
       background-color:#FFFFFF;
       border-top: 2px solid grey;
       width: 33.333%;
       height: 70px;
       text-align:center;
       margin-top: 10px;
       
}
.button_content{
       font-size: 15px;
       color: black;
}
.box{
       margin-bottom: 50px;
}
.container{
       position: relative;
}

.container_content{
       position: relative;
       min-height: 100vh;
       box-sizing: border-box;
       padding-bottom: 60rpx;
       padding-top: 0rpx;
}

/* 有无这个属性都行,之后可能会用到 */
.tabar{
       width: 100%;
         text-align: center;
         letter-spacing: 4rpx;
         position: absolute;
         bottom: 0;
}

appointmentApproval2.js

const db = wx.cloud.database()
const _ = db.command
Page({
       data: {
              list:[],
       },
       onLoad(options) {
              console.log("列表携带的值",options)
              db.collection("appointment")
                            .where({
                                 state:2,
                            })
                            .get()
                            .then(res=>{
                                   console.log('查询数据库成功',res.data)
                                   //将返回的res.data里面的值赋值给list
                                   this.setData({
                                          list :res.data,
                                   })
                                   console.log("这是list",this.data.list)
                            })

       },
       onPullDownRefresh() {

       },
       onReachBottom() {

       },
       goDetail(e){
              console.log("点击了详情页面,将展示活动的id ",e)
              wx.navigateTo({
              // 跳转到活动详情页面并携带活动id
                url: '/pages/appointmentDetail/appointmentDetail?id=' +e.currentTarget.dataset.id 
              })
       },
       // 前往待审批页面
       goApprovalPage(){
              wx.redirectTo({
                     url: '../appointmentApproval/appointmentApproval',
                     })
       },
       // 前往已通过页面
       goPassPage(){
              wx.redirectTo({
                     url: '../appointmentApproval3/appointmentApproval3',
                     })
       },
       // 前往已驳回页面
       goRejectPage(){
              wx.showToast({
                     title: '您已经在当前页面',
                     icon:'none'
                     })    
       },
})

appointmentDetail.wxml

<view class="container">
       <view class="">
              <!-- 预约信息 -->
              <view>
                     <view class="subtitle_font">预约基本信息</view>
                     <view class="message">
                            <view class="font">申请预约的组织:{{list.g1_orderInstitute}}</view>
                            <view class="font">预约的老师:{{list.g1_orderTeacher}}</view>
                            <view class="font">预约的时间:{{list.appointment}}</view>
                            <view class="font">发出预约的时间:{{list.time}}</view>
                            <view class="font">预约事项:{{list.content}}</view>
                            <view class="font">预约人:{{list.subscriber}}</view>
                            <view class="font">手机号:{{list.subscriberPhone}}</view>
                            <block wx:if="{{list.state==2}}">
                                   <view class="font">驳回理由:{{list.rejectReason}}</view>
                            </block>
                     </view>
              </view>
       
       </view>
<!-- 条件渲染,只有待审批的活动才能显示 -->
<view>
       <block wx:if="{{list.state==0}}">
       <view class="subtitle_font">如果驳回,请备注驳回理由</view>
       <input bindinput="rejectReason" class="rejectReason" placeholder="驳回的理由"> </input>
       <button bindtap="pass" class="button_location1" style="margin-left:2%; width: 48%;">审批通过</button>
       <button bindtap="reject" class="button_location2" style="margin-right:2%;width:48%" >审批驳回</button>
       </block>
</view>
</view>

appointmentDetail.wxss

.rejectReason{
       margin-top: 15px;
       margin-left: 20px;
       margin-right:20px;
       margin-bottom: 15px;
       padding-top: 3px;
       padding-bottom: 3px;
       padding-left: 15px;
       padding-right:15px;
       border-radius: 30px;
       border: 1px solid #F2E6E6;
}
.inputborder{
       margin-top: 15px;
       margin-left: 20px;
       margin-right:20px;
       margin-bottom: 15px;
       padding-top: 3px;
       padding-bottom: 3px;
       padding-left: 15px;
       padding-right:15px;
       border-radius: 30px;
       border: 1px solid #F2E6E6;
}

.message{
       margin-top: 15px;
       margin-left: 20px;
       margin-right:20px;
       margin-bottom: 15px;
       padding-top: 3px;
       padding-bottom: 3px;
       padding-left: 15px;
       padding-right:15px;
       border-radius: 30px;
       border: 1px solid #F2E6E6;
       height: 400px;
       }
.font{
       margin-top: 5px;
       font-size: 20px;
       font-weight: 100;
}
/* 小标题内容 */
.subtitle_font{
       font-size: large;
       font-weight: 400;
       color: #D43C33;
       margin-left: 20px;
}
/* 审批通过 */
.button_location1{
       border-radius: 80rpx;
       margin-top: 5%;
       color:#FFFFFF;
       background-color: #D43030;
       box-shadow: 16rpx 8rpx 24rpx rgba(212,48,48, 0.35);
       float: left;

}
/* 审批驳回 */
.button_location2{
       border-radius: 80rpx;
       margin-top: 5%;
       color:#FFFFFF;
       background-color: #D43030;
       box-shadow: 16rpx 8rpx 24rpx rgba(212,48,48, 0.35);
       float: right;

}

.container{
       display: flex;
       width: 100%;
       height:700px;
       flex-direction: column;
       justify-content: space-between;
}

appointmentDetail.js

let eventid = ''
const DB = wx.cloud.database().collection("appointment")
Page({
       data:{
              list:[],
              id:"",
              rejectReason:""
       },
       onLoad(option){
              console.log("列表所携带的值",option)
              var id = option.id
              this.setData({
                     id :option.id
              })
              
              DB
              .doc(id)
              .get()
              .then(res=>{
                     this.setData({
                            list:res.data
                     })
                     
              })
              .catch(res=>{
                     console.log("活动详情页请求失败",res)
              })
       },
       pass(){
              let that = this;
              wx.showLoading({
                title: '正在上传中……',
                mask:true
              })
              DB.doc(this.data.id)
              .update({ // updata指 插入数据库中的userlist表;
                //将我们获取到的新值代入
                  data: { 
                         state:1
                  },
                }).then(res => {
                  console.log("上传成功", res)
                  wx.showToast({
                    title: '成功',
                  })
                  wx.navigateTo({
                    url: '../appointmentApproval/appointmentApproval',
                  })
                  .then(()=>{
                     wx.startPullDownRefresh()
                  })
                })
                .catch(err => {
                  console.log("上传失败", err)
                  wx.showToast({
                    title: '失败',
                    icon:"none"
                  })
                })
              

       },
       
       reject(){
              let that = this;
              wx.showLoading({
                title: '正在上传中……',
                mask:true
              })
              DB.doc(this.data.id)
              .update({ // updata指 插入数据库中的userlist表;
                //将我们获取到的新值代入
                  data: { 
                         state:2,
                         rejectReason: this.data.rejectReason
                  },
                }).then(res => {
                  console.log("上传成功", res)
                  wx.showToast({
                    title: '成功',
                  })
                  wx.navigateTo({
                    url: '../appointmentApproval/appointmentApproval',
                  })
                  .then(()=>{
                     wx.startPullDownRefresh()
                  })
                })
                .catch(err => {
                  console.log("上传失败", err)
                  wx.showToast({
                    title: '失败',
                    icon:"none"
                  })
                })
              

       },
       rejectReason(event){
              console.log("这是驳回输入框里的信息",event.detail.value)
              this.setData({
                     rejectReason:event.detail.value
              })
       }
})


题外话

这一系列文章会持续更新,手把手教你从零创建一个小程序项目!并且免费提供源码。如果有什么疑问欢迎大家在底下留言讨论!你的赞和收藏是我最大的动力!! 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
本程序结合了OA办公系统+HR人力资源管理系统+CRM客户关系管理系统集合而成。我们把程序设计信息化应用分为三个方面的内容:通用办公应用、业务管理和决策支持。采用现代最新技术,建立一种新概念的、开放的现代管理和办公环境,它以TCP/IP、广域网互连、路由、防火墙和网络管理技术为核心,建立一个安全可靠的网络应用平台。利用最新的ASP.NET平台、javascript和AJAX、SQLSERVER关系型数据库等技术,结合OA思想的独特设计,建立一个开放的信息资源管理平台。 利用数据库及分布式处理技术、模块化功能设计,构造信息存储与事务处理平台。该智能办公平台结合了广大机构的信息需求所研发,适用于全部的政府和企业的信息办公需要。程序具体商业价值型,同时也是完全的开源,可以供下载者研究和进行二次的开发均可。该智能办公平台具有如下几大特色亮点: 亮点一:office文档在线编辑。 两点二:动态生成各报表。 亮点三:工作流优化,方便新建任意格式审批单。 亮点四:功能授权于数据授权并用,可对多部门,多人员进行进行交叉授权。 亮点五:提供“智能窗体”向导,可任您快速且自由地制作多功能的网页办公系统。 亮点六:自定义工作流程,系统所有参数可自定义配置,支持多分公司、多部门架构。 亮点七:系统基于B/S结构,客户零管理,避免了C/S系统维护的烦琐,降低维护成本。 亮点八:细分的权限管理,可满足用户不同的权限管理要求。 亮点九:灵活的配置,可方便自定义工作表单、环节和流程。 亮点十:良好的系统开放性和可扩展性,为企业轻松架构Internet应用。 政 府、企事业单位的信息化建设是一个集办公自动化、业务管理、领导决策等应用为一体综合信息管理系统,是一个应用覆盖面广泛,涉及部门多的应用系统。财务、 人事、或业务管理系统往往只是涉及一个部门,或者一部分人员使用的业务管理系统。而整个单位的信息化涉及各个部门和各项业务,使用人员包括单位的最高级领 导、管理部门和全体员工。因此,政府和企业的信息化是一个涉及面广泛的综合信息管理系统。该OA办公程序是一套通用的信息管理平台,平台主要包含八个主要部分:个人事务、工作流程、公共事务、信息交流、人力资源、销售管理、附件程序和系统管理。 个人事务:主要是与个人办公、通讯、考勤、会议等等相关内容的整合。 工作流程:涉及个人的网络公章管理及使用记录,各种表单的定制、别管理,工作流的管理及工作管理。 公共事务:涉及工作计划、办公用品的管理、会议、车辆以及固定资产的管理。 信息交流:用于建立公司企业内部的交流平台及短信发送。 人力资源:对公司人员的信息档案有一定的管理,涵盖了人事档案、考勤批示、统计、薪资管理、培训记录及奖惩记录等等。 销售管理:大致分为客户方面的管理、产品方面管理以及销售方面管理的综合业务管理。 附件管理:提供常用的日历、世界时间查询、常用网址的保存(便于一键打开特定的地址)、全国各个省、县、市的邮政编码和电话区号。 系统管理:用于规划本单位信息系统的结构、内容、印章、公告、红头文件的管理。按照组织机构、业务分、功能需要设计信息系统的菜单,按照用户所属的部门、角色、职位、管理范围进行管理和权限指派。其中主要的功能模块和说明如下解释: 个人办公: 内部邮件---系统内部的信息交流、文件交流、信息提醒等 Internet邮件---接口外部邮箱,采用pop3和smtp协议代收代发 单位公告通知---管理公告通知、新闻等信息,可选定特定部门发送 投票---内部信息投票,每个用户拥有一次投票权利 手机短信---发送内部或者外部的手机短信消息,用于提醒等 日程安排---个人日程以日历形式重点体现,到期自动提醒 工作日志---工作过程中的记录以及工作日志等 通讯簿 --- 包含各种分,主要用于联系使用 个人设置 --- 设置个人参数、邮箱参数、提醒参数、修改密码等 审批流程: 新建工作---新建新的审批工作流,选定需要的工作新建即可 我的工作--- 个人发起的所有工作,包括已审批、未审批的所有工作 待办工作---需要当前用户进行办理或者审批的工作列表 已办工作---当前用户已经办理过的各项工作,包含历史工作 工作查询---查询系统中工作的信息,全面检索 工作监控---管理员监控运行,发现问题,可强制干预 归档工作---已办理完成的工作,自动进行归档 工作委托 --- 当前用户指定办理人,所有待办事项自动提交到委托人办理 流程设置 --- 自定义流程、自定义表单、表单各个字段在流程中权限控制 印章管理 --- 管理公章与私章,查看印章的各项使用日志等 公文收发: 接收文件--- 需要接受的文件,未签收时有颜色标注 传阅文件 --- 传阅发送出去文件 接收分 --- 按照指定文件夹分查看 传阅分 --- 传阅文件夹个人分查看 工作管理: 我的计划---个人工作计划,可共享给其他指定用户协同查看 协同计划--- 其他用户协同共享查看的工作计划信息 我的汇报---个人工作汇报,可共享给其他指定用户协同查看 协同汇报---其他用户协同共享查看的工作汇报信息 下属任务: 我的任务 --- 个人接收到的各项任务,提交工作任务报告 任务分配--- 对下属用户分派工作任务,实时监控任务情况 下属日程 --- 下属员工的日程安排信息 下属日志 --- 下属员工的工作日志信息 下属计划--- 下属员工的工作计划信息 下属汇报 --- 下属员工的工作汇报信息 下属邮件 --- 下属员工的内部邮件信息 下属客户--- 下属员工的客户资料信息 知识文档: 个人文件 --- 同与网络硬盘、个人文件柜存储等文件存储 单位文件 --- 单位各文件存储区 项目文件 --- 项目实施、进度、评审等文件存储 电子刊物 --- 电子刊物等文件存储 重要文件 --- 特别重要的文件额外存储 机密文件 --- 机密文件存储 知识库 --- 各项知识库、技术资料、学习资料、单位规范等 技术文件 --- 技术文件存储 共享文件 --- 查看各共享的文件资料 回收站 --- 删除的文件,可恢复或者彻底删除 扩展应用: 资产管理--- 管理固定资产、仪器、办公用品等 培训管理--- 管理培训信息 会议管理 --- 各项会议会议、上传会议记录 车辆管理 --- 车辆信息、使用、维修、保险、加油等 图书管理 --- 图书信息、借阅、归还等 档案卷库 --- 各档案分卷库保存、销毁 考试管理 --- 在线考试、可分题库、题目型、试卷制定、自动评分等 学习管理--- 在线学习、学习心得、领导批注等 客户管理: 会员管理 --- 会员信息管理,即为个人别的客户 我的客户 --- 个人客户资料、联系记录、需求等 客户管理 --- 管理所有客户资料,联系人、联系记录、需求计划等 进销存: 产品管理--- 产品管理、库存列表显示、库存报警等 销售管理 --- 销售合同、产品销售出库、利润等 采购管理 --- 采购合同、产品采购入库等 供应商管理 --- 管理各个供应商、供应商联系人 项目管理: 项目信息 --- 项目各项信息、状态等 评审信息 --- 评审记录 项目进度--- 项目具体进度安排、时间进度 收款信息 --- 收款具体情况,按照项目分 项目实施 --- 项目的具体实施情况 报销申请 --- 项目单独报销,也可使用审批流程中的自定义流程 报销管理 --- 审批报销记录,复杂流程可使用审批流程 项目利润 --- 核算具体利润情况 数据统计 --- 数据各项统计 人力资源: 考勤管理 --- 考勤记录、考勤设置、查询、统计等 人事档案--- 人事基本资料维护 人事合同--- 合同管理情况 奖惩记录 --- 奖惩各记录管理 奖惩制度 --- 各具体制度安排、单位规章制度等。 应聘简历 --- 简历管理,建立单位人才库 面试管理 --- 具体面试情况管理 绩效考核 --- 绩效考核数据上报等 绩效参数 --- 绩效各项参数的设置 薪酬管理--- 薪酬各数据管理 薪酬参数 --- 各个参数设置 报表中心: 报表分--- 报表分设置,根据需要可分多个别 报表管理--- 动态定制报表、动态数据抓取。报表可自定义。 信息交流: 论坛BBS---论坛各个信息、帖子发帖信息 版块设置 --- 版块具体设置 内部聊天室 --- 各个聊天室进入后可自由聊天 聊天室设置 ---聊天室的基本设置 组织机构: 单位信息查询 --- 查询单位基本信息 部门信息查询 --- 查询部门信息 用户信息查询 --- 查询用户个人信息 附件程序: 电话区号查询--- 电话区号查询 邮政编码查询---邮政编码查询,超级链接到网址 列车时刻查询 --- 链接到列车时刻查询网址 公交线路查询 --- 公交线路查询 法律法规查询 --- 法律法规各项资料超级链接查询 休闲游戏 --- 链接到游戏网 万年历--- 日历基本信息 世界时钟 --- 时间查询 常用网址---常用的网站

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hiddenSharp429

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值