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

news2024/10/1 5:39:36

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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2181619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

88E1111使用技巧

一、88E1111简介 88E1111这款芯片是Marvel公司的产品&#xff0c;算是早期产品&#xff0c;但是市面上通用量较高&#xff0c;目前仍在大量使用&#xff0c;当然该公司也推出新产品&#xff0c;如88E1512&#xff0c;后续会有续篇&#xff0c;本篇文章重点讲述88E1111。 88E1…

66 使用注意力机制的seq2seq_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录动机加入注意力总结代码定义注意力解码器训练小结练习 我们来真的看一下实际应用中&#xff0c;key&#xff0c;value&#xff0c;query是什么东西&#xff0c;但是取决于应用场景不同&#xff0c;这三个东西会产生变化。先将放在seq2seq这个…

使用 SSH 连接 Docker 服务器:IntelliJ IDEA 高效配置与操作指南

使用 SSH 连接 Docker 服务器&#xff1a;IntelliJ IDEA 高效配置与操作指南 本文详细介绍了如何在 2375 端口未开放的情况下&#xff0c;通过 SSH 连接 Docker 服务器并在 Idea 中进行开发。通过修改用户权限、生成密钥对以及配置 SSH 访问&#xff0c;用户可以安全地远程操作…

Ubuntu 系统崩了,如何把数据拷下来

问题描述&#xff1a; Linux系统中安装输入法后&#xff0c;重启后&#xff0c;导致系统无法进入&#xff0c;进入 recovery mode下的resume 也启动不了&#xff0c;所以决定将需要的东西复制到U盘 解决方案&#xff1a; 1.重启ubuntu&#xff0c;随即点按Esc进入grub菜单&am…

Linux shell脚本set -e的作用详解

文章目录 功能详细解释示例不使用 set -e 的情况总结 set -e 是一个用于控制脚本行为的命令&#xff0c;它的作用是&#xff1a; 功能 当脚本运行时&#xff0c;set -e 会确保一旦某个命令返回非零的退出状态&#xff08;即执行失败&#xff09;&#xff0c;整个脚本会立即停止…

Docker面试-24年

1、Docker 是什么&#xff1f; Docker一个开源的应用容器引擎&#xff0c;是实现容器技术的一种工具&#xff0c;让开发者可以打包他们的应用以及环境到一个镜像中&#xff0c;可以快速的发布到任何流行的操作系统上。 2、Docker的三大核心是什么? 镜像&#xff1a;Docker的…

在 Kali Linux 中安装 Impacket

步骤 1&#xff1a;更新系统 打开终端并确保你的系统是最新的&#xff1a; sudo apt update && sudo apt upgrade -y 步骤 2&#xff1a;安装依赖 在安装 Impacket 之前&#xff0c;你需要确保安装了 Python 和一些必要的依赖。通常&#xff0c;Kali 已经预装了 Pytho…

工作日志:el-table在无数据情况下,出现横向滚动条。

1、遇到一个警告。 原因&#xff1a;中的组件不能呈现动画的非元素根节点。 也就是说&#xff0c;Transition包裹的必须是一个单根的组件。 2、el-table在无数据情况下&#xff0c;出现横向滚动条&#xff0c;大概跟边框的设置有关系。 开始排查。 给.el-scrollbar加了一个…

Linux 线程同步

前言 上一期我们介绍了线程互斥&#xff0c;并通过加锁解决了多线程并发访问下的数据不一致问题&#xff01;本期我们来介绍一下同步问题&#xff01; 目录 前言 一、线程同步 • 线程同步的引入 • 同步的概念 理解同步和饥饿问题 • 条件变量 理解条件变量 • 同步…

TypeScript 算法手册 【数组基础知识】

