|
|
|
|
# 项目开发流程、结构及知识
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
项目架构:
|
|
|
|
|
|
|
|
|
|
demo-api:为后端与后端交互而提供的接口服务。【为服务层和通用处理层提供的接口。】
|
|
|
|
|
|
|
|
|
|
demo-dao:后端与数据库直接交互的地方。【数据持久层】
|
|
|
|
|
|
|
|
|
|
demo-manager:代码管理层。【通用处理层:处理三方平台和三方平台的接口】
|
|
|
|
|
|
|
|
|
|
demo-service:复杂业务层。
|
|
|
|
|
|
|
|
|
|
demo-web:为前端提供接口。【这里从某种角度,就是图中的开放接口】
|
|
|
|
|
|
|
|
|
|
start:启动和测试使用。
|
|
|
|
|
|
|
|
|
|
项目主提结构:【根据阿里巴巴项目目录结构所分析的图形化】
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 用户角色设计
|
|
|
|
|
|
|
|
|
|
采用分层权限模型,来对公司各职务权限和人员进行管理。
|
|
|
|
|
|
|
|
|
|
如下所示:
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
user 对应 用户
|
|
|
|
|
|
|
|
|
|
role 对应 角色
|
|
|
|
|
|
|
|
|
|
permission 对应 权限
|
|
|
|
|
|
|
|
|
|
通过两个关联表来实现分层权限。【分别为:user_role、role_permission】
|
|
|
|
|
|
|
|
|
|
对于权限,我们将其分为操作权限,和访问权限。分别对应为:menu、operation。
|
|
|
|
|
> 对于访问权限和操作权限的表跟权限表,我采用两个表分别进行关联起来。【menu_permission、operation_permission】
|
|
|
|
|
|
|
|
|
|
这样就可以更详细的描述公司人员之间的关系了。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 前后分离思路
|
|
|
|
|
|
|
|
|
|
> 这里的需要注意的是,token的作用是给系统系别你这账号的权限的。cookie则是自己设置系统是否开启cookie的功能的。如果开启,浏览器就会生成一个cookie给用户,让用户下次登录就不用再次输入账号密码之类的操作。
|
|
|
|
|
|
|
|
|
|
在做前后分离时,首先要考虑自己的所提供给前端,应该是按照什么格式去反馈。
|
|
|
|
|
|
|
|
|
|
即请求体和响应体的格式,不同开发人员所定义的请求结构是不同的。所以要找到适合自己习惯的。
|
|
|
|
|
|
|
|
|
|
下面是自己所觉得合理的请求、响应体:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{// 登录响应
|
|
|
|
|
"code": 200,
|
|
|
|
|
"msg": "",
|
|
|
|
|
"data": null,
|
|
|
|
|
"token": null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{//请求体
|
|
|
|
|
"token": null,
|
|
|
|
|
"data": {
|
|
|
|
|
....
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
实现的流程1 :
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
实现流程2:
|
|
|
|
|
|
|
|
|
|
![实现流程][thik]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
查
|
|
|
|
|
|
|
|
|
|
## Spring boot 事务操作
|
|
|
|
|
|
|
|
|
|
### 注意事项
|
|
|
|
|
|
|
|
|
|
1. 同一个类中方法调用,导致@Transactional失效
|
|
|
|
|
开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。
|
|
|
|
|
那为啥会出现这种情况?其实这还是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
|
|
|
|
|
————————————————
|
|
|
|
|
版权声明:本文为CSDN博主「丶炜钦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
|
|
|
|
原文链接:https://blog.csdn.net/weixin_44521690/article/details/116797363
|
|
|
|
|
|
|
|
|
|
这里该怎么做?
|
|
|
|
|
|
|
|
|
|
## 数据库的设计测试案例及方案
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
```mysql
|
|
|
|
|
create database test;
|
|
|
|
|
use test;
|
|
|
|
|
# 用户
|
|
|
|
|
create table users(
|
|
|
|
|
id int primary key auto_increment, # 自动递增主键
|
|
|
|
|
name varchar(244),
|
|
|
|
|
password varchar(244),
|
|
|
|
|
rolesid int, # 外键 关联角色的ID
|
|
|
|
|
createdate timestamp,
|
|
|
|
|
updatedate timestamp
|
|
|
|
|
) character set = UTF8MB4;
|
|
|
|
|
# 角色
|
|
|
|
|
create table roles(
|
|
|
|
|
id int not null default 0 , # 主键 默认0
|
|
|
|
|
name varchar(30),
|
|
|
|
|
permissionid int not null auto_increment, # 非主键 约束唯一索引 自动递增 并 外键 关联 permission 的ID
|
|
|
|
|
createdate timestamp,
|
|
|
|
|
updatedate timestamp,
|
|
|
|
|
primary key (`id`),
|
|
|
|
|
unique key (`permissionid`)
|
|
|
|
|
)character set = UTF8MB4;
|
|
|
|
|
# 权限表
|
|
|
|
|
create table permission(
|
|
|
|
|
id int primary key auto_increment, # 自动递增主键
|
|
|
|
|
rolesid int,
|
|
|
|
|
name varchar(20),
|
|
|
|
|
operationid int, # 外键 关联operation的ID
|
|
|
|
|
createdate timestamp,
|
|
|
|
|
updatedate timestamp
|
|
|
|
|
)character set = UTF8MB4;
|
|
|
|
|
# menu操作权限访问模块表
|
|
|
|
|
create table operation(
|
|
|
|
|
id int primary key , # 主键 非自动递增
|
|
|
|
|
name varchar(20),
|
|
|
|
|
url varchar(20),
|
|
|
|
|
createdate timestamp,
|
|
|
|
|
updatedate timestamp
|
|
|
|
|
)character set = UTF8MB4;
|
|
|
|
|
|
|
|
|
|
# 用户---角色的外键
|
|
|
|
|
alter table users add constraint ur foreign key (rolesid) references roles(id);
|
|
|
|
|
# 角色---权限 & 权限---menu访问模块 的外键。
|
|
|
|
|
alter table permission add constraint pr foreign key (rolesid) references roles(id);
|
|
|
|
|
alter table permission add constraint op foreign key (operationid) references operation(id);
|
|
|
|
|
|
|
|
|
|
alter table permission drop foreign key op;
|
|
|
|
|
alter table users drop foreign key ur;
|
|
|
|
|
|
|
|
|
|
drop table users;
|
|
|
|
|
drop table roles;
|
|
|
|
|
drop table permission;
|
|
|
|
|
|
|
|
|
|
# 用户
|
|
|
|
|
insert into users (name,password,rolesid,createdate,updatedate) VALUES ('123333','vip2333','1',now(),now());
|
|
|
|
|
insert into users (name,password,rolesid,createdate,updatedate) VALUES ('123343','vip2343','2',now(),now());
|
|
|
|
|
insert into users (name,password,rolesid,createdate,updatedate) VALUES ('123353','vip2353','3',now(),now());
|
|
|
|
|
# 角色
|
|
|
|
|
insert into roles (id, name, createdate, updatedate) VALUES ('1','admin1',now(),now());
|
|
|
|
|
insert into roles (id, name, createdate, updatedate) VALUES ('2','admin2',now(),now());
|
|
|
|
|
insert into roles (id, name, createdate, updatedate) VALUES ('3','admin3',now(),now());
|
|
|
|
|
insert into roles (id, name, createdate, updatedate) VALUES ('4','admin4',now(),now());
|
|
|
|
|
# 权限
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','add','1',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','delete','1',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','select','1',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','updata','1',now(),now());
|
|
|
|
|
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','add','191',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','delete','191',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','select','191',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','updata','191',now(),now());
|
|
|
|
|
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','add','1101',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','delete','1101',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','select','1101',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','updata','1101',now(),now());
|
|
|
|
|
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','add','1111',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','delete','1111',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','select','1111',now(),now());
|
|
|
|
|
insert into permission (rolesid, name,operationid, createdate, updatedate) VALUES ('3','updata','1111',now(),now());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 菜单功能访问模块
|
|
|
|
|
# 设置menu 1 【】
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('1','个人信息','/me',now(),now());
|
|
|
|
|
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('21','部门管理','/index/work',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('31','人员管理','/index/people',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('41','资产类别','/index/assettype',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('51','品牌','/index/brand',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('61','取得方式','/index/method',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('71','供应商','/index/vendor',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('81','存放地点','/index/address',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('91','设备用途','/index/driver',now(),now());
|
|
|
|
|
# insert into operation (id, name, url, createdate, updatedate) VALUES ('11','报废方式','/index/repair',now(),now());
|
|
|
|
|
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('111','资产申购','/:user/by',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('121','资产入库','/:user/input',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('131','资产信息维护','/:user/edit',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('141','资产借还','/:user/debit',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('151','资产转移','/:user/Transfer',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('161','资产维修','/:user/fix',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('171','资产报废','/:user/repair',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('181','资产盘点','/:user/Inventory',now(),now());
|
|
|
|
|
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('191','资产查询统计','/:user/Query',now(),now());
|
|
|
|
|
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('1101','资产申购审批','/:user/Approval/by',now(),now());
|
|
|
|
|
insert into operation (id, name, url, createdate, updatedate) VALUES ('1111','资产报废审批','/:user/Approval/repair',now(),now());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
select * from users;
|
|
|
|
|
select * from roles;
|
|
|
|
|
select * from operation;
|
|
|
|
|
select * from permission;
|
|
|
|
|
|
|
|
|
|
# 通过角色去查询权限。
|
|
|
|
|
select distinct u.name,o.id,o.url from users as u
|
|
|
|
|
left join roles as r on u.rolesid = r.id
|
|
|
|
|
left join permission p on u.rolesid = p.rolesid
|
|
|
|
|
right join operation o on p.operationid = o.id
|
|
|
|
|
where u.name = 123353;
|
|
|
|
|
# 结果:1 = 40 = admin1 ;2 = 80 = admin2 ;3 = 32 = admin3;
|
|
|
|
|
# 过滤用户名,权限:四种权限的operation
|
|
|
|
|
|
|
|
|
|
# 角色添加?
|
|
|
|
|
# 用户授权?
|
|
|
|
|
# 超级用户:拥有对整个系统的权限角色分配,功能分配有着绝对的操作。并且可对所存在的公司员工进行查询。
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在设计数据库中的时候,对于公司类型的管理系统,我们可以通过分层权限结构来对其人员权限进行设计,这样才更贴近公司层级。
|
|
|
|
|
|
|
|
|
|
[thik]: data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBEbyBub3QgZWRpdCB0aGlzIGZpbGUgd2l0aCBlZGl0b3JzIG90aGVyIHRoYW4gZGlhZ3JhbXMubmV0IC0tPgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgd2lkdGg9IjkzMXB4IiBoZWlnaHQ9IjQ5MXB4IiB2aWV3Qm94PSItMC41IC0wLjUgOTMxIDQ5MSIgY29udGVudD0iJmx0O214ZmlsZSBob3N0PSZxdW90O2FwcC5kaWFncmFtcy5uZXQmcXVvdDsgbW9kaWZpZWQ9JnF1b3Q7MjAyMy0wNC0wOVQyMDoyMzo0OC41OThaJnF1b3Q7IGFnZW50PSZxdW90O01vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzE1XzcpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS8xMTEuMC4wLjAgU2FmYXJpLzUzNy4zNiBFZGcvMTExLjAuMTY2MS42MiZxdW90OyBldGFnPSZxdW90OzVydEllX3FucWZiUzNGRkZQSWIzJnF1b3Q7IHZlcnNpb249JnF1b3Q7MjEuMS41JnF1b3Q7IHR5cGU9JnF1b3Q7ZGV2aWNlJnF1b3Q7Jmd0OyZsdDtkaWFncmFtIG5hbWU9JnF1b3Q756ysIDEg6aG1JnF1b3Q7IGlkPSZxdW90O19fUTROdXNGQy1Fb2dhTXZWMEQ4JnF1b3Q7Jmd0OzdWdGJjK01tRlA0MVBEWWpDVjNRbytSTGQzYTJzNW1tMDAwZUZZdllhbVRqd1RpeDk5Y1hFTG9yc1ZQTFJ0NG1MNEVEUXVnN2gzUGpHTURSY3ZjN2pkYUxQMGlNVTJBWjhRN0FNYkFzMDRZMi95Y28rNHlDTEpRUjVqU0oxYVNTY0pmOHhJcG9LT28yaWZHbU5wRVJrckprWFNmT3lHcUZaNnhHaXlnbHIvVnBUeVN0djNVZHpYR0xjRGVMMGpiMVJ4S3pSZjRWWGtuL2dwUDVJbit6NmZyWnlETEtKNnN2MlN5aW1MeFdTSEFDNElnU3dyTFdjamZDcVFBdnh5VjdidnJHYUxFeGlsZnNtQWUrZm45NStQdkxOa21uZjhiNDNtVjh3dk52VU8yTjdmTVB4akgvZnRVbGxDM0luS3lpZEZKU1EwcTJxeGlMVlEzZUsrZDhJMlROaVNZbi9vTVoyeXRtUmx0R09HbkJscWtheGJ1RTNWZmFEMktwRzBmMXhqdTFzdXpzSzUxYlRKTWxacGdxV3JaM3NlRTNJVkdrRGRuU0dYNEhCeVdsTEtKenpONlpaeFdNNHhLUENkOE4zZlBuS0U0amxyelU5eEVwMFpzWDg0cEhiMG5DZDJnWjZwZ1UwcTRPaWVrWTlTV3kvYXVuU2g3elJtVWJKVWx5L2dOUzRPcVVBdVBHSDVBZ1dFY0tnbk9pSU5SWStGRitxVTIrUk9sV3ZhbkZ3QXJRWk12U1pJVkhoWVlVa0QwbGFUb2lLYUZ5T2h6SlAwN2ZNRXFlY1dYRVJjZ01JUitaMHloT09KNzUySXFzY0lVOFRpaGZQU0VyT1VTRjhsT0w1WHJURXBSRnRCWTdYTzdtd2w3Y3JEQjdKZlI1Y3pOTHlUWVcreUxsRy9qYm4rUmZ3ZUlYVEJuZXZjL2tObFBVQTlCdW5ETEx5ZnF2cFdMMzFaUkZSYWMzRDJOdmJMUVBzN0VCaDJHNHJtU1RBQ0xoVmlwSWs3bEFuSWxEVjFDL1JZODR2U1diUlBIamtUQkdsbnhDMmhpWWNlakVLUW9qdFU1QnVEYjVXYy82RVJLdklTTm1XMFpNbzBOSXZITUppZk1wSkwwSnlRYlRGN254SGdURmFVcEtMaFVIdEVreHIzZEo4UTlMeWdYTWVvKzIyRHZTRmlPZHR0aHJvejV4UURBQkFXKzRBQ0VRZW1EaWdTQUV3YlRGa0RyY3I0dUU0YnQxSkZGNTViTGJCZTFKVXV2V2hiWUlUcXJxemVxUVd2ZGNRbXVhdjVyVW9pT2wxalM2T1hVWnNUWGgveGIzVTJPNGszQkhMZGhuM0hwVGtxYmNNRTBnUUFiZ1ZvUHJDOThIWVNoVVNUZ0d2cE1QbVMwbUhkQVpkUTcxb0VGZzdqVVBSNFVjNFNKZElwN2xiTnpmcStkbHB4TE9pbTRaejhyZUh2UWV2T1pwaE1ObndOYXFlNUFXL3Z5WHJOTTE4ZFRUeWRNaXkvbkowejU1Nm12bHFSNDkrb3Z6OUMzN2VpR2VIcEYwdWk2LzczamdvVmFqWjdTQjUvR2hQd0pvTE53OEZJREFsQlFvS2JaMC9FYmEvVDNIR1p5LzEwNS9COTl2QlhTQmRKSUZobE1RT0xJeEJnaUNpUy9jYWI5dG9uUTd6OURWRG1hSFBpZ0JSQ0pua1NVeUJpYVdxSkYrUTlxQjdFb0V1U0w1azRWeDRud2Jwd041QnVoTXB5UEhmVm5zT2xLWEFxQ3B5S01KeUhqYkh5UjJGdFNOWGY0TmpRUWtRbExjcE9JTDdFRmlCN3Z1Vmk2TG5kdkdUcVBIVzNxNUQ1V1JibzhYOU9kQVdTb1ZlTmlCMG52cDdWOExiOHBvcEF4QUhxcGo1NDlHanVlcDFzc1RlRFhuN1pwNENyVkdtSG5GM3lkUGUrV3AxdUFWYXE0UUc3WmRoRnJ0SXJ3YXU2aUZONmRteGVXakFhWFJ2akpoTFNveE41V1ZHd1dkcmxtUDgyMjdVWnZibU8vazM5TTluemV5SGZSYTlXbDFYQUdMKzBaUGh2NDhoSkJ0M1lGK00vK2tQMlZpdGU4YnYvNzRpeE1HaUo3ZFNEalpIZWdocHcyZWZUYncyaGZnSWtvTkFvQkdLdCtFVEZrdlk0akdJRUYxb0RFc1VPRWJPWUFzNWNSQjlVUnFWSlFsY1hUZFlZTHE1amNUZ3dHMVd6MGlKQ0FVSW11QzBPbklsUTRTWFMrL2N4OE11aDFGR3dMTEhMWndLdG9DMUFrSWpiSU9acERvSWhNT0MxMWI2Kzk2aklwSGVQVE5iVkZDYy9HYlczaHNuYW10TjY3dXVtQ1E1MFBrZDNQTE9janpZYU82d1hRNjdoQXZlejY2TG1OdEVISXZKQ3d2WTV1d2NRQllIYWxXUlh5ejVINlp4SEYydVBBbStSazl5cVVFcWlxQzRPczZJWERHWWkxK25qYlowUkpMMTJ2a1ZSMTh0YUJla2Zvd0RrYmpVcU1qTWU5MGVOandiT3daVUZyUU9FNTlOVkpJNXVYVWw1My9MSGJZaGE5Mmw0L0tmU2xQK1A1Wnhid2Z5RVBvQXlRdiswSUlBbFM2cng5VVlqMmNpK1p0dldPZUwvVGszZktud0ZtRVgvNmdHazcrQlE9PSZsdDsvZGlhZ3JhbSZndDsmbHQ7L214ZmlsZSZndDsiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjQsIDIwLCAyOSk7Ij48ZGVmcy8+PGc+PHBhdGggZD0iTSAxMTAgNzAgTCAyNzMuNjMgNzAiIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDI0MCwgMjQwLCAyNDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48cGF0aCBkPSJNIDI3OC44OCA3MCBMIDI3MS44OCA3My41IEwgMjczLjYzIDcwIEwgMjcxL
|