前后端交互——模拟QQ相册(连表查询判断数据)

为什么要有连表查询:
正常来说QQ相册都是一个用户一个自己的相册,别人看不到我的相册,我也看不到别人的相册,所以用到连表查询通过用户名密码来判断数据,然后渲染数据到页面,否则所有人的相册都在一个地方的话,你上传之后你再去看你就看不到刚才自己上传的图片了,只会看到在你后边上传的人的相册。


代码示例:

  1. 服务器文件
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
const fs = require("fs");
const koaBody = require("koa-body");
const mysql2 = require("mysql2");

let uName = "";

const connection = mysql2.createConnection({
    host: "localhost",
    user: "root",
    password: "123321",
    database: "js01",
    charset: "utf8"
});

let app = new Koa();
let router = new Router();

app.use(static(__dirname+"/static"));
app.use(koaBody({
    multipart:true
}))

router.get("/",ctx=>{
    ctx.body = "你好"
});
router.post("/checkUser",async ctx=>{
    // 获取到数据库数据,以完成后续的验证
    let sql = "SELECT * FROM qq_username";
    let [rows] = await connection.promise().query(sql);
    let qqUserName = rows;

    // 验证用户名和密码
    qqUserName.forEach(el => {
        if(el.username == ctx.request.body.username && el.password == ctx.request.body.pwd){
            uName = el.username;
            ctx.redirect("/photo.html");
        }
    });
    
    ctx.body = "密码错误";
});
router.get("/photo",async ctx=>{
    // 获取数据
    let imgArr = [];
    let sql = "SELECT u.username,p.imgurl,p.text FROM qq_username AS u LEFT JOIN qq_photo AS p ON u.username = p.username";
    let [rows] = await connection.promise().query(sql);

    // 连表查询符合用户名的图片
    rows.forEach(el=>{
        // 如果两个表的username相同,就把图片路径和文本添加到imgArr这个数组内
        if(el.username == uName){
            imgArr.push({
                url:el.imgurl,
                text:el.text
            });
        };
    });
    // 返回数据
    ctx.body = {
        user : uName,
        imgArr:imgArr
    };
});
router.post("/upload",async ctx=>{
    // 阅读文件
    let fileData = fs.readFileSync(ctx.request.files.img.path);
    // 图片路径
    let imgurl = "/img_upload/"+ctx.request.files.img.name;
    // 文本
    let text = ctx.request.files.img.name;
    // 用户名
    let username =ctx.request.body.user;

    // 获取数据
    let imgsql = "INSERT INTO qq_photo (username,imgurl,text) VALUES (?,?,?)";
    await connection.promise().query(imgsql,[username,imgurl,text]);

    // 写入文件
    fs.writeFileSync("static/img_upload/"+ctx.request.files.img.name,fileData);

    ctx.body = "hello world"
})

app.use(router.routes());
app.listen(8080);
  1. 静态页面
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="css/photo.css">
</head>

<body>
    <!-- 展示相关 -->
    <div class="container">
        <div class="photoHeader">
            <div class="imgContainer">
                <img class="photoName" src="img/1.jpg" />
            </div>
            <div class="btnContainer">
                <span class="photoTitle">相册名称</span>
                <button class="mybtn">上传照片</button>
            </div>
        </div>

        <div class="photoContainer">
            <div class="photoItem">
                <img src="img/1.jpg" />
                <span>
                    home
                </span>
            </div>
        </div>
    </div>
    <!-- 上传相关 -->
    <div class="masking">
        <div class="addPhotoContainer"></div>
        <div class="addController">
            <h3 class="addTitle">上传照片-普通上传(H5)<span class="close"></span></h3>
            <div class="photoTitles">
                <span class="uploadTo">上传到</span>
                <div class="photoSelect">
                    <img class="showPhoto" src="img/1.jpg" />
                    相册名称
                </div>
            </div>

            <!-- 上传按钮 -->
            <div class="showContainer">
                <div class="uploadContainer">
                    <span class="fileinput-button">
                        <span>上传图片</span>
                        <input class="imgFile" type="file" name="" multiple="multiple" />
                    </span>
                    <span class="hint">
                        按住Ctrl可多选
                    </span>
                </div>
            </div>

            <!-- 显示待上传图片  -->
            <div class="loadContainer">
                <div class="wantUpload">
                    <div class="uploadPhotoItem">
                        <!-- <span class="myProgress">
                            <span class="plan"></span>
                            30%
                        </span>
                        <img src="img/1.jpg" />
                        <span class="pictureName">
                            home
                        </span> -->
                    </div>
                </div>
                <div class="addStyle">
                    <span class="fileinput-add">
                        <span></span>
                        <input class="imgFile-add" type="file" multiple="multiple" />
                    </span>
                </div>
                <!-- 开始上传按钮 -->
                <div class="bottomStyle">
                    <span class="uploadBtn">开始上传</span>
                </div>
            </div>

        </div>
    </div>
