目录:
我作为一个易班工作站的技术人员,经常会遇到要制作轻应用的需求。但是,易班平台的【轻应用快搭】有点单调,存在以下两个问题:
- 模式单一。只有报名,抢票,评选三个模板。不能自定义界面UI。模块有限且使用有限制。
- 功能有限。【轻应用快搭】只能解决特定场景下的需求,比如活动报名,比赛评选等。但是,当我们需要一些个性化的功能的时候,快搭并不能提供。
轻应用快搭大多数是千篇一律。所以,我需要一个能够自定义功能和界面的轻应用来满足易班工作站个性化的需求。那么,作为一个程序员,第一个想到的是看官方文档。结果…
创建轻应用的流程
再看另外一个…
轻应用开发指南
当时作为一个小白,我是看不懂这个文档在说什么。然后第一反应是,我缺少了一些必要知识。比如,这个轻应用到底是怎么回事,开发流程具体是怎么样的?经过一系列百度之后,我终于明白开发一个第三方轻应用不是一个依靠百度就能够解决的事情。这已经是相当于从头开始开发一个网站了。那么我研究了一个星期,终于把它搞懂了。在做出来一个轻应用之后,我想把自己的经验分享一下。所以,我把我开发轻应用走过的坑,开发的过程给写出来,给大家参考。首先,我们要明白,易班轻应用到底是什么?
在易班开放平台的文档中心,是这么写的。
那么,可以理解为【轻应用】分为两种:
易班提供服务器,提供模板,用户有限修改后,提交审核。然后易班在自己的服务器上开辟一个空间,存放用户修改后的模板,然后提供链接在易班APP上显示出来。
开发者自己提供服务器,自己制作一个网站应用。申请易班轻应用,提供链接给易班审核,通过后,用户可以通过易班平台使用你的网站应用。
所以,我们要搭建的轻应用是一个网站,那么,必须有一个可以存放项目的服务器,建议去阿里云或者腾讯云购买,还有服务器软件,最重要的是我们的轻应用项目。
当初作为一个小白,我是有很多不明白的,比如以下的问题:
接下来,我将一一讲解轻应用到底是怎么开发的。
首先,我们要明白轻应用到底是怎么回事。易班轻应用说到底是一个网站应用,可以通过web访问的应用程序。就像你要进行百度一样。你首先是在浏览器输入一个网址www.baidu.com
,然后浏览器给你显示一个网页,接着,你在百度输入框中输入要查找的内容,浏览器接着跳转,显示搜索结果。这就是一个程序基本的功能:用户请求/输入,应用处理请求和返回结果。
整个过程,实际上就像这样子:
那么要开发类似的网站应用:易班轻应用。很明显,需要以下的东西:
那么,我们需要一些基础的知识:
<>>
构成,一对尖括号里面是内容,内容一般会被显示出来。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>音乐title>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<script src="bootstrap.min.js">script>
<script src="jquery-3.3.1.min.js">script>
head>
<body>
<div class="container">
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="text-center">befallh4>
div>
<div class="panel-body">
<div><audio class="center-block" controls="controls" src="begin1.mp3">audio>div>
div>
div>
var text = "易班工作站技术部";
var show = function(text){
console.log(text);
for(var i=0; i<2; ++i){
if(i==1){
break;
}
}
}
$text = "易班工作站技术部";
function show($text){
echo $text;
for($i =0; $i<=2; ++$i){
echo $text;
}
}
以上是我们需要的基础知识,可以通过下面的【1. 必备基础知识】的链接进行学习。
接下来,我们需要一个服务器。为什么呢?因为我们的轻应用是需要被很多人使用的,轻应用是一个网页,这意味着我们需要把它放在一个公共的地方,而不是放在自己的电脑上。而这个公共的地方就是服务器。服务器实际上也是一台电脑,只有主机的电脑。它一般24小时开机,所以服务器能够被任何人任何时候访问。当然,需要安装一些东西才能被访问。就像是接待客人一样,你得有一定的规矩,才能让你喜欢的客人满意,而把不喜欢的客人拒之门外。
我们可以到阿里云或者腾讯云购买服务器,具体操作请看【2. 服务器购买】
我们的服务器,要让用户访问到,需要一个地址。一般是你的ip地址。但是为了安全,我们需要去备案一个域名,让别人不能轻易攻击我们的服务器。除了一个域名之外,我们还需要在服务器上安装好服务器软件,这是你接待用户的第一步:解析请求,并返回结果。一般有两种:Apache和Nginx,最近几年,Nodejs也是很火。这篇文章是以Apache为基础讲解的,所以我们选择Apache 。
安装服务器软件能够让我们解析请求,而对请求进行操作,返回结果需要脚本的支持。我们选择php作服务器端的脚本。
安装php环境后就能够运行php脚本。另外,光是对请求进行操作还是不够的。我们还要返回数据和存储数据,这时候需要一个系统的文件夹方便我们调用。所以我们安装mysql作为我们的数据库。
以上的所有安装包,都被集成在wamp server安装包上,这样就不用一个个安装和对接了。具体安装请看下面的【3. 环境配置(服务器端)】
以上都完成后,我们就可以进行轻应用的开发。首先,请看【4. 轻应用申请】
我们需要把项目部署到服务器,轻应用才能安全便捷地被外部访问。有的人会想购买一个实体的服务器,但是轻应用一般比较小,用户也是学校里面的学生,所以并不需要一个实体的服务器,麻烦,我们只需要购买一个云服务器即可。具体流程查看各云服务器提供商提供的机型。另外,阿里云和腾讯云进行学生认证后,都有学生价。可以以低价格购入服务器。
服务器配置:
机型1核1GB即可,操作系统选择windows Server2012 64位,带宽1M,时长一个月到三个月,测试用服务器无需购买域名,如果要作为应用服务器,那么需要购买域名。
远程连接:
因为在服务器提供商的网页上远程操作服务器有些掉帧,所以,我们用自己的电脑进行远程连接。正好我们的服务器系统是windows,所以如果你的电脑是windows操作系统,那么使用window自带的远程连接软件进行远程连接。一般这个远程连接软件是在【windows附件】这个文件夹里面的,叫做【远程桌面连接】。
【计算机】填你要连接服务器的公网ip(例子:127.0.0.1)
【用户名】一般默认为Administrator
【密码】你的服务器用户名下的密码,而不是服务商网站控制台上的密码
这里会出现一个问题:出现身份验证错误,要求函数
有两个办法可以解决:一个是在自己电脑上解决,另一个是在云服务器提供商的网页控制台上修改服务器。
一,本地配置修改
二,服务器端修改
最后,你就可以通过自己电脑连接上自己的服务器了。
由于我们是初学者,所以就先用windows server来作为服务器系统。实际上的生产环境是需要linux系统作为服务器系统的。并且需要配合终端软件进行文件传输和远程控制。
服务器端的系统环境是window server 2012 , wamp环境
vc++
运行库环境(2008-2015全部)http://localhost
以下的错误修改是基于wamp server 2.5的
Require local
修改成Require all granted
www目录:C:/wamp64/www/
变更目录: G:/wamproot
C:\wamp64\bin\apache\Apache2.2.17\conf\httpd.conf
ctrl+f
查找:DocumentRootDocumentRoot "G:/wamproot"
wampmanager.ini
和wampmanager.tpl
C:/wamp64/wampmanager.ini
Type: item; Caption: "www directory"; Action: shellexecute; FileName: "c:/wamp64/www"; Glyph: 2
Type: item; Caption: "www directory"; Action: shellexecute; FileName: "g:/wamproot"; Glyph: 2
C:\wamp\wampmanager.tpl
Type: item; Caption: "${w_wwwDirectory}"; Action: shellexecute; FileName: "${wwwDir}"; Glyph: 2
Type: item; Caption: "${w_wwwDirectory}"; Action: shellexecute; FileName: "g:/wamproot"; Glyph: 2
以上四步完成后,接下来在自己的电脑上进行轻应用开发。首先,我们要下载文本编辑器sublime text3,方便代码的编写。其次,我们下载chrome浏览器最新版本,方便我们的调试。
以上的步骤都是为开发和运营做准备的。
现在我以自己曾经开发过的一款易班轻应用【易晚归】为例子,分析轻应用的开发过程。
分两个:建立轻应用项目,建立轻应用的数据库。在上线的时候,要把项目和数据库都转移到服务器上。
以下的开发环境为最简便的。
请按照以上清单部署开发环境
需求分析在我们的轻应用开发中算是第一步。需求一般是在易班工作站中开会提出来的,我需要一个什么样功能的轻应用。这个功能就是需求。分析功能,然后拆解成可执行的目标,就是我们这一步的目的。
到了这一步。我们将功能拆解为小目标后,就要用代码实现其过程。首先,我们需要将整个项目的功能逻辑完整地列出来,以便于我们知道整个应用运行的具体流程是怎么样的。也方面团队成员的分工合作。接着根据功能逻辑,确定项目的结构,什么脚本实现什么功能,需要什么依赖,数据结构又是怎么样的。最后,才是一步步编写代码,测试。
yiban_lateback
|
|____index.php(负责易班授权,判断用户信息,控制数据的呈现)
|
|____php(服务器脚本,构建页面,传输数据)
|____form_submit.php(晚归表格,向数据库插入数据,并返回成功界面)
|____check_form_submit.php(审核界面,向数据库插入数据,并返回审核完毕界面)
|____authority.php(易班授权,启用session存储用户信息)
|____openDB.php(类,打开数据库,并把数据库对象暴露出来)
|____formCreater.php(类,界面构建,提供模板引擎的功能)
|____checkFromer.php(审核表格搭建,根据后台信息构建页面)
|____formPageCreater.php(晚归表格搭建,根据用户信息构建页面)
|____reactPage.php(审核结果页面,根据用户id,从数据库判断用户的审核结果)
|____html(网页模板,网页)
|____check_from_modle.html(审核页面模板)
|____form_page_modle.html(晚归表格页面模板)
|____react_page_modle.html(审核结果页面模板)
|____js(前端脚本,表单验证)
|____index.js(晚归表格验证)
|____check.js(审核界面的选择审核不通过显示原因选项)
|____check_form.js(审核页面的隐藏部分界面功能)
|____check_form_lateback.js(晚归表格,验证非空)
|____bootstrap.min.js(前端框架,js美化页面)
|____jquery-3.3.1.min.js(前端框架,对一般的功能进行封装,比如dom操作)
|____yb_h5.js(易班在手机上的一些功能,我们使用定位的功能)
|____css(网页修饰)
|____bootstrap.min.css(前端框架,css样式的一个库)
|____lib(依赖文件,其他功能的依赖包)
|____fonts(bootstrap的图标库)
|____fpdf(PHP的一个类,让html能够转为pdf)
yiban_lateback //晚归表
|____stu_name varchar(20) //学生名字
|____yiban_id varchar(10) //易班id
|____studentID varchar(15) //学号
|____academy varchar(22) //学院
|____className varcahr(13) //班级和班别
|____phone varchar(11)//本人手机号
|----reason text //理由
|----time_log varchar(38) //提交时间
|----passed varchar(6) // 审核状态:待审核,未通过,已通过
|----local_address text //定位的位置
|____back_method varchar(4) // 是否晚归
|____reason_method varchar(4) //是否兼职
|____react_reason text // 驳回理由,无则为空
yiban_notback //不归表
|____yiban_id varchar(10) //易班id
|____time_log varchar(38) //提交时间
|____late_time varchar(38) //离校时间
|____back_time varchar(38) //回校时间
|____address text //去向
|____connect_name varchar(20) //联系人名字
|____connect_phone varchar(11) //联系人电话
part_time_job //兼职表
|____yiban_id varchar(10) //易班id
|____time_log varchar(38) //提交时间
|____agent_name varchar(20) //兼职联系人名字
|_____agent_phone varchar(11) //联系电话
|_____agent_address text //兼职地点
yiban_admins //管理员表
|____admin_name varchar(10)//管理者名字
|____academy varchar(22)//管理者所属学院
|____yiban_id varchar(10) //管理者的易班id
|____auth varchar(6) //管理者权限
//index.php
require("php/opendb.php");
include("php/check_former.php");
include("php/ReactPage.php");
include("php/FormPageCreater.php");
$DB_obj = new DB();
$db = $DB_obj-> db;
mysqli_set_charset($db, "utf8");
//初始化,获取用户信息以及打开数据库一次
$userInfo = $_SESSION["userInfo"];
if($adminInfo = is_yiban_admin($userInfo["info"]["yb_realname"],
$userInfo["info"]["yb_userid"],$db)){//根据信息判断是否为管理员
if($auth = has_student_apply($adminInfo["academy"],$adminInfo["auth"],$db)){
$studentInfo = getStudentInfo($adminInfo["academy"],true,$db,$auth);//有学生申请,则数组长度大于0
if(count($studentInfo) > 0){//返回审核页面
setCheckForm($adminInfo["admin_name"],$adminInfo["academy"],$studentInfo);
}else{
setReactPage("glyphicon-refresh","目前没有学生登记晚归,请稍后再来","warning");
}
}else{
if($passed = was_student_fill($userInfo["info"]["yb_realname"],$userInfo["info"]["yb_userid"],$db)){//今天填写过,则再次打开会返回审核结果页面
if($passed == "待审核"){
setReactPage("glyphicon-option-horizontal","正在审核中,请稍后再来","warning");
}else if($passed == "通过"){
setReactPage("glyphicon-glyphicon-ok","审核通过!请在次日凌晨1点之前回来,不然晚归登记无效","success");
}else{
setReactPage("glyphicon-alert","审核未通过","danger");
}
}else{//没有填写过,返回表格页面
date_default_timezone_set('PRC');//设置为中国时区
$nowTimer = strval(date('Y-m-d H:i:s', time()));
if(!is_time_out($nowTimer,"08:00:00","22:00:00")){
setFormPage($userInfo);
require("html/readme.html");
}else{
setReactPage("glyphicon-exclamation-sign","已经超过晚归填写时间,请在明天的8:00-22:00前来填写","warning");
}
}
}
//more code.....上面出现过的方法都在下文,这里省略
index.php
的,通过require('php/authority.php');
引用。易班授权的原理是发起一个http请求,在请求中带上自己轻应用的参数,接着服务器会返回授权界面,让用户进行授权。所有的服务器脚本都会有自带的http请求的方法的。//authority.php
session_start();//开始会话
ini_set("display_errors", "On");
error_reporting(0);
if (!function_exists('curl_init')) {
throw new Exception('YiBan needs the CURL PHP extension.');
}
if (!function_exists('json_decode')) {
throw new Exception('YiBan needs the JSON PHP extension.');
}
if (!function_exists('mcrypt_decrypt')) {
throw new Exception('YiBan needs the mcrypt PHP extension.');
}
//以下三个变量内容需换成本应用的
$APPID = "xxx"; //在open.yiban.cn管理中心的AppID
$APPSECRET = "xxx"; //在open.yiban.cn管理中心的AppSecret
$CALLBACK = "http://f.yiban.cn/iappxxxx"; //在open.yiban.cn管理中心的oauth2.0回调地址
if(isset($_GET["code"])){ //用户授权后跳转回来会带上code参数,此处code非access_token,需调用接口转化。
$getTokenApiUrl = "https://oauth.yiban.cn/token/info?code=".$_GET['code']."&client_id={$APPID}&client_secret={$APPSECRET}&redirect_uri={$CALLBACK}";
$res = sendRequest($getTokenApiUrl);
if(!$res){
throw new Exception('Get Token Error');
}
$userTokenInfo = json_decode($res);
$access_token = $userTokenInfo["access_token"];
if($access_token) echo "success";
}else{
$postStr = pack("H*", $_GET["verify_request"]);
if(strlen($APPID) == '16') {
$postInfo = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $APPSECRET, $postStr, MCRYPT_MODE_CBC, $APPID);
}else {
$postInfo = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $APPSECRET, $postStr, MCRYPT_MODE_CBC, $APPID);
}
$postInfo = rtrim($postInfo);
$postArr = json_decode($postInfo, true);
if(!$postArr['visit_oauth']){ //说明该用户未授权需跳转至授权页面
header("Location: https://openapi.yiban.cn/oauth/authorize?client_id={$APPID}&redirect_uri={$CALLBACK}&display=web");
}
$access_token = $postArr['visit_oauth']['access_token'];
}
//拿到access token了,接下来我们获取当前用户的基本信息试试看,so easy!
$userInfoJsonStr = sendRequest("https://openapi.yiban.cn/user/verify_me?access_token={$access_token}");
$userInfo = json_decode($userInfoJsonStr,true);
/*$post_data = array(
"client_id" => "413f4e7b9d90c170",
"access_token" => $access_token;
);*/
//$userAccessInfo = sendPostRequest("https://openapi.yiban.cn/oauth/token_info",$post_data);
//$std = sendmail($access_token, $userInfo["info"]["yb_userid"],"your mail is sent");
$_SESSION["userInfo"] = $userInfo;//存储用户信息,方便以后调用
$_SESSION["auth"] = $access_token;//存储授权令牌,方便发送邮件等操作,过期时间为一天多
function sendRequest($uri){//这里发送的是GET请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_USERAGENT, 'Yi OAuth2 v0.1');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array());
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ch);
return $response;
}
/*formCreater.php
* 这是一个父类,对所有继承它的类会提供打开文件,替换字符串,关闭文件的操作。
* 重复替换可以达到构建多个模块的页面的效果。当然,这是我写的原生的模板引擎,比不上别人写好框架里面的模板引擎。
*
*/
class FormCreater
{
private $model_file;
protected $target_file;
private $file_handle;
protected $str_handle;
function __construct($target_file)
{
$this -> target_file = $target_file;
}
public function openFile($model_file){//复制一个模板到目标文件
$this -> file_handle = fopen($model_file,"r");//只读打开
$this -> str_handle = $this ->read_File($model_file);//读取文件,返回文件的字符串
// echo (fread($this -> file_handle,filesize($model_file)));
$this -> str_handle = str_replace('','',$this -> str_handle);
fclose($this -> file_handle);
$handle = fopen($this -> target_file,"w");//只写打开,清除所有
fwrite($handle,$this -> str_handle);//写入
fclose($handle);//指针关闭
$this -> file_handle = fopen($this -> target_file,"r");//只读打开
//$this -> str_handle = read_File($this -> file_handle);
fclose($this -> file_handle);
//读取本文件的字符串句柄
}
public function read_File($file){//读取大文件
$fp = fopen($file,"r");
$num = 10;//十行
$chunk = 4096;//一块
clearstatcache();
$fs = sprintf("%u", filesize($file));//返回不包含正负号的十进制数
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);//设置最大值
$readData = "";
for ($len = 0; $len < $max; $len += $chunk)
{
$seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;//取一块,不足则取剩余
fseek($fp, ($len + $seekSize) * -1, SEEK_END);//移动文件指针,在文件尾处,把尾当成头
$readData = fread($fp, $seekSize) . $readData;//读取一块,返回一块的字符串
}
return $readData;
}
public function closeFile($replaceStr){//将更改后的字符串写入,关闭
$this -> file_handle = fopen($this -> target_file,"w");//只写打开,清除所有
fwrite($this -> file_handle,$replaceStr);//写入
fclose($this -> file_handle);
}
}
审核
{icon_block}
{add_block}
/*openDB.php
*
*这是数据库的连接方法,我把它写成一个类,方便在各个文件中调用
*/
class DB {
private $db_config = array(
"host"=>'127.0.0.1',
"port"=>3306,
"user"=>"root",
"password" =>"IhasPassword",
"database" => "university",
"table" => "yiban_lateback"
);
public $db;//将数据库对象暴露出来,创建数据库对象之后,会自动赋值给对象。
function __construct(){
$server = $this-> db_config['host'] . ':' . $this -> db_config['port'];
$this -> db = mysqli_connect($server, $this-> db_config['user'], $this-> db_config['password'], $this-> db_config['database']) or die('unabel to connect mysql server:' . mysqli_error($this -> db));
}
}
require("opendb.php");
$userId = $userInfo["info"]["yb_userid"];
$userLocal = */
$userId = $_POST['yiban_id'];
date_default_timezone_set('PRC');//设置为中国时区
$timer = strval(date('Y-m-d H:i:s', time()));
$uname = $_POST['uname'];
$academy = $_POST['academy'];
$className = $_POST['className'];
$phone = strval($_POST['phone']);
$reason =addslashes($_POST['reason']);
$passed = "待审核";
$local_address = $_POST['local_address'];
$backMethod = $_POST["backMethod"];
$reasonMethod = $_POST["reasonMethod"];
$studentId =$_POST["studentId"];
$DB_obj = new DB();
$db = $DB_obj-> db;
mysqli_set_charset($db, "utf8");
if(was_student_fill($uname,$userId,$db)){
setReactPage("glyphicon-ban-circle","不能重复提交","warning");
die;
}else{
$sql = "INSERT INTO yiban_lateback(stu_name, yiban_id,school_code,academy,className, phone, reason, time_log,passed,local_address,back_method,reason_method) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
//按照mysql的语句来写,不过具体数值用?代替,防止sql注入
$stmt = mysqli_prepare($db, $sql);//预编译,防止sql注入
mysqli_stmt_bind_param($stmt, 'ssssssssssss', $uname,$userId,$studentId ,$academy, $className, $phone, $reason, $timer,$passed,$local_address,$backMethod,$reasonMethod);
//为语句绑定变量;
$success = mysqli_stmt_execute($stmt);//执行语句
}
本地PC端测试
本地打开wamp,等图标到绿色,将项目的所有文件放进www目录下,然后在浏览器地址栏中输入http://localhost
,就能查看项目的效果。
移动端测试
在易班官网的开放平台上,点击轻应用页面,在自己要测试的轻应用上点击【调试应用】,接着用手机易班扫码进行测试。也可以在手机易班的【应用广场】自己页面中找到自己开发中的轻应用。
到了这一步,我们需要把自己在本地建好的项目给放在【服务器】端的wamp的www目录下。然后把本地建好的数据库中的数据表导出,在【服务器】端的数据库中导入。这个过程使用wamp自带的phpadmin。
轻应用在正式上线之前需要进行小范围的测试,因为很多时候某些bug在本地测试的时候没有发现,直到上线后运行一段时间才发现。所以需要在正式上线之前在内部进行一下小范围的测试。基本没有问题后,就可以正式上线,然后通过易班工作站进行推广。建议预留投诉页面。
通过对易班轻应用是什么,怎么开发进行梳理,我们知道了轻应用怎么开发从上线。整个易班轻应用的开发过程就是这样。各位开发的小伙伴有问题可以留言,不过在留言之前先百度一下。
v1.0