python开发基础篇2——登陆机制

news2025/1/21 18:41:37

文章目录

  • 一、管理平台页面布局
  • 二、登录页面
    • 2.1 token登录
    • 2.2. kubeconfig登录
    • 2.3 添加装饰器

一、管理平台页面布局

应用名称:

  1. dashboard:存放公共

  2. k8s:

    • Node:K8s集群计算节点。
    • Namespaces:命名空间,用于隔离资源。
    • PersistentVolumes(PV):持久卷,存储数据
  3. workload:

    • Deployments:无状态应用部署控制器。
    • DaemonSets:守护进程控制器,在每个节点启动一个Pod。
    • StatefulSets:有状态应用部署控制器。
    • Pods:K8s最小部署单元
  4. loadbalancer:

    • Services:为Pod提供服务发现和负载均衡。
    • Ingresses:集群中应用统一入口,对外暴露应用
  5. storage:

    • PersistentVolumeClaims(PVC):持久卷申请,与PV绑定。
    • ConfigMaps:存储配置内容,例如应用程序配置文件。
    • Secrets:存储应用敏感数据,例如用户名密码

二、登录页面

登录认证流程:

  • AJAX提交登录认证数据 到服务端——> 验证提交数据格式合法性(编写一个登录认证检查函数)——> 确认没问题向session里写入认证信息 ——> 返回AJAX,AJAX跳转到首页。
    在这里插入图片描述

2.1 token登录

  • 验证token登录验证逻辑。若输入的token是正确有效的,则会将token写入到数据库中的session保存,方便下次登录。

1.根据布局创建对象的django 应用。

python manage.py startapp dashboard
python manage.py startapp k8s
python manage.py startapp workload
python manage.py startapp loadbalancer
python manage.py startapp storage  

2.启用django默认数据库,用于保存session状态。

python manage.py makemigrations
python manage.py migrate

在这里插入图片描述

3.验证代码。

##########################################################
##自定义模块。
from kubernetes import client,config
import os

#连接k8s验证输入的token或者kubeconfig是否有效。
def auth_check(auth_type,token):
    if auth_type == "token":
        configuration = client.Configuration()
        configuration.host = "https://192.168.161.120:6443"  # APISERVER地址
        # ca_file = os.path.join(os.getcwd(), "ca.crt") # K8s集群CA证书(/etc/kubernetes/pki/ca.crt)
        # configuration.ssl_ca_cert= ca_file
        configuration.verify_ssl = False
        configuration.api_key = {"authorization": "Bearer " + token}   ##固定格式。
        client.Configuration.set_default(configuration)
        apps_api = client.AppsV1Api()
        try:
            core_api = client.CoreApi()
            core_api.get_api_versions()  # 查看8s版本,由此验证是否有效的
            return True
        except Exception as e:
            print(e)
            return False
    elif auth_type == "kubeconfig":
        pass
##########################################################
##视图逻辑。
from django.shortcuts import render
from Layui import k8s  ##导入自定义模块。
from django.http import  JsonResponse

def index(request):
    return render(request,'index.html')

def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        token =request.POST.get("token")
        #处理token登录。
        if token:
            if k8s.auth_check("token",token):  # 如token是有效登录成功
                request.session['is login'] = True
                request.session['auth_type'] = token  # 用于后期前端调用django,django拿这个信息去请k8s api
                request.session['token'] = token
                code = 0
                msg = "登录成功"
            else:
                code = 1
                msg = "Token无效!"
        else:
        #处理kubeconfig文件登录。
            file_obj  = request.FILES.get("file")
        result = {'code': code,'msg': msg}
        return JsonResponse(result)
