This commit is contained in:
苏丽娟 2023-09-15 14:54:01 +08:00
parent 1a8f8e804c
commit a1f742e015
733 changed files with 126800 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# Default ignored files
/target/
/log/
/.idea/
/*.iml
/.fastRequest/
/staticServer
fastRequest/
.fastRequest/
/file_data/
/old_webdav/
/docker/

4
Dockerfile Normal file
View File

@ -0,0 +1,4 @@
FROM harbor.svnlan.com/library/office6_jdk8_ffmpeg6_libraw_skagent_centos7
COPY target/disk-0.0.1-SNAPSHOT.jar /app.jar
COPY src/main/resources/itest/agent.config /agent/config/agent.config
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., [http://fsf.org/]
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) 2017 小柒2012
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

301
db/ddl.sql Normal file
View File

@ -0,0 +1,301 @@
-- 2023-04-07
create table `visit_count_record`
(
id BIGINT UNSIGNED auto_increment comment '主键id',
visitCount BIGINT UNSIGNED not null comment '用户访问次数',
deviceType TINYINT default null comment '设备类型 1 pc , 2 h5, 3 安卓app, 4 ios-app, 5 小程序, 6 电脑app, 7 其他',
visitDay DATE DEFAULT NULL comment '访问的日期',
modifyTime BIGINT UNSIGNED not null comment '最后修改时间',
createTime BIGINT UNSIGNED not null comment '创建时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8 COMMENT ='访问次数记录表';
-- 2023-04-11 io_source 添加 文件类型 fileType
ALTER TABLE io_source
ADD COLUMN `type` TINYINT(3) UNSIGNED default null comment '文档类型 1 文档 2 图片 3 音乐 4 视频 5 压缩包 6 其他' AFTER sourceHash;
-- 2023-04-11 根据 fileType 设置文件类型 type
UPDATE io_source
SET `type` = (
CASE
WHEN find_in_set(fileType,
'txt,md,pdf,ofd,doc,docx,xls,xlsx,ppt,pptx,xps,pps,ppsx,ods,odt,odp,docm,dot,dotm,xlsb,xlsm,mht,djvu,wps,dpt,csv,et,ett,pages,numbers,key,dotx,vsd,vsdx,mpp')
THEN 1
WHEN find_in_set(fileType, 'jpg,jpeg,png,gif,bmp,ico,svg,webp,tif,tiff,cdr,svgz,xbm,eps,pjepg,heic,raw,psd,ai')
THEN 2
WHEN find_in_set(fileType, 'mp3,wav,wma,m4a,ogg,omf,amr,aa3,flac,aac,cda,aif,aiff,mid,ra,ape,mpa') THEN 3
WHEN find_in_set(fileType,
'mp4,flv,rm,rmvb,avi,mkv,mov,f4v,mpeg,mpg,vob,wmv,ogv,webm,3gp,mts,m2ts,m4v,mpe,3g2,asf,dat,asx,wvx')
THEN 4
WHEN find_in_set(fileType, 'zip,gz,rar,iso,tar,7z,ar,bz,bz2,xz,arj') THEN 5
ELSE 6
END
)
WHERE isFolder = 0
AND `type` IS NULL;
-- 2023-04-11 设置文件夹 type 类型为 NULL
UPDATE io_source
SET `type` = 0
WHERE isFolder = 1;
-- 2023-04-12
ALTER TABLE `visit_count_record`
ADD COLUMN osName VARCHAR(20) DEFAULT NULL COMMENT '操作系统' AFTER deviceType;
ALTER TABLE `visit_count_record`
ADD COLUMN `type` TINYINT(3) DEFAULT 1 COMMENT '1 客户端访问 2 用户访问 3 操作系统访问 4 各操作系统总访问' AFTER osName;
-- 2023-04-20
ALTER TABLE `user`
ADD COLUMN dingOpenId VARCHAR(64) DEFAULT NULL COMMENT '钉钉 openId' AFTER `status`;
ALTER TABLE `user`
ADD COLUMN wechatOpenId VARCHAR(64) DEFAULT NULL COMMENT '微信 openId' AFTER wechatOpenId;
ALTER TABLE `user`
ADD COLUMN alipayOpenId VARCHAR(64) DEFAULT NULL COMMENT '支付宝 openId' AFTER alipayOpenId;
-- 2023-05-10
ALTER TABLE `user`
ADD COLUMN enWechatOpenId VARCHAR(64) DEFAULT NULL COMMENT '企业微信 openId' AFTER wechatOpenId;
-- 2023-05-16
drop table if exists notice;
create table notice
(
id BIGINT UNSIGNED auto_increment comment '通知id' primary key,
title VARCHAR(128) not null comment '标题',
level TINYINT UNSIGNED default 0 comment '0 弱提示左下角通知栏显示红点1 强提示:用户登录后直接弹出通知。',
status TINYINT UNSIGNED default 0 comment '状态0暂存1已发送2已删除',
enable TINYINT UNSIGNED default 0 comment '是否启用0未启用1启用',
send_time BIGINT UNSIGNED not null comment '通知发送时间',
sender_id BIGINT UNSIGNED not null comment '通知发送者id',
sender_ip VARCHAR(64) not null comment '发送通知的IP地址json(222.22.22.22,杭州)',
notice_type TINYINT UNSIGNED default 1 comment '消息类型1通知2消息3私信',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' NOT NULL,
modify_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' NULL
);
ALTER TABLE notice
COMMENT = '消息表';
drop table if exists notice_detail_copy2;
create table notice_detail
(
id BIGINT UNSIGNED not null comment '主键id' primary key,
notice_id BIGINT UNSIGNED not null comment '通知id',
content TEXT not null comment '消息内容',
is_all TINYINT UNSIGNED default 1 comment '是否为所有用户 1 是 0 否',
target_ids JSON not null comment '接收者',
`status` TINYINT UNSIGNED default 0 comment '状态0未读1已读',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' NOT NULL,
modify_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' NULL
);
ALTER TABLE notice_detail
COMMENT = '消息详情表';
CREATE TABLE notice_user
(
id BIGINT UNSIGNED auto_increment comment '主键' primary key,
notice_id BIGINT UNSIGNED not null comment '通知id',
user_id BIGINT UNSIGNED not null comment '用户id',
is_read tinyint default 0 comment '是否已读 0 未读 1 已读',
`year` year not null comment '年份',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' NOT NULL,
modify_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' NULL
);
ALTER TABLE notice_detail
COMMENT = '消息用户表';
-- target_ids
-- {"u": [12312312,52345234,32342345],"g": [2341324,123123,345345],"r": [3252345,346134,132646345,6756354]}
-- 2023-05-17
ALTER TABLE notice_user
ADD COLUMN last_notice_time DATETIME DEFAULT NULL COMMENT '最后一条通知的时间' AFTER is_read;
ALTER TABLE notice_user
DROP COLUMN notice_id;
ALTER TABLE notice_user
ADD COLUMN notice_id JSON DEFAULT NULL COMMENT '通知id集合' AFTER user_id;
ALTER TABLE notice
ADD COLUMN send_type TINYINT DEFAULT 1 COMMENT '推送方式 1 立即推送 2 计划推送' AFTER `enable`;
ALTER TABLE notice
DROP COLUMN send_time;
ALTER TABLE notice
ADD COLUMN send_time DATETIME DEFAULT NULL COMMENT '通知发送时间' AFTER send_type;
ALTER TABLE notice
ADD COLUMN sort BIGINT DEFAULT 0 COMMENT '排序 越大越靠前' AFTER send_time;
ALTER TABLE notice_detail
DROP COLUMN `status`;
ALTER TABLE notice_detail
DROP COLUMN target_ids;
ALTER TABLE notice_detail
ADD COLUMN target_user_ids JSON DEFAULT NULL COMMENT '目标用户id集合' AFTER is_all;
ALTER TABLE notice_detail
ADD COLUMN target_dept_ids JSON DEFAULT NULL COMMENT '目标部门id集合' AFTER target_user_ids;
ALTER TABLE notice_detail
ADD COLUMN target_role_ids JSON DEFAULT NULL COMMENT '目标角色id集合' AFTER target_dept_ids;
ALTER TABLE notice_detail
ADD COLUMN notice_detail_id BIGINT DEFAULT NULL COMMENT '通知详情表id' AFTER target_role_ids;
-- 2023-05-19
alter table notice
modify sender_ip VARCHAR(64) null comment '发送通知的IP地址json(222.22.22.22,杭州)';
alter table notice
modify create_time DATETIME(19) default CURRENT_TIMESTAMP null comment '创建时间';
alter table notice_detail
modify create_time DATETIME default CURRENT_TIMESTAMP null comment '创建时间';
-- 2023-05-22
ALTER TABLE notice_user
ADD COLUMN total BIGINT UNSIGNED DEFAULT 0 COMMENT '总数' AFTER is_read;
-- 2023-05-23
drop table if exists notice;
drop table if exists notice_detail_copy;
drop table if exists notice_detail;
create table notice
(
id BIGINT UNSIGNED auto_increment comment '通知id'
primary key,
title VARCHAR(128) not null comment '标题',
level TINYINT UNSIGNED default 0 comment '0 弱提示左下角通知栏显示红点1 强提示:用户登录后直接弹出通知。',
status TINYINT UNSIGNED default 0 comment '状态0暂存1已发送2已删除',
enable TINYINT UNSIGNED default 0 comment '是否启用0未启用1启用',
send_type TINYINT default 1 comment '推送方式 1 立即推送 2 计划推送',
send_time DATETIME null comment '通知发送时间',
sort BIGINT default 0 comment '排序 越大越靠前',
sender_id BIGINT UNSIGNED not null comment '通知发送者id',
sender_ip VARCHAR(64) default null comment '发送通知的IP地址json(222.22.22.22,杭州)',
notice_type TINYINT UNSIGNED default 1 comment '消息类型1通知2消息3私信',
create_time DATETIME not null comment '创建时间',
modify_time DATETIME default null comment '更新时间'
);
create table notice_detail
(
id BIGINT UNSIGNED auto_increment comment '主键id'
primary key,
notice_id BIGINT UNSIGNED not null comment '通知id',
content TEXT not null comment '消息内容',
is_all TINYINT UNSIGNED default 1 comment '是否为所有用户 1 是 0 否',
target_user_ids JSON null comment '目标用户id集合',
target_dept_ids JSON null comment '目标部门id集合',
target_role_ids JSON null comment '目标角色id集合',
notice_detail_id BIGINT null comment '通知详情表id',
create_time DATETIME not null comment '创建时间',
modify_time DATETIME default null comment '更新时间'
);
drop table if exists notice_user;
create table notice_user
(
id BIGINT UNSIGNED auto_increment comment '主键'
primary key,
user_id BIGINT UNSIGNED not null comment '用户id',
notice_id BIGINT UNSIGNED not null comment '通知id集合',
is_read TINYINT default 0 comment '是否已读 0 未读 1 已读',
create_time DATETIME not null comment '创建时间',
modify_time DATETIME default null comment '更新时间'
);
ALTER TABLE notice
COMMENT = '通知';
ALTER TABLE notice_detail
COMMENT = '通知详情';
ALTER TABLE notice_user
COMMENT = '通知用户关联';
-- 2023-05-25
ALTER TABLE notice_user
ADD UNIQUE INDEX user_notice_key (user_id, notice_id);
ALTER TABLE notice_detail
ADD COLUMN dr TINYINT DEFAULT 0 COMMENT '逻辑删除 0 未删除 1 已删除' AFTER modify_time;
-- 2023-05-26
DROP TABLE IF EXISTS share_report;
create table share_report_copy
(
id BIGINT UNSIGNED auto_increment comment '自增id'
primary key,
share_id BIGINT UNSIGNED not null comment '分享id',
title VARCHAR(255) not null comment '分享标题',
source_id BIGINT UNSIGNED not null comment '举报资源id',
file_id BIGINT UNSIGNED not null comment '举报文件id,文件夹则该处为0',
user_id BIGINT UNSIGNED not null comment '举报用户id',
report_type TINYINT UNSIGNED not null comment '举报类型 (1-侵权,2-色情,3-暴力,4-政治,5-其他)',
reason VARCHAR(255) not null comment '举报原因(其他)描述',
status TINYINT UNSIGNED not null comment '处理状态(0-未处理,1-已处理,2-允许分享,3-禁止分享)',
create_time DATETIME not null comment '创建时间',
modify_time DATETIME DEFAULT null comment '最后修改时间'
);
ALTER TABLE share_report_copy
COMMENT = '分享链接举报';
ALTER TABLE share_report
ADD INDEX create_time_index (user_id);
-- 2023-05-30
ALTER TABLE share
ADD COLUMN `status` TINYINT UNSIGNED DEFAULT 1 COMMENT '状态 1 正常 2 取消分享 3 禁止分享' AFTER isLink;
ALTER TABLE io_source
ADD COLUMN canShare TINYINT UNSIGNED DEFAULT 1 COMMENT '是否可以分享 1 正常 0 禁止分享' AFTER `sort`;
ALTER TABLE share_report
MODIFY status TINYINT UNSIGNED DEFAULT 0 COMMENT '处理状态(0-未处理,1-已处理)';
-- 2023-05-31
alter table share_report
modify reason VARCHAR(255) DEFAULT null comment '举报原因(其他)描述';
alter table share
modify status TINYINT(3) UNSIGNED default 1 null comment '状态 1 正常 3 禁止分享 4 取消分享';
-- 2023-06-08
INSERT INTO system_option (`type`, `key`, `value`, createTime, modifyTime)
values ('Storage', 'LOCAL', '{"name":"local1","size":"1024","location":"/uploads","storageKey":"LOCAL"}', 1682386870,
1682386870);
-- 2023-06-13
ALTER TABLE common_info
ADD COLUMN likeCount INT(10) DEFAULT 0 COMMENT '点赞数' AFTER actualViewCount;
ALTER TABLE common_info
ADD COLUMN isLogin TINYINT DEFAULT 0 COMMENT '是否需要登录 0 否 1 是' AFTER isHide;
create table user_common_info
(
id BIGINT UNSIGNED auto_increment
primary key,
user_id BIGINT UNSIGNED not null comment '用户id',
info_id BIGINT UNSIGNED not null comment '资讯id',
view_count INT UNSIGNED default 0 comment '阅读数',
is_like TINYINT UNSIGNED default 0 comment '是否点赞 0 否 1 是',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP comment '创建时间',
modify_time DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP comment '最后修改时间',
constraint userId_infoId_unique
unique (user_id, info_id)
)ENGINE = InnoDB CHARSET = utf8mb4 COLLATE = utf8mb4_bin COMMENT '用户资讯表';
ALTER TABLE user_common_info DROP INDEX userId_infoId_unique;
ALTER TABLE user_common_info ADD UNIQUE INDEX infoId_userId_unique(info_id, user_id);
ALTER TABLE user_common_info ADD COLUMN ip VARCHAR(30) DEFAULT NULL COMMENT '用户ip' AFTER info_id;
ALTER TABLE user_common_info ADD UNIQUE INDEX infoId_ip_unique(info_id, ip);
ALTER TABLE user_common_info MODIFY user_id BIGINT UNSIGNED DEFAULT NULL comment '用户id';
-- 2023-08-09
create index file_name_index on io_file (fileName(8));
drop index path on io_file;
-- 2023-08-23
create table t_tenant
(
id BIGINT auto_increment primary key,
tenant_name VARCHAR(64) not null comment '名称',
second_level_domain VARCHAR(64) not null comment '二级域名',
user_id BIGINT not null comment '超级管理员用户id',
status TINYINT(3) default 0 not null comment '状态0停用1启用2删除',
start_time DATETIME not null comment '生效时间',
expire_time DATETIME not null comment '失效时间',
size_use BIGINT default 0 not null comment '已使用大小(byte)',
group_count BIGINT default 0 not null comment '组织数',
user_count BIGINT default 0 not null comment '用户数',
remark VARCHAR(255) null comment '备注',
create_time DATETIME not null comment '创建时间',
modify_time DATETIME not null comment '最后修改'
) ENGINE = InnoDB CHARSET = utf8mb4 COLLATE = utf8mb4_bin COMMENT '用户租户表';

35
harbor Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
import os
import sys
site_name = "harbor.svnlan.com"
app_name = "library/java/disk"
dep_version = "latest"
docker_login_name = "admin"
docker_login_password = "Harbor12345"
#执行shell命令
def docker_cmd(cmd):
return_code = subprocess.call(cmd, shell=True)
if return_code != 0:
print "command === %s === error" % (cmd)
usage()
return return_code
def main():
global dep_version
if len(sys.argv) >= 2:
dep_version = sys.argv[1]
docker_login = 'docker login -u %s -p %s https://%s' % (docker_login_name, docker_login_password, site_name )
docker_tag = 'docker build -t %s/%s:%s .' % ( site_name.lower(), app_name.lower(), dep_version)
docker_push = 'docker push %s/%s:%s' % ( site_name.lower(), app_name.lower(),dep_version)
for cmd in [docker_login, docker_tag, docker_push]:
docker_cmd(cmd)
print "docker cmd is run..."
if __name__ =='__main__':
main()

52
java-disk-deployment.yaml Normal file
View File

@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-disk
namespace: default
labels:
app-name: java-disk
spec:
replicas: 1
minReadySeconds: 30
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app-name: java-disk
template:
metadata:
labels:
app-name: java-disk
spec:
nodeSelector:
type: deployment
containers:
- name: java-disk
image: harbor.svnlan.com/library/java/disk:latest
imagePullPolicy: Always
securityContext:
privileged: true
ports:
- containerPort: 80
name: disk
protocol: TCP
volumeMounts:
- name: nfs-pvc-svnlan-cloud-disk
mountPath: "/uploads"
- name: nfs-pvc-svnlan-log30
mountPath: "/log"
- name: mem
mountPath: "/dev/mem"
volumes:
- name: nfs-pvc-svnlan-cloud-disk
persistentVolumeClaim:
claimName: svnlan-cloud-disk
- name: nfs-pvc-svnlan-log30
hostPath:
path: /data0/logs/app
- name: mem
hostPath:
path: /dev/mem

Binary file not shown.

Binary file not shown.

644
pom.xml Normal file
View File

@ -0,0 +1,644 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.svnlan</groupId>
<artifactId>disk</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>disk</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatis-spring-boot>1.2.0</mybatis-spring-boot>
<mysql-connector>5.1.47</mysql-connector>
<spring-boot-starter-redis-version>1.3.2.RELEASE</spring-boot-starter-redis-version>
<lucene-core.version>7.5.0</lucene-core.version>
<tika-core.version>1.28.5</tika-core.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x-activation</artifactId>
<version>8.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.12.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.9.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.26</version>
</dependency>
<!-- 实现web功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-pdf</artifactId>
<version>23.4</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/aspose-pdf-23.4-crack.jar</systemPath>
</dependency>
<!-- Spring Boot Redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--使用redisson作为分布式锁-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.8</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot Mybatis 依赖 -->
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>${mybatis-spring-boot}</version>-->
<!-- </dependency>-->
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector}</version>
</dependency>
<!-- 支持发送邮件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- email -->
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.48.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
<!-- mp3处理工具 -->
<dependency>
<groupId>com.mpatric</groupId>
<artifactId>mp3agic</artifactId>
<version>0.9.1</version>
</dependency>
<!-- mp3处理工具 -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.9</version>
</dependency>
<!-- 解压rar所需的依赖 -->
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>4.0.0</version>
</dependency>
<!--Jsoup解析html-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- 阿里oss上传-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
<!-- apache的ant解压-->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.5</version>
</dependency>
<!-- 对 rar5 的支持 和其他众多压缩支持 可参考 package net.sf.sevenzipjbinding.ArchiveFormat; -->
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding</artifactId>
<version>9.20-2.00beta</version>
</dependency>
<dependency>
<groupId>net.sf.sevenzipjbinding</groupId>
<artifactId>sevenzipjbinding-all-platforms</artifactId>
<version>9.20-2.00beta</version>
</dependency>
<!-- apache的ant解压-->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.11.5</version>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.13</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.12</version>
</dependency>
<!-- word 转码-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>com.github.eljah</groupId>
<artifactId>xmindjbehaveplugin</artifactId>
<version>0.8</version>
</dependency>
<!--alibaba工具类-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- java服务器信息监控【oshi】 -->
<!-- java服务器信息监控【oshi】end -->
<!--pinyin4j-->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
<!--分页助手工具-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/eu.bitwalker/UserAgentUtils -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.21</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.6</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
</dependency>
<!--jpushclient-->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jmessage-client</artifactId>
<version>1.1.8</version>
</dependency>
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 解决 localDate 与 Date 映射的问题 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-typehandlers-jsr310</artifactId>
<version>1.0.2</version>
</dependency>
<!-- excel 导出 -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<!-- excel 导出 结束 -->
<!-- 基于 jvm 的缓存 -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.0</version>
</dependency>
<!-- dingding -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dingtalk</artifactId>
<version>1.5.58</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>2.0.0</version>
</dependency>
<!-- &lt;!&ndash; 模版引擎 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.thymeleaf</groupId>-->
<!-- <artifactId>thymeleaf</artifactId>-->
<!-- <version>3.0.15.RELEASE</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!-- new webdav -->
<dependency>
<groupId>com.ithit.webdav</groupId>
<artifactId>webdav-server</artifactId>
<version>6.2.9090-Beta</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/webdav-server-6.2.9090-Beta.jar</systemPath>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- JNA dependencies -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.13.0</version>
<exclusions>
<exclusion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
<!-- Search dependencies -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>${lucene-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>${lucene-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>${lucene-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>${tika-core.version}</version>
<exclusions>
<exclusion>
<artifactId>cxf-core</artifactId>
<groupId>org.apache.cxf</groupId>
</exclusion>
<exclusion>
<artifactId>cxf-rt-rs-client</artifactId>
<groupId>org.apache.cxf</groupId>
</exclusion>
<exclusion>
<artifactId>httpservices</artifactId>
<groupId>edu.ucar</groupId>
</exclusion>
<exclusion>
<artifactId>maven-scm-provider-svnexe</artifactId>
<groupId>org.apache.maven.scm</groupId>
</exclusion>
<exclusion>
<artifactId>maven-scm-api</artifactId>
<groupId>org.apache.maven.scm</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>c3p0</artifactId>
<groupId>c3p0</groupId>
</exclusion>
<exclusion>
<artifactId>httpclient</artifactId>
<groupId>org.apache.httpcomponents</groupId>
</exclusion>
<exclusion>
<artifactId>grib</artifactId>
<groupId>edu.ucar</groupId>
</exclusion>
<exclusion>
<artifactId>cdm</artifactId>
<groupId>edu.ucar</groupId>
</exclusion>
<exclusion>
<artifactId>unit-api</artifactId>
<groupId>javax.measure</groupId>
</exclusion>
<exclusion>
<artifactId>activation</artifactId>
<groupId>javax.activation</groupId>
</exclusion>
<exclusion>
<groupId>org.apache.sis.storage</groupId>
<artifactId>sis-netcdf</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.plugin</groupId>-->
<!-- <artifactId>spring-plugin-core</artifactId>-->
<!-- <version>2.0.0.RELEASE</version>-->
<!-- </dependency>-->
<!--<dependency>-->
<!--<groupId>com.svnlan</groupId>-->
<!--<artifactId>redis-lock</artifactId>-->
<!--<version>0.0.1-SNAPSHOT</version>-->
<!--</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
<overwrite>false</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- 覆盖原有文件 -->
<overwrite>true</overwrite>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<!-- 也可以用下面这样的方式指定相对url的方式指定outputDirectory <outputDirectory>target/classes</outputDirectory> -->
<!-- 待处理的资源定义 -->
<resources>
<resource>
<!-- 指定resources插件处理哪个目录下的资源文件 -->
<directory>src/main/resources/${package.environment}</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>lib</directory>
<targetPath>WEB-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>pufay</id>
<activation>
<property>
<name>env</name>
<value>pufay</value>
</property>
</activation>
<properties>
<package.environment>pufay</package.environment>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<property>
<name>env</name>
<value>dev</value>
</property>
</activation>
<properties>
<package.environment>dev</package.environment>
</properties>
</profile>
<profile>
<id>pre</id>
<activation>
<property>
<name>env</name>
<value>pre</value>
</property>
</activation>
<properties>
<package.environment>pre</package.environment>
</properties>
</profile>
<profile>
<id>itest</id>
<activation>
<property>
<name>env</name>
<value>itest</value>
</property>
</activation>
<properties>
<package.environment>itest</package.environment>
</properties>
</profile>
<profile>
<id>pro</id>
<activation>
<property>
<name>env</name>
<value>pro</value>
</property>
</activation>
<properties>
<package.environment>pro</package.environment>
</properties>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,122 @@
package com.svnlan;
import com.svnlan.annotation.EnableVisitRecord;
import com.svnlan.utils.SpringUtil;
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
@SpringBootApplication
// mapper 接口类扫描包配置
@MapperScan("com.svnlan.**.dao")
@EnableAsync
@EnableVisitRecord
@ServletComponentScan(basePackages = {"com.svnlan.interceptor", "com.svnlan.webdav"})
@Import(value={SpringUtil.class})
@EnableEncryptableProperties
public class DiskApplication {
@Bean
RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverterList = new ArrayList<>();
for (HttpMessageConverter<?> mc : restTemplate.getMessageConverters()) {
if (!(mc instanceof MappingJackson2XmlHttpMessageConverter)) {
messageConverterList.add(mc);
}
}
restTemplate.setMessageConverters(messageConverterList);
return restTemplate;
}
public static void main(String[] args) {
SpringApplication.run(DiskApplication.class, args);
}
/** 用做异步 */
@Bean(name = "asyncTaskExecutor")
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//核心线程数
taskExecutor.setCorePoolSize(3);
//线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
taskExecutor.setMaxPoolSize(20);
//缓存队列
taskExecutor.setQueueCapacity(15);
//许的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
taskExecutor.setKeepAliveSeconds(200);
//异步方法内部线程名称
taskExecutor.setThreadNamePrefix("async-disk-");
/**
* 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize如果还有任务到来就会采取任务拒绝策略
* 通常有以下四种策略
* ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
* ThreadPoolExecutor.DiscardPolicy也是丢弃任务但是不抛出异常
* ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务然后重新尝试执行任务重复此过程
* ThreadPoolExecutor.CallerRunsPolicy重试添加当前的任务自动重复调用 execute() 方法直到成功
*/
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.initialize();
return taskExecutor;
}
/**
* 默认线程池线程池
*
* @return Executor
*/
@Bean
public ThreadPoolTaskExecutor threadPoolDefault() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程数目
executor.setCorePoolSize(24);
//指定最大线程数
executor.setMaxPoolSize(64);
//队列中最大的数目
executor.setQueueCapacity(24);
//线程名称前缀
executor.setThreadNamePrefix("diskThreadPool_");
//rejection-policy当pool已经达到max size的时候如何处理新任务
//CALLER_RUNS不在新线程中执行任务而是由调用者所在的线程来执行
//对拒绝task的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//线程空闲后的最大存活时间
executor.setKeepAliveSeconds(120);
//加载
executor.initialize();
return executor;
}
@Bean(name="encryptorBean")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("WJHL2023");
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}

View File

@ -0,0 +1,70 @@
package com.svnlan.NettyWebchat.Common;
import com.svnlan.NettyWebchat.Domain.ClientInfo;
import com.svnlan.enums.BusinessTypeEnum;
import com.svnlan.utils.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.AttributeKey;
/**
* @Author:
* @Description:
*/
public class CommonHandler {
public static void setBaseClientInfo(ChannelHandlerContext ctx, FullHttpRequest req, String channelName, Boolean isCommon) {
//
setBaseClientInfo(ctx, req, channelName, isCommon, BusinessTypeEnum.COMMON.getCode());
}
public static void setBaseClientInfo(ChannelHandlerContext ctx, FullHttpRequest req, String channelName, Boolean isCommon,
String businessType) {
//记录roomName
AttributeKey<ClientInfo> attributeKey;
if (AttributeKey.exists("clientInfo")) {
attributeKey = AttributeKey.valueOf("clientInfo");
} else {
attributeKey = AttributeKey.newInstance("clientInfo");
}
//客户端信息写入
ClientInfo clientInfo = new ClientInfo();
clientInfo.setRoomName(channelName);
clientInfo.setUserAgent(req.headers().get("user-agent"));
clientInfo.setReferer(req.headers().get("referer"));
clientInfo.setIp(IpUtil.getIp(req, ctx));
clientInfo.setLoginTime(System.currentTimeMillis());
if (isCommon){
Long userId = getUserIdFromChannelName(channelName);
clientInfo.setUserId(userId);
}
clientInfo.setCommon(isCommon);
clientInfo.setBusinessType(businessType);
ctx.channel().attr(attributeKey).set(clientInfo);
}
private static Long getUserIdFromChannelName(String channelName) {
String hexUserId = channelName.split("_")[0];
return Long.valueOf(hexUserId, 16);
}
public static ClientInfo getClientInfo(Channel channel) {
ClientInfo clientInfo;
AttributeKey<ClientInfo> attributeKey = AttributeKey.valueOf("clientInfo");
try {
clientInfo = channel.attr(attributeKey).get();
} catch (Exception e){
LogUtil.error(e, "获取clientInfo 失败");
clientInfo = new ClientInfo();
}
if (clientInfo == null){
clientInfo = new ClientInfo();
}
return clientInfo;
}
public static ClientInfo getClientInfo(ChannelHandlerContext ctx) {
return getClientInfo(ctx.channel());
}
}

View File

