云笔记小程序的实现

1.前言

云笔记, 是基于HotApp小程序统计云后台提供的api接口开发的一个微信小程序。

2.功能

  • 离线保存笔记

  • 云端数据同步, 更换了设备也可以找到以前的笔记

  • 接入了好推二维码提供的数据统计工具, 可以到平台上查看用户分析、留存分析、事件分析。

3.界面效果

***HotApp云笔记,基于HotApp小程序统计云后台

***免费云后台申请地址 https://weixin.hotapp.cn/cloud

***API 文档地址:https://weixin.hotapp.cn/api

四、代码实现

{
    "pages": [
        "pages/index/index",
        "pages/feedback/index",
        "pages/edit/index",
        "pages/create/index"
    ],
    "window": {
        "navigationBarBackgroundColor": "#ff9b6e",
        "navigationBarTitleText": "HotApp云笔记",
        "navigationBarTextStyle": "black",
        "backgroundTextStyle": "light",
        "backgroundColor": "#efeff4",
        "enablePullDownRefresh": true
    },
    "tabBar": {
        "color": "#b3b3b3",
        "selectedColor": "#fc8e5d",
        "backgroundColor": "#f5f5f7",
        "borderStyle": "white",
        "position": "bottom",
        "list": [
            {
                "pagePath": "pages/index/index",
                "text": "记事本",
                "iconPath": "images/icon1.png",
                "selectedIconPath": "images/sicon1.png"
            },
            {
                "pagePath": "pages/feedback/index",
                "text": "反馈",
                "iconPath": "images/icon2.png",
                "selectedIconPath": "images/sicon2.png"
            }
        ]
    },
    "sitemapLocation": "sitemap.json"
}
<!--/*
***HotApp云笔记,基于HotApp小程序统计云后台
***免费云后台申请地址 https://weixin.hotapp.cn/cloud
***API 文档地址:https://weixin.hotapp.cn/api

*/-->
<!--index.wxml-->
<view class="container">
    <!--写笔记-->
    <view class='col'>
        <view class='item add_box'  bindtap="onNewItem">
            <image class="add_bg" src="../../images/add.png" style="width:120rpx;height:120rpx;"></image>
        </view> 
        <!--没有笔记时的提示-->
        <block wx:if="{{items.length < 1}}">
            <view class='tips'>
                <view class='tips_box'>
                    <image class='tips_icon' src="../../images/tips_icon.png"style="width:70rpx;height:70rpx;"></image>
                </view>
                <view class='tips_txt'>点此添加新记事本</view>
            </view>
        </block>
    </view>

    <!--笔记列表-->
    <block wx:for="{{items}}">
        <view class="col" wx:if="{{ item.state != 3 }}">
            <view class='item notepad {{item.class}}' data-key="{{item.key}}" bindtap="onEditItem">
                <view class='content'>
                    <view class='txt'>{{item.value.title}}</view>
                </view>
                <view class='bottom'>
                    <view class='txt'>
                        {{item.year}} {{item.month}} {{item.date}}
                    </view>
                </view>
            </view>
        </view>
    </block>
</view>
/*
***HotApp云笔记,基于HotApp小程序统计云后台
***免费云后台申请地址 https://weixin.hotapp.cn/cloud
***API 文档地址:https://weixin.hotapp.cn/api
*/
var app = getApp();

