Flask+LayUI开发手记(六):树型表格的增删改查

news2024/9/23 17:21:58

       树型表格的增删改查功能与数据表格的是完全一致,就是调用layui-form表单组件实现数据输入再提交,比较大的区别是树型节点的编辑,都需要有上级节点的输入,而这个上级节点的展示,必须是以树型方式展示出来。当然,树型也有多种模式展示,比如最简单,仍然是select选项域,只是选项用一些特征字符作为前缀,以显示出树型的错落出来。而复杂的展示模式,就是用真正的树型组件来展示,而layui也正好提供了树型组件Tree。

       所以,本节树型表格的编辑功能重点还是介绍级节点树型输入域的构建过程,我构建是一个组合的输入,即一个基本的select选项树型和一个通过按钮点开的Tree组件树型。

       程序主要包括四个部分,前端列表实现编辑页面展示、表单编辑页面、后端数据提取及编辑处理服务程序和树型数据生成程序。

       第一个是上一节树型列表的表头工具栏和行内工具栏的具体处理程序,内容如下。这部分程序与数据列表的处理没有区别,不再详述。

<script>
layui.use(['jquery','layer','treeTable'], function(){
	var $=layui.jquery
        ,layer=layui.layer
        ,table=layui.treeTable;
    var cur_row = null;
    var url_tree = '{{url_for("sysadm.branch_list")}}';
    var url_edit = '{{url_for("sysadm.branch_edit")}}';

    table.render({
            elem: '#table_tree'
            ,height: 'full'
            ,url: url_tree
            ,toolbar: '#toolBar'
            ,method: 'POST'
            ,page: false
            ,limits: [13, 26, 39, 52, 65]           
            ,limit : 13 
            ,even : true
            ,size : 'sm' 
            ,cols: [[ 
            { type: 'checkbox', fixed: 'left' }
            ,{field: 'id', title: 'ID', width:40, sort: true, fixed: 'left'}
            ,{field: 'name', title: '机构名称', width:140}
            ,{field: 'parent_id', title: 'PID', width:40, sort: true}
            ,{field: 'short_name', title: '简称', width:80}
            ,{field: 'branch_cd', title: '编码', width:60}
            ,{field: 'status_name', title: '状态', width:60}
            ,{field: 'category_name', title: '业务条线', width: 100}
            ,{field: 'type_name', title: '机构类型', width: 100}
            ,{field: 'regtime', title: '注册时间', width: 140}
            ,{fixed: 'right', width:200, align:'center', toolbar: '#linetoolBar'}
            ]]
            ,done: function () {
                table.expandAll('table_tree', true);
            }
    });

    //表头工具栏事件
    table.on('toolbar(table_tree)', function (obj) {
        switch (obj.event) {
            case 'search':
                tree_refresh(1);
                break;
            case 'add':
                cur_row=null;
		        tree_edit('add','新增机构节点',0);
                break;
            case 'mdel':
                tree_mdelete(1)
                break;
        };
    });

    //table行内工具栏事件
    table.on('tool(table_tree)', function (obj) {    
        //obj是指这张表中的数据,将表中选中的行数据赋给cur_row变量        
        cur_row = obj.data;                             
        var rid = cur_row.id;

        switch(obj.event) {
            case 'edit':
                tree_edit('upd',"修改机构节点",rid);
                break;
            case 'adds':
                tree_edit('adds',"新增下级机构",rid);
                break;
            case 'del':
                if (cur_row.isParent == true) {
                    layer.msg(cur_row.name + cur_row.id + '有子机构结点,不能删除!!');
                    return false;
                }
                layer.confirm('确认删除吗?', {icon: 3, title:'提示'}, function(index){
                    $.post(url_edit + '?opr=del',{id:rid},function(rs){
                        if(rs.success){
                            //调用查询方法刷新数据
                            layer.msg(rs.msg,function(){});
                            tree_refresh(1);
                        }else{
                            layer.msg(rs.msg,function(){});
                        }
                    },'json');
                    layer.close(index);
                });                
                break;
        }
    });

    //弹出层显示记录编辑界面
    function tree_edit(opr,title,uid){
        layer.open({
            type: 2, 
            title:title,
            area: ['660px', '540px'],   //宽高
            skin: 'layui-layer-rim',    //样式类名
            content:  url_edit + '?opr=' + opr + '&&id=' + uid, //编辑页面
            btn:['保存','关闭'],
            yes: function(index, layero){
                tree_save(layero,opr);
            },
            success: function(layero, index, that){
            },
            btn2: function(index, layero){
                layer.closeAll();
            },
        });
    }

    //存储表单数据
    function tree_save(layero,opr) {
        var iframeWin = window[layero.find('iframe')[0]['name']];
        var vform = iframeWin.layui.form;
        console.log('vform:' + JSON.stringify(vform));
        vform.submit('edit-form',function(data){
            console.log('data:' + JSON.stringify(data));
            $.post(url_edit + '?opr=' + opr,
                data.field,function(rs){
                if(rs.success){
                    layer.closeAll();
                    layer.msg(rs.msg,function(){});
                    tree_refresh(1);
                }else{
                    layer.msg(rs.msg,function(){});
                }
            },'json');
        });
    }

    function tree_mdelete(cpage) {
        var checkData = table.checkStatus('table_tree').data; //得到选中的数据
        if (checkData.length === 0) {
            layer.msg('请选择数据');
            return false;
        }

        var idArr = [];
        for (var i = 0; i < checkData.length; i++) {
            idArr.push(checkData[i].id);
        }
        layer.confirm('确认批量删除吗?', {icon: 3, title:'提示'}, function(index){
            $.post(url_edit + '?opr=mdel' ,
                {id:idArr.join(',')},function(rs){
                if(rs.success){
                    tree_refresh(1);
                    layer.msg(rs.msg);
                }else{
                    layer.msg(rs.msg);
                }
            },'json');
            layer.close(index);
        });                
    }
    
    function tree_refresh(cpage) {
        table.reload('table_tree', {
            where: {                           
                'searchtext':$('#searchtext').val()
            },  
            page: { curr: cpage },
        },true);
    }

});

