Разработка апплета WeChat завершена + описание проблемы

внешний интерфейс WeChat JavaScript Апплет WeChat

出发吧一起

предисловие

После почти месяца разработки апплет WeChat «Пойдем вместе», разработанный нашей командой, наконец, был разработан, и текущая онлайн-версия — версия 2.2.4-бета.

Этот документ в основном знакомит с технологиями, использованными при разработке апплета, и решениями проблем, возникших при разработке.

Введение в мини-программы

«Пусть интересы больше не будут одинокими, а хобби больше не блуждают» — тема апплета WeChat «Пойдем вместе». Этот апплет призван решить проблему одиночества современных студентов в студенческой жизни, чтобы каждый мог найти себе по душе целеустремленные друзья. Найдите партнера для бега, фитнеса, соревнований и т. д. Используя небольшую программу, чтобы использовать ее сразу же, совместите ее с дружбой, это будет эффективный, быстрый и необременительный инструмент для знакомства в автономном режиме.

Этот апплет предоставленbmobЗакрытие облака обеспечивает поддержку обработки данных и хранения данных

код апплета

欢迎扫描体验

Сводка технических проблем в разработке

1. Проблемы с использованием e.target.dataset

В процессе разработки апплета мы часто используем значение атрибута атрибута в теге.<view>Средние настройкиdata-*="{{XXX}}"затем вJSчерезe.target.dateset.*получитьXXXзначение, но я часто сталкиваюсь с получениемundefined,использоватьconsole.log(e)Глядя на выходную информацию, вы обнаружите, что вeОбъект содержит два объекта, которыеcurrentTargetа такжеtarget, а иногда и данныеcurrentTargetсередина,

На этом этапе вы можете заменить код этим, чтобы получить значение

  • WXML
<view bindtap="bintap" data-id="1"></view>
  • JS
bintap:function(e){
    var id = e.currentTarget.dataset.id;
}

В интернете тоже есть поговоркаdata-*внутри*Проблема именования, удаление имени верблюда, чистый нижний регистр также может быть решена

2. Как отобразить количество слов в реальном времени в текстовом поле апплета

  • WXML
<view>
    <view>
        <textarea name="content" bindinput="bindTextAreaChange" maxlength="{{noteMaxLen}}" />
        <view class="chnumber">{{noteNowLen}}/{{noteMaxLen}}</view>
    </view>
</view>
  • JS
data:{
    noteMaxLen: 200,//备注最多字数
    noteNowLen: 0,//备注当前字数
}

  //字数改变触发事件
  bindTextAreaChange: function (e) {
    var that = this
    var value = e.detail.value,
      len = parseInt(value.length);
    if (len > that.data.noteMaxLen)
      return;
    that.setData({
      content: value, noteNowLen: len
    })
  },

3. Используйте JS для реализации нечеткого запроса

Поскольку мы используемBmobПоддержка обработки и хранения данных, предоставляемая серверным облаком, в соответствии с документами по разработке, предоставленными Bmob, бесплатная версия приложения не может выполнять нечеткий запрос.Увидев это и посмотрев на завершенный интерфейс поиска активности, ощущение неописуемое. Когда я собирался сдаться, я вдруг подумал о методе, который заключается в том, чтобы сначала сохранить все данные в фоновом режиме в коллекцию, а затем сопоставить их один за другим в соответствии с входным значением поиска.javaScriptдокументация,StringОбъект имеет метод, которыйindexOf(), может возвращать позицию, в которой заданное строковое значение впервые появляется в строке, таким образом, становится, обходить все данные, извлекать каждый символ каждого фрагмента данных, если он появляется, добавлять его в набор результатов поиска.

  • JS
//js 实现模糊匹配查询
  findEach: function (e) {
    var that = this
    var strFind = that.data.wxSearchData.value; //这里使用的 wxSearch 搜索UI插件,
    if (strFind == null || strFind == "") {
      wx.showToast({
        title: '输入为空',
        icon: 'loading',
      })
    }
    if (strFind != "") {
      var nPos;
      var resultPost = [];
      for (var i in smoodList) {
        var sTxt = smoodList[i].title || ''; //活动的标题
        nPos = sTxt.indexOf(strFind); 
        if (nPos >= 0) {//如果输入的关键字在该活动标题中出现过,则匹配该活动
          resultPost.push(smoodList[i]); //将该活动加入到搜索到的活动列表中
        }
      }
      that.setData({
        moodList: resultPost
      })
    }
  },

Для получения более подробного кода перейдите кGithubПроверить

4. Используйте JS для преобразования времени в строковом формате в секунды назад, минуты назад...

