CMS 实现过程(重点)
一. 程序结构介绍
1. 目录结构介绍
— cms 程序根目录
-- cms.sql 数据库导出文件,可通过导入建立系统数据库
-- controller.php 服务端接口处理程序
-- js js相关文件(jQuery)
-- css css 样式相关文件
-- res 程序中的图片资源文件
-- KindEditor 富文本编辑器
-- home 前台页面文件
-- admin 后台页面文件
2. 前后端交互过程
- 基本通信过程示意图
- 页面加载过程示意图
- 实现过程示意图
2.1 交互过程功能模块划分
- index.html 负责前端页面的展示
- controller.php 负责后端业务的逻辑处理
- Database 负责数据的处理
2.2 交互过程实现步骤
- 步骤一 页面基本布局框架实现与加载
- 步骤二 通过Ajax向服务端发起请求,获取页面需要显示的数据
- 步骤三 服务端接收客户端请求,并根据传递的参数进行业务的区分
- 步骤四 在接口函数中通过PDO向数据库发起查询,并将查询结果返回
- 步骤五 Ajax成功回调函数中接收服务端返回的数据,并将数据展示到页面中
2.3 按步骤实现过程
步骤一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
p{
width: 800px;
height: 50px;
margin: 0 auto;
margin-top: 100px;
line-height: 50px;
text-align: center;
font-weight: bold;
font-size: 20px;
}
div{
width: 800px;
height: 50px;
background: red;
margin: 0 auto;
line-height: 50px;
text-align: center;
}
ul{
list-style: none;
display: flex;
justify-content: space-between;
padding: 0;
}
</style>
</head>
<body>
<p>静态页面</p>
<div id="staticNav">
<ul>
<li><a href="list.html?id=1">创业资讯</a></li>
<li><a href="list.html?id=3">创业指导</a></li>
<li><a href="list.html?id=2">创业故事</a></li>
<li><a href="list.html?id=5">创业点子</a></li>
<li><a href="list.html?id=4">职场江湖</a></li>
<li><a href="list.html?id=6">求职攻略</a></li>
<li><a href="list.html?id=7">故事语录</a></li>
<li><a href="about.html">关于我们</a></li>
</ul>
</div>
<p>动态加载数据</p>
<div id="Nav">
</div>
</body>
</html>
步骤二
<script src="../cms/js/jquery-1.11.3.js"></script>
<script>
$(function(){
$.get('controller.php',{"a":"getNavData"},function(data){
},'json');
});
</script>
步骤三
```php <?php header(“content-type:text/html;charset=utf-8”);// 获取请求参数,进行业务判断 $act = $_GET[‘a’]; if($act == “getNavData”){
// 调用对应的业务处理函数
getNavData();
}
?>
- 步骤四
```php
<?php
// 数据库封装函数
function queryAll($sql){
$url = "mysql:host=localhost;dbname=cms";
$user = "root";
$pwd = "";
$conn = new PDO($url,$user,$pwd);
$st = $conn->query($sql);
$rs = $st->fetchAll(PDO::FETCH_ASSOC);
return $rs;
}
// 业务处理函数
function getNavData(){
$class = queryAll("select id,name from class where type=0 order by sort");
echo json_encode($class);
}
?>
步骤五
// Ajax 成功回调函数
$.get('controller.php',{"a":"getNavData"},function (data){
// 用于拼接内容的字符串
var html = "<ul>";
for(var i=0;i<data.length;i++){
var o = data[i];
html += "<li><a href='list.html?id=" + o.id + "'>" + o.name +"</a></li>";
}
html += "<li><a href='about.html'>关于我们</a></li>";
html += "</ul>";
// 将拼接内容设置到页面中
$("#Nav").html(html);
},"json");
3. Controller.php 服务端Ajax请求处理程序
<?php
header("content-type:text/html;charset=utf-8");
session_start();
/**
* Ajax的处理类
*/
//########【页面Ajax逻辑处理】########################################
$module = $_GET["m"]; //访问的模块:前台home、后台admin
$act = ""; //操作
if($module == "home"){
//前台
$act = $_GET["a"];
}
elseif ($module == "admin"){
// 后台
$act = $_GET["a"];
}
//########【前台接口函数封装函数】########################################
//########【后台接口函数封装函数】########################################################################
//########【MySQL封装函数】###############################################
// 查询多条记录, 返回结果的二维数组
function queryAll($sql){
$url = "mysql:host=localhost;dbname=cms";
$user = "root";
$pwd = "";
$conn = new PDO($url,$user,$pwd);
$st = $conn->query($sql);
$rs = $st->fetchAll(PDO::FETCH_ASSOC);
return $rs;
}
// 查询单条记录,返回结果的一维数组
function queryOne($sql){
$url = "mysql:host=localhost;dbname=cms";
$user = "root";
$pwd = "";
$conn = new PDO($url,$user,$pwd);
$st = $conn->query($sql);
$rs = $st->fetch(PDO::FETCH_ASSOC);
return $rs;
}
// 执行增删改,返回影响结果
function execute($sql){
$url = "mysql:host=localhost;dbname=cms";
$user = "root";
$pwd = "";
$conn = new PDO($url,$user,$pwd);
$row = $conn->exec($sql);
return $row;
}
二. 前台页面实现
1. index.html
index页面功能模块
1.1 获取展示分类标题
- 请求目标: 前台
m=home
- 请求动作:
a=getClass
controller.php
if($act == "getClass"){
getClass();
}
// 获取分类函数
function getClass(){
//获得所有分类
$class = queryAll("select id,name from class where type=0 order by sort");
echo json_encode($class);
}
页面中getClass函数
//获得所有分类
function getClass(){
// 发起请求,获取分类数据
$.get("../controller.php?m=home&a=getClass",function(data){
// 拼接 页头和页脚的内容
var p1 = "<ul>";
// 页头的导航条需要,页脚不需要
var p2 = "<li><a href='index.html'>首页</a></li>";
// 中间分类内容
var p3 = "";
// 遍历请求返回的数据
for(var i=0;i<data.length;i++){
// 拿到数据
var o = data[i];
//使用字符串形式拼接页面内容,点击跳转后传入分类的id,方便对应页面获取该类的数据
p3 += "<li><a href='list.html?id=" + o.id + "'>" + o.name +"</a></li>";
}
p3 += "<li><a href='about.html'>关于我们</a></li>";
p3 += "</ul>";
// 页头包含首页
var s1 = p1 + p2 + p3;
// 页脚不包含首页
var s2 = p1 + p3;
// 分别设置页头和页脚
// 通过标签名 header 找到页面位置,并将内容显示到页面中
$("header").html(s1);
// 通过ID名 footer 找到页面位置,并将内容显示到页面中
$("#footer").html(s2);
},"json");
}
1.2 获取展示分类数据(重点)
- 请求目标: 前台
m=home
- 请求动作:
a=getClassData
controller.php
// 路由判断
...
else if($act == "getClassData"){
getClassData();
}
...
// 获取分类数据函数
function getClassData(){
// 返回数据格式
/**
* [[name: 标题 , items:[item1, item2,... ], ...]
*/
$data = [];
// 先获取分类标题
$class = queryAll("select id, name from class where type=0 order by sort");
// 遍历标题,获取每个标题对应的数据
foreach($class as $obj){
//获得所有分类中按时间排序后的前5条数据
$items= queryAll("select id, title, images, click from content where classId={$obj['id']} order by date desc limit 5");
// 创建一个关系数组,使用分类名做为key, 使用分类对应数据做为 Value
$tmp = ["name"=>$obj['name'], "items"=>$items];
// 添加到数组中
$data[] = $tmp;
}
// 最后返回的是一个索引数组,对应的每个元素是每一个分类的关系数组
echo json_encode($data);
}
页面中getClassData函数
//获得所有分类数据
function getClassData(){
$.get("../controller.php?m=home&a=getClassData",function(data){
// 调用页面内容设置函数来设置内容
setContent( data );
},"json");
}
// 设置页面内容
function setContent(data){
// 每一个分类,都被单独的放到一个section标签中
// 该标签中包含分类标题和分类内容两部分
for(var i=0;i<data.length;i++){
var html = "";
// 获取单个分类
var item = data[i];
// 设置分类标题
html += '<div class="title">';
html += '<img src="../res/icon_text3.png" />' + item.name;
html += '</div>';
// 追加到页面中
$("#s"+i).append(html);
// 获取内容数组
var items = item.items;
// 拼接行内分页内容item
var row = "";
row += '<div class="row">';
for(var j=0;j<items.length;j++){
var o = items[j];
row += '<div>';
row += '<img src="' + o.images + '"/>';
row += '<div class="t">' + o.title + '</div>';
row += '<div class="msg">';
row += '<div>' + item.name + '</div>';
row += '<div>人气:'+ o.click + '</div>';
row += '</div>';
row += '</div>';
}
row += '</div>';
$("#s"+i).append(row);
}
}
1.3 获取展示排序数据
- 请求目标: 前台
m=home
- 请求动作:
a=getRank
controller.php
// 路由判断
...
else if($act == 'getRank'){
getRank();
}
...
// 获取推荐排行函数
function getRank(){
// 查询排行数据
$rank = queryAll('select id, title from content order by homePageWeight desc limit 10;');
// 服务端返回数据的另一种形式,直接返回拼接好的页面中要显示的内容
$html = '';
foreach($rank as $v){
// 通过查询结果拼接 html 代码,将文章 ID 做为参数放到地址中,在跳转内容页面时,
// 可以通过ID获取该页面的内容
$html .= "<li><span>.</span> <a href='content.html?id={$v['id']}'>{$v['title']}</a></li>";
}
echo $html;
}
页面中getRank函数
// 获取新闻排行
function getRank(){
$.get("../controller.php?m=home&a=getRank",function(data){
// 因为请求返回的数据就是页面的HTML代码,所以直接添加到页面中
$("#rank").html(data);
});
}
1.4 获取展示ICP备案信息
- 请求目标: 前台
m=home
- 请求动作:
a=getIcp
controller.php
// 路由判断
else if($act == "getIcp"){
getIcp();
}
// 获取备案信息的内容
function getIcp(){
$icp = queryAll('select IcpId from website;');
echo json_encode($icp);
}
页面中的getICP函数
// 获取备案号
function getIcp(){
$.get("../controller.php",{'m':"home",'a':"getIcp"},function (data){
$('#icp').html(data[0].IcpId);
},"json");
}
1.5 获取展示轮播图数据(重点)
- 请求目标: 前台
m=home
- 请求动作:
a=getIcp
controller.php
// 路由判断
else if($act == "getLbt"){
getLbt();
}
// 获取轮播图数据
function getLbt(){
$imgs = queryAll('select sort,name,url from rotationchart order by sort;');
echo json_encode($imgs);
}
页面中的getLbt函数及轮播图按钮事件绑定函数
// 获取轮播图数据
function getLbt(){
$.get("../controller.php",{'m':"home",'a':"getLbt"},function (data){
lbtImgs = data;
var obj = lbtImgs[0];
$(".lbt img").attr({"src":obj.url});
$(".lbt>.txt").html(obj.name);
},"json");
}
// 绑定事件方法
function bindEvent(){
$(".leftBtn").click(function(){
lbtIdx--;
if(lbtIdx < 0) lbtIdx = lbtImgs.length-1;
var obj = lbtImgs[lbtIdx];
$(".lbt img").attr({"src":obj.url});
$(".lbt>.txt").html(obj.name);
console.log("left");
});
$(".rightBtn").click(function(){
lbtIdx++;
if(lbtIdx == lbtImgs.length) lbtIdx = 0;
var obj = lbtImgs[lbtIdx];
$(".lbt img").attr({"src":obj.url});
$(".lbt>.txt").html(obj.name);
console.log("right");
});
}
2. list.html
list页面功能模块
2.1 导航,页脚,备案信息可复用index.html内容
- 请求目标: 前台
m=home
- 导航,页脚
- 请求动作:
a=getClass
- 请求动作:
- 备案信息
- 请求动作:
a=getIcp
- 请求动作:
2.2 获取推荐文章
- 请求目标: 前台
m=home
- 请求动作:
a=getListTj
controller.php
// 路由判断
...
else if($act == "getListTj"){
getListTj();
}
...
// 获取推荐文章
function getListTj(){
$tj = queryAll("select id,title,images from content order by classificationWeight desc limit 4;");
echo json_encode($tj);
}
页面中getListTj函数实现
// 获取推荐文章
function getListTj(){
$.get("../controller.php",{"m":"home","a":"getListTj"},function(data){
var html = "";
for(var i=0;i<data.length;i++){
var o = data[i];
html += "<div>";
html += " <div><img src='" + o.images+ "' /></div>";
html += " <div><a href='content.html?id=" + o.id +"'>" + o.title + "</a></div>";
html += "</div>";
}
$("#tj").append(html);
},"json");
}
2.3 获取热门浏览
- 请求目标: 前台
m=home
- 请求动作:
a=getListHot
controller.php
// 路由判断
...
else if($act == "getListHot"){
getListHot();
}
...
// 获取热门浏览
function getListHot(){
$hot = queryAll("select id,title from content order by click desc limit 10;");
echo json_encode($hot);
}
页面中getListHot函数实现
// 获取热门浏览
function getListHot(){
$.get("../controller.php",{"m":"home","a":"getListHot"},function(data){
var html = "";
for(var i=0;i<data.length;i++){
var o = data[i];
html += '<li><span>.</span> <a href="content.html?id='+o.id+'">' +o.title+ '</a></li>';
}
$("#hot").html(html);
},"json");
}
2.4 获取站点分类
- 请求目标: 前台
m=home
- 请求动作:
a=getSiteClass
controller.php
// 路由判断
...
else if($act == "getSiteClass"){
getSiteClass();
}
...
// 获取网站分类
function getSiteClass(){
$sc = queryAll("select id, name from class order by sort;");
echo json_encode($sc);
}
页面中getSiteClass函数实现
// 获取侧边栏网站分类
function getSiteClass(){
$.get("../controller.php?m=home&a=getSiteClass",function(data){
var html = "";
for(var i=0;i<data.length;i++){
var o = data[i];
html += '<li><span>.</span> <a href="list.html?id='+ o.id +'">' + o.name + '</a></li>';
}
$("#siteClass").html(html);
},"json");
}
2.5 获取友情链接
- 请求目标: 前台
m=home
- 请求动作:
a=getLinks
controller.php
// 路由判断
...
else if($act == "getLinks"){
getLinks();
}
...
// 获取友情链接
function getLinks(){
$links = queryAll("select id,name,url from links;");
echo json_encode($links);
}
页面中getLinks函数实现
// 获取友情链接
function getLinks(){
var html = '';
$.get("../controller.php",{"m":"home","a":"getLinks"},function (data){
for(var i=0;i<data.length;i++){
var o = data[i];
html += '<li><span>.</span> <a href="'+ o.url+'">' + o.name + '</a></li>';
}
$("#links").html(html);
},"json");
}
2.6 获取列表页面内容(重点)
- 请求目标: 前台
m=home
- 请求动作:
a=getContent
controller.php
// 路由判断
...
else if($act == "getContent"){
// 获取分类ID和当前页数
$cid = $_GET["cid"];
$page = isset($_GET["page"]) ? $_GET["page"] : 1;
getContent($cid, $page);
}
...
// 获取内容
function getContent($cid, $page){
// 页面显示的记录数
$pageNum = 8;
// 获取分类名
$c = queryOne("select name from class where id = {$cid}");
// 获取总记录数
$allNum = queryAll("select count(*) as num from content where classId = {$cid}")[0]["num"];
// 获取分类的内容
$startPage = ($page-1) * $pageNum;
$contents = queryAll("select id,title,images,date,content from content where classId = {$cid} limit {$startPage}, {$pageNum}");
// 总页数
$allPage = ceil($allNum / $pageNum);
// 页码的配置信息
$pageInfo = ["currentPage"=>$page, "allPage"=> $allPage];
// 组合页面信息
$tmp = ["name"=>$c["name"], "content"=>$contents, "pageInfo"=>$pageInfo];
echo json_encode($tmp);
}
页面中getContent函数实现
// 获取内容
function getContent(){
// 通过请求地址将分类ID取出来
var cid = window.location.href.split("id=")[1];
console.log(cid);
$.get("../controller.php",{"m":"home","a":"getContent","cid":cid},function(data){
// 将返回的数据,做为参数传给 setPageContent函数,来设置页面内容
setPageContent(cid, data);
},"json")
}
// 设置页面内容的函数,用来首次请求和页码响应后,获取数据展示到页面中
function setPageContent(cid, data){
var cn = data.name;
var content = data.content;
// 设置分类标题
$("#className").html(cn);
// 拼接内容
var html = "";
// 添加导航下面的背景图片
html += '<div class="t">';
html += ' <img src="../res/bg2.jpg" />';
html += '</div>';
for(var i=0;i<content.length;i++){
var o = content[i];
// 截取内容中的第一段内容做为简单描述
var desc = o.content.split('</p>')[0];
// 去掉内容p标签上的样式
desc = desc.split('">')[1].trim();
// 处理时间
date = o.date.split(" ")[0];
// 拼接页面内容
html += '<div class="row">';
html += ' <img src="' + o.images +'" />';
html += ' <div>';
html += ' <div> <a href="content.html?id=' + o.id + '">'+ o.title +'</a> </div>';
html += ' <div class="desc">' + desc+ '</div>';
html += ' <div>';
html += ' <img src="../res/icon_time.png" />' + date;
html += ' </div>';
html += ' </div>';
html += '</div> ';
}
// 设置页码内容
var pageInfo = data.pageInfo;
html += "<ul class='page_list'>";
html += " <li onclick=getPageContent("+ cid + "," + 1 +")>首页</li>";
var prePage = pageInfo.currentPage == 1? 1 : pageInfo.currentPage - 1;
html += " <li onclick=getPageContent("+ cid + "," + prePage +")>前一页</li>";
for(var i=1;i<=pageInfo.allPage;i++){
if(i == pageInfo.currentPage)
// 绑定分页获取数据的方法
html += " <li class='num active' onclick=getPageContent("+ cid + "," + i +")>" + i + "</li>";
else
html += " <li class='num' onclick=getPageContent("+ cid + "," + i +")>" + i + "</li>";
}
var nextPage = pageInfo.currentPage == pageInfo.allPage ? pageInfo.allPage : parseInt(pageInfo.currentPage) + 1;
html += " <li onclick=getPageContent("+ cid + "," + nextPage +")>后一页</li>";
html += " <li onclick=getPageContent("+ cid + "," + pageInfo.allPage +")>尾页</li>";
html += "</ul>";
// 先将页面中原来的内容清空
$("#list_content").empty();
// 将新内容添加到页面中
$("#list_content").append(html);
}
2.7 获取分页内容(重点)
- 请求目标: 前台
m=home
- 请求动作:
a=getContent
controller.php
// 路由判断
...
else if($act == "getContent"){
// 获取分类ID和当前页数
$cid = $_GET["cid"];
$page = isset($_GET["page"]) ? $_GET["page"] : 1;
getContent($cid, $page);
}
...
页面中getPageContent函数实现
// 获取分页数据的内容
function getPageContent(cid,page){
$.get("../controller.php",{"m":"home","a":"getContent","cid":cid,"page":page},function(data){
// 将返回的数据,做为参数传给 setPageContent函数,来设置页面内容
setPageContent(cid, data);
},"json")
}
3. content.html
content页面功能模块划分
3.1 导航,页脚,推荐,热门,分类,链接可复用list页面内容
- 请求目标: 前台
m=home
- 导航,页脚
- 请求动作:
a=getClass
- 请求动作:
- 备案信息
- 请求动作:
a=getIcp
- 请求动作:
- 推荐文章
- 请求动作:
a=getListTj
- 请求动作:
- 热门浏览
- 请求动作:
a=getListHot
- 请求动作:
- 网站分类
- 请求动作:
a=getSiteClass
- 请求动作:
- 友情链接
- 请求动作:
a=getLinks
- 请求动作:
3.2 获取用户状态信息
- 请求目标: 前台
m=home
- 请求动作:
a=getUserStatus
controller.php
// 路由判断
...
else if($act == "getUserStatus"){
getUserStatus();
}
...
// 返回用户状态,如果登陆返回用户名,未登陆返回空字符串
function getUserStatus(){
$userStatus = [];
$userStatus["uid"] = isset($_SESSION["uid"]) ? $_SESSION["uid"] : "0";
$userStatus["user"] = isset($_SESSION["user"]) ? $_SESSION["user"] : "匿名用户";
echo json_encode($userStatus);
}
页面中getUserStatus函数
// 获取用户状态
function getUserStatus(){
$.get("../controller.php",{"m":"home","a": "getUserStatus"}, function (data){
// 将当前用户的用户添加到评论前的名称上
$(".pinglun .plbox .pluser").html(data.user);
userStatus = data;
console.log(userStatus);
},"json");
}
3.3 获取文章内容(重点)
- 请求目标: 前台
m=home
- 请求动作:
a=getNewsContent
controller.php
// 路由判断
...
else if($act == "getNewsContent"){
getNewsContent();
}
...
// 返回文章内容,及上一条下一条数据
function getNewsContent(){
$id1 = $_GET["cid"];
$id0 = $id1-1;
$id2 = $id1+1;
$content = queryAll("select id, title,content, date, userId, click, supportNum, classId from content where id in({$id0}, {$id1} ,{$id2});");
// 判断返回记录是否是三条(上一条,当前条,下一条)
if(count($content) < 3){
// 如果第一条是当前条,说明没有上一条数据
if($content[0]["id"] == $id1){
// 在第一个位置,添加"没有了"
array_unshift($content, ["id"=>0, "title"=>"没有了"]);
}else{
array_push($content, ["id"=>0, "title"=>"没有了"]);
}
}
// 通过结果中的userId查发布者,将发布者保存到数据中
$user = queryOne("select userName from user where id = {$content[1]['userId']}");
$content[1]["userId"] = $user;
// 通过查询结果中的classId,将该文章所属的分类名取出
$className = queryOne("select name from class where id = {$content[1]["classId"]}");
$content[1]["classId"] = $className["name"];
// 获取Uid,cid, 判断当前用户是否点赞
$uid = isset($_SESSION["uid"]) ? $_SESSION["uid"] : "0";
$isSupport = queryOne("select issupport from support where contentId = {$id1} and userId = {$uid}");
// 如果该用户在该文章没有点赞记录,或者点赞状态为0
if($isSupport == false || $isSupport["issupport"] == "0"){
// 没点赞
$content[1]["isSupport"] = 0;
}else{
// 点赞了
$content[1]["isSupport"] = 1;
}
// 将数据返回
echo json_encode($content);
}
页面中getNewsContent函数
// 获取内容
function getNewsContent(){
$.get("../controller.php",{"m":"home","a":"getNewsContent", "cid":cid},function(data){
console.log(data);
// 设置分类标题
cn = data[1].classId;
$("#className").html(cn);
// 设置文章内容
for(var i=0;i<data.length;i++){
var o = data[i];
if(i == 0){
// 上一篇
$("#pre>a").attr({"href": (o.id !=0? "content.html?id=" +o.id:"javascript:;") });
$("#pre>a>span").html(o.title);
}else if(i == 1){
// 当前文章
// 标题
$(".detail .ctitle .row1").html(o.title);
// 赞数
if(o.isSupport != "0")
$(".zan img").attr({"src":"../res/newHeart2021Active.png"});
else
$(".zan img").attr({"src":"../res/newHeart2021Black.png"});
$(".zan span").html(o.supportNum);
// 发布时间
$(".fdate").html(o.date);
// 作者
$(".author").html(o.userId.userName);
// 围观
$(".look").html(o.click);
// 内容
$(".content_text").html(o.content);
}else{
// 下一篇
$("#next>a").attr({"href": (o.id !=0? "content.html?id=" +o.id:"javascript:;") });
$("#next>a>span").html(o.title);
}
}
},"json")
}
3.4 点赞事件逻辑(重点)
- 请求目标: 前台
m=home
- 请求动作:
a=clickZan
controller.php
// 路由判断
...
else if($act == "clickZan"){
clickZan();
}
...
// 点赞请求
function clickZan(){
$cid = $_GET["cid"];
$uid = $_GET["uid"];
// var_dump($cid);
// var_dump($uid);
$isSupport = queryOne("select issupport from support where contentId = {$cid} and userId = {$uid}");
// var_dump($isSupport);
// var_dump("-----");
// 点赞状态取反
if($isSupport == false){
// 没有点赞的情况,插入新点赞记录
$isSup = "1";
// 改变点赞表中,文章/用户/是否点赞状态
execute("insert into support (contentId,userId,issupport) values({$cid},{$uid},{$isSup})");
// 改变文章的总赞数
execute("UPDATE content set supportNum = supportNum + 1 where id = {$cid};");
}else{
// 如果有点赞记录,取反
$isSup = $isSupport["issupport"] == "1" ? "0" : "1";
// 改变点赞表中,文章/用户/是否点赞状态
execute("update support set issupport = {$isSup} where contentId = {$cid} and userId = {$uid}");
// 改变文章的总赞数
if($isSup == "0"){
execute("UPDATE content set supportNum = supportNum - 1 where id = {$cid};");
}else{
execute("UPDATE content set supportNum = supportNum + 1 where id = {$cid};");
}
}
echo json_encode(["isSupport"=> $isSup]);
}
页面中clickZan函数
// 点赞事件
function clickZan(){
if(userStatus.uid == "0"){
window.location = 'login.html';
}else{
$.get("../controller.php",{"m":"home", "a":"clickZan", "cid":cid, "uid":userStatus.uid},function (data){
var num = parseInt($(".zan span").html());
console.log(num);
console.log(data);
if(data.isSupport == "1")
{
alert("YesZan");
$(".zan img").attr({"src":"../res/newHeart2021Active.png"});
$(".zan span").html(num + 1);
}
else
{
alert("NoZan");
$(".zan img").attr({"src":"../res/newHeart2021Black.png"});
$(".zan span").html(num - 1);
}
},"json");
}
}
3.5 获取用户评论
- 请求目标: 前台
m=home
- 请求动作:
a=getUserStatus
controller.php
// 路由判断
...
else if($act == "getComments"){
getComments();
}
...
// 获取评论
function getComments(){
$cid = $_GET["cid"];
$comments = queryAll("select id, userId, content, time from comments where contentId = {$cid} order by time desc");
// 将评论者Id 修改为评论者姓名
foreach($comments as &$item){
$item['user'] = queryOne("select loginName as name from user where id = {$item['userId']}")["name"];
// 处理时间
$item["time"] = date("Y-m-d H:i:s", $item['time']);
// 添加 当前用户的id
$item["currentUserId"] = isset($_SESSION["id"])?$_SESSION["id"]:0;
}
echo json_encode($comments);
}
页面中getComments函数
// 获取用户评论
function getComments(){
$.get("../controller.php", {"m":"home","a": "getComments","cid":cid}, function (data){
// 清空原有内容
$(".plcontent").empty();
// 拼接评论内容
var html = '';
for(var i=0;i<data.length;i++){
var o = data[i];
html += '<div class="msgItem">';
html += ' <div class="msguser"><span class="user">' + o.user + '</span>';
if(o.currentUserId == o.userId){
html += '<span class="msgdel"></span></div>';
}else{
html += '</div>';
}
html += ' <div class="msg">' + o.content + '</div>';
html += ' <div class="msgtime">' + o.time + '</div>';
html += '</div>';
}
console.log(html);
$('.plcontent').html(html);
},"json");
}
3.6 发表用户评论
- 请求目标: 前台
m=home
- 请求动作:
a=getUserStatus
controller.php
// 路由判断
...
else if($act == "addComments"){
addComments();
}
...
// 添加评论
function addComments(){
$cid = $_GET["cid"];
$uid = $_GET["uid"];
$comm = $_GET["comm"];
$time = 1642342314;
// $time = $_GET["time"];
var_dump($cid);
var_dump($uid);
var_dump($comm);
var_dump($time);
$sql = "insert into comments(contentId, userId, content, time) values({$cid},{$uid},'{$comm}',{$time})";
var_dump($sql);
$ret = execute($sql);
var_dump($ret);
echo $ret;
}
页面中addComments函数
function addComments(){
if(userStatus.uid == "0"){
window.location = 'login.html';
}else{
// 获取评论
var comm = $(".plin").val();
// 获取当前时间
var timestamp = new Date().getTime()
$.get("../controller.php",{"m":"home", "a":"addComments","cid":cid, "uid":userStatus.uid,"comm":comm, "time":timestamp},function (data){
var comm = $(".plin").val("");
// 重新获取评论
getComments();
});
}
}
4. login.html
- 请求目标: 前台
m=home
- 请求动作:
a=login
controller.php
// 开启Session会话
session_start();
// 路由判断
...
else if($act == "login"){
login();
}
...
// 登陆函数
function login(){
$user = $_GET["user"];
$pwd = $_GET["pwd"];
$login = queryOne("select id from user where loginName='{$user}' and password='{$pwd}'");
if($login != false){
// 保存session信息
$_SESSION['uid'] = $login["id"];
$_SESSION['user'] = $user;
$_SESSION['pwd'] = $pwd;
echo 1;
}else{
echo 0;
}
}
login页面中登陆按钮事件
<script>
$(function(){
$("#btn").click(function(){
var user = $("#user").val();
var pwd = $("#pwd").val();
if( user == ""){
alert("用户名不能为空!");
$("#user").focus();
return;
}
if(pwd == ""){
alert("密码不能为空!");
$("#pwd").focus();
return;
}
$.get('../controller.php',{"m":"home","a":"login","user":user,"pwd":pwd},function(data){
if(data == 1){
window.location = "index.html?user=" + user;
}else{
alert("用户名或密码错误");
}
},"html");
});
});
</script>
三. 后台页面实现
1. loginback.html
- 请求目标: 前台
m=home
- 请求动作:
a=login
controller.php
// 开启Session会话
session_start();
// 路由判断
...
elseif ($module == "admin"){
$act = $_GET["a"];
//后台
if($act == "login"){
backLogin();
}
...
// 后台登陆函数
function backLogin(){
$user = $_GET["user"];
$pwd = $_GET["pwd"];
$login = queryOne("select id from user where usertypeId = 1 and loginName='{$user}' and password='{$pwd}'");
if($login != false){
$_SESSION['buid'] = $login["id"];
$_SESSION['buser'] = $user;
$_SESSION['bpwd'] = $pwd;
echo 1;
}else{
echo 0;
}
}
loginback页面中登陆按钮事件
<script>
$(function(){
$("#btn").click(function(){
var user = $("#user").val();
var pwd = $("#pwd").val();
if( user == ""){
alert("用户名不能为空!");
$("#user").focus();
return;
}
if(pwd == ""){
alert("密码不能为空!");
$("#pwd").focus();
return;
}
$.get('../controller.php',{"m":"admin","a":"login","user":user,"pwd":pwd},function(data){
if(data == 1){
window.location = "websiteback.html?user=" + user;
}else{
alert("用户名或密码错误");
}
},"html");
});
});
</script>
2. websiteback.html
websiteback页面功能模块划分
2.1 回显数据
- 请求目标: 后台
m=admin
- 请求动作:
a=getWebSite
controller.php
// 路由判断
...
else if($act == "getWebSite"){
getWebSite();
}
...
// webSite 表格中回显的数据
function getWebSite(){
$web = queryOne("select id, name, logo, Icpid from website;");
echo json_encode($web);
}
页面中getWebSite请求回调函数
<script src="../js/jquery-1.11.3.js"></script>
<script>
// 用来保存选中logo图片的索引
var logoIdx = 1;
// 用来保存选中的logo地址
var selectLogo = "";
// 入口函数
$(function(){
// 回显数据
$.get("../controller.php",{"m":"admin","a":"getWebSite"},function(data){
$("[name=webname]").val(data.name);
$("[name=icp]").val(data.Icpid);
// 获取图片编号
var logo = data.logo.split(".png")[0];
logoIdx = logo.substr(-1);
logoIdx = ".webrow2 img:nth-child("+ logoIdx+")";
$(logoIdx).addClass("logoSelect");
},"json");
});
</script>
2.2 logo图片添加响应事件
该功能没有发起网络请求,是在回显数据之后,点击图片时,给相应图片添加样式,并记录该图片地址.
// 入口函数
...
// 给logo 图片添加响应事件
console.log($(".webrow2 img"));
$(".webrow2 img").click(function(event){
// 移除选中状态
$(".webrow2 img").removeClass('logoSelect');
// 添加选中状态
$(this).addClass("logoSelect");
// 获取logo地址
selectLogo = $(this).attr("src");
});
...
2.3 保存按钮响应事件
- 请求目标: 后台
m=admin
- 请求动作:
a=updateWebSite
controller.php
// 路由判断
...
else if($act == "updateWebSite"){
updateWebSite();
}
...
// 更新webSite数据
function updateWebSite(){
$name = $_GET["name"];
$logo = $_GET["logo"];
$icp = $_GET["icp"];
$ret = execute("update website set name='{$name}', logo='{$logo}', Icpid='{$icp}' where id = 1");
// var_dump($ret);
echo $ret;
}
页面中保存按钮绑定响应函数
// 入口函数
...
// 保存按钮绑定事件
$("#webBtn").click(function(){
// 获取修改后的值,提交保存
var webName = $("[name=webname]").val();
var icp = $("[name=icp]").val();
$.get("../controller.php",{"m":"admin","a":"updateWebSite","name":webName,"logo":selectLogo,"icp":icp},function(data){
if(data == 1){
alert("修改成功" + data);
}else{
alert("修改失败" + data);
}
console.log(data);
})
});
...
2.4 退出按钮响应事件
- 请求目标: 后台
m=admin
- 请求动作:
a=logout
controller.php
// 路由判断
...
else if($act == "logout"){
session_destroy();
}
...
页面中退出按钮绑定回调函数
// 退出按钮绑定事件
$("#out").click(function(){
// confirm 会弹出一个带取消按钮的弹框,确定返回true,取消返回 false,
// 根据 confrim 的返回值进行不同的操作
var cof=window.confirm("确认退出吗?");
if(cof==true)
{
$.get("../controller.php",{"m":"admin","a":"logout"},function(data){
window.location = 'loginback.html';
});
// 下面的返回值可以不写,也可以添加后给其它功能使用,这里没用
return true; //确认
}
else
return false; //取消
});
3. rotationchartback.html
rotationchartback页面功能模块划分
3.1 退出按钮事件复用和模态框准备工作
复用退出功能 ,定义模态框相关变量
<script>
// 用来保存选中logo图片的索引
var imgIdx = 1;
// 用来保存选中的logo地址
var selectImg = "";
// 用来记录当前页码,删除数据后刷新使用
var cpn = 1;
// 用来保存添加或修改状态的变量
var status = "";
// 用来保存修改数据的id
var changeId = '';
// 入口函数
$(function(){
// 退出按钮响应事件
$("#out").click(function(){
$.get("../controller.php",{"m":"admin","a":"logout"},function(data){
window.location = 'loginback.html';
});
});
// 让模态框隐藏
$(".model").hide();
// 给模态框关闭按钮添加事件
$(".close").click(function(){
$(".model").hide();
});
// 给模态框中的图片添加响应事件
$(".webrow2 img").click(function(event){
// 移除选中状态
$(".webrow2 img").removeClass('logoSelect');
// 添加选中状态
$(this).addClass("logoSelect");
// 获取logo地址
selectImg = $(this).attr("src");
});
});
<script>
3.2 获取轮播图数据
- 请求目标: 后台
m=admin
- 请求动作:
a=getLbtData
controller.php
// 路由判断
...
else if($act == "getLbtData"){
getLbtData();
}
...
// 获取后台轮播图数据
function getLbtData(){
// 当前页总条数
$pageNum = 8;
// 获取当前页码
$currentPage = $_GET["currentPage"];
// 分页信息
$allData = queryOne("select count(*) as allNum from rotationchart;");
$allPage = ceil($allData["allNum"]/$pageNum);
// 在删除最后一页中最后一条记录时,应该返回到上一页
$currentPage = $currentPage > $allPage ? $allPage : $currentPage;
// sql 中用的当前页码
$cp = ($currentPage - 1)*$pageNum;
// 数据
$data = queryAll("select id,sort,name,url from rotationchart limit {$cp}, {$pageNum};");
// 组合页面数据和分页数据
$page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
$tmp = ["content"=>$data, "page"=>$page];
echo json_encode($tmp);
}
页面中getLbtData函数
// 入口函数
...
getLbtData();
...
// 获取轮播图数据, 同时获取分页数据的内容
function getLbtData(currentPage){
$.get("../controller.php",{"m":"admin","a":"getLbtData","currentPage":currentPage},function(data){
// 记录当前的页码
cpn = currentPage;
// 设置页面内容的方法
setContent(data.content);
// 设置页码内容
setPageInfo(data.page);
},"json");
}
//
// 设置页面内容的方法
function setContent(data){
var html = "<tr class='tableTitle'><td>名称</td><td>图片</td><td>图片排序</td><td>操作</td></tr>";
for(var i=0;i<data.length;i++){
var o = data[i];
html += '<tr>';
html += ' <td>'+ o.name +'</td>';
html += ' <td><img src="'+ o.url +'" alt="" ></td>';
html += ' <td>'+ o.sort +'</td>';
html += ' <td><button onclick="changeItem(' + o.id +')">修改</button> <button onclick="delItem(' + o.id +')">删除</button></td>';
html += '</tr> ';
}
console.log(html);
$("#lbt table").html(html);
}
// 设置分页内容的方法
function setPageInfo(pageInfo){
html = "";
html += "<ul class='page_list'>";
html += " <li onclick=getLbtData("+ 1 +")>首页</li>";
var prePage = pageInfo.currentPage == 1? 1 : pageInfo.currentPage - 1;
html += " <li onclick=getLbtData("+ prePage +")>前一页</li>";
for(var i=1;i<=pageInfo.allPage;i++){
if(i == pageInfo.currentPage)
// 绑定分页获取数据的方法
html += " <li class='num active' onclick=getLbtData("+ i +")>" + i + "</li>";
else
html += " <li class='num' onclick=getLbtData("+ i +")>" + i + "</li>";
}
var nextPage = pageInfo.currentPage == pageInfo.allPage ? pageInfo.allPage : parseInt(pageInfo.currentPage) + 1;
html += " <li onclick=getLbtData("+ nextPage +")>后一页</li>";
html += " <li onclick=getLbtData("+ pageInfo.allPage +")>尾页</li>";
html += "</ul>";
// 将新内容添加到页面中
$("#lbtPage").html(html);
}
3.3 删除记录功能
- 请求目标: 后台
m=admin
- 请求动作:
a=delLbtItem
controller.php
// 路由判断
...
else if($act == "delLbtItem"){
delLbtItem();
}
...
// 删除轮播图数据
function delLbtItem(){
$id = $_GET["id"];
$res = execute("delete from rotationchart where id = {$id}");
echo $res;
}
页面中delLbtItem函数
// 删除方法
function delItem(id){
$.get("../controller.php", {"m":"admin","a":"delLbtItem","id":id},function(data){
getLbtData(cpn);
})
}
3.4 添加按钮弹出模态框功能(重点)
- 页面中添加按钮响应事件函数
// 入口函数
...
// 给添加按钮绑定事件,显示模态框
$("#lbtAddBtn").click(function(){
$(".modelTitle").html("添加图片");
$(".model").show();
status = "add";
// 因为和修改是共用一个model框,所以如果使用添加功能 ,那么先清除一下前面的痕迹
$(".webrow2 img").removeClass('logoSelect');
$("[name=webname]").val("");
$("[name=icp]").val("");
});
...
3.5 修改按钮弹出模态框功能 (重点)
- 请求目标: 后台
m=admin
- 请求动作:
a=getLbtChangeItem
controller.php
// 路由判断
...
else if($act == "getLbtChangeItem"){
getLbtChangeItem();
}
...
// 获取轮播图修改时的回显数据
function getLbtChangeItem(){
$id = $_GET["id"];
$data = queryOne("select id,name,url,sort from rotationchart where id ={$id}");
echo json_encode($data);
}
页面中changeItem函数
// 修改方法
function changeItem(id){
$(".modelTitle").html("修改图片");
$(".model").show();
status = "change";
// 保存id,在提交时使用
changeId = id;
$.get("../controller.php",{"m":"admin","a":"getLbtChangeItem","id":id},function(data){
// 回显数据
$("[name=webname]").val(data.name);
$("[name=icp]").val(data.sort);
// 获取图片编号
var logo = data.url.split(".jpg")[0];
imgIdx = logo.substr(-1);
imgIdx = ".webrow2 img:nth-child("+ imgIdx +")";
// 因为可能修改多个数据, 先将上一次的选中状态清除
$(".webrow2 img").removeClass('logoSelect');
// 给当前数据图片添加选中状态
$(imgIdx).addClass("logoSelect");
},"json");
}
3.6 模态框提交按钮响应事件方法(重点)
因为添加和修改是共用一个模态框 ,所以在提交时,要区别功能的不同,分开提交
- 请求目标: 后台
m=admin
- 请求动作:
a=lbtAddItemData
- 请求动作:
a=lbtChangeItemData
controller.php
// 路由判断
...
else if($act == "lbtAddItemData"){
lbtAddItemData();
}else if($act == "lbtChangeItemData"){
lbtChangeItemData();
}
...
// 添加轮播图
function lbtAddItemData(){
$name = $_GET['name'];
$url = $_GET['url'];
$sort = $_GET['sort'];
$res = execute("insert into rotationchart(name,url,sort) values('{$name}','{$url}',{$sort})");
echo $res;
}
// 修改轮播图
function lbtChangeItemData(){
$id = $_GET['id'];
$name = $_GET['name'];
$url = $_GET['url'];
$sort = $_GET['sort'];
$res = execute("update rotationchart set name='{$name}', url='{$url}', sort = {$sort} where id={$id}");
echo $res;
}
- 页面中modelSubmit提交按钮响应函数
// 模态框提交按钮响应方法,该方法已在模板中与按钮绑定完成
function modelSubmit(){
// 获取要提交的数据
var name = $("[name=webname]").val();
var sort = $("[name=icp]").val();
// 判断状态是什么操作
if(status == 'add'){
$.get("../controller.php",{"m":"admin",'a':"lbtAddItemData","name":name, "sort":sort,"url":selectImg},function(data){
alert(data);
$(".model").hide();
getLbtData(cpn);
});
}else if(status == "change"){
$.get("../controller.php",{"m":"admin",'a':"lbtChangeItemData","id":changeId, "name":name, "sort":sort,"url":selectImg},function(data){
alert(data);
$(".model").hide();
getLbtData(cpn);
});
}
}
四. 其它三个页面的显示数据
- 请求目标: 后台
m=admin
- 请求动作:
a=getClassManagerData
- 请求动作:
a=getContentManagerData
- 请求动作:
a=getUserManagerData
controller.php
// 路由判断
...
else if($act == "getClassManagerData"){
getClassManagerData();
}else if($act == "getContentManagerData"){
getContentManagerData();
}else if($act == "getUserManagerData"){
getUserManagerData();
}
...
// ///////////////////////////////////////// classBack.html //////////////////////////////////////////////
function getClassManagerData(){
$data = queryAll("select id,name,sort,type from class;");
// 当前页总条数
$pageNum = 8;
// 获取当前页码
$currentPage = $_GET["currentPage"];
// 分页信息
$allData = queryOne("select count(*) as allNum from class;");
$allPage = ceil($allData["allNum"]/$pageNum);
$page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
$tmp = ['content'=>$data, "page"=>$page];
echo json_encode($tmp);
}
// ///////////////////////////////////////// contentBack.html /////////////////////////////////////////////
function getContentManagerData(){
$data = queryAll("select id,title,classId,userId,date,click from content;");
foreach($data as &$item){
$item['classId'] = queryOne("select name from class where id = {$item['classId']}")['name'];
$item['userId'] = queryOne("select userName from user where id = {$item['userId']}")['userName'];
}
// 当前页总条数
$pageNum = 8;
// 获取当前页码
$currentPage = $_GET["currentPage"];
// 分页信息
$allData = queryOne("select count(*) as allNum from content;");
$allPage = ceil($allData["allNum"]/$pageNum);
$page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
$tmp = ['content'=>$data, "page"=>$page];
echo json_encode($tmp);
}
// ///////////////////////////////////////// userback.html ////////////////////////////////////////////////
function getUserManagerData(){
$data = queryAll("select id, userName, loginName, password, usertypeId from user;");
foreach($data as &$item){
$item['usertypeId'] = $item['usertypeId'] == 1?"管理员":"用户";
}
// 当前页总条数
$pageNum = 8;
// 获取当前页码
$currentPage = $_GET["currentPage"];
// 分页信息
$allData = queryOne("select count(*) as allNum from user;");
$allPage = ceil($allData["allNum"]/$pageNum);
$page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
$tmp = ['content'=>$data, "page"=>$page];
echo json_encode($tmp);
}