Page({
  data: {
    items: [],
  },

  /**
   * 首次渲染事件
   */
  onShow: function() {
    this.setData({
      items: []
    });
    // 获取数据
    var that = this;
    app.globalData.hotapp.wxlogin(function(res) {
        that.onLoadData();
    });
  },

  /**
   * 新增笔记事件
   */
  onNewItem: function(event) {
    wx.navigateTo({
      url: "../create/index"
    })
  },

  /**
   * 编辑笔记事件
   */
  onEditItem: function(event) {
    wx.navigateTo({
       url: '../edit/index?key=' + event.currentTarget.dataset.key
    })
  },

  /**
   * 获取数据事件
   */
  onLoadData: function() {
    var that = this;
    app.getItems(function(items) {
      that.setData({
        items: items
      });
    });
  },

  /**
   * 下拉刷新事件, 数据同步
   */
  onPullDownRefresh: function() {
    wx.showToast({
      title: '正在同步数据',
      icon: 'loading'
    });

    // 临时变量
    var tempData = this.data.items;
    var that = this;
    // 先检查版本, 如果和服务器版本不同, 则需要从服务器拉取数据
    app.checkVersion(function(shouldPullData) {
      if (shouldPullData) {
        var filters = {
          prefix: app.globalData.hotapp.getPrefix('item')
        };
        // 从服务器拉取所有数据
        app.globalData.hotapp.searchkey(filters, function(res) {
          if (res.ret == 0) {
            // 拉取成功, 更新版本号
            app.updateVersion(function(success) {
              if (success) {
                // 更新版本号之后把本地数据和服务器数据合并去重
                tempData = that.syncServerDatatoLocal(tempData, res.data.items);
                tempData.forEach(function(item, index, arr) {
                  arr[index] = app.formatItem(item);
                  arr[index].state = 2;
                });
                // 更新视图数据
                that.setData({
                  items: tempData
                });
                // 把合并好的数据存缓存
                
                wx.setStorageSync('items', tempData);
                that.syncLocalDataToServer(tempData);
              }
            });
          }
        }); 
      } else {
        // 版本号和服务器相同, 则不需要从服务器上拉取数据, 直接同步数据到服务器
        that.syncLocalDataToServer(tempData);
      }
    });
  },

  /**
   * 将本地数据同步到服务器
   */
  syncLocalDataToServer: function(data) {
    var that = this;
    // 遍历所有的数据
    data.forEach(function(item, index, items) {
      app.globalData.hotapp.replaceOpenIdKey(item.key, function(newKey) {
        if (newKey) {
          item.key = newKey;
          // 如果还有数据没有同步过, 则调用post接口同步到服务器
          if (item.state == 1) {
            app.globalData.hotapp.post(item.key, item.value, function(res) {
              if (res.ret == 0) {
                // 同步成功后更新状态, 并存缓存
                item.state = 2;
                item = app.formatItem(item);
                that.setData({
                  items: items
                });
                wx.setStorageSync('items', items);
              }
            });
          }

          // 如果数据被删除过, 则调用delete接口从服务器删除数据
          if (item.state == 3) {
            app.globalData.hotapp.del(item.key, function(res) {
              if (res.ret == 0 || res.ret == 103) {
                // 服务器的数据删除成功后, 删除本地数据并更新缓存
                items.splice(index, 1);
                that.setData({
                  items: items
                });
                wx.setStorageSync('items', items);
              }
            });
          }
        } else {
          return;
        }
      })
    });
  },

  /**
   * 将服务器的数据同步到本地
   */
  syncServerDatatoLocal: function(localData, serverData) {
    var that = this;

    // 通过hash的性质去重, 服务器数据覆盖本地数据
    // 但是要保留本地中状态为已删除的数据
    // 删除的逻辑不在这里处理
    var localHash = new Array();
    localData.forEach(function(item) {
      localHash[item.key] = item;
    });

    var serverHash = new Array();
    serverData.forEach(function(item) {
      serverHash[item.key] = item;
    });

    // 先把服务器上有的数据但是本地没有的数据合并
    serverData.forEach(function(item) {
      var t = localHash[item.key];
      // 有新增的数据
      if (!t) {
        localHash[item.key] = item;
      }
      // 有相同的key则以服务器端为准
      if (t && t.state != 3) {
        item.state = 2;
        item = app.formatItem(item);
        localHash[item.key] = item;
      }
    });

    // 然后再删除本地同步过的但是服务器上没有的缓存数据(在其它设备上删除过了)
    localData.forEach(function(item, index, arr) {
      var t = serverHash[item.key];
      if (!t && item.state == 2) {
        console.log(item);
        delete localHash[item.key];
      }
    });

    // 将hash中的数据转换回数组
    var result = new Array();
    for (var prob in localHash) {
      result.push(localHash[prob]);
    }

    // 按时间排序
    result.sort(function(a, b) {
      return a.create_time < b.create_time;
    });

    console.log(result);
    return result;
  }
})

五、源码下载

云笔记小程序实现.zip

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/543680.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 入门教程||Java 关键字

Java 关键字 Java教程 - Java关键字 Java中的关键字完整列表 关键词是其含义由编程语言定义的词。 Java关键字和保留字&#xff1a; abstract class extends implements null strictfp true assert const false import package super try …

OpenHarmony实战开发-Actor并发模型对比内存共享并发模型

内存共享并发模型指多线程同时执行复数任务&#xff0c;这些线程依赖同一内存并且都有权限访问&#xff0c;线程访问内存前需要抢占并锁定内存的使用权&#xff0c;没有抢占到内存的线程需要等待其他线程释放使用权再执行。 Actor并发模型每一个线程都是一个独立Actor&#xf…

【vs2019】window10环境变量设置

【vs2019】window10环境变量设置 【先赞后看养成习惯】求关注点赞收藏&#x1f60a; 安装VS2019时建议默认安装地址&#xff0c;最好不要改动&#xff0c;不然容易出问题 以下是安装完VS2019后环境变量的设置情况&#xff0c;C:\Program Files (x86)\Microsoft Visual Studi…

20240414,类的嵌套,分文件实现

笑死&#xff0c;和宝哥同时生病了 一&#xff0c;封装-案例 1.0 立方体类 #include<iostream>//分别用全局函数和成员函数判定立方体是否相等 using namespace std;class Cube { public:int m_area;int m_vol;int geth(){return m_h;}int getl() { return m_l; }int…

【群智能算法改进】一种改进的火鹰优化算法 改进的IFHO算法【Matlab代码#77】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 原始火鹰优化算法1.1 种群初始化1.2 火鹰点火阶段1.3 猎物移动阶段 2. 改进的火鹰优化算法2.1 Tent映射种群初始化2.2 非线性复合自适应惯性权重随机抉择策略 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源…

大模型实战案例:8卡环境微调马斯克开源大模型 Grok-1

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

【LeetCode: 705. 设计哈希集合 + 数据结构设计】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

