WeTalk 说明书

备注:

  1. 该项目为纯前段静态页面,但是为后台服务的对接提供了良好的接口;
  2. 部分功能之提供接口,不提供实现;
    2.1. 右上角菜单的用户信息扫一扫按钮(如图4标4);
    2.2. 聊天界面其他功能显示框(如图7标7);
    2.3. 通讯录界面的操作按钮(如图5标3);
    2.4. 消息列"界面的操作*按钮中的置顶按钮(如图5标2);
  3. 在不同的设备可以自适应,在Iphone 6Plus和IPad mini2经测良好;

欢迎大家拍砖:diary_zhk.sina.com


一. 项目简介

该项目使用angularjs+bootstrip+grunt开发,旨在做一个聊天的前端界面(不包括服务器),分为三个部分,分别是顶部菜单,中间内容,底部导航。实现了消息通讯录聊天窗口三个模块。
预览如下:

通讯录 图1

聊天界面 图2
消息 图3

二. 功能说明

在这里将分为顶部菜单,底部导航,通讯录,消息列表,聊天界面五个部分,分别介绍WeTalk的功能。

1. 顶部菜单

顶部菜单构造如图4所示。


顶部菜单 图4

分为四个部分:

  • 返回按钮(图4标1) : 该菜单返回消息列表,只有在聊天界面才会显示,会显示未读消息的总数量;
  • 标题(图4标2): 显示标题;
  • 操作菜单(图4标3,4):提供的操作按钮;

2. 底部导航

底部导航有两个按钮,“消息”和“通讯录”,这两个菜单高度固定,钉在底部。其中“消息”菜单会显示未读消息的总数量。

3. 通讯录

通讯录,顾名思义就是所用可以联系用户的汇总,如图5所示。


通讯录 图5

分为四个部分:

  • 搜索框(图5标1): 在这里,输入联系人的姓名或者姓名的中的某个字,会进行检索,筛选出符合条件的用户;
  • 字母检索(图5标2): 按住不放手,在这些字母上滑动,将按照首字母检索,把符合条件的首个用户显示在顶部;
  • 操作(图5标3):在某个用户上,向右滑动,将显示出操作按钮;
  • 用户条目(图5标4):显示用户信息,包括图片和姓名,点击姓名将进入聊天界面;

4. 消息

消息列表记录最近聊得人,如图6所示。


消息 图6

分为四个部分:

  • 搜索框(图6标1):输入内容,自动检索用户名+最后消息内容,显示出符合条件的用户;
  • 操作框(图6标2):在某个用户上,向右滑动,将显示出操作按钮;
  • 用户信息(图6标3,4):显示用户头像和用户名;
  • 最后信息(图6标5,6,7):5表示最后联系内容,6表示该用户未读的消息数量,7表示最后联系时间

5. 聊天界面

聊天界面最主要的功能就是发送和接收消息,暂时支持语音,文字,表情三种内容,如图7]所示。


聊天界面 图7

分为两个部分:

  • 消息(图7标1,2,3):1表示用户头像,2表示消息内容,3表示发送或接收消息的时间;
  • 消息输入(图7标4,5,6,7,8):4表示文字和语音消息的切换按钮,5消息或者问题输入框,6表示表情显示框,7其他功能显示框,8表示6和7点击之后显示的操作内容;

三. 开发说明

该项目用到的技术或使用的工具有angularjs,bootstrip,grunt,Less,JSHint等。

1. 开发说明

实现了以下功能:

  1. 多个js,css文件代码合并;
  2. js,css压缩;
  3. 根据JSLint对js进行校验;
  4. 监听文件变更,自动更新;
  5. 开发环境(default)和正式环境(online)正式校验;

2. 目录结构

在开发过程中,使用模块化的方法组织目录结果,目录结果和各个目录的说明图8.


目录结构 图8

3. 数据结构

在开发过程中,包括聊天记录,用户信息及其保存都有一定的结构,下面讲述几种主要的数据结构。

3.1 用户信息

如图5中标4表示的一个条目所需要的信息。
{ "id": 1, ----用户编码 "name": "陈奕迅", ----用户姓名 "imgUrl": "/app/displaydata/imgs/chenyixun.png", ----用户头像 "initial":"C" ----首字母,便于查询 }

3.2 消息列表

如图6中标3~7的表示一个条目所需要的信息。
{ userId : 2, ---用户ID userName : "陈奕迅", ---用户名 userImgUrl : "/app/displaydata/imgs/chenyixun.png", ---用户头像 noReadNum: 2, --- 未读的消息数目 lastMsgContent : "最后一条内容", ---最后一条消息的内容(接收或发送) lastMsgTime : 16711312832 --- 最后一条消息的时间(接收或发送) }

3.3 聊天记录

如图7中标1~3的表示一个条目所需要的信息。
{ "id": "1", ---消息ID "content": "我收到你得消息了。-测试", --- 消息内容(文本消息类型) "time": 1465293529060, --- 消息时间(文本消息类型) "status" : 1, ---消息状态(0-成功,1-失败) "sourceType": 1, ---消息来源(1-接收,2-发送) "msgType": 1, ---消息类型(1-文本,2-语音) "src" : '/app/displaydata/test.mp3', ---音频存放位置 "isRead": false ---是否已读 }

