golang结合neo4j实现权限功能设计

neo4j 是非关系型数据库之图形数据库,这里不再赘述。
传统关系数据库基于rbac实现权限, user ---- role ------permission,加上中间表共5张表。
如果再添上部门的概念:用户属于部门,部门拥有 角色,则又多了一层:
user
------
dept *-------- * role *------*permission,
如果再引入子部门概念。。。

1.权限设计

1.1 关系

user ---*-----> role --- * --> permission
user ------> dept [-->父dept -->父dept --->父dept]  ---可让子部门继承*-> role --- * --> permission
user ------> dept ---不允许子部门继承*-> role --- * --> permission

1.2 图

用户和部门之间的关系:
在这里插入图片描述

部门和子部门之间的关系:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

部门和角色关系:
在这里插入图片描述
角色和权限关系:
在这里插入图片描述
后台配置界面:
在这里插入图片描述

1.查询一个用户拥有的权限集:

match paths=(admin:Admin{name:'zs'})-[:HAS_ROLE]->(:Role)-[:HAS]->(p:Permission)
return p.id as id, p.name as name, p.url as url
union
match (admin:Admin{name:'zs'})
match paths=(admin)-[:BELONG_TO]->(:Dept)-[:CHILD_OF*0..3]->(d:Dept)-[:ALLOW_INHERIT]->(:Role)
-[:HAS]->(p:Permission)
return p.id as id, p.name as name, p.url as url
union
match (admin:Admin{name:'zs'})
match paths=(admin)-[:BELONG_TO]->(d:Dept)-[:ALLOW_NO_INHERIT]->(:Role)
-[:HAS]->(p:Permission)
return p.id as id, p.name as name, p.url as url

在这里插入图片描述
查询用户权限集:链路:

match paths=(admin:Admin{name:'xiaolan'})-[:HAS_ROLE]->(:Role)-[:HAS]->(p:Permission)
return paths
union
match (admin:Admin{name:'xiaolan'})
match paths=(admin)-[:BELONG_TO]->(:Dept)-[:CHILD_OF*0..3]->(d:Dept)-[:ALLOW_INHERIT]->(:Role)
-[:HAS]->(p:Permission)
return paths
union
match (admin:Admin{name:'xiaolan'})
match paths=(admin)-[:BELONG_TO]->(d:Dept)-[:ALLOW_NO_INHERIT]->(:Role)
-[:HAS]->(p:Permission)
return paths

在这里插入图片描述

2.判断一个用户是否可访问特定资源(url, 通过权限体现此概念):

match c=(admin:Admin{name:'xiaoQ'})-[:HAS_ROLE]->(:Role)-[:HAS]->(p:Permission{url:'/api/v2/goods/list'})
return count(c) as accessCount
union
match c=(admin:Admin{name:'xiaoQ'})-[:BELONG_TO]->(:Dept)-[:CHILD_OF*0..3]->(d:Dept)-[:ALLOW_INHERIT]->(:Role)
-[:HAS]->(p:Permission {url:'/api/v2/goods/list'})
where not ((admin)-[:BELONG_TO]->(:Dept)-[:CHILD_OF*0..3]->(d:Dept)-[:DENY]->(:Role))
return count(c) as accessCount
union
match c=(admin:Admin{name:'xiaoQ'})-[:BELONG_TO]->(d:Dept)-[:ALLOW_NO_INHERIT]->(:Role)
-[:HAS]->(p:Permission {url:'/api/v2/goods/list'})
return count(c) as accessCount

在这里插入图片描述

3.查看谁拥有指定资源(url) 的权限:

match (p:Permission{url:'/api/v2/admin/list'})
match (admin:Admin)-[:HAS_ROLE]->(:Role)-[:HAS]->(p)
return admin.id as id, admin.name as name
union
match (p:Permission{url:'/api/v2/admin/list'})
match (admin:Admin)-[:BELONG_TO]->(:Dept)-[:CHILD_OF*0..3]->(d:Dept)-[:ALLOW_INHERIT]->(:Role)-[:HAS]->(p)
where not ((admin)-[:BELONG_TO]->(:Dept)-[:CHILD_OF*0..3]->(d:Dept)-[:DENY]->(:Role))
return admin.id as id, admin.name as name
union
match (p:Permission{url:'/api/v2/admin/list'})
match (admin:Admin)-[:BELONG_TO]->(d:Dept)-[:ALLOW_NO_INHERIT]->(:Role)-[:HAS]->(p)
return admin.id as id, admin.name as name

