微信小程序实现仿钉钉报销页面新增报销明细功能

先上一个效果图,要实现的效果就是报销明细的组别里,填写相应的字段,点击新增一条报销,可以在组别里增加一组。提交时计算出报销的总金额,确认无误后提交。
微信小程序实现仿钉钉报销页面新增报销明细功能_第1张图片

UI组件我这边使用的是vant weapp组件库

第一步是基础的组件json配置

{
  "usingComponents": {
    "van-field": "@vant/weapp/field/index",
    "van-button": "@vant/weapp/button/index"
  }
}

首先,我们先对初始的页面进行布局,本来我是想将所有的可见项都放进一个form表单中一起提交,但是碍于接口采用了报销明细条目特殊符号拼接的传参方式,如果全部放进去,遍历表单数据的时候会不方便,所以,我只把明细组别里的数据放进表单中。

wxml:




    
      审核单号
    
  
  
    
  

  
    
      申请人姓名
    
  
  
    
  

  
    
      申请人所属部门
    
  
  
    
  

报销明细 类别 {{subs[index].typename}} + 新增一条报销

wxss:

.form-group-title-box  {
  padding-left: 8px;
  padding-bottom: 8px;
}

.form-group-title {
  color: rgb(132, 145, 151);
  font-size: 12px;
}

.group-separator {
  background-color: rgb(245, 246, 249);
  height: 8px;
}

.add-new-button {
  height: 44px;
  text-align: center;
}

.add-new-button {
  font-size: 16px;
  color: rgb(24, 113, 248);
}


.submit-button {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  background-color: rgb(24, 113, 248);
  height: 50px;
}
.picker {
  display: flex;
  flex-direction: row;
  align-items: center;
  height: 40px; 
  background-color: white
}

.picker-inner-title {
  width: 100px;
  padding-left: 16px;
  font-size: 14px;
  color: rgb(100, 101, 102);
}

.picker-inner-text {
  font-size: 14px;
}

.submit-button-inner-text {
  font-size: 14px;
  color: white;
  text-align: center;
}

page {
  height: 100%;
  background-color: rgb(245, 246, 249)
}

写js之前想到一个问题,需求是报销的申请是可以回来查看的,所以,只能使用map+数组的形式来构建列表,这样问题就来了,我填写完一组后,新增一组,我该如何把之前已经填写的那一组放进列表数组里去呢。。。,不解决这个问题,填写完一组新增就白写了。。。

本来我一开始的做法是,声明一个文件内的全局对象,每次监听到input值变化的时候,我就更新那个对象,新增时,将这个对象push进数组,不过事实证明,我想多了,这样push进来了,但是数组是倒着的。。。,只能另想一个解决方案。

我为啥不直接修改数组里面每一个对象的属性呢,但是,setData可以修改属性对象里面的值吗,最后,我找到了方法

js

Page({
  data: {
    array: ['差旅费', '误餐费', '招待费', '燃料费', '过桥过路费', '办公费', '电话费', '房租', '水电', '运费', '取暖费', '修理费', '其他'],
    orderNumText: '10000922222',
    nameText: wx.getStorageSync('userinfo').opername,
    depText: wx.getStorageSync('userinfo').depname,
    namePlaceholder: '请输入姓名',
    depPlaceholder: '请输入部门',
    orderText: '单据号',
    pickerIndex: 0,
    dic: {
      typename: '',
      memo: '',
      fee: '',
      imgurl: '',
    },
    subs: [{
      typename: '',
      memo: '',
      fee: '',
      imgurl: '',
    }],
    imgurl: ''
  },

  handleAddNew: function (e) {
    // console.log(this.data.dic)
    // this.data.subs.push(this.data.dic)
    console.log(this.data.subs)
    var newDic = {
      typename: '',
      memo: '',
      fee: '',
      imgurl: '',
    }
    this.data.subs.push(newDic)
    this.setData({
      subs: this.data.subs
    })
    console.log(this.data.subs)
  },
  onOrderNumChange: function(e) {
    this.setData({
      orderNumText: e.detail
    })
  },
  onUserNameChange: function(e) {
    this.setData({
      nameText: e.detail
    })
  },
  onDepNameChange: function(e) {
    this.setData({
      depText: e.detail
    })
  },
  onTypenNameChage: function (e) {
    console.log('onTypenNameChage')
    var val = e.detail
    let index = e.currentTarget.dataset.index
    let typename = 'subs['+ index +'].typename'
    this.setData({
      [typename]: val
    })
  },
  onUseChange: function (e) {
    var val = e.detail
    let index = e.currentTarget.dataset.index
    let memo = 'subs['+ index +'].memo'
    this.setData({
      [memo]: val
    })
  },
  onAmountChange: function (e) {
    var val = e.detail
    let index = e.currentTarget.dataset.index
    let fee = 'subs['+ index +'].fee'
    this.setData({
      [fee]: val
    })
  },
  onAppendixChange: function (e) {
  },
  bindPickerChange: function (e) {
    // console.log('bindPickerChange')
    // this.setData({
    //   pickerIndex: e.detail.value
    // })
    var obj = e.detail
    var val = this.data.array[obj.value]
    console.log(this.data.array)
    let index = e.currentTarget.dataset.index
    let typename = 'subs['+ index +'].typename'
    this.setData({
      [typename]: val
    })
  },

  formSubmit: function (e) {
    let obj = e.detail.value
    if (JSON.stringify(obj) === '{}') {
      wx.showToast({
        title: '请填写至少一条报销申请后再提交',
        icon: 'none',
        duration: 2000
      })
      return
    }
    var dataArr = ''
    var totalamount = 0
    for (let key in obj) {
      if (key.indexOf("amount") != -1) {
        totalamount += parseInt(obj[key])
      }
      let ele = obj[key]
      dataArr = dataArr + '$' + `${ele}`
    }
    console.log(totalamount)
  },
})

好了,到这里问题就解决了,还有一个小问题,就是,如果将input和 picker绑定在一起的时候,可能会出现两种情况

第一、弹出的键盘遮挡住picker
第二、弹出picker选中其中一项,选中的值不会填充进input

所以,咱们尽量不要将input和picker一起使用,我的处理是,自定义了一个组件,view里面包含了一个用作前缀的view,还有中心用于文本展示的text

wxml

    
      
        
        类别
        {{subs[index].typename}}
      
    

wxss

.picker {
  display: flex;
  flex-direction: row;
  align-items: center;
  height: 40px; 
  background-color: white
}

.picker-inner-title {
  width: 100px;
  padding-left: 16px;
  font-size: 14px;
  color: rgb(100, 101, 102);
}

.picker-inner-text {
  font-size: 14px;
}

效果几乎和vant的input组件一样

嘿嘿

你可能感兴趣的:(微信小程序,js)