</script>

        第二部分是前端树型编辑的页面程序,包括Html+JavaScript,程序文件名为branch_edit.html.j2,主要内容如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>栏目编辑</title>
<link rel="stylesheet" href="/static/layui/css/layui.css"  media="all">
</head>
<style>
.layui-form-select dl{
	max-height:150px;
}
</style>
<body>
<div style="padding:10px;">
    <form class="layui-form  layui-form-pane" lay-filter="edit-form" action="">
        <input type="hidden" id="id" name="id"/>
        <div class="layui-form-item" >
            <div class="layui-inline" style="width:70%">
                <label class="layui-form-label">上级机构</label>
                <div class="layui-input-block">
                    <select id="parent_id" name="parent_id" lay-search="">
                        <option value="0">---请选择---</option>
                    </select>
                </div>
            </div>
            <div class="layui-inline">
                <button id="btn_tree" type="button" class="layui-btn layui-btn-sm">
                    <i class="layui-icon layui-icon-cols"></i>树型
                </button>
            </div>
            <div id="parent_tree" style="border:1px solid;border-color:#eee"></div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">机构名称</label>
            <div class="layui-input-block">
                <input type="text" id="branch_name" name="branch_name" autocomplete="off" placeholder="请输入机构名称" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <div class="layui-inline" style="width:48%">
                <label class="layui-form-label">机构编码</label>
                <div class="layui-input-block" >
                    <input type="text" id="branch_cd" name="branch_cd" autocomplete="off" placeholder="请输入机构编码" class="layui-input">
                </div>
            </div>
            <div class="layui-inline" style="width:48%">
                <label class="layui-form-label">机构简称</label>
                <div class="layui-input-block" >
                    <input type="text" id="short_name" name="short_name" autocomplete="off" placeholder="请输入机构简称" class="layui-input">
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">办公地址</label>
            <div class="layui-input-block">
                <input type="text" id="address" name="address" autocomplete="off" placeholder="请输入办公地址" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <div class="layui-inline" style="width:48%">
                <label class="layui-form-label">电话</label>
                <div class="layui-input-block" >
                    <input type="text" id="phone" name="phone" autocomplete="off" placeholder="请输入联系电话" class="layui-input">
                </div>
            </div>
            <div class="layui-inline" style="width:48%">
                <label class="layui-form-label">邮箱</label>
                <div class="layui-input-block" >
                    <input type="text" id="email" name="email" autocomplete="off" placeholder="请输入电子邮箱" class="layui-input">
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <div class="layui-inline" style="width:48%">
                <label class="layui-form-label">业务条线</label>
                <div class="layui-input-block" >
                    <select id="branch_cat" name="branch_cat">
                        <option value="00">---请选择---</option>
                        <option value="10">10_分支机构</option>
                        <option value="20">20_管理部门</option>
                    </select>
                </div>
            </div>
            <div class="layui-inline" style="width:48%">
                <label class="layui-form-label">机构类型</label>
                <div class="layui-input-block" >
                    <select id="branch_type" name="branch_type">
                        <option value="00">---请选择---</option>
                        <option value="10">10_管理机构</option>
                        <option value="20">20_营业机构</option>
                    </select>
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">状态</label>
            <div class="layui-input-block">
                <select name="status">
                    <option value="">---请选择---</option>
                    <option value="0">0_启用</option>
                    <option value="1">1_停用</option>
                </select>
            </div>
        </div>
    </form>