在这里插入图片描述
附上完整关系图:
在这里插入图片描述

下面介绍golang代码整合处理:

先上成型图:
在这里插入图片描述
在这里插入图片描述

1.启动项目时读取配置,初始化neo4j driver:

package commonimport ("context""github.com/neo4j/neo4j-go-driver/v5/neo4j""log"
)var DBName string
var Neo4jCtx = context.Background()
var Driver neo4j.DriverWithContextfunc initNeo4jConfig(c neo4jConfig) {var err error// Driver is thread safe: can be shared by multiple threadsDriver, err = neo4j.NewDriverWithContext(c.DbUri, neo4j.BasicAuth(c.DbUser, c.DbPwd, ""))if err != nil {log.Println("new neo4j driver with context failed:", err.Error())return}err = Driver.VerifyConnectivity(Neo4jCtx)if err != nil {log.Printf("init neo4j failed:%s\n", c)return}log.Println("neo4j connection established...")DBName = c.DBName
}

2.neo4j列表分页查询数据

func PageDept(pageNo, pageSize int, name string, queryParentOnly string, parent uint64) (*common.Page, error) {var ctx = common.Neo4jCtxsession := common.Driver.NewSession(ctx, neo4j.SessionConfig{DatabaseName: common.DBName})defer session.Close(ctx)tx, err := session.BeginTransaction(ctx)if err != nil {return nil, err}defer tx.Rollback(ctx)whereSql, params := composeDeptSearchQuerySql(name, queryParentOnly, parent)res, err := tx.Run(ctx, whereSql+` return count(d.id) as c`, params)if err != nil {return nil, err}record, err := res.Single(ctx)if err != nil {return nil, err}var c = int64(0)if r, flg := record.Get("c"); flg && r != nil {c = r.(int64)}// 没有数据if c == int64(0) {return common.NewPage([]model.Dept{}, pageNo, pageSize, 0), nil}params["s"] = (pageNo - 1) * pageSizeparams["size"] = pageSizeres, err = tx.Run(ctx, whereSql + ` return `+row+` order by d.id SKIP $s limit $size`, params)if err != nil {return nil, err}var ds []model.Deptfor res.Next(ctx) {m := res.Record().AsMap()var d model.Depterr = mapstructure.Decode(m, &d)if err != nil {return nil, err}d.CreatedTimeStr = d.CreatedTime.Format(time.DateTime)ds = append(ds, d)}return common.NewPage(ds, pageNo, pageSize, int(c)), nil
}func composeDeptSearchQuerySql(name string, only string, parent uint64) (string, map[string]any) {var params = map[string]any{}sb := strings.Builder{}sb.WriteString("match (d:Dept) ")// 没有条件查询if name == "" && only == "" && parent == 0 {return sb.String(), params}// 只查询父分类if only == "on" {sb.WriteString(" where d.parent = 0")return sb.String(), params}// 查询指定的父分类if parent > 0 {sb.WriteString("-[:CHILD_OF]->(:Dept{id: $parent})")//sb.WriteString(" where d.parent = $parent")params["parent"] = parent}// 有部门名称的模糊查询if len(name) > 0 {sb.WriteString(" where d.name CONTAINS $name")params["name"] = name}return sb.String(), params
}

权限permission dao for neo4j操作:

package neoimport ("commerce/common""commerce/model""fmt""github.com/mitchellh/mapstructure""github.com/neo4j/neo4j-go-driver/v5/neo4j""strings""sync"
)var permissionLock sync.Mutexfunc PagePermission(pageNo, pageSize int, name string) (*common.Page, error) {var ctx = common.Neo4jCtxsession := common.Driver.NewSession(ctx, neo4j.SessionConfig{DatabaseName: common.DBName})defer session.Close(ctx)tx, err := session.BeginTransaction(ctx)if err != nil {return nil, err}defer tx.Rollback(ctx)whereSql, params := composePermissionSearchQuerySql(name)res, err := tx.Run(ctx, whereSql+` return count(p.id) as c`, params)if err != nil {return nil, err}record, err := res.Single(ctx)if err != nil {return nil, err}var c = int64(0)if r, flg := record.Get("c"); flg && r != nil {c = r.(int64)}// 没有数据if c == int64(0) {return common.NewPage([]model.Permission{}, pageNo, pageSize, 0), nil}params["s"] = (pageNo - 1) * pageSizeparams["size"] = pageSizeres, err = tx.Run(ctx, whereSql+` return p.id as id, p.name as name, p.priority as priority, p.status as status, p.public_res_flg as public_res_flg order by p.id SKIP $s limit $size`, params)if err != nil {return nil, err}var rs []model.Permissionfor res.Next(ctx) {m := res.Record().AsMap()var r model.Permissionerr = mapstructure.Decode(m, &r)if err != nil {return nil, err}rs = append(rs, r)}return common.NewPage(rs, pageNo, pageSize, int(c)), nil
}func GetPermissionById(id uint64) (*model.Permission, error) {sqlTpl := `match (p:Permission {id: $id}) return p.id as id, p.name as name, p.priority as priority, p.status as status, p.public_res_flg as public_res_flg`res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id": id,}, neo4j.EagerResultTransformer,neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting(),)if err != nil {return nil, err}records := res.Recordsif records == nil || len(records) == 0 {return nil, err}m := records[0].AsMap()var r model.Permissionerr = mapstructure.Decode(m, &r)if err != nil {return nil, err}return &r, nil
}func AddPermission(c model.Permission) (uint64, error) {permissionLock.Lock()defer permissionLock.Unlock()res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, `match (p:Permission {name: $name}) return p.id as id limit 1`, map[string]any{"name": c.Name},neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting())if err != nil {return 0, err}if res.Records != nil && len(res.Records) > 0 {return 0, fmt.Errorf("%s 已存在,不允许创建", c.Name)}id := common.IdGenerator.Generate()sqlTpl := `create (p:Permission {id: $id, name: $name, priority: $priority, status:$status, public_res_flg: $publicResFlg, created_time: datetime({timezone: 'Asia/Shanghai'}), updated_time: datetime({timezone: 'Asia/Shanghai'})})`_, err = neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id":           id,"name":         c.Name,"priority":     c.Priority,"status":       c.Status,"publicResFlg": c.PublicResFlg,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return 0, err}return id, nil
}func UpdatePermission(c model.Permission) (bool, error) {permissionLock.Lock()defer permissionLock.Unlock()res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, `match (p:Permission {name: $name}) return p.id as id limit 1`, map[string]any{"name": c.Name},neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting())if err != nil {return false, err}records := res.Recordsif records != nil && len(records) > 0 {r, _ := records[0].Get("id")dbId := uint64(r.(int64))if dbId != c.Id {return false, fmt.Errorf("%s 已存在,不允许更新部门名称为此值", c.Name)}}sqlTpl := `match (p:Permission {id: $id}) set p.name=$name, p.priority=$priority,p.public_res_flg=$publicResFlg, p.updated_time=datetime({timezone: 'Asia/Shanghai'})`res, err = neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id":           c.Id,"name":         c.Name,"priority":     c.Priority,"publicResFlg": c.PublicResFlg,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return false, err}return res.Summary.Counters().ContainsUpdates(), nil
}func composePermissionSearchQuerySql(name string) (string, map[string]any) {var params = map[string]any{}sb := strings.Builder{}sb.WriteString("match (p:Permission) ")// 没有条件查询if name == "" {return sb.String(), params}// 有权限名称的模糊查询if len(name) > 0 {sb.WriteString(" where p.name CONTAINS $name")params["name"] = name}return sb.String(), params
}func UpdatePermissionStatus(id uint64, status int8) error {sqlTpl := `match (p:Permission {id: $id}) set p.status = $status, p.updated_time=datetime({timezone: 'Asia/Shanghai'})`_, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id":     id,"status": status,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return err}return nil
}func ListAllPermission() ([]model.Permission, error) {res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver,`match (p:Permission) where p.status = $status return p.id as id, p.name as name order by p.priority`,map[string]any{"status": 1},neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting())if err != nil {return nil, err}records := res.Recordsvar ps = make([]model.Permission, len(records))for i, r := range records {var p model.Permissionerr = mapstructure.Decode(r.AsMap(), &p)if err != nil {return nil, err}ps[i] = p}return ps, nil
}func ListPermissionByRoleId(roleId uint64) ([]model.Permission, error) {res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver,`match (p:Permission {status: $status})<-[:HAS]-(r:Role {id: $roleId}) return distinct p.id as id, p.name as name`,map[string]any{"status": 1, "roleId": roleId},neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting())if err != nil {return nil, err}records := res.Recordsvar ps = make([]model.Permission, len(records))for i, r := range records {var p model.Permissionerr = mapstructure.Decode(r.AsMap(), &p)if err != nil {return nil, err}ps[i] = p}return ps, nil
}