免费VPS云服务器汇总,最长永久免费使用

目前云服务器市场竞争很激烈&#xff0c;为了方便吸引上云&#xff0c;很多云计算服务商提供免费试用云服务器&#xff0c;下面给大家整理汇总一下免费VPS云服务器&#xff0c;最长永久免费使用&#xff01; 一、雨云&#xff08;优惠码:ABC&#xff09; 活动地址&#xff1a;…

通讯录的实现(顺序表版本)

我们知道通讯录是基于顺序表的前提下&#xff0c;要写好通讯录我们就要深入了解好顺序表。我们先来看看什么是顺序表。&#xff08;注意今天代码量有点多&#xff0c;坚持一下&#xff09;。冲啊&#xff01;兄弟们&#xff01; 顺序表的简单理解 对于顺序表&#xff0c;我们首…

软件测试 测试开发丨Pytest结合数据驱动-yaml,熬夜整理蚂蚁金服软件测试高级笔试题

编程语言 languages: PHPJavaPython book: Python入门: # 书籍名称 price: 55.5 author: Lily available: True repertory: 20 date: 2018-02-17 Java入门: price: 60 author: Lily available: False repertory: Null date: 2018-05-11 yaml 文件使用 查看 yaml 文件 pych…

2024.4.19 Python爬虫复习day07 可视化3

综合案例 需求: 已知2020年疫情数据,都是json数据,需要从文件中读出,进行处理和分析,最终实现数据可视化折线图 相关知识点: json json简介: 本质是一个特定格式的字符串 举例: [{},{},{}] 或者 {}python中json包: import jsonpython数据转为json数据: 变量接收json…

刷题之Leetcode206题(超级详细)

206.反转链表 力扣题目链接(opens new window)https://leetcode.cn/problems/reverse-linked-list/ 题意&#xff1a;反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 思路 如果再定义一个新的链表&#xff0…

Linux文本编辑器vim使用和分析—2

目录 1.对vim的简单理解&#xff1a; 2.看待vim的视角&#xff1a; 3.命令模式&#xff1a; 3.1vim被打开后默认的模式&#xff1a; 3.2命令模式切换插入模式&#xff1a; 3.3其他模式回到命令模式&#xff1a; 3.4光标定位&#xff1a; 4.插入模式(编辑模式)&#xff1…

赋能未来:AI技术革新中的创业契机

目录 前言 一、行业解决方案 1、行业参考说明 2、操作步骤建议 二、智能产品和服务 1、行业参考说明 2、操作步骤建议 三、教育和培训 1、行业参考说明 2、操作步骤建议 总结 前言 随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;越来越多的创业…

【Java】新手一步一步安装 Java 语言开发环境

文章目录 一、Windows 10 系统 安装 JDK8二、 Mac 系统 安装 JDK8三、IDEA安装 一、Windows 10 系统 安装 JDK8 &#xff08;1&#xff09;打开 JDK下载网站&#xff0c;根据系统配置选择版本&#xff0c;这里选择windows 64位的版本&#xff0c;点击下载&#xff08;这里需要…

音频变速python版

音频变速 如何能在不改变音频其他特点的情况下&#xff0c;只改变语速呢&#xff1f; 有几个python的库可以实现该功能&#xff0c;下面一一介绍。 pydub库 首先&#xff0c;确保安装了pydub和ffmpeg。 下面是一个简单的Python脚本&#xff0c;展示如何改变音频的播放速度&a…

《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)

1.简介 TestNG为日志记录和报告提供的不同选项。现在&#xff0c;宏哥讲解分享如何开始使用它们。首先&#xff0c;我们将编写一个示例程序&#xff0c;在该程序中我们将使用 ITestListener方法进行日志记录。 2.TestNG自定义日志 2.1创建测试用例类 1.按照宏哥前边的方法&…

论文笔记:Teach LLMs to Phish: Stealing Private Information from Language Models

iclr 2024 reviewer 评分 588 1 intro 提出了一种“神经网络钓鱼攻击” 一种新的针对在敏感用户数据上训练或finetune的LLMs的攻击向量攻击者将看似无害的投毒数据插入到模型的训练数据集中&#xff0c;以“教会LLMs进行钓鱼”&#xff0c;即诱导模型记住他人的个人身份信息&…

DAY9|28. 实现 strStr()、459.重复的子字符串

28.实现 strStr&#xff08;&#xff09;、459重复的子字符串 28. 实现 strStr()减一版next数组时间复杂度分析前缀表统一减一 C代码实现前缀表&#xff08;不减一&#xff09;C实现 459.重复的子字符串移动匹配KMP前缀表统一减一前缀表&#xff08;不减一&#xff09;的C代码实…

从零自制docker-10-【cgroup进行容器资源限制】

文章目录 目的导入包的相关公开原则当前进程的挂载信息deferfor scanner.Scan()判断字符串包含新建的cgroup的默认文件cpu相关配置对应到ubuntu 22.04版本的cpu相关配置top注意查看你可使用的cpu注意坑启动后的top查看显示进程使用的cpu序号代码结果 目的 启动容器时通过-mem、…