</div>
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['layer','form','jquery','tree'],function(){
	var $=layui.jquery,
    layer=layui.layer,
	form=layui.form,
    tree=layui.tree;

    initDimension();
    initFormData();

    //由UID从服务器数据库中取出数据作为原始数据
    function initFormData(){
        rscode = null;
        {% if rsdata %}
            rscode = {{ rsdata.success }};
            var rsmsg = '{{ rsdata.msg | safe }}';
            var rsdata = {{ rsdata.data | tojson}};
            if (rscode != null) {
                form.val('edit-form',$.extend({}, rsdata||{}));//将父页面传递的行数据赋值到表单中
            }
        {% endif %}
    }

    //由后台取出选项条目数据对选项进行动态刷新
    function initDimension() {
        {% if rsdim %}
            var opr_dim = {{ rsdim.opr_dim | safe }};
            var branch_tlist = {{ rsdim.branch_tlist | safe }};
            var branch_tree = {{ rsdim.branch_tree | safe }};
            var status_dim = {{ rsdim.status_dim | safe }};
            var category_dim = {{ rsdim.category_dim | safe }};
            var type_dim = {{ rsdim.type_dim | safe }};

            if (branch_tlist != null) set_select_tree(branch_tlist,'parent_id');
            if (branch_tree != null) set_tree_render(branch_tree,'parent_tree');
            if (status_dim != null) set_select_option(status_dim,'status');
            if (category_dim != null) set_select_option(category_dim,'branch_cat');
            if (type_dim != null) set_select_option(type_dim,'branch_type');

            if (opr_dim.opr_funt == 'adds') {
                disable_parent_tree(opr_dim.rid);
            }
            form.render('select'); 
        {% endif %}
    }

    //设置select中的选项条目
    function set_select_option(select_dim,sname) {

        var $select = $('[name="'+ sname + '"]');
  
        $select.empty();
        for (var i = 0; i<select_dim.length; i++ ) {
            option_item = select_dim[i];
            $select.append($('<option>').text(option_item[0] + '_' + option_item[1]).attr('value', option_item[0]));
        }
    }

    //设置select中的树型选项条目
    function set_select_tree(select_dim,sname) {

        var $select = $('[name="'+ sname + '"]');
  
        $select.empty();

        $select.append($('<option>').text('根结点_0').attr('value', 0));
        for (var i = 0; i<select_dim.length; i++ ) {
            option_item = select_dim[i];
            let level = option_item[3];
            let lstr ='├' + '─'.repeat(level)

            $select.append($('<option>').text(lstr + option_item[1] + '_' + option_item[0]).attr('value', option_item[0]));
        }
    }

	//绑定树型展开按钮的点击事件
	$('#btn_tree').click(function(){
        pt_elem = $('#parent_tree');
        if (pt_elem.is(":hidden"))
            pt_elem.show();
        else
            pt_elem.hide()
	});

    //渲染树型组件
    function set_tree_render(itree,ielem) {
        //console.log('tree:' + JSON.stringify(itree));
        tree.render({
            elem: '#'+ielem,
            data: itree,
            onlyIconControl: true,  // 是否仅允许节点左侧图标控制展开收缩
            size : 'sm',
            click: function(obj){
                //layer.msg(JSON.stringify(obj.data));
                $('#parent_id').val(obj.data.id);
                form.render('select'); 
                $('#' + ielem).hide();
            }
        });

        $('#'+ielem).hide();
    }

    //加子节点功能时,将父节点输入域及按钮设置为不可操作
    function disable_parent_tree(uid) {
        $('#parent_id').val(uid);
        $('#parent_id').attr('disabled','disabled');
        $('#btn_tree').attr('disabled','disabled');
    }

});

