Flask+微信小程序实现Login+Profile

devtools/2024/10/22 5:15:47/

Python代码

首先flask的session用不了,只能用全局变量来实现。

import pymysql
from flask import Flask, request, jsonify, session
from flask_cors import CORS
from flask import make_responseapp = Flask(__name__)
CORS(app, supports_credentials=True)  # 允许带上凭据(cookies)app.secret_key = 'your_secret_key' # 数据库配置
db_config = {'host': 'localhost','user': 'root','password': '123456','database': 'pet','charset': 'utf8mb4'
}current_user_id = None@app.route('/login', methods=['POST'])
def login():global current_user_id  # 声明使用全局变量data = request.get_json()username = data.get('username')password = data.get('password')connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:sql = "SELECT * FROM users WHERE username=%s AND password=%s"cursor.execute(sql, (username, password))result = cursor.fetchone()if result:current_user_id = result[0]  # 设置全局变量print(f"User ID set globally: {current_user_id}")return jsonify({'message': '登录成功', 'status': 'success', 'data': {'id': current_user_id, 'username': result[1]}})else:return jsonify({'message': '登录失败', 'status': 'fail'}), 401finally:connection.close()@app.route('/register', methods=['POST'])
def register():data = request.get_json()print("Received data:", data)  # 打印接收到的数据username = data.get('username')password = data.get('password')# 检查用户名和密码是否提供if not username or not password:return jsonify({'message': '用户名和密码不能为空', 'status': 'fail'}), 400connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:# 查询数据库以检查用户名是否已存在sql_check = "SELECT * FROM users WHERE username=%s"cursor.execute(sql_check, (username,))result = cursor.fetchone()if result:return jsonify({'message': '用户名已存在', 'status': 'fail'}), 400# 插入新用户sql_insert = "INSERT INTO users (username, password) VALUES (%s, %s)"cursor.execute(sql_insert, (username, password))connection.commit()return jsonify({'message': '注册成功', 'status': 'success'}), 201except pymysql.MySQLError as db_err:return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500except Exception as e:return jsonify({'message': '注册失败', 'status': 'fail', 'error': str(e)}), 500finally:connection.close()  # 确保连接在完成后关闭@app.route('/profile', methods=['GET'])
def profile():global current_user_id  # 声明使用全局变量if current_user_id is None:return jsonify({'message': '未登录', 'status': 'fail'}), 401# 查询用户信息connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:sql = "SELECT username, nickname, phone, email FROM users WHERE id=%s"cursor.execute(sql, (current_user_id,))result = cursor.fetchone()if result:user_data = {"username": result[0],"nickname": result[1],"phone": result[2],"email": result[3]}return jsonify({'message': '获取成功', 'status': 'success', 'data': user_data})else:return jsonify({'message': '用户未找到', 'status': 'fail'}), 404finally:connection.close()#==========================发布笔记===============================
@app.route('/post_note', methods=['POST'])
def post_note():global current_user_idif current_user_id is None:return jsonify({'message': '未登录', 'status': 'fail'}), 401data = request.get_json()print(data)content = data.get('content')if not content:return jsonify({'message': '笔记内容不能为空', 'status': 'fail'}), 400connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:sql_insert = "INSERT INTO notes (user_id, content) VALUES (%s, %s)"cursor.execute(sql_insert, (current_user_id, content))connection.commit()return jsonify({'message': '发布成功', 'status': 'success'}), 201except pymysql.MySQLError as db_err:return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500finally:connection.close()# ========================== 获取笔记和评论 ===========================
@app.route('/get_note/<int:note_id>', methods=['GET'])
def get_note(note_id):connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:# 获取笔记sql_get_note = "SELECT content, created_at FROM notes WHERE id=%s"cursor.execute(sql_get_note, (note_id,))note = cursor.fetchone()if not note:return jsonify({'message': '笔记未找到', 'status': 'fail'}), 404# 获取评论sql_get_comments = "SELECT user_id, comment, created_at FROM comments WHERE note_id=%s"cursor.execute(sql_get_comments, (note_id,))comments = cursor.fetchall()return jsonify({'message': '获取成功','status': 'success','data': {'content': note[0],'comments': [{'user_id': comment[0], 'comment': comment[1], 'created_at': comment[2]}for comment in comments]}})except pymysql.MySQLError as db_err:return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500finally:connection.close()# ========================== 提交评论 ================================
@app.route('/post_comment', methods=['POST'])
def post_comment():data = request.get_json()note_id = data.get('note_id')comment = data.get('comment')user_id = data.get('user_id')if not note_id or not comment or not user_id:return jsonify({'message': '笔记ID、评论内容和用户ID不能为空', 'status': 'fail'}), 400connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:# 检查笔记是否存在sql_check_note = "SELECT id FROM notes WHERE id=%s"cursor.execute(sql_check_note, (note_id,))note_exists = cursor.fetchone()if not note_exists:return jsonify({'message': '笔记不存在', 'status': 'fail'}), 404# 插入评论sql_insert_comment = "INSERT INTO comments (note_id, user_id, comment) VALUES (%s, %s, %s)"cursor.execute(sql_insert_comment, (note_id, user_id, comment))connection.commit()return jsonify({'message': '评论成功', 'status': 'success'}), 201except pymysql.MySQLError as db_err:return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500finally:connection.close()#========================all_notes====展示全部笔记====================
@app.route('/get_notes', methods=['GET'])
def get_notes():connection = pymysql.connect(**db_config)try:with connection.cursor() as cursor:sql = "SELECT id, content, user_id FROM notes"  # 假设你有一个 'notes' 表存储笔记和用户IDcursor.execute(sql)notes = cursor.fetchall()notes_list = [{'id': note[0], 'content': note[1], 'user_id': note[2]} for note in notes]return jsonify({'message': '获取成功', 'status': 'success', 'data': {'notes': notes_list}})except pymysql.MySQLError as db_err:return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500finally:connection.close()if __name__ == '__main__':app.run()

