昨天在电脑里无意中翻到了几年前做的一个小东西,也从来没有正式上线运营过。想着放那里也是浪费,不如凑一篇文章放出来算了,所以有了这篇拙文。本文详细的展示一个小型理财APP从立项到上线运营的全过程,旨在帮助初级从业者对产品的开发周期有一个完整的理解,亦帮助想要投资或创立中小型软件或者网络公司的创始人对行业有个基本的认识,同时帮助那些想要寻找软件外包的老板理解软件开发的每个节点,避免被坑。
在开始之前先看看成品的演示,APP端:

PC后台管理端:

本文所讲解的代码及美术资源除第三方框架以外均已申请软件著作权,本文也在CSDN首发。如需转载,请注明详细出处。
一、原型设计
二、美术设计
三、前端开发
四、后端开发
五、测试
六、部署上线
一、原型设计
1、需求来源
在进行原型设计之前,需要对需求进行有效的分析。如果你是一个软件外包团队,通常情况下需求是由甲方提出的,产品负责人就需要根据甲方提供的需求进行分析,包括显性需求与隐性需求,并将其原型化。如果你的产品是自营产品,那么需求就需要根据市场人员的反馈或者项目需求人的目标和意愿来进行收集分析,并将其原型化。
2、需求分析
作为一名合格的产品负责人,要明白并接受的是所有的需求来源都不是成体系的。这些信息都是碎片化的,且有可能会出现逻辑上有互相冲突的情况,在实际的需求分析中这是非常正常现象。并且有许多需求非专业人事对其进行描述和他真正想要的内容相差十万八千里。这就十分考验产品负责人的需求捕获和分析的技巧。
需求分析包括业务需求、用户需求和功能需求。以我们的理财APP项目为例来分别进行需求分析。
业务需求:
a、准确的展示现有的理财产品,并向用户提供详细的理财产品说明书。
b、理财产品分为不同的类型,有日结、月结、年结。
c、理财产品的价格不固定,不同的理财产品购买价格不同,参与的门槛与分红的次数不同,且风险级别也不相同。
d、理财产品有参与上限,额满即止。
e、自动计算该理财产品的应分红的次数以及分红的金额,将分红的金额自动返还到购买者的平台账户内。
f、有推荐功能,用户可以推荐其他用户进行购买,推荐并成功购买的推荐官可以即时获得一定额度的奖励,该奖励为一次性发放。
g、内置简单商城系统,用户赚取的利润可以直接在商城内进行购物。
h、对接支付系统,方便用户自主充值购买。
i、提供公告功能,以便随时提醒用户有关平台的最新信息。
j、提供活动入口,以便对理财项目或者商城内的商品进行促销。
用户需求:
a、整个系统分为消费者与管理者两种不同的用户职能。且消费者有两种不同的角色,分别为消费者和推荐官。每一个消费者除了可以在APP内进行消费购买理财产品之外,还可以通过二维码邀请其他用户来购买理财产品。用户使用手机号进行注册和登录。
b、用户与被邀请用户之间只有一个层级,且下级用户购买每笔理财产品,上级用户都可以获得奖励,获得的奖励为一次性发放。
c、推荐官有不同的等级,等级名称及等级区间可以自行定义。
d、用户购买的理财金到期后根据用户的推荐级按比例提取理财金。提取的比例可自行定义。
e、如有未能提取的理财金,可以根据推荐级别在商城内进行消费。
f、用户在商城内消费需要收集发货地址以及收货人,以便平台能正确的发货。
c、管理者可以通过提供的系统来实时查看并管理普通消费者的相关内容。
系统需求:
略
3、原型设计
在进行原型设计之前,我们先要了解一下都有哪些原型的设计工具。常见的原型设计工具有Axure、墨刀等,这些原型设计工具都非常容易使用。对于产品岗来说首先重要的是要关注整个产品的流程设计,使得整个产品能够相互衔接,至于界面是否能美观,可以请美术人员来协助制作。
所以产品岗在原型设计阶段可以使用线框或者占位图来设计整个APP的界面以及页面之间的逻辑。Axure与墨刀都能够非常轻松的为每个锚点添加链接,使得页面之间能够顺利的切换跳转。下面是使用墨刀制作的理财APP的首页原型图。