@ -0,0 +1,58 @@
package com.svnlan.NettyWebchat.Common;
import com.svnlan.utils.BeanUtil;
import com.svnlan.utils.SpringUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
/**
* @Author:
* @Description:
*/
public class SpringManager {
//单例
private static SpringManager instance = new SpringManager();
private ApplicationContext ctx;
private WebApplicationContext mvcContext;
private DispatcherServlet dispatcherServlet;
private SpringManager() {
// ctx = new ClassPathXmlApplicationContext("spring.xml");
ctx = SpringUtil.getApplicationContext();
// mvcContext = new XmlWebApplicationContext();
// mvcContext.setConfigLocation("classpath:spring-mvc.xml");
// mvcContext.setParent(ctx);
BeanUtil beanUtil = SpringUtil.getBean(BeanUtil.class);
ServletContext servletContext = beanUtil.getServletContext();
mvcContext = beanUtil.getWebApplicationContext();
MockServletConfig servletConfig = new MockServletConfig(servletContext, "dispatcherServlet");
dispatcherServlet = new DispatcherServlet(mvcContext);
try {
dispatcherServlet.init(servletConfig);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SpringManager getInstance(){
return instance;
}
public ApplicationContext getSpringContext(){
return ctx;
}
public WebApplicationContext getMvcContext(){
return mvcContext;
}
public DispatcherServlet getDispatcherServlet(){
return dispatcherServlet;
}
}

View File

@ -0,0 +1,79 @@
package com.svnlan.NettyWebchat.Domain;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.RandomUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author:
* @Description:
*/
public class ChannelSupervise {
//游客
public static ConcurrentHashMap<String, ConcurrentHashMap<String, Channel>> visitorRooms = new ConcurrentHashMap<>();
//通用业务
public static ConcurrentHashMap<String, ConcurrentHashMap<Channel, Long>> commonRooms = new ConcurrentHashMap<>();
//扫码登录业务
public static ConcurrentHashMap<String, ConcurrentHashMap<Channel, String>> scanLoginRooms = new ConcurrentHashMap<>();
/** 聊天室内同步发送消息kafka */
public static final String SEND_ROOMMESSAGE_Netty = "sendRoomMessageNetty";
//服务标识 uuid
public static String uuid = RandomUtil.getuuid();
/**
* @Description: 发送通用返回结果
* @params: [ctx, code, type]
* @Return: void
* @Modified:
*/
public static void sendCommonReturn(ChannelHandlerContext ctx, String code, String type) {
CommonReturnMessage commonReturnMessage = new CommonReturnMessage(code, type);
ChannelSupervise.sendToUser(ctx, JsonUtils.beanToJson(commonReturnMessage));
}
/**
* @description: 发送通用返回结果
* @param ctx
* @param type
* @param code
* @param message
* @return void
*/
public static void sendCommonReturn(ChannelHandlerContext ctx, String type, String code, String message) {
CommonReturnMessage commonReturnMessage = new CommonReturnMessage(code, type, message);
ChannelSupervise.sendToUser(ctx, JsonUtils.beanToJson(commonReturnMessage));
}
public static String getRoomName(String uri) {
return uri.substring(uri.lastIndexOf("/") + 1);
}
public static void sendToUser(ChannelHandlerContext ctx, String s) {
sendToUser(ctx.channel(), s);
}
public static void sendToUser(Channel channel, String s){
if (channel == null){
return;
}
if (!channel.isWritable()){
LogUtil.error("无法写了,"
+ (channel.id() == null ? "" : channel.id().asLongText()) );
return;
}
try {
channel.writeAndFlush(new TextWebSocketFrame(s));
} catch (Exception e){
LogUtil.error(e, "netty消息发送失败, " + s);
}
}
}

View File

@ -0,0 +1,232 @@
package com.svnlan.NettyWebchat.Domain;
import com.svnlan.enums.BusinessTypeEnum;
/**
* @Author:
* @Description:
*/
public class ClientInfo {
private String userAgent;
private String ip;
private String roomName;
private Long userId;
private Boolean platformManager;
private String groupId;
private String name;
private Boolean isCommon;
private String from;
private Boolean isLogin;
private String uuid;
private Long loginTime;
//大班分组序号
private Integer groupIndex;
private String groupName;
//游客ID
private String visitorId;
private Boolean isDevice;
//业务类型:common-通用scanLogin-扫码登录
private String businessType = BusinessTypeEnum.COMMON.getCode();
private String referer;
//登录方式
private Integer CSLoginFrom;
//客服加密串
private String CServiceKey;
//上次发送消息的时间戳
private Long lastMsgTimestamp;
//是否客服人员
private Boolean isStaff;
//下线, 重复登录被踢
private Boolean offline;
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Boolean getPlatformManager() {
return platformManager;
}
public void setPlatformManager(Boolean platformManager) {
this.platformManager = platformManager;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getCommon() {
return isCommon;
}
public void setCommon(Boolean common) {
isCommon = common;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public Boolean getLogin() {
return isLogin;
}
public void setLogin(Boolean login) {
isLogin = login;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public Long getLoginTime() {
return loginTime;
}
public void setLoginTime(Long loginTime) {
this.loginTime = loginTime;
}
public Integer getGroupIndex() {
return groupIndex;
}
public void setGroupIndex(Integer groupIndex) {
this.groupIndex = groupIndex;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getBusinessType() {
return businessType;
}
public void setBusinessType(String businessType) {
this.businessType = businessType;
}
public String getVisitorId() {
return visitorId;
}
public void setVisitorId(String visitorId) {
this.visitorId = visitorId;
}
public Boolean getDevice() {
return isDevice;
}
public void setDevice(Boolean device) {
isDevice = device;
}
public String getReferer() {
return referer;
}
public void setReferer(String referer) {
this.referer = referer;
}
public Integer getCSLoginFrom() {
return CSLoginFrom;
}
public void setCSLoginFrom(Integer CSLoginFrom) {
this.CSLoginFrom = CSLoginFrom;
}
public String getCServiceKey() {
return CServiceKey;
}
public void setCServiceKey(String CServiceKey) {
this.CServiceKey = CServiceKey;
}
public Long getLastMsgTimestamp() {
return lastMsgTimestamp;
}
public void setLastMsgTimestamp(Long lastMsgTimestamp) {
this.lastMsgTimestamp = lastMsgTimestamp;
}
public Boolean getStaff() {
return isStaff;
}
public void setStaff(Boolean staff) {
isStaff = staff;
}
public Boolean getOffline() {
return offline;
}
public void setOffline(Boolean offline) {
this.offline = offline;
}
}

View File

@ -0,0 +1,46 @@
package com.svnlan.NettyWebchat.Domain;
/**
* @Author:
* @Description:
*/
public class CommonReturnMessage {
private String type;
private String code;
private String message;
public CommonReturnMessage(String code, String type) {
this.type = type;
this.code = code;
}
public CommonReturnMessage(String type, String code, String message) {
this.type = type;
this.code = code;
this.message = message;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,170 @@
package com.svnlan.NettyWebchat.Domain;
import java.util.List;
import java.util.Set;
/**
* @Author:
* @Description: 房间内广播
*/
public class RoomMsg {
/** 房间名 */
private String roomName;
/** 私聊 */
private Long uid;
/** 被屏蔽的session */
private String sessionId;
/** 被屏蔽的uid集合 */
private Set<Long> quarantineUid;
/** 消息体 */
private String message;
/** 发送给多个用户id */
private List<Long> userIdList;
/** 抽样发送比例 */
private Long sampleRate;
private Long sendToUid;
private String channelId;
private String groupNum;
private String groupName;
private Integer groupOnlineCount;
//是否公开课
private Integer isPublic;
//包含游客的抽样发送比例
private Long visitorSampleRate;
private String visitorId;
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Long getUid() {
return uid;
}
public void setUid(Long uid) {
this.uid = uid;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public Set<Long> getQuarantineUid() {
return quarantineUid;
}
public void setQuarantineUid(Set<Long> quarantineUid) {
this.quarantineUid = quarantineUid;
}
public List<Long> getUserIdList() {
return userIdList;
}
public void setUserIdList(List<Long> userIdList) {
this.userIdList = userIdList;
}
public Long getSampleRate() {
return sampleRate;
}
public void setSampleRate(Long sampleRate) {
this.sampleRate = sampleRate;
}
public Long getSendToUid() {
return sendToUid;
}
public void setSendToUid(Long sendToUid) {
this.sendToUid = sendToUid;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getGroupNum() {
return groupNum;
}
public void setGroupNum(String groupNum) {
this.groupNum = groupNum;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Integer getGroupOnlineCount() {
return groupOnlineCount;
}
public void setGroupOnlineCount(Integer groupOnlineCount) {
this.groupOnlineCount = groupOnlineCount;
}
public Integer getIsPublic() {
return isPublic;
}
public void setIsPublic(Integer isPublic) {
this.isPublic = isPublic;
}
public Long getVisitorSampleRate() {
return visitorSampleRate;
}
public void setVisitorSampleRate(Long visitorSampleRate) {
this.visitorSampleRate = visitorSampleRate;
}
public String getVisitorId() {
return visitorId;
}
public void setVisitorId(String visitorId) {
this.visitorId = visitorId;
}
}

View File

@ -0,0 +1,28 @@
package com.svnlan.NettyWebchat;
import com.svnlan.NettyWebchat.initializer.NettyServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Profile;
/**
* @Author:
* @Description:
* @Date:
*/
@Profile({"dev","test", "pre", "pro"})
@SpringBootApplication
//@EnableAsync
public class NettyApplication implements CommandLineRunner {
// public static void main(String[] args) {
// SpringApplication.run(NettyApplication.class);
// System.out.println("SpringBoot start");
// }
@Override
public void run(String... args) {
new NettyServer().initNetty();
// new NettyServer().start();
}
}

View File

@ -0,0 +1,27 @@
package com.svnlan.NettyWebchat.dto;
import lombok.Data;
/**
* @description: 扫码登录消息
*/
@Data
public class ScanLoginMessage {
//消息类型tvScanLogin-TV端;webScanLogin-web端appScanLogin-APP端
private String msgType;
//动作
private String action;
//动作值
private String actionVal;
//登录token
private String token;
//临时登录授权码
private String tempAuth;
//登录token的网校域名test.1x.cn
private String serverName;
}

View File

@ -0,0 +1,20 @@
package com.svnlan.NettyWebchat.dto;
import lombok.Data;
import java.util.Date;
/**
* @description: 扫码登录二维码存储信息
*/
@Data
public class ScanLoginQRDTO {
private String roomName;
//使用状态0-未使用1-已使用登录
private String state;
private Long userId;
//二维码生成时间
private Date gmtCreate;
}

View File

@ -0,0 +1,21 @@
package com.svnlan.NettyWebchat.dto;
import lombok.Data;
/**
* @description: 扫码登录结果信息
*/
@Data
public class ScanLoginResult {
private String action;
private String code;
private String message;
//TV或WEB用于登录的临时授权码
private String tempAuth;
//TV或WEB用于登录的网校域名如test.1x.cn
private String schoolDomain;
}

View File

@ -0,0 +1,16 @@
package com.svnlan.NettyWebchat.dto;
import lombok.Data;
/**
* @description: 临时授权码对应的TOKEN信息
*/
@Data
public class TempAuthDTO {
//登录TOKEN
private String token;
//
private String roomName;
}

View File

@ -0,0 +1,47 @@
package com.svnlan.NettyWebchat.initializer;
import com.svnlan.utils.LogUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.stereotype.Service;
/**
* @Author:
* @Description: 服务启动
* @Date:
*/
@Service
public class NettyServer {
public void initNetty(){
new Thread(() -> new NettyServer().start()).start();
}
public void start(){
LogUtil.info("正在启动websocket服务器");
NioEventLoopGroup boss = new NioEventLoopGroup();
NioEventLoopGroup work = new NioEventLoopGroup();
try {
LogUtil.info("availableProcessors, " + Runtime.getRuntime().availableProcessors());
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss,work);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.childHandler(new WebSocketChannelInitializer());
//设置高低水位
bootstrap.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(32 * 1024,64 * 1024));
Channel channel = bootstrap.bind(81).sync().channel();
LogUtil.info("webSocket服务器启动成功"+channel);
channel.closeFuture().sync();
} catch (InterruptedException e) {
LogUtil.error(e,"运行出错");
}finally {
boss.shutdownGracefully();
work.shutdownGracefully();
LogUtil.info("websocket服务器已关闭");
}
}
}

View File

@ -0,0 +1,49 @@
package com.svnlan.NettyWebchat.initializer;
import com.svnlan.NettyWebchat.service.WebSocketHandler;
import com.svnlan.NettyWebchat.service.impl.HeartBeatServerHandler;
import com.svnlan.NettyWebchat.service.impl.HttpHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.NettyRuntime;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.internal.SystemPropertyUtil;
import java.util.concurrent.TimeUnit;
/**
* @Author:
* @Description:
* @Date:
*/
public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> {
private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(2, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
//主业务线程池
private static final EventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(DEFAULT_EVENT_LOOP_THREADS);
//耗时业务线程池
private static final EventExecutorGroup largeConsumptionExecutorGroup = new DefaultEventExecutorGroup(DEFAULT_EVENT_LOOP_THREADS);
// private static final ChannelTrafficShapingHandler shapingHandler = new ChannelTrafficShapingHandler(2000);
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast("logging",new LoggingHandler("DEBUG"));//设置log监听器并且日志级别为debug方便观察运行流程
ch.pipeline().addLast("http-codec",new HttpServerCodec());//设置解码器
ch.pipeline().addLast("aggregator",new HttpObjectAggregator(1024 * 20));//聚合器使用websocket会用到
ch.pipeline().addLast("http-chunked",new ChunkedWriteHandler());//用于大数据的分区传输
ch.pipeline().addLast("compress", new WebSocketServerCompressionHandler());
ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(0, 0, 120, TimeUnit.SECONDS));
ch.pipeline().addLast(new HeartBeatServerHandler());
// ch.pipeline().addLast(shapingHandler);
// ch.pipeline().addLast("handler", new BaseEventHandler());
ch.pipeline().addLast(eventExecutorGroup, new WebSocketHandler());//自定义的业务handler
ch.pipeline().addLast(eventExecutorGroup, new HttpHandler());//自定义的业务handler
}
}

View File

@ -0,0 +1,20 @@
package com.svnlan.NettyWebchat.service;
import com.svnlan.NettyWebchat.Domain.RoomMsg;
/**
* @Author:
* @Description:
*/
public interface NettyBroadcastService {
/**
* @description: 发给某房间指定某channel消息
* @param roomMsg
* @return void
*/
void sendScanLoginMessage(RoomMsg roomMsg);
}

View File

@ -0,0 +1,16 @@
package com.svnlan.NettyWebchat.service;
import io.netty.channel.ChannelHandlerContext;
/**
* @description: 扫码登录
*/
public interface NettyLoginService {
void connect(ChannelHandlerContext ctx, String channelName);
void disconnect(ChannelHandlerContext ctx);
void receiveMessage(ChannelHandlerContext ctx, String message);
}

View File

@ -0,0 +1,200 @@
package com.svnlan.NettyWebchat.service;
import com.svnlan.NettyWebchat.Common.CommonHandler;
import com.svnlan.NettyWebchat.Domain.ChannelSupervise;
import com.svnlan.NettyWebchat.Domain.ClientInfo;
import com.svnlan.enums.BusinessTypeEnum;
import com.svnlan.utils.BeanUtil;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.SpringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil;
import static io.netty.handler.codec.http.HttpUtil.isKeepAlive;
/**
* @Author:
* @Description:
* @Date:
*/
public class WebSocketHandler extends SimpleChannelInboundHandler<Object>{
private WebSocketServerHandshaker handShaker;
//连接
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//添加连接
LogUtil.info("客户端加入连接:" + ctx.channel().id().asLongText());
// ChannelSupervise.addChannel(ctx.channel());
}
//读信息
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
if (msg instanceof FullHttpRequest){
//以http请求形式接入但是走的是websocket
LogUtil.info("websocket WebSocketHandler FullHttpRequest");
handleHttpRequest(ctx, (FullHttpRequest) msg);
}else if (msg instanceof WebSocketFrame){
//处理websocket客户端的消息
LogUtil.info("websocket WebSocketHandler WebSocketFrame");
handlerWebSocketFrame(ctx, (WebSocketFrame) msg);
}else {
LogUtil.info("websocket WebSocketHandler other");
// ReferenceCountUtil.release(msg)
};
} catch (Exception e){
LogUtil.error(e, "read0出错");
}
}
//断开
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//断开连接
// LogUtil.info("客户端断开连接:"+ctx.channel());
ClientInfo clientInfo = (ClientInfo) ctx.channel().attr(AttributeKey.valueOf("clientInfo")).get();
LogUtil.info("断开连接, " + JsonUtils.beanToJson(clientInfo));
try {
if (clientInfo == null){
return;
}
//扫码登录
if(BusinessTypeEnum.SCAN_LOGIN.getCode().equals(clientInfo.getBusinessType())) {
//
getLoginService().disconnect(ctx);
}
} catch (Exception e) {
LogUtil.error(e, "断开处理失败" + JsonUtils.beanToJson(clientInfo));
}
}
private NettyLoginService getLoginService() {
BeanUtil beanUtil = SpringUtil.getBean(BeanUtil.class);
return beanUtil.getNettyLoginService();
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
/**
* 唯一的一次http请求用于创建websocket
* */
private void handleHttpRequest(ChannelHandlerContext ctx,
FullHttpRequest req) {
//要求Upgrade为websocket过滤掉get/Post
LogUtil.info("request info : " + req.decoderResult().isSuccess() + ", " + req.headers().get("Upgrade")
+ ", " + req.headers().get("Connection")
);
if (!req.decoderResult().isSuccess()) {
//\\\\(不是)若不是websocket方式则创建BAD_REQUEST的req返回给客户端
// sendHttpResponse(ctx, req, new DefaultFullHttpResponse(
// HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
//处理http请求
ctx.fireChannelRead(req);
return;
}
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
"ws://localhost:8081/websocket/webchat/xx", null, true, 2048);
handShaker = wsFactory.newHandshaker(req);
if (handShaker == null) {
WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
} else {
System.out.println("handleHttpRequest url....." + req.uri());
if (req.uri().indexOf("/websocket/webchat/scanLogin/") == 0){ //扫码登录
String channelName = ChannelSupervise.getRoomName(req.uri());
NettyLoginService nettyLoginService = getLoginService();
CommonHandler.setBaseClientInfo(ctx, req, channelName, false, BusinessTypeEnum.SCAN_LOGIN.getCode());
nettyLoginService.connect(ctx, channelName);
}
handShaker.handshake(ctx.channel(), req);
}
}
/**
* 拒绝不合法的请求并返回错误信息
* */
private static void sendHttpResponse(ChannelHandlerContext ctx,
FullHttpRequest req, DefaultFullHttpResponse res) {
// 返回应答给客户端
if (res.status().code() != 200) {
ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(),
CharsetUtil.UTF_8);
res.content().writeBytes(buf);
buf.release();
}
ChannelFuture f = ctx.channel().writeAndFlush(res);
// 如果是非Keep-Alive关闭连接
if (!isKeepAlive(req) || res.status().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE);
}
}
private void handlerWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame){
LogUtil.info("webSocketLog handlerWebSocketFrame");
// 判断是否关闭链路的指令
if (frame instanceof CloseWebSocketFrame) {
LogUtil.info("webSocketLog CloseWebSocketFrame");
handShaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
return;
}
// 判断是否ping消息
if (frame instanceof PingWebSocketFrame || frame instanceof PongWebSocketFrame) {
LogUtil.info("webSocketLog PingWebSocketFrame or PongWebSocketFrame");
// ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content().retain()));
return;
}
// 其他格式帧
ClientInfo clientInfo;
try {
clientInfo = CommonHandler.getClientInfo(ctx.channel());
LogUtil.info("webSocketLog clientInfo=" + JsonUtils.beanToJson(clientInfo));
} catch (Exception e){
LogUtil.error(e.getMessage(), "非text消息, 客户端信息获取失败. ");
clientInfo = new ClientInfo();
}
if (!(frame instanceof TextWebSocketFrame)) {
try {
LogUtil.info(String.format(
"%s frame types not supported", frame.getClass().getName()) + ", " + JsonUtils.beanToJson(clientInfo));
} catch (Exception e){
LogUtil.error(e.getMessage(), "非text消息, ");
}
return;
}
if (clientInfo.getRoomName() == null){
return;
}
// 返回应答消息
String message = ((TextWebSocketFrame) frame).text();
LogUtil.info("服务端收到:" + message);
if (message.equals("1")){ //保活
ChannelSupervise.sendToUser(ctx, "2");
return;
}
String businessType = clientInfo.getBusinessType();
if(businessType.equals(BusinessTypeEnum.SCAN_LOGIN.getCode())) { //扫码登录
//
getLoginService().receiveMessage(ctx, message);
}
}
}

View File

@ -0,0 +1,27 @@
package com.svnlan.NettyWebchat.service.impl;
import com.svnlan.utils.LogUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
/**
* @Author:
* @Description: 心跳检测
* @Date:
*/
public class HeartBeatServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent){
IdleStateEvent event = (IdleStateEvent)evt;
if (event.state() == IdleState.READER_IDLE){
LogUtil.info("关闭这个不活跃通道!, " + ctx.channel().id().asLongText());
ctx.channel().close();
}
} else {
super.userEventTriggered(ctx,evt);
}
}
}

View File

@ -0,0 +1,36 @@
package com.svnlan.NettyWebchat.service.impl;
import com.svnlan.NettyWebchat.Common.SpringManager;
import com.svnlan.NettyWebchat.utils.ResponseUtil;
import com.svnlan.NettyWebchat.utils.RequestTransUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* @Author:
* @Description:
* @Date:
*/
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest) throws Exception {
// boolean isKeepAlive = HttpUtil.isKeepAlive(req);
// FullHttpRequest fullHttpRequest = (FullHttpRequest) req;
fullHttpRequest.retain();
MockHttpServletRequest servletRequest = RequestTransUtil.transRequest2Spring(fullHttpRequest);
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
try {
SpringManager.getInstance().getDispatcherServlet().service(servletRequest, servletResponse);
FullHttpResponse nettyResponse = RequestTransUtil.transResponse2Netty(servletResponse);
ResponseUtil.sendHttpResponse(ctx, fullHttpRequest, nettyResponse);
} catch (Exception e) {
ResponseUtil.sendHttpResponse(ctx, fullHttpRequest, ResponseUtil.get500Response());
}
// NettyWebchatService webchatService = SpringUtil.getBean(NettyWebchatService.class);
// webchatService.aaa(ctx, fullHttpRequest);
}
}

View File

@ -0,0 +1,38 @@
package com.svnlan.NettyWebchat.service.impl;
import com.svnlan.NettyWebchat.Domain.ChannelSupervise;
import com.svnlan.NettyWebchat.Domain.RoomMsg;
import com.svnlan.NettyWebchat.service.NettyBroadcastService;
import com.svnlan.utils.*;
import io.netty.channel.Channel;
import org.springframework.stereotype.Service;
/**
* @Author:
* @Description:
*/
@Service
public class NettyBroadcastServiceImpl implements NettyBroadcastService {
@Override
public void sendScanLoginMessage(RoomMsg roomMsg) {
String roomMame = roomMsg.getRoomName();
if (StringUtil.isEmpty(roomMsg.getChannelId())) {
if (ChannelSupervise.scanLoginRooms.get(roomMame) != null) {
for (Channel channel : ChannelSupervise.scanLoginRooms.get(roomMame).keySet()) {
ChannelSupervise.sendToUser(channel, roomMsg.getMessage());
}
}
} else {
if (ChannelSupervise.scanLoginRooms.get(roomMame) != null) {
for (Channel channel : ChannelSupervise.scanLoginRooms.get(roomMame).keySet()) {
if (channel.id().asLongText().equals(roomMsg.getChannelId())) {
ChannelSupervise.sendToUser(channel, roomMsg.getMessage());
}
}
}
}
}
}

View File

