Python代码
首先flask的session用不了,只能用全局变量来实现。
import pymysql
from flask import Flask, request, jsonify, session
from flask_cors import CORS
from flask import make_response
app = 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'}), 401
finally:
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'}), 400
connection = 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'}), 201
except pymysql.MySQLError as db_err:
return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500
except Exception as e:
return jsonify({'message': '注册失败', 'status': 'fail', 'error': str(e)}), 500
finally:
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'}), 404
finally:
connection.close()
#==========================发布笔记===============================
@app.route('/post_note', methods=['POST'])
def post_note():
global current_user_id
if current_user_id is None:
return jsonify({'message': '未登录', 'status': 'fail'}), 401
data = request.get_json()
print(data)
content = data.get('content')
if not content:
return jsonify({'message': '笔记内容不能为空', 'status': 'fail'}), 400
connection = 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'}), 201
except pymysql.MySQLError as db_err:
return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500
finally:
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)}), 500
finally:
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'}), 400
connection = 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'}), 201
except pymysql.MySQLError as db_err:
return jsonify({'message': '数据库错误', 'status': 'fail', 'error': str(db_err)}), 500
finally:
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' 表存储笔记和用户ID
cursor.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)}), 500
finally:
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, // 选中的笔记ID
comments: [] // 当前笔记的评论列表
},
// 输入笔记内容
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>