Поскольку апплет включает в себя ряд функций, включая комментирование, добавление действий и избранное, включая время события, формат времени, хранящийся в базе данных,2017-11-30 23:36:10Теперь я хочу отображать на интерфейсе не конкретное время, а отображать отличие от текущего времени, то есть несколько секунд назад, несколько минут назад и т.д.

Это не сложно реализовать.Основная идея состоит в том, чтобы сначала преобразовать время строки в временную метку, а затем сравнить ее с текущей временной меткой, чтобы ее можно было преобразовать в несколько секунд назад, несколько минут назад, несколько часов назад, несколько дней назад и т. д. форма

  • JS
//字符串转换为时间戳
function getDateTimeStamp(dateStr) {
  return Date.parse(dateStr.replace(/-/gi, "/"));
}
//格式化时间
function getDateDiff(dateStr) {
  var publishTime = getDateTimeStamp(dateStr) / 1000,
    d_seconds,
    d_minutes,
    d_hours,
    d_days,
    timeNow = parseInt(new Date().getTime() / 1000),
    d,

    date = new Date(publishTime * 1000),
    Y = date.getFullYear(),
    M = date.getMonth() + 1,
    D = date.getDate(),
    H = date.getHours(),
    m = date.getMinutes(),
    s = date.getSeconds();
  //小于10的在前面补0
  if (M < 10) {
    M = '0' + M;
  }
  if (D < 10) {
    D = '0' + D;
  }
  if (H < 10) {
    H = '0' + H;
  }
  if (m < 10) {
    m = '0' + m;
  }
  if (s < 10) {
    s = '0' + s;
  }

  d = timeNow - publishTime;
  d_days = parseInt(d / 86400);
  d_hours = parseInt(d / 3600);
  d_minutes = parseInt(d / 60);
  d_seconds = parseInt(d);

  if (d_days > 0 && d_days < 3) {
    return d_days + '天前';
  } else if (d_days <= 0 && d_hours > 0) {
    return d_hours + '小时前';
  } else if (d_hours <= 0 && d_minutes > 0) {
    return d_minutes + '分钟前';
  } else if (d_seconds < 60) {
    if (d_seconds <= 0) {
      return '刚刚';
    } else {
      return d_seconds + '秒前';
    }
  } else if (d_days >= 3 && d_days < 30) {
    return M + '-' + D + ' ' + H + ':' + m;
  } else if (d_days >= 30) {
    return Y + '-' + M + '-' + D + ' ' + H + ':' + m;
  }
}

5. Апплет WeChat отправляет форму для очистки данных формы.

После события публикации, поскольку данные в форме не очищаются, взаимодействие с пользователем должно быть плохим, но взаимодействие данных апплета не похоже наhtml + jSтаким образом, используйтеdataSet({})Чтобы присвоить значение, уровень представления может активировать значение асинхронно, поэтому я подумал, после отправки формы, дать этиinputВсе назначаются пустыми, чтобы реализовать эффект очистки формы.Конечно, форма содержит не толькоinput, но эффект очистки может быть достигнут таким образом

  • WXML
<form bindsubmit="submitForm">
    <text class="key">活动名称</text>
    <input name="title"  maxlength="100" value="{{title}}" />
    <button  formType="submit">确定</button>
</form>
  • JS
