资产信息管理系统-前后端开发

题目要求:

资产管理系统

利用H5规范,CSS样式与JS脚本独立于HTML页面,Javascript调用jQuery库,CRUD后端使用FastAPI封装,前端页面在Nginx中运行,调用API模块, 实现CURD的课设总结

基本设计:

后端:

前后端的对接可以通过 FastAPI 框架提供的 API 接口实现。
第一,在后端部分,使用 FastAPI 构建了一个封装了 CRUD 操作的 API 服务器。这个服务器可以接收来自前端的请求,并根据请求中的操作类型(如 POST、GET、PUT、DELETE 等)和数据来执行相应的操作。前端部分通过使用 HTML、CSS 和 JS 等技术构建了用户界面,包括 CRUD 操作的界面。这些界面可以通过浏览器或 Nginx 服务器提供给用户使用。

在前后端对接的过程中,前端页面可以通过 AJAX 或 Fetch API 等技术向 API 服务器发送请求。API 服务器接收请求后,根据请求中的操作类型和数据执行相应的操作,然后将结果返回给前端。前端接收到结果后,可以根据结果更新页面或做出相应的响应。



综上,通过 FastAPI 框架提供的 API 接口实现了前后端的对接。前端发送请求给 API 服务器,API 服务器处理请求并返回结果给前端,从而实现了前后端的交互和数据管理。

数据库:

资产表(Assets):
资产ID(AssetID):主键,自增长,类型为整数
资产名称(AssetName):资产名称,类型为字符串,长度为255
资产类型(AssetType):资产类型,类型为字符串,长度为50
购买日期(PurchaseDate):购买日期,类型为日期
购买价格(PurchasePrice):购买价格,类型为数值型,精度为两位小数
资产状态(AssetStatus):资产状态,类型为字符串,长度为50
其他相关字段...
用户表(Users):
用户ID(UserID):主键,自增长,类型为整数
用户名(Username):用户名,类型为字符串,长度为255
密码(Password):密码,类型为字符串,长度为255
姓名(Name):姓名,类型为字符串,长度为100
邮箱(Email):邮箱,类型为字符串,长度为100
其他相关字段...
操作记录表(OperationRecords):
记录ID(RecordID):主键,自增长,类型为整数
用户ID(UserID):操作用户ID,类型为整数
操作类型(OperationType):操作类型,类型为字符串,长度为50
操作时间(OperationTime):操作时间,类型为时间戳
其他相关字段...
main.py:

# -*-coding:utf-8-*-
from fastapi import FastAPI, HTTPException, Depends, Form
from starlette.middleware.cors import CORSMiddleware

from user import user_router
from asset import asset_router
from operation import op_router
import uvicorn

app = FastAPI()
#三个路由,模块化,对应各自的路由
app.include_router(user_router, prefix='/user')
app.include_router(asset_router, prefix='/asset')
app.include_router(op_router, prefix='/operation')

# 添加跨域访问中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://127.0.0.1"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

if __name__ == '__main__':
    uvicorn.run(app)

user.py:

# -*-coding:utf-8-*-
from datetime import datetime
from fastapi import APIRouter, Query, Depends, Response
from pydantic import BaseModel
from sqlalchemy import select, func
from sqlalchemy.orm import Session

from tool import *
from model import User

#验证请求参数是否正确
class UserParam(BaseModel):
    username: str
    phone: str
    birth: str
    email: str
    asset_count: int


user_router = APIRouter()

#请求到user/list则执行该函数
@user_router.get('/list')#分页:
def get_user_list(page: int = Query(1), keyword: str = Query(None), limit: int = Query(15),
                  dbs: Session = Depends(get_db)):
#以下通过dbs操作数据库
    if keyword is None:
        query = dbs.query(User)#是空,则声明一个查询
    else:
        query = dbs.query(User).filter((User.username.ilike(f"%{keyword}%")))
    total_count = query.with_entities(func.count(User.user_id)).scalar()
#统计数据经行分页
    return {'code': 0, 'data': query.offset((page - 1) * limit).limit(limit).all(), 'count': total_count}
#线偏移,限制和所有结果
#请求post路径时,参数和数据在UserParam请求体中,相对get来说更安全一些,且数据没有上限,而get有上限
@user_router.post('/add')
def add_user(user: UserParam, dbs: Session = Depends(get_db)):
    try:

        new_user = User(**user.model_dump())
