钉钉小程序开发案例-fitnessManagement

介绍,健身记录管理,完全就是一个单机应用
在这里插入图片描述
在这里插入图片描述

一、首页
index.axml

<!--textarea.axml-->
<view>
<view class="summary">
  <view class="fontLarger">fitness summary</view>
  <label a:for="{
     
     {summaries}}">
    <label class="item" data-index={
     
     {index}} data-content={
     
     {item.content}} onTap="updateNote">
      <label class="item">{
   
   {item.fitType}}</label>
      <label class="item">{
   
   {item.fitCnt}}</label>
    </label>
  </label>
</view>
<view class="page" a:for="{
     
     {notes}}">
  <view class="card" data-index={
     
     {index}} data-content={
     
     {item.content}} onTap="updateNote">
    <view class=""><label>fitness type: </label>{
   
   {item.fitType}}</view>
    <view class=""><label>fitness count: </label>{
   
   {item.fitCnt}}</view>
    <view class=""><label>fitness time: </label>{
   
   {item.fitTime}}</view>
  </view>
</view>
<modal show="{
     
     {showSearchModal}}" height='30%' onCancel="searchModalCancel" onSubmit='searchModalSubmit'>
  <view class="remind_del"><image mode="scaleToFill" src="/page/image/remind_del.png"/></view>
</modal>
<view><button class="btn" onTap="toPage13">增加</button></view>
<view><button style="bottom:30px;background-color:red;" class="btn" onTap="deleteAll">删除</button></view>
</view>

index.acss

.page {
    
    
  font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
  padding: 8rpx;
  flex: 1;
}
.content{
    
    
  font-size: x-large;
  color: black;
  font-weight: bolder;
}

.item{
    
    
  font-size: small;
  margin-right: 5px;
  color: black;
}

.card{
    
    
  width: 80%;
  margin-left: auto;
  margin-right: auto;
  border: 1px solid rgb(216, 10, 206);
  border-radius: 15px;
  padding: 5px;
  margin-top: 5px;
  font-size: small;
}

.fontLarger{
    
    
  font-size: larger;
  font-weight: bolder;
}

.summary{
    
    
  width: 80%;
  margin-left: auto;
  margin-right: auto;
}

.btn_img{
    
    
  z-index: 9;
  position: fixed;
  background: url('/page/image/del.png');
  margin-top: -50px;
  margin-left: 280px;
  width: 50px;
  height: 50px;
}

.remind_del{
    
    
  margin: 0 auto;
  width:300px;
  height:60px;
}

.btn {
    
    
  z-index: 10;
  width: 50px;
  height: 50px;
  color: cornsilk;
  font-family: 黑体,宋体,Arieal;
  font-weight: bold;
  background-color: gray;
  border-radius: 50%;
  border: 1px solid black;
  right: 30px;
  bottom: 100px;
  position: fixed;
}

index.js