</body>
<script>
    // 数据渲染页面
    function quest() {
        // 实例化ajax
        let xhr = new XMLHttpRequest();
        // 提交方式,提交路由,是否异步
        xhr.open("get", "/photo", true);
        // 接收返回值
        xhr.onload = function () {
            // 接收数据,因为数据是对象,但是接受过来是字符串,所以需要转一下格式
            let obj = JSON.parse(xhr.responseText);
            // 渲染数据
            document.querySelector(".photoTitle").innerHTML = obj.user;
            let str = "";
            obj.imgArr.forEach(el => {
                str += `
                        
${el.url}" /> ${el.text}
`
; }); document.querySelector(".photoContainer").innerHTML = str; } // 发送服务器 xhr.send() } quest(); document.querySelector(".close").onclick = function () { document.querySelector(".masking").style.display = "none"; } document.querySelector(".mybtn").onclick = function () { document.querySelector(".masking").style.display = "block"; document.querySelector(".loadContainer").style.display = "none"; document.querySelector(".showContainer").style.display = "block"; } let uploadArr = []; // 获取到图片 document.querySelector(".imgFile").onchange = function () { // 他的值发生改变是触发,也就是图片上传上来时 document.querySelector(".loadContainer").style.display = "block"; document.querySelector(".showContainer").style.display = "none"; // 获取到图片信息 // console.log(this.files); // this.files为类数组,直接用会报错,所以加上... 剩余参数 [...this.files].forEach(file => { let uploadObj = new UploadImg(file); uploadArr.push(uploadObj); uploadObj.createHtml(); }); }; document.querySelector(".imgFile-add").onchange = function () { // 他的值发生改变是触发,也就是图片上传上来时 document.querySelector(".loadContainer").style.display = "block"; document.querySelector(".showContainer").style.display = "none"; // this.files为类数组,直接用会报错,所以加上... 剩余参数 [...this.files].forEach(file => { let uploadObj = new UploadImg(file); uploadArr.push(uploadObj); uploadObj.createHtml(); }); }; class UploadImg { // 类里整个都是原型的东西,要想写给函数,所以需要的话要写在constructor里 constructor(file) { this.file = file; this.ele = null; } createHtml() { // 将文件转换成 base64的格式 let fileReader = new FileReader(); fileReader.readAsDataURL(this.file); let _this = this fileReader.onload = function () { // console.log(fileReader.result); let uploadDiv = document.createElement("div"); uploadDiv.classList.add("uploadPhotoItem"); uploadDiv.innerHTML = ` 0% ${fileReader.result}" /> ${_this.file.name} `; document.querySelector(".wantUpload").appendChild(uploadDiv); _this.ele = uploadDiv; } } uploadFile() { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open("post", "/upload", true); let form = new FormData(); form.append("img", this.file); xhr.onload = function () { console.log(xhr.responseText); }; xhr.upload.onprogress = (evt) => { let percent = Math.round(evt.loaded / evt.total * 100); this.ele.querySelector(".plan").style.width = percent + "%"; this.ele.querySelector(".percentText").innerHTML = percent + "%"; this.ele.querySelector(".myProgress").style.display = "block"; if (evt.loaded >= evt.total) { console.log("上传完成"); resolve(); } } xhr.send(form); }); } } document.querySelector(".uploadBtn").onclick = function () { // uploadArr.forEach(imgfile => { // imgfile.uploadFile(); // }); async function que() { // 依次上传 for (let i = 0; i < uploadArr.length; i++) { await uploadArr[i].uploadFile(); } } que(); } </script> </html>
  1. 数据库截图
    前后端交互——模拟QQ相册(连表查询判断数据)_第1张图片前后端交互——模拟QQ相册(连表查询判断数据)_第2张图片
  2. 文件夹位置
    前后端交互——模拟QQ相册(连表查询判断数据)_第3张图片

你可能感兴趣的:(前端)