商贸树洞app开发


前言

老样子,我的风格,直接上项目做,大家学到这里都是具备了一定的前端知识和编程基础的,本学期的课程我将引导你自己来设计一款属于你自己的独特的手机APP。

但是在此之前,你啥也不会,我先带你做一个简单的应用程序,我把它叫做商贸树洞,树洞的意思就是大家吐露心声的地方,这是一种新型的社区,针对的是现在压力过大,且比较孤独的年轻人群,在大学中非常常见。

其实说简单一点就是一个具备匿名功能的留言板,当然,这种社区如果再加上匹配功能就演变成soul等软件,然后通过付费匹配获取盈利,这个不扯远了,跟着做就完事了,做完再说。

一、创建项目

前端还是选择使用uni-app的框架。

打开HBuilder X,点左上角的文件,新建一个项目,选择uniapp中的默认模板即可,项目名称随便取一个好了。

二、注册页面

1.前端(signup.vue)

<template>
	<view>
		<!-- 图片区域 -->
		<div class="image_section flex_column">
			<image style="width: 100px;height: 100px;" src="../../static/iloli.gif" mode=""></image>
			<h4>Hi~请注册</h4>
		</div>
		<!-- 输入区域 -->
		<div class="input_section flex_column">
			<!-- 用户名及用户名输入框 -->
			<div class="flex_row">
				<p>用户名</p>
				<input type="text" placeholder="请输入用户名"/>
			</div>
			<!-- 密码及密码输入框 -->
			<div class="flex_row">
				<p>密码</p>
				<input type="password" placeholder="请输入密码"/>
			</div>
			<!-- 确认密码及确认密码输入框 -->
			<div class="flex_row">
				<p>确认密码</p>
				<input type="password" placeholder="请输入确认密码"/>
			</div>
		</div>
		<!-- 按钮区域 -->
		<div class="button_section flex_row">
			<button @click="zhuce()" class="blue_button">注册</button>
		</div>
		<!-- 导航区域 -->
		<div class="nav_section">
			<navigator url=""></navigator>
		</div>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			// 注册按钮
			zhuce(){
				// 发送请求
				uni.request({
					// 请求的地址
					url:'http://localhost:7777/1.php',
					// 请求的方法
					method:'GET',
                    // 请求携带的参数
                    data:{
                      username:'张三',
                      password:'123456'
                    },
					// 请求成功后的回调函数
					success: (res) => {
						// 打印后端给我们的回答
						console.log(res)
					}
				})
			}
		}
	}
</script>