@ -0,0 +1,397 @@
package com.svnlan.NettyWebchat.service.impl;
import com.svnlan.NettyWebchat.Common.CommonHandler;
import com.svnlan.NettyWebchat.Domain.ChannelSupervise;
import com.svnlan.NettyWebchat.Domain.ClientInfo;
import com.svnlan.NettyWebchat.Domain.CommonReturnMessage;
import com.svnlan.NettyWebchat.Domain.RoomMsg;
import com.svnlan.NettyWebchat.dto.ScanLoginMessage;
import com.svnlan.NettyWebchat.dto.ScanLoginQRDTO;
import com.svnlan.NettyWebchat.dto.ScanLoginResult;
import com.svnlan.NettyWebchat.dto.TempAuthDTO;
import com.svnlan.NettyWebchat.service.NettyBroadcastService;
import com.svnlan.NettyWebchat.service.NettyLoginService;
import com.svnlan.common.GlobalConfig;
import com.svnlan.enums.BusinessTypeEnum;
import com.svnlan.enums.ScanLoginActionEnum;
import com.svnlan.enums.ScanLoginMsgTypeEnum;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.utils.*;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* @description: 扫码登录处理
* @author
*/
@Service
public class NettyLoginServiceImpl implements NettyLoginService {
@Autowired
private LoginUserUtil loginUserUtil;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Value("${scan.login.code.expire}")
private Long scanLoginCodeExpire;
@Resource
private NettyBroadcastService newBroadcastService;
@Override
public void connect(ChannelHandlerContext ctx, String channelName) {
BeanUtil beanUtil = SpringUtil.getBean(BeanUtil.class);
StringRedisTemplate stringRedisTemplate = beanUtil.getStringRedisTemplate();
//查询key是否存在
String val = stringRedisTemplate.opsForValue().get(GlobalConfig.SCAN_LOGIN_CODE_REDIS_KEY + channelName);
//二维码已经失效请重新扫描或不存在
if (StringUtil.isEmpty(val)){
LogUtil.error("[扫码登录]建立连接时检测二维码已经失效>>>channelName:" + channelName);
}
}
@Override
public void disconnect(ChannelHandlerContext ctx) {
ClientInfo clientInfo = CommonHandler.getClientInfo(ctx);
String roomName = clientInfo.getRoomName();
//
HashOperations hashOperations = this.stringRedisTemplate.opsForHash();
String channelId = ctx.channel().id().asLongText();
//删除内存值
if (ChannelSupervise.scanLoginRooms.get(roomName) != null) {
//
ChannelSupervise.scanLoginRooms.get(roomName).remove(ctx.channel());
}
//删除REDIS缓存
//扫码登录的 channelId与标识ID(loginId)的关联关系
String lcRelationRedisKey = String.format(GlobalConfig.ScanLoginIdChannelRelation, roomName);
//删除扫码登录的 APP token与 生成的临时授权码的关联关系的REDIS缓存
String tempAuthRelationRedisKey = String.format(GlobalConfig.ScanLoginTempAuthRelation, roomName);
Map<String, String> lcMap = hashOperations.entries(lcRelationRedisKey);
Iterator iterator = lcMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
String tempChannelId = entry.getKey();
String loginId = entry.getValue();
if(tempChannelId.equals(channelId) && hashOperations.hasKey(tempAuthRelationRedisKey, loginId)) {
hashOperations.delete(tempAuthRelationRedisKey, loginId);
}
}
//删除channelId与标识ID(loginId)的关联关系的REDIS缓存
hashOperations.delete(lcRelationRedisKey, channelId);
ScanLoginResult scanLoginResult = new ScanLoginResult();
scanLoginResult.setAction("disconnect");
scanLoginResult.setCode("200");
scanLoginResult.setMessage("disconnect success");
RoomMsg roomMsg = new RoomMsg();
roomMsg.setRoomName(roomName);
roomMsg.setMessage(JsonUtils.beanToJson(scanLoginResult));
roomMsg.setChannelId(channelId);
newBroadcastService.sendScanLoginMessage(roomMsg);
}
@Override
public void receiveMessage(ChannelHandlerContext ctx, String message) {
String prefix = "[扫码登录]收到处理消息>>>";
ClientInfo clientInfo = CommonHandler.getClientInfo(ctx);
String roomName = clientInfo.getRoomName();
//校验房间号不能为空
if (StringUtil.isEmpty(roomName)){
ChannelSupervise.sendCommonReturn(ctx, "400", "rcv");
return;
}
String channelId = ctx.channel().id().asLongText();
String paramTip = String.format("<<<房间号:%s内容:%schannelId%s", roomName, message, channelId);
LogUtil.info(prefix + " start" + paramTip);
//校验二维码房间号是否已失效
BeanUtil beanUtil = SpringUtil.getBean(BeanUtil.class);
StringRedisTemplate stringRedisTemplate = beanUtil.getStringRedisTemplate();
String redisKey = GlobalConfig.SCAN_LOGIN_CODE_REDIS_KEY + roomName;
//查询key是否存在
Object qrCodeObj = stringRedisTemplate.opsForValue().get(redisKey);
Date qrGmtCreate = null;
if(null == qrCodeObj) {
CommonReturnMessage commonReturnMessage = new CommonReturnMessage(BusinessTypeEnum.SCAN_LOGIN.getCode(),
CodeMessageEnum.QR_INVALID.getCode(), "二维码已失效");
LogUtil.error(prefix + "二维码已失效" + paramTip);
ChannelSupervise.sendToUser(ctx, JsonUtils.beanToJson(commonReturnMessage));
return;
} else {
ScanLoginQRDTO scanLoginQRDTO = JsonUtils.jsonToBean(StringUtil.changeNullToEmpty(qrCodeObj), ScanLoginQRDTO.class);
qrGmtCreate = scanLoginQRDTO.getGmtCreate();
}
if(StringUtil.isEmpty(message)) {
ChannelSupervise.sendCommonReturn(ctx, BusinessTypeEnum.SCAN_LOGIN.getCode(),
CodeMessageEnum.shareErrorParam.getCode(), "消息为空无效");
}
ScanLoginMessage scanLoginMessage = null;
try {
scanLoginMessage = JsonUtils.jsonToBean(message, ScanLoginMessage.class);
} catch (Exception e) {
LogUtil.error(e, prefix + "消息内容格式有误" + paramTip);
ChannelSupervise.sendCommonReturn(ctx, BusinessTypeEnum.SCAN_LOGIN.getCode(),
CodeMessageEnum.shareErrorParam.getCode(), "消息内容格式有误");
}
//处理接收到的消息
this.handleMessage(prefix, scanLoginMessage, roomName, ctx, qrGmtCreate);
}
/**
* @description: 处理接收到的消息
* @param prefix
* @param scanLoginMessage
* @param roomName
* @param ctx
* @param qrGmtCreate
* @return
*/
private void handleMessage(String prefix, ScanLoginMessage scanLoginMessage, String roomName, ChannelHandlerContext ctx, Date qrGmtCreate) {
String msgType = StringUtil.trim(scanLoginMessage.getMsgType());
String action = StringUtil.trim(scanLoginMessage.getAction());
String actionVal = StringUtil.trim(scanLoginMessage.getActionVal());
String token = StringUtil.trim(scanLoginMessage.getToken());
String resultAction = action;
String serverName = StringUtil.trim(scanLoginMessage.getServerName());
String code = CodeMessageEnum.success.getCode();
String message = "";
String tempAuth = scanLoginMessage.getTempAuth();
String schoolDomain = null;
//是否原路回消息
Boolean isReturnMsg = Boolean.TRUE;
//是否转发消息
Boolean isTransfer = Boolean.FALSE;
//转发的接收人loginId标识
String transferReceiverId = "";
String transferAction = action;
String transferCode = "200";
String transferMessage = "";
//扫码登录的 channelId与标识ID(loginId)的关联关系
String lcRelationRedisKey = String.format(GlobalConfig.ScanLoginIdChannelRelation, roomName);
//扫码登录的 APP token与 生成的临时授权码的关联关系
String tempAuthRelationRedisKey = String.format(GlobalConfig.ScanLoginTempAuthRelation, roomName);
HashOperations hashOperations = this.stringRedisTemplate.opsForHash();
ValueOperations valueOperations = this.stringRedisTemplate.opsForValue();
try {
String channelId = ctx.channel().id().asLongText();
if(!ScanLoginMsgTypeEnum.contains(msgType)) {
code = CodeMessageEnum.shareErrorParam.getCode();
message = "msgType值非法";
}
LoginUser loginUser = null;
//若是TVWEB端
if(!msgType.equals(ScanLoginMsgTypeEnum.APP_SCAN_LOGIN.getCode())) {
if(!ScanLoginActionEnum.containsTvWebAction(action)) {
code = CodeMessageEnum.success.getCode();
message = "action值非法";
} else {
//
if(action.equals(ScanLoginActionEnum.FEED_BACK.getCode())) {
if(!actionVal.equals("success") && !actionVal.equals("fail")) {
code = CodeMessageEnum.shareErrorParam.getCode();
message = "actionVal值非法";
}
}
}
} else { //若是APP端
if(!ScanLoginActionEnum.containsAppAction(action)) {
code = CodeMessageEnum.shareErrorParam.getCode();
message = "action值非法";
} else {
//校验TOKEN
if (StringUtil.isEmpty(token)) {
code = CodeMessageEnum.errorAdminAuth.getCode();
message = "token不能为空";
} else {
if (StringUtil.isEmpty(serverName)) {
code = CodeMessageEnum.shareErrorParam.getCode();
message = "serverName不能为空";
} else {
//
loginUser = this.loginUserUtil.getLoginUser(serverName, token);
if (loginUser == null || loginUser.getUserID() == null) {
code = CodeMessageEnum.errorAdminAuth.getCode();
message = CodeMessageEnum.errorAdminAuth.getMsg();
}
}
}
}
}
String loginId = roomName;
if("200".equals(code) || "common.success".equals(code)) {
//若是APP端
if (msgType.equals(ScanLoginMsgTypeEnum.APP_SCAN_LOGIN.getCode())) {
loginId = token;
}
//动作
//若是confirm-确认连接时
if(ScanLoginActionEnum.CONFIRM.getCode().equals(action)) {
//置房间channel标识的实例内存
ChannelSupervise.scanLoginRooms.putIfAbsent(roomName, new ConcurrentHashMap<>());
ChannelSupervise.scanLoginRooms.get(roomName).put(ctx.channel(), loginId);
//置redis缓存
hashOperations.put(lcRelationRedisKey, channelId, loginId);
this.stringRedisTemplate.expire(lcRelationRedisKey, this.scanLoginCodeExpire, TimeUnit.MINUTES);
ClientInfo clientInfo = CommonHandler.getClientInfo(ctx);
clientInfo.setLogin(true);
ctx.channel().attr(AttributeKey.valueOf("clientInfo")).set(clientInfo);
//若是APP端则得转发消息通知下TV或WEB端扫描成功
if(ScanLoginMsgTypeEnum.APP_SCAN_LOGIN.getCode().equals(msgType)) {
transferAction = ScanLoginActionEnum.SCAN.getCode();
transferMessage = "扫描成功";
isTransfer = Boolean.TRUE;
transferReceiverId = roomName;
}
}
//是auth-登录授权APP端
else if(ScanLoginActionEnum.AUTH.getCode().equals(action)) {
//若多次授权存在则返回原有的
if(hashOperations.hasKey(tempAuthRelationRedisKey, token)) {
tempAuth = StringUtil.changeNullToEmpty(hashOperations.get(tempAuthRelationRedisKey, token));
}
//否则产生新的临时授权码给TVWEB
else {
tempAuth = GlobalConfig.ScanLoginTempAuthRedisKeyPrefix + RandomUtil.getuuid();
//置APP token与生成的临时授权码的关联关系 redis缓存
hashOperations.put(tempAuthRelationRedisKey, token, tempAuth);
Long currentML = System.currentTimeMillis();
//剩余有效期
Long remainExpire = qrGmtCreate.getTime() + this.scanLoginCodeExpire*60*1000 - currentML;
this.stringRedisTemplate.expire(tempAuthRelationRedisKey, remainExpire, TimeUnit.MILLISECONDS);
TempAuthDTO tempAuthDTO = new TempAuthDTO();
tempAuthDTO.setToken(token);
tempAuthDTO.setRoomName(roomName);
// 临时登录授权码与APP登录TOKEN的 REDIS缓存
valueOperations.set(tempAuth, JsonUtils.beanToJson(tempAuthDTO), this.scanLoginCodeExpire, TimeUnit.MINUTES);
}
//app扫码登录对应的网校域名
schoolDomain = serverName;
//暂不原路回消息给APP
isReturnMsg = Boolean.FALSE;
//转发消息给TV或WEB端
transferAction = ScanLoginActionEnum.AUTH.getCode();
transferMessage = "APP授权成功";
isTransfer = Boolean.TRUE;
transferReceiverId = roomName;
}
//是feedBack-反馈登录结果TV或WEB端
else if(ScanLoginActionEnum.FEED_BACK.getCode().equals(action)
&& !msgType.equals(ScanLoginMsgTypeEnum.APP_SCAN_LOGIN.getCode())) {
//action为feedBack时则必填
//校验临时授权码
if (StringUtil.isEmpty(tempAuth)) {
code = CodeMessageEnum.errorAdminAuth.getCode();
message = "tempAuth不能为空";
} else {
Object appTokenObj = valueOperations.get(tempAuth);
if(ObjectUtils.isEmpty(appTokenObj)) {
code = CodeMessageEnum.TEMP_AUTH_INVALID.getCode();
message = CodeMessageEnum.TEMP_AUTH_INVALID.getMsg();
}
//转发给对应的APP通知下 TV或WEB登录结果
else {
TempAuthDTO tempAuthDTO = JsonUtils.jsonToBean(StringUtil.changeNullToEmpty(appTokenObj), TempAuthDTO.class);
String appToken = tempAuthDTO.getToken();
isTransfer = Boolean.TRUE;
transferReceiverId = appToken;
transferAction = ScanLoginActionEnum.AUTH.getCode();
//action为feedBack时登录成功则放success否则放fail
if(!"success".equals(actionVal)) {
transferCode = CodeMessageEnum.QR_INVALID.getCode();
transferMessage = CodeMessageEnum.QR_INVALID.getMsg();
}
//若是成功
else {
//删除临时授权码的REDIS缓存
this.stringRedisTemplate.delete(tempAuth);
//删除二维码的缓存使失效
this.stringRedisTemplate.delete(GlobalConfig.SCAN_LOGIN_CODE_REDIS_KEY + roomName);
}
}
}
}
}
} catch (Exception e) {
LogUtil.error(e, prefix + "未知异常");
code = CodeMessageEnum.shareErrorParam.getCode();
message = "未知异常,请重试";
}
//原路回消息
if(isReturnMsg) {
ScanLoginResult scanLoginResult = new ScanLoginResult();
scanLoginResult.setAction(resultAction);
scanLoginResult.setCode(code);
scanLoginResult.setMessage(message);
String resultJson = JsonUtils.beanToJson(scanLoginResult);
LogUtil.info(prefix + "原路回消息结果内容:" + resultJson);
//发送消息回去
ChannelSupervise.sendToUser(ctx, resultJson);
}
//转发消息
if(isTransfer) {
ScanLoginResult scanLoginResult = new ScanLoginResult();
scanLoginResult.setAction(transferAction);
scanLoginResult.setCode(transferCode);
scanLoginResult.setMessage(transferMessage);
scanLoginResult.setTempAuth(tempAuth);
scanLoginResult.setSchoolDomain(schoolDomain);
RoomMsg roomMsg = new RoomMsg();
roomMsg.setRoomName(roomName);
roomMsg.setMessage(JsonUtils.beanToJson(scanLoginResult));
Map<String, String> lcMap = hashOperations.entries(lcRelationRedisKey);
Iterator iterator = lcMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
String channelId = entry.getKey();
String loginId = entry.getValue();
if(transferReceiverId.equals(loginId)) {
roomMsg.setChannelId(channelId);
String msg = JsonUtils.beanToJson(roomMsg);
LogUtil.info(prefix + "转发消息内容:" + msg);
newBroadcastService.sendScanLoginMessage(roomMsg);
}
}
}
}
}

View File

@ -0,0 +1,99 @@
package com.svnlan.NettyWebchat.utils;
import com.svnlan.NettyWebchat.Common.SpringManager;
import com.svnlan.utils.ParamUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
import javax.servlet.ServletContext;
import java.util.Map;
/**
* @Author:
* @Description:
*/
public class RequestTransUtil {
//Netty转Spring请求
public static MockHttpServletRequest transRequest2Spring(FullHttpRequest nettyRequest){
UriComponents uriComponents = UriComponentsBuilder.fromUriString(nettyRequest.uri()).build();
ServletContext servletContext = SpringManager.getInstance().getDispatcherServlet().getServletConfig().getServletContext();
MockHttpServletRequest servletRequest = new MockHttpServletRequest(servletContext);
servletRequest.setRequestURI(uriComponents.getPath());
servletRequest.setPathInfo(uriComponents.getPath());
servletRequest.setMethod(nettyRequest.method().name());
if (uriComponents.getScheme() != null) {
servletRequest.setScheme(uriComponents.getScheme());
}
if (uriComponents.getHost() != null) {
servletRequest.setServerName(uriComponents.getHost());
}
if (uriComponents.getPort() != -1) {
servletRequest.setServerPort(uriComponents.getPort());
}
for (String name : nettyRequest.headers().names()) {
servletRequest.addHeader(name, nettyRequest.headers().get(name));
}
ByteBuf content = nettyRequest.content();
content.readerIndex(0);
byte[] data = new byte[content.readableBytes()];
content.readBytes(data);
servletRequest.setContent(data);
if (uriComponents.getQuery() != null) {
String query = UriUtils.decode(uriComponents.getQuery(), "UTF-8");
servletRequest.setQueryString(query);
}
Map<String, String> paramMap = ParamUtil.getRequestParams(nettyRequest);
if(! CollectionUtils.isEmpty(paramMap)){
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
servletRequest.addParameter(entry.getKey(), entry.getValue());
}
}
return servletRequest;
}
//WebSocket转Spring请求
public static MockHttpServletRequest transFrame2Spring(WebSocketFrame frame, String url){
ServletContext servletContext = SpringManager.getInstance().getDispatcherServlet().getServletConfig().getServletContext();
MockHttpServletRequest servletRequest = new MockHttpServletRequest(servletContext);
servletRequest.setRequestURI(url);
servletRequest.setPathInfo(url);
servletRequest.setMethod(HttpMethod.POST.name());
servletRequest.setContentType(HttpHeaderValues.TEXT_PLAIN.toString());
if(frame != null){
ByteBuf content = frame.content();
content.readerIndex(0);
byte[] data = new byte[content.readableBytes()];
content.readBytes(data);
servletRequest.setContent(data);
}
return servletRequest;
}
//Spring转Netty响应
public static FullHttpResponse transResponse2Netty(MockHttpServletResponse servletResponse){
HttpResponseStatus status = HttpResponseStatus.valueOf(servletResponse.getStatus());
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.wrappedBuffer(servletResponse.getContentAsByteArray()));
for (String name : servletResponse.getHeaderNames()) {
for (Object value : servletResponse.getHeaderValues(name)) {
response.headers().add(name, value);
}
}
return response;
}
}

View File

@ -0,0 +1,70 @@
package com.svnlan.NettyWebchat.utils;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import org.apache.commons.lang3.StringUtils;
/**
* @Author:
* @Description:
*/
public class ResponseUtil {
/**
* 获取400响应
*/
public static FullHttpResponse get400Response(){
return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST);
}
/**
* 获取200响应
*/
public static FullHttpResponse get200Response(String content){
return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(content.getBytes()));
}
/**
* 获取500响应
*/
public static FullHttpResponse get500Response(){
return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR, Unpooled.wrappedBuffer("服务器异常".getBytes()));
}
/**
* 发送HTTP响应
*/
public static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, FullHttpResponse response) {
// 返回应答给客户端
if (response.status().code() != 200) {
ByteBufUtil.writeUtf8(response.content(), response.status().toString());
}
//添加header描述length避免客户端接收不到数据
if(StringUtils.isEmpty(response.headers().get(HttpHeaderNames.CONTENT_TYPE))){
response.headers().add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN);
}
if(StringUtils.isEmpty(response.headers().get(HttpHeaderNames.CONTENT_LENGTH))){
response.headers().add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
}
//解决跨域的问题
response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN,"*");
response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS,"*");//允许headers自定义
response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS,"GET, POST, PUT,DELETE");
response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS,"true");
// 如果是非Keep-Alive关闭连接
if (! HttpUtil.isKeepAlive(request) || response.status().code() != 200) {
response.headers().add(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
ctx.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}else{
response.headers().add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
ctx.channel().writeAndFlush(response);
}
}
}

View File

@ -0,0 +1,11 @@
package com.svnlan.annotation;
import javax.validation.groups.Default;
/**
* 创建组
*
* @author lingxu 2023/05/16 16:46
*/
public interface CreateGroup extends Default {
}

View File

@ -0,0 +1,21 @@
package com.svnlan.annotation;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.lang.annotation.*;
/**
* 开启访问数统计
*
* @author lingxu 2023/04/11 15:57
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)
@EnableScheduling
public @interface EnableVisitRecord {
}

View File

@ -0,0 +1,18 @@
package com.svnlan.annotation;
import com.svnlan.interceptor.VisitRecordAop;
import com.svnlan.utils.timer.VisitRecordSchedule;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 自定义注入类
*
* @author lingxu 2023/04/11 16:02
*/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{VisitRecordAop.class.getName(), VisitRecordSchedule.class.getName()};
}
}

View File

@ -0,0 +1,14 @@
package com.svnlan.annotation;
import java.lang.annotation.*;
/**
* 指定值 注解
*
* @author lingxu 2023/06/13 10:48
*/
@Target({ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SpecifiedValue {
}

View File

@ -0,0 +1,11 @@
package com.svnlan.annotation;
import javax.validation.groups.Default;
/**
* 修改组
*
* @author lingxu 2023/05/16 16:46
*/
public interface UpdateGroup extends Default {
}

View File

@ -0,0 +1,11 @@
package com.svnlan.annotation;
/**
* 当访问时的处理器
*
* @author lingxu 2023/06/13 10:25
*/
public interface VisitHandler {
void handle(Object value);
}

View File

@ -0,0 +1,92 @@
package com.svnlan.annotation;
import org.springframework.data.util.Pair;
import java.lang.annotation.*;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
/**
* 访问记录
*
* @author lingxu 2023/04/06 16:53
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface VisitRecord {
/**
* 是否需要异步
*/
boolean isAsync() default true;
/**
* 时间类型
*/
TimeType[] timeType() default {TimeType.MILLI_SECOND, TimeType.DAY};
/**
* 记录哪种类型数据
*/
RecordType[] recordType() default {RecordType.ALL};
/**
* 是否需要处理访问数
*/
boolean handle() default false;
enum RecordType {
// 设备类型
CLIENT_TYPE,
// 操作系统类型
OS_NAME,
// 所有类型
ALL;
}
enum TimeType {
// 按天记录
DAY,
// 按小时记录
HOUR,
// 按分钟记录
MINUTE,
// 按秒记录
SECOND,
// 按毫秒记录
MILLI_SECOND;
/**
* 判断是否在给定的数组中
*/
public static boolean isContains(TimeType[] timeTypes, TimeType timeType) {
for (TimeType item : timeTypes) {
if (item == timeType) {
return true;
}
}
return false;
}
/**
* 获取时间类型及对应的时间戳
*
* @param now 当前时间
* @return 时间类型及对应时间戳集合
*/
public static List<Pair<TimeType, Supplier<Long>>> getTimeList(LocalDateTime now) {
List<Pair<TimeType, Supplier<Long>>> list = new ArrayList<>();
list.add(Pair.of(VisitRecord.TimeType.MILLI_SECOND, () -> now.toInstant(ZoneOffset.of("+8")).toEpochMilli()));
list.add(Pair.of(VisitRecord.TimeType.SECOND, () -> now.toInstant(ZoneOffset.of("+8")).getEpochSecond()));
list.add(Pair.of(VisitRecord.TimeType.MINUTE, () -> now.withSecond(0).withNano(0).toEpochSecond(ZoneOffset.of("+8"))));
list.add(Pair.of(VisitRecord.TimeType.HOUR, () -> now.withSecond(0).withNano(0).withMinute(0).toEpochSecond(ZoneOffset.of("+8"))));
list.add(Pair.of(VisitRecord.TimeType.DAY, () -> now.withSecond(0).withNano(0).withMinute(0).withHour(0).toEpochSecond(ZoneOffset.of("+8"))));
return list;
}
}
}

View File

@ -0,0 +1,38 @@
package com.svnlan.common;
import io.jsonwebtoken.Claims;
/**
* @Author: @Description:验证信息
*/
public class CheckResult {
private int errCode;
private boolean success;
private Claims claims;
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Claims getClaims() {
return claims;
}
public void setClaims(Claims claims) {
this.claims = claims;
}
}

View File

@ -0,0 +1,254 @@
package com.svnlan.common;
import java.time.format.DateTimeFormatter;
/**
* @Author:
* @Description: 常量
*/
public class GlobalConfig {
public static final String COMMA_DELIMITER = ",";
public static final String PWD_SALT = "PJEA4DR2WS8DF651DGT";
public static final String JWT_REDIS_PREFIX = "jwt";
public static final String JWT_TOKEN_HASH_PRE = "jwt_token_hash_";
public static final String HOST_REDIS_PREFIX = "host";
public static final String default_disk_path_pre = "/uploads";
public static final String UPCONFIG = "upconfig.properties";
public static final String LOGIN_PASSWORD_AES_KEY = "njsdearr8h239ay3";
public static final String OPEN_LOGIN_PASSWORD_AES_KEY = "oi2qpe2dnwufa982";
//记录,判断短时间内多次登录使用
public static final String JWT_FAST_LOGIN_KEY_PRE = "jwt_fast_login_key_";
//第三方登录, 临时权限redis key前缀
public static final String THIRD_LOGIN_TEMP_AUTH_PRE = "thirdLoginTempAuth_";
public static final String SEVEN_DAY_CLIENT_COUNT = "seven_day_client_count_";
public static final String RIGHTS_API_KEY = "rights_api_hash";
// api token redis key
public static final String JWT_API_REDIS_PREFIX = "api_jwt_";
/** copy验证码的cookie键名 **/
public static final String CAPTCHA_CODE_COOKIE_KEY = "captchaCode";
public static final int CAPTCHA_CODE_TTL = 180; // 验证码的有效时间,
// 生成验证码图片方法 outCaptcha(),返回map中,对应的客户端的cookie的值的key
public static final String CAPTCHA_CODE_COOKIE_VALUE_RETURNKEY="codeCookieValue";
// 生成验证码图片方法 outCaptcha(),返回map中,对应的图片验证码内容的key
public static final String CAPTCHA_CODE_CODE_VALUE_RETURNKEY = "captchaCodeValue";
/** resources目录下验证码图片子目录名称 **/
public static final String RESOURCES_CAPTCHA_DIRECTORY = "captcha";
/** 验证码的cookie键名 **/
public static final String CAPTCHA_COOKIE_KEY = "captcha";
public static final int CAPTCHA_TTL = 180; // 验证码的有效时间,
// 生成验证码图片方法 outCaptcha(),返回map中,对应的客户端的cookie的值的key
public static final String CAPTCHA_COOKIE_VALUE_RETURNKEY="cookieValue";
// 生成验证码图片方法 outCaptcha(),返回map中,对应的图片验证码内容的key
public static final String CAPTCHA_CODE_VALUE_RETURNKEY = "captchaValue";
/** copy验证码的cookie键名 图形滑动验证码 **/
public static final String IMAGE_CAPTCHA_CODE_COOKIE_KEY = "captchaImageCode";
public static final int IMAGE_CAPTCHA_CODE_TTL = 180; // 验证码的有效时间,
// 生成验证码图片方法 outCaptcha(),返回map中,对应的客户端的cookie的值的key
//学习心得图片类型
public static final String[] STUDY_EXPERIENCE_IMAGE_TYPE = {"jpg", "jpeg", "gif", "bmp", "png", "svg"};
//课程下载
public static final String COURSE_DOWNLOAD_AES_KEY = "fj0j023rwdopqwpo";
//m3u8 播放AES key
public static final String M3U8_PLAY_AES_KEY = "dfjgj6kqdfvh89he";
//m3u8 播放key的分隔符
public static final String M3U8_PLAY_KEY_SEPARATOR = "pp&&kk&&";
public static final String ATTACHMENT_AES_KEY = "sadh8as1d032r0h0";
public static final String ATTACHMENT_KEY_SEPARATOR = "ff_&_gg";
// "jpg", "jpeg", "png", "gif", "bmp", "ico", "svg", "webp", "tif", "tiff", "cdr", "svgz", "xbm", "eps", "pjepg", "heic", "raw", "psd", "ai"
public static final String[] IMAGE_TYPE_ARR = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "svg", "webp", "tif", "tiff", "cdr", "svgz", "xbm", "eps", "pjepg", "heic", "raw", "psd", "ai"};
public static final String[] list_path_source_type = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "svg", "webp", "tif", "tiff", "cdr", "svgz", "xbm", "eps", "pjepg", "heic", "raw", "psd", "ai", "mp3"};
public static final String[] IMAGE_NO_GIF_TYPE_ARR = {"jpg", "jpeg", "bmp", "png"};
public static final String[] IMAGE_LITE_TYPE_ARR = {"jpg", "jpeg", "png"};
public static final String[] IMAGE_SHOW_TYPE_ARR = {"jpg", "jpeg", "gif", "bmp", "png", "svg", "psd", "tga"};
public static final String[] VIDEO_SHOW_TYPE_ARR = {"flv","avi","mpeg","mpg","mp4","rmvb","rm","mov","3gp","f4v","wmv", "pmg", "mkv", "m4v"};
public static final String[] DOC_TYPE_ARR = {"doc", "docx", "ppt", "pptx", "pdf", "xls", "xlsx"};
public static final String[] yongzhong_doc_type = {"eid","docx","dotx","doc","dot","rtf","txt","uot","htm","wps","wpt"};
public static final String[] yongzhong_excel_type = {"eis","xlsx","xltx","xls","xlt","uos","dbf","csv","xml","et","ett"};
public static final String[] yongzhong_ppt_type = {"eip","pptx","potx","ppt","pot","ppsx","pps","dps","dpt","uop"};
public static final String[] yongzhong_doc_excel_ppt_type = {"eid","docx","dotx","doc","dot","rtf","txt","uot","htm","wps","wpt",
"eis","xlsx","xltx","xls","xlt","uos","dbf","csv","xml","et","ett",
"eip","pptx","potx","ppt","pot","ppsx","pps","dps","dpt","uop", "pdf"
// ,"zip","gz","rar","iso","tar","7z","ar","bz","bz2","xz", "arj"
};
// 相机文件 dng,nef,orf,pef,srw,x3f,srf,arw,sr2
//public static final String[] CAMERA_TYPE_ARR = {"cr2", "dcr", "epf", "raf", "kdc", "dcr", "dng", "nef", "orf", "pef", "tiff", "cdr", "svgz", "xbm", "eps", "pjepg", "heic", "raw", "psd", "ai"};
public static final String[] CAMERA_TYPE_ARR = {"arw", "mrw", "erf", "raf","cr2", "nrw", "nef", "orf", "rw2", "pef", "srf"
, "dcr", "kdc", "dng"};
public static final String[] DOC_SHOW_TYPE_ARR = {"doc", "docx", "ppt", "pptx", "pdf", "xls", "xlsx", "pps", "wps", "txt"};
public static final String[] AUDIO_SHOW_TYPE_ARR = {"mp3", "wav", "flac", "mpa"};
public static final String[] UNZIP_SHOW_TYPE_ARR = {"tar", "zip", "gzip", "bz2", "rar", "7z", "gz", "iso", "ar", "bz", "xz", "arj"};
public static final String[] ZIP_SHOW_TYPE_ARR = {"zip", "tar"};
public static final String[] VIDEO_TYPE_ARR = {"mp4", "flv", "rm", "rmvb", "avi", "mkv", "mov", "f4v", "mpeg", "mpg", "vob", "wmv", "ogv", "webm", "3gp", "mts", "m2ts", "m4v", "mpe", "3g2", "asf", "dat", "asx", "wvx"};
public static final String[] VIDEO_AUDIO_TYPE_CONVERT = {"mp4", "wav", "flac", "flv", "rm", "rmvb", "avi", "mkv", "mov", "f4v", "mpeg", "mpg", "vob", "wmv", "ogv", "webm", "3gp", "mts", "m2ts", "m4v", "mpe", "3g2", "asf", "dat", "asx", "wvx"};
public static final String[] AUDIO_VIDEO_SHOW_TYPE_ARR = {"mp4", "flv", "rm", "rmvb", "avi", "mkv", "mov", "f4v", "mpeg", "mpg", "vob", "wmv", "ogv", "webm", "3gp", "mts", "m2ts", "m4v", "mpe", "3g2", "asf", "dat", "asx", "wvx", "mpa", "mp3", "wav", "wma", "m4a", "ogg", "omf", "amr", "aa3", "flac", "aac", "cda", "aif", "aiff", "mid", "ra", "ape"};
public static final String CONVERT_SOURCE_ID_H5_MAP = "convert_source_id_h5";
public static final String CONVERT_SOURCE_ID_SWF_MAP = "convert_source_id_swf";
public static final String M3U8_KEY_INFO_SEPARATOR = "_&_&_";
public static final String M3U8_AES_PASSWORD = "vj90eu321fk01";
public static final String CLOUD_OPERATION_LOCK_KEY = "cloudOperationLock";
public static final long CHUNK_FILE_SIZE = 2 * 1024 * 1024;
//转码文件redis key
public static final String CONVERT_FILE_REDIS_KEY_PRE = "convert_file_";
//redis存2小时20分钟
public static final Long CONVERT_FILE_REDIS_TTL = 8400L;
//项目启动10分钟内
public static final Long RUN_TIME_OFFSET = 600000L;
public static final String IMAGE_LARGE_SIZE_KEY = "imageLargeSize";
//用户发送绑定邮件验证码发送频率限制 REDIS KEY(userId)
public static final String EMAIL_BIND_SEND_FREQUENCY_KEY = "email_bind_send_frequency_%d";
//用户发送绑定邮件验证码每日限制次数 REDIS KEY(userId)
public static final String EMAIL_BIND_SEND_LIMIT_KEY = "email_bind_send_limit_%d";
//用户发送绑定 同一邮箱 邮件验证码每日限制次数 REDIS KEY(userIdemail)
public static final String SINGLE_EMAIL_BIND_SEND_LIMIT_KEY = "single_email_bind_send_limit_%d_%s";
//用户发送绑定邮件验证码每日限制次数
public static final Integer EMAIL_BIND_SEND_LIMIT_NUM = 10;
//用户发送绑定 同一邮箱 邮件验证码每日限制次数
public static final Integer SINGLE_EMAIL_BIND_SEND_LIMIT_NUM = 10;
// 缓存用户前缀
public static final String REDIS_KEY_USER = "user_";
// 缓存用户前缀
public static final String REDIS_KEY_USER_CODE = "user_verifyCode:";
public static final String REDIS_KEY_USER_STATE = "user_state_";
public static final String REDIS_KEY_USER_GROUP_AUTH = "user_group_auth";
// 普通下载定时删除redis
public static final String COMMON_DOWNLOAD_KEY_SET = "commonDownloadKeySet";
public static final String my_fav_key = "my_fav_key_";
public static final String my_tag_key = "my_tag_key_";
public static final String my_share_key = "my_share_key_";
public static final String SYSTEM_AUTH = "explorer.add,explorer.upload,explorer.view,explorer.download,explorer.share,explorer.remove,explorer.edit,explorer.move,explorer.serverDownload,explorer.search,explorer.unzip,explorer.zip,user.edit,user.fav,explorer.informationView,admin.index.dashboard,admin.index.setting,admin.index.loginLog,admin.index.log,admin.index.server,admin.role.list,admin.role.edit,admin.job.list,admin.job.edit,admin.member.list,admin.member.userEdit,admin.member.groupEdit,admin.auth.list,admin.auth.edit,admin.plugin.list,admin.plugin.edit,admin.storage.list,admin.storage.edit,admin.autoTask.list,admin.autoTask.edit,admin.index.information";
public static final String SYSTEM_GROUP_AUTH = "1,2,3,4,5,6,7,8,9,10,11,12,13,14";
public static final String oldInnerServer = "http://video.zdb9.com";
public static final String m3u8ConvertUrlPlaceholder = "m3u8_convert_server_url_placeholder";
public static final String async_key_zip_file = "async_key_zip_file:";
public static final String progress_key_zip_file = "progress_key_zip_file:";
public static final String async_key_zip_file_info = "async_key_zip_file_info:";
public static final String CONVERT_TIME_KEY = "convert_time_set";
public static final String file_edit_key = "file_edit_key:";
public static final String yzwo_file_edit_key = "yzwo_file_edit_key:";
public static final String separator = "\\\\";
public static final String separatorTO = "/";
public static final String systemConfig_captcha = "systemConfig_captcha";
public static final String userRoleAuth_key = "userRoleAuth_key";
public static final String yzwo_file_edit_user_key = "yzwo_file_edit_user_key:";
// 压缩预览
public static final String FILE_PREVIEW_COMPRESS_KEY = "compress_preview_file_key:";
public static final String[] DESIGN_WEB_CLIENT_TYPE_ARR = {"pc", "mb"};
// 视频编辑redis
public static final String video_edit_getVideoShearList = "video_edit_getVideoShearList_key_";
// 文件夹
public static final String dir_user_pathDisplay = "dir_user_pathDisplay_";
public static final String dir_group_pathDisplay = "dir_group_pathDisplay";
// 资讯导入
public static final String IMPORT_ARTICLE_LOCK = "importArticleLock_";
//转成图片的缓存KEY(其中%d为文件ID)
public static String infoConvertToJPGKey = "infoConvertToJPG_%d";
//转成图片的防并发的缓存KEY(其中%d为文件ID)
public static String concurrentConvertToJPGKey = "concurrentConvertToJPG_%d";
public static final DateTimeFormatter dateTimeStandardFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static final DateTimeFormatter dateStandardFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static final String BAN_WORDS_LIB_FILE_NAME = "banWords.txt";
//非小程序其他最多装扮数量限制
public static final Integer MaxDesignCount = 100;
public static final String SEARCH_PERMISSION_KEY = "searchComponentPermission";
//主页二级页后缀
public static final String GEN_PAGE_SUFFIX = ".shtml";
//favicon
public static final String FAV_ICON_FILENAME = "favicon.png";
public static final String FAV_ICON_PATH = "/common/";
//装扮url防并发
public static final String DESIGN_URL_LOCK_PRE = "design_url_lock";
public static final Long DESIGN_URL_LOCK_TTL = 5 * 1000L;
//扫码登录加解密的密钥
public static final String ScanLoginSalt = "OPjanpEaoE7ZGl9v";
public static final Integer scanLoginSignatureExpire = 1;
public static final Integer scanLoginCodeExpire = 60;
//扫码登录校验KEY
public static final String SCAN_LOGIN_CODE_REDIS_KEY = "scanLogin_";
public static final String logAuthUrl = "/pages/download.html";
//防并发加锁的REDIS KEY其中%s为tempAuth
public static final String ScanLoginAuth = "sla_%s";
public static final String mesWarning_cache_key = "mesWarning_cache_key";
public static final int mesWarning_cache_ttl = 8; // 消息预警缓存有效时间
// 消息预警判断持续redis
public static final String mesWarning_cpu_key = "mesWarning_cpu_key";
public static final String mesWarning_mem_key = "mesWarning_mem_key";
public static final String mesWarning_du_key = "mesWarning_du_key";
public static final String mesWarning_send_temp_key = "【消息预警】%s %s %s使用占比超过%s请注意您可在管理后台>消息预警,关闭此提醒)";
//扫码登录的 channelId与标识ID(loginId)的关联关系 HASH REDIS KEY%s为对应的房间roomName
public static final String ScanLoginIdChannelRelation = "SLIdChannelRelation_%s";
//扫码登录的 APP token与 生成的临时授权码的关联关系 HASH REDIS KEY%s为对应的房间roomName
public static final String ScanLoginTempAuthRelation = "SLTempAuthRelation_%s";
//扫码登录的临时授权码REDIS KEY 前缀
public static final String ScanLoginTempAuthRedisKeyPrefix = "scanLg";
public static final String private_replace_key = "/{dir}/{path}/";
public static final String async_key_convert_doc_file = "async_key_convert_doc_file_";
public static final String progress_key_convert_doc_file = "progress_key_convert_doc_file_";
public static final String show_img_api_key = "/api/disk/video/img/";
public static final String async_key_unzip_file = "async_key_unzip_file_";
public static final String progress_key_unzip_file = "progress_key_unzip_file_";
public static final String temp_img_video_key = "temp_img_video_key_";
public static final String homeExplorerRedisKey = "homeExplorerRedisKey_";
public static final String homeExplorerOneRedisKey = "homeExplorerOneRedisKey_";
public static final String async_key_convert_img_video = "async_key_convert_img_video_";
public static final String progress_key_convert_img_video = "progress_key_convert_img_video_";
}