submitForm:function(e){
     var title = e.detail.value.title;
     ......
     success: function (res) {
         //将title值设置空
        that.setData({
            title: ''
         }
     }
}

6. Аккаунт WeChat, номер QQ, номер мобильного телефона, регулярная проверка

Поскольку в заявке на участие в мероприятии необходимо указать настоящее имя, контактную информацию и другую информацию, чтобы предотвратить произвольное заполнение информации пользователями, эта информация должна быть проверена.

  • JS
    var wxReg = new RegExp("^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$"); //微信号正则校验
    var qqReg = new RegExp("[1-9][0-9]{4,}"); //QQ号正则校验
    var phReg = /^1[34578]\d{9}$/; //手机号正则校验
    var nameReg = new RegExp("^[\u4e00-\u9fa5]{2,4}$"); //2-4位中文姓名正则校验

7. Используйте Bmob SDK для успешной регистрации. Отправьте шаблон сообщения для создания двумерного кода, такого как апплеты.

В процессе разработки я хотел понять, как уведомлять пользователя об успешной регистрации пользователя.Я проверил документацию по разработке апплета и обнаружил, что существует API для отправки шаблонных сообщений, а затем запросил документацию по разработке Bmob, и обнаружил, что эта функция была реализована. Это правда. Это очень полезно. Сообщение шаблона может быть успешно отправлено только на реальной машине. После настройки важно добиться успеха, но есть проблема в использовании. , то есть после выпуска апплета, если сообщение шаблона содержитpageПараметр не будет отправлен, но он может быть успешно отправлен в разрабатываемой версии.Сообщалось об этой проблеме, и предполагается, что апплет Bmob будет ждать.SDKЭта проблема будет решена после обновления.

Конкретный код писать не буду, документация по разработке bmob есть прямо

Скриншоты и гифки

启动画面

消息通知

地图模式.gif

Структура таблицы базы данных Bmob

Пользовательская таблица: (_User, поставляется с таблицей)

|--objectId //Id
|--userPic(String) //用户头像
|--username(String) //用户名
|--password(String) //密码
|--nickname(String) //昵称
|--sex(Number) //性别
|--userData(Object) //微信登录用户数据
|--eventJoin(Array) //参加的活动Id 数组Array
|--eventFavo(Array) //收藏的活动Id 数组Array
|--feednum(Number) //反馈次数

Информационный лист события: (события)

|--objectId //活动Id
|--publisher(Pointer-->_User) //发起人
|--title(String) //活动主题
|--content(String) //活动内容
|--actpic(File) //活动宣传照片
|--acttype(String) //活动类别
{
    1:运动,2:游戏,3:交友,
    4:旅行,5:读书,6:竞赛,
    7:电影,8: 音乐,9: 其他
}
|--isShow(Number) //是否公开显示在首页
|--endtime(String) //组队截止时间
|--address(String) //活动地点
|--latitude(Number)  //地址纬度
|--longitude(Number) //地址经度
|--peoplenum(String)//人数限制
|--likenum(Number)  //点赞数
|--liker(Array) //点赞人Id集合
|--commentnum(Number) //评论数
|--joinnumber(Number) // 现在参加的人数
|--joinArray(Array) // 现在参加的人集合

Таблица расширения информации о событиях: (EventMore)

|--objectId //活动信息扩展表Id
|--event(Pointer-->Events) //活动
|--Status(Number) //活动状态,(1:准备中,2:进行中,3:已结束)
|--Statusname(String) //活动状态名称
|--qrcode(File) //活动群聊二维码

Форма комментариев: (Комментарии)

|--objectId //评论Id
|--publisher(Pointer-->_User) //评论发布者
|--olderUsername(String) //上一条评论人昵称
|--olderComment(Pointer-->Comments) //上一条评论
|--event(Pointer-->Events) //评论的活动
|--content(String)  //评论内容

Нравится форма: (Нравится)

|--objectId //点赞的Id
|--liker(Pointer-->_User) //点赞人
|--event(Pointer-->Events) //点赞的活动

Любимый лист: (Favos)

|--objectId //收藏的Id
|--favor(Pointer-->_User)  //收藏者
|--event(Pointer-->Events) //收藏的活动

Форма уведомления о сообщении: (Plyre)

|--objectId //消息通知的Id
|--fid(String)  //活动发布者Id(被赞或者被取消赞的人的ID,或者被回复,被评论的人的ID)(被通知的人)
|--uid(Pointer-->_User)   //消息通知人
|--wid (String) //被赞,或者取消赞,被评论,或者被回复,加入,取消加入的活动id
|--avatar (String) //消息通知人的头像
|--username (String) //消息通知人的姓名
|--is_read(Number) //这条消息是否已读(1代表已读,0代表未读)
|--bigtype(Number) //消息通知大类(1代表消息,2代表通知)
|--behavior(Number) //(消息提醒类型)
{
	1:赞
	2:取消赞
	3:被评论
	4:被回复
	5:加入活动
	6:取消加入活动
	7:修改了加入信息
}

Контактная форма мероприятия: (Контакты)

|--objectId //联系表Id
|--publisher(Pointer-->_User)  //活动发布者
|--currentUser (Pointer-->_User) //当前用户
|--event(Pointer-->Events)  //想要加入的活动
|--realname (String) //真实姓名
|--contactWay(String) //联系方式(微信号,手机号,QQ号)
|--contactValue(String) //联系方式的号码

Форма обратной связи: (Обратная связь)

|--objectId //反馈Id
|--feedUser(Pointer-->_User) //反馈人Id
|--title(String) //反馈标题
|--content(String) //反馈内容
|--feedpic(File) //反馈图片
|--feedinfo(String) //反馈用户的设备信息 	

Благодаря следующим проектам с открытым исходным кодом и сообществам веб-сайтов