文章目录 1. 数组简介1.1 数组定义1.2 数组特点 2. 数组的基本操作2.1 访问元素2.2 添加元素2.3 删除元素2.4 修改元素2.5 查找元素 3. 数组的常见方法3.1 数组的创建3.2 数组的遍历3.3 数组的映射3.4 数组的过滤3.5 数组的归约3.6 数组的查找3.7 数组的排序3.8 数组的反转3.9 …

AI写作赋能数据采集,开启无限可能性

由人工智能 AI 掀起的新一轮科技革命浪潮&#xff0c;正在不断推动社会进步、各行各业升级发展&#xff0c;深刻影响人们的生活方式&#xff0c;引领我们进入一个充满无限可能的新时代。 那么在数据采集方面&#xff0c;人工智能 AI 可以做什么呢&#xff1f; 下面是搜集网络…

开源在线表结构设计工具

Free, simple, and intuitive database design tool and SQL generator. drawDB在线体验 Discord X drawDB DrawDB is a robust and user-friendly database entity relationship (DBER) editor right in your browser. Build diagrams with a few clicks, export sql scri…

若依--文件上传前端

前端 ry的前端文件上传单独写了一个FileUpload.Vue文件。在main.js中进行了全局的注册&#xff0c;可以在页面中直接使用文件上传的组件。全局导入 在main.js中 import 组件名称 from /components/FileUpLoadapp.compoent(组件名称) //全局挂载组件在项目中使用 组件命令 中…

定时器定时中断定时器外部中断

TIM的函数 // 恢复缺省设置 void TIM_DeInit(TIM_TypeDef* TIMx); // 时基单元初始化&#xff0c;第一个参数TIMx选择某个定时器&#xff0c;第二个参数是结构体&#xff0c;包含了配置时基单元的一些参数。 void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDe…

28 Vue3之搭建公司级项目规范

可以看到保存的时候ref这行被提到了最前面的一行 要求内置库放在组件的前面称为auto fix&#xff0c;数组new arry改成了字面量&#xff0c;这就是我们配置的规范 js规范使用的是airbnb规范模块使用的是antfu 组合prettier&eslint airbnb规范&#xff1a; https://github…

《More Effective C++》的学习

引用与指针 没有所谓的null reference reference一定需要代表某个对象&#xff0c;所以C要求reference必须有初值。 QString &s; 使用reference可能比使用pointer更高效。 因为reference一定是有效的&#xff0c;而指针可能为空&#xff08;需要多加一个判断&#xff0…

Springboot3 + MyBatis-Plus + MySql + Vue + ProTable + TS 实现后台管理商品分类(最新教程附源码)

Springboot3 MyBatis-Plus MySql Uniapp 商品加入购物车功能实现&#xff08;针对上一篇sku&#xff09; 1、效果展示2、数据库设计3、后端源码3.1 application.yml 方便 AliOssUtil.java 读取3.2 model 层3.2.1 BaseEntity3.2.1 GoodsType3.2.3 GoodsTypeSonVo3.3 Controll…

论文翻译 | LLaMA-Adapter :具有零初始化注意的语言模型的有效微调

摘要 我们提出了一种轻量级的自适应方法&#xff0c;可以有效地将LLaMA微调为指令遵循模型。lama - adapter采用52K自指导演示&#xff0c;在冻结的LLaMA 7B模型上只引入1.2M可学习参数&#xff0c;在8个A100 gpu上进行微调花费不到一个小时。具体来说&#xff0c;我们采用了一…

Vue3+Antv X6流程图基本使用

安装 antv/X6 npm i antv/x6 <template><div class"homes"><div class"Shang">上</div><div class"Zhong"><div id"container"></div></div><div class"Xia">下<…

wordpress Contact form 7发件人邮箱设置

此教程仅适用于演示站有留言的主题&#xff0c;演示站没有留言的主题&#xff0c;就别往下看了&#xff0c;免费浪费时间。 使用了Contact form 7插件的简站WordPress主题&#xff0c;在有人留言时&#xff0c;就会发邮件到网站的系统邮箱(一般与管理员邮箱为同一个)里。上面显…