View File

@ -0,0 +1,43 @@
package com.svnlan.common;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class HttpSessionUtil<T> {
private static final String LANGAUAGE_KEY = "Language"; //lang-country
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
public HttpSessionUtil() {
}
public HttpServletResponse getResponse() {
return this.response;
}
public HttpServletRequest getRequest() {
return this.request;
}
public String getLanage() {
try {
return this.request.getHeader(LANGAUAGE_KEY);
} catch (Exception var2) {
return null;
}
}
public String getRequestId() {
try {
return this.request.getHeader("REQUESTID");
} catch (Exception var2) {
return null;
}
}
}

View File

@ -0,0 +1,86 @@
package com.svnlan.common;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Locale;
import javax.annotation.Resource;
/**
* @Author: sulijuan
* @Description: @Autowired 自动装配仅在托管类中有效例如注释为@ Component@ Service或在应用程序上下文xml中定义
* @Date: 2023/2/6 15:01
*/
@Component
@Slf4j
public class I18nUtils {
// 如果当前bean不加@Component注解则messageSource无法注入始终为null
private static MessageSource messageSource;
private static HttpSessionUtil httpSessionUtil;
@Autowired
public void setMessageSource(MessageSource messageSource) {
I18nUtils.messageSource = messageSource;
}
@Autowired
public void setHttpSessionUtil(HttpSessionUtil httpSessionUtil) {
I18nUtils.httpSessionUtil = httpSessionUtil;
}
/**
* 解析code对应的信息进行返回如果对应的code不能被解析则抛出异常NoSuchMessageException
*
* @param code 需要进行解析的code对应资源文件中的一个属性名
* @param args 当对应code对应的信息不存在时需要返回的默认值
* @return 国际化翻译值
*/
public static String i18n(String code, Object... args) {
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
}
/**
* 解析code对应的信息进行返回如果对应的code不能被解析则抛出异常NoSuchMessageException
*
* @param locale 需要转换的语言
* @param code 需要进行解析的code对应资源文件中的一个属性名
* @param args 当对应code对应的信息不存在时需要返回的默认值
* @return 国际化翻译值
*/
public static String i18n(Locale locale, String code, Object... args) {
return messageSource.getMessage(code, args, locale);
}
/**
* 解析code对应的信息进行返回如果对应的code不能被解析则返回默认信息defaultMessage
*
* @param code 需要进行解析的code对应资源文件中的一个属性名
* @param defaultMessage 当对应code对应的信息不存在时需要返回的默认值
* @param args 需要用来替换code对应的信息中包含参数的内容{0},{1,date},{2,time}
* @return 对应的Locale
*/
public static String i18nOrDefault(String code, String defaultMessage, Object... args) {
return messageSource.getMessage(code, args, defaultMessage, LocaleContextHolder.getLocale());
}
/**
* 因为i18n方法如果获取不到对应的键值会抛异常NoSuchMessageException
* 本方法是对i18n方法的封装当报错时并不抛出异常而是返回source
*
* @param source 模板
* @param args 参数
* @return 返回I18n正常结束或者source抛出异常
* @see #i18n(String, Object...)
*/
public static String tryI18n(@NonNull String source, @NonNull Object... args) {
String res;
try {
res = i18n(source, args);
} catch (Exception ignored) {
res = source;
}
return res;
}
}

View File

@ -0,0 +1,12 @@
package com.svnlan.common;
/**
* @Author:
* @Date:
* @Description:
*/
public class LogScheduleStateConstants {
public static final String UNSTART = "0";
public static final String SUCCESS = "1";
public static final String FAILURE = "2";
}

View File

@ -0,0 +1,166 @@
package com.svnlan.common;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import org.springframework.util.ObjectUtils;
import java.io.Serializable;
/** @Author: @Description: */
public class Result implements Serializable {
private static final long serialVersionUID = -1L;
/** 状态码 */
private Boolean success;
/** 结果消息 */
private String message;
/** 错误码 */
private String code;
/** 返回的数据 */
private Object data;
private Long timeStamp;
/**
* 构造函数
* @param code
* @param data
*/
public Result(String code, Object data) {
this(true, code, data);
}
public Result(boolean success, String code, Object data) {
this.success = success;
this.message = I18nUtils.i18n(code);
this.code = code;
this.data = data;
this.timeStamp = System.currentTimeMillis();
}
public Result(boolean success, String code,String message) {
this.success = success;
if (ObjectUtils.isEmpty(message)) {
this.message = I18nUtils.i18n(code);
}else {
this.message = message;
}
this.code = code;
this.data = message;
this.timeStamp = System.currentTimeMillis();
}
public Result(boolean success, String code,String message, boolean isFmt) {
this.success = success;
if (isFmt){
String m = I18nUtils.i18n(code);
this.message = String.format(m,message);
}else {
this.message = I18nUtils.i18n(code);
}
this.code = code;
this.timeStamp = System.currentTimeMillis();
}
public Result(boolean success, String message) {
this.success = success;
this.message = message;
this.code = "-1";
this.timeStamp = System.currentTimeMillis();
}
public Result(boolean success, String code, String message, Object data) {
this.success = success;
this.message = message;
if (ObjectUtils.isEmpty(message)){
this.message = I18nUtils.i18n(code);
}
this.code = code;
this.data = data;
this.timeStamp = System.currentTimeMillis();
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(Long timeStamp) {
this.timeStamp = timeStamp;
}
/**
* 返回自定义异常
*
* @param e
* @return
*/
public static Result returnSvnException(SvnlanRuntimeException e) {
return new Result(Boolean.FALSE, e.getErrorCode(), null);
}
/**
* 返回失败
*
* @param codeMessageEnum
* @return
*/
public static Result returnError(CodeMessageEnum codeMessageEnum) {
return new Result(Boolean.FALSE, codeMessageEnum.getCode(), null);
}
public static Result returnError(String message) {
return new Result(Boolean.FALSE, message);
}
/**
* 返回成功
*
* @param data
* @return
*/
public static Result returnSuccess(Object data) {
return new Result(Boolean.TRUE, CodeMessageEnum.success.getCode(), data);
}
public static Result returnSuccess() {
return new Result(Boolean.TRUE, CodeMessageEnum.success.getCode(), null);
}
}

View File

@ -0,0 +1,60 @@
package com.svnlan.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import java.util.Properties;
/**
* mybatis配置
*
* @author lingxu 2023/05/25 10:02
*/
@Configuration
public class MybatisConfig {
/**
* mp 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor interceptor = new PaginationInterceptor();
interceptor.setDialectType(DbType.MYSQL.getDb());
return interceptor;
}
/**
* 性能分析插件
*/
@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(15000);
performanceInterceptor.setFormat(false);
return performanceInterceptor;
}
/**
* 功能描述: 配置mybatis的分页插件pageHelper
*
* @param:
* @return:
*/
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("offsetAsPageNum", "true");
properties.setProperty("rowBoundsWithCount", "true");
properties.setProperty("reasonable", "false");
//配置mysql数据库的方言
properties.setProperty("dialect", "mysql");
pageHelper.setProperties(properties);
return pageHelper;
}
}

View File

@ -0,0 +1,114 @@
package com.svnlan.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* redis配置
*
* @author lingxu 2023/04/07 10:11
*/
@Configuration
public class RedisConfig {
//读取配置文件中redis的配置
// @Bean
// @ConfigurationProperties(prefix = "spring.redis")
// public JedisConnectionFactory jedisConnectionFactory() {
// return new JedisConnectionFactory();
// }
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory factory) {
//String
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//JdkSerialization
//JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSgiterializationRedisSerializer();
//Jackson2Json
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
//PropertyAccessor.ALL所有JsonAutoDetect.Visibility.ANY修饰范围ANY-所有
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//指定序列化输入的类型类必须是非final修饰的
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisTemplate<String, Object> template = new RedisTemplate<>();
//连接工厂
template.setConnectionFactory(factory);
//全局key的序列化策略
template.setKeySerializer(stringRedisSerializer);
//全局value的序列化策略
template.setValueSerializer(jackson2JsonRedisSerializer);
//全局HashKey的序列化策略
template.setHashKeySerializer(stringRedisSerializer);
//全局HashValue的序列化策略
template.setHashValueSerializer(jackson2JsonRedisSerializer);
//支持事务
template.setEnableTransactionSupport(true);
template.afterPropertiesSet();
return template;
}
@Resource
private Environment environment;
// 这些环境的 redis 配置将被认做 single
private static final List<String> redisSingleList = Arrays.asList("local", "dev", "pro", "pufay");
@ConditionalOnBean(name = "redisTemplate")
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient(RedisProperties redisProperties) {
// 创建配置 指定redis地址及节点信息
Config config = new Config();
if (Arrays.stream(environment.getActiveProfiles()).anyMatch(redisSingleList::contains)) {
SingleServerConfig singleServerConfig = config.useSingleServer()
.setDatabase(redisProperties.getDatabase())
.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort());
if (StringUtils.hasText(redisProperties.getPassword())) {
singleServerConfig.setPassword(redisProperties.getPassword());
}
} else {
ClusterServersConfig clusterServersConfig = config.useClusterServers();
for (String node : redisProperties.getCluster().getNodes()) {
clusterServersConfig
.addNodeAddress("redis://" + node);
}
clusterServersConfig.setScanInterval(2000);
if (StringUtils.hasText(redisProperties.getPassword())) {
clusterServersConfig.setPassword(redisProperties.getPassword());
}
}
// 根据config创建出RedissonClient实例
return Redisson.create(config);
}
}

View File