##########################################################
##子模板文件。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <style>
        /* 整个内容区 */
        body {
            background-color: #edeff0;
        }
        .a {
            width: 900px;
            height: 400px;
            background-color: white;
            /* 定位到中间 */
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
            /* 添加阴影 */
            box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12);
        }
        /* 头部蓝色背景 */
        .c {
            height: 60px;
            width: 900px;
            background-color: #326de6;
            color: white;
            font-size: 20px;
        }
        /* 头部蓝色中文字向右移动并居中*/
        .c p {
            padding-left: 300px;
            padding-top: 12px;
            font-weight: bold;
            font-size: 26px;
            letter-spacing: 1px;
        }
        /* 所有文字右、下移 */
        .d,.e,.f,.g {
            padding-left: 300px;
        }

        /* 给选择按钮加超链接并加粗 */
        .d a, .e a {
            font-weight: bold;
            font-size: 18px;
            text-decoration: none;
        }
        /* 超链接显示处理 */
        a:active, a:link, a:visited, a:hover {color: black}
        /* 文字左、右向内靠拢 */
        .p {
            padding-left: 10px;
            padding-right: 10px;
        }
        /* 实心圆外面圆 */
        .s {
            display: block;
            width: 18px;
            height: 18px;
            border-radius: 20px;
            border: 2px solid gray;
            float: left;  /* 与Token水平 */
            margin-right: 10px;
        }
        /* 实心圆 */
        .ss {
            display: block;
            width: 10px;
            height: 10px;
            background-color: #326de6;
            border-radius: 20px;
            border: 2px solid white;
            /* 上、左移动,让实心圆居中 */
            position: relative;
            top: 13%;
            left: 10%;
        }
        .f, .g {
            display: none;  /* 默认两个input隐藏 */
        }
        .f input {
            width: 500px;
            height: 25px;
            border-style: none;
            border-bottom: 1px solid black;
            outline: none;  /* 点击输入框不显示外边框 */
            margin-top: 10px;
            margin-left: 10px;
        }
        .g input {
            margin-top: 10px;
            margin-left: 10px;
            color: gray;
            outline: none;
        }
        #btn {
            height: 50px;
            width: 150px;
            margin-left: 400px;
            margin-top: 40px;
            border-style: none;
            font-size: 22px;
            background-color: #326de6;
            color: white;
            padding: 8px 15px 8px 15px;
            outline: none;
            box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12);
        }
        #btn:hover {
            cursor: pointer;
        }

    </style>
</head>
<body>
{% csrf_token %}
<div class="a">
    <div class="b">
        <div class="c">
            <p>欢迎访问Kubernetes管理平台</p>
        </div>
        <div>
            <div class="d">
                <p><a href="#" id="tokenBtn"><span class="s" id="s1"><span id="ss1"></span></span>Token</a></p>
                <p class="p"></p>
            </div>
            <div class="e">
                <p><a href="#" id="kubeBtn"><span class="s" id="s2"><span id="ss2"></span></span>Kubeconfig</a></p>
                <p class="p"></p>
            </div>
            <div class="f" id="token">
                <input type="password" name="token" placeholder="输入token" >
            </div>
            <div class="g" id="kube">
                <input type="file" name="kubeconfig" id="kubeconfig">
            </div>
            <p><button type="button" id="btn">登录</button>&nbsp;&nbsp;&nbsp;<span id="notice"></span></p>
        </div>

    </div>
</div>
<script type="text/javascript">
    // 默认选中Toekn认证。
    $("#token").css("display", "inline");  // 显示输入token
    $("#s1").css("border", "2px solid #326de6");  // 边框改为蓝色
    $("#ss1").addClass("ss");  // 添加蓝色实心圆

    $("#tokenBtn").click(function () {
        $("#token").css("display", "inline");  // 显示输入token
        $("#kube").css("display", "none");  // 另外一个隐藏

        $("#s1").css("border", "2px solid #326de6");  // 边框改为蓝色
        $("#s2").css("border", "2px solid gray");  // 另外一个,边框改为灰色

        $("#ss1").addClass("ss");  // 添加蓝色实心圆
        $("#ss2").removeClass("ss");  // 去掉蓝色实心圆
    });
    $("#kubeBtn").click(function () {
        $("#kube").css("display", "inline");   // 显示选择文件框
        $("#token").css("display", "none");  // 另外一个隐藏

        $("#s1").css("border", "2px solid gray");  // 另外一个,边框改为蓝灰色
        $("#s2").css("border", "2px solid #326de6");  // 边框改为蓝色

        $("#ss2").addClass("ss");  // 添加蓝色实心圆
        $("#ss1").removeClass("ss");  // 去掉蓝色实心圆
    });
    $("#btn").click(function () {
        var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
        // 判断选择的认证方式,即有实心圆类
        if ($("#ss1").hasClass("ss")) {
            var token = $("input[name='token']").val();
            // 判断输入是否为空
            if (! token) {
                $("#notice").html("请输入Token!").css("color", "red");
                return
            }
            var data = {'token': token, 'csrfmiddlewaretoken': csrf_token};
            $.ajax({
                type: "POST",
                url: "/login/",
                timeout: 5000,
                dataType: "json",
                data: data,
                success: function(res) {
                    if (res.code == 0) {
                        location.href = "/"
                    } else if (res.code == 1){
                        $("#notice").html(res.msg).css("color", "red");
                    }
                },
                error: function (res) {
                    $("#notice").html("服务器接口异常!").css("color", "red");
                }
            })
        } else if ($("#ss2").hasClass("ss")) {
            var fd = new FormData();
            // var file = $("input[name='kubeconfig']")[0].files[0]);
            var file = $("#kubeconfig")[0].files[0];
            if (! file) {
                $("#notice").html("请选择kubeconfig文件!").css("color", "red");
                return
            }
            fd.append('file', file);
            fd.append("csrfmiddlewaretoken", csrf_token);
            $.ajax({
                type: "POST",
                url: "/login/",
                timeout: 5000,
                dataType: "json",
                data: fd,
                processData: false,
                contentType: false,
                success: function(res) {
                    if (res.code == 0) {
                        location.href = "/"
                    } else if (res.code == 1){
                        $("#notice").html(res.msg).css("color", "red");
                    }
                },
                error: function () {
                    $("#notice").html("服务器接口异常!").css("color", "red");
                }
            })
        }
    })
</script>
</body>
</html>
##########################################################
##母版文件。
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>{% block title %}{% endblock %}</title>
  <link rel="stylesheet" href="/static/layui/css/layui.css">
</head>
<div style="width: 100px;height: 100px;background-color: oldlace;display: none" id="qingjun">
</div>

<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header layui-bg-cyan">
    <div class="layui-logo layui-hide-xs layui-bg-cyan">DevOps管理平台</div>
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="/logout">
          <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          退出
        </a>
        <!--
        <dl class="layui-nav-child">
          <dd><a href="">Your Profile</a></dd>
          <dd><a href="">Settings</a></dd>
          <dd><a href="">Sign out</a></dd>
        </dl>
        -->
      </li>
        <!--
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
        -->
    </ul>
  </div>

  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll layui-bg-cyan">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul class="layui-nav layui-nav-tree layui-bg-cyan" lay-filter="test">
        <li class="layui-nav-item">
          <a class="" href="/"><i class="layui-icon layui-icon-home" style="color: #00FFFF;font-size: 20px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;仪表盘</i></a>
        </li>

        <li class="layui-nav-item {% block item-1 %}{% endblock %}">
          <a class="" href="javascript:;"><i class="layui-icon layui-icon-app" style="color: #01AAED;font-size: 15px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kubernetes</i></a>
          <dl class="layui-nav-child">
            <dd><a href="{% url 'node' %}" class="{% block item-1-1 %}{% endblock %}">Node</a></dd>
            <dd><a href="{% url 'namespace' %}" class="{% block item-1-2 %}{% endblock %}">NameSpace</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item {% block item-2 %}{% endblock %}">
          <a href="javascript:;"><i class="layui-icon layui-icon-template-1" style="color: #01AAED;font-size: 15px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Workload</i></a>
          <dl class="layui-nav-child">
            <dd><a href="{% url 'deployment' %}" class="{% block item-2-1 %}{% endblock %}">Deployment</a></dd>
            <dd><a href="{% url 'daemonset' %}" class="{% block item-2-2 %}{% endblock %}">DaemonSet</a></dd>
{#            <dd><a href="">超链接</a></dd>#}
          </dl>
{#        </li>#}
{#        <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>#}
{#        <li class="layui-nav-item"><a href="">the links</a></li>#}
      </ul>
    </div>
  </div>

  <div class="layui-body" style="background-color: #cccccc">
    <!-- 内容主体区域 -->
    <div style="padding: 15px;">{% block context%}{% endblock %}</div>
  </div>

  <div class="layui-footer" style="text-align: center">
    <!-- 底部固定区域 -->
    k8s管理平台
  </div>
</div>
<script src="/static/layui/layui.js"></script>
{% block custom_js %}{% endblock %}
<script>
//JS
layui.use(['element', 'layer', 'util'], function(){
  var element = layui.element
  ,layer = layui.layer
  ,util = layui.util
  ,$ = layui.$;

  //头部事件
  util.event('lay-header-event', {
    //左侧菜单事件
    menuLeft: function(othis){
      layer.msg('展开左侧菜单的操作', {icon: 0});
    }
    ,menuRight: function(){
      layer.open({
        type: 1
        ,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
        ,area: ['260px', '100%']
        ,offset: 'rt' //右上角
        ,anim: 5
        ,shadeClose: true
      });
    }
  });

});
</script>
</body>
</html>

4.token验证,查看数据库是否保存了token信息。
在这里插入图片描述
在这里插入图片描述
5.验证数据库中的session保存的返回信息。
在这里插入图片描述

2.2. kubeconfig登录

  • 验证使用正确的kubeconfig文件登录,则会登录到主页。

1.自定义一个类,在数据库中创建一张表,用于保存kubeconfig文件内容。

#######################################################
##生成一张数据库表,用于保存kubeconfig文件内容。dasshboard/models下定义一个类。
from django.db import models
class User(models.Model):
    auth_type = models.CharField(max_length=30)
    token = models.CharField(max_length=100)
    content = models.TextField()
    datetime = models.DateTimeField(auto_now=True)
#######################################################
##同步数据库。settings文件添加如下一行。
INSTALLED_APPS = [
     ......
    'dashboard'
]

python manage.py makemigrations
python manage.py migrate

在这里插入图片描述
2.添加视图。

import requests
from django.shortcuts import render,redirect
from Layui import k8s  ##导入自定义模块。
from django.http import  JsonResponse
from  dashboard.models import User
def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        token =request.POST.get("token")
        #处理token登录。
        if token:
            if k8s.auth_check("token",token):  # 如token是有效登录成功
                request.session['is_login'] = True
                request.session['auth_type'] = 'token'  # 用于后期前端调用django,django拿这个信息去请k8s api
                request.session['token'] = token
                code = 0
                msg = "登录成功"
            else:
                code = 1
                msg = "Token无效!"
        else:
           #处理kubeconfig文件登录。
            file_obj  = request.FILES.get("file")
            import random
            token_random = str(random.random()).split('.')[1]  ##生成一个随机数作为标识。
            try:
                content = file_obj.read().decode()  ##bytes ——> str
                User.objects.create(
                    auth_type="kubeconfig",
                    token=token_random,
                    content=content
                )
                code = 0
                msg = "登陆成功"
            except Exception:
                code = 1
                msg = "kubeconfig文件错误!"
            if k8s.auth_check('kubeconfig',token_random):
                request.session['is_login'] = True
                request.session['auth_type'] = 'kubeconfig'  # 用于后期前端调用django,django拿这个信息去请k8s api
                request.session['token'] = token_random
                code = 0
                msg = "登陆成功"
            else:
                User.objects.get(token=token_random).delete()
                code = 1
                msg = "kubeconfig文件无效!!!"
        result = {'code': code,'msg': msg}
        return JsonResponse(result)

3.修改自定义模块类。

from kubernetes import client,config
import os
from dashboard.models import User
import yaml

# 连接k8s验证输入的token或者kubeconfig是否有效。
def auth_check(auth_type,token=None):
    if auth_type == "token":
        configuration = client.Configuration()
        configuration.host = "https://192.168.161.120:6443"  # APISERVER地址
        # ca_file = os.path.join(os.getcwd(), "ca.crt") # K8s集群CA证书(/etc/kubernetes/pki/ca.crt)
        # configuration.ssl_ca_cert= ca_file
        configuration.verify_ssl = False
        configuration.api_key = {"authorization": "Bearer " + token}   ##固定格式。
        client.Configuration.set_default(configuration)
        apps_api = client.AppsV1Api()
        try:
            core_api = client.CoreApi()
            core_api.get_api_versions()  # 查看8s版本,由此验证是否有效的
            return True
        except Exception as e:
            print(e)
            return False
    elif auth_type == "kubeconfig":
        user = User.objects.get(token=token)
        content = user.content
        yaml_content = yaml.load(content, Loader=yaml.FullLoader) ##yaml文件转为json
        print(yaml_content)
        try:
            config.load_kube_config_from_dict(yaml_content)
            core_api = client.CoreApi()
            core_api.get_api_versions()   # 查看k8s版本,由此验证是否有效的
            return True
        except Exception as e:
            print(e)
            return False

4.使用正确的Kubeconfig文件登陆成功,其他文件登陆失败。
在这里插入图片描述
在这里插入图片描述

2.3 添加装饰器

  • 引用装饰器,使得访问127.0.0.1:8000也是登录页面,而不是首页。

1.在自定义模块文件中添加。

from   django.shortcuts import redirect
def self_login_required(func):
    def inner(request, *args, **kwargs):
        is_login = request.session.get('is_login', True)
        if is_login:
            return func(request, *args, **kwargs)
        else:
            return redirect("/login")
    return inner

2.首页引用装饰器。

@k8s.self_login_required
def index(request):
    return render(request,'index.html')

3.查看效果。
在这里插入图片描述

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

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

相关文章

ABAP WS_DELIVERY_UPDATE 报错 BS013

在使用 WS_DELIVERY_UPDATE 创建内向交货单时 报错&#xff1a;System status ESTO is active (EQU ***) 可以用事务代码IE03--->历史去看下 你可以手动将它的状态去改回EDEL 或者 SLOR IE02--> Special serial no. functions --> Manual transaction.

C#,《小白学程序》第十七课:随机数(Random)第四,移动平均值(Moving Average)的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十七课&#xff1a;随机数&#xff08;Random&#xff09;第四&#xff0c;移动平均值的计算方法与代码 /// 继续学习数据统计&#xff0c;移动平均值的计算方法 /// 移动平均值就是一定步长内数值的平均值&#xff0c;用…

Llama 2 论文《Llama 2: Open Foundation and Fine-Tuned Chat Models》阅读笔记

文章目录 Llama 2: Open Foundation and Fine-Tuned Chat Models1.简介2.预训练2.1 预训练数据2.2 训练详情2.3 LLAMA 2 预训练模型评估 3. 微调3.1 supervised Fine-Tuning(SFT)3.2 Reinforcement Learning with Human Feedback (RLHF)3.2.1 人类偏好数据收集3.2.2 奖励模型训…

Matlab 如何选择窗函数和 FFT 的长度

Matlab 如何选择窗函数和 FFT 的长度 1、常用的四种窗函数 对于实际信号序列&#xff0c;如何选取窗函数呢&#xff1f;一般来说&#xff0c;选择第一旁瓣衰减大&#xff0c;旁瓣峰值衰减快的窗函数有利于緩解截断过程中产生的頻泄漏问题。但具有这两个特性的窗函数&#xff0…

[BFS] 广度优先搜索

1. 数字操作 常见的模板 // 使用一个数组判断元素是否入过队 int inqueue[N] {0}; // 层数或者可以称为深度 int step 0; // 判断是否可以入队的条件 int isvalid(){ } BFS(int x){ // 将初始的元素压入队列 // 注意每次压队的时候都要将inque[x] 1,表明入队过…

python实现adb辅助点击屏幕工具

#!/usr/bin/env python # -*- coding: utf-8 -*-import re import os import time import subprocess import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk# 设置ADB路径&#xff08;根据你的系统和安装路径进行调整&#xff09; ADB_PATH C…

Ubuntu快速搭建内网NTP Server

文章目录 安装NTP服务配置NTP配置NTP 同步源配置NTP 允许客户端访问重启NTP服务使得配置生效 推荐阅读 NTP(Network Time Protocol)------网络时间协议-----应用层协议&#xff0c;用来在分布式时间服务器和客户端之间进行时间同步。 是对网络内所有具有时钟的设备进行时钟同步…

图解 LeetCode 算法汇总——链表

本文首发公众号&#xff1a;小码A梦 一般数据主要存储的形式主要有两种&#xff0c;一种是数组&#xff0c;一种是链表。数组是用来存储固定大小的同类型元素&#xff0c;存储在内存中是一片连续的空间。而链表就不同于数组。链表中的元素不是存储在内存中可以是不连续的空间。…

酒店类型的软文怎么写?

马上就放长假了&#xff0c;有不少酒店行业来找盒子做推广&#xff0c;其实酒店行业想要写好软文只要掌握三种类型就好了&#xff0c;今天就让盒子告诉大家酒店类型的软文怎么写才能吸引用户。 一、以故事打动用户 故事型软文大多用于民宿酒店&#xff0c;民宿酒店文案除了展现…

Docker认识即安装

Docker及相关概念 Docker和虚拟机方式的区别&#xff1a;虚拟机技术是虚拟出一套硬件后&#xff0c;在其上运行一个完整的操作系统&#xff0c;在该系统上在运行所需应用进程&#xff1b;而容器内的应用进程是直接运行于宿主的内核&#xff0c;容器内没有自己的内核&#xff0…

2023区块链应用操作员认证(4级)报名来弘博创新

区块链应用操作员&#xff0c;是指运用区块链技术及工具&#xff0c;从事政务、金融、医疗、教育、养老等场景系统应用操作的人员。 腾讯作为广东省第一批公布的社会培训评价组织&#xff0c;可开展职业技能等级认定职业(工种)区块链应用操作员(4-3-2-1级)。 证书含金量 证书是…

小节4:input()函数的一些讲究

千万注意&#xff1a;不管用户输入的是什么&#xff0c;input()返回的一律都是字符串&#xff0c;代码如下&#xff1a; user_input input("Please input something: ") print(type(user_input)) 所以&#xff0c;如果直接拿用户输入的内容去做数学运算&#xff0c…

JavaScript 之 常用迭代方法forEach、filter()、map()、reduce()

JavaScript 之 常用迭代方法forEach、filter、map、reduce 1. for、forEach1.1 for 遍历的3种写法1.2 forEach 回调函数 遍历1.3 forEach 箭头函数 遍历 2. filter()2.1 介绍2.2 例子1——简单过滤2.3 例子2——在修改数组时 filter() 方法的行为2.4 例子3——在数组中搜索 3…

生成式 AI 中的风险认知

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 直到几年前&#xff0c;你能想象一台机器可以创造艺术、制作故事&#xff0c;甚至理解复杂的数据&#xff0c;如医疗和法律文件吗&#xff1f; 应该不会。对于我们大多数人来说&#xff0c;它仅限于一部看似牵强附会的…

博客系统项目

文章目录 数据库的增删改查草稿箱草稿箱自动保存分页查询后端前端 评论区后端前端 md5加盐加密 md5加盐对用户密码进行加密; 全服用户博客列表页,实现分页查询; 用户博客列表页; 写博客,发博客,改博客; 博客草稿箱,自动保存,定时发布; 博客访问量,博客评论区,博客点赞; 数据库…

MojoTween:使用「Burst、Jobs、Collections、Mathematics」优化实现的Unity顶级「Tween动画引擎」

MojoTween是一个令人惊叹的Tween动画引擎&#xff0c;针对C#和Unity进行了高度优化&#xff0c;使用了Burst、Jobs、Collections、Mathematics等新技术编码。 MojoTween提供了一套完整的解决方案&#xff0c;将Tween动画应用于Unity Objects的各个方面&#xff0c;并可以通过E…

恒运资本:人民币汇率何时走出低谷?

9月7日&#xff0c;国家外汇管理局发布统计数据显现&#xff0c;到2023年8月末&#xff0c;我国外汇储藏规划为31601亿美元&#xff0c;较7月末下降442亿美元&#xff0c;降幅为1.38%。 国家外汇管理局相关负责人表明&#xff0c;2023年8月&#xff0c;受首要经济体微观经济数…

《机器人学一(Robotics(1))》_台大林沛群 第 7 周 【轨迹规划_综合】Quiz 7

题 4-5 存疑&#xff0c;仅供参考&#xff0c;欢迎交流 文章目录 题4-9&#xff1a;题4-5求解代码&#xff1a; Python题6-7求解代码&#xff1a; Python求解 θ4-θ6 时&#xff0c; 记得 将 R 改成相应的&#xff01;&#xff01;&#xff01;&#xff01; 题8-9求解代码&…

深浅拷贝与赋值

数据类型 数据类型 在JavaScript中&#xff0c;数据类型有两大类。一类是基本数据类型&#xff0c;一类是引用数据类型。 基本数据类型有六种&#xff1a;number、string、boolean、null、undefined、symbol。 基本数据类型存放在栈中。存放在栈中的数据具有数据大小确定&a…

2023高教社杯数学建模B题思路代码 - 多波束测线问题

# 1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀 速直线传播&#xff0c; 在不同界面上产生反射&#xff0c; 利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信 号&#xff0c;并记录从声波发射到…