根据需求将剩下的页面原型制作出来,就可以交付给美术人员进行页面设计了。这里需要强调的是产品的最终形态以及产品页面之间的路径,都是在原型阶段就完成的。也就是说原型阶段将APP设计成什么样,最终制作出来的APP成品就是什么样,在设计和开发阶段,仅做原型的实现,不做业务逻辑的修改了。所以说原型阶段是决定APP最终形态的最重要的阶段。
对于相对大型一些的产品来说,原型阶段可能需要联合多个部门例如技术部、设计部、市场部、运营部等一起来制定产品的最终形态,是需要进行充分论证和考量的,绝不是一拍脑袋就定下的。原型阶段就是APP成型阶段,最终APP的体验就是在原型阶段完成的。
除了业务逻辑的需求以外,产品岗还要注重用户的体验,许多已经被市场培育的行为习惯极少需要产品去重新创新的。例如购物环节购物车的设置和收货地址的设置等,这些用户行为已经是经过市场的锤炼过的,用户已经养成了对应的行为习惯了,在此处就没有必要花费过多的精力去进行创新。而对于自身核心业务部分来说则是需要着重提炼的。例如用户的交互,数据的展示,页面的切换等等。
二、美术设计
美术常用的设计软件有PhotoShop(简称PS)、sketch等等,你也可以使用任意你觉得顺手的设计软件来设计APP的界面。这里作者使用了PS来设计理财APP的界面。正常情况下产品将原型制作完毕后应当交由专业的美术设计师来完成界面的设计,因为这只是一个小型的APP,界面相对来说比较简单,所以同样由作者来完成界面的设计。以下是根据原型图设计的所有界面的源文件。

APP首页的分层设计图如下图所示:

设计师按照原型图一张一张的将页面设计好之后,就可以交付给前端工程师来进行APP的开发了。
三、前端开发
对于APP的开发,早期不同的平台需要有对应的APP开发人员来进行。例如我们这个理财APP的开发,按照原来人员配置的话需要IOS平台发人员一名、安卓平台开发人员一名,再加上PC端前端开发人员,完成一个带管理后台的APP开发至少需要三名前端人员才能搞定。按照一线城市初级程序员的薪水15000/月来计算,两名开发人员就需要支付30000元/月的薪水,再加上初级前端工程师10000/月的薪水,光前端部分就需要40000元/月的成本。相对于大企业来说还好一点,对于初创团队来说压力就比较大了。
随着技术的发展,有很多很不错的第三方开发平台可以帮助我们以更低的成本和更少的时间来完成APP的开发,例如uniapp就是一个非常不错的开发框架,他是一个使用 Vue.js 开发所有前端应用的框架,也就是说我们只要会VUE的开发,那么就可以使用uniapp来开发APP,并且uniapp可以同时导出小程序、H5页面、APP等,更加详细的信息大家可以去uniapp的官网去了解,这里我们就不讲了。
使用uniapp来开发我们的理财APP,只需要一个前端开发人员即可完成,不再需要每一个平台找一个人来进行开发。对于作者来说短时间内掌握VUE比短时间内掌握IOS和安卓开发要更容易,所以我们选择uniapp来进行开发。下面是我们理财APP的首页代码,看上去是不是很简单?就好像是在写网页前端一样,非常方便快捷,差不多一天可以写2、3个页面。首页代码如下:
<template>
<view>
<view class="banner">
<swiper class="swiper" :indicator-dots="true" :autoplay="true" :interval="interval" :duration="duration" indicator-active-color="#ffffff" indicator-color="rgba(255,255,255,.5)">
<swiper-item class="swiper-item" v-for="(items,index) in lunbolist" :key="index">
<navigator :url="items.urls">
<image :src="items.pics" mode="scaleToFill"></image>
</navigator>
</swiper-item>
</swiper>
</view>
<view class="gg">
<view class="lbimg">
<image src="../../static/lb.png"></image>
</view>
<navigator :url="'/pages/news/news?id='+newsid">
<view class="lbtxt">{{newtitle}}</view>
</navigator>
</view>
<view class="blc">
<view class="lf">
<navigator url="../jp/jp" hover-class="none" open-type="switchTab">
<view>财富推荐</view>
<view>官方财富推荐,最划算</view>
<view><button>立即抢购</button></view>
</navigator>
</view>
<view class="rf">
<navigator url="../shop/shop" hover-class="none" open-type="switchTab">
<view>精品商品</view>
<view>超实惠的购物,最优惠</view>
<view><button>进入购买</button></view>
</navigator>
</view>
</view>
<navigator url="../my/tui" hover-class="none" open-type="navigate">
<view class="hblc">
<view class="hblc_l">
<view>分享赚钱</view>
<view>最高可享受直推的10%</view>
<view><button>我要分享</button></view>
</view>
<view class="hblc_r">
<image src="../../static/erweima.png"></image>
</view>
</view>
</navigator>
<view class="line"></view>
<view class="remen">热门项目</view>
<!------------>
<view v-for="(proj,index) in list" :key="index">
<view class="bc">
<view class="titles">
{{proj.title}}({{proj.fhtype}})
</view>
<view class="itmlist">
<view class="itm">
<view class="reds">
{{proj.price}}元
</view>
<view class="hui">
价格
</view>
</view>
<view class="itm">
<view class="lan">
{{proj.fhnumb}}次
</view>
<view class="hui">
分红次数
</view>
</view>
<view class="itm">
<view class="lan">
{{proj.fhavgnumb}}元
</view>
<view class="hui">
每次分红
</view>
</view>
</view>
<view class="disp">
{{proj.disp}}
</view>
<navigator :url="'/pages/cfdetail/cfdetail?id='+proj.id">
<view class="btns">
立即抢购
</view>
</navigator>
</view>
<view class="cline"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
lunbolist:{},
interval:5000,
duration:500,
newtitle:"",
newsid:"",
list:{},
}
},
onLoad() {
uni.request({
url:this.$BASEURL+'/index.php/api/index/getlunbo',
header:{
'content-type':'application/x-www-form-urlencoded',
},
success: (res) => {
this.lunbolist=res.data;
}
});
uni.request({
url:this.$BASEURL+'/index.php/api/index/getnews',
header:{
'content-type':'application/x-www-form-urlencoded',
},
success: (res) => {
this.newtitle=res.data.title;
this.newsid=res.data.id;
}
});
uni.request({
url:this.$BASEURL+'/index.php/api/index/getproj',
header:{
'content-type':'application/x-www-form-urlencoded',
},
success: (res) => {
this.list=res.data;
}
});
},
onShow() {
uni.getStorage({
key:'loginstate',
success(local) {
if(local.data.denglu!=1){
uni.navigateTo({
url:"/pages/login/login"
});
}
},
fail() {
uni.navigateTo({
url:"/pages/login/login"
})
}
});
},
methods: {
}
}
</script>
<style>
.banner{
height: 409.8rpx;
}
.swiper{
height: 409.8rpx;
}
.swiper-item{
height: 409.8rpx;
}
swiper-item image{
height: 409.8rpx;
width: 100%;
}
.gg{
display: flex;
flex-direction: row;
justify-content: flex-start;
background-color: #f7f6f6;
height: 74.5rpx;
}
.lbimg{
width: 37.25rpx;
height: 33.33rpx;
margin-left: 19.6rpx;
margin-top: 9.8rpx;
margin-right: 19.6rpx;
}
.lbimg image{
width: 37.25rpx;
height: 33.33rpx;
}
.lbtxt{
font-size: 12px;
color: #4b4a4a;
height: 74.5rpx;
line-height: 74.5rpx;
}
.blc{
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 25.49rpx;
margin-left: 25.49rpx;
margin-right: 25.49rpx;
}
.lf{
background: url("~@/static/l1.png") no-repeat center;
background-size: 100%;
width: 337.25rpx;
height: 186.27rpx;
border-radius: 9.8rpx;
}
.lf view:nth-child(1){
font-size: 31.37rpx;
color: #FFFFFF;
margin-left: 31.37rpx;
margin-top: 19.6rpx;
}
.lf view:nth-child(2){
font-size: 23.52rpx;
color: #a8d1ff;
margin-left: 31.37rpx;
}
.lf view:nth-child(3){
float: left;
margin-left: 31.37rpx;
margin-top: 17.64rpx;
}
.lf view:nth-child(3) button{
width: 166.66rpx;
height: 50.98rpx;
color: #008dff;
background-color: #FFFFFF;
border-radius: 9.8rpx;
font-size: 23.52rpx;
line-height: 50.98rpx;
}
.rf{
background: url("~@/static/r1.png") no-repeat center;
background-size: 100%;
width: 337.25rpx;
height: 186.27rpx;
border-radius: 9.8rpx;
}
.rf view:nth-child(1){
font-size: 31.37rpx;
color: #FFFFFF;
margin-left: 31.37rpx;
margin-top: 19.6rpx;
}
.rf view:nth-child(2){
font-size: 23.52rpx;
color: #a8d1ff;
margin-left: 31.37rpx;
}
.rf view:nth-child(3){
float: left;
margin-left: 31.37rpx;
margin-top: 17.64rpx;
}
.rf view:nth-child(3) button{
width: 166.66rpx;
height: 50.98rpx;
color: #008dff;
background-color: #FFFFFF;
border-radius: 9.8rpx;
font-size: 23.52rpx;
line-height: 50.98rpx;
}
.hblc{
margin-top: 25.49rpx;
margin-left: 25.49rpx;
margin-right: 25.49rpx;
background: url("~@/static/heng.png") no-repeat center;
background-size: 100%;
border-radius: 9.8rpx;
height: 186.27rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 25.49rpx;
}
.hblc_l view:nth-child(1){
font-size: 31.37rpx;
color: #FFFFFF;
margin-left: 31.37rpx;
margin-top: 19.6rpx;
}
.hblc_l view:nth-child(2){
font-size: 23.52rpx;
color: #a8d1ff;
margin-left: 31.37rpx;
}
.hblc_l view:nth-child(3){
float: left;
margin-left: 31.37rpx;
margin-top: 17.64rpx;
}
.hblc_l view:nth-child(3) button{
width: 166.66rpx;
height: 50.98rpx;
color: #008dff;
background-color: #FFFFFF;
border-radius: 9.8rpx;
font-size: 23.52rpx;
line-height: 50.98rpx;
}
.hblc_r image{
width: 158.82rpx;
height: 158.82rpx;
margin-top: 12rpx;
margin-right: 12rpx;
}
.line{
height: 1px;
background-color: #f7f6f6;
}
.remen{
height: 27.45rpx;
margin: 0 auto;
text-align: center;
background: url("~@/static/rm.png") no-repeat center;
margin-top: 29.41rpx;
font-size: 27.45rpx;
padding-bottom: 9.8rpx;
font-weight: bold;
}
.bc{
margin-left: 25.49rpx;
margin-right: 25.49rpx;
margin-top: 31.37rpx;
}
.titles{
font-size: 27.45rpx;
font-weight: bold;
height: 47.05rpx;
border-bottom: dashed 1px #e1e1e1;
padding-bottom: 9.8rpx;
}
.itmlist{
display: flex;
flex-direction: row;
justify-content: center;
height: 147.05rpx;
border-bottom: dashed 1px #e1e1e1;
font-size: 27.45rpx;
}
.itm{
margin-right: 52.94rpx;
margin-left: 52.94rpx;
margin-top: 23.52rpx;
text-align: center;
}
.reds{
color: red;
}
.hui{
color: #afafaf;
}
.lan{
color: #008dff;
}
.disp{
font-size: 23.52rpx;
margin-top: 19.6rpx;
}
.btns{
height: 88.23rpx;
background-color: #008DFF;
color: #FFFFFF;
font-size: 27.45rpx;
border-radius: 9.8rpx;
margin: 0 auto;
text-align: center;
line-height: 88.23rpx;
margin-top: 39.21rpx;
margin-bottom: 29.41rpx;
}
.cline{
height: 4px;
background-color: #f3f3f3;
}
</style>
使用uniapp将每个页面都写好之后,我们接下来就要开始开发后端管理系统了。
四、后端开发
后端开发可以使用你习惯的任何一种语言进行开发,包括不限于JAVA、PHP、Python、Go、Nodejs等等,任何一门后端开发语言都足以胜任这一个小项目的开发,这里作者选择的是PHP来进行开发。
在进行后端开发之前我们先要了解后端的组成部分。后端管理系统也是一个相对独立和完整的B/S系统,所以它包含三个部分,分别为前端、数据库以及程序部分。前端部分我们选择的是Layui前端开发框架,Layui是一个比较成熟开源的国产前端开发框架,使用起来非常方便。其具体的使用方法可以参考Layui的官方网站。
下面是后台首页的Layui代码示例,代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<LINK href="__PUBLIC__/css/admin.css" type="text/css" rel="stylesheet">
<LINK href="__PUBLIC__/js/css/layui.css" type="text/css" rel="stylesheet">
<style type="text/css">
</style>
</HEAD>
<BODY >
<script src="__PUBLIC__/js/echarts.common.min.js"></script>
<script language="javascript" src="__PUBLIC__/js/layui.js"></script>
<script language="javascript" src="__PUBLIC__/js/jquery.min.js"></script>
<!--一行为12-->
<div class="layui-row layui-col-space10" style="margin: 0px; ">
<div class="layui-col-md8" style="padding-bottom: 0px;">
<div class="main_cont">
<div class="main_titles">数据概览</div>
<div class="main_cont_chd">
<div class="layui-row layui-col-space15">
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">总用户数</div>
<div class="main_block_numb">{$numbers.user_count}</div>
</div>
</div>
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">今日新增用户数</div>
<div class="main_block_numb">{$numbers.today_user_count}</div>
</div>
</div>
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">APP注册数量</div>
<div class="main_block_numb">{$numbers.trd_sum}</div>
</div>
</div>
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">H5注册数量</div>
<div class="main_block_numb">{$numbers.today_trd_sum}</div>
</div>
</div>
</div>
<div class="layui-row layui-col-space15">
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">总充值笔数</div>
<div class="main_block_numb">{$numbers.trd_count}</div>
</div>
</div>
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">24小时充值笔数</div>
<div class="main_block_numb">{$numbers.today_trd_count}</div>
</div>
</div>
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">总充值金额</div>
<div class="main_block_numb">{$numbers.ti_count}</div>
</div>
</div>
<div class="layui-col-md3 main_tops_chd ">
<div class="main_block">
<div class="main_block_title">24小时充值金额</div>
<div class="main_block_numb">{$numbers.ti_shen_count}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-col-md4" style="padding-bottom: 0px;">
<div class="main_cont main_cont_right_panel" >
<div class="main_titles">版本信息</div>
<div style="margin-top: -5px;">
<table class="layui-table">
<colgroup>
<col width="100">
<col>
</colgroup>
<tbody>
<tr>
<td>当前版本</td>
<td>V1.0.0 </td>
</tr>
<tr>
<td>最新版本</td>
<td>V1.0.0 </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="layui-row layui-col-space10" style="margin: 0px;padding-top: 0px;">
<div class="layui-col-md8" style="padding-top: 0px;padding-bottom: 0px;">
<div class="main_cont">
<div class="main_titles">最近15天用户注册数量</div>
<div style="height: 382px;" id="charts"></div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('charts'),"light");
var option = {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['1', '2', '3', '4', '5', '6', '7','8','9','10','11','12','13','14','15']
},
yAxis: {
type: 'value'
},
series: [{
data: [{$lastnumbers[14]},{$lastnumbers[13]},{$lastnumbers[12]},{$lastnumbers[11]},{$lastnumbers[10]},{$lastnumbers[9]},{$lastnumbers[8]},{$lastnumbers[7]},{$lastnumbers[6]},{$lastnumbers[5]},{$lastnumbers[4]},{$lastnumbers[3]},{$lastnumbers[2]},{$lastnumbers[1]},{$lastnumbers[0]}],
type: 'line',
areaStyle: {}
}]
};
myChart.setOption(option);
window.onresize = function() {
myChart.resize();
};
</script>
</div>
</div>
<div class="layui-col-md4" style="padding-top: 0px;padding-bottom: 0px;">
<div class="main_cont main_cont_right_panel2" style="height: 424px; overflow-y: scroll;">
<div class="main_titles">最近登录IP及地区</div>
<div style="height: 341px;">
<table class="layui-table" id="ips">
<colgroup>
<col >
<col >
<col>
<col>
</colgroup>
<thead>
<tr>
<th>账号</th>
<th>时间</th>
<th>IP</th>
<th>地区</th>
</tr>
</thead>
<tbody>
{volist name="adminarrs" id="vo"}
<tr>
<td>{$vo.username}</td>
<td>{$vo.logintime}</td>
<td>{$vo.loginip}</td>
<td>{$vo.area}</td>
</tr>
{/volist}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="layui-row layui-col-space10" style="margin: 0px;padding-top: 0px;">
<div style="padding-top: 0px;">
<div class="main_cont">
<div class="main_titles">服务器信息</div>
<div style="height: 288px;">
<!---->
<table class="layui-table">
<colgroup>
<col width="20%">
<col width="30%">
<col width="20%">
<col>
</colgroup>
<thead>
<tr>
<th>项目</th>
<th>数据</th>
<th>项目</th>
<th>数据</th>
</tr>
</thead>
<tbody>
<tr>
<td>服务器操作系统</td>
<td>{$pcou.ios}</td>
<td>Web服务器</td>
<td>{$pcou.webserver}</td>
</tr>
<tr>
<td>语言版本</td>
<td>{$pcou.ver}</td>
<td>数据库版本</td>
<td>{$pcou.mysql}</td>
</tr>
<tr>
<td>安全模式</td>
<td>{$pcou.safe_mode}</td>
<td>安全模式GID</td>
<td>{$pcou.safe_mode_gid}</td>
</tr>
<tr>
<td>Socket支持</td>
<td>{$pcou.socket}</td>
<td>服务器时间</td>
<td><a id="tim">{$pcou.tim}</a></td>
</tr>
<tr>
<td>GD版本</td>
<td>{$pcou.gdv}</td>
<td>Zlib支持</td>
<td>{$pcou.zlib}</td>
</tr>
<tr>
<td>编码</td>
<td>{$pcou.char_set}</td>
<td>文件上传的最大大小</td>
<td>{$pcou.upsize}</td>
</tr>
</tbody>
</table>
<!---->
</div>
</div>
</div>
</div>
<div class="buttomss"><span class="STYLE6"> 瑞丰理财APP及管理系统,不得非法运营</span></div>
</BODY></HTML>
PHP部分使用的thinkphp开发框架,thinkphp同样是国人开发的开源PHP开发框架。可以通过该框架快速的开发Web应用。具体信息可查询Thinkphp的官方网站。对于后台首页的显示,PHP的代码如下:
public function main()
{
$data=$this->getsys_info();
$this->assign("pcou",$data);
$adminlogin_arr=$this->getadmin_login_log();
$this->assign("adminarrs",$adminlogin_arr);
$numbers=$this->getnumbers();
$this->assign("numbers",$numbers);
$lastnumbers=$this->getlastnumbers();
$this->assign("lastnumbers",$lastnumbers);
$this->display("Index:main");
}
具体方法进行了封装,可以在文末查看完整的源代码。后台部分同样应当是产品负责人来进行设计,也就是说后台长什么样在产品设计的时候也一并设计完毕了。这样后端开发人员可以根据设计好的原型来指定数据库以及数据表的相关内容。理财APP的数据表如下:

此处我们使用的是Mysql数据库,所以使用Navicat for Mysql客户端来对Mysql进行管理。Navicat for Mysql是一款可视化的Mysql数据库管理工具,使用起来简单方便。与之类似的Mysql客户端管理工具还有Workbench以及在线的数据库管理工具phpmyadmin。
后端开发完成之后,就需要与APP端进行数据对接,大多数APP都采用JSON格式通过HTTP或者HTTPS协议来进行后端与APP端的数据交换。对于一些实时性要求比较高的功能,例如在线客服系统中的即时通信,则需要使用WebSocket协议来进行数据交换。对于我们的理财APP来说,使用HTTP或者HTTPS协议通过JSON格式来进行数据交换即可满足要求了。
五、测试
前端与后端对接并开发完毕之后,前后端开发人员经过简单的测试没有问题之后将会交付给专业的测试人员进行测试。对于这类比较小的APP测试来说,大多是进行黑盒测试,即通过输入输出来判断是否出现错误。
除了黑盒测试以外,在了解相关接口时,也可以通过一些辅助工具来模拟提交相关数据,这类辅助工具在后端开发人员开发接口时也可以使用。这类工具有Fiddler、PostMan等,可以无需界面直接通过接口发送数据给后端,看后端处理数据的内容以及返回的内容是否会出错。其中Fiddler除了可以模拟提交数据以外,还可以拦截请求数据进行分析。如图所示。