</script>
</body>
</html>

       编辑页面程序需要特别说明的是上级机构输入域的构成,前面说了,这是一个输入组合,可以通过普通select选项域选择机构,也可以展开layui-Tree树型,点击相应机构分支。

       普通select选择输入域如下图所示,在前端选项初始化时,添加了所有选项的前置字符,以展现出树型的样式来,而实质仍然是select选择域。

       机构条目可能很多,所以,建议在select定义中加入lay-search="",这样普通选项树型不但可以进行选择标准操作,还可以在选项里输入关键字进行检索匹配操作,以快速确定机构选项。

       layui-Tree树型在初始状态是隐藏的,通过点击树型button可以展现出来,然后可以进行树型展开操作,并点击相应的机构条目选定机构,点击条目后树型自动关闭。再次展现需要再次点击树型button。

        对于单选树型来说,加入layui-Tree展示只是提供更友好的界面。不过,如果是在树型里多选的话,普通select选项域是无法满足要求的,必须用加checkbox的树型才能实现这个功能。而layui-Tree组件无论是多选还是单选都能支持。多选树型的数据准备和控制比单选树型要复杂一些,但单选树型通了,多选也基本没啥难度,大家可以自己研究一下。       

       页面的JavaScript部分主要包括表单数据的初始化、表单选项域和树型的初始化,上述初始化所要求的数据都是由后端服务程序提供的,处理过程也与数据表格dataTalbe的处理类似。需要特殊说明的是disable_parent_tree(),这个函数是为增加子节点的功能而设置的,增加子节点功能要求上级机构是固定的值,不能改变。所以用disable_parent_tree()将相应的选择域和button都置成不能操作。

        第三部分是后端服务处理程序,内容如下:

#机构信息编辑
@bp.route('/branch_edit/',methods=['GET','POST'])
@login_required
#@admin_auth
def branch_edit():
    if request.method == 'GET':
        opr = request.values.get('opr')
        if opr == None:
            opr = 'upd'
        rid= request.values.get('id')
        if rid == None:
            rid = 0
        branchTree = Branch_Tree()
        udim = {
            'opr_dim' : json.dumps({'opr_funt':opr,'rid':rid}),
            'branch_tlist': json.dumps(branchTree.get_tlist()),
            'branch_tree' : json.dumps(branchTree.get_tree()),
            'status_dim' : json.dumps(Branch_Status().get_list()),
            'category_dim' : json.dumps(Branch_Category().get_list()),
            'type_dim' : json.dumps(Branch_Type().get_list()),

        }
        if opr != 'upd':
            return render_template('admin/branch_edit.html.j2',rsdim=udim)
        else:
            irow = db.session.query(Branchs).filter_by(id=rid).first()
            udata = dict(id=irow.id,branch_name=irow.branch_name,parent_id=irow.parent_id,
                        short_name= irow.short_name,branch_cd=irow.branch_cd,
                        email=irow.email,phone=irow.phone,address=irow.address,
                        branch_cat=irow.branch_cat,branch_type=irow.branch_type,
                        status=irow.status)
            rsdata = {
                "success": 1,
                "msg": "取机构数据成功",
                "data":udata
            }
            return render_template('admin/branch_edit.html.j2',rsdim=udim,rsdata=rsdata)
    else :
        opr = request.values.get('opr')
        rid = request.values.get('id')
        try :
            if opr == 'add' or opr == 'adds':
                rs_data = branch_add()
            elif opr == 'upd' :
                rs_data = branch_update(rid)
            elif opr == 'del' :
                rs_data = branch_delete(rid)
            elif opr == 'mdel':
                rs_data = branch_mdelete(rid)
            else :
                rs_data = {
                    'success':0,
                    'msg':'错误的操作码' + opr,
                    'status':200
                }
        except SQLAlchemyError as e:
            db.session.rollback()
            rs_data = {
                'success':0,
                'msg':'更新机构数据错误:' + str(e.orig),
                'status':200
            } 
        if rs_data.get('success') == 1:
            Branch_Tree.init_dim()
        return json.dumps(rs_data)

#新增机构    
def branch_add():
    logging.debug('Add Branch....')
    parent_id = request.values.get('parent_id')
    branch_cd = request.values.get('branch_cd')
    branch_cat = request.values.get('branch_cat')
    branch_type = request.values.get('branch_type')
    branch_name = request.values.get('branch_name')
    short_name = request.values.get('short_name')
    email = request.values.get('email')
    phone = request.values.get('phone')
    address = request.values.get('address')
    status = request.values.get('status')
    rowadd = Branchs( branch_name=branch_name,parent_id=parent_id,
                        short_name= short_name,branch_cd=branch_cd,
                        email=email,phone=phone,address=address,
                        branch_cat=branch_cat,branch_type=branch_type,
                        status=status)
    db.session.add(rowadd)
    db.session.commit()
    rs_data = {
        'success':1,
        'msg':'增加机构成功' + branch_cd + branch_name,
        'status':200
    }
    return rs_data

#修改机构
def branch_update(uid):
    logging.debug('update Branch %s....' % uid)

    irow = db.session.query(Branchs).filter_by(id=uid).first()
    irow.parent_id = request.values.get('parent_id')
    irow.branch_cd = request.values.get('branch_cd')
    irow.branch_cat = request.values.get('branch_cat')
    irow.branch_type = request.values.get('branch_type')
    irow.branch_name = request.values.get('branch_name')
    irow.short_name = request.values.get('short_name')
    irow.email = request.values.get('email')
    irow.phone = request.values.get('phone')
    irow.address = request.values.get('address')
    irow.status = request.values.get('status')
    db.session.commit()
    rs_data = {
        'success':1,
        'msg':'修改机构信息成功',
        'status':200
    }
    return rs_data

#删除机构--设置status标志为'9'
def branch_delete(uid):
    logging.debug('Branch delete ' + uid)
    irow = db.session.query(Branchs).filter_by(id=uid).first()
    db.session.delete(irow)
    db.session.commit()
    rs_data = {
        'success':1,
        'msg':'删除机构成功' + uid,
        'status':200
    }
    return rs_data