角色操作neo4j dao:

package neoimport ("commerce/common""commerce/model""fmt""github.com/mitchellh/mapstructure""github.com/neo4j/neo4j-go-driver/v5/neo4j""strings""sync"
)var roleLock sync.Mutexfunc PageRole(pageNo, pageSize int, name string) (*common.Page, error) {var ctx = common.Neo4jCtxsession := common.Driver.NewSession(ctx, neo4j.SessionConfig{DatabaseName: common.DBName})defer session.Close(ctx)tx, err := session.BeginTransaction(ctx)if err != nil {return nil, err}defer tx.Rollback(ctx)whereSql, params := composeRoleSearchQuerySql(name)res, err := tx.Run(ctx, whereSql+` return count(r.id) as c`, params)if err != nil {return nil, err}record, err := res.Single(ctx)if err != nil {return nil, err}var c = int64(0)if r, flg := record.Get("c"); flg && r != nil {c = r.(int64)}// 没有数据if c == int64(0) {return common.NewPage([]model.Role{}, pageNo, pageSize, 0), nil}params["s"] = (pageNo - 1) * pageSizeparams["size"] = pageSizeres, err = tx.Run(ctx, whereSql+` return r.id as id, r.name as name, r.priority as priority, r.status as status order by r.id SKIP $s limit $size`, params)if err != nil {return nil, err}var rs []model.Rolefor res.Next(ctx) {m := res.Record().AsMap()var r model.Roleerr = mapstructure.Decode(m, &r)if err != nil {return nil, err}rs = append(rs, r)}return common.NewPage(rs, pageNo, pageSize, int(c)), nil
}func GetRoleById(id uint64) (*model.Role, error) {sqlTpl := `match (r:Role {id: $id}) return r.id as id, r.name as name, r.priority as priority, r.status as status`res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id": id,}, neo4j.EagerResultTransformer,neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting(),)if err != nil {return nil, err}records := res.Recordsif records == nil || len(records) == 0 {return nil, err}m := records[0].AsMap()var r model.Roleerr = mapstructure.Decode(m, &r)if err != nil {return nil, err}return &r, nil
}func AddRole(c model.Role) (uint64, error) {roleLock.Lock()defer roleLock.Unlock()res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, `match (r:Role {name: $name}) return r.id as id limit 1`, map[string]any{"name": c.Name},neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting())if err != nil {return 0, err}if res.Records != nil && len(res.Records) > 0 {return 0, fmt.Errorf("%s 已存在,不允许创建", c.Name)}id := common.IdGenerator.Generate()sqlTpl := `create (r:Role {id: $id, name: $name,priority: $priority, status:$status, created_time: datetime({timezone: 'Asia/Shanghai'}), updated_time: datetime({timezone: 'Asia/Shanghai'})})`_, err = neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id":       id,"name":     c.Name,"priority": c.Priority,"status":   c.Status,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return 0, err}return id, nil
}func UpdateRole(c model.Role) (bool, error) {roleLock.Lock()defer roleLock.Unlock()res, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, `match (r:Role {name: $name}) return r.id as id limit 1`, map[string]any{"name": c.Name},neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName),neo4j.ExecuteQueryWithReadersRouting())if err != nil {return false, err}records := res.Recordsif records != nil && len(records) > 0 {r, _ := records[0].Get("id")dbId := uint64(r.(int64))if dbId != c.Id {return false, fmt.Errorf("%s 已存在,不允许更新部门名称为此值", c.Name)}}sqlTpl := `match (r:Role {id: $id}) set r.name=$name, r.priority=$priority, r.updated_time=datetime({timezone: 'Asia/Shanghai'})`res, err = neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id":       c.Id,"name":     c.Name,"priority": c.Priority,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return false, err}return res.Summary.Counters().ContainsUpdates(), nil
}func composeRoleSearchQuerySql(name string) (string, map[string]any) {var params = map[string]any{}sb := strings.Builder{}sb.WriteString("match (r:Role) ")// 没有条件查询if name == "" {return sb.String(), params}// 有角色名称的模糊查询if len(name) > 0 {sb.WriteString(" where r.name CONTAINS $name")params["name"] = name}return sb.String(), params
}func UpdateRoleStatus(id uint64, status int8) error {sqlTpl := `match (r:Role {id: $id}) set r.status = $status, r.updated_time=datetime({timezone: 'Asia/Shanghai'})`_, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"id":     id,"status": status,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return err}return nil
}func AttachRolePermissionList(roleId uint64, permissionIdList []uint64) error {var sqlTpl stringif len(permissionIdList) == 0 {sqlTpl = `match (:Role {id: $roleId})-[rel:HAS]->(:Permission) delete rel`} else {sqlTpl = `match (r:Role {id: $roleId})CALL {match (r:Role {id: $roleId})-[rel:HAS]->(:Permission) delete rel }with runwind $permissionIdList as pIdmatch (p:Permission {id: pId})merge (r)-[:HAS]->(p)`}_, err := neo4j.ExecuteQuery(common.Neo4jCtx, common.Driver, sqlTpl, map[string]any{"roleId":           roleId,"permissionIdList": permissionIdList,}, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase(common.DBName))if err != nil {return err}return nil
}

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

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

相关文章

小暑节气,选对劳保鞋,让安全与清凉同行

在七月炽热的阳光下&#xff0c;我们迎来了二十四节气中的小暑&#xff0c;标志着盛夏时节的正式开始。随着气温的节节攀升&#xff0c;不仅大自然万物进入了生长的旺季&#xff0c;我们的工作与日常生活也面临着新的挑战——如何在高温环境下保障自身安全&#xff0c;成为了不…

计算机网络——数据链路层(以太网)

目录 局域网的数据链路层 局域网可按照网络拓扑分类 局域网与共享信道 以太网的两个主要标准 适配器与mac地址 适配器的组成与运作 MAC地址 MAC地址的详细介绍 局域网的mac地址格式 mac地址的发送顺序 单播、多播&#xff0c;广播mac地址 mac帧 如何取用…

Spring源码十四:Spring生命周期

上一篇我们在Spring源码十三&#xff1a;非懒加载单例Bean中看到了Spring会在refresh方法中去调用我们的finishBeanFactoryInitialization方法去实例化&#xff0c;所有非懒加载器单例的bean。并实例化后的实例放到单例缓存中。到此我们refresh方法已经接近尾声。 Spring的生命…

提升系统稳定性:熔断、降级和限流策略详解

文章目录 前言一、熔断&#xff08;Circuit Breaker&#xff09;二、降级&#xff08;Degradation&#xff09;三、限流&#xff08;Rate Limiting&#xff09;四、应用案例五、小结推荐阅读 前言 随着互联网业务的快速发展&#xff0c;系统稳定性和高可用性成为现代分布式系统…

【Python机器学习】算法链与管道——网格搜索预处理步骤与模型参数

我们可以利用管道将机器学习工作流程中的所有处理步骤封装成一个scikit-learn估计器。这么做的好处在于&#xff1a;现在我们可以使用监督任务&#xff08;分类或回归&#xff09;的输出来调节预处理参数。 下面用一个管道来完成一个建模过程。管道包含了3个步骤&#xff1a;缩…

ELK优化之Filebeat部署

目录 1.安装配置Nginx 2.安装 Filebeat 3.设置 filebeat 的主配置文件 4.修改Logstash配置 5.启动配置 6.kibana验证 主机名ip地址主要软件es01192.168.9.114ElasticSearches02192.168.9.115ElasticSearches03192.168.9.116ElasticSearch、Kibananginx01192.168.9.113ng…

【C语言】register 关键字

在C语言中&#xff0c;register关键字用于提示编译器将变量尽量存储在CPU的寄存器中&#xff0c;而不是在内存中。这是为了提高访问速度&#xff0c;因为寄存器的访问速度比内存快得多。使用register关键字的变量通常是频繁使用的局部变量。 基本用法 void example() {regist…

iOS多target时怎么对InfoPlist进行国际化

由于不同target要显示不同的App名称、不同的权限提示语&#xff0c;国际化InfoPlist文件必须创建名称为InfoPlist.strings的文件&#xff0c;那么多个target时怎么进行国际化呢&#xff1f;步骤如下&#xff1a; 一、首先我们在项目根目录创建不同的文件夹对应多个不同的targe…

自闭症儿童的治疗方法有哪些?

身为星贝育园自闭症儿童康复学校的资深教育者&#xff0c;我深知自闭症谱系障碍&#xff08;ASD&#xff09;儿童的教育与治疗需要一个全面、个性化的方案。在星贝育园&#xff0c;我们致力于为孩子们提供一个充满爱与理解的环境&#xff0c;采用多种科学验证的教育方法&#x…

商贸物流大脑:大模型+数据要素赋能智慧物流数据平台

项目背景与意义 物流行业快速发展&#xff0c;数据量急剧增加&#xff0c;随着电子商务、智能制造等领域的快速发展&#xff0c;物流行业面领着前所未有的挑战和机遇&#xff0c;如效率低下、资源配置不均、信息不透明等问题。随着全球化和电子商务的快速发展&#xff0c;数据…

Arthas实战(5)- 项目性能调优

1、接口耗时查询&#xff1a;trace命令 trace 命令能主动搜索 class-pattern&#xff0f;method-pattern 对应的方法调用路径&#xff0c;渲染和统计整个调用链路上的所有性能开销和追踪调用链路。 1.1 准备测试应用 新建一个 SpringBoot 应用&#xff0c;写一耗时久的代码&…

编写优雅Python代码的20个最佳实践

想要让你的代码像艺术品一样既实用又赏心悦目吗&#xff1f;今天我们就来聊聊如何通过20个小技巧&#xff0c;让你的Python代码从平凡走向优雅&#xff0c;让同行看了都忍不住点赞&#xff01; **温馨提示&#xff1a;更多的编程资料&#xff0c;领取方式在&#xff1a; 1. 拥…

《基于 defineProperty 实现前端运行时变量检测》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;欢迎多多交流~ &am…

209.力扣每日一题:质数的最大距离

代码解决 class Solution { public:// 判断一个数是否为质数bool isPrime(int n) {if (n < 1) {return false;}if (n < 3) {return true;}if (n % 2 0 || n % 3 0) {return false;}for (int i 5; i * i < n; i 6) {if (n % i 0 || n % (i 2) 0) {return false;…

C生万物之文件操作

文章目录 一、为什么使用文件&#xff1f;二、什么是文件&#xff1f;1、程序文件2、数据文件3、文件名 三、文件的打开和关闭1、文件指针2、文件的打开和关闭 四、文件的顺序读写1. 8个重要的库函数1.1 单字符输入输出【fputc和fgetc】1.2 文本行输入输出【fputs和fgets】1.3 …

API Object设计模式

API测试面临的问题 API测试由于编写简单&#xff0c;以及较高的稳定性&#xff0c;许多公司都以不同工具和框架维护API自动化测试。我们基于seldom框架也积累了几千条自动化用例。 •简单的用例 import seldomclass TestRequest(seldom.TestCase):def test_post_method(self…

固态,机械,移动(U盘),sd卡,哪个更适合长期储存数据 保存数据用什么硬盘可靠 硬盘数据丢失怎么找回 硬盘维护注意事项

有关硬盘数据丢失的恢复技巧&#xff0c;这篇文章一定要收藏好。在硬盘使用过程中&#xff0c;很多情况都会导致数据丢失&#xff0c;例如硬盘跌落、病毒感染、系统文件损坏等。这时候&#xff0c;一定要采用正确的方法&#xff0c;抢救硬盘中存储的珍贵数据和文档。 有关长期保…

如何选择最佳的照片和视频恢复软件

您是否意外从硬盘或 USB 卡中删除了照片或视频&#xff1f;最好的视频和照片恢复软件可以帮到您&#xff01;如果您一直在寻找最好的照片恢复软件&#xff0c;那么您来对地方了。本文将分享一些帮助您找到最佳视频恢复软件的提示。 重要提示&#xff1a;事实&#xff1a;媒体文…

【Qt5.12.9】程序无法显示照片问题(已解决)

问题记录&#xff1a;Qt5.12.9下无法显示照片 我的工程名为03_qpainter&#xff0c;照片cd.png存放在工程目录下的image文件夹中。 /03_qpainter/image/cd.png 因为这是正点原子Linux下Qt书籍中的例程&#xff0c;在通过学习其配套的例程中的项目&#xff0c;发现我的项目少…

广州星启帆:点亮自闭症儿童康复之路的璀璨星辰

在广州这座充满温情的城市中&#xff0c;广州星启帆自闭症康复中心如同一颗璀璨的星辰&#xff0c;照亮了无数自闭症儿童及其家庭的前行之路。这家机构以“点亮希望&#xff0c;启航未来”为使命&#xff0c;向所有踏入这里的家庭承诺&#xff1a;我们将携手并肩&#xff0c;共…