对于前端测试则可以使用谷歌浏览器的调试工具来查看页面中是否会有出错的部分,并且可以通过浏览器中的控制台来给脚本提交相应的数据以测试其反应,如图所示

六、部署
当测试没有问题之后,就可以部署上线了。对于初创团队来说,将代码托管至云主机比自己采购服务器托管至机房成本要低很多。前期业务量往往也不太大,且云主机本身也支持随时扩容。所以使用云主机进行代码的托管是一件正确的事情。市面上云主机比较多,名气比较大的当属阿里云,于此类似的还有腾讯云、七牛云、AWS、华为云、金山云等等。
根据实际情况购买云主机后,就可以将代码部署上去了,在购买云主机时需要注意你代码运行的环境。以PHP为例,可以运行在Windows上也可以运行在Linux上,通常情况下运行在Linux上会比Windows要稳定一些。所以在选购云主机时注意选择操作系统类型以及其版本。
当代码已经上传至云主机后,想要正常的访问还需要购买一个域名,将域名指向该服务器。如要绑定域名,在国内则还需要完成服务器的备案以及域名的实名认证。这一些都完成之后,你就可以将APP中域名修改为正式服务器的域名并编译打包,完成之后就可以上传至应用市场供用户下载了。
本文详述了一个小型理财APP的开发过程,包括原型设计、美术设计、前端开发、后端开发、测试和部署。文章适合初级从业者理解产品开发周期,帮助创始人了解行业,以及让寻求软件外包的老板理解每个开发节点。文中提到使用Axure和Photoshop进行原型和设计,前端使用uniapp,后端采用PHP和Thinkphp框架,并用MySQL作为数据库。
&spm=1001.2101.3001.5002&articleId=119298132&d=1&t=3&u=2b71d7e03c1c40babe664c4d84d65053)
5465

被折叠的 条评论
为什么被折叠?