<style>
.image_section{
	width: 100vw;
	height: 20vh;
	background-color: antiquewhite;
}
.input_section{
	width: 100vw;
	height: 30vh;
	background-color: cadetblue;
}
.button_section{
	width: 100vw;
	height: 20vh;
	background-color: chartreuse;
}
.nav_section{
	width: 100vw;
	height: 30vh;
	background-color: chocolate;
}
/* 弹性盒子横着排 */
.flex_row{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: row;/*排列方向:横向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: column;/*排列方向:纵向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
input{
	border: 1px solid black;
	margin: 10px;
	padding: 10px;
}
.blue_button{
	background-color: #ecf5ff;
	width: 100px;
	border: 1px solid #409eff;
	color: #409eff;
	font-weight: bold;
}
</style>

2.后端(Signup.php)

后端我用的是php语言来写,相对java的后端会简单不少。

后端其实就是接收来自前端的请求,然后发送到数据库,比如前端发来一个请求,表示想注册,后端就把前端传过来的用户名和密码添加到数据库就行了。

有同学可能会疑惑,前端直接把数据添加到数据库不就行了吗?这样多省事,为什么非得经过后端,但是如果前端都能直接操作数据库的话,你不觉得太危险了吗?因为前端代码会发送给用户的浏览器,也就意味着前端代码对用户是完全可见的,用户甚至可以随意修改前端的代码,这样的做法叫做JS绕过,如果有机会的话,我会设计一些网站安全相关的案例带大家去做,我如果就这样说,什么是JS绕过,不管讲得再精彩,你肯定也理解不了,还得得通过实际的案例来说明。

总之就是后端代码存在于服务器上,对用户是不可见的,前端可以很轻易的绕过,后端要攻破就不是那么容易了,我们先写好基础的逻辑,之后讨论安全相关的内容。

准备工作:

  1. 打开小皮面板、在首页启动apache服务器
  2. 打开vscode
  3. 新建Signup.php

由于是第一次讲后端,我把分析的过程一步步给大家展示出来,之后的页面我就直接写完整代码了。

<?php
echo '你好';
?>

在上面这段代码中,<?php ?>是 PHP 代码的开放和关闭标签,就是说写在中间的内容就会被当作php的代码来执行,不然不认识。

echo的中文翻译是回声的意思,其实就是咱们不是发了一个请求给后端吗?后端收到请求是不是得给咱们一个回应啊,上面这段代码就是回答了我们一声,说了一句“你好”。

前端对这个接口发请求,看看能不能收到一句“你好”呢?如果收到了,表示前后端成功对话了。

还记得注册页面是不是得传三个参数,也就是前端得告诉我们需要注册账号的用户名,以及还输入了两次密码,这些参数我们都需要后端接收,并保存到数据库,如果接收呢?

<?php
// 定义变量$username,用于接收get请求获取的字段
$username = $_GET['username'];
echo $username;
?>

上述代码接收了来自前端get请求发送的字段username,并保存在$username变量里,我们用echo回答给前端,表示我们收到了,很简单。

<?php
// 定义变量$username,用于接收get请求获取的字段
$username = $_GET['username'];
$password = $_GET['password'];
echo $username;
echo $password;
?>

但是这样做有一个问题,就是如果要接收两个参数的话,返回数据的时候就出问题,通俗来说,你发现这两个数据是“粘”在一起的,要用的话还得想办法给他们分开,根本分不开的好吧。

这个时候需要定义一个数组类型的变量,用于保存多个数据。

但是注意,我们之前学过python的数组类型,不就是定义一个[],然后往这里面装东西不就行了吗?使用上比较简单,但是php的数组是一种关联数组,是用键值对的形式来存储的,硬要比较的话,和python中的字典类型很像。

<?php
// 定义变量$username,用于接收get请求获取的字段
$username = $_GET['username'];
$password = $_GET['password'];

$a = array(); // 定义一个空数组
$a['username'] = $username;
$a['password'] = $password;

// 返回之前要先将数组转换为json格式
echo json_encode($a);
?>

注意:

  • 返回之前要先将数组转换为json格式
  • 在网络中传播的数据基本上都是json格式
  • 原因是,虽然都是数组,但是php的数组和python的数组在结构上完全不一样
  • 这就导致不同语言之间的数据在传输的时候互相不认识
  • 大家就规定了一种通用的格式,就是json,他就是一种简单的键值对类型,一个键对应一个值
  • 所以只要是键值对类型的数据几乎都可以转换为json格式,相当于一种通用的货币

3.数据库

  1. 启动小皮面板首页的MYSQL
  2. 在数据库选项卡中创建数据库(我已经帮你们创建好了)
  3. 在软件管理中的第四个网站程序,第一个就是,phpMyadmin,点击管理进入管理页面,这里需要输入数据库的密码。
  4. 新建数据表users
  5. 新建字段
字段名 类型 默认值 含义
id int10 用户的唯一标识
username varchar100 用户名
password varchar100 密码
admin int10 0 管理权限

数据库连接文件(conn.php)

<?php
// 连接数据库服务器(用户名、密码、数据库名)
$conn = mysqli_connect("localhost","admin","123456","web");
if(!$conn){
    die('连接数据库失败');
}

// 设置字符集
mysqli_query($conn,"set names utf8");

4.完善后端(Signup.php)

数据库建好了之后,我们再来写注册页面的后端

<?php
// 连接数据库
include_once "conn.php";

// 定义变量$username,用于接收get请求获取的字段
$username = $_GET['username'];
$password = $_GET['password'];

$a = array(); // 定义一个空数组[]

// 新增一条数据
$sql = "INSERT INTO `users`(`username`,`password`) VALUES ('$username','$password')";
// 执行sql语句
$result = mysqli_query($conn,$sql);
// 如果执行成功,$result就为true,反之为false
if($result){
    $a['error'] = 0;
    $a['msg'] = '请求成功';
}else{
    $a['error'] = 1;
    $a['msg'] = '请求失败';
}
// 返回之前要先将数组转换为json格式
echo json_encode($a);
exit;
?>

现在可以通过添加数据到数据库,但是还是有一点问题,因为产品是需要结合具体的使用场景的,如果注册了两个同名的用户,那么登录的时候就出问题了,到底应该是登录谁的账号,所以按理来说应该是一个账号对应一个用户名,我们不能允许用户注册相同的用户名。

也就是说,用户在注册的时候,程序需要先校验,当前数据库是否已经存在相同的用户名了。

// 先判断是否已经存在相同的用户名
$sql = "SELECT * FROM `users` WHERE `username` = '$username'";
// 对于SELECT查询,由于它们产生一个结果集
$result = mysqli_query($conn,$sql);
// 需要通过mysqli_fetch_row()函数来从结果集中逐行获取数据
$info = mysqli_fetch_array($result);
// 还可以通过mysqli_num_rows()函数获取数量
$num = mysqli_num_rows($result);
if($num){
    $a['error'] = 1;
    $a['msg'] = '该用户名已存在';
    echo json_encode($a);
    exit;
}

5.完善前端(signup.vue)

再回过头来完善一下前端代码

<template>
	<!-- 网页主体 -->
	<body class="flex_column">
		<!-- 标题区域 -->
		<div class="title_section flex_row" style="justify-content: space-around;">
			<h3>用户注册</h3>
			<h3>X</h3>
		</div>
		<!-- 图片区域 -->
		<div class="image_section flex_column">
			<image style="width: 100px;height: 100px;" src="../../static/logo.png" mode=""></image>
			<h4>Hi、请注册</h4>
		</div>
		<!-- 用户输入区域 -->
		<div class="input_secition flex_column">
			<div class="flex_row">
				<p>用户名:</p>
				<input v-model="username" type="text" placeholder="请输入账号"/>
			</div>
			<div class="flex_row">
				<p>密码:</p>
				<input v-model="password" type="password" placeholder="请输入密码"/>
			</div>
			<div class="flex_row">
				<p>确认密码:</p>
				<input v-model="cpassword" type="password" placeholder="请再次输入密码"/>
			</div>
		</div>
		<!-- 按钮区域 -->
		<div class="button_section flex_row">
			<button @click="signup()" class="login_button">注册</button>
		</div>
	</body>
</template>

<script>
	export default {
		data() {
			return {
				username: "",
				password: "",
				cpassword: "",
			}
		},
		onLoad() {

		},
		methods: {
			// 注册
			signup(){
                // 非空校验
				if(!this.username || !this.password || !this.cpassword){
					uni.showToast({
						title:'用户名、密码、确认密码、反正有一个没输入',
						duration:2000
					})
					return false
				}
                // 密码的长度不能小于6位
				if(this.password.length < 6 || this.password.length > 18){
					uni.showToast({
						title:'前端:密码不能小于6位、或者不能大于18位',
						duration:3000,
						icon:'error'
					})
					return false
				}
				// 密码不一致校验
				if(this.password != this.cpassword){
					uni.showToast({
						title:'两次输入的密码不一致'
					})
					return false
				}
                // 发送请求
				uni.request({
				    url: "http://localhost:7777/Signup.php",
				    data: {
				        username: this.username,
						password: this.password,
						cpassword: this.cpassword
				    },
				    success: (res) => {
				        console.log(res);
						if(res.data.error==1){
							uni.showToast({
								title:res.data.msg,
								duration:3000,
								icon:'error'
							})
						}else{
							uni.showToast({
								title:res.data.msg,
								duration:3000,
								icon:'success'
							})
						}
				    }
				});
			}
		}
	}
</script>

<style>
.login_button{
	width: 50vw;
	font-weight: bold;
}
.login_button:hover{
	background-color: aquamarine;
}
input{
	border: 1px solid black;
	margin: 10px;
	padding: 10px;
}
.title_section{
	width: 100vw;
	height: 10vh;
	background-color: antiquewhite;
}
.image_section{
	width: 100vw;
	height: 25vh;
	background-color: darkgray;
}
.input_secition{
	width: 100vw;
	height: 30vh;
	background-color: darkseagreen;
}
.button_section{
	width: 100vw;
	height: 20vh;
	background-color: pink;
}
/* 弹性盒子横着排 */
.flex_row{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: row;/*排列方向:横向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: column;/*排列方向:纵向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
</style>

6.完善后端校验(Signup.php)

<?php
include_once 'conn.php';

$a = array(); // 定义一个空数组

// 定义变量$username,用于接收get请求获取的字段
$username = trim($_GET['username']);
$password = trim($_GET['password']);
$cpassword = trim($_GET['cpassword']);

// 非空校验
if(!strlen($username) || !strlen($password) || !strlen($cpassword)){
    $a['error'] = 1;
    $a['msg'] = '用户名、密码、确认密码、反正有一个没输入';
    echo json_encode($a);
    exit;
}

// 密码不能低于6位、或者密码不能大于18位
if(strlen($password) < 6 || strlen($password) > 18){
    $a['error'] = 1;
    $a['msg'] = '后端:密码不能低于6位、或者密码不能大于18位';
    echo json_encode($a);
    exit;  // 终止程序往下运行
}

// 密码不一致校验
if($password <> $cpassword){
    $a['error'] = 1;
    $a['msg'] = '两次输入的密码不一致';
    echo json_encode($a);
    exit;
}

// 不能注册同名账号
$sql = "SELECT * FROM `users` WHERE `username` = '$username'";
$result = mysqli_query($conn,$sql);
$num = mysqli_num_rows($result);
if($num){
    $a['error'] = 1;
    $a['msg'] = '该用户名已经注册了';
    echo json_encode($a);
    exit;
}

// 插入一条数据
$sql = "INSERT INTO `users`(`username`, `password`) VALUES ('$username','$password')";
$result = mysqli_query($conn,$sql);
if($result){
    $a['error'] = 0;
    $a['msg'] = '注册成功';
}else{
    $a['error'] = 1;
    $a['msg'] = '注册失败';
}

// 返回之前要先将数组转换为json格式
echo json_encode($a);
?>

7.注册僵尸账号(了解)

先去这个网站弄个密码字典,https://www.bugku.com/mima/

import requests

file = open('./password_hanhan.txt','r',encoding='utf-8')
content_list =file.readlines()
for content in content_list:
    username = content.strip()
    password = content.strip()

    url = 'http://localhost:7777/Signup.php'
    params = {
        'username':username,
        'password':password,
        'cpassword':password,
    }

    res = requests.get(url,params=params)
    res.encoding = 'utf-8'

    print(res.text)

8.后端的接口文档

请求地址 请求方式
http://localhost:7777/Signup.php GET
字段名称 类型和长度 是否必须 默认值
username varchar(100)
password varchar(100)
cpassword varchar(100)
返回参数 字段
error error为1表示有错误、error为0表示没有错误
msg 错误的具体内容

三、登录页面

后端

<?php
// 链接上数据库
include_once 'conn.php';

// 接收前端传过来的用户名和密码
$username = $_GET['username'];
$password = $_GET['password'];

// 定义一个空数组、用于存放返回的数据
$a = array();

// 用户名、密码不能为空 0:false   非0:true
if(!strlen($username) || !strlen($password)){
    $a['error'] = 1;
    $a['msg'] = '后端:用户名、密码,反正你有一个没填';
    echo json_encode($a);
    exit;  // 终止程序往下运行
}

// 密码不能低于6位、或者密码不能大于18位
if(strlen($password) < 6 || strlen($password) > 18){
    $a['error'] = 1;
    $a['msg'] = '后端:密码不能低于6位、或者密码不能大于18位';
    echo json_encode($a);
    exit;  // 终止程序往下运行
}

// 去数据库查询,有没有这样一条数据,用户名和密码都等于前端输入的用户名和密码
$sql = "SELECT * FROM `users` WHERE `username` = '$username' and `password` = '$password'";
// 执行上面的sql查询语句,得到一个结果集
$result = mysqli_query($conn,$sql);
// 数一下结果集里有多少条数据
$num = mysqli_num_rows($result);
// 如果查出来有1条以上,就为true(登录成功),否者为false(登录失败)
if($num){
    $a['error'] = 0;
    $a['msg'] = '登录成功';
    echo json_encode($a);
    exit;
}else{
    $a['error'] = 1;
    $a['msg'] = '用户名或密码错误';
    echo json_encode($a);
    exit;
}
?>

后端接口文档

请求的地址 请求的方式
http://localhost:7777/Login.php get
携带的参数 类型 是否必须 默认值
username varcher(100)
password varcher(100)
返回参数 字段
error error为1表示有错误、error为0表示没有错误
msg 错误的具体内容

前端

<template>
	<view>
		<!-- 图片区域 -->
		<div class="image_section flex_column">
			<image src="../../static/angry.gif" style="height: 100px;width: 100px;" mode=""></image>
			<h4>Hi~请登陆</h4>
		</div>
		<!-- 输入区域 -->
		<div class="input_section flex_column">
			<!-- 用户名及用户名输入框 -->
			<div class="flex_row">
				<p>用户名</p>
				<input type="text" placeholder="请输入用户名" v-model="username"/>
			</div>
			<!-- 密码及密码输入框 -->
			<div class="flex_row">
				<p>密码</p>
				<input type="password" placeholder="请输入密码" v-model="password"/>
			</div>
		</div>
		<!-- 按钮区域 -->
		<div class="button_section flex_row">
			<button @click="login()" class="blue_button">登陆</button>
		</div>
		<!-- 导航区域 -->
		<div class="nav_section flex_row">
			<navigator url="/pages/signup/signup">
				<button class="blue_button" style="width: 70vw;">没有账号、立即注册</button>
			</navigator>
		</div>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				username:'',
				password:''
			}
		},
		methods: {
			// 登陆按钮
			login(){
				// 输入框的空校验
				if(!this.username || !this.password){
					uni.showToast({
						title:'前端:用户名、密码,反正有一个没填',
						duration:3000,
						icon:'error'
					})
					return false
				}
				// 密码的长度不能小于6位
				if(this.password.length < 6 || this.password.length > 18){
					uni.showToast({
						title:'前端:密码不能小于6位、或者不能大于18位',
						duration:3000,
						icon:'error'
					})
					return false
				}
				// 发送登录请求
				uni.request({
					url:'http://localhost:7777/Login.php',
					method:'GET',
					data:{
						username:this.username,
						password:this.password
					},
					// 如果请求成功
					success: (res) => {
						console.log(res)
						// 用户登录成功
						if(res.data.error == 0){
							uni.showToast({
								title:res.data.msg,
								icon:'success'
							})
							// 登录成功之后,将用户名保存在缓存里
							uni.setStorageSync('username',this.username)
							// const username = uni.getStorageSync('username')
							// console.log(username)
						}else{
							uni.showToast({
								title:res.data.msg,
								icon:'error'
							})
						}
					}
				})
			}
		}
	}
</script>

<style>
.image_section{
	width: 100vw;
	height: 20vh;
	background-color: antiquewhite;
}
.input_section{
	width: 100vw;
	height: 30vh;
	background-color: cadetblue;
}
.button_section{
	width: 100vw;
	height: 20vh;
	background-color: chartreuse;
}
.nav_section{
	width: 100vw;
	height: 30vh;
	background-color: chocolate;
}
/* 弹性盒子横着排 */
.flex_row{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: row;/*排列方向:横向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: column;/*排列方向:纵向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
input{
	border: 1px solid black;
	margin: 10px;
	padding: 10px;
}
.blue_button{
	background-color: #ecf5ff;
	width: 100px;
	border: 1px solid #409eff;
	color: #409eff;
	font-weight: bold;
}
</style>

密码爆破

import requests

url = 'http://localhost:7777/Login.php'

file = open('./password.txt','r',encoding='utf-8')
rows = file.readlines()
for row in rows:
    username = row.strip()
    password = row.strip()
    params = {
        'username' : username,
        'password' : password
    }

    res = requests.get(url,params)
    if r'\u767b\u5f55\u6210\u529f' in res.text:
        print(password)
        break

四、制作底部导航栏

官方的代码示例:

"tabBar": {
	"color": "#7A7E83",
	"selectedColor": "#3cc51f",
	"borderStyle": "black",
	"backgroundColor": "#ffffff",
	"list": [{
		"pagePath": "pages/component/index",
		"iconPath": "static/image/icon_component.png",
		"selectedIconPath": "static/image/icon_component_HL.png",
		"text": "组件"
	}, {
		"pagePath": "pages/API/index",
		"iconPath": "static/image/icon_API.png",
		"selectedIconPath": "static/image/icon_API_HL.png",
		"text": "接口"
	}]
}

我写的代码:(pages.json)

{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"navigationBarTitleText": "树洞"
			}
		},
		{
			"path" : "pages/mine/mine",
			"style" : 
			{
				"navigationBarTitleText" : "个人中心",
				"enablePullDownRefresh" : false
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {},
	"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#00aaff",
		"borderStyle": "black",
		"backgroundColor": "#ffffff",
		"list": [{
			"pagePath": "pages/index/index",
			"iconPath": "static/home.png",
			"selectedIconPath": "static/home-active.png",
			"text": "首页"
		}, {
			"pagePath": "pages/mine/mine",
			"iconPath": "static/mine.png",
			"selectedIconPath": "static/mine-active.png",
			"text": "我的"
		}]
	}

}

这里我是顺便把标题栏的名字也改了。

五、个人中心页面(mine.vue)

<template>
	<body>
		<!-- 用户信息区域 -->
		<div class="flex_row" style="width: 100vw;height: 18vh;background-color: cornflowerblue;">
			<!-- 左边的头像区域 -->
			<div class="flex_row" style="width: 30%;height: 100%;">
				<image style="width: 80px;height: 80px;" src="../../static/头像/ikun_7.jpg" mode=""></image>
			</div>
			<!-- 右边的用户名区域 -->
			<div class="flex_column" style="width: 70%;height: 100%;justify-content: space-evenly;">
				<h3 style="color: white;">{{username}}</h3>
				<!-- 登录注册按钮 -->
				<navigator v-if="username=='未登录'" url="/pages/login/login">
					<button style="width: 100px; font-weight: bold;background-color: antiquewhite;font-size: medium;">登陆注册</button>
				</navigator>
			</div>
		</div>
		<!-- 菜单项(我的树洞) -->
		<div class="flex_row" style="border-bottom: 1px solid gray; padding: 10px;box-sizing: border-box; width: 100vw;height: 8vh;background-color: white;margin-top: 20px;">
			<div class="flex_row" style="justify-content: flex-start; width: 50%;height: 100%;">
				<image class="mid_icon" src="../../static/contact.png" mode=""></image>
				<p>我的树洞</p>
			</div>
			<div class="flex_row" style="justify-content: flex-end; width: 50%;height: 100%;">
				<image src="../../static/right_arrow.png" class="mid_icon" mode=""></image>
			</div>
		</div>
		<!-- 菜单项(修改密码) -->
		<navigator v-if="username!='未登录'" url="/pages/mod_password/mod_password">
			<div class="flex_row" style="border-bottom: 1px solid gray;padding: 10px;box-sizing: border-box; width: 100vw;height: 8vh;background-color: white;">
				<div class="flex_row" style="justify-content: flex-start; width: 50%;height: 100%;">
					<image class="mid_icon" src="../../static/contact.png" mode=""></image>
					<p>修改密码</p>
				</div>
				<div class="flex_row" style="justify-content: flex-end; width: 50%;height: 100%;">
					<image src="../../static/right_arrow.png" class="mid_icon" mode=""></image>
				</div>
			</div>
		</navigator>
		<!-- 菜单项(退出登录) -->
		<div @click="exit()" class="flex_row" style="border-bottom: 1px solid gray;padding: 10px;box-sizing: border-box; width: 100vw;height: 8vh;background-color: white;">
			<div class="flex_row" style="justify-content: flex-start; width: 50%;height: 100%;">
				<image class="mid_icon" src="../../static/contact.png" mode=""></image>
				<p>退出登录</p>
			</div>
			<div class="flex_row" style="justify-content: flex-end; width: 50%;height: 100%;">
				<image src="../../static/right_arrow.png" class="mid_icon" mode=""></image>
			</div>
		</div>
	</body>
</template>

<script>
	export default {
		data() {
			return {
				username:'未登录'
			}
		},
		// 定义网页的相关方法
		methods: {
			// 退出登录
			exit(){
				// 清除缓存中的用户名
				uni.removeStorageSync('username')
				// 更新页面上的数据为未登录
				this.username = '未登录'
				// 弹框提醒用户
				uni.showToast({
					title:'退出成功'
				})
			}
		},
		// 生命周期函数(当页面显示出来的时候自动调用)
		 onShow(){
			// 如果缓存里有用户名,再去替换,否则不要替换
			if(uni.getStorageSync('username')){ //''为False,否则都是True
				// 读取缓存中存放的用户名,并且更新到页面
				const username = uni.getStorageSync('username')
				this.username = username
			}
		 }
	}
</script>

<style>
.samll_icon{
	width: 20px;
	height: 20px;
}
.mid_icon{
	width: 30px;
	height: 30px;
}
.big_icon{
	width: 40px;
	height: 40px;
}
body{
	background-color: #efefef;
	width: 100vw;
	height: 100vh;
}
/* 弹性盒子横着排 */
.flex_row{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: row;/*排列方向:横向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
    display: flex; /* 排列方式:弹性盒子 */
    flex-direction: column;/*排列方向:纵向*/
    justify-content: center;/*主轴居中*/
    align-items: center;/*副轴居中*/
}
</style>

六、发布树洞页面

<template>
	<view>
		<!-- 输入区域 -->
		<div class="input_section">
			<textarea v-model="content" style="height: 60%;" maxlength="50"/>
			<p>字数提示:{{content.length}}/50</p>
		</div>
		<!-- 按钮区域 -->
		<div class="button_section">
			<button @click="commit()" class="commit_button">发布</button>
		</div>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				content:''   // 用户输入的内容
			}
		},
		methods: {
			// 发布按钮
			commit(){
				// 前端空校验
				if(this.content == ''){
					alert('请输入内容')
					return
				}
				// 从缓存里去取用户名
				const username = uni.getStorageSync('username')
				// 发请求到后端
				uni.request({
					url:'http://localhost:7777/Commit.php',
					method:'GET',
					data:{
						content: this.content,
						username: username
					},
					// 发送请求成功
					success: (res) => {
						console.log(res)
						// 如果发布成功
						if (res.data.error == 0) {
							uni.showToast({
								title:res.data.msg
							})
							// 跳转到广场页面
							uni.switchTab({
								url:'/pages/index/index'
							})
							this.content = ''
						}else{
							uni.showToast({
								title:res.data.msg,
								icon:'error'
							})
						}
					}
				})
			}
		},
		// 当页面自动显示的时候,自动执行一次
		onShow: () => {
			// 从缓存里去取用户名
			const username = uni.getStorageSync('username')
			console.log(username);
			// 如果没有用户名
			if (!username){   // ''为false,否则就是true
				// 弹一个登录的对话框
				uni.showModal({
					title: '提示',
					content: '请先登录',
					success: function (res) {
						// 如果点击确定的话
						if (res.confirm) {
							// 跳转到登录页面
							uni.navigateTo({
								url:'/pages/login/login'
							})
						// 如果用户点击了取消
						} else if (res.cancel) {
							// 跳转到登录页面
							uni.navigateTo({
								url:'/pages/login/login'
							})
						}
					}
				});
			}
		}
	}
</script>

<style>
textarea{
	border: 1px solid gray;
	padding: 10px;
	margin: 10px;
}
.input_section{
	width: 100vw;
	height: 40vh;
	background-color: antiquewhite;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
}
.button_section{
	width: 100vw;
	height: 20vh;
	background-color: aquamarine;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
}
.commit_button{
	width: 30%;
	border: 1px saddlebrown solid;
	background-color: lightblue;
	color: darkblue;
	font-weight: bold;
}
</style>
<?php
// 连接数据库
include_once 'conn.php';

// 定义一个数组a,用于存放返回的数据
$a = array();

// 接收前端发过来的内容
$content = $_GET['content'];
$username = $_GET['username'];

// 插入一条数据
$sql = "INSERT INTO `shudong`(`username`, `content`) VALUES ('$username','$content')";
// 执行sql语句 (返回一个结果,如果执行成功,返回true,否则返回false)
$result = mysqli_query($conn,$sql);
if($result){
    $a['error'] = 0;
    $a['msg'] = '执行成功';
}else{
    $a['error'] = 1;
    $a['msg'] = '执行失败';
}

echo json_encode($a);
?>

文章作者: 神秘码农
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 神秘码农 !
  目录