Page({
    
    
  data: {
    
    
    notes: [],
    summaries: [],
    array: ['仰卧起坐','俯卧撑','引体向上','自重深蹲','俯身W抬头','窄距俯卧撑','屈腿两头起','5kg哑铃','站立扭腰','单车推拉','反转上杠','跳绳','跑步','游泳','平板支撑','握力器'],
   showSearchModal: false,
  },

  compare(prop,align){
    
    
    return function(a,b){
    
    
          var value1=a[prop];
          var value2=b[prop];
          if(align=="positive"){
    
    //正序
              return new Date(value1)-new Date(value2);
          }else if(align=="inverted"){
    
    //倒序
              return new Date(value2)-new Date(value1);
          }
    }
  },
  onShow(){
    
    
    dd.getStorage({
    
    
  key: 'fitness_record',
  success: (res) => {
    
    
    if(res.data!==null){
    
    
      const notes = res.data;
      console.log('notes',notes)
      //对数据进行排序
      notes.sort(this.compare('fitTime','inverted'));
      console.log("倒叙排列",notes)
      let groups={
    
    };
      notes.forEach(c=>{
    
    
        let value=c['fitType'];
        groups[value]=groups[value]||[];
        groups[value].push(c);
    });
    console.log('groups',groups)
    var summaries = []
    for(var key in groups){
    
    
      var cnt = 0;
      for(var item of groups[key]){
    
    
        cnt += parseInt(item.fitCnt);
      }
      var summ = {
    
    }
      summ['fitType']= key;
      summ['fitCnt']=cnt;
      summaries.push(summ);
    }
    console.log('summaries',summaries)
    this.setData({
    
    notes})
    this.setData({
    
    summaries})
    }
  },
  fail: function(res){
    
    
    dd.alert({
    
    content: res.errorMessage});
  }
});
  },
  toPage13(){
    
    
    dd.redirectTo({
    
    url:'/page/page13_1/index'});
  },
  updateNote(event){
    
    
    const content= event.target.dataset.content;
    const index= event.target.dataset.index;
    dd.redirectTo({
    
    url:'/page/page13_1/index?content='+content+'&index='+index});
  },
  del(event){
    
    
    const index= event.target.dataset.index;
    console.log(index);
    //设置data,设置缓存
    const notes = this.data.notes;
    notes.splice(index,1);
    this.setData({
    
    notes});
    //写入缓存
    dd.setStorage({
    
    
    key: 'notes',
    data: notes,
    success: function() {
    
    
    dd.alert({
    
    content: '删除成功'});
      }
    });
  },
  deleteAll(){
    
    
    this.setData({
    
    showSearchModal: true})
  },
  searchModalCancel(){
    
    
  this.setData({
    
    
  showSearchModal: false,
  });
  },
  searchModalSubmit(){
    
    
  this.setData({
    
    
  showSearchModal: false,
  });
  var _this = this;
  dd.removeStorage({
    
    
  key: 'fitness_record',
  success: function(){
    
    
    dd.alert({
    
    content: '删除成功'});
    _this.setData({
    
    notes: []})
  }
});
},

});

index.json

{
    
    
    "defaultTitle": "fitness management",
    "usingComponents": {
    
    
        "modal": "/page/component/modal/modal" 
    }
}

第二页
index.axml

<!--textarea.axml-->
<view class="page">
  <view class="page-section">
    <form onSubmit="bindFormSubmit">
        <picker onChange="bindPickerChange" value="{
     
     {index}}" range="{
     
     {array}}">
          <view class="row">
            <view class="row-extra"><label>fitness Type:</label>{
   
   {array[index]}}</view>
          </view>
        </picker>
        <view class="row">
        </view>
        <label>fitness count:</label><input name="fitCnt" type="number" value="{
     
     {record.fitCnt}}"/>
      <view class="page-section-btns">
        <button onTap="back" size="mini" type="primary">返回</button>
        <button form-type="submit" size="mini" type="primary">提交</button>
      </view>  
    </form>
  </view>
</view>

index.js

Page({
    
    
  data: {
    
    
    index:0,
    array: ['仰卧起坐','俯卧撑','引体向上','自重深蹲','俯身W抬头','窄距俯卧撑','屈腿两头起','5kg哑铃','站立扭腰','单车推拉','反转上杠','跳绳','跑步','游泳','平板支撑','握力器'],
    record: {
    
    }
  },
  bindPickerChange(e) {
    
    
    console.log('picker发送选择改变,携带值为', e.detail.value);
    this.setData({
    
    
      index: e.detail.value,
    });
  },
  onLoad(options){
    
    
    console.log('进入')
  },
  onShow(){
    
    
  },
  bindButtonTap() {
    
    
    this.onFocus();
  },
  onFocus() {
    
    
    this.setData({
    
    
      focus: true,
    });
  },
  onBlur() {
    
    
    this.setData({
    
    
      focus: false,
    });
  },

  bindTextAreaBlur(e) {
    
    
    console.log(e.detail.value);
  },
  bindFormSubmit(e) {
    
    
    console.log('e.detail.value.fitCnt',e.detail.value.fitCnt)
    if(e.detail.value.fitCnt===""){
    
    
      console.alert("提交失败,内容为空!");
      return;
    }

    var tempNotes;

    //先读出缓存数据
    dd.getStorage({
    
    
  key: 'fitness_record',
  success: (res) => {
    
    
    console.log("缓存数据:",res.data);
    if(res.data===null){
    
    
      tempNotes = [];
    }else{
    
    
      tempNotes = res.data;
    }

    const record = {
    
    
      fitType: this.data.array[this.data.index],
      fitCnt: e.detail.value.fitCnt,
      fitTime: new Date().toLocaleDateString()+' '+new Date().toLocaleTimeString(),
    }
    console.log('record',record)
    const index = this.data.record.index;
    if(index){
    
    
      tempNotes[index] = record;
    }else{
    
    
      tempNotes.push(record);
    }
    console.log("写入缓存数据",tempNotes)
    //写入缓存
    dd.setStorage({
    
    
    key: 'fitness_record',
    data: tempNotes,
    success: function() {
    
    
    dd.alert({
    
    content: '写入成功'});
    }
    });

  },
  fail: function(res){
    
    
    dd.alert({
    
    content: res.errorMessage});
  }
  });
  },
  back(){
    
    
    dd.redirectTo({
    
    url:'/page/page13/index'});
  }
});