微信小程序代码

Login

Page({data: {username: '',password: ''},onUsernameInput: function(e) {this.setData({username: e.detail.value});},onPasswordInput: function(e) {this.setData({password: e.detail.value});},login: function() {const { username, password } = this.data;if (!username || !password) {wx.showToast({title: '请输入账号和密码',icon: 'none'});return;}wx.request({url: 'http://127.0.0.1:5000/login',method: 'POST',data: {username,password},success: function(res) {if (res.statusCode === 200) {const data = res.data;wx.showToast({title: data.message,icon: data.status === 'success' ? 'success' : 'none'});if (data.status === 'success') {// 登录成功后,处理返回的数据const userData = data.data; // 获取数组数据console.log(userData); wx.redirectTo({url: '/pages/index/index' });// 这里可以根据需要进行进一步处理// 可以在这里进行页面跳转等操作}} else {wx.showToast({title: '登录失败',icon: 'none'});}},fail: function(err) {wx.showToast({title: '网络错误',icon: 'none'});console.error(err);}});},goToRegister: function() {wx.redirectTo({url: '/pages/register/register' // 修改为目标页面的路径});}
});
<view class="container"><view class="input-group"><input type="text" placeholder="请输入用户名" bindinput="onUsernameInput" /></view><view class="input-group"><input type="password" placeholder="请输入密码" bindinput="onPasswordInput" /></view><button bindtap="login">登录</button><button bindtap="goToRegister">注册</button> <!-- 添加注册按钮 -->
</view>
/* 样式文件 */
.container {display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;padding: 20px;
}.input-group {width: 100%;max-width: 300px;margin-bottom: 20px;
}input {width: 100%;padding: 10px;border: 1px solid #ccc;border-radius: 4px;font-size: 16px;
}button {width: 100%;max-width: 300px;padding: 10px;background-color: #007bff;color: white;border: none;border-radius: 4px;font-size: 16px;cursor: pointer;
}button:hover {background-color: #0056b3;
}

profile

Page({data: {username: '',nickname: '',phone: '',email: ''},goToIndex() {wx.navigateTo({url: '/pages/index/index',  // 笔记页面的路径});},onLoad: function() {wx.request({url: 'http://127.0.0.1:5000/profile',method: 'GET',success: (res) => {if (res.statusCode === 200) {const data = res.data.data;this.setData({username: data.username,nickname: data.nickname,phone: data.phone,email: data.email});} else {wx.showToast({title: res.data.message,icon: 'none'});}},fail: (err) => {wx.showToast({title: '网络错误',icon: 'none'});console.error(err);}});}
});
<view class="container"><view class="info-section"><view class="info-item"><text>用户名:</text><text>{{username}}</text></view><view class="info-item"><text>昵称:</text><text>{{nickname}}</text></view><view class="info-item"><text>电话:</text><text>{{phone}}</text></view><view class="info-item"><text>邮箱:</text><text>{{email}}</text></view></view><!-- 前往笔记页面的按钮 --><view class="button-section"><button bindtap="goToIndex">返回主页</button></view>
</view>
.container {padding: 20px;background-color: #f8f8f8; /* 背景颜色 */border-radius: 8px; /* 圆角 */box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
}.info-section {margin-bottom: 20px; /* 下边距 */
}.info-item {margin-bottom: 15px; /* 每项的下边距 */padding: 10px; /* 内边距 */background-color: #ffffff; /* 每项的背景颜色 */border: 1px solid #e0e0e0; /* 边框颜色 */border-radius: 5px; /* 边框圆角 */display: flex; /* 使用flex布局 */justify-content: space-between; /* 子项两端对齐 */align-items: center; /* 垂直居中对齐 */
}.info-item text {color: #333333; /* 文本颜色 */font-size: 16px; /* 字体大小 */
}button {background-color: #007aff; /* 按钮背景颜色 */color: white; /* 按钮文本颜色 */padding: 10px 15px; /* 按钮内边距 */border: none; /* 无边框 */border-radius: 5px; /* 圆角 */font-size: 16px; /* 字体大小 */cursor: pointer; /* 鼠标悬停时的光标样式 */
}button:hover {background-color: #005bb5; /* 悬停时的背景颜色 */
}

register

Page({data: {username: '',password: ''},onUsernameInput: function(e) {this.setData({username: e.detail.value});},onPasswordInput: function(e) {this.setData({password: e.detail.value});},register: function() {const { username, password } = this.data;if (!username || !password) {wx.showToast({title: '请输入账号和密码',icon: 'none'});return;}wx.request({url: 'http://127.0.0.1:5000/register',method: 'POST',data: {username,password},success: function(res) {if (res.statusCode === 200) {const data = res.data;wx.showToast({title: data.message,icon: data.status === 'success' ? 'success' : 'none'});} else {wx.showToast({title: '注册失败',icon: 'none'});}},fail: function(err) {wx.showToast({title: '网络错误',icon: 'none'});console.error(err);}});}
});
<view class="container"><view class="input-group"><input type="text" placeholder="请输入用户名" bindinput="onUsernameInput" /></view><view class="input-group"><input type="password" placeholder="请输入密码" bindinput="onPasswordInput" /></view><button bindtap="register">注册</button>
</view>
/* 样式文件 */
.container {display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;padding: 20px;
}.input-group {width: 100%;max-width: 300px;margin-bottom: 20px;
}input {width: 100%;padding: 10px;border: 1px solid #ccc;border-radius: 4px;font-size: 16px;
}button {width: 100%;max-width: 300px;padding: 10px;background-color: #007bff;color: white;border: none;border-radius: 4px;font-size: 16px;cursor: pointer;
}button:hover {background-color: #0056b3;
}

index

Page({// 跳转到发布笔记页面goToPublishNote() {wx.navigateTo({url: '/pages/notes/notes', // 发布笔记页面的路径});},// 跳转到查看全部笔记页面goToAllNotes() {wx.navigateTo({url: '/pages/all_notes/all_notes', // 全部笔记页面的路径});},goToProfile() {wx.navigateTo({url: '/pages/profile/profile', // 全部笔记页面的路径});}
});
<view class="container"><button bindtap="goToPublishNote">发布笔记</button><button bindtap="goToAllNotes">查看全部笔记</button><button bindtap="goToProfile">进入个人页面</button>
</view>

all_notes

Page({data: {notes: [], // 笔记列表},// 页面加载时获取所有笔记onLoad() {this.fetchNotes();},// 获取笔记列表fetchNotes() {wx.request({url: 'http://127.0.0.1:5000/get_notes', // 获取笔记的后端接口method: 'GET',success: (res) => {if (res.data.status === 'success') {this.setData({ notes: res.data.data.notes });} else {wx.showToast({title: res.data.message,icon: 'none',});}},fail: () => {wx.showToast({title: '请求失败',icon: 'none',});},});},// 选择某个笔记时触发selectNote(event) {const noteId = event.currentTarget.dataset['noteId'];const userId = event.currentTarget.dataset['userId'];// 跳转到笔记详情页面,并传递noteId和userId作为参数wx.navigateTo({url: `/pages/note_detail/note_detail?noteId=${noteId}&userId=${userId}`,});},
});
<view class="note-list"><block wx:for="{{notes}}" wx:key="id"><view class="note-item" bindtap="selectNote" data-note-id="{{item.id}}" data-user-id="{{item.user_id}}"><text>笔记内容: {{item.content}}</text><text>用户ID: {{item.user_id}}</text></view></block>
</view>

notes

Page({data: {noteContent: '',        // 发布的笔记内容commentContent: '',     // 评论的内容notes: [],              // 笔记列表selectedNoteId: null,   // 选中的笔记IDcomments: []            // 当前笔记的评论列表},// 输入笔记内容onInputNote(event) {this.setData({noteContent: event.detail.value});},// 发布笔记postNote() {const { noteContent } = this.data;if (!noteContent) {wx.showToast({title: '笔记内容不能为空',icon: 'none'});return;}wx.request({url: 'http://127.0.0.1:5000/post_note',method: 'POST',data: {content: noteContent},success: (res) => {if (res.data.status === 'success') {wx.showToast({ title: '发布成功' });this.fetchNotes(); // 重新获取笔记列表this.setData({ noteContent: '' });} else {wx.showToast({ title: res.data.message, icon: 'none' });}}});},
});
<view class="container"><!-- 发布笔记区域 --><view class="post-note"><textarea placeholder="请输入笔记内容" bindinput="onInputNote" value="{{noteContent}}"></textarea><button bindtap="postNote">发布笔记</button></view>  
</view>
.container {padding: 20px;
}.post-note textarea, .post-note button {margin-bottom: 10px;width: 100%;
}.note-list {margin-top: 20px;
}.note-item {padding: 10px;background-color: #f5f5f5;margin-bottom: 10px;border-radius: 5px;
}.comment-list {margin-top: 20px;
}.comment-item {padding: 5px;background-color: #eee;margin-bottom: 5px;border-radius: 3px;
}

note_detail

Page({data: {noteId: null,userId: null,noteContent: '',comments: [],  // 评论列表newComment: '',  // 用户输入的新评论},onLoad(options) {const { noteId, userId } = options;this.setData({ noteId, userId });this.fetchNoteDetail(noteId);this.fetchComments(noteId);},// 根据noteId获取笔记详情fetchNoteDetail(noteId) {wx.request({url: `http://127.0.0.1:5000/get_note/${noteId}`,method: 'GET',success: (res) => {if (res.data.status === 'success') {this.setData({ noteContent: res.data.data.content });} else {wx.showToast({title: res.data.message,icon: 'none',});}},fail: () => {wx.showToast({title: '请求失败',icon: 'none',});},});},// 获取该笔记的评论fetchComments(noteId) {wx.request({url: `http://127.0.0.1:5000/get_comments/${noteId}`,  // 获取评论的接口method: 'GET',success: (res) => {if (res.data.status === 'success') {this.setData({ comments: res.data.data.comments });} else {wx.showToast({title: res.data.message,icon: 'none',});}},fail: () => {wx.showToast({title: '请求失败',icon: 'none',});},});},// 处理评论输入handleCommentInput(event) {this.setData({ newComment: event.detail.value });},// 提交评论submitComment() {if (!this.data.newComment.trim()) {wx.showToast({title: '请输入评论内容',icon: 'none',});return;}wx.request({url: 'http://127.0.0.1:5000/post_comment',method: 'POST',data: {note_id: this.data.noteId,comment: this.data.newComment,user_id: this.data.userId, // 假设使用userId代表发表评论的用户},success: (res) => {if (res.data.status === 'success') {wx.showToast({title: '评论成功',});// 评论成功后,重新获取评论列表this.fetchComments(this.data.noteId);this.setData({ newComment: '' });  // 清空输入框} else {wx.showToast({title: res.data.message,icon: 'none',});}},fail: () => {wx.showToast({title: '评论失败',icon: 'none',});},});},
});
<view class="note-detail"><text>笔记ID: {{noteId}}</text><text>用户ID: {{userId}}</text><text>笔记内容: {{noteContent}}</text><!-- 评论部分 --><view class="comments-section"><text>评论列表:</text><block wx:for="{{comments}}" wx:key="id"><view class="comment-item"><text>用户{{item.user_id}}: {{item.comment}}</text></view></block></view><!-- 新增评论输入框 --><view class="add-comment"><input type="text" placeholder="输入你的评论" value="{{newComment}}" bindinput="handleCommentInput" /><button bindtap="submitComment">提交评论</button></view>
</view>


http://www.ppmy.cn/devtools/122164.html

相关文章

音视频入门基础:FLV专题(8)——FFmpeg源码中,解码Tag header的实现

一、引言 在《音视频入门基础&#xff1a;FLV专题&#xff08;7&#xff09;——Tag header简介》中对Tag header进行了简介&#xff0c;本文讲述FFmpeg源码中是怎样解码FLV文件的Tag header&#xff0c;拿到里面的信息。 二、FFmpeg源码中&#xff0c;解码Tag header的实现 …

08-Registry搭建docker私仓

08-Registry搭建docker私仓 Docker Registry Docker Registry是官方提供的工具&#xff0c;用于构建私有镜像仓库。 环境搭建 Docker Registry也是Docker Hub提供的一个镜像&#xff0c;可以直接拉取运行。 步骤&#xff1a; 拉取镜像 docker pull registry启动Docker R…

代码随想录一刷完结

非常偶然的机会让我看到这个算法训练营的存在&#xff0c;虽然我也没有多大的动力&#xff0c;但当时就觉得没什么事情&#xff0c;想着刷刷题&#xff0c;为以后找工作打打基础。 收获 提示&#xff1a;在刷题过程中的收获 第一次使用CSDN记录&#xff0c;每次有别人点赞和收…

C++面试速通宝典——10

177. #include <filename> 和 #include "filname.h" 有什么区别&#xff1f; ‌‌‌‌  对于 #include <filename> &#xff0c; 编译器从标准库路径开始搜索 filename.h。 ‌‌‌‌  对于 #include "filename.h&#xff0c;编译器从用户的工作…

decltype推导规则

decltype推导规则 当用decltype(e)来获取类型时&#xff0c;编译器将依序判断以下四规则&#xff1a; 1.如果e是一个没有带括号的标记符表达式(id-expression)或者类成员访问表达式&#xff0c;那么decltype(e)就是e所命名的实体的类型。此外&#xff0c;如果e是一个被重载的函…

计算机毕业设计 助农产品采购平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

滚雪球学Oracle[4.2讲]:PL/SQL基础语法

全文目录&#xff1a; 前言一、PL/SQL基础语法1.1 变量声明变量声明示例&#xff1a; 二、记录类型与集合类型的使用2.1 记录类型记录类型的定义与使用 2.2 集合类型 三、PL/SQL表与关联数组3.1 PL/SQL表&#xff08;嵌套表&#xff09;嵌套表的定义与使用 3.2 关联数组关联数组…

P3792 由乃与大母神原型和偶像崇拜

原题链接 不愧是 lxl&#xff0c;硬控我一个半小时。最终也是极限卡过了。 这道题题解区有许多用哈希思想做的&#xff0c;可能实现方式略有不同。而我还是喜欢写保证了正确性的做法。具体说&#xff0c;就是用线段树维护区间最大最小值&#xff0c;因为是一段连续的数&#…