您的位置:首页 > 理论基础 > 计算机网络

一个APP的迭代(3) - 网络篇

2018-01-27 22:54 295 查看

添加登录、注册、忘记密码、备份日记功能

上一篇博文:一个APP的迭代(2) - 基础篇,已经把日记列表,查看日记,删除日记,修改日记的功能做出来了,并且已经上线到应用市场,有用户在使用。

但也仅限本地使用,无法备份日记,这篇博文介绍如何把备份功能做上去的思路及相关技术。

上个版本的版本号为2.0.0,这个版本迭代新增了一个备份日记的功能,就把版本号算级为2.1.0,最后一个0表示的是修复BUG的版本,例如:你修复了一个备份日记的BUG,那么版本号就升级为2.1.1

需求拆分

注册功能

登录功能

忘记密码功能

备份日记功能

还原日记功能

后端搭建

一开始是计划用 Node + TypeScript + MongoDB 搭建后端,毕竟它是跨平台的方案。

但是,技术只是手段,产品才是目的。 由于我是做C#出身的,那么我就用 ASP.NET Core + C# + MySQL ,这套也是开源的跨平台方案,性能要比NODE强。

搭数据库

用户表

日记表

缓存表(用来处理注册时验证码等临时数据)

这三个表已经够用了,迭代开发,不做过度设计。

ASP.NET Core 控制器设计(RESTful)

UserController (用户控制器)

请求短信验证码接口(注册用户与忘记密码)

注册用户接口

用户登录接口

忘记密码接口

DiaryController (日记控制器)

获取指定时间以后的日记接口

备份单篇日记接口

备份日记这个功能相当复杂,这就像SVN的版本记录一样,会存在日记内容冲突的矛盾,因为日记表的记录是必须存在的,若是不存在,就无法对比和解决冲突。日记表的记录不能删,而是用一个valid的字段表示该篇日记是否有效,另外还需要有一个modified_time的字段设为ON UPDATE CURRENT_TIMESTAMP来表示该日记被修改的时间。

关于 备份/还原 日记逻辑就不细说了,估计几万个字都说不完,总之有点复杂,当逻辑理清之后还是比较简单的

后端业务逻辑基础类的编写

上面的控制器只是用于输出http请求结果的json数据,业务逻辑还是与控制器分离的。MVC模式嘛,控制器表示C层,业务逻辑就写在M层那里,然而这里并没有V层,以后做日记网站了就可以用到V层咯。

备份/恢复 日记的业务代码如下:

public class DiaryBusiness : IDiary
{
public CompareResult CompareServerDiary(DiaryDetail diaryDetail)
{
var connection = ToolFactory.BuildConnectionInstance();
var serverDiaryDetails = connection.QueryFirstOrDefault<DiaryDetail>($"select * from note_details where id=@id;", new { id = diaryDetail.id });
if (serverDiaryDetails == null)
{
return new CompareResult { Code = CompareCode.ServerNotData, Remark = "服务端无此日记。" };
}
if (diaryDetail.modified_time > serverDiaryDetails.modified_time)
{
return new CompareResult { Code = CompareCode.ServerHasOldData, Remark = "服务端的日记较旧。" };
}
else if (diaryDetail.modified_time < serverDiaryDetails.modified_time)
{
return new CompareResult { Code = CompareCode.ServerHasNewData, Remark = "服务端的日记较新。" };
}
else if (diaryDetail.modified_time == serverDiaryDetails.modified_time)
{
return new CompareResult { Code = CompareCode.ServerHasSameData, Remark = "客户端与服务端的日记一致。" };
}
return null;
}

public bool CreateDiary(DiaryDetail diaryDetails)
{
if (diaryDetails.modified_time == null)
{
diaryDetails.modified_time = DateTime.Now;
}
using (var connection = ToolFactory.BuildConnectionInstance())
{
try
{
if (diaryDetails.id == null || diaryDetails.id == Guid.Empty) return false;
var exeResult = connection.Execute($"insert into note_details (id,title,content,user_id,create_time,modified_time) value " +
$"(@id,@title,@content,@user_id,@create_time,@modified_time);",
diaryDetails);
return exeResult > 0;
}
catch
{
return false;
}
}
}

public bool DeleteDiary(Guid diaryId)
{
using (var connection = ToolFactory.BuildConnectionInstance())
{
var result = connection.Execute($"update note_details set valid=0 where id=@id;", new { id = diaryId });
return result > 0;
}
}

public DiaryDetail PullServerDiary(Guid diaryId)
{
using (var connection = ToolFactory.BuildConnectionInstance())
{
var DiaryDetails = connection.QueryFirstOrDefault<DiaryDetail>($"select * from note_details where id=@id;", new { id = diaryId });
return DiaryDetails;
}
}

public List<DiaryDetail> PullServerDiarys(DateTime versionTime, Guid userId)
{
using (var connection = ToolFactory.BuildConnectionInstance())
{
var diaryDetails = connection.Query<DiaryDetail>($"select * from note_details where modified_time>@modified_time and user_id=@user_id;",
new { modified_time = versionTime, user_id = userId });
if (diaryDetails.Any())
{
foreach (var item in diaryDetails)
{
item.content = "";
item.title = "";
}
}
return diaryDetails.AsList();
}
}

public bool UpdateDiary(DiaryDetail diaryDetails)
{
if (diaryDetails.modified_time == null)
{
diaryDetails.modified_time = DateTime.Now;
}
using (var connection = ToolFactory.BuildConnectionInstance())
{
var exeResult = connection.Execute(
$"update note_details set " +
$"title=@title," +
$"content=@content," +
$"user_id=@user_id," +
$"modified_time=@modified_time," +
$"valid=@valid where id=@id;", diaryDetails);
return exeResult > 0;
}
}
}


目前 小励日记APP 只有10万的用户(包括已注册的和未注册的),日访客量500左右。

这里要注意的时,备份日记与恢复日记接口要做鉴权近控制,这里的做法是日记控制器继承鉴权控制器,一旦鉴权失败直接报错,而不进入日记控制器。

日记APP一定要严格保护好用户的隐私。

鉴权的逻辑

日记用户的注册、登录、忘记密码的功能代码我就不贴出来了。这里说一下鉴权的业务逻辑。

登录成功后,接口会输一个TOKEN

APP端要保存好这个TOKEN,每次请求时,用这个TOKEN + 时间戳 + 密钥 计算MD5,后端接收到这个MD5后也要重新计算一次,然后对比MD5,如果一样,则鉴权通过

如果请求被拦截,那么黑客用这个MD5就可以获得用户的所有操作了,其实这个MD5只会有一次,并且时间在60分钟内有效,如果后端的历史记录表有该MD5,则表示该操作非法。

那如果是跨时区的,那这60分钟明显不够啊?所以呢,APP端就要转换为标准的北京时间了。

备份/恢复 日记、登录、注册 就这几个简单的需求,其实做起来也不容易啊,也是有很多代码量的。

这让我想起了前些天,有个网友找到我,让我帮它做个APP,就只有几个简单的界面而已,然而我报出来的天数是90天。他吓了一跳,说后端接口用PHP他们只用12天就做好了。

我问他:后端有做过测试验收没?他答:接口人员跟我说已经好了。

在我看来,后端未经过严格测试的,完成度只能算20%。前端APP人员要跟后端沟通、联调的时间成本就要占了一半,仅剩下的一半时间来完成APP需求。[/b]

前端界面

前端开发完成后的界面如下







这个版本已经把备份/恢复日记 、注册、登录、忘记密码的功能做进去了,也发布到应用市场了,下一篇博文 要把扩展的功能 本地密码锁、日记照片、日记语音 迭代出来。

迭代开发就是这么回事,一个版本一个版本来,先做让用户可以用的版本,新功能在后面的版本迭代。这里说的只适合资源不足的情况下,如果开发人力充足,也可以一次做出一个大版本。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息