commit
This commit is contained in:
parent
1a8f8e804c
commit
a1f742e015
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal 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
4
Dockerfile
Normal 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
339
LICENSE
Normal 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
301
db/ddl.sql
Normal 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
35
harbor
Normal 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
52
java-disk-deployment.yaml
Normal 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
|
BIN
lib/aspose-pdf-23.4-crack.jar
Normal file
BIN
lib/aspose-pdf-23.4-crack.jar
Normal file
Binary file not shown.
BIN
lib/webdav-server-6.2.9090-Beta.jar
Normal file
BIN
lib/webdav-server-6.2.9090-Beta.jar
Normal file
Binary file not shown.
644
pom.xml
Normal file
644
pom.xml
Normal 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>
|
||||
<!-- <!– 模版引擎 –>-->
|
||||
<!-- <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>
|
122
src/main/java/com/svnlan/DiskApplication.java
Normal file
122
src/main/java/com/svnlan/DiskApplication.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
232
src/main/java/com/svnlan/NettyWebchat/Domain/ClientInfo.java
Normal file
232
src/main/java/com/svnlan/NettyWebchat/Domain/ClientInfo.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
170
src/main/java/com/svnlan/NettyWebchat/Domain/RoomMsg.java
Normal file
170
src/main/java/com/svnlan/NettyWebchat/Domain/RoomMsg.java
Normal 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;
|
||||
}
|
||||
}
|
28
src/main/java/com/svnlan/NettyWebchat/NettyApplication.java
Normal file
28
src/main/java/com/svnlan/NettyWebchat/NettyApplication.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
16
src/main/java/com/svnlan/NettyWebchat/dto/TempAuthDTO.java
Normal file
16
src/main/java/com/svnlan/NettyWebchat/dto/TempAuthDTO.java
Normal 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;
|
||||
|
||||
}
|
@ -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服务器已关闭");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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,内容:%s,channelId:%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;
|
||||
//若是TV、WEB端
|
||||
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));
|
||||
}
|
||||
//否则产生新的临时授权码给TV、WEB
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
src/main/java/com/svnlan/annotation/CreateGroup.java
Normal file
11
src/main/java/com/svnlan/annotation/CreateGroup.java
Normal 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 {
|
||||
}
|
21
src/main/java/com/svnlan/annotation/EnableVisitRecord.java
Normal file
21
src/main/java/com/svnlan/annotation/EnableVisitRecord.java
Normal 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 {
|
||||
}
|
18
src/main/java/com/svnlan/annotation/MyImportSelector.java
Normal file
18
src/main/java/com/svnlan/annotation/MyImportSelector.java
Normal 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()};
|
||||
}
|
||||
}
|
14
src/main/java/com/svnlan/annotation/SpecifiedValue.java
Normal file
14
src/main/java/com/svnlan/annotation/SpecifiedValue.java
Normal 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 {
|
||||
}
|
11
src/main/java/com/svnlan/annotation/UpdateGroup.java
Normal file
11
src/main/java/com/svnlan/annotation/UpdateGroup.java
Normal 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 {
|
||||
}
|
11
src/main/java/com/svnlan/annotation/VisitHandler.java
Normal file
11
src/main/java/com/svnlan/annotation/VisitHandler.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.svnlan.annotation;
|
||||
|
||||
/**
|
||||
* 当访问时的处理器
|
||||
*
|
||||
* @author lingxu 2023/06/13 10:25
|
||||
*/
|
||||
public interface VisitHandler {
|
||||
|
||||
void handle(Object value);
|
||||
}
|
92
src/main/java/com/svnlan/annotation/VisitRecord.java
Normal file
92
src/main/java/com/svnlan/annotation/VisitRecord.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
38
src/main/java/com/svnlan/common/CheckResult.java
Normal file
38
src/main/java/com/svnlan/common/CheckResult.java
Normal 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;
|
||||
}
|
||||
}
|
254
src/main/java/com/svnlan/common/GlobalConfig.java
Normal file
254
src/main/java/com/svnlan/common/GlobalConfig.java
Normal 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(userId、email)
|
||||
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_";
|
||||
|
||||
|
||||
|
||||
}
|
43
src/main/java/com/svnlan/common/HttpSessionUtil.java
Normal file
43
src/main/java/com/svnlan/common/HttpSessionUtil.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
86
src/main/java/com/svnlan/common/I18nUtils.java
Normal file
86
src/main/java/com/svnlan/common/I18nUtils.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
166
src/main/java/com/svnlan/common/Result.java
Normal file
166
src/main/java/com/svnlan/common/Result.java
Normal 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);
|
||||
}
|
||||
}
|
60
src/main/java/com/svnlan/config/MybatisConfig.java
Normal file
60
src/main/java/com/svnlan/config/MybatisConfig.java
Normal 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;
|
||||
}
|
||||
}
|
114
src/main/java/com/svnlan/config/RedisConfig.java
Normal file
114
src/main/java/com/svnlan/config/RedisConfig.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
49
src/main/java/com/svnlan/enums/AdminDocAuthEnum.java
Normal file
49
src/main/java/com/svnlan/enums/AdminDocAuthEnum.java
Normal 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;
|
||||
}
|
||||
}
|
101
src/main/java/com/svnlan/enums/AuthEnum.java
Normal file
101
src/main/java/com/svnlan/enums/AuthEnum.java
Normal 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;
|
||||
}
|
||||
}
|
26
src/main/java/com/svnlan/enums/BusinessTypeEnum.java
Normal file
26
src/main/java/com/svnlan/enums/BusinessTypeEnum.java
Normal 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;
|
||||
}
|
||||
}
|
64
src/main/java/com/svnlan/enums/ClientTypeEnum.java
Normal file
64
src/main/java/com/svnlan/enums/ClientTypeEnum.java
Normal 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;
|
||||
}
|
||||
}
|
93
src/main/java/com/svnlan/enums/DocumentTypeEnum.java
Normal file
93
src/main/java/com/svnlan/enums/DocumentTypeEnum.java
Normal 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;
|
||||
}
|
||||
}
|
46
src/main/java/com/svnlan/enums/EventEnum.java
Normal file
46
src/main/java/com/svnlan/enums/EventEnum.java
Normal 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;
|
||||
}
|
||||
}
|
38
src/main/java/com/svnlan/enums/FindTypeEnum.java
Normal file
38
src/main/java/com/svnlan/enums/FindTypeEnum.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/com/svnlan/enums/GroupMetaEnum.java
Normal file
44
src/main/java/com/svnlan/enums/GroupMetaEnum.java
Normal 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;
|
||||
}
|
||||
}
|
93
src/main/java/com/svnlan/enums/LogTypeEnum.java
Normal file
93
src/main/java/com/svnlan/enums/LogTypeEnum.java
Normal 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;
|
||||
}
|
||||
}
|
71
src/main/java/com/svnlan/enums/MenuEnum.java
Normal file
71
src/main/java/com/svnlan/enums/MenuEnum.java
Normal 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;
|
||||
}
|
||||
}
|
42
src/main/java/com/svnlan/enums/MetaEnum.java
Normal file
42
src/main/java/com/svnlan/enums/MetaEnum.java
Normal 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;
|
||||
}
|
||||
}
|
44
src/main/java/com/svnlan/enums/MyMenuEnum.java
Normal file
44
src/main/java/com/svnlan/enums/MyMenuEnum.java
Normal 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;
|
||||
}
|
||||
}
|
33
src/main/java/com/svnlan/enums/OperatingSystemEnum.java
Normal file
33
src/main/java/com/svnlan/enums/OperatingSystemEnum.java
Normal 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;
|
||||
}
|
||||
}
|
72
src/main/java/com/svnlan/enums/ScanLoginActionEnum.java
Normal file
72
src/main/java/com/svnlan/enums/ScanLoginActionEnum.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/com/svnlan/enums/ScanLoginMsgTypeEnum.java
Normal file
44
src/main/java/com/svnlan/enums/ScanLoginMsgTypeEnum.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
101
src/main/java/com/svnlan/enums/SecurityTypeEnum.java
Normal file
101
src/main/java/com/svnlan/enums/SecurityTypeEnum.java
Normal 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 qq,4 email,5微博,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 qq,4 email,5微博,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;
|
||||
}
|
||||
}
|
31
src/main/java/com/svnlan/enums/SendOperateTypeEnum.java
Normal file
31
src/main/java/com/svnlan/enums/SendOperateTypeEnum.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
43
src/main/java/com/svnlan/enums/ShareMenuEnum.java
Normal file
43
src/main/java/com/svnlan/enums/ShareMenuEnum.java
Normal 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;
|
||||
}
|
||||
}
|
49
src/main/java/com/svnlan/enums/SortEnum.java
Normal file
49
src/main/java/com/svnlan/enums/SortEnum.java
Normal 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; }
|
||||
}
|
47
src/main/java/com/svnlan/enums/SortFieldEnum.java
Normal file
47
src/main/java/com/svnlan/enums/SortFieldEnum.java
Normal 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; }
|
||||
}
|
79
src/main/java/com/svnlan/enums/SourceFieldEnum.java
Normal file
79
src/main/java/com/svnlan/enums/SourceFieldEnum.java
Normal 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; }
|
||||
}
|
41
src/main/java/com/svnlan/enums/SourceSortEnum.java
Normal file
41
src/main/java/com/svnlan/enums/SourceSortEnum.java
Normal 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; }
|
||||
}
|
44
src/main/java/com/svnlan/enums/ToolsEnum.java
Normal file
44
src/main/java/com/svnlan/enums/ToolsEnum.java
Normal 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;
|
||||
}
|
||||
}
|
42
src/main/java/com/svnlan/enums/UserMetaEnum.java
Normal file
42
src/main/java/com/svnlan/enums/UserMetaEnum.java
Normal 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;
|
||||
}
|
||||
}
|
88
src/main/java/com/svnlan/enums/UserOptionEnum.java
Normal file
88
src/main/java/com/svnlan/enums/UserOptionEnum.java
Normal 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;
|
||||
}
|
||||
}
|
30
src/main/java/com/svnlan/enums/UserTypeEnum.java
Normal file
30
src/main/java/com/svnlan/enums/UserTypeEnum.java
Normal 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;
|
||||
}
|
||||
}
|
47
src/main/java/com/svnlan/enums/UserTypeExactEnum.java
Normal file
47
src/main/java/com/svnlan/enums/UserTypeExactEnum.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
181
src/main/java/com/svnlan/exception/CodeMessageEnum.java
Normal file
181
src/main/java/com/svnlan/exception/CodeMessageEnum.java
Normal 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;
|
||||
}
|
||||
}
|
396
src/main/java/com/svnlan/exception/DingCallbackCrypto.java
Normal file
396
src/main/java/com/svnlan/exception/DingCallbackCrypto.java
Normal 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));
|
||||
}
|
||||
|
||||
}
|
124
src/main/java/com/svnlan/exception/SvnlanRuntimeException.java
Normal file
124
src/main/java/com/svnlan/exception/SvnlanRuntimeException.java
Normal 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;
|
||||
}
|
||||
}
|
103
src/main/java/com/svnlan/home/controller/CommentController.java
Normal file
103
src/main/java/com/svnlan/home/controller/CommentController.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
97
src/main/java/com/svnlan/home/controller/DingController.java
Normal file
97
src/main/java/com/svnlan/home/controller/DingController.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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 "";
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
95
src/main/java/com/svnlan/home/controller/M3u8Controller.java
Normal file
95
src/main/java/com/svnlan/home/controller/M3u8Controller.java
Normal 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";
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
333
src/main/java/com/svnlan/home/controller/ShareController.java
Normal file
333
src/main/java/com/svnlan/home/controller/ShareController.java
Normal 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();
|
||||
}
|
||||
}
|
888
src/main/java/com/svnlan/home/controller/UploadController.java
Normal file
888
src/main/java/com/svnlan/home/controller/UploadController.java
Normal 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 + "-check,getVideoImgAttachmentWithName 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);
|
||||
}
|
||||
}
|
375
src/main/java/com/svnlan/home/controller/VideoGetController.java
Normal file
375
src/main/java/com/svnlan/home/controller/VideoGetController.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
23
src/main/java/com/svnlan/home/dao/CommentDao.java
Normal file
23
src/main/java/com/svnlan/home/dao/CommentDao.java
Normal 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);
|
||||
}
|
28
src/main/java/com/svnlan/home/dao/CommonLabelDao.java
Normal file
28
src/main/java/com/svnlan/home/dao/CommonLabelDao.java
Normal 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);
|
||||
}
|
42
src/main/java/com/svnlan/home/dao/CommonScheduleDao.java
Normal file
42
src/main/java/com/svnlan/home/dao/CommonScheduleDao.java
Normal 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);
|
||||
|
||||
}
|
24
src/main/java/com/svnlan/home/dao/ExplorerOperationsDao.java
Normal file
24
src/main/java/com/svnlan/home/dao/ExplorerOperationsDao.java
Normal 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);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
77
src/main/java/com/svnlan/home/dao/HomeExplorerDao.java
Normal file
77
src/main/java/com/svnlan/home/dao/HomeExplorerDao.java
Normal 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);
|
||||
}
|
70
src/main/java/com/svnlan/home/dao/IoFileDao.java
Normal file
70
src/main/java/com/svnlan/home/dao/IoFileDao.java
Normal 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);
|
||||
}
|
22
src/main/java/com/svnlan/home/dao/IoSourceAuthDao.java
Normal file
22
src/main/java/com/svnlan/home/dao/IoSourceAuthDao.java
Normal 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);
|
||||
}
|
142
src/main/java/com/svnlan/home/dao/IoSourceDao.java
Normal file
142
src/main/java/com/svnlan/home/dao/IoSourceDao.java
Normal 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);
|
||||
}
|
27
src/main/java/com/svnlan/home/dao/IoSourceEventDao.java
Normal file
27
src/main/java/com/svnlan/home/dao/IoSourceEventDao.java
Normal 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
Loading…
Reference in New Issue
Block a user