来自客户的项目需求
有一天,有位客户和我说,他想做一个H5激励视频广告业务后台,经过沟通,梳理的后台需求如下:
【H5激励视频广告】
1、一套H5激励视频广告接口
1)获取广告接口,进行展示,提供给客户端开发者用
参考:http://developers.adnet.qq.com/doc/ios/union/union_h5_reward
2)事件上报接口
展示成功、广告跳转、浏览器关闭、视频插放开始、视频插放完成等
3)回调接口,提供给流量商那边回调数据
接口可参考:https://ad.68mob.com/doc/api2.0.html
2、管理后台
1)接口密钥分配,针对不同的流量商进行后台生成,可删除
2)统计报表,个展示数量、点击数量、回调 能知道我们展示多少 点击多少 点击率多少
3)广告管理,上/删 视频素材 上/删 视频标题 上/删 行动语 上/删 封面 上/删 logo 上/删 落地页链接
4)视频、图片等素材存在服务器,不使用云存储
3、其他
1)交付全部源代码
2)进行线上安装与部署
3)提供在线接口文档
4)配合协作第一位开发者、第一位流量商接入使用
5)输出产品原型PRD
就其中后台的开发任务,可以基于PhalApi开源框架的portal运营平台进行快速开发,估计可以从5天的时间缩减成1天的开发时间。
广告业务后台的PRD如下,有:
- 后台登录
- 广告管理
- 密钥管理
- API接口
下面结合这个真实案例,介绍PhalApi开源框架,如何帮助项目进行快速开发。
PhalApi开源框架的portal运营后台
PhalApi的Portal运营平台,是提供给运营团队使用的管理后台。从PhalApi 2.12.0 及以上版本提供,可以非常方便进行数据和业务上的管理。
介绍
运营平台有以下几个特点:
- 免费使用,可放心用于商业项目开发
- 基于layuiminiLAYUI MINI 后台管理模板和layui经典模块化前端框架开发运营平台界面,让后端开发也能轻松入手
- 提供与后面界面配套的后台数据接口,基本不用写代码,就能实现后台数据的增删改查操作
- 可视化运营平台安装,安装后即可使用
在我们PhalApi官方文档也要相应的详细介绍。
对于本次广告业务后台,实现的效果截图如下。大家可以访问测试环境:
http://test.h5_video_ad.yesapi.net/portal/index.html#/page/ad/index.html
账号:admin,密码:123456
编辑页效果:
登录页面:
portal快速开发步骤
从底层数据库往前端页面倒推的方式,进行以下开发(你也可以反过来,从前端页面到数据库)。
后端PHP开发部分
首先,根据业务需求,创建数据库表,例如【广告管理】功能模块,需要以下字段:
- 广告标题
- 广告副标题
- 广告icon
- 视频素材
- 视频封面
- 按钮名称
- 落地页链接
- 状态
对应的SQL语句是:
CREATE TABLE `ad` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ad_title` varchar(500) DEFAULT '' COMMENT '广告标题',
`ad_sub_title` varchar(500) DEFAULT '' COMMENT '广告副标题',
`ad_icon` varchar(500) DEFAULT '',
`add_time` datetime DEFAULT NULL,
`ad_status` tinyint(4) DEFAULT '1' COMMENT '状态,1正常0关闭',
`video_url` varchar(500) DEFAULT '' COMMENT '视频链接',
`video_img` varchar(500) DEFAULT NULL COMMENT '视频封面',
`btn_title` varchar(100) DEFAULT '' COMMENT '按钮名称',
`download_url` varchar(500) DEFAULT '' COMMENT '落地页',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
然后,为广告创建对应的Model类,新建文件:./src/portal/Model/Ad.php ,添加以下基础的PHP代码,注意你的Model子类要继承DataModel,后面会有更详情地介绍。
<?php
namespace Portal\Model;
use PhalApi\Model\DataModel;
class Ad extends DataModel {
public function getTableName($id) {
return 'ad';
}
}
接下来,为广告创建Api类,添加src/portal/Api/Ad.php文件,并放入以下PHP代码。注意Api子类需要继承DataApi,并且需要重载实现getDataModel()方法,在里面返回上面实现的广告Model类。
<?php
namespace Portal\Api;
use Portal\Common\DataApi as Api;
class Ad extends Api {
protected function getDataModel() {
return new \Portal\Model\Ad();
}
}
至此,针对广告这一业务单元,后端开发已完成基础性的开发。
前端开发部分
接下来,进入前端的业务开发。
首先,把前端页面的示例目录./public/portal/page/phalapi-curd-table,复制一份到 ./public/portal/page/ad目录,里面会有三个HTML文件:
- add.html 添加页面
- edit.html 编辑页面
- index.html 模块首页
但这时,页面还不会显示,需要再添加左侧菜单。在【菜单管理】中,把刚才复制的页面路径,放置到 菜单链接中,即:page/ad/index.html,菜单标题为:广告管理。
刷新页面后,就可以看到菜单,并进行访问。
随后,前端只需要定制需要搜索的条件、需要展示的表格数据,以及需要调用的对应接口模块,剩下的由框架完成即可。例如模块列表首页,修改需要显示的表格数据,可以通过JS配置实现。修改./public/portal/page/ad/index.html 文件,
cols: [[
{type: "checkbox", width: 50, fixed: "left"},
{field: 'id', width: 80, title: 'ID', sort: true},
{field: 'ad_title', minWidth: 50, title: '广告标题'},
{field: 'ad_sub_title', minWidth: 50, title: '广告副标题'},
{
field: 'icon', minWidth: 50, align: 'center', templet: function (d) {
//return '<a target="" href="/portal/page/stat/index.html?id='+d.id+'">查看统计</a>';
return '<img src="'+d.ad_icon+'" height="28" alt="无法加载"/>';
}, title: '广告icon', sort: false
},
{field: 'add_time', minWidth: 80, title: '添加时间', sort: true},
{
field: 'ad_status', minWidth: 50, align: 'center', templet: function (d) {
if (d.ad_status == 0) {
return '<span class="layui-badge layui-bg-red">关闭</span>';
} else {
return '<span class="layui-badge-rim">正常</span>';
}
}, title: '广告状态', sort: true
},
{
field: 'id', minWidth: 50, align: 'center', templet: function (d) {
//return '<a target="" href="/portal/page/stat/index.html?id='+d.id+'">查看统计</a>';
return '<a target="_blank" href="/portal/index.html?id='+d.id+'#/page/stat/index.html">查看统计</a>';
}, title: '统计', sort: true
},
{title: '操作', minWidth: 50, templet: '#currentTableBar', fixed: "right", align: "center"}
]],
同时,修改指定调用的接口。
table.render({
elem: '#currentTableId',
url: '/?s=Portal.Ad.TableList', // 换成相应的运营平台接口
当数据库有测试数据后,刷新页面可以看到以下效果。
再调整添加数据页面的表单数据,修改./public/portal/page/ad/add.html文件,修改HTML,
<div class="layui-form layuimini-form">
<div class="layui-form-item">
<label class="layui-form-label required">广告标题</label>
<div class="layui-input-block">
<input type="text" name="ad_title" lay-reqtext="广告标题不能为空" class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label required">广告副标题</label>
<div class="layui-input-block">
<input type="text" name="ad_sub_title" lay-reqtext="广告副标题不能为空" class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">广告icon</label>
<div class="layui-input-block">
<button class="layui-btn" id="uploadIcon">上传图片</button>
<br>
<img id="imgIcon" src="" alt="">
<input type="hidden" name="ad_icon" value="">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">视频素材</label>
<div class="layui-input-block">
<button class="layui-btn" id="uploadVideo">上传视频</button>
<input type="text" name="video_url" class="layui-input" value="">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">视频封面</label>
<div class="layui-input-block">
<button class="layui-btn" id="uploadVideoImg">上传图片</button>
<br>
<img id="imgVideo" src="" alt="">
<input type="hidden" name="video_img" value="">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">按钮名称</label>
<div class="layui-input-block">
<input type="text" name="btn_title" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">落地页链接</label>
<div class="layui-input-block">
<input type="text" name="download_url" value="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="ad_status" value="1" checked title="正常" >
<input type="radio" name="ad_status" value="0" title="关闭" >
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="saveBtn">添加广告</button>
</div>
</div>
</div>
刷新后,添加广告的页面效果如下,
别忘了同步修改保存接口的地址,
upload.render({
elem: '#uploadIcon'
,url: '/?s=Portal.Ad.upload' //必填项
到这里,添加广告的功能就实现了。编辑功能类似,由于还有文件上传的部分,所以还需要一些额外的代码开发。
以此类推,可以继续快速开发其他菜单模块,例如剩下的还有密钥管理、报表统计等。
PhalApi开源框架的DataModel数据模型介绍
为了进一步减少数据库操作的代码开发量,避免在开发者在Model子类重复编写代码实现基本的数据库操作。从PhalApi 2.12.0 及以上版本起,我们提供了PhalApi\Model\DataModel数据库数据基类。
如果你是初次使用PhalApi框架,建议在项目开发过程中全部的Model子类都继承于此PhalApi\Model\DataModel基类;如果你已经使用PhalApi框架开发有段时间,那么在新的Model或原有的Model子类也可以把原来继承于PhalApi\Model\NotORMModel基类调整成PhalApi\Model\DataModel,可能的影响是会存在函数名冲突。
使用DataModel前后的继承关系对比如下:
而最大的区别是,DataModel直接提供了对外可用的数据库操作接口,是开放式的;而NotORMModel是封闭式的,很多数据库操作都需要在NotORMModel内部先实现再提供编写好的接口给外部调用。
一键生成DataModel源代码
如果项目本来已经有数据库表,或者新项目时设计好了一批数据库表,这时,可以使用脚本./bin/phalapi_build_data_model.php迅速一键生成全部的DataModel源代码。
这将能极大提升开发的效率。
PhalApi开源框架的DataApi通用数据接口介绍
为了进一步实现接口低代码编程,为了能以更少的代码,实现更多的接口,满足更广业务需求,PhalApi结合多年的接口系统和项目开发经验,从PhalApi 2.13.0 版本起推出PhalApi\Api\DataApi通用数据接口。
它的特色在于,可以针对单个数据库表提供一套完整的、常用的、基本的数据接口,以自动完成对数据库表的CURD基本操作,避免重复接口开发。
DataApi有哪些接口?
如果需要实现对数据库表的数据管理,进行常见的增删改查操作,那么可以让你的Api接口类直接继承PhalApi\Api\DataApi基类。继承后便可自动拥有一套基本的数据接口。
目前有5个数据接口(后面会进一步扩展):
- 创建新数据,{命名空间}.{接口类名}.CreateData
- 批量删除,{命名空间}.{接口类名}.DeleteDataIDs
- 获取一条数据,{命名空间}.{接口类名}.GetData
- 获取表格列表数据,{命名空间}.{接口类名}.TableList
- 更新数据,{命名空间}.{接口类名}.UpdateData
结合的力量,1+1 > 2
当我们把DataModel和DataApi相合时,就能快速完成后端的接口开发;当我们使用portal的HTML页面模板时,就能快速完成前端的基本开发;当我们把后端和前端进行结合时,在平时项目需求开发时,就能更快速地实现需要的功能和菜单模块。实现 1加1,大于2的效果。
如果需要进一步了解PhalApi开源框架的相关内容,可以查看官方文档,链接:http://docs.phalapi.net/#/v2.0/tutorial
来源:oschina
链接:https://my.oschina.net/dogstar/blog/4945127