index.json

{
    
    
    "defaultTitle": "fitness management"
}

自定义组件
page/component/modal
modal.axml

<view class='mask' a:if='{
     
     {show}}' onTap='clickMask'>
 <view class='modal-content' style='height:{ 
        { 
        height}}'>
 <scroll-view scroll-y class='main-content'>
 <slot></slot>
 </scroll-view>
 <view class='modal-btn-wrapper'>
 <view class='cancel-btn' style='color:rgba(7,17,27,0.6)' onTap='cancel'>取消</view>
 <view class='confirm-btn' style='color:#13b5f5' onTap='submit'>确定</view>
 </view>
 </view>
</view>

modal.acss

.mask{
    
    
 position: absolute;
 top: 0;
 bottom: 0;
 width: 100%;
 height: 100%;
 display: flex;
 justify-content: center;
 align-items: center;
 background-color: rgba(0,0,0,0.4);
 z-index: 9999;
}

.modal-content{
    
    
 flex-direction: column;
 width: 90%;
 /* height: 80%; */
 position: fixed;
 top: 10%;
 left: 5%;
 background-color: #fff;
 border-radius: 10rpx;
}

.modal-btn-wrapper{
    
    
 display: flex;
 flex-direction: row;
 height: 100rpx;
 line-height: 100rpx;
 background-color: #fff;
 border-radius: 10rpx;
 border-top: 2rpx solid rgba(7,17,27,0.1);
}

.cancel-btn, .confirm-btn{
    
    
 flex: 1;
 height: 100rpx;
 line-height: 100rpx;
 text-align: center;
 font-size: 32rpx;
}

.cancel-btn{
    
    
 border-right: 2rpx solid rgba(7,17,27,0.1);
}

.main-content{
    
    
 flex: 1;
 height: 100%;
 overflow-y: hidden; 
}

modal.js

/**
 * 自定义modal浮层
 * 使用方法:
 * <modal show="{
    
    {showModal}}" height='80%' onCancel="modalCancel" onSubmit='modalSubmit'>
 <view>你自己需要展示的内容</view>
 </modal>
 
 属性说明:
 show: 控制modal显示与隐藏
 height:modal的高度
 onCancel:点击取消按钮的回调函数
 onSubmit:点击确定按钮的回调函数
 
 */
 
 Component({
    
    
 
 /**
 * 组件的属性列表
 */
 props: {
    
    
 // modal的默认高度
 height: '60%',
 
 //是否显示modal
 show: false,
 
 // submit()
 onSubmit:(data) => console.log(data),
 
 // onCancel()
 onCancel:(data) => console.log(data),
 },
 
 /**
 * 组件的初始数据
 */
 data: {
    
    
 
 },
 
 /**
 * 组件的方法列表
 */
 methods: {
    
    
 clickMask() {
    
    
 // this.setData({show: false})
 },
 
 cancel(e) {
    
    
 // this.setData({ show: false });
 this.props.onCancel(e);
 },
 
 submit(e) {
    
    
 // this.setData({ show: false });
 this.props.onSubmit(e);
 }
 }
 })

modal.json

 {
    
    
  "component": true,
  "usingComponents": {
    
    }
 }

猜你喜欢

转载自blog.csdn.net/AnalogElectronic/article/details/127294566