#批量删除机构
def branch_mdelete(ridstr):
    logging.debug('Branch muli delete ' + ridstr)
    ridlist = list(map(int,ridstr.split(',')))
    rows = db.session.query(Branchs).filter(Branchs.id.in_(ridlist)).all()
    for irow in rows:
        db.session.delete(irow)
    db.session.commit()
    rs_data = {
        'success':1,
        'msg':'删除机构列表成功' + ridstr,
        'status':200
    }
    return rs_data

       后端数据获取和处理服务程序的路由命名为'/branch_edit/'。分为get和post两部分。

       get部分是为编辑表单提供初始化数据的,提供的数据主要包括表单初值数据和表单选项数据两部。由于树型表单的特殊要求,服务程序将操作方式也表单选项数据下传,以便表单能够针对操作做特殊处理。

       post部分是对数据增删改等操作进行统一的处理,需要特别说明的是在编辑功能完成后加了Branch_Tree.init_dim(),这是为了在修改机构数据后可以同步机构树型的数据,相应的数据处理是第四部分的内容。

       第四部分是机构树型构建及树型选项列表以及Layui-Tree树型的数据生成程序,内容如下 :

#############机构树型维表处理
class Branch_Tree(Tree_Dimension):
    dim_dict = None

    def __init__(self) :
        if self.dim_dict == None:
            self.dim_dict = current_app.config.get('BRANCH_DIM')
            if self.dim_dict ==None :
                self.dim_dict = Branch_Tree.init_dim()

    #初始化dim_dict变量 
    @staticmethod
    def init_dim():
        logging.debug('Initial Branch dim....')
        rows = db.session.query(Branchs).filter_by(status=0).order_by(Branchs.id.desc()).all()
        rows_info = {}
        for irow in rows:
            rows_info[irow.id] = dict(name=irow.short_name,pid=irow.parent_id)
        current_app.config['BRANCH_DIM'] = rows_info
        return rows_info

class Tree_Dimension(object) :
    dim_dict = {}

    # 初始化方法
    def __init__(self,v_dim=None):
        # 实例属性
        if v_dim :
            #logging.debug('dimention %s' % str(v_dim))
            self.dim_dict = v_dim

    def get_name(self,id) :
        return self.dim_dict.get(id).get('name')

    def get_list(self) :
        auth_list = []
        for (k,v) in self.dim_dict.items():
            auth_item = [k,v['name'],v['pid'],0]
            auth_list.append(auth_item)
        return sorted(auth_list)

    def id_format(self,id):
        idname = self.dim_dict.get(id).get('name')
        if isinstance(id, str) :
            return id + '_' + idname
        else :
            return str(id) + '_' + idname

    #为普通select输入域构建选项列表
    def get_tlist(self) :
        auth_dim = self.get_list()
        auth_tlist = self.build_tlist(auth_dim,0,0)
        return auth_tlist

    
    def build_tlist(self,tlist,p_id,level):
        treelist = []
        for row in tlist:
            if row[2] != p_id:
                continue
            row[3] = level
            treelist.append(row)
            treechild = self.build_tlist(tlist, row[0], level+1)
            if treechild:
                treelist.extend(treechild)
        return treelist

    #为LayUI Tree 生成数据
    def get_tree(self) :
        auth_dim = self.get_list()
        auth_tree = self.build_tree(auth_dim,0,0)
        return auth_tree

    def build_tree(self,data,p_id,level=0):
        tree = []
        row = {}
        for item in data:
            if item[2] ==p_id:
                row = dict(id = item[0], title= item[1] + '_' + str(item[0]), parent_id=item[2],level= level)
                child = self.build_tree(data, row['id'], level+1)
                row['children'] = []
                if child:
                    row['children'] += child
                tree.append(row)
        return tree

       树型选项采用了类方式来构建,tree_dimension是树型基础类,构建了一组功能函数,包括取树型节点的名称、取树型数据节点的条目。get_tlist用于构建普通选择域的选项列表,get_tree用于构建Layui-Tree组件所需要的数据。

       通过上面几部分的程序,一个基本的树型表单编辑功能就完成了,主要的界面如下:

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

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

相关文章

【Qt应用】Qt编写简易文件管理系统