#**代表解包,user.model_dump()整体代表字典
#解包:a(**{'a':1})==a(a==1)
#创建一个新操作保存操作记录
        new_operation = OperationRecord(
            **{"user_id": new_user.user_id, "username": new_user.username, "operation_type": "添加用户",
               "operation_time": datetime.now()})
        for key, value in user.model_dump().items():
#判断是否是日期的格式,如果是则转换成datatime对象
            if key == 'birth':
                setattr(new_user, key, datetime.strptime(value, '%Y-%m-%d'))
            else:
                setattr(new_user, key, value)
        dbs.add(new_user)
        dbs.flush()#刷新
        dbs.add(new_operation)
        dbs.commit()
        return {'code': 0}#正确
    except Exception:
        return Response(status_code=404)

#路径/user/modify?user_id=2
#此处与之前相比多了一个user_id参数
@user_router.post('/modify')
def modify_user(user: UserParam, user_id: int = Query(...), dbs: Session = Depends(get_db)):
    try:
        user_modify = dbs.query(User).filter(User.user_id == user_id).first()
#用user_id查询
        new_operation = OperationRecord(
            **{"user_id": user_modify.user_id, "username": user_modify.username, "operation_type": "修改用户",
               "operation_time": datetime.now()})
        if user_modify is None:
            raise HTTPException(status_code=404, detail="User not found")
        for key, value in user.model_dump().items():
            if 'birth' == key:
                setattr(user_modify, key, datetime.strptime(value, '%Y-%m-%d'))
            else:
                setattr(user_modify, key, value)
        dbs.add(new_operation)
        dbs.commit()#直接提交到数据库
        return {'code': 0}#正确结束
    except Exception:
        return Response(status_code=404)

@user_router.get('/del')
#...代表必要要有query,否则返回错误,即:不可以/user/del直接请求,而是/user/del?user_id=
def del_user(user_id: int = Query(...), dbs: Session = Depends(get_db)):
    db_user = dbs.query(User).filter(User.user_id == user_id).first()

    new_operation = OperationRecord(
        **{"user_id": db_user.user_id, "username": db_user.username, "operation_type": "删除用户",
           "operation_time": datetime.now()})
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    dbs.delete(db_user)
    dbs.add(new_operation)
    dbs.commit()
    return {'code': 0}

 tool.py:

# -*-coding:utf-8-*-
from datetime import timedelta, datetime
from typing import Optional

from fastapi import Cookie, HTTPException, Header
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from model import *

# 在数据库中创建表
Base.metadata.create_all(engine)#engine相当于数据库
session_maker = sessionmaker(autocommit=False, autoflush=False, bind=engine)
#返回一个数据库操作接口

def get_db():
    db = session_maker()#数据库库接口
    try:
        yield db
    finally:
        db.close()

 model.py:

# -*-coding:utf-8-*-
from sqlalchemy import create_engine, Column, Integer, String, Numeric, Date, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
#该orm框架应用很广泛
# 创建数据库连接
engine = create_engine('sqlite:///shiyan.db')
#创建引擎
# 创建一个基类
Base = declarative_base()

#创建表的类后不需要用sql语句创建
# 定义用户表(Users)
class User(Base):#三个表继承基类创建
    __tablename__ = 'users'

    user_id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(255))
    phone = Column(String(255))
    birth = Column(Date)
    email = Column(String(100))
    asset_count = Column(Integer)


# 定义资产表(Assets)
class Asset(Base):
    __tablename__ = 'assets'
    asset_id = Column(Integer, primary_key=True, autoincrement=True)
    asset_name = Column(String(255))
    asset_type = Column(String(50))
    purchase_date = Column(Date)
    purchase_price = Column(Numeric(10, 2))
    asset_status = Column(String(50))
    user_id = Column(Integer, ForeignKey('users.user_id'))#外键


# 定义操作记录表(OperationRecords)
class OperationRecord(Base):
    __tablename__ = 'operation_records'

    record_id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, nullable=True)
    username = Column(String(255), nullable=True)
    asset_id = Column(Integer, nullable=True)
    asset_name = Column(String(255), nullable=True)
    operation_type = Column(String(50))
    operation_time = Column(DateTime)

asset.py:

# -*-coding:utf-8-*-
from datetime import datetime
from fastapi import APIRouter, Query, Depends, Response
from pydantic import BaseModel
from sqlalchemy import select, func
from sqlalchemy.orm import Session

from tool import *
from model import Asset


class AssetParam(BaseModel):
    asset_name: str
    asset_type: str
    purchase_date: str
    purchase_price: str
    asset_status: str
    user_id: int


asset_router = APIRouter()


@asset_router.get('/list')
def get_asset_list(page: int = Query(1), limit: int = Query(15), keyword: str = Query(None),
                   dbs: Session = Depends(get_db)):
    if keyword is None:
        query = dbs.query(Asset.asset_id, Asset.asset_name, Asset.asset_type, Asset.asset_status, Asset.purchase_date,
                          Asset.purchase_price, User.user_id, User.username).where(Asset.user_id == User.user_id)
    else:
        query = dbs.query(Asset.asset_id, Asset.asset_name, Asset.asset_type, Asset.asset_status, Asset.purchase_date,
                          Asset.purchase_price, User.user_id, User.username).where(
            Asset.user_id == User.user_id).filter((Asset.asset_name.ilike(f"%{keyword}%")))#ilike模糊查询
    total_count = query.with_entities(func.count(Asset.asset_id)).scalar()

    return {'code': 0, 'data': query.offset((page - 1) * limit).limit(limit).all(), 'count': total_count}


@asset_router.post('/add')
def add_user(asset: AssetParam, dbs: Session = Depends(get_db)):
    try:
        new_asset = Asset(**asset.model_dump())
        user_modify = dbs.query(User).filter(User.user_id == asset.user_id).first()

        if user_modify is not None:
            for key, value in asset.model_dump().items():
                if 'date' in key:
                    setattr(new_asset, key, datetime.strptime(value, '%Y-%m-%d'))
                else:
                    setattr(new_asset, key, value)
            new_operation = OperationRecord(
                **{"user_id": user_modify.user_id, "username": user_modify.username, "asset_id": new_asset.asset_id,
                   "asset_name": new_asset.asset_name, "operation_type": "添加资产", "operation_time": datetime.now()})
            user_modify.asset_count += 1#资产增加了对应的用户的资产数量也增加
            dbs.add(new_asset)
            dbs.add(new_operation)
            dbs.commit()
            return {'code': 0}
        else:
            return Response(status_code=404)
    except Exception:
        return Response(status_code=404)


@asset_router.post('/modify')
def modify_asset(asset: AssetParam, asset_id: int = Query(...), dbs: Session = Depends(get_db)):
    try:
        asset_modify = dbs.query(Asset).filter(Asset.asset_id == asset_id).first()
        old_user_modify = dbs.query(User).filter(User.user_id == asset_modify.user_id).first()
        new_user_modify = dbs.query(User).filter(User.user_id == asset.user_id).first()

        if asset_modify is None or new_user_modify is None:
            raise HTTPException(status_code=404, detail="Asset not found")
        for key, value in asset.model_dump().items():
            if 'date' in key:
                setattr(asset_modify, key, datetime.strptime(value, '%Y-%m-%d'))
            else:
                setattr(asset_modify, key, value)
        new_operation = OperationRecord(
            **{"user_id": old_user_modify.user_id, "username": old_user_modify.username,
               "asset_id": asset_modify.asset_id,
               "asset_name": asset_modify.asset_name, "operation_type": "修改资产", "operation_time": datetime.now()})

        old_user_modify.asset_count -= 1#资产拥有者改变,相应的拥有者资产数量改变
        new_user_modify.asset_count += 1
        dbs.add(new_operation)
        dbs.commit()
        return {'code': 0}
    except Exception:
        return Response(status_code=404)


@asset_router.get('/sell')
def sell_user(asset_id: int = Query(...), dbs: Session = Depends(get_db)):
    db_asset = dbs.query(Asset).filter(Asset.asset_id == asset_id).first()
    user_modify = dbs.query(User).filter(User.user_id == db_asset.user_id).first()

    if db_asset is None:
        raise HTTPException(status_code=404, detail="Asset not found")
    new_operation = OperationRecord(
        **{"user_id": user_modify.user_id, "username": user_modify.username, "asset_id": db_asset.asset_id,
           "asset_name": db_asset.asset_name, "operation_type": "售出资产", "operation_time": datetime.now()})
    user_modify.asset_count -= 1
    dbs.delete(db_asset)
    dbs.add(new_operation)
    dbs.commit()
    return {'code': 0}

operation.py:

# -*-coding:utf-8-*-
from fastapi import APIRouter, Query, Depends
from sqlalchemy import select, func
from sqlalchemy.orm import Session

from tool import *
from model import *

op_router = APIRouter()


@op_router.get('/list')
def get_op_list(page: int = Query(1), limit: int = Query(15), dbs: Session = Depends(get_db)):
    query = dbs.query(OperationRecord)
    total_count = query.with_entities(func.count(OperationRecord.record_id)).scalar()
    return {'code': 0, 'data': query.offset((page - 1) * limit).limit(limit).all(), 'count': total_count}

资产表页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>layui</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
    <link rel="stylesheet" href="../css/public.css" media="all">
</head>
<body>
<div class="layuimini-container">
    <div class="layuimini-main">

        <fieldset class="table-search-fieldset">
            <legend>搜索信息</legend>
            <div style="margin: 10px 10px 10px 10px">
                <form class="layui-form layui-form-pane" action="">
                    <div class="layui-form-item">
                        <div class="layui-inline">
                            <label class="layui-form-label">名称</label>
                            <div class="layui-input-inline">
                                <input type="text" name="name" autocomplete="off" class="layui-input">
                            </div>
                        </div>


                        <div class="layui-inline">
                            <button type="submit" class="layui-btn layui-btn-primary" lay-submit
                                    lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索
                            </button>
                        </div>
                    </div>
                </form>
            </div>
        </fieldset>

        <script type="text/html" id="toolbarDemo">
            <div class="layui-btn-container">
                <button class="layui-btn layui-btn-normal layui-btn-sm data-add-btn" lay-event="add"> 添加</button>
            </div>
        </script>

        <table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>

        <script type="text/html" id="currentTableBar">
            <a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="edit">编辑</a>
            <a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">售出</a>
        </script>

    </div>
</div>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
    layui.use(['form', 'table'], function () {
        var $ = layui.jquery,
            form = layui.form,
            table = layui.table;

        table.render({
            elem: '#currentTableId',
            url: 'http://127.0.0.1:8000/asset/list',
            toolbar: '#toolbarDemo',
            defaultToolbar: ['filter', 'exports', 'print', {
                title: '提示',
                layEvent: 'LAYTABLE_TIPS',
                icon: 'layui-icon-tips'
            }],
            cols: [[
                {type: "checkbox", width: 50},
                {field: 'asset_id', width: 80, title: 'ID', sort: true},
                {field: 'asset_name', width: 100, title: '资产名称'},
                {field: 'asset_type', width: 100, title: '资产类型', sort: true},
                {field: 'purchase_date', width: 150, title: '购买日期', sort: true},
                {field: 'purchase_price', title: '购买单价', width: 100, sort: true},
                {field: 'asset_status', title: '购买数量', width: 100, sort: true},
                {field: 'user_id', title: '所属用户ID', width: 100},
                {field: 'username', title: '所属用户名称', width: 150},
                {title: '操作', width: 250, toolbar: '#currentTableBar', align: "center"}
            ]],
            limits: [10, 15, 20, 25, 50, 100],
            limit: 15,
            page: true,
            skin: 'line'
        });

        // 监听搜索操作
        form.on('submit(data-search-btn)', function (data) {

            //执行搜索重载
            table.reload('currentTableId', {
                page: {
                    curr: 1
                }
                , where: {
                    keyword: data.field.name
                }
            }, 'data');

            return false;
        });

        /**
         * toolbar监听事件,点击按钮时触发
         */
        table.on('toolbar(currentTableFilter)', function (obj) {
            if (obj.event === 'add') {  // 监听添加操作
                var index = layer.open({
                    title: '添加资产',
                    type: 2,
                    shade: 0.2,
                    maxmin: true,
                    shadeClose: true,
                    area: ['90%', '90%'],
                    content: '../page/table/edit-asset.html',#打开修改资产网页
                });
                $(window).on("resize", function () {
                    layer.full(index);
                });
            }
        });

        table.on('tool(currentTableFilter)', function (obj) {
            var data = obj.data;
            if (obj.event === 'edit') {

                var index = layer.open({
                    title: '编辑资产',
                    type: 2,
                    shade: 0.2,
                    maxmin: true,
                    shadeClose: true,
                    area: ['90%', '90%'],
                    content: '../page/table/edit-asset.html',
                    success: function (layero, index) {
                        let body = layer.getChildFrame('body', index);
                        body.find("#asset_id").val(data.asset_id);
                        body.find("#asset_name").val(data.asset_name);
                        body.find("#asset_type").val(data.asset_type);
                        body.find("#purchase_date").val(data.purchase_date);
                        body.find("#purchase_price").val(data.purchase_price);
                        body.find("#asset_status").val(data.asset_status);
                        body.find("#user_id").val(data.user_id);
                        layui.form.render();
                    },
                    end: function () {//重载表格
                        table.reload('currentTableId', {
                            page: {
                                curr: 1
                            }
                            , where: {}
                        }, 'data');
                        return false;
                    }
                });
                $(window).on("resize", function () {
                    layer.full(index);
                });
                return false;
            } else if (obj.event === 'delete') {
                layer.confirm('真的售出资产吗', function (index) {
                    $.ajax({
                        url: 'http://127.0.0.1:8000/asset/sell?asset_id=' + data.asset_id,
                        method: 'GET',
                        success: function (response) {
                            obj.del();
                            layer.close(index);
                        },
                        error: function (error) {
                            layer.alert(error);
                        }
                    });
                });
            }
        });

    });
</script>

</body>
</html>

资产编辑页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>layui</title>
    <meta name="renderer" content="webkit">//用webkit引擎渲染
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
//提示浏览器用最新的渲染模式
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../../lib/layui-v2.6.3/css/layui.css" media="all">
    <link rel="stylesheet" href="../../css/public.css" media="all">
    <style>
        body {
            background-color: #ffffff;//设置网页背景为白色
        }
    </style>
</head>
<body>
<div class="layui-form layuimini-form">
    <div class="layui-form-item">
        <div class="layui-input-block">
            <input type="number" name="asset_id" value="-1" class="layui-input" style="display: none"
                   id="asset_id">
        </div>
    </div>
    <div class="layui-form-item required">
        <label class="layui-form-label required">资产名</label>
        <div class="layui-input-block">
            <input type="text" name="asset_name" lay-verify="required"
                   placeholder="请输入资产名" value="" class="layui-input" id="asset_name">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label required">资产类型</label>
        <div class="layui-input-block">
            <input type="text" name="asset_type" lay-verify="required" placeholder="请输入资产类型"
                   value="" class="layui-input" id="asset_type">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label required">购买日期</label>
        <div class="layui-input-block">
            <input type="date" name="purchase_date" placeholder="请选择购买日期" value=""
                   class="layui-input" lay-verify="required" id="purchase_date">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label required">购买价格</label>
        <div class="layui-input-block">
            <input type="text" name="purchase_price" placeholder="请输入购买价格" lay-verify="required" value=""
                   class="layui-input" id="purchase_price">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label required">资产状态</label>
        <div class="layui-input-block">
            <input type="text" name="asset_status" placeholder="请输入资产状态" lay-verify="required"
                   class="layui-input" id="asset_status">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label required">所属用户</label>
        <div class="layui-input-block">
            <input type="number" name="user_id" placeholder="请输入资产所属用户" lay-verify="required"
                   class="layui-input" id="user_id">
        </div>
    </div>
    <div class="layui-form-item">
        <div class="layui-input-block">
            <button class="layui-btn layui-btn-normal" lay-submit lay-filter="saveBtn">确认保存</button>
        </div>
    </div>
</div>
</div>
<script src="../../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
    layui.use(['form'], function () {
        var form = layui.form,
            layer = layui.layer,
            $ = layui.$;

        //监听提交
        form.on('submit(saveBtn)', function (data) {
            $.ajax({
                url: data.field.asset_id === "-1" ? "http://127.0.0.1:8000/asset/add" : ("http://127.0.0.1:8000/asset/modify?asset_id=" + data.field.asset_id + "&user_id=" + data.field.user_id),
                method: 'POST',
                contentType: 'application/json',
                data: JSON.stringify(data.field),
                success: function (response) {
                    layer.alert("操作成功!", function () {
                        var iframeIndex = parent.layer.getFrameIndex(window.name);
                        parent.layer.close(iframeIndex);
                    })
                },
                error: function (error) {
                    alert(error);
                }
            });

            return false;
        });

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

操作页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>layui</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../lib/layui-v2.6.3/css/layui.css" media="all">
    <link rel="stylesheet" href="../css/public.css" media="all">
</head>
<body>
<div class="layuimini-container">
    <div class="layuimini-main">

        <table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>

        <script type="text/html" id="currentTableBar">
            <a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="edit">编辑</a>
            <a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
        </script>

    </div>
</div>
<script src="../lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<script>
    layui.use(['form', 'table'], function () {
        var $ = layui.jquery,
            form = layui.form,
            table = layui.table;

        table.render({//渲染
            elem: '#currentTableId',
            url: 'http://127.0.0.1:8000/operation/list',
            toolbar: '#toolbarDemo',
            defaultToolbar: ['filter', 'exports', 'print', {
                title: '提示',
                layEvent: 'LAYTABLE_TIPS',
                icon: 'layui-icon-tips'
            }],
            cols: [[
                {type: "checkbox", width: 50},
                {field: 'record_id', width: 120, title: '记录ID', sort: true},
                {field: 'username', width: 200, title: '用户'},
                {field: 'asset_name', width: 200, title: '资产'},
                {field: 'operation_type', title: '操作类型'},
                {field: 'operation_time', title: '操作时间', sort: true},
            ]],
            limits: [10, 15, 20, 25, 50, 100],
            limit: 15,
            page: true,
            skin: 'line'
        });


    });
</script>

</body>
</html>

 Uvicon服务器正在监听127.0.0.1的8000端口

 127.0.0.1也称为localhost,表示计算机本身地址

效果图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

增强Wi-Fi信号的10种方法,值得去尝试

Wi-Fi信号丢失,无线盲区。在一个对一些人来说,上网和呼吸一样必要的世界里,这些问题中的每一个都令人抓狂。 如果你觉得你的Wi-Fi变得迟钝,有很多工具可以用来测试你的互联网速度。你还可以尝试一些技巧来解决网络问题。然而,如果你能获得良好接收的唯一方法是站在无线路…

nginx部署前端项目自动化脚本

文章目录 配置入口服务器nginx的conf.d使用docker创建一个nginx配置自动化脚本 前言 将项目 通过nginx 部署到 新的服务器 通过nginx反向代理出去 配置入口服务器nginx的conf.d 一般在这个文件夹下 找不到使用 find / -name nginx 2>/dev/null 找到nginx 的位置如果有些没有…

PostGIS教程学习十九:基于索引的聚簇

PostGIS教程学习十九&#xff1a;基于索引的聚簇 数据库只能以从磁盘获取信息的速度检索信息。小型数据库将完全位于于RAM缓存&#xff08;内存&#xff09;&#xff0c;并摆脱物理磁盘访问速度慢的限制。但是对于大型数据库&#xff0c;对物理磁盘的访问将限制数据库的信息检…

正则表达式的语法

如果要想灵活的运用正则表达式&#xff0c;必须了解其中各种元素字符的功能&#xff0c;元字符从功能上大致分为&#xff1a; 限定符 选择匹配符 分组组合和反向引用符 特殊字符 字符匹配符 定位符 我们先说一下元字符的转义号 元字符(Metacharacter)-转义号 \\ \\ 符号…

【Matplotlib】基础设置之图形组合07

figures, subplots, axes 和 ticks 对象 figures, axes 和 ticks 的关系 这些对象的关系可以用下面的图来表示&#xff1a; 示例图像&#xff1a; 具体结构&#xff1a; figure 对象 figure 对象是最外层的绘图单位&#xff0c;默认是以 1 开始编号&#xff08;MATLAB 风格…

Mysql 数据库ERROR 1820 (HY000): You must reset your password using ALTER USER 解决办法

Mysql 5.7数据库原来一直都能正常访问&#xff0c;突然访问不了&#xff0c;查看日志提示数据库需要修改密码&#xff0c; 具体解决办法如下操作&#xff1a; Windows 下&#xff1a; mysql的bin目录下&#xff0c; mysql>use mysql; mysql>mysql -uroot -p密码; 判…

[前车之鉴] SpringBoot原生使用Hikari数据连接池升级到动态多数据源的深坑解决方案 RocketMQ吞掉异常问题排查

文章目录 背景说明蒙蔽双眼口说无凭修补引发的新问题解决配置问题 本地监控佐证万法归元 背景说明 当前业务场景我们使用原生SpringBoot整合Hikari数据源连接池提供服务&#xff0c;但是近期业务迭代需要使用动态多数据源&#xff0c;很自然想到dynamic-source&#xff0c;结果…

windows下全免费手动搭建php8+mysql8开发环境及可视化工具安装

最近PHP项目少了&#xff0c;一直在研究UE5和Golang&#xff0c;但是考虑到政府、国企未来几年国产化的要求&#xff0c;可能又要重拾PHP。于是近日把用了N年的框架重新更新至适合PHP8.2以上的版本&#xff0c;同时也乘着新装机&#xff0c;再次搭建php和mysql开发环境。本文留…

Java18:网络编程

一.对象序列化&#xff1a; 1.对象流&#xff1a; ObjectInputStream 和 ObjectOutputStream 2.作用&#xff1a; ObjectOutputSteam&#xff1a;内存中的对象-->存储中的文件&#xff0c;通过网络传输出去 ObjectInputStream:存储中的文件&#xff0c;通过网络传输出去…

LeetCode-数组-双指针-中等难度

文章目录 双指针1. 删除有序数组中的重复项&#xff08;入门&#xff09;1.1 题目描述1.2 解题思路1.3 代码实现 2. 删除有序数组中的重复项 II&#xff08;简单&#xff09;2.1 题目描述2.2 解题思路2.3 代码实现 3. 移动零&#xff08;简单&#xff09;3.1 题目描述3.2 代码实…

SpringCloud系列篇:核心组件之网关组件

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.网关组件是什么 二. 网关组件的…

The Sandbox 2024 Game Jam 启动|向博姆库斯博士证明你的游戏开发实力!

The Sandbox Game Jam 是面向所有游戏制作爱好者的创作比赛&#xff01;我们诚邀您加入 The Sandbox 的生态系统&#xff0c;这里充满活力&#xff0c;游戏与文化相融&#xff0c;创作者彼此切磋&#xff0c;共同实现梦想。唯一能限制您的只有想象力。The Sandbox 游戏由大家共…

控制台项目和ASP.Net Core 1.项目创建 2.一键启动多个服务 3.引入别的库

感悟&#xff1a; 1.注意选择&#xff1a;.NET/.Net Core下面的控制台或者ASP.NET Core web应用&#xff0c;而且只有.net core的项目是跨平台的&#xff0c;选错的话&#xff0c;是无法发布到linux上的。 2.c#的命名空间和java包的区别&#xff1a; c#中是按照包来的&#x…

使用Django框架自带的Form表单完成简单的用户登录注册

如果不知道怎么配置Django环境以及如何连接数据库请点击我的上一篇博客&#xff1a; 使用pycharm初始化Django框架并连接Sql Server 文章目录 1.Django默认生成的数据表2.用户登录2.1创建登录页面2.2视图处理登录请求2.3配置访问路径 3.用户注册3.1创建用户表单3.2创建注册模版…

linux系统基础知识-基础IO

IO 概念引入位图的概念IO的系统调用函数openwriteread()close简单使用样例&#xff1a; 文件描述符fd默认文件流stdin/stdout/stderr文件描述符的分配规则 重定向的概念输出重定向输入重定向追加重定向dup2()系统调用总结 文件缓冲区深入理解缓冲区的概念输出缓冲区部分代码解释…

jmeter循环控制器

1.循环控制器 简单粗暴 写几次 循环几次 经常结合自定义变量使用 2.foreach控制器 搭配 变量一起使用的循环 一般变量的值是一个集合或者 是2个及2个以上的内容

BERT 模型是什么

科学突破很少发生在真空中。相反&#xff0c;它们往往是建立在积累的人类知识之上的阶梯的倒数第二步。要了解 ChatGPT 和 Google Bart 等大型语言模型 &#xff08;LLM&#xff09; 的成功&#xff0c;我们需要回到过去并谈论 BERT。 BERT 由 Google 研究人员于 2018 年开发&…

软件测试笔记

文章目录 基础知识1.常见测试分类2.质量模型3.测试流程4.用例5.等价类6.边界值分析方法7.判定表8.流程图9.场景法10.错误推测法11.缺陷12.缺陷编写13.缺陷管理工具注&#xff1a;内容和图片来自黑马程序员视频。 基础知识 1.常见测试分类 按阶段划分 (1)单元测试&#xff1a…

详解java继承

目录 一 、为什么需要继承 二、准备工作&#xff1a;用java代码先定义狗类、猫类、动物类&#xff0c;这是代码准备如下 三、继承代码实现 四、 子类中访问父类的成员方法 4.1. 成员方法名字不同 4.2 成员方法名字相同 五、子类构造方法 扩展&#xff1a;如果你对子类和…