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

题目要求:

资产管理系统

利用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,表示计算机本身地址

效果图

相关推荐
街尾杂货店&3 小时前
css - 实现三角形 div 容器,用css画一个三角形(提供示例源码)简单粗暴几行代码搞定!
前端·css
顺凡3 小时前
删一个却少俩:Antd Tag 多节点同时消失的原因
前端·javascript·面试
小白路过3 小时前
CSS transform矩阵变换全面解析
前端·css·矩阵
前端大卫3 小时前
动态监听DOM元素高度变化
前端·javascript
Cxiaomu4 小时前
React Native App 图表绘制完整实现指南
javascript·react native·react.js
qq. 28040339844 小时前
vue介绍
前端·javascript·vue.js
Mr.Jessy4 小时前
Web APIs 学习第五天:日期对象与DOM节点
开发语言·前端·javascript·学习·html
Hi~晴天大圣5 小时前
HTML onclick用法
前端·html
速易达网络5 小时前
HTML<output>标签
javascript·css·css3
!win !6 小时前
前端跨标签页通信方案(上)
前端·javascript