目录 引言 一、准备工作 二、设计思路 三、创建项目和基本界面 四、目录浏览功能 实现效果 五、文件操作功能 5.1 设置添加文件与删除文件按钮 5.2 添加文件槽函数 5.3 删除文件槽函数 5.4 实现效果 六、文件搜索功能 6.1 准备工作 6.2 搜索按钮槽函数 6.3 实现…

[Algorithm][综合训练][合并k个已排序的链表][dd爱旋转][小红取数]详细讲解

目录 1.合并k个已排序的链表1.题目链接2.算法原理讲解 && 代码实现 2.dd爱旋转1.题目链接2.算法原理详解 && 代码详解 3.小红取数1.题目链接2.算法原理详解 && 代码实现 1.合并k个已排序的链表 1.题目链接 合并k个已排序的链表 2.算法原理讲解 &…

网络性能优化的几个思路

指标工具 工具指标 网络性能优化 总的来说&#xff0c;先要获得网络基准测试报告&#xff0c;然后通过相关性能工具&#xff0c;定位出网络性能瓶颈。再接下来的优化工作&#xff0c;就是水到渠成的事情了。 当然&#xff0c;还是那句话&#xff0c;要优化网络性能&#xff0…

Stable Diffusion majicMIX_realistic模型的介绍及使用

一、简介 majicMIX_realistic模型是一种能够渲染出具有神秘或幻想色彩的真实场景的AI模型。这个模型的特点是在现实场景的基础上&#xff0c;通过加入一些魔法与奇幻元素来营造出极具画面效果和吸引力的图像。传统意义的现实场景虽然真实&#xff0c;但通常情况下缺乏奇幻性&a…

前后端交互的路径怎么来的?后端解决cors问题的一种方法

背景&#xff1a;后端使用node.js搭建&#xff0c;用的是express 前端请求的路径baseURL怎么来的 &#xff1f; 前后端都在同一台电脑上运行&#xff0c;后端的域名就是localhost&#xff0c;如果使用的是http协议&#xff0c;后端监听的端口号为3000&#xff0c;那么前端请求…

MySQL将数据库所有表格和列编码格式从utf8mb3换成utf8mb4

最近在做数据导入&#xff0c;发现客户数据很多都带特殊符号&#xff0c;然后数据库就会提示 “java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x8C\xB8\xEF\xBC…’ for column ‘name’ at row 1”&#xff0c;看了一下数据库对应字段字符集是 utf8mb3 的&#…

<Python><AI>基于智谱AI免费大模型GLM-4-Flash的智能聊天程序

前言 智谱AI开放了一个免费使用的大模型GLM-4-Flash&#xff0c;官方也提供了python的示例程序&#xff0c;我们结合pyqt5来编写一个基于GLM-4的简单的智能聊天工具。 界面大致如下&#xff1a; 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&a…

Fedora koji构建系统详细教程之二 -- 构建

写在前面 本篇文章是上一篇文章的继续&#xff0c;由于koji里面的内容实在是太多&#xff0c;都塞进一篇文章里会显得很臃肿&#xff0c;于是我就拆成了两部分。在上一篇文章里&#xff0c;我们已经部署好了Fedora koji系统&#xff0c;此时kojihub已经运行、可以通过kojiweb或…

LavaDome:一款基于ShadowDOM的DOM树安全隔离与封装工具

关于LavaDome LavaDome是一款针对HTML代码安全和Web安全的强大工具&#xff0c;该工具基于ShadowDOM实现其功能&#xff0c;可以帮助广大研究人员实现安全的DOM节点/树隔离和封装。 在当今的Web标准下&#xff0c;尚无既定方法可以安全地选择性地隔离DOM子树。换句话说&#x…

这是不一样的svg图像优化哦。-可优化也可转换为组件

田间的风吹老了岁月&#xff0c;老舍笔下的茶馆写的是近代史&#xff0c;真的写尽了当时的苦态&#xff0c;可能现在的地铁写的是现代史吧。时光飞逝&#xff0c;很快就工作两三年了。昨天做项目的时候&#xff0c;引入svg图像转换为组件的时候&#xff0c;觉得很麻烦&#xff…