3.4 消息缓存

这里采用json的格式,将最近聊天记录和最近联系人保存到浏览器的本地存储空间中( window.localStorage),说明如下:

消息 key 格式 说明
最近联系人 [loginUserId]_recent_users JsonArray 例如:10000_recent_users: "[{"userId":8,"userName":"希特勒","userImgUrl":"/app/displaydata/imgs/xitele.png"}]"
历史消息 [loginUserId]_history_[toUserId] JsonArray 例如:10000_history_41:"[{"id":1,"content":"测试-收到消息 ","time":1469499329490,"sourceType":1,"msgType":1,"status":0,"isRead":false}]" , 具体请参见3.3聊天记录

4. 技术要点及实现

下面将为大家介绍该系统中比较关键的技术要点及其实现。

4.1 结构层次

该系统采用仿后台“MVC”结构,使用服务器,控制器,路由器,展示器四层结构。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

4.1.1 服务器

见图8中的services.js文件,这个里面封装了所有对外的服务接口,具体我们分析下面的代码:
//消息服务 app.service("weService", function ($http) { return { /* 获取用户列表 */ getUserList : function () { return $http({ url : '/app/displaydata/userlist.json', method : 'get', dataType : 'json' }); }, /*获取聊天界面的操作列表*/ getMsgToolsList : function () { return $http({ url : '/app/modules/base/data/messageTools.json', method : 'get', dataType : 'json' }); } }; });
这段代码封装了一个名为"weService"的服务对象,其中有两个接口,都使用ajax的方式异步请求服务器数据。封装好之后可以将服务器"weService"传递给控制器,以便直接使用服务器定义好的借口。

4.1.2 控制器

见图8中的app/modules//_controlller.js文件,对不同的模块封装了不同的控制器,当然你也可以把所有的控制器放在同一个文件中,但是这样不利于维护。下面我们分析下面的代码:
app.controller("userListController", function ($rootScope, $scope, $location, $timeout, weService) { $rootScope.title = '通讯录'; $scope.getUserList = function(){ $scope.userList = []; //初始化数据-获取用户列表 weService.getUserList().then(function(res){ //原始数据 $scope.userListOrg = res.data; // 搜索的时候回事是变化 $scope.userList = res.data; //整理右侧的query $scope.queryKeyList = []; angular.forEach($scope.userList, function(user){ var queryKey = user.initial; var flag = true; angular.forEach($scope.queryKeyList, function(qk){ if(qk === queryKey){ flag = false; return ; } }); if(flag){ $scope.queryKeyList.push(queryKey); } }); //$timeout(function(){myScroll.refresh();},200);; }); }; $scope.getUserList(); });
上述代码封装了一个名为"userListController"的控制器,在初始化方法中使用4.1.1定义的服务器"weService",调用weService的获"取用户列表"接口,实现业务逻辑。

4.1.2 路由器

见图8中的modules.js文件,其通过路由的方式定义了每个控制器和展示页面的关系,具体代码如下:
app.config( function ($routeProvider) { $routeProvider .when('/userList', { templateUrl: "/app/modules/user/htmls/user_list.html", controller : "userListController" }) .otherwise({ templateUrl: "/app/modules/base/htmls/unknow.part.html", controller : function($rootScope, $scope){ $rootScope.bodyClass = 'error-page'; } }); });
上述代码定义了两个路由,一个“/userList”,一个“otherwise”。“otherwise”顾名思义就是找不到指定路由时处理方法;“/userList”定义了当url为“/userList”时的控制器和展示器。

4.1.4 展示器

展示器就是纯html页面,同时可以将控制层的数据按照指定的方式展示,其中支持EL表达式,{{}},angularjs指令等等,具体情况请参考<a href="http://www.apjs.net/">angularjs教学</a>

4.2 表情

表情有两种表现形式:一种将表情编码,像IOS中的EMOJI表情;另一种就是动态或者静态的图片。这里我们采用第二种,使用动态图片,图片的存放在imgs/face目录下,通过读取文件名,对表情进行简单的编码,编码规则为:
[em-文件名]
以编码形式进行保存,当需要显示时通过对编码的解析,转换成img标签:
function(str){ str = str.replace(/</g,'<'); str = str.replace(/>/g,'>'); str = str.replace(/\n/g,'<br/>'); str = str.replace(/\[em-([0-9]*)\]/g, '<img src="/imgs/face/$1.gif" border="0"/>'); return str; };

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • 通过AngularJS仿豆瓣一刻的案例:https://github.com/zhongxiaolian/doub...
    中小恋阅读 1,749评论 1 21
  • AngularJS是什么?AngularJs(后面就简称ng了)是一个用于设计动态web应用的结构框架。首先,它是...
    200813阅读 1,583评论 0 3
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,715评论 2 17
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,345评论 0 17