@ -0,0 +1,49 @@
package com.svnlan.enums;
/**
* @Author:
* @Description:
*/
public enum AdminDocAuthEnum {
show(1, "admin.auth.show", "文件列表"),
showAction(2, "admin.auth.showAction", "文件列表查看"),
view(3, "admin.auth.view", "文件预览"),
viewAction(4, "admin.auth.viewAction", "文件打开预览"),
download(5, "admin.auth.download", "下载/复制"),
downloadAction(6, "admin.auth.downloadAction", "下载/复制/文件预览打印"),
uploadAction(7, "admin.auth.uploadAction", "文件(夹)上传/远程下载"),
edit(8, "admin.auth.edit", "编辑新建"),
editAction(9, "admin.auth.editAction", "新建文件(夹)/重命名/粘贴到文件夹/编辑文件/设置备注/创建副本/解、压缩"),
removeAction(10, "admin.auth.removeAction", "剪切/复制/移动"),
shareAction(11, "admin.auth.shareAction", "外链分享/与他人协作分享"),
comment(12, "admin.auth.comment", "文档评论"),
commentAction(13, "admin.auth.commentAction", "文档评论查看;添加/删除自己的评论(需编辑权限)"),
event(14, "admin.auth.event", "文档动态"),
eventAction(15, "admin.auth.eventAction", "文档动态查看、订阅动态"),
root(16, "admin.auth.root", "管理权限"),
rootAction(17, "admin.auth.rootAction", "设置成员权限/评论管理/历史版本管理"),
;
private int id;
private String code;
private String value;
AdminDocAuthEnum(int id,String code, String value) {
this.id = id;
this.code = code;
this.value = value;
}
public int getId() { return id; }
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,101 @@
package com.svnlan.enums;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/6 16:30
*/
public enum AuthEnum {
explorerAdd(1, "explorer.add", ""),
explorerUpload(2, "explorer.upload", ""),
explorerView(3, "explorer.view", ""),
explorerDownload(4, "explorer.download", ""),
explorerShare(5, "explorer.share", ""),
explorerRemove(6, "explorer.remove", ""),
explorerEdit(7, "explorer.edit", ""),
explorerMove(8, "explorer.move", ""),
explorerServerDownload(9, "explorer.serverDownload", ""),
explorerSearch(10, "explorer.search", ""),
explorerUnzip(11, "explorer.unzip", ""),
explorerZip(12, "explorer.zip", ""),
userEdit(13, "user.edit", ""),
userFav(14, "user.fav", ""),
adminIndexDashboard(15, "admin.index.dashboard", ""),
adminIndexSetting(16, "admin.index.setting", ""),
adminIndexLoginLog(17, "admin.index.loginLog", ""),
adminIndexLog(18, "admin.index.log", ""),
adminIndexServer(19, "admin.index.server", ""),
adminRoleList(20, "admin.role.list", ""),
adminRoleEdit(21, "admin.role.edit", ""),
adminJobList(22, "admin.job.list", ""),
adminJobEdit(23, "admin.job.edit", ""),
adminMemberList(24, "admin.member.list", ""),
adminMemberUserEdit(25, "admin.member.userEdit", ""),
adminMemberGroupEdit(26, "admin.member.groupEdit", ""),
adminAuthList(26, "admin.auth.list", ""),
adminAuthEdit(27, "admin.auth.edit", ""),
adminPluginList(28, "admin.plugin.list", ""),
adminPluginEdit(29, "admin.plugin.edit", ""),
adminStorageList(28, "admin.storage.list", ""),
adminStorageEdit(29, "admin.storage.edit", ""),
adminAutoTaskList(28, "admin.autoTask.list", ""),
adminAutoTaskEdit(29, "admin.autoTask.edit", ""),
adminIndexInfo(30, "admin.index.information", ""),
explorerInfoView(31, "explorer.informationView", ""),
;
private int id;
private String code;
private String value;
public static List<String> authList = Arrays.stream(values()).map(AuthEnum::getCode).collect(Collectors.toList());
AuthEnum(int id, String code, String value) {
this.id = id;
this.code = code;
this.value = value;
}
public static Map<String, Object> getUserAuthMap(String userAuth){
List<String> aList = !ObjectUtils.isEmpty(userAuth) ? Arrays.asList(userAuth.split(",")).stream().map(String::valueOf).collect(Collectors.toList()) : null;
Map<String, Object> userAuthMap = new HashMap<>(1);
for (String code : authList){
int auth = 0;
if (!CollectionUtils.isEmpty(aList) && aList.contains(code)){
auth = 1;
}
userAuthMap.put(code , auth);
}
return userAuthMap;
}
public static boolean contains(String busType) {
return authList.contains(busType);
}
public int getId() {
return id;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,26 @@
package com.svnlan.enums;
/**
* @description: 业务类型
*/
public enum BusinessTypeEnum {
COMMON("common", "通用"),
SCAN_LOGIN("scanLogin", "扫码登录");
private String code;
private String text;
BusinessTypeEnum(String code, String text) {
this.code = code;
this.text = text;
}
public String getCode() {
return code;
}
public String getText() {
return text;
}
}

View File

@ -0,0 +1,64 @@
package com.svnlan.enums;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/24 16:32
*/
public enum ClientTypeEnum {
// 1pc , 2h5, 3安卓app, 4 ios-app, 5小程序 6电脑app
pc("1", "pc"),
h5("2", "h5"),
android("3", "安卓"),
ios("4", "ios"),
mini("5", "小程序"),
pcApp("6", "pc app"),
other("7", "其他"),
;
private String code;
private String value;
/**
* 获取所有枚举的 code 集合
*/
public static List<String> getCodeList() {
return Arrays.stream(ClientTypeEnum.values()).map(it -> it.code).collect(Collectors.toList());
}
/**
* 获取所有枚举的 code 集合
* @param exclude 需要排除的类型
*/
public static List<String> getCodeList(List<String> exclude) {
return Arrays.stream(ClientTypeEnum.values())
.filter(it -> {
if (CollectionUtils.isEmpty(exclude)) {
return true;
}
return !exclude.contains(it.code);
})
.map(it -> it.code).collect(Collectors.toList());
}
ClientTypeEnum(String code, String value) {
this.code = code;
this.value = value;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,93 @@
package com.svnlan.enums;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 14:25
*/
public enum DocumentTypeEnum {
// 文档
doc("doc", 1, "explorer.type.doc", "txt,md,pdf,ofd,doc,docx,xls,xlsx,ppt,pptx,xps,pps,ppsx,ods,odt,odp,docm,dot,dotm,xlsb,xlsm,mht,djvu,wps,dpt,csv,et,ett,pages,numbers,key,dotx,vsd,vsdx,mpp", "doc"),
// 图片
image("image", 2, "explorer.type.image", "jpg,jpeg,png,gif,bmp,ico,svg,webp,tif,tiff,cdr,svgz,xbm,eps,pjepg,heic,raw,psd,ai", "image"),
// 音乐
music("music", 3, "explorer.type.music", "mp3,wav,wma,m4a,ogg,omf,amr,aa3,flac,aac,cda,aif,aiff,mid,ra,ape,mpa", "music"),
// 视频
movie("movie", 4, "explorer.type.movie", "mp4,flv,rm,rmvb,avi,mkv,mov,f4v,mpeg,mpg,vob,wmv,ogv,webm,3gp,mts,m2ts,m4v,mpe,3g2,asf,dat,asx,wvx", "movie"),
// 压缩包
zip("zip", 5, "explorer.type.zip", "zip,gz,rar,iso,tar,7z,ar,bz,bz2,xz,arj", "zip"),
// 其他
others("other", 6, "explorer.type.others", "swf,html,exe,msi", "other"),
;
private String code;
private Integer type;
private String value;
private String ext;
private String icon;
DocumentTypeEnum(String code, Integer type, String value, String ext, String icon) {
this.type = type;
this.ext = ext;
this.code = code;
this.value = value;
this.icon = icon;
}
private static final Map<String, Integer> fileExtMap = new HashMap<>();
static {
for (DocumentTypeEnum typeEnum : DocumentTypeEnum.values()) {
String[] split = typeEnum.ext.split(",");
for (String ext : split) {
fileExtMap.put(ext, typeEnum.type);
}
}
}
/**
* 通过文件后缀获取文件类型
*
* @param ext 文件后缀
* @return 文件类型
*/
public static Integer getTypeByExt(String ext) {
// for (DocumentTypeEnum documentTypeEnum : DocumentTypeEnum.values()) {
// if (documentTypeEnum.ext.contains(ext)) {
// return documentTypeEnum.getType();
// }
// }
// 默认为其他类型
// return others.getType();
return Optional.ofNullable(fileExtMap.get(ext)).orElse(others.getType());
}
public Integer getType() {
return type;
}
public String getIcon() {
return icon;
}
public String getExt() {
return ext;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,46 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 11:25
*/
public enum EventEnum {
mkdir("create", "mkdir"),
mkfile("create", "mkfile"),
upload("create", "upload"),
uploadNew("create", "uploadNew"),
copy("create", "copy"),
rename("rename", "rename"),
recycle("recycle", "toRecycle"),
restore("recycle", "restore"),
addDesc("addDesc", "addDesc"),
shareToAdd("share", "shareToAdd"),
edit("edit", "edit"),
remove("remove", "remove"),
shareLinkAdd("share", "shareLinkAdd"),
shareLinkRemove("share", "shareLinkRemove"),
shareEdit("share", "shareEdit"),
shareLinkEdit("share", "shareLinkEdit"),
shareToRemove("share", "shareToRemove"),
rollBack("rollBack", "rollBack"),
;
private String code;
private String value;
private EventEnum(String code, String value) {
this.code = code;
this.value = value;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,38 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
*/
public enum FindTypeEnum {
MOBILE("1", "手机"),
EMAIL("2", "邮箱"),
WXLOGIN("3", "微信"),
QQLOGIN("4", "qq登录"),
WEIBOLOGIN("5", "微博"),
ALILOGIN("6", "支付宝");
private String code;
private String value;
FindTypeEnum(String code, String value) {
this.code = code;
this.value = value;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,44 @@
package com.svnlan.enums;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/10 17:04
*/
public enum GroupMetaEnum {
namePinyin(1, "namePinyin"),
namePinyinSimple(2, "namePinyinSimple"),
authShowType(3, "authShowType"),
authShowGroup(4, "authShowGroup"),
;
private Integer code;
private String value;
public static List<String> keyList = Arrays.stream(values()).map(GroupMetaEnum::getValue).collect(Collectors.toList());
public static List<String> delKeyList(){
return Arrays.asList(namePinyin.value, namePinyinSimple.value, authShowType.value, authShowGroup.value);
}
public static boolean contains(String value) {
return keyList.contains(value);
}
GroupMetaEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,93 @@
package com.svnlan.enums;
import com.svnlan.common.I18nUtils;
import org.springframework.util.ObjectUtils;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/4 11:41
*/
public enum LogTypeEnum {
authEdit(1, "admin.auth.edit", "", ""),
authRemove(2, "admin.auth.remove", "", ""),
groupEdit(3, "admin.group.edit", "", ""),
memberAdd(4, "admin.member.add", "", ""),
memberEdit(5, "admin.member.edit", "", ""),
roleAdd(6, "admin.role.add", "", ""),
roleEdit(7, "admin.role.edit", "", ""),
fileDownload(8, "explorer.index.fileDownload", "文件下载", "admin.log.downFile"),
fileEdit(9, "file.edit", "编辑文件", "admin.log.editFile"),
fileMkDir(10, "file.mkdir", "新建文件夹", "log-type-create-mkdir"),
fileMkFile(11, "file.mkfile", "新建文件", "log-type-create-mkfile"),
fileRemove(12, "file.remove", "删除文件", "admin.log.delFile"),// 彻底删除文件
fileRename(13, "file.rename", "重命名", "log-type-rename"),
fileshareEdit(14, "file.shareEdit", "编辑协作", ""),
fileShareLinkAdd(15, "file.shareLinkAdd", "外链分享", "log.file.shareLink"),
fileShareToAdd(16, "file.shareToAdd", "协作分享", "log.file.shareTo"),
fileShareToRemove(17, "file.shareToRemove", "取消协作分享", "admin.log.delShareTo"),
fileToRecycle(18, "file.toRecycle", "移到回收站", "log-type-recycle-toRecycle"),
fileUpload(19, "file.upload", "上传文件", "log-type-create-upload"),
loginSubmit(20, "user.index.loginSubmit", "登录", "common.login"),
logout(21, "user.index.logout", "退出", "explorer.toolbar.uiLogout"),
restore(22, "file.restore", "还原回收站", "explorer.recycleRestore"),
copy(23, "file.copy", "文件复制", "admin.role.readCopy"),
favDel(24, "explorer.fav.del", "取消收藏", "explorer.delFav"),
favAdd(25, "explorer.fav.add", "添加收藏", "explorer.addFav"),
move(26, "file.move", "移动文件", "log-type-move"),
moveOut(27, "file.moveOut", "移走文件", "log-type-moveOut"),
shareLinkRemove(28, "file.shareLinkRemove", "取消外链分享", "admin.log.delLinkTo"),
fileShareLinkEdit(15, "file.shareLinkEdit", "编辑分享", "log-type-share-shareEdit"),
wechatBind(30, "wechat.bind", "", ""),
wechatUnbind(31, "wechat.unbind", "", ""),
zipDownload(32, "explorer.index.zipDownload", "文件夹下载", "admin.log.downFolder"),
fileOut(33, "explorer.index.fileOut", "", "admin.log.downFile"),
clearTenant(34, "tenant.clear", "租户资源清理", "admin.tenant.clear"),
;
private int id;
private String code;
private String value;
private String tag;
private LogTypeEnum(int id,String code, String value, String tag) {
this.id = id;
this.code = code;
this.value = value;
this.tag = tag;
}
public static String getValueByCode(String code) {
for (LogTypeEnum itemEnum : LogTypeEnum.values()) {
if (itemEnum.code.equals(code) && !ObjectUtils.isEmpty(itemEnum.getTag())) {
return I18nUtils.i18n(itemEnum.getTag());
}
}
return "其他";
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public int getId() { return id; }
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,71 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 15:18
*/
public enum MenuEnum {
// 位置
position("common.position", "files", "", "1", "position"),
// 工具
tools("common.tools", "tools", "", "1", "tool"),
// 文件类型
fileType("common.fileType", "fileType", "explorer.pathDesc.fileType", "0", "fileType"),
// 标签
tag("common.tag", "fileTag", "explorer.pathDesc.tag", "0", "tag"),
;
private String code;
private String type;
private String desc;
private String open;
private String icon;
MenuEnum(String code, String type, String desc, String open, String icon) {
this.code = code;
this.type = type;
this.desc = desc;
this.open = open;
this.icon = icon;
}
public static String getCode(String msg) {
for (MenuEnum codeMsg : MenuEnum.values()) {
if (codeMsg.type.equals(msg)) {
return codeMsg.code;
}
}
return null;
}
public static String getMsg(String code) {
for (MenuEnum codeMsg : MenuEnum.values()) {
if (codeMsg.code.equals(code)) {
return codeMsg.type;
}
}
return null;
}
public String getIcon() {
return icon;
}
public String getDesc() {
return desc;
}
public String getOpen() {
return open;
}
public String getCode() {
return code;
}
public String getType() {
return type;
}
}

View File

@ -0,0 +1,42 @@
package com.svnlan.enums;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/13 16:46
*/
public enum MetaEnum {
namePinyin(1, "namePinyin"),
namePinyinSimple(2, "namePinyinSimple"),
;
private Integer code;
private String value;
public static List<String> keyList = Arrays.stream(values()).map(MetaEnum::getValue).collect(Collectors.toList());
public static List<String> delKeyList(){
return Arrays.asList(namePinyin.value, namePinyinSimple.value);
}
public static boolean contains(String value) {
return keyList.contains(value);
}
MetaEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,44 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 16:37
*/
public enum MyMenuEnum {
// 收藏夹
fav("explorer.toolbar.fav", "", "0", "fav"),
// 个人空间
rootPath("explorer.toolbar.rootPath", "explorer.pathDesc.home", "1", "space"),
;
private String code;
private String desc;
private String isRoot;
private String icon;
MyMenuEnum(String code, String desc, String isRoot, String icon) {
this.code = code;
this.desc = desc;
this.isRoot = isRoot;
this.icon = icon;
}
public String getIcon() {
return icon;
}
public String getDesc() {
return desc;
}
public String getCode() {
return code;
}
public String getIsRoot() {
return isRoot;
}
}

View File

@ -0,0 +1,33 @@
package com.svnlan.enums;
import org.springframework.util.StringUtils;
/**
* 操作系统
*
* @author lingxu 2023/04/17 10:35
*/
public enum OperatingSystemEnum {
MAC_OS_IPHONE("Mac OS X (iPhone)"),
ANDROID("Android"),
MAC_OS_X("Mac OS X"),
WINDOWS("Windows");
private String type;
OperatingSystemEnum(String type) {
this.type = type;
}
public static OperatingSystemEnum checkAndGet(String osName) {
if (StringUtils.hasText(osName)) {
for (OperatingSystemEnum item : OperatingSystemEnum.values()) {
if (osName.startsWith(item.type)) {
return item;
}
}
}
return null;
}
}

View File

@ -0,0 +1,72 @@
package com.svnlan.enums;
/**
* @description: 扫码登录消息动作
*/
public enum ScanLoginActionEnum {
CONFIRM("confirm", "确认连接"),
FEED_BACK("feedBack", "反馈登录结果"),
AUTH("auth", "登录授权"),
SCAN("scan", "扫描成功")
;
ScanLoginActionEnum(String code, String text) {
this.code = code;
this.text = text;
}
private String code;
private String text;
public String getCode() {
return code;
}
public String getText() {
return text;
}
/**
* @description: 包含某CODE
* @param code
* @return java.lang.Boolean
*/
public static Boolean contains(String code) {
Boolean exists = Boolean.FALSE;
for (ScanLoginActionEnum scanLoginMsgTypeEnum : ScanLoginActionEnum.values()) {
if(scanLoginMsgTypeEnum.getCode().equals(code)) {
exists = Boolean.TRUE;
}
}
return exists;
}
/**
* @description: 是否包含TV或WEB端发起的动作
* @param code
* @return java.lang.Boolean
*/
public static Boolean containsTvWebAction(String code) {
Boolean exists = Boolean.FALSE;
if(CONFIRM.getCode().equals(code) || FEED_BACK.getCode().equals(code)) {
exists = Boolean.TRUE;
}
return exists;
}
/**
* @description: 是否包含APP端发起的动作
* @param code
* @return java.lang.Boolean
*/
public static Boolean containsAppAction(String code) {
Boolean exists = Boolean.FALSE;
if(CONFIRM.getCode().equals(code) || AUTH.getCode().equals(code)) {
exists = Boolean.TRUE;
}
return exists;
}
}

View File

@ -0,0 +1,44 @@
package com.svnlan.enums;
/**
* @description: 扫码登录消息类型
*/
public enum ScanLoginMsgTypeEnum {
TV_SCAN_LOGIN("tvScanLogin", "TV端"),
WEB_SCAN_LOGIN("webScanLogin", "web端"),
APP_SCAN_LOGIN("appScanLogin", "APP端")
;
ScanLoginMsgTypeEnum(String code, String text) {
this.code = code;
this.text = text;
}
private String code;
private String text;
public String getCode() {
return code;
}
public String getText() {
return text;
}
/**
* @description: 包含某CODE
* @param code
* @return java.lang.Boolean
*/
public static Boolean contains(String code) {
Boolean exists = Boolean.FALSE;
for (ScanLoginMsgTypeEnum scanLoginMsgTypeEnum : ScanLoginMsgTypeEnum.values()) {
if(scanLoginMsgTypeEnum.getCode().equals(code)) {
exists = Boolean.TRUE;
}
}
return exists;
}
}

View File

@ -0,0 +1,101 @@
package com.svnlan.enums;
import java.util.Optional;
/**
* @Author:
* @Description: 安全设置类型
*/
public enum SecurityTypeEnum {
MOBILE("1", "mobilePhone"),
WECHAT("2", "wechat"),
QQ("3", "qq"),
EMAIL("4", "email"),
WEIBO("5", "weibo"),
ALIPAY("6", "alipay"),
EN_WECHAT("7", "enWechat"),
DING_DING("8", "dingding"),
WECHAT_APP("12", "wechatApp");
private String code;
private String value;
SecurityTypeEnum(String code, String value) {
this.code = code;
this.value = value;
}
public static SecurityTypeEnum deriveEnum(Integer openIdType) {
String type = String.valueOf(Optional.ofNullable(openIdType).orElse(-1));
for (SecurityTypeEnum itemEnum : SecurityTypeEnum.values()) {
if (itemEnum.code.equals(type)) {
return itemEnum;
}
}
return null;
}
/**
* 1手机号2微信3 qq4 email5微博6 支付宝
*/
public static String getValue(String code) {
switch (code) {
case "1":
return MOBILE.getValue();
case "2":
return WECHAT.getValue();
case "3":
return QQ.getValue();
case "4":
return EMAIL.getValue();
case "5":
return WEIBO.getValue();
case "6":
return ALIPAY.getValue();
case "7":
return EN_WECHAT.getValue();
case "8":
return DING_DING.getValue();
case "12":
return WECHAT_APP.getValue();
default:
return null;
}
}
/**
* 1手机号2微信3 qq4 email5微博6 支付宝
* getUserInfo type 不等于空时使用
*/
public static String getValueString(String value) {
switch (value) {
case "mobilePhone":
return MOBILE.getValue();
case "wechat":
return WECHAT.getValue();
case "qq":
return QQ.getValue();
case "email":
return EMAIL.getValue();
case "weibo":
return WEIBO.getValue();
case "alipay":
return ALIPAY.getValue();
case "enWechat":
return EN_WECHAT.getValue();
case "dingding":
return DING_DING.getValue();
default:
return null;
}
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,31 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
*/
public enum SendOperateTypeEnum {
BINDING("1","绑定"),
FIND("2","忘记登录密码"),
FORGET("3","设置支付密码");
private String code;
private String value;
SendOperateTypeEnum(String code, String value) {
this.code = code;
this.value = value;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,43 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/4/11 15:42
*/
public enum ShareMenuEnum {
// 与我协作
shareToMe("explorer.toolbar.shareToMe", "", "0", "shareToMe"),
info("explorer.toolbar.info", "", "0", "info"),
;
private String code;
private String desc;
private String isRoot;
private String icon;
ShareMenuEnum(String code, String desc, String isRoot, String icon) {
this.code = code;
this.desc = desc;
this.isRoot = isRoot;
this.icon = icon;
}
public String getIcon() {
return icon;
}
public String getDesc() {
return desc;
}
public String getCode() {
return code;
}
public String getIsRoot() {
return isRoot;
}
}

View File

@ -0,0 +1,49 @@
package com.svnlan.enums;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/9 13:50
*/
public enum SortEnum {
asc("1", "asc"),
desc("2", "desc"),
;
private String code;
private String value;
SortEnum(String code, String value) {
this.code = code;
this.value = value;
}
public static String getSortType(String value) {
switch (value) {
case "asc":
return asc.getValue();
case "up":
return asc.getValue();
case "desc":
return desc.getValue();
default:
return desc.getValue();
}
}
public static List<String> sortList = Arrays.stream(values()).map(SortEnum::getValue).collect(Collectors.toList());
public static boolean contains(String value) {
return sortList.contains(value);
}
public String getCode() {
return code;
}
public String getValue() { return value; }
}

View File

@ -0,0 +1,47 @@
package com.svnlan.enums;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/9 14:09
*/
public enum SortFieldEnum {
sizeUse("1", "sizeUse"),
roleID("2", "roleID"),
;
private String code;
private String value;
SortFieldEnum(String code, String value) {
this.code = code;
this.value = value;
}
public static String getSortField(String value) {
switch (value) {
case "sizeUse":
return sizeUse.getValue();
case "roleID":
return roleID.getValue();
default:
return sizeUse.getValue();
}
}
public static List<String> sortList = Arrays.stream(values()).map(SortFieldEnum::getValue).collect(Collectors.toList());
public static boolean contains(String value) {
return sortList.contains(value);
}
public String getCode() {
return code;
}
public String getValue() { return value; }
}

View File

@ -0,0 +1,79 @@
package com.svnlan.enums;
import org.springframework.util.ObjectUtils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/15 16:28
*/
public enum SourceFieldEnum {
name("1", "name"),
fileType("2", "fileType"),
size("3", "size"),
modifyTime("4", "modifyTime"),
createTime("3", "createTime"),
;
private String code;
private String value;
SourceFieldEnum(String code, String value) {
this.code = code;
this.value = value;
}
public static String getSortField(String value) {
switch (value) {
case "name":
return "name_pinyin";
case "size":
return size.getValue();
case "ext":
case "fileType":
return fileType.getValue();
case "modifyTime":
return modifyTime.getValue();
default:
return name.getValue();
}
}
public static String getConvertSortField(String value) {
if (ObjectUtils.isEmpty(value)){
return "stateSort";
}
switch (value) {
case "name":
return "io." + name.getValue();
case "size":
return "io." + size.getValue();
case "fileType":
case "ext":
return "io." + fileType.getValue();
case "modifyTime":
return "cc." + modifyTime.getValue();
case "createTime":
return "cc." + createTime.getValue();
default:
return "stateSort";
}
}
public static List<String> sortList = Arrays.stream(values()).map(SourceFieldEnum::getValue).collect(Collectors.toList());
public static boolean contains(String value) {
return sortList.contains(value);
}
public String getCode() {
return code;
}
public String getValue() { return value; }
}

View File

@ -0,0 +1,41 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/15 16:20
*/
public enum SourceSortEnum {
asc("1", "asc"),
desc("2", "desc"),
;
private String code;
private String value;
SourceSortEnum(String code, String value) {
this.code = code;
this.value = value;
}
public static String getSortType(String value) {
switch (value) {
case "up":
return asc.getValue();
case "asc":
return asc.getValue();
case "down":
return desc.getValue();
case "desc":
return desc.getValue();
default:
return desc.getValue();
}
}
public String getCode() {
return code;
}
public String getValue() { return value; }
}

View File

@ -0,0 +1,44 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 15:40
*/
public enum ToolsEnum {
// 最近文档
recentDoc("explorer.toolbar.recentDoc", "explorer.pathDesc.recentDoc", "recentDoc"),
// 我的协作
// shareTo("explorer.toolbar.shareTo", "explorer.pathDesc.shareTo", "shareTo"),
// 外链分享
shareLink("explorer.toolbar.shareLink", "explorer.pathDesc.shareLink", "shareLink"),
// 我的相册
photo("explorer.toolbar.photo", "explorer.photo.desc", "photo"),
// 工具箱
toolbox("explorer.toolbar.toolbox", "explorer.toolbox.desc", "toolbox"),
// 回收站
recycle("explorer.toolbar.recycle", "explorer.pathDesc.recycle", "recycle"),
;
private String code;
private String value;
private String icon;
ToolsEnum(String code, String value, String icon) {
this.code = code;
this.value = value;
this.icon = icon;
}
public String getIcon() {
return icon;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,42 @@
package com.svnlan.enums;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/10 17:25
*/
public enum UserMetaEnum {
namePinyin(1, "namePinyin"),
namePinyinSimple(2, "namePinyinSimple"),
;
private Integer code;
private String value;
public static List<String> keyList = Arrays.stream(values()).map(UserMetaEnum::getValue).collect(Collectors.toList());
public static List<String> delKeyList(){
return Arrays.asList(namePinyin.value, namePinyinSimple.value);
}
public static boolean contains(String value) {
return keyList.contains(value);
}
UserMetaEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,88 @@
package com.svnlan.enums;
import com.svnlan.user.domain.UserOption;
import com.svnlan.utils.ChinesUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/13 10:23
*/
public enum UserOptionEnum {
listSort("listSort", "", "folderInfo"),
folderInfoListType("listType", "", "folderInfo"),
listType("listType", "icon", ""),
listSortField("listSortField", "name", ""),
listSortOrder("listSortOrder", "up", ""),
fileIconSize("fileIconSize", "80", ""),
fileOpenClick("fileOpenClick", "dbclick", ""),
fileShowDesc("fileShowDesc", "0", ""),
animateOpen("animateOpen", "1", ""),
soundOpen("soundOpen", "0", ""),
theme("theme", "auto", ""),
themeImage("themeImage", "", ""),
wall("wall", "4", ""),
listTypeKeep("listTypeKeep", "1", ""),
listSortKeep("listSortKeep", "1", ""),
fileRepeat("fileRepeat", "replace", ""),
recycleOpen("recycleOpen", "1", ""),
kodAppDefault("kodAppDefault", "", ""),
fileIconSizeDesktop("fileIconSizeDesktop", "70", ""),
fileIconSizePhoto("fileIconSizePhoto", "120", ""),
photoConfig("photoConfig", "", ""),
resizeConfig("resizeConfig", "{\"filename\":250,\"filetype\":80,\"filesize\":80,\"filetime\":215,\"editorTreeWidth\":200,\"explorerTreeWidth\":200}", ""),
imageThumb("imageThumb", "1", ""),
fileSelect("fileSelect", "1", ""),
displayHideFile("displayHideFile", "0", ""),
filePanel("filePanel", "1", ""),
shareToMeShowType("shareToMeShowType", "list", ""),
messageSendType("messageSendType", "enter", ""),
loginDevice("loginDevice", "", ""),
recycleList("recycleList", "[]", "recycle"),
;
public static List<String> keyList = Arrays.stream(values()).map(UserOptionEnum::getCode).collect(Collectors.toList());
public static List<String> sortKeyList = Arrays.asList(listSortField.getCode(),listSortOrder.getCode(),fileIconSize.getCode(),listSortKeep.getCode(),listSort.getCode(),listType.getCode());
public static boolean contains(String value) {
return keyList.contains(value);
}
public static List<UserOption> setDefaultOptionList(Long userID){
List<UserOption> paramList = new ArrayList<>();
for (UserOptionEnum optionEnum :values()){
paramList.add(new UserOption(userID, optionEnum.getType(), optionEnum.getCode(), optionEnum.getValue()));
}
return paramList;
}
private String code;
private String value;
private String type;
UserOptionEnum(String code, String value, String type) {
this.code = code;
this.value = value;
this.type = type;
}
public String getType() {
return type;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,30 @@
package com.svnlan.enums;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/8 17:19
*/
public enum UserTypeEnum {
MANAGER(1, "系统管理员"),
USER(2, "其他用户"),
GUEST(3, "游客"),
;
private Integer code;
private String value;
UserTypeEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,47 @@
package com.svnlan.enums;
/**
* @Author:
* @Description: 用户具体类型
* @Date:
*/
public enum UserTypeExactEnum {
SYSTEM_ADMIN("1", "系统管理员"),
GENERAL_ADMIN("2", "普通管理员"),
USER("3", "用户"),
;
private String typeCode;
private String typeName;
UserTypeExactEnum(String typeCode, String typeName){
this.typeCode = typeCode;
this.typeName = typeName;
}
public String getTypeCode() {
return typeCode;
}
public String getTypeName() {
return typeName;
}
/**
* @description: 由code得对应的枚举
* @param typeCode
* @return com.svnlan.jwt.enums.UserTypeExactEnum
* @author
*/
public static UserTypeExactEnum getUserTypeExactEnumByCode(String typeCode) {
UserTypeExactEnum resultEnum = null;
for (UserTypeExactEnum tempEnum : UserTypeExactEnum.values()) {
if(tempEnum.getTypeCode().equals(typeCode)) {
resultEnum = tempEnum;
break;
}
}
return resultEnum;
}
}

View File

@ -0,0 +1,181 @@
package com.svnlan.exception;
/**
* @Description: 响应码枚举
* @Date:
*/
public enum CodeMessageEnum {
success("common.success", "成功"),
system_error("explorer.systemError", "系统错误"),
namePwdNotNull("user.namePwdNotNull", "账号密码不能为空!"),
user_pwdNotNull("user.pwdNotNull", "密码不能为空!"),
loginNoPermission("user.loginNoPermission", "抱歉,您没有该权限,请使用有此权限的账号登录!"),
loginFirst("user.loginFirst", "您尚未登录!请先登录"),
bindSignError("user.bindSignError", "签名异常,请重新操作一次!"),
bindUpdateError("user.bindUpdateError", "用户信息更新失败,请重试"),
bindTypeError("user.bindTypeError", "无效的绑定类型"),
bindWxConfigError("user.bindWxConfigError", "获取配置信息异常"),
loginTimeout("user.loginTimeout", "当前登录已超时,请重新登录!"),
loginTokenError("common.loginTokenError", "登录已失效,请重新登录!"),
loginSuccess("common.loginSuccess", "登录成功!"),
loginError("common.loginError", "登录失败"),
bindSuccess("common.bindSuccess", "绑定成功!"),
bindError("common.bindError", "绑定失败"),
passwordErrorLock("admin.setting.passwordErrorLock", "密码输入错误锁定"),
errorAdminAuth("admin.auth.errorAdmin", "权限不足"),
codeError("user.codeError", "验证码错误"),
rootPwdEqual("user.rootPwdEqual", "两次密码不一致!"),
rootPwdTips("user.rootPwdTips", "请设置管理员密码!"),
pwdError("user.pwdError", "用户名或密码错误!"),
oldPwdError("user.oldPwdError", "原密码错误!"),
userEnabled("user.userEnabled", "账号被禁用或尚未启用!请联系管理员"),
invalidEmail("user.invalidEmail", "您没有有效的邮箱地址,请联系管理员修改"),
roleError("user.roleError", "所属权限组不存在,请联系管理员"),
sendSuccess("user.sendSuccess", "发送成功"),
sendFail("user.sendFail", "发送失败"),
sendSuccessDesc("user.sendSuccessDesc", "验证码发送成功,请前往查看"),
sendFailDesc("user.sendFailDesc", "验证码发送失败,请联系管理员"),
codeExpired("user.codeExpired", "验证码已过期,请重新获取"),
codeErrorTooMany("user.codeErrorTooMany", "验证码错误次数过多,请重新获取"),
codeErrorFreq("user.codeErrorFreq", "发送频率过高,请稍后再试!"),
codeErrorCnt("user.codeErrorCnt", "发送次数已超限制,将被锁定%s小时。"),
registSuccess("user.registSuccess", "注册成功"),
roleDelErrTips("admin.role.delErrTips", "该角色正在被使用,无法删除!"),
shareErrorParam("explorer.share.errorParam", "参数错误!"),
paramFormatError("explorer.paramFormatError", "参数格式错误!"),
errorUser("explorer.share.errorUser", "用户信息错误!"),
errorPwd("explorer.share.errorPwd", "密码错误!"),
adminAuthError("admin.auth.error", "角色权限错误(没有权限设置)"),
authTargetError("admin.auth.targetError", "权限对象类型错误,必须为用户或部门"),
ERROR_USER_LOGIN_LOCK("ERROR_USER_LOGIN_LOCK", "抱歉,密码尝试输入错误过多,当前账号已锁定,请1分钟后再试!"),
explorerNotNull("explorer.notNull", "必填项不能为空!"),
registRoleEmpty("admin.setting.registRoleEmpty", "角色权限不能为空!"),
parentNullError("admin.group.parentNullError", "上级部门不能为空"),
picCannotNull("explorer.picCannotNull", "图片地址不能为空!"),
inputEmailCode("user.inputEmailCode", "请输入邮箱验证码!"),
inputSmsCode("user.inputSmsCode", "请输入短信验证码!"),
inputVerifyCode("user.inputVerifyCode", "请输入验证码!"),
inputPwd("user.inputPwd", "请输入密码!"),
inputPwdAgain("user.inputPwdAgain", "请再次输入密码!"),
inputNickName("user.inputNickName", "请输入昵称!"),
inputEmail("user.inputEmail", "请输入邮箱地址!"),
inputPhone("user.inputPhone", "请输入手机号!"),
inputPhoneEmail("user.inputPhoneEmail", "请输入手机/Email!"),
invalidPhoneEmail("user.invalidPhoneEmail", "无效的手机/Email!"),
defAdminError("admin.install.defAdminError", "管理员账号添加失败!"),
passwordCheckError("user.passwordCheckError", "密码格式不符合密码强度规则!"),
saveSuccess("explorer.saveSuccess", "保存成功!"),
saveError("explorer.saveError", "保存失败!"),
explorerSuccess("explorer.success", "操作成功!"),
explorerError("explorer.error", "操作失败!"),
explorerDataError("explorer.dataError", "数据异常!"),
userAvatarExt("user.userAvatarExt", "仅支持 JPG、JPEG、PNG 的图片格式!"),
ignoreFileSizeTips("admin.role.ignoreFileSizeTips", "抱歉,当文件超出大小限制; 具体请联系管理员!"),
msgSysSizeErr("msgWarning.main.msgSysSizeErr", "服务器系统盘剩余空间不足(%s)"),
pathNotSupport("explorer.pathNotSupport", "此类型目录不支持该操作!"),
pathIsRoot("explorer.pathIsRoot", "已经到根目录了!"),
pathNull("explorer.pathNull", "文件夹为空!"),
zipFileLarge("explorer.zipFileLarge", "该文件太大,请解压后再进行预览操作!"),
charNoSupport("explorer.charNoSupport", "不支持的特殊字符:"),
moveError("explorer.moveError", "移动失败!"),
lockError("explorer.lockError", "出错了,并发锁定超时!"),
lockErrorDesc("explorer.lockErrorDesc", "请稍后再试(可降低请求频率,优化并发相关配置)."),
moveSubPathError("explorer.moveSubPathError", "出错了,父目录不能移动到子目录!"),
spaceIsFull("explorer.spaceIsFull", "剩余空间不足,请联系管理员!"),
sessionSaveError("explorer.saveError", "session写入失败!请查看磁盘是否已满,或咨询服务商。"),
pathNotExists("common.pathNotExists", "该文件不存在!"),
fileLockError("explorer.fileLockError", "当前文件为锁定状态,请联系锁定者解锁后再试!"),
downError("explorer.downError", "下载失败!"),
sourceShareDisabled("source.shareDisabled","当前资源禁止分享"),
shareNotExist("explorer.share.notExist", "分享不存在"),
shareExpiredTips("explorer.share.expiredTips", "抱歉,该分享已过期,请联系分享者!"),
shareDownExceedTips("explorer.share.downExceedTips", "抱歉,该分享下载次数超过分享者设置的上限"),
shareLoginTips("explorer.share.loginTips", "抱歉,该分享必须登录用户才能访问"),
shareNoDownTips("explorer.share.noDownTips", "抱歉,该分享者禁用了下载"),
shareNoViewTips("explorer.share.noViewTips", "抱歉,该分享者禁用了预览"),
shareNoUploadTips("explorer.share.noUploadTips", "抱歉,该分享者禁用了上传"),
shareNeedPwd("explorer.share.needPwd", "该分享需要密码"),
shareActionNotSupport("explorer.share.actionNotSupport", "分享内容,不支持该操作"),
shareErrorPathTips("explorer.share.errorPathTips", "分享链接错误,或分享者已经取消了该外链分享"),
selectUserTips("admin.member.selectUserTips", "请选择要操作的账号!"),
rptSelectTips("admin.share.rptSelectTips", "请选择待操作项!"),
selectValidFolder("explorer.selectValidFolder", "请选择要有效的文件夹!"),
selectFolderFile("explorer.selectFolderFile", "选择文件或文件夹!"),
renameSuccess("explorer.renameSuccess", "重命名成功!"),
noPermissionRead("explorer.noPermissionRead", "您没有读取权限!"),
noPermissionDownload("explorer.noPermissionDownload", "您没有下载权限!"),
noPermissionWrite("explorer.noPermissionWrite", "该目录没有写权限!"),
noPermissionAction("explorer.noPermissionAction", "您没有此权限,请联系管理员!"),
noPermissionAuthAll("explorer.noPermissionAuthAll", "%s ,没有此操作权限"),
noPermissionWriteAll("explorer.noPermissionWriteAll", "该文件或目录没有写权限!"),
noPermissionWriteFile("explorer.noPermissionWriteFile", "该文件没有写权限!"),
noPermissionReadAll("explorer.noPermissionReadAll", "该文件或目录没有读权限!"),
noPermission("explorer.noPermission", "管理员禁止了此权限!"),
noPermissionExt("explorer.noPermissionExt", "管理员禁止了该类型文件权限!"),
descTooLong("explorer.descTooLong", "描述长度过长!"),
notSupport("explorer.notSupport", "出错了, 不支持该内容格式!"),
noPermissionGroup("explorer.noPermissionGroup", "您不在该用户组!"),
ERROR_USER_NOT_EXISTS("ERROR_USER_NOT_EXISTS", "用户不存在"),
ERROR_USER_PASSWORD_ERROR("ERROR_USER_PASSWORD_ERROR", "密码错误!"),
ERROR_USER_EXIST_NAME("ERROR_USER_EXIST_NAME", "用户名已存在"),
ERROR_USER_EXIST_PHONE("ERROR_USER_EXIST_PHONE", "手机号已存在"),
ERROR_USER_EXIST_EMAIL("ERROR_USER_EXIST_EMAIL", "该邮箱已存在"),
ERROR_USER_EXIST_NICKNAME("ERROR_USER_EXIST_NICKNAME", "昵称已存在"),
ERROR_IP_NOT_ALLOW("ERROR_IP_NOT_ALLOW", "您当前IP或访问设备不允许登录,请联系管理员"),
emailCodeText("admin.emailCodeText", "您正在进行邮箱验证,本次请求的验证码如下,为了保障您帐号的安全性,请及时完成验证。"),
repeatError("explorer.repeatError", "操作失败,该名称已存在"),
pathExists("explorer.pathExists", "该名称已存在"),
groupDelError("explorer.groupDelError", "抱歉部门文件夹不支持删除"),
unzipErrorTips("explorer.unzipErrorTips", "出错了!未识别的压缩文件格式;<br/> 请检查该文件是否为压缩文件或者是否损坏。"),
dragDownloadOpenTips("admin.setting.dragDownloadOpenTips", "请联系管理员在后台设置中开启"),
infoTypeDelError("admin.info.typeDelError", "删除失败,有子分类或数据"),
DOMAIN_CANNOT_RECOGNIZE("admin.info.domainIdentifyError", "网站无法识别"),
ARTICLE_CANNOT_RECOGNIZE("admin.info.articleIdentifyError", "文章无法识别"),
domainSupportError("admin.info.domainSupportError", "该网站暂不支持采集"),
fileTooLarge("admin.info.fileTooLarge", "文件过大"),
EXCEEDS_LIMIT("admin.exceeds.limit", "超出限制"),
Enabling_Not_Deleted("admin.design.deleted", "启用状态无法删除"),
designUrlLocked("admin.design.url.locked", "当前url被锁定, 暂时不能使用"),
SING_INVALID("explorer.SING_INVALID", "签名异常"),
TEMP_AUTH_INVALID("explorer.TEMP_AUTH_INVALID", "临时授权码无效(失效)"),
QR_INVALID("explorer.QR_INVALID", "二维码已失效"),
uploadError("explorer.upload.error", "上传失败"),
;
private String code;
private String msg;
CodeMessageEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
public static String getCode(String msg) {
for (CodeMessageEnum codeMsg : CodeMessageEnum.values()) {
if (codeMsg.msg.equals(msg)) {
return codeMsg.code;
}
}
return null;
}
public static String getMsg(String code) {
for (CodeMessageEnum codeMsg : CodeMessageEnum.values()) {
if (codeMsg.code.equals(code)) {
return codeMsg.msg;
}
}
return null;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}

View File

@ -0,0 +1,396 @@
package com.svnlan.exception;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 钉钉加解密
*
* @author lingxu 2023/03/28 14:30
*/
public class DingCallbackCrypto {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final Base64 base64 = new Base64();
private byte[] aesKey;
private String token;
private String corpId;
/**
* ask getPaddingBytes key固定长度
**/
private static final Integer AES_ENCODE_KEY_LENGTH = 43;
/**
* 加密随机字符串字节长度
**/
private static final Integer RANDOM_LENGTH = 16;
/**
* 构造函数
*
* @param token 钉钉开放平台上开发者设置的token
* @param encodingAesKey 钉钉开放台上开发者设置的EncodingAESKey
* @param corpId 企业自建应用-事件订阅, 使用appKey
* 企业自建应用-注册回调地址, 使用corpId
* 第三方企业应用, 使用suiteKey
* @throws DingTalkEncryptException 执行失败请查看该异常的错误码和具体的错误信息
*/
public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException {
if (null == encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL);
}
this.token = token;
this.corpId = corpId;
aesKey = Base64.decodeBase64(encodingAesKey + "=");
}
public Map<String, String> getEncryptedMap(String plaintext) throws DingTalkEncryptException {
return getEncryptedMap(plaintext, System.currentTimeMillis(), Utils.getRandomStr(16));
}
/**
* 将和钉钉开放平台同步的消息体加密,返回加密Map
*
* @param plaintext 传递的消息体明文
* @param timeStamp 时间戳
* @param nonce 随机字符串
* @return
* @throws DingTalkEncryptException
*/
public Map<String, String> getEncryptedMap(String plaintext, Long timeStamp, String nonce) throws DingTalkEncryptException {
if (null == plaintext) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL);
}
if (null == timeStamp) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_TIMESTAMP_ILLEGAL);
}
if (null == nonce) {
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL);
}
// 加密
String encrypt = encrypt(Utils.getRandomStr(RANDOM_LENGTH), plaintext);
String signature = getSignature(token, String.valueOf(timeStamp), nonce, encrypt);
Map<String, String> resultMap = new HashMap<>();
resultMap.put("msg_signature", signature);
resultMap.put("encrypt", encrypt);
resultMap.put("timeStamp", String.valueOf(timeStamp));
resultMap.put("nonce", nonce);
return resultMap;
}
/**
* 密文解密
*
* @param msgSignature 签名串
* @param timeStamp 时间戳
* @param nonce 随机串
* @param encryptMsg 密文
* @return 解密后的原文
* @throws DingTalkEncryptException
*/
public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg) throws DingTalkEncryptException {
//校验签名
String signature = getSignature(token, timeStamp, nonce, encryptMsg);
if (!signature.equals(msgSignature)) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
// 解密
String result = decrypt(encryptMsg);
return result;
}
/*
* 对明文加密.
* @param text 需要加密的明文
* @return 加密后base64编码的字符串
*/
private String encrypt(String random, String plaintext) throws DingTalkEncryptException {
try {
byte[] randomBytes = random.getBytes(CHARSET);
byte[] plainTextBytes = plaintext.getBytes(CHARSET);
byte[] lengthByte = Utils.int2Bytes(plainTextBytes.length);
byte[] corpidBytes = corpId.getBytes(CHARSET);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byteStream.write(randomBytes);
byteStream.write(lengthByte);
byteStream.write(plainTextBytes);
byteStream.write(corpidBytes);
byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size());
byteStream.write(padBytes);
byte[] unencrypted = byteStream.toByteArray();
byteStream.close();
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] encrypted = cipher.doFinal(unencrypted);
String result = base64.encodeToString(encrypted);
return result;
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR);
}
}
/*
* 对密文进行解密.
* @param text 需要解密的密文
* @return 解密得到的明文
*/
private String decrypt(String text) throws DingTalkEncryptException {
byte[] originalArr;
try {
// 设置解密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// 使用BASE64对密文进行解码
byte[] encrypted = Base64.decodeBase64(text);
// 解密
originalArr = cipher.doFinal(encrypted);
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);
}
String plainText;
String fromCorpid;
try {
// 去除补位字符
byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);
// 分离16位随机字符串,网络字节序和corpId
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLegth = Utils.bytes2int(networkOrder);
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);
}
// corpid不相同的情况
if (!fromCorpid.equals(corpId)) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);
}
return plainText;
}
/**
* 数字签名
*
* @param token isv token
* @param timestamp 时间戳
* @param nonce 随机串
* @param encrypt 加密文本
* @return
* @throws DingTalkEncryptException
*/
public String getSignature(String token, String timestamp, String nonce, String encrypt) throws DingTalkEncryptException {
try {
String[] array = new String[]{token, timestamp, nonce, encrypt};
Arrays.sort(array);
System.out.println(JSON.toJSONString(array));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
sb.append(array[i]);
}
String str = sb.toString();
System.out.println(str);
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
}
public static class Utils {
public Utils() {
}
public static String getRandomStr(int count) {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count; ++i) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
public static byte[] int2Bytes(int count) {
byte[] byteArr = new byte[]{(byte) (count >> 24 & 255), (byte) (count >> 16 & 255), (byte) (count >> 8 & 255), (byte) (count & 255)};
return byteArr;
}
public static int bytes2int(byte[] byteArr) {
int count = 0;
for (int i = 0; i < 4; ++i) {
count <<= 8;
count |= byteArr[i] & 255;
}
return count;
}
}
public static class PKCS7Padding {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;
public PKCS7Padding() {
}
public static byte[] getPaddingBytes(int count) {
int amountToPad = 32 - count % 32;
if (amountToPad == 0) {
amountToPad = 32;
}
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; ++index) {
tmp = tmp + padChr;
}
return tmp.getBytes(CHARSET);
}
public static byte[] removePaddingBytes(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
private static char chr(int a) {
byte target = (byte) (a & 255);
return (char) target;
}
}
public static class DingTalkEncryptException extends Exception {
public static final int SUCCESS = 0;
public static final int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001;
public static final int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002;
public static final int ENCRYPTION_NONCE_ILLEGAL = 900003;
public static final int AES_KEY_ILLEGAL = 900004;
public static final int SIGNATURE_NOT_MATCH = 900005;
public static final int COMPUTE_SIGNATURE_ERROR = 900006;
public static final int COMPUTE_ENCRYPT_TEXT_ERROR = 900007;
public static final int COMPUTE_DECRYPT_TEXT_ERROR = 900008;
public static final int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009;
public static final int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010;
private static Map<Integer, String> msgMap = new HashMap();
private Integer code;
static {
msgMap.put(0, "成功");
msgMap.put(900001, "加密明文文本非法");
msgMap.put(900002, "加密时间戳参数非法");
msgMap.put(900003, "加密随机字符串参数非法");
msgMap.put(900005, "签名不匹配");
msgMap.put(900006, "签名计算失败");
msgMap.put(900004, "不合法的aes key");
msgMap.put(900007, "计算加密文字错误");
msgMap.put(900008, "计算解密文字错误");
msgMap.put(900009, "计算解密文字长度不匹配");
msgMap.put(900010, "计算解密文字corpid不匹配");
}
public Integer getCode() {
return this.code;
}
public DingTalkEncryptException(Integer exceptionCode) {
super((String) msgMap.get(exceptionCode));
this.code = exceptionCode;
}
}
static {
try {
Security.setProperty("crypto.policy", "limited");
RemoveCryptographyRestrictions();
} catch (Exception var1) {
}
}
private static void RemoveCryptographyRestrictions() throws Exception {
Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity");
Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions");
Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission");
if (jceSecurity != null) {
setFinalStaticValue(jceSecurity, "isRestricted", false);
PermissionCollection defaultPolicy = (PermissionCollection) getFieldValue(jceSecurity, "defaultPolicy", (Object) null, PermissionCollection.class);
if (cryptoPermissions != null) {
Map<?, ?> map = (Map) getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class);
map.clear();
}
if (cryptoAllPermission != null) {
Permission permission = (Permission) getFieldValue(cryptoAllPermission, "INSTANCE", (Object) null, Permission.class);
defaultPolicy.add(permission);
}
}
}
private static Class<?> getClazz(String className) {
Class clazz = null;
try {
clazz = Class.forName(className);
} catch (Exception var3) {
}
return clazz;
}
private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & -17);
field.set((Object) null, newValue);
}
private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
return dstClazz.cast(field.get(owner));
}
}

View File

@ -0,0 +1,124 @@
package com.svnlan.exception;
import com.svnlan.common.I18nUtils;
/**
* @Author:
* @Description: 自定义运行时异常抛出不符合业务需求的结果异常
* @Modified:
*/
public class SvnlanRuntimeException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 错误编码
*/
private String errorCode;
/**
* 消息是否为属性文件中的Key
*/
private boolean propertiesKey = true;
/**
* 构造一个基本异常.
*
* @param i18eCode 信息描述
*/
public SvnlanRuntimeException(String i18eCode) {
// 根据资源文件的属性名以及当前语言环境获取国际化信息
super(I18nUtils.tryI18n(i18eCode));
this.setErrorCode(i18eCode);
}
public SvnlanRuntimeException(String i18eCode, Object... args) {
// 根据资源文件的属性名属性值中的参数以及当前语言环境获取国际化信息
// args用来替换资源文件属性值中的占位符参数
super(I18nUtils.tryI18n(i18eCode, args));
this.setErrorCode(i18eCode);
}
/**
* 构造一个基本异常.
*
* @param errorCode 错误编码
* @param message 信息描述
*/
/* public SvnlanRuntimeException(String errorCode, String message)
{
this(errorCode, message, true);
}*/
/**
* 构造一个基本异常.
*
* @param errorCode 错误编码
* @param message 信息描述
*/
public SvnlanRuntimeException(String errorCode, String message, Throwable cause)
{
this(errorCode, message, cause, true);
}
/**
* 构造一个基本异常.
*
* @param errorCode 错误编码
* @param message 信息描述
* @param propertiesKey 消息是否为属性文件中的Key
*/
public SvnlanRuntimeException(String errorCode, String message, boolean propertiesKey)
{
super(message);
this.setErrorCode(errorCode);
this.setPropertiesKey(propertiesKey);
}
/**
* 构造一个基本异常.
*
* @param errorCode 错误编码
* @param message 信息描述
*/
public SvnlanRuntimeException(String errorCode, String message, Throwable cause, boolean propertiesKey)
{
super(message, cause);
this.setErrorCode(errorCode);
this.setPropertiesKey(propertiesKey);
}
/**
* 构造一个基本异常.
*
* @param message 信息描述
* @param cause 根异常类可以存入任何异常
*/
public SvnlanRuntimeException(String message, Throwable cause)
{
super(message, cause);
}
public SvnlanRuntimeException(CodeMessageEnum codeMessageEnum) {
this(codeMessageEnum.getCode(), codeMessageEnum.getMsg());
}
public String getErrorCode()
{
return errorCode;
}
public void setErrorCode(String errorCode)
{
this.errorCode = errorCode;
}
public boolean isPropertiesKey()
{
return propertiesKey;
}
public void setPropertiesKey(boolean propertiesKey)
{
this.propertiesKey = propertiesKey;
}
}

View File

@ -0,0 +1,103 @@
package com.svnlan.home.controller;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.domain.Comment;
import com.svnlan.home.dto.CommentDto;
import com.svnlan.home.service.CommentService;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import com.svnlan.utils.PageResult;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/8/1 14:19
*/
@RestController
public class CommentController {
@Resource
CommentService commentService;
@Resource
LoginUserUtil loginUserUtil;
/**
* @Description: 添加评论
* @params: [dto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/comment/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String saveComment(@RequestBody CommentDto dto) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
Comment comment = commentService.saveComment(dto, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), comment);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), e.getMessage());
} catch (Exception e) {
LogUtil.error(e, "保存评论失败" + JsonUtils.beanToJson(dto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 删除评论
* @params: [dto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/comment/del", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String delComment(@RequestBody CommentDto dto) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
commentService.delComment(dto, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), e.getMessage());
} catch (Exception e) {
LogUtil.error(e, "删除评论失败" + JsonUtils.beanToJson(dto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 评论列表
* @params: [dto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/comment/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getCommentList(CommentDto dto) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
PageResult re = null;
try {
re = commentService.getCommentList(dto, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "分享列表" + JsonUtils.beanToJson(dto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,245 @@
package com.svnlan.home.controller;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.CheckFileDTO;
import com.svnlan.home.dto.LabelDto;
import com.svnlan.home.service.CommonLabelService;
import com.svnlan.home.utils.UserAuthTool;
import com.svnlan.home.vo.CommonLabelVo;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @Author: sulijuan
* @Description: 标签
* @Date: 2023/3/2 10:52
*/
@RestController
public class CommonLabelController {
@Resource
LoginUserUtil loginUserUtil;
@Resource
CommonLabelService commonLabelService;
@Resource
UserAuthTool userAuthTool;
@Resource
StringRedisTemplate stringRedisTemplate;
@RequestMapping(value = "/api/disk/tag/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String addTag(@Valid @RequestBody LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
commonLabelService.addTag(labelDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "添加标签" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/tag/edit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String editTag(@Valid @RequestBody LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
commonLabelService.editTag(labelDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "编辑标签" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/tag/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String list(LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
List<CommonLabelVo> list = commonLabelService.getTagList(labelDto, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), list);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "编辑标签" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/tag/fileTag", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String fileTag(@Valid @RequestBody LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
commonLabelService.fileTag(labelDto, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "操作关联标签" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/tag/del", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String delTag(@Valid @RequestBody LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
commonLabelService.delTag(labelDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "编辑标签" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 标签下的文件置顶
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/tag/moveTop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String moveTop(@Valid @RequestBody CheckFileDTO labelDto){
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
boolean success = commonLabelService.moveTop(labelDto, resultMap, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e){
LogUtil.error(e, "标签下的文件置顶失败" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 标签下的文件置底
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/tag/moveBottom", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String moveBottom(@Valid @RequestBody CheckFileDTO labelDto){
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
boolean success = commonLabelService.moveBottom(labelDto, resultMap, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e){
LogUtil.error(e, "标签下的文件置底失败" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 标签夹置顶
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/tag/top", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String tagTop(@Valid @RequestBody LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
boolean success = commonLabelService.tagTop(labelDto, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "标签置顶失败" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 标签置底
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/tag/bottom", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String tagBottom(@Valid @RequestBody LabelDto labelDto){
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
boolean success = commonLabelService.tagBottom(labelDto, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "标签置底失败" + JsonUtils.beanToJson(labelDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,97 @@
package com.svnlan.home.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.DingCallbackCrypto;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.DingDto;
import com.svnlan.home.dto.LabelDto;
import com.svnlan.home.vo.CommonLabelVo;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import org.apache.tomcat.util.bcel.classfile.Constant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/3/28 14:54
*/
@RestController
public class DingController {
@Value("${dingding.token}")
private String dingToken;
@Value("${dingding.aes.key}")
private String dingAesKey;
@Value("${dingding.app.key}")
private String ownKey;
@PostMapping("/api/disk/dingCallback2")
public Map<String, String> eventCallback(HttpServletRequest request,
@RequestParam(value = "msg_signature", required = false) String msg_signature,
@RequestParam(value = "timestamp", required = false) String timeStamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestBody(required = false) JSONObject json) throws DingCallbackCrypto.DingTalkEncryptException {
DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(dingToken, dingAesKey, ownKey);
Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
LogUtil.info(successMap.toString());
return successMap;
}
@PostMapping("/api/disk/dingCallback")
public Map<String, String> callBack(
@RequestParam(value = "msg_signature", required = false) String msg_signature,
@RequestParam(value = "timestamp", required = false) String timeStamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestBody(required = false) JSONObject json) {
try {
// 1. 从http请求中获取加解密参数
// 2. 使用加解密类型
// Constant.OWNER_KEY 说明
// 1开发者后台配置的订阅事件为应用级事件推送此时OWNER_KEY为应用的APP_KEY
// 2调用订阅事件接口订阅的事件为企业级事件推送
// 此时OWNER_KEY为企业的appkey企业内部应用或SUITE_KEY三方应用
DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(dingToken, dingAesKey, ownKey);
String encryptMsg = json.getString("encrypt");
String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);
// 3. 反序列化回调事件json数据
JSONObject eventJson = JSON.parseObject(decryptMsg);
String eventType = eventJson.getString("EventType");
// 4. 根据EventType分类处理
if ("check_url".equals(eventType)) {
// 测试回调url的正确性
LogUtil.info("测试回调url的正确性");
} else if ("user_add_org".equals(eventType)) {
// 处理通讯录用户增加事件
LogUtil.info("发生了:" + eventType + "事件");
} else {
// 添加其他已注册的
LogUtil.info("发生了:" + eventType + "事件");
}
// 5. 返回success的加密数据
Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
return successMap;
} catch (DingCallbackCrypto.DingTalkEncryptException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,111 @@
package com.svnlan.home.controller;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.HomeExplorerDTO;
import com.svnlan.home.service.ExplorerFileService;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.jwt.tool.JWTTool;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/4/25 14:15
*/
@RestController
public class ExplorerFileController {
@Autowired
ExplorerFileService explorerFileService;
@Resource
JWTTool jwtTool;
@Resource
LoginUserUtil loginUserUtil;
/**
* @Description: 压缩包预览
* @params: [homeExp, request]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/4/25 14:23
* @Modified:
*/
@GetMapping("/api/disk/unzipList")
public String unzipList(HomeExplorerDTO homeExp, HttpServletRequest request) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
Object re;
LoginUser loginUser = loginUserUtil.getLoginUser(request);
try {
if (ObjectUtils.isEmpty(loginUser)){
loginUser = new LoginUser();
loginUser.setUserID(0L);
loginUser.setUserType(4);
loginUser.setName("demo");
loginUser.setNickname("游客");
}
re = explorerFileService.unzipList(homeExp, loginUser);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), re);
return JsonUtils.beanToJson(result);
}
/**
* @Description: 查看压缩包是否有密码
* @params: [homeExp, request]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/5/5 14:54
* @Modified:
*/
@GetMapping("/api/disk/checkIsEncrypted")
public String checkZipIsEncrypted(HomeExplorerDTO homeExp, HttpServletRequest request) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
Object re;
LoginUser loginUser = loginUserUtil.getLoginUser(request);
try {
if (ObjectUtils.isEmpty(loginUser)){
result = new Result(false, CodeMessageEnum.bindSignError.getCode(), null);
return JsonUtils.beanToJson(result);
}
re = explorerFileService.checkZipIsEncrypted(homeExp);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), re);
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,105 @@
package com.svnlan.home.controller;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.CheckFileDTO;
import com.svnlan.home.dto.ExplorerOperationsDTO;
import com.svnlan.home.dto.ExplorerShareDTO;
import com.svnlan.home.service.ExplorerOperationsService;
import com.svnlan.home.vo.HomeExplorerVO;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.jwt.tool.JWTTool;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author KingMgg
* @data 2023/2/7 16:07
*/
@Api("用户操作")
@RestController
public class ExplorerOperationsController {
@Autowired
ExplorerOperationsService operationsService;
@Resource
JWTTool jwtTool;
@Resource
LoginUserUtil loginUserUtil;
/**
* 初始化io_source的 parentLevel 父路径id; 例如: ,0,2,5,10,
*
* @param
* @return
*/
@RequestMapping(value = "/api/disk/initSourcePathLevel", method = RequestMethod.GET)
public String initSourcePathLevel(ExplorerOperationsDTO dto) {
Result result;
try {
operationsService.initSourcePathLevel(dto.getSourceID());
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, " initSourcePathLevel Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, " initSourcePathLevel Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 根据入参统计文件夹的size
* @params: [operation 需要统计的文件夹ID多个用英文逗号,隔开,status=1则统计未删除的不传默认都统计]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/9/9 12:51
* @Modified:
*/
@RequestMapping(value = "/api/disk/countSize", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String zip(@RequestBody CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
if (ObjectUtils.isEmpty(loginUser.getUserType()) || loginUser.getUserType().intValue() != 1) {
result = new Result(false, CodeMessageEnum.errorAdminAuth.getCode(), null);
return JsonUtils.beanToJson(result);
}
try {
operationsService.countSize(updateFileDTO, resultMap, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "压缩zip失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,107 @@
package com.svnlan.home.controller;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.CheckFileDTO;
import com.svnlan.home.service.FileDocConvertService;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.jwt.tool.JWTTool;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/6/28 13:40
*/
@RestController
public class FileDocConvertController {
@Resource
FileDocConvertService fileDocConvertService;
@Resource
JWTTool jwtTool;
@Resource
LoginUserUtil loginUserUtil;
@Resource
StringRedisTemplate stringRedisTemplate;
/**
* @Description: 文件互转功能
* @params: [updateFileDTO, request]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/6/28 14:02
* @Modified:
*/
@RequestMapping(value = "/api/disk/doc/convert", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String doc2Convert(@RequestBody CheckFileDTO updateFileDTO, HttpServletRequest request){
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info(prefix + " videoCommonDto=" + JsonUtils.beanToJson(updateFileDTO));
re = fileDocConvertService.doc2Convert(updateFileDTO, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, prefix + "文件互转失败 " + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
// 视频转码
/*if (!CollectionUtils.isEmpty(list)) {
for (CommonSource source : list) {
ConvertDTO convertDTO = new ConvertDTO();
convertDTO.setBusId(source.getSourceID());
convertDTO.setBusType("cloud");
convertDTO.setOtherType("docConvert");
String serverUrl = HttpUtil.getRequestRootUrl(null);
source.setDomain(serverUrl);
convertDTO.setDomain(serverUrl);
convertUtil.doConvert(convertDTO, source);
}
}*/
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/doc/convert/taskAction", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String zipTaskAction(HttpServletResponse response, CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
boolean success = true;
try {
success = fileDocConvertService.taskAction(updateFileDTO, resultMap, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "taskAction转换失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
if (!ObjectUtils.isEmpty(resultMap) && resultMap.containsKey("status") && "1".equals(resultMap.get("status").toString())) {
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,56 @@
package com.svnlan.home.controller;
import com.svnlan.annotation.VisitRecord;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.CheckFileDTO;
import com.svnlan.home.service.FilePreViewService;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/4/26 16:38
*/
@RestController
public class FilePreViewController {
@Resource
LoginUserUtil loginUserUtil;
@Resource
FilePreViewService filePreViewService;
@RequestMapping(value = "/api/disk/previewXml", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String preview(HttpServletResponse response, CheckFileDTO checkFileDTO){
if (ObjectUtils.isEmpty(checkFileDTO.getShareCode())){
LoginUser loginUser = loginUserUtil.getLoginUser();
if (ObjectUtils.isEmpty(loginUser)){
Result result = new Result(false, CodeMessageEnum.bindSignError.getCode(), null);
return JsonUtils.beanToJson(result);
}
checkFileDTO.setLoginUser(loginUser);
}
try {
return filePreViewService.getPreviewXml(checkFileDTO);
} catch (SvnlanRuntimeException e){
LogUtil.error(e, "previewXml 云盘获取预览信息失败");
} catch (Exception e){
LogUtil.error(e, "previewXml error 云盘获取预览信息失败");
}
return "";
}
}

View File

@ -0,0 +1,501 @@
package com.svnlan.home.controller;
import com.alibaba.fastjson.JSONObject;
import com.svnlan.annotation.VisitRecord;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.domain.CommonSource;
import com.svnlan.home.domain.IOSource;
import com.svnlan.home.dto.AddCloudDirectoryDTO;
import com.svnlan.home.dto.AddSubCloudDirectoryDTO;
import com.svnlan.home.dto.HomeExplorerDTO;
import com.svnlan.home.dto.HomeSettingDTO;
import com.svnlan.home.service.HomeExplorerService;
import com.svnlan.home.service.SourceFileService;
import com.svnlan.home.service.SourceHistoryService;
import com.svnlan.home.vo.*;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.jwt.tool.JWTTool;
import com.svnlan.user.service.IoSourceService;
import com.svnlan.user.service.SystemLogService;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import com.svnlan.utils.PageResult;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author KingMgg
* @data 2023/2/6 11:43
*/
@Api("首页的文件管理目录")
@RestController
public class HomeExplorerController {
@Autowired
HomeExplorerService homeExplorerService;
@Resource
private LoginUserUtil loginUserUtil;
@Resource
JWTTool jwtTool;
@Resource
SourceHistoryService sourceHistoryService;
@Resource
IoSourceService ioSourceService;
@Resource
SourceFileService sourceFileService;
@Resource
StringRedisTemplate stringRedisTemplate;
@Resource
private SystemLogService systemLogService;
/**
* 获取文件目录
*
* @param homeExp
* @return
*/
@VisitRecord(isAsync = true)
@GetMapping("/api/disk/list/path")
public String homeExplorer(HomeExplorerDTO homeExp, HttpServletRequest request) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
HomeExplorerResult explorerResult;
LoginUser loginUser = loginUserUtil.getLoginUser(request);
try {
if (ObjectUtils.isEmpty(loginUser)) {
result = new Result(false, CodeMessageEnum.bindSignError.getCode(), null);
return JsonUtils.beanToJson(result);
}
explorerResult = homeExplorerService.homeExplorer(homeExp, loginUser);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), e.getMessage());
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), explorerResult);
return JsonUtils.beanToJson(result);
}
/**
* 获取文件详情
*
* @param
* @return
*/
@VisitRecord(isAsync = true)
@GetMapping("/api/disk/getFileDetail")
public String getFileDetail(HomeExplorerVO homeExplorerVO, HttpServletRequest request) {
String prefix = this.jwtTool.findApiPrefix(request);
HomeFileDetailVO fileDetail;
Result result;
try {
fileDetail = homeExplorerService.getFileDetail(homeExplorerVO);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
result = new Result(true, CodeMessageEnum.success.getCode(), fileDetail);
return JsonUtils.beanToJson(result);
}
/**
* @Description: 创建文件夹
* @params: [homeExplorerVO, httpServletRequest]
* @Return: com.svnlan.common.Result
* @Modified:
*/
@PostMapping("/api/disk/createFolder")
public String createFolder(@RequestBody HomeExplorerVO homeExplorerVO, HttpServletRequest httpServletRequest) {
String prefix = this.jwtTool.findApiPrefix(httpServletRequest);
LoginUser loginUser = loginUserUtil.getLoginUser(httpServletRequest);
if (null == loginUser.getUserID()) {
throw new SvnlanRuntimeException(CodeMessageEnum.loginFirst.getMsg());
}
Result result;
homeExplorerVO.setTargetID(loginUser.getUserID());
homeExplorerVO.setCreateUser(loginUser.getUserID());
homeExplorerVO.setModifyUser(loginUser.getUserID());
homeExplorerVO.setIsFolder(1);
try {
IOSource source = homeExplorerService.createDir(homeExplorerVO, loginUser);
Map<String, Object> resultMap = new HashMap<>(1);
resultMap.put("source", source);
result = new Result(true, CodeMessageEnum.success.getCode(), resultMap);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(),e.getMessage(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 设置文件夹操作排序图标大小等
* @params: [homeExplorerVO, httpServletRequest]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/2/18 10:51
* @Modified:
*/
@PostMapping("/api/disk/folder/setting")
public String folderSetting(@RequestBody HomeSettingDTO homeExplorerVO, HttpServletRequest httpServletRequest) {
String prefix = this.jwtTool.findApiPrefix(httpServletRequest);
LoginUser loginUser = loginUserUtil.getLoginUser(httpServletRequest);
if (null == loginUser.getUserID()) {
throw new SvnlanRuntimeException(CodeMessageEnum.loginFirst.getMsg());
}
Result result;
homeExplorerVO.setTargetID(loginUser.getUserID());
homeExplorerVO.setCreateUser(loginUser.getUserID());
homeExplorerVO.setModifyUser(loginUser.getUserID());
homeExplorerVO.setIsFolder(1);
try {
homeExplorerService.folderSetting(homeExplorerVO, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
result = new Result(true, CodeMessageEnum.success.getCode(), true);
return JsonUtils.beanToJson(result);
}
/**
* @Description: 文件动态
* @params: [homeExplorerVO, request]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/2/22 16:10
* @Modified:
*/
@GetMapping("/api/disk/pathLog")
public String pathLog(HomeExplorerDTO homeExplorerVO, HttpServletRequest request) {
String prefix = this.jwtTool.findApiPrefix(request);
PageResult re;
Result result;
try {
re = homeExplorerService.getPathLog(homeExplorerVO);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
result = new Result(true, CodeMessageEnum.success.getCode(), re);
return JsonUtils.beanToJson(result);
}
/**
* 获取系统设置
*
* @param
* @return
*/
@VisitRecord(isAsync = true)
@GetMapping("/api/disk/home")
public String home(HttpServletRequest request) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
Map<String, Object> explorerResult;
try {
explorerResult = homeExplorerService.systemOpenInfo();
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), explorerResult);
return JsonUtils.beanToJson(result);
}
/**
* 获取文件历史记录
*
* @param
* @return
*/
@GetMapping("/api/disk/history/get")
public String sourceHistoryList(HttpServletRequest request, HomeExplorerDTO homeExplorerDTO) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
HomeExplorerResult explorerResult;
try {
explorerResult = sourceHistoryService.getSourceHistoryList(homeExplorerDTO);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), explorerResult);
return JsonUtils.beanToJson(result);
}
@PostMapping("/api/disk/history/setDetail")
public String sourceHistorySetDetail(HttpServletRequest request, @RequestBody HomeExplorerDTO homeExplorerDTO) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
try {
sourceHistoryService.setHistoryDetail(homeExplorerDTO);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), null);
return JsonUtils.beanToJson(result);
}
/**
* @Description: 删除历史版本
* @params: [request, homeExplorerDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/31 15:48
* @Modified:
*/
@PostMapping("/api/disk/history/delete")
public String sourceHistoryDelete(HttpServletRequest request, @RequestBody HomeExplorerDTO homeExplorerDTO) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
try {
sourceHistoryService.deleteHistory(homeExplorerDTO);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), null);
return JsonUtils.beanToJson(result);
}
/**
* @Description: 历史记录设置当前版本
* @params: [request, homeExplorerDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/4/20 11:23
* @Modified:
*/
@PostMapping("/api/disk/history/setVersion")
public String setHistoryRevision(HttpServletRequest request, @RequestBody HomeExplorerDTO homeExplorerDTO) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
sourceHistoryService.setHistoryRevision(homeExplorerDTO, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), null);
return JsonUtils.beanToJson(result);
}
@GetMapping("/api/disk/parentSourceList")
public String parentSourceList(HttpServletRequest request, HomeExplorerDTO homeExplorerDTO) {
String prefix = this.jwtTool.findApiPrefix(request);
Result result;
List re;
try {
re = sourceHistoryService.parentSourceList(homeExplorerDTO, loginUserUtil.getLoginUser());
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, prefix + " Svnlan error!");
//处理异常
result = new Result(false, e.getErrorCode(), null);
return JsonUtils.beanToJson(result);
} catch (Exception e) {
LogUtil.error(e, prefix + " Exception error!");
//处理异常
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
return JsonUtils.beanToJson(result);
}
// 返回平台信息
result = new Result(true, CodeMessageEnum.success.getCode(), re);
return JsonUtils.beanToJson(result);
}
/**
* 获取用户文件类型占比
*/
@GetMapping("/api/disk/userProportion")
public Result getFileTypeProportionByUserId() {
LoginUser loginUser = loginUserUtil.getLoginUser();
List<JSONObject> jsonList = ioSourceService.getFileTypeProportionByUserId(loginUser.getUserID());
return Result.returnSuccess(
new JSONObject().fluentPut("fileTypeProportion", jsonList)
);
}
@RequestMapping(value = "/api/disk/addBatchDirectory", method = RequestMethod.POST)
public String addBatchDirectory(@Valid @RequestBody AddCloudDirectoryDTO addCloudDirectoryDTO) {
Result result = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
List<AddSubCloudDirectoryDTO> list = sourceFileService.addBatchDirectory(addCloudDirectoryDTO, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), list);
} catch (SvnlanRuntimeException e) {
result = new Result(false, CodeMessageEnum.system_error.getCode(), e.getMessage(), null);
} catch (Exception e) {
LogUtil.error(e, "云盘文件夹批量创建失败" + JsonUtils.beanToJson(addCloudDirectoryDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/homeExplorer", method = RequestMethod.GET)
public String homeExplorerVo(HomeExplorerDTO homeExp, HttpServletRequest request) {
Result result = null;
try {
HomeExplorerVO re = homeExplorerService.getHomeExplorer(homeExp, loginUserUtil.getLoginUser());
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
} catch (Exception e) {
LogUtil.error(e, "/api/disk/homeExplorer获取详情" + JsonUtils.beanToJson(homeExp));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/execImgVideoThumb", method = RequestMethod.GET)
public String execImgVideoThumb(HomeExplorerDTO homeExp, HttpServletRequest request) {
Result result = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
HomeExplorerVO re = homeExplorerService.execImgVideoThumb(homeExp, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
} catch (Exception e) {
LogUtil.error(e, "/api/disk/execImgVideoThumb" + JsonUtils.beanToJson(homeExp));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* 用户登陆设置统计
*/
@RequestMapping(value = "/api/disk/loginDevice/stat", method = RequestMethod.GET)
public Result userLoginDeviceStat() {
return Result.returnSuccess(systemLogService.selectUserLoginDeviceStat(30, loginUserUtil.getLoginUserId()));
}
/**
* @Description: 获得文件夹下的图片列表
* @params: [homeExp, request]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/getImgList", method = RequestMethod.GET)
public String getImgList(HomeExplorerDTO homeExp) {
Result result = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
List re = sourceFileService.getImgList(homeExp, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
} catch (Exception e) {
LogUtil.error(e, "/api/disk/getImgList" + JsonUtils.beanToJson(homeExp));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,95 @@
package com.svnlan.home.controller;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.service.M3u8Service;
import com.svnlan.home.dto.*;
import com.svnlan.home.utils.CommonConvertUtil;
import com.svnlan.utils.LogUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
/**
* @Author:
* @Description:
* @Date:
*/
@RestController
public class M3u8Controller {
@Resource
private M3u8Service m3u8Service;
@Resource
private CommonConvertUtil commonConvertUtil;
@RequestMapping(value = "/api/disk/mu/key", method = RequestMethod.GET)
public String getKey(HttpServletResponse response,String key){
try {
m3u8Service.getKey(key,response);
} catch (Exception e){
LogUtil.error(e, "获取key失败");
}
return "error";
}
@RequestMapping(value = "/api/disk/mu/getM3u8.m3u8", method = RequestMethod.GET)
public String getM3u8(HttpServletResponse response, HttpServletRequest request, GetM3u8DTO getM3u8DTO){
try {
m3u8Service.getM3u8(getM3u8DTO, response, request);
} catch (SvnlanRuntimeException e) {
return e.getMessage();
} catch (Exception e){
LogUtil.error(e, "获取m3u8失败");
}
return "error";
}
/**
* @Description: m3u8鉴权接口
* @params: [response, request, getM3u8DTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/mu/getMyM3u8.m3u8", method = RequestMethod.GET)
public String getM3u8WithAuth(HttpServletResponse response, HttpServletRequest request,@Valid GetM3u8NewDTO getM3u8DTO){
try {
String m3u8WithAuth = m3u8Service.getM3u8WithAuth(getM3u8DTO, response, request, 0);
if (m3u8WithAuth != null){
return m3u8WithAuth;
}
} catch (SvnlanRuntimeException e) {
return e.getMessage();
} catch (Exception e){
LogUtil.error(e, "获取m3u8失败");
}
return "error";
}
/**
* @Description: m3u8鉴权接口api
* @params: [response, request, getM3u8DTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/service/mu/getMyM3u8.m3u8", method = RequestMethod.GET)
public String getCommonM3u8WithAuth(HttpServletResponse response, HttpServletRequest request, GetMyM3u8DTO getMyM3u8DTO){
GetM3u8NewDTO getM3u8DTO;
try {
getM3u8DTO = commonConvertUtil.convertGetM3u8NewDTO(getMyM3u8DTO);
String m3u8WithAuth = m3u8Service.getM3u8WithAuth(getM3u8DTO, response, request, 1);
if (m3u8WithAuth != null){
return m3u8WithAuth;
}
} catch (SvnlanRuntimeException e) {
return e.getMessage();
} catch (Exception e){
LogUtil.error(e, "/api/common/service/mu/getMyM3u8.m3u8 获取m3u8失败");
}
return "error";
}
}

View File

@ -0,0 +1,66 @@
package com.svnlan.home.controller;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.svnlan.common.Result;
import com.svnlan.user.service.NoticeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
/**
* C 通知
*
* @author lingxu 2023/05/20 10:54
*/
@Slf4j
@RestController("noticeWebController")
@RequestMapping("api/notice")
public class NoticeController {
@Resource
private NoticeService noticeService;
/**
* C端查询通知消息列表
*/
@GetMapping("read/list/page")
public Result noticeList(@RequestParam("currentPage") Integer currentPage, @RequestParam("pageSize") Integer pageSize) {
JSONObject jsonObject = noticeService.pageList(currentPage, pageSize);
return Result.returnSuccess(jsonObject);
}
/**
* C端查询未读消息数
*/
@GetMapping("unread")
public Result hasNoticeUnread() {
return Result.returnSuccess(noticeService.hasNoticeUnread());
}
/**
* C端消息信息
*/
@GetMapping("info")
public Result noticeInfo(Long id) {
List<Long> ids = Lists.asList(id, new Long[]{});
List<JSONObject> previewList = noticeService.preview(ids);
if (!CollectionUtils.isEmpty(previewList)) {
JSONObject jsonObject = previewList.get(0);
if (Objects.equals(jsonObject.getInteger("status"), 1)) {
noticeService.executeNoticeRead(id);
return Result.returnSuccess(previewList.get(0));
}
}
return Result.returnSuccess();
}
}

View File

@ -0,0 +1,333 @@
package com.svnlan.home.controller;
import com.svnlan.annotation.CreateGroup;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.dto.HomeExplorerDTO;
import com.svnlan.home.dto.ShareDTO;
import com.svnlan.home.service.ShareService;
import com.svnlan.home.vo.HomeExplorerResult;
import com.svnlan.home.vo.ShareVo;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.user.dto.ShareReportDTO;
import com.svnlan.user.dto.UserDTO;
import com.svnlan.user.service.ShareReportService;
import com.svnlan.user.vo.SelectAuthVo;
import com.svnlan.utils.JsonUtils;
import com.svnlan.utils.LogUtil;
import com.svnlan.utils.LoginUserUtil;
import com.svnlan.utils.PageResult;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @Author: sulijuan
* @Description: 分享/协作
* @Date: 2023/3/3 13:33
*/
@RestController
public class ShareController {
@Resource
LoginUserUtil loginUserUtil;
@Resource
ShareService shareService;
@Resource
StringRedisTemplate stringRedisTemplate;
/**
* @Description: 添加外部分享
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/3 14:41
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String saveShare(@Valid @RequestBody ShareDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
shareService.saveShare(shareDTO, loginUser);
stringRedisTemplate.delete(GlobalConfig.my_share_key + loginUser.getUserID());
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "保存分享失败" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 取消外部分享
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/3 14:41
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/cancel", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String cancelShare(@Valid @RequestBody ShareDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
shareService.cancelShare(shareDTO, loginUser);
stringRedisTemplate.delete(GlobalConfig.my_share_key + loginUser.getUserID());
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), null);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "取消分享失败" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 获得单个分享链接详情
* @params: [labelDto]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/3 13:37
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getShare(ShareDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
ShareVo re = shareService.getShare(shareDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "获得单个分享链接详情失败" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 分享列表
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/8 14:17
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getShareList(HomeExplorerDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
HomeExplorerResult re = null;
try {
re = shareService.getShareList(shareDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "分享列表" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 对外查询分享配置
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/6 16:11
* @Modified:
*/
@RequestMapping(value = "/api/disk/share/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getShareFile(ShareDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
ShareVo re = shareService.getShareFile(shareDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, " 对外查询分享配置失败" + JsonUtils.beanToJson(shareDTO));
if (e instanceof IllegalArgumentException) {
result = new Result(false, e.getMessage());
}else{
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 查询分享下文件夹列表
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/7 17:30
* @Modified:
*/
@RequestMapping(value = "/api/disk/share/pathList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getShareFileList(HomeExplorerDTO shareDTO) {
Result result;
try {
HomeExplorerResult re = shareService.getLinkShareList(shareDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, " 对外查询分享配置失败" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/share/menu", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getShareMenuList(HomeExplorerDTO shareDTO) {
Result result;
try {
shareDTO.setIsFolder(1);
HomeExplorerResult re = shareService.getLinkShareList(shareDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, " 对外查询分享左边菜单列表失败" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 与我协作列表
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/8 14:17
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/shareToMe", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String shareToMe(HomeExplorerDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
HomeExplorerResult re = null;
try {
re = shareService.shareToMeList(shareDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "与我协作列表" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 选择协作部门或用户列表
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/9 9:10
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/groupList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String userGroupList(HomeExplorerDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
SelectAuthVo re = null;
try {
re = shareService.userGroupList(shareDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "选择协作部门或用户列表 error" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/share/previewNum", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String previewNum(ShareDTO shareDTO) {
Result result;
Map<String, Object> re = null;
String key = "previewNum_" + shareDTO.getShareCode();
try {
final Boolean setFlag = this.stringRedisTemplate.opsForValue().setIfAbsent(key, "1");
if (setFlag == null || !setFlag) {
// 流程处理中
re = new HashMap<>(1);
re.put("numView", 0);
} else {
re = shareService.previewNum(shareDTO);
}
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, " 对外查询分享配置失败" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
} finally {
this.stringRedisTemplate.delete(key);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 选择协作部门或用户列表 (用于搜索只返回用户)
* @params: [shareDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/5/8 16:54
* @Modified:
*/
@RequestMapping(value = "/api/disk/userShare/userList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String userList(UserDTO shareDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
PageResult re = null;
try {
re = shareService.getUserList(loginUser, shareDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "选择用户列表 error" + JsonUtils.beanToJson(shareDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@Resource
private ShareReportService shareReportService;
/**
* 对分享的举报
* 可以匿名举报
*/
@PostMapping("api/disk/share/report")
public Result shareReport(@RequestBody @Validated(CreateGroup.class) ShareReportDTO dto) {
shareReportService.shareReport(dto);
return Result.returnSuccess();
}
}

View File

@ -0,0 +1,888 @@
package com.svnlan.home.controller;
import com.svnlan.annotation.VisitRecord;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.domain.CommonSource;
import com.svnlan.home.dto.*;
import com.svnlan.home.dto.convert.ConvertDTO;
import com.svnlan.home.service.*;
import com.svnlan.home.utils.ConvertUtil;
import com.svnlan.home.utils.FileUtil;
import com.svnlan.home.utils.UserAuthTool;
import com.svnlan.home.vo.CommonSourceVO;
import com.svnlan.home.vo.IoSourceAuthVo;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.tools.SystemSortTool;
import com.svnlan.utils.*;
import com.svnlan.webdav.MimeTypeEnum;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/16 9:03
*/
@RestController
@CrossOrigin
public class UploadController {
@Resource
LoginUserUtil loginUserUtil;
@Resource
ConvertUtil convertUtil;
@Resource
private UploadService uploadService;
@Resource
SystemSortTool systemSortTool;
@Resource
StringRedisTemplate stringRedisTemplate;
@Resource
private UploadZipService uploadZipService;
@Resource
private FavService favService;
@Resource
AuthService authService;
@Resource
UserAuthTool userAuthTool;
@Resource
VideoGetService videoGetService;
@Value("${environment.type}")
private String environmentType;
@RequestMapping(value = "/api/disk/upload", method = RequestMethod.POST)
public String upload(@Valid UploadDTO uploadDTO) {
String uuid = RandomUtil.getuuid();
try {
String ip = IpUtil.getIp(HttpUtil.getRequest());
LogUtil.info("文件大小, " + uploadDTO.getFile().getSize() + ", ip," + ip + ", uuid" + uuid);
} catch (Exception e) {
LogUtil.error(e, "文件日志失败");
}
LoginUser loginUser = loginUserUtil.getLoginUser();
Result result;
if (ObjectUtils.isEmpty(loginUser)) {
result = new Result(false, CodeMessageEnum.bindSignError.getCode(), null);
return JsonUtils.beanToJson(result);
}
try {
CommonSource commonSource = new CommonSource();
String serverUrl = HttpUtil.getRequestRootUrl(null);
commonSource.setDomain(serverUrl);
CommonSourceVO commonSourceVO = null;
if (!ObjectUtils.isEmpty(uploadDTO.getPath()) && !"0".equals(uploadDTO.getPath())) {
// 编辑上传覆盖文件
commonSourceVO = uploadService.fileUpload(uploadDTO, loginUser, commonSource);
} else {
// 上传文件
commonSourceVO = uploadService.upload(uploadDTO, loginUser, commonSource);
}
if (!ObjectUtils.isEmpty(commonSourceVO.getPath())){
commonSourceVO.setPreviewPath(FileUtil.getShowImageUrl(commonSourceVO.getPath(), commonSourceVO.getName()));
}
result = new Result(commonSourceVO.getState().equals(1),
CodeMessageEnum.success.getCode(),
commonSourceVO);
// 异步合并则不转码转码放到异步执行
if (ObjectUtils.isEmpty(commonSource.getCheckMerge()) || !commonSource.getCheckMerge()) {
commonSource.setUserID(loginUser.getUserID());
// 试着转码
uploadService.tryToConvertFile(commonSourceVO, commonSource, uploadDTO.getBusType());
}
} catch (SvnlanRuntimeException e) {
LogUtil.error("上传: " + e.getMessage());
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
uploadDTO.setFile(null);
LogUtil.error(e, "上传失败, dto:" + JsonUtils.beanToJson(uploadDTO) + ", e:" + e.getMessage());
result = new Result(false, CodeMessageEnum.uploadError.getCode(), null);
} finally {
stringRedisTemplate.delete(systemSortTool.getUserSpaceKey(loginUser.getUserID()));
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
String resultStr = JsonUtils.beanToJson(result);
LogUtil.info("返回, " + resultStr + ", uuid" + uuid);
return resultStr;
}
/**
* @Description: 查看文件是否存在, 秒传
* @params: [checksum]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/upload/check", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Result check(@Valid CheckFileDTO checkFileDTO) {
String path = ObjectUtils.isEmpty(checkFileDTO.getPath()) ? "file" : checkFileDTO.getPath();
LoginUser loginUser = loginUserUtil.getLoginUser();
switch (path) {
case "file":
return this.checkFile(checkFileDTO, loginUser);
case "chunk":
return this.checkChunk(checkFileDTO, loginUser);
default:
return this.checkFile(checkFileDTO, loginUser);
}
}
public Result checkFile(CheckFileDTO checkFileDTO, LoginUser loginUser) {
Map<String, Object> resultMap = null;
try {
if (!ObjectUtils.isEmpty(checkFileDTO.getPath()) && !"0".equals(checkFileDTO.getPath())) {
// 编辑上传覆盖文件
resultMap = uploadService.checkFileReplace(checkFileDTO, loginUser);
} else {
resultMap = uploadService.checkFile(checkFileDTO, loginUser);
}
return new Result(true, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
return new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "秒传失败");
} finally {
stringRedisTemplate.delete(systemSortTool.getUserSpaceKey(loginUser.getUserID()));
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
return new Result(false, CodeMessageEnum.uploadError.getCode(), null);
}
public Result checkChunk(CheckFileDTO checkChunkDTO, LoginUser loginUser) {
try {
Map<String, Object> resultMap = uploadService.checkChunk(checkChunkDTO, loginUser);
return new Result(true, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
return new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
}
return new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
/**
* @Description: 预览
* @params: [response, previewAttachDTO]
* @Return: void
* @Author: sulijuan
* @Date: 2023/2/17 10:43
* @Modified:
*/
@VisitRecord(isAsync = true)
@RequestMapping(value = "/api/disk/preview", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String preview(HttpServletResponse response, CheckFileDTO checkFileDTO) {
if (ObjectUtils.isEmpty(checkFileDTO.getShareCode())) {
LoginUser loginUser = loginUserUtil.getLoginUser();
if (ObjectUtils.isEmpty(loginUser)) {
Result result = new Result(false, CodeMessageEnum.bindSignError.getCode(), null);
return JsonUtils.beanToJson(result);
}
checkFileDTO.setLoginUser(loginUser);
}
String path = ObjectUtils.isEmpty(checkFileDTO.getPath()) ? "info" : checkFileDTO.getPath();
switch (path) {
case "attachment":
this.previewAttach(response, checkFileDTO);
break;
case "info":
return this.getPreviewInfo(checkFileDTO);
case "edit":
return this.getPreviewEditInfo(checkFileDTO);
case "refresh":
return this.getPreviewRefreshInfo(checkFileDTO);
case "fileUrl":
return this.getPreviewFileUrl(checkFileDTO);
default:
this.previewAttach(response, checkFileDTO);
break;
}
return "";
}
/**
* @Description: 预览
* @params: [response, checkFileDTO]
* @Return: void
* @Author: sulijuan
* @Date: 2023/2/17 11:24
* @Modified:
*/
public void previewAttach(HttpServletResponse response, CheckFileDTO checkFileDTO) {
String resultStr = "";
try {
resultStr = uploadService.returnSource(checkFileDTO, null, response);
// response.sendRedirect(resultStr);
} catch (SvnlanRuntimeException e) {
resultStr = e.getMessage();
} catch (Exception e) {
LogUtil.error(e, "预览失败" + JsonUtils.beanToJson(checkFileDTO));
}
// return resultStr;
}
@RequestMapping(value = "/api/disk/preview/{fileName}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public void previewAttachWithName(HttpServletResponse response, CheckFileDTO previewAttachDTO, @PathVariable("fileName") String passedFileName) {
String resultStr = "";
try {
resultStr = uploadService.returnSource(previewAttachDTO, passedFileName, response);
// response.sendRedirect(resultStr);
} catch (SvnlanRuntimeException e) {
resultStr = e.getMessage();
} catch (Exception e) {
LogUtil.error(e, "预览失败" + JsonUtils.beanToJson(previewAttachDTO));
}
// return resultStr;
}
/**
* @Description: 预览信息
* @params: [getCloudPreviewDTO]
* @Return: java.lang.String
* @Modified:
*/
public String getPreviewInfo(CheckFileDTO checkFileDTO) {
Result result;
try {
Map<String, Object> re = uploadService.getPreviewInfo(checkFileDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "云盘获取预览信息失败");
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
public String getPreviewEditInfo(CheckFileDTO checkFileDTO) {
Result result;
try {
Map<String, Object> re = favService.getPreviewEditInfo(checkFileDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "云盘获取文档编辑链接信息失败");
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
public String getPreviewRefreshInfo(CheckFileDTO checkFileDTO) {
Result result;
try {
Map<String, Object> re = favService.getPreviewRefreshInfo(checkFileDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
LogUtil.error(e, "云盘获取文档预览信息");
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
public String getPreviewFileUrl(CheckFileDTO checkFileDTO) {
return favService.getPreviewFileUrl(checkFileDTO);
}
/**
* @Description: 文件操作
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@VisitRecord(isAsync = true)
@RequestMapping(value = "/api/disk/operation", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String copyFile(@Valid @RequestBody CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
boolean success = uploadService.updateFile(updateFileDTO, resultMap, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerOneRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
LogUtil.error(e, "operation操作失败updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, e.getErrorCode(), e.getMessage(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "云盘文件复制失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
} finally {
stringRedisTemplate.delete(systemSortTool.getUserSpaceKey(loginUser.getUserID()));
}
return JsonUtils.beanToJson(result);
}
/**
* 预览/下载
*/
@RequestMapping(value = "/api/disk/attachment/{fileName}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getAttachmentWithName(HttpServletResponse response, @Valid GetAttachmentDTO getAttachmentDTO,
@PathVariable("fileName") String passedFileName) {
String resultStr = "";
try {
if ("dev".equals(environmentType)){
getAttachmentDTO.setGetInfo(2);
}
Map<String, Object> resultMap = new HashMap<>();
resultStr = uploadService.getAttachment(response, getAttachmentDTO, passedFileName, resultMap);
LogUtil.info("resultStr=" + resultStr + "attachment" + JsonUtils.beanToJson(getAttachmentDTO) + "resultMap=" + JsonUtils.beanToJson(resultMap));
if (!StringUtil.isEmpty(resultStr) && resultStr.indexOf("http") == 0) {
//获取信息
if (getAttachmentDTO.getGetInfo() == 1) {
Result result = Result.returnSuccess(resultMap);
LogUtil.info("attachment true");
return JsonUtils.beanToJson(result);
}else {
response.sendRedirect(resultStr);
}
}else {
outFile(response,resultStr,passedFileName, true);
return "";
}
} catch (SvnlanRuntimeException e) {
resultStr = e.getMessage();
} catch (Exception e) {
LogUtil.error(e, "预览失败" + JsonUtils.beanToJson(getAttachmentDTO));
}
LogUtil.info("resultStr=" + resultStr + "attachment" + JsonUtils.beanToJson(getAttachmentDTO));
return resultStr;
}
/**
* 视频切图预览/下载
*/
@RequestMapping(value = "/api/disk/video/img/{fileName}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public void getVideoImgAttachmentWithName(HttpServletResponse response, HttpServletRequest request, @Valid VideoCommonDto videoCommonDto,
@PathVariable("fileName") String passedFileName) {
String resultStr = "";
boolean check = true;
try {
Map<String, Object> resultMap = new HashMap<>();
resultStr = videoGetService.getVideoShearImg(response, videoCommonDto, passedFileName, resultMap);
/*if (!StringUtil.isEmpty(resultStr) && resultStr.indexOf("http") == 0) {
check = true;
//获取信息
response.sendRedirect(resultStr);
}*/
} catch (SvnlanRuntimeException e) {
resultStr = e.getMessage();
check = false;
LogUtil.error(e, "getVideoImgAttachmentWithName 预览失败" + JsonUtils.beanToJson(videoCommonDto) + "resultStr=" + resultStr);
} catch (Exception e) {
check = false;
LogUtil.error(e, "getVideoImgAttachmentWithName 预览失败" + JsonUtils.beanToJson(videoCommonDto) + "resultStr=" + resultStr);
}
LogUtil.info(check + "-checkgetVideoImgAttachmentWithName resultStr=" + resultStr + "attachment" + JsonUtils.beanToJson(videoCommonDto));
boolean isDown = false;
if (!ObjectUtils.isEmpty(videoCommonDto.getIsDown()) && "1".equals(videoCommonDto.getIsDown())){
isDown = true;
}
String ext = resultStr.substring(resultStr.lastIndexOf(".") + 1);
if ("mp4".equals(ext)){
outMp4File(resultStr, request, response,passedFileName);
return;
}
if (check){
outFile(response,resultStr,passedFileName, isDown);
}
}
private void outFile(HttpServletResponse response, String resultStr, String passedFileName, boolean isDown){
File file = new File(resultStr);
if (!file.exists()) {
LogUtil.error("outFile 该资源不存在或不可预览");
return;
}
// 获取文件后缀
String ext = resultStr.substring(resultStr.lastIndexOf(".") + 1);
try (FileInputStream fis = new FileInputStream(file); ServletOutputStream sos = response.getOutputStream()) {
String mineType = MimeTypeEnum.getContentType(ext);
response.setContentType(mineType);
if (isDown) {
response.setHeader("Content-Disposition", "attachment;filename="
// 解决中文名称乱码的问题
+ new String(passedFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
}
IOUtils.copy(fis, sos);
sos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
LogUtil.error("outFile 拷贝文件流出错 resultStr=" + resultStr);
}
}
//path为本地文件路劲
public void outMp4File(String path, HttpServletRequest request, HttpServletResponse response, String passedFileName) {
LogUtil.info("outMp4File path=" + path);
RandomAccessFile targetFile = null;
OutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
response.reset();
//获取请求头中Range的值
String rangeString = request.getHeader(HttpHeaders.RANGE);
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
response.setHeader(HttpHeaders.CONTENT_TYPE, "video/mp4");
//打开文件
File file = new File(path);
if (file.exists()) {
//使用RandomAccessFile读取文件
targetFile = new RandomAccessFile(file, "r");
long fileLength = targetFile.length();
long requestSize = (int) fileLength;
//分段下载视频
if (StringUtils.hasText(rangeString)) {
//从Range中提取需要获取数据的开始和结束位置
long requestStart = 0, requestEnd = 0;
String[] ranges = rangeString.split("=");
if (ranges.length > 1) {
String[] rangeDatas = ranges[1].split("-");
requestStart = Integer.parseInt(rangeDatas[0]);
if (rangeDatas.length > 1) {
requestEnd = Integer.parseInt(rangeDatas[1]);
}
}
if (requestEnd != 0 && requestEnd > requestStart) {
requestSize = requestEnd - requestStart + 1;
}
//根据协议设置请求头
if (!StringUtils.hasText(rangeString)) {
response.setHeader(HttpHeaders.CONTENT_LENGTH, fileLength + "");
} else {
long length;
if (requestEnd > 0) {
length = requestEnd - requestStart + 1;
response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + requestEnd + "/" + fileLength);
} else {
length = fileLength - requestStart;
response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + (fileLength - 1) + "/"
+ fileLength);
}
}
//断点传输下载视频返回206
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
//设置targetFile从自定义位置开始读取数据
targetFile.seek(requestStart);
} else {
//如果Range为空则下载整个视频
//response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + passedFileName);
//设置文件长度
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileLength));
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + 0 + "-" + (fileLength - 1) + "/"
+ fileLength);
}
//从磁盘读取数据流返回
byte[] cache = new byte[4096];
try {
while (requestSize > 0) {
int len = targetFile.read(cache);
if (requestSize < cache.length) {
outputStream.write(cache, 0, (int) requestSize);
} else {
outputStream.write(cache, 0, len);
if (len < cache.length) {
break;
}
}
requestSize -= cache.length;
}
} catch (IOException e) {
// tomcat原话写操作IO异常几乎总是由于客户端主动关闭连接导致所以直接吃掉异常打日志
//比如使用video播放视频时经常会发送Range为0- 的范围只是为了获取视频大小之后就中断连接了
LogUtil.error(e, "play error");
}
} else {
throw new RuntimeException("文件路劲有误");
}
outputStream.flush();
} catch (Exception e) {
LogUtil.error(e,"文件传输错误");
throw new RuntimeException("文件传输错误");
}finally {
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
LogUtil.error(e,"流释放错误");
}
}
if(targetFile != null){
try {
targetFile.close();
} catch (IOException e) {
LogUtil.error(e,"文件流释放错误");
}
}
}
}
/**
* @Description: txt 写入文件
* @params: [uploadDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/1 13:29
* @Modified:
*/
@RequestMapping(value = "/api/disk/fileSave", method = RequestMethod.POST)
public String fileSave(@RequestBody SaveUploadDTO uploadDTO) {
String uuid = RandomUtil.getuuid();
LoginUser loginUser = loginUserUtil.getLoginUser();
Result result;
try {
if (ObjectUtils.isEmpty(uploadDTO.getTaskID())) {
uploadDTO.setTaskID(RandomUtil.getuuid());
}
CommonSource commonSourceVO = uploadService.fileSave(uploadDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), commonSourceVO);
} catch (SvnlanRuntimeException e) {
LogUtil.error("上传fileSave: " + e.getMessage());
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e) {
uploadDTO.setFile(null);
LogUtil.error(e, "上传失败fileSave, dto:" + JsonUtils.beanToJson(uploadDTO) + ", e:" + e.getMessage());
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}finally {
stringRedisTemplate.delete(systemSortTool.getUserSpaceKey(loginUser.getUserID()));
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
String resultStr = JsonUtils.beanToJson(result);
LogUtil.info("返回, " + resultStr + ", uuid" + uuid);
return resultStr;
}
/**
* @Description: 收藏夹置顶
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/fav/moveTop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String moveTop(@Valid @RequestBody CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
boolean success = favService.moveTop(updateFileDTO, resultMap, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "收藏夹置顶失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 收藏夹置底
* @params: [updateFileDTO]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/fav/moveBottom", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String moveBottom(@Valid @RequestBody CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
// 校验标签权限
userAuthTool.checkUserTagPermission(loginUser);
boolean success = favService.moveBottom(updateFileDTO, resultMap, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "收藏夹置底失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
return JsonUtils.beanToJson(result);
}
/**
* zip 压缩
*/
@VisitRecord(isAsync = true)
@RequestMapping(value = "/api/disk/zip", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String zip(@RequestBody CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
boolean success = uploadZipService.zipFile(updateFileDTO, resultMap, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
if (!ObjectUtils.isEmpty(loginUser)){
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), e.getMessage(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "压缩zip失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/zip/taskAction", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String zipTaskAction(HttpServletResponse response, CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
boolean success = true;
try {
success = uploadZipService.taskAction(updateFileDTO, resultMap);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "taskAction压缩zip失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
if (!ObjectUtils.isEmpty(updateFileDTO.getOperation()) && "down".equals(updateFileDTO.getOperation())) {
if (!ObjectUtils.isEmpty(resultMap) && resultMap.containsKey("finalFilePath")) {
String cdnPath = systemSortTool.getCdnPath(resultMap.get("finalFilePath").toString(), resultMap.get("fileName").toString());
LogUtil.info("taskAction *** resultMap=" + JsonUtils.beanToJson(resultMap));
//获取信息
if (!ObjectUtils.isEmpty(updateFileDTO.getGetInfo()) && updateFileDTO.getGetInfo() == 1) {
resultMap.put("cdnPath", cdnPath);
result = Result.returnSuccess(resultMap);
return JsonUtils.beanToJson(result);
} else {
resultMap.put("downloadUrl", cdnPath);
result = Result.returnSuccess(resultMap);
/*try {
response.sendRedirect(cdnPath);
}catch (Exception e){
LogUtil.error(e, "taskAction zip 下载失败");
}*/
}
}
}else {
if (!ObjectUtils.isEmpty(resultMap) && resultMap.containsKey("status") && "1".equals(resultMap.get("status").toString())
&& !ObjectUtils.isEmpty(loginUser)) {
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 解压
* @params: [sourceID]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/3/24 14:16
* @Modified:
*/
@VisitRecord(isAsync = true)
@RequestMapping(value = "/api/disk/unZip", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String unZip(@RequestBody CheckFileDTO checkFileDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
List<CommonSource> list = null;
try {
if (ObjectUtils.isEmpty(checkFileDTO.getTaskID())){
checkFileDTO.setTaskID(RandomUtil.getuuid());
}
list = uploadZipService.unZip(checkFileDTO, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), checkFileDTO);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), e.getMessage(), checkFileDTO);
} catch (Exception e) {
LogUtil.error(e, "解压失败 checkFileDTO=" + checkFileDTO);
result = new Result(false, CodeMessageEnum.system_error.getCode(), checkFileDTO);
}
// 视频转码
if (!CollectionUtils.isEmpty(list)) {
for (CommonSource source : list) {
ConvertDTO convertDTO = new ConvertDTO();
convertDTO.setBusId(source.getSourceID());
convertDTO.setBusType("cloud");
convertDTO.setOtherType("unZip");
String serverUrl = HttpUtil.getRequestRootUrl(null);
source.setDomain(serverUrl);
convertDTO.setDomain(serverUrl);
convertUtil.doConvert(convertDTO, source);
}
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/unZip/taskAction", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String unZipTaskAction(HttpServletResponse response, CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
boolean success = true;
try {
success = uploadZipService.taskActionUnZip(updateFileDTO, resultMap, loginUser);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "解压 taskAction失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
if (!ObjectUtils.isEmpty(resultMap) && resultMap.containsKey("status") && "1".equals(resultMap.get("status").toString())) {
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 设置文档权限
* @params: [checkFileDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/4/11 17:16
* @Modified:
*/
@RequestMapping(value = "/api/disk/setAuth", method = RequestMethod.POST)
public String setAuth(@RequestBody CheckFileDTO checkFileDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
authService.setAuth(checkFileDTO, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), checkFileDTO);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), e.getMessage(), checkFileDTO);
} catch (Exception e) {
LogUtil.error(e, "设置文档权限 checkFileDTO=" + checkFileDTO);
result = new Result(false, CodeMessageEnum.system_error.getCode(), checkFileDTO);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 获取文档权限
* @params: [checkFileDTO]
* @Return: java.lang.String
* @Author: sulijuan
* @Modified:
*/
@GetMapping(value = "/api/disk/getSourceAuth")
public String getSourceAuth(CheckFileDTO checkFileDTO) {
Result result;
LoginUser loginUser = loginUserUtil.getLoginUser();
try {
List<IoSourceAuthVo> list = authService.getSourceAuth(checkFileDTO, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), list);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), checkFileDTO);
} catch (Exception e) {
LogUtil.error(e, "获取文档权限 checkFileDTO=" + checkFileDTO);
result = new Result(false, CodeMessageEnum.system_error.getCode(), checkFileDTO);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/preview/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getPreview(HttpServletResponse response, CheckFileDTO checkFileDTO) {
Map<String, Object> re = null;
Result result;
try {
re = uploadService.getFileContent(checkFileDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), checkFileDTO);
} catch (Exception e) {
LogUtil.error(e, "/api/disk/preview/get checkFileDTO=" + checkFileDTO);
result = new Result(false, CodeMessageEnum.system_error.getCode(), checkFileDTO);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/preview/blob", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getPreviewBlob(HttpServletResponse response, CheckFileDTO checkFileDTO) {
Map<String, Object> re = null;
Result result;
try {
re = uploadService.getFileContentBlob(checkFileDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), checkFileDTO);
} catch (Exception e) {
LogUtil.error(e, "/api/disk/preview/blob checkFileDTO=" + checkFileDTO);
result = new Result(false, CodeMessageEnum.system_error.getCode(), checkFileDTO);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/preview/byte", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String getPreviewByte(HttpServletResponse response, CheckFileDTO checkFileDTO) {
Map<String, Object> re = null;
Result result;
try {
re = uploadService.getFileContentByte(checkFileDTO);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), checkFileDTO);
} catch (Exception e) {
LogUtil.error(e, "/api/disk/preview/byte checkFileDTO=" + checkFileDTO);
result = new Result(false, CodeMessageEnum.system_error.getCode(), checkFileDTO);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,375 @@
package com.svnlan.home.controller;
import com.svnlan.common.GlobalConfig;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.exception.SvnlanRuntimeException;
import com.svnlan.home.domain.CommonSource;
import com.svnlan.home.dto.CheckFileDTO;
import com.svnlan.home.dto.VideoCommonDto;
import com.svnlan.home.dto.convert.ConvertDTO;
import com.svnlan.home.service.VideoGetService;
import com.svnlan.home.service.VideoImagesService;
import com.svnlan.home.utils.ConvertUtil;
import com.svnlan.home.utils.ObjUtil;
import com.svnlan.jwt.domain.LoginUser;
import com.svnlan.utils.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @Author: sulijuan
* @Description: 视频剪辑
* @Date: 2023/5/17 11:27
*/
@RestController
public class VideoGetController {
@Resource
VideoGetService videoGetService;
@Resource
LoginUserUtil loginUserUtil;
@Resource
ConvertUtil convertUtil;
@Resource
StringRedisTemplate stringRedisTemplate;
@Resource
VideoImagesService videoImagesService;
/**
* @Description: 根据帧数获取图片
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/imgList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoList(VideoCommonDto videoCommonDto){
Result result;
List re = null;
try {
re = videoGetService.getVideoShearListAll(videoCommonDto);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "获取视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/video/checkImgCut", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String checkImgCut(VideoCommonDto videoCommonDto){
Result result;
boolean re = false;
try {
re = videoGetService.checkImgCut(videoCommonDto);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "获取视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频剪切
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/cut", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoCut(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/cut videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.cutVideo(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "cut剪切视频失败 " + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频剪切
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Author: sulijuan
* @Date: 2023/5/18 16:56
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/cutSave", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoCutSave(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/cutSave videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.cutVideoSave(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
if (re.containsKey("convertList")){
List<CommonSource> list = ObjUtil.objectToList(re.get("convertList"), CommonSource.class);
// 视频转码
if (!CollectionUtils.isEmpty(list)){
for (CommonSource source : list){
ConvertDTO convertDTO = new ConvertDTO();
convertDTO.setBusId(source.getSourceID());
convertDTO.setBusType("cloud");
convertDTO.setOtherType("cutVideo");
String serverUrl = HttpUtil.getRequestRootUrl(null);
source.setDomain(serverUrl);
convertDTO.setDomain(serverUrl);
convertUtil.doConvert(convertDTO, source);
}
}
re.put("convertList", null);
}
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "cutSave剪切视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频拆分
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/splitSave", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoSplitSave(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/cutSave videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.splitVideoSave(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
if (re.containsKey("convertList")){
List<CommonSource> list = ObjUtil.objectToList(re.get("convertList"), CommonSource.class);
// 视频转码
if (!CollectionUtils.isEmpty(list)){
String serverUrl = HttpUtil.getRequestRootUrl(null);
for (CommonSource source : list){
ConvertDTO convertDTO = new ConvertDTO();
convertDTO.setBusId(source.getSourceID());
convertDTO.setBusType("cloud");
convertDTO.setOtherType("splitVideo");
source.setDomain(serverUrl);
convertDTO.setDomain(serverUrl);
convertUtil.doConvert(convertDTO, source);
}
}
re.put("convertList", null);
}
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "splitSave拆分视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频合并
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/mergeSave", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoMergeSave(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/videoMergeSave videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.mergeVideoSave(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "videoMergeSave合并视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频转码
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/convertSave", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoConvertSave(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/videoConvertSave videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.convertVideoSave(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "videoConvertSave转码视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频设置
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/setting", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoConfigSave(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/videoConfigSave videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.videoConfigSave(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "videoConvertSave转码视频失败" + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频剪切-照相
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/cutImg", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoCutImg(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/cutImg videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.cutVideoImg(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "cut剪切视频失败 " + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 视频剪切-抽取音频
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/copyAudio", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String videoCopyAudio(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/copyAudio videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoGetService.copyAudio(videoCommonDto, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "cut剪切视频失败 " + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
/**
* @Description: 图片转视频
* @params: [videoCommonDto]
* @Return: java.lang.String
* @Modified:
*/
@RequestMapping(value = "/api/disk/video/imagesToVideo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String imagesToVideo(@RequestBody VideoCommonDto videoCommonDto){
Result result;
Map<String, Object> re = null;
try {
if (ObjectUtils.isEmpty(videoCommonDto.getTaskID())){
videoCommonDto.setTaskID(RandomUtil.getuuid());
}
LoginUser loginUser = loginUserUtil.getLoginUser();
LogUtil.info("/api/disk/video/imagesToVideo videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto));
re = videoImagesService.imagesToVideo(videoCommonDto, loginUser);
result = new Result(true, CodeMessageEnum.success.getCode(), re);
} catch (SvnlanRuntimeException e){
result = new Result(false, e.getErrorCode(), null);
} catch (Exception e){
LogUtil.error(e, "imagesToVideo " + JsonUtils.beanToJson(videoCommonDto));
result = new Result(false, CodeMessageEnum.system_error.getCode(), null);
}
return JsonUtils.beanToJson(result);
}
@RequestMapping(value = "/api/disk/video/imagesToVideo/taskAction", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String imagesToVideoTaskAction(HttpServletResponse response, CheckFileDTO updateFileDTO) {
Result result;
Map<String, Object> resultMap = new HashMap<>(1);
LoginUser loginUser = loginUserUtil.getLoginUser();
boolean success = true;
try {
success = videoImagesService.taskAction(updateFileDTO, resultMap, loginUser);
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
result = new Result(success, CodeMessageEnum.success.getCode(), resultMap);
} catch (SvnlanRuntimeException e) {
result = new Result(false, e.getErrorCode(), resultMap);
} catch (Exception e) {
LogUtil.error(e, "imagesToVideo taskAction 失败" + JsonUtils.beanToJson(updateFileDTO));
result = new Result(false, CodeMessageEnum.system_error.getCode(), resultMap);
}
if (!ObjectUtils.isEmpty(resultMap) && resultMap.containsKey("status") && "1".equals(resultMap.get("status").toString())) {
stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS);
}
return JsonUtils.beanToJson(result);
}
}

View File

@ -0,0 +1,36 @@
package com.svnlan.home.controller;
import com.svnlan.common.Result;
import com.svnlan.exception.CodeMessageEnum;
import com.svnlan.home.dto.YzOfficDto;
import com.svnlan.home.service.YzService;
import com.svnlan.utils.JsonUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/4/7 13:37
*/
@RestController
public class YzCallbackController {
@Resource
YzService yzService;
@PostMapping(value = "/api/disk/yzwo/office", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String YzCallback(YzOfficDto officDto, MultipartFile file) {
yzService.yzCallback(officDto, file);
Result re = new Result(true, CodeMessageEnum.success.getCode(), true);
return JsonUtils.beanToJson(re);
}
}

View File

@ -0,0 +1,23 @@
package com.svnlan.home.dao;
import com.svnlan.home.domain.Comment;
import com.svnlan.home.vo.CommentVo;
import java.util.List;
import java.util.Map;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/8/1 14:20
*/
public interface CommentDao {
int insert(Comment comment);
int setCommentCount(Comment comment);
int deleteComment(Long commentID);
List<CommentVo> getCommentList(Map<String, Object> map);
long getCountComment(Map<String, Object> map);
Integer checkCommentExist(Long commentID);
CommentVo getTargetIdByCommentId(Long commentID);
}

View File

@ -0,0 +1,28 @@
package com.svnlan.home.dao;
import com.svnlan.home.domain.CommonLabel;
import com.svnlan.home.vo.CommonLabelVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 17:22
*/
public interface CommonLabelDao {
int insert(CommonLabel commonLabel);
int update(CommonLabel commonLabel);
int deleteTag(Long labelId);
int updateStatus(CommonLabel commonLabel);
List<CommonLabelVo> getUserLabelList(Long userID);
List<CommonLabelVo> getInfoLabelList(Long userID);
Integer getMaxSort(@Param("userID") Long userID, @Param("tagType") Integer tagType);
int updateSort(@Param("labelId") Long labelId, @Param("sort") Integer sort);
List<Long> checkLabelNameRepeat(@Param("labelName") String labelName, @Param("userID") Long userID, @Param("tagType") Integer tagType);
}

View File

@ -0,0 +1,42 @@
package com.svnlan.home.dao;
import com.svnlan.home.domain.CommonSchedule;
import org.apache.ibatis.annotations.Param;
/**
* 功能描述:
*
* @author:
* @date:
*/
public interface CommonScheduleDao {
int insert(CommonSchedule record);
int insertSelective(CommonSchedule record);
CommonSchedule selectByPrimaryKey(String commonScheduleId);
int updateByPrimaryKeySelective(CommonSchedule record);
int updateByPrimaryKey(CommonSchedule record);
int updateOperateTime(String commonScheduleId);
int getCountById(@Param("commonScheduleId") String commonScheduleId, @Param("gmtModified") String gmtModified);
/**
* @Description:验证定时任务是不是当天执行了
* @params: [commonScheduleId, gmtModified]
* @Return: int
* @Modified:
*/
int getCountByDay(@Param("commonScheduleId") String commonScheduleId, @Param("gmtModified") String gmtModified);
/**
* @description: 由日志ID得对应定时任务信息
* @param logScheduleId
*/
CommonSchedule findCommonScheduleByLogScheduleId(Long logScheduleId);
}

View File

@ -0,0 +1,24 @@
package com.svnlan.home.dao;
import com.svnlan.home.domain.IOSource;
import com.svnlan.home.vo.HomeExplorerShareDetailVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @author KingMgg
* @data 2023/2/7 16:13
*/
public interface ExplorerOperationsDao {
List<HomeExplorerShareDetailVO> getAllSourceList(Map<String, Object> paramMap);
int batchUpdateLevel(List<HomeExplorerShareDetailVO> list);
List<IOSource> getSourceListByLevelToContSize(@Param("parentLevel") String parentLevel, @Param("status") Integer status);
int batchUpdateSizeByCountSize(List<IOSource> list);
}

View File

@ -0,0 +1,77 @@
package com.svnlan.home.dao;
import com.svnlan.home.domain.IOSource;
import com.svnlan.home.dto.AddSubCloudDirectoryDTO;
import com.svnlan.home.vo.HomeExplorerVO;
import com.svnlan.home.vo.HomeFileDetailVO;
import com.svnlan.user.vo.GroupSizeVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @author KingMgg
* @data 2023/2/6 11:51
*/
public interface HomeExplorerDao {
/**
* 分类列表下面的子分类列表 根据参数判断 文件 文件夹
*
* @return
*/
List<HomeExplorerVO> getHomeExplorer(Map<String, Object> paramMap);
Long getCountHomeExplorer(Map<String, Object> paramMap);
/** 收藏夹*/
List<HomeExplorerVO> getUserFavExplorer(Map<String, Object> paramMap);
/** 回收站*/
List<HomeExplorerVO> getUserRecycleExplorer(Map<String, Object> paramMap);
/** 最近文档*/
List<HomeExplorerVO> getUserRencentExplorer(Map<String, Object> paramMap);
/**
* 创建文件夹
*
* @return
*/
int createDir(IOSource source);
int createDirectory(AddSubCloudDirectoryDTO source);
/**
* 获取文件详情
*
* @param fileID
* @return
*/
HomeFileDetailVO getFileDetail(Long fileID);
HomeExplorerVO getHomeSpace(@Param("targetID") Long targetID, @Param("parentID") Long parentID);
HomeExplorerVO getEnterpriseSpace();
List<HomeExplorerVO> getUserSpace(@Param("userID") Long userID, @Param("groupID") Long groupID);
List<HomeExplorerVO> getSourceChileCont(List<Long> list);
/**
* 修改云盘空间使用大小
*
* @param paramMap
* @return
*/
void updateMemory(Map<String, Object> paramMap);
int updateMemoryList(Map<String, Object> paramMap);
void updateUserMemory(Map<String, Object> paramMap);
void updateSubtractUseUserMemory(Map<String, Object> paramMap);
int batchUpdateGroupMemoryList(@Param("list") List<GroupSizeVo> list);
HomeExplorerVO getOneSourceInfo(Long sourceID);
List<HomeExplorerVO> getUserGroupSourceList(Long userID);
List<HomeExplorerVO> getSystemGroupSourceList();
Integer getUserIdentityInfo(Long userID);
String getParentName(Long sourceID);
List<HomeExplorerVO> getParentNameList(@Param("list") List<Long> list);
Integer checkUserRecycleExplorer(Long userID);
String getGroupParentLevel(Long groupID);
List<String> getGroupParentLevelList(@Param("list") List<Long> list);
List<HomeExplorerVO> getImgAndAudioHomeExplorer(@Param("list") List<Long> list, @Param("lnkAudio") Integer lnkAudio);
List<HomeExplorerVO> getFolderAndImgAndAudioHomeExplorer(@Param("list") List<Long> list, @Param("lnkAudio") Integer lnkAudio);
List<HomeExplorerVO> getImgByFolderList(Map<String, Object> paramMap);
}

View File

@ -0,0 +1,70 @@
package com.svnlan.home.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.svnlan.home.domain.CommonSource;
import com.svnlan.home.domain.IOFile;
import com.svnlan.home.domain.IOFileMeta;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
import java.util.Map;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/16 13:57
*/
public interface IoFileDao extends BaseMapper<IOFile> {
CommonSource getFileAttachment(Long sourceID);
int insert(IOFile ioFile);
int batchInsert(List<IOFile> list);
int insertMeta(IOFileMeta ioFile);
int batchInsertMeta(List<IOFileMeta> list);
List<Long> getSameSourceEmptyInfo(@Param("hashMd5") String hashMd5, @Param("size") Long size);
int updateVideoConvert(CommonSource commonSource);
int updateSameFile(@Param("commonSource") CommonSource commonSource, @Param("list") List<Long> list);
int updateDocConvert(CommonSource commonSource);
List<Long> getSameSourceEmptyInfoDoc(@Param("hashMd5") String hashMd5, @Param("size") Long size);
int updateSameFileSwf(@Param("map") Map<String, Object> updateMap, @Param("list") List<Long> list);
void updateSameFileDoc(@Param("map") Map<String, Object> docPath, @Param("list") List<Long> list);
CommonSource selectByChecksum(@Param("hashMd5") String hashMd5, @Param("size") Long size);
CommonSource selectByChecksumAndTime(@Param("hashMd5") String hashMd5, @Param("size") Long size, @Param("time") Long time);
int removeUserFile(List<Long> list);
int removeUserFileMeta(List<Long> list);
int removeUserFileContents(List<Long> list);
String getFileUrlValue(Long fileID);
List<IOFileMeta> getFileUrlValueList(List<Long> list);
int updateFileUrlValue(List<IOFileMeta> list);
int updateOneFileUrlValue(@Param("fileID") Long fileID, @Param("value") String value);
int updateAudioConvert(CommonSource commonSource);
int updateCameraConvert(CommonSource commonSource);
IOFileMeta getFileValue(Long sourceID);
CommonSource findCommonSourceById(Long sourceID);
int deleteFileOrgPath(Long fileID);
CommonSource getHistoryFileAttachment(@Param("id") Long id);
@Select("SELECT `name`, `path`, size, modifyTime, createTime FROM io_file WHERE fileID = #{id} AND isExistFile = 1")
IOFile getFileByFieldId(@Param("id") Long fileID);
int updateFileMd5ByPath(@Param("hashMd5") String hashMd5, @Param("path") String path);
CommonSource getHistoryFileAttachmentUrl(@Param("id") Long id);
CommonSource getFileAttachmentUrl(Long sourceID);
int updateFileMd5AndSizeByFileID(@Param("hashMd5") String hashMd5, @Param("fileID") Long fileID, @Param("size") Long size);
int updateVideoFilePath(@Param("fileID") Long fileID, @Param("path") String path);
int updateH264Info(CommonSource commonSource);
@Select("SELECT SUM(size) FROM io_file WHERE path like CONCAT(#{location},'%')")
Long selectStorageUsage(String location);
@Update("UPDATE io_file SET size = #{size} WHERE fileID = #{fileID}")
void updateFileSize(@Param("fileID") Long fileID, @Param("size") long size);
}

View File

@ -0,0 +1,22 @@
package com.svnlan.home.dao;
import com.svnlan.home.domain.IoSourceAuth;
import com.svnlan.home.vo.IoSourceAuthVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/4/11 17:21
*/
public interface IoSourceAuthDao {
int insert(IoSourceAuth ioSourceEvent);
int batchInsert(List<IoSourceAuth> list);
int deleteSourceAuth(Long sourceID);
List<IoSourceAuthVo> getSourceAuthBySourceID(Long sourceID);
List<IoSourceAuthVo> getGroupNameListByGID(List<Long> list);
List<IoSourceAuthVo> getSourceAuthBySourceIDList(@Param("list") List<Long> list, @Param("targetID") Long targetID);
}

View File

@ -0,0 +1,142 @@
package com.svnlan.home.dao;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.svnlan.home.domain.CommonSource;
import com.svnlan.home.domain.IOFile;
import com.svnlan.home.domain.IOSource;
import com.svnlan.home.dto.SourceOpDto;
import com.svnlan.home.vo.IOSourceVo;
import com.svnlan.home.vo.ParentPathDisplayVo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 11:13
*/
public interface IoSourceDao extends BaseMapper<IOSource> {
int insert(IOSource source);
int batchInsert(List<IOSource> list);
CommonSource getSourceInfo(Long sourceID);
List<CommonSource> getSourceInfoList(List<Long> list);
List<IOSource> copySourceList(List<Long> list);
List<IOSource> copySourceListByLevel(List<String> list);
int deleteDirOrFile(List<Long> list);
int deleteSourceByParent(List<String> list);
int restoreSourceByParent(@Param("list") List<String> list, @Param("userID") Long userID);
int batchFileRename(@Param("list") List<SourceOpDto> list, @Param("userID") Long userID);
int batchUpdateParent(List<IOSource> list);
int restoreDirOrFile(@Param("list") List<Long> list, @Param("userID") Long userID);
int removeUserSource(List<Long> list);
int removeUserSourceByParent(List<String> list);
List<Long> getFileIDBySourceID(List<Long> list);
List<IOSourceVo> getFileCountBySourceID(List<Long> list);
int updateSourceMemoryList(@Param("list") List<Long> list, @Param("memory") Long memory);
int subtractSourceMemoryList(@Param("list") List<Long> list, @Param("memory") Long memory);
int batchUpdateSourceMemoryList(@Param("list") List<IOSource> list);
int batchSubtractSourceMemoryList(@Param("list") List<IOSource> list);
Integer getMaxSort(Long parentID);
int updateSort(@Param("sourceID") Long sourceID, @Param("sort") Integer sort);
int updateSourceInfo(IOSource source);
List<IOSourceVo> copySourcePathList(List<Long> list);
List<IOSourceVo> copySourcePathListByLevel(List<String> list);
List<CommonSource> getSourceFileInfoList(List<Long> list);
int updateSourceModifyUser(IOSource source);
int updateFileSize(IOSource source);
List<String> getSourceNameList(Long sourceID);
List<CommonSource> checkSourceNameList(Long sourceID);
List<JSONObject> fileCount();
@Select("SELECT COUNT(sourceID) count, `type` FROM io_source WHERE isFolder = 0 AND `type` IS NOT NULL GROUP BY `type`")
List<JSONObject> getFileTypeProportion();
List<IOSourceVo> getFileCountByPath(List<String> list);
@Select("SELECT name FROM io_source WHERE sourceID = #{id}")
IOSource getSourceNameBySourceId(@Param("id") Long sourceID);
List<JSONObject> getUserDirectoryAndFile(@Param("userId") Long userId, @Param("parentId") Long parentId);
@Select("SELECT sourceID, isFolder, `name`, parentID, parentLevel, fileID, modifyTime, createTime FROM io_source WHERE targetID = #{userId} AND isDelete = 0 AND parentID = #{parentId}")
List<IOSourceVo> getSourceInfoByParentIdAndUser(@Param("parentId") Long id, @Param("userId") long userId);
@Select("SELECT `name`, sourceID, parentLevel, modifyTime, createTime, targetType, targetID,parentID, isFolder, storageID from io_source where targetID = #{userId} AND parentID = 0 AND isFolder = 1 AND targetType = 1 AND isDelete = 0")
IOSourceVo getUserRootDirectory(@Param("userId") Long userId);
@Select("SELECT sourceID, parentLevel FROM io_source WHERE targetID = #{userId} AND `name` = #{lastPathName} AND isFolder = #{isFolder} and isDelete = 0")
List<IOSourceVo> getSourceByNameAndUserId(@Param("lastPathName") String lastPathName, @Param("userId") Long userId, @Param("isFolder") Integer isFolder);
@Select("SELECT COUNT(sourceID) count, `type` FROM io_source WHERE createUser = #{userId} and isFolder = 0 AND `type` IS NOT NULL GROUP BY `type`")
List<JSONObject> getFileTypeProportionByUserId(@Param("userId") Long userId);
int batchUpdateParentAndName(List<IOSource> list);
IOFile getFileContentByNameAndUserId(@Param("fileName") String fileName, @Param("userId") Long userId, @Param("isVideoFile") Boolean isVideoFile);
@Select("SELECT name FROM io_source WHERE isFolder = 1 AND `name` LIKE CONCAT(#{lastPath}, '%') AND parentLevel = #{parentLevel} AND isDelete = 0")
List<String> getDirectoryByParentLevelAndName(String parentLevel, String lastPath);
@Select("SELECT sourceID,parentLevel,isFolder, modifyTime, createTime, `size`, fileID, `name`, targetType, targetID, parentID, storageID FROM io_source WHERE targetID = #{userId} AND parentLevel = #{parentLevel} AND name = #{name} AND isDelete = 0")
IOSourceVo querySourceVoByParentLevelAndUserIdAndName(@Param("parentLevel") String parentLevel, @Param("userId") Long userId, @Param("name") String name);
List<ParentPathDisplayVo> getParentPathDisplay(List<String> list);
String getSourceName(Long sourceID);
int updateSourceAddSizeInfo(IOSource source);
int updateSourceConvertSize(@Param("sourceID") Long sourceID, @Param("convertSize") Long convertSize);
int updateSourceThumbSize(@Param("sourceID") Long sourceID, @Param("thumbSize") Long thumbSize);
List<IOSourceVo> getDesktopSourceList(@Param("parentID") Long parentID, @Param("name") String name);
Long getSourceSize(@Param("sourceID") Long sourceID);
int updateSourceSize(@Param("sourceID") Long sourceID, @Param("size") Long size);
@Select("SELECT fileType ft, COUNT(sourceID) c, SUM(size) s FROM io_source WHERE isFolder = 0 AND targetType = 1 GROUP BY fileType")
List<JSONObject> selectFileProportion();
@Select("SELECT targetType ty, SUM(size) s FROM io_source WHERE isFolder = 0 GROUP BY targetType")
List<JSONObject> getTargetTypeProportion();
List<ParentPathDisplayVo> getParentPathDisplayByIds(List<Long> list);
int updateSourceDesc(@Param("sourceID") Long sourceID, @Param("description") String description);
}

View File

@ -0,0 +1,27 @@
package com.svnlan.home.dao;
import com.alibaba.fastjson.JSONObject;
import com.svnlan.home.domain.IoSourceEvent;
import com.svnlan.home.vo.IoSourceEventVo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.data.util.Pair;
import java.util.List;
/**
* @Author: sulijuan
* @Description:
* @Date: 2023/2/14 11:16
*/
public interface IoSourceEventDao {
int insert(IoSourceEvent ioSourceEvent);
int batchInsert(List<IoSourceEvent> list);
List<IoSourceEventVo> getSourceEventBySourceID(@Param("sourceID") Long sourceID, @Param("isFolder") int isFolder);
@Select("SELECT DATE(FROM_UNIXTIME(createTime)) `date`, COUNT(1) count from io_source_event WHERE createTime >= #{timeRange.first} AND createTime <= #{timeRange.second} GROUP BY `date` ORDER BY `date`")
List<JSONObject> queryFileOperateCount(@Param("timeRange") Pair<Long, Long> timeRange);
List<JSONObject> queryVideoFileOperateCount(@Param("timeRange") Pair<Long, Long> timeRange);
}

Some files were not shown because too many files have changed in this diff Show More