2.2 语言处理程序基础

以编译方式翻译C/C源程序的过程中&#xff0c;类型检查在&#xff08; &#xff09;阶段处理。 A. 词法分析 B. 语义分析 C. 语法分析 D. 目标代码生成 正确答案是 B。 解析 本题考查的是编译器工作过程。 A选项词法分析阶段处理的错误&#xff1a;非法字符、单词拼写错误等。与…

《王者荣耀》游戏玩法与部分机制分析

目录 游戏机制 MOBA核心玩法 匹配机制 游戏模式 隐藏分机制 游戏规则 总结 王者荣耀的ELO匹配机制是如何具体工作的&#xff1f; 王者荣耀中隐藏分机制的详细规则是什么&#xff1f;&#xff08;难绷&#xff01;&#xff09; 王者荣耀边境突围和五军对决模式的具体玩…

解释:有序树是什么意思?

目录 有序树的特性&#xff1a; 例子&#xff1a; 总结 &#x1f31f; 嗨&#xff0c;我是命运之光&#xff01; &#x1f30d; 2024&#xff0c;每日百字&#xff0c;记录时光&#xff0c;感谢有你一路同行。 &#x1f680; 携手启航&#xff0c;探索未知&#xff0c;激发…

STM32基于HAL库使用串口+DMA 不定长接收数据 学习记录

我这些博客都只是记录一下自己学习的内容&#xff0c;以及记录一些思考过的问题和疑惑的东西 这里的代码借鉴了一位博主的博客 地址&#xff1a;[] 这里cubemx串口基础配置部分参考这一篇博客 &#xff08;只配置了串口中断接收和printf重定向&#xff09; 这一篇博客我们需要开…

C++编程:理解左值(lvalue)和右值(rvalue)

C 值的分类(Value Categories) 目录 1 概述 2 主要分类 1.1 左值(lvalue) 1.1.1 左值详情 1.1.2 左值属性 1.2 纯右值(prvalue) 1.2.1 纯右值详情 1.2.2 纯右值属性 1.3 将逝值(xvalue) 1.3.1 将逝值详情 1.3.2 将逝值属性 3 混合分类 3.1 泛型左值…

Day51 | 117. 软件构建(拓扑排序)47. 参加科学大会 dijkstra(朴素版)

语言 117. 软件构建 117. 软件构建 题目 题目描述 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依赖于文件 B&#xff0c;则必须在处理…

【STM32】通用定时器TIM(时钟源选择与更新中断)

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 通用定时器简介 定时器时钟使能 选择时基单元时钟源 内部时钟源 外部时钟源 时基单元初始化 更新中断使能 定时器使能 定时器中断代码 Timer.h Timer.c 获取计数值 TIM(Time…

【王树森】RNN模型与NLP应用(7/9):机器翻译与Seq2Seq模型(个人向笔记)

Machine Translation Data 做机器学习任务的第一步都是处理数据&#xff0c;我们首先需要准备机器翻译的数据。由于我们是学习用途&#xff0c;因此拿一个小规模数据集即可&#xff1a;http://www.manythings.org/anki/下面的数据集中&#xff1a;一个英语句子对应多个德语句子…

Spring MVC执行流程

整体流程&#xff1a; 用户向前端控制器发送请求前端控制器接收到请求后调用处理映射器处理器映射器找到具体的处理器&#xff0c;生成处理器对象以及处理器拦截器&#xff0c;再一起返回给前端控制器然后前端控制器调用处理器适配器处理器适配器调用具体的处理器处理器适配器…

element plus el-upload上传组件,自动上传,记录解决:本地报404,文件找不到问题

问题&#xff1a; 解决问题&#xff1a; 重点是&#xff1a;加入action"#"和:http-request"uploadHttpRequest" <el-uploadv-loading"isLoading"ref"upload"v-model"fileList":multiple"multiple"action&quo…