diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a24230 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/target/ +/log/ +/.idea/ +/*.iml +/.fastRequest/ +/staticServer + +fastRequest/ +.fastRequest/ +/file_data/ +/old_webdav/ +/docker/ + + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d154a15 --- /dev/null +++ b/Dockerfile @@ -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 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ddb6349 --- /dev/null +++ b/LICENSE @@ -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. \ No newline at end of file diff --git a/db/ddl.sql b/db/ddl.sql new file mode 100644 index 0000000..647fd84 --- /dev/null +++ b/db/ddl.sql @@ -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 '用户租户表'; \ No newline at end of file diff --git a/harbor b/harbor new file mode 100644 index 0000000..dba86a5 --- /dev/null +++ b/harbor @@ -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() diff --git a/java-disk-deployment.yaml b/java-disk-deployment.yaml new file mode 100644 index 0000000..f6a58f3 --- /dev/null +++ b/java-disk-deployment.yaml @@ -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 \ No newline at end of file diff --git a/lib/aspose-pdf-23.4-crack.jar b/lib/aspose-pdf-23.4-crack.jar new file mode 100644 index 0000000..c62ed44 Binary files /dev/null and b/lib/aspose-pdf-23.4-crack.jar differ diff --git a/lib/webdav-server-6.2.9090-Beta.jar b/lib/webdav-server-6.2.9090-Beta.jar new file mode 100644 index 0000000..b4c9f02 Binary files /dev/null and b/lib/webdav-server-6.2.9090-Beta.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..98dcb3d --- /dev/null +++ b/pom.xml @@ -0,0 +1,644 @@ + + 4.0.0 + com.svnlan + disk + jar + 0.0.1-SNAPSHOT + disk + http://maven.apache.org + + org.springframework.boot + spring-boot-starter-parent + 2.2.12.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 1.2.0 + 5.1.47 + 1.3.2.RELEASE + 7.5.0 + 1.28.5 + + + + org.apache.skywalking + apm-toolkit-trace + 8.6.0 + + + org.apache.skywalking + apm-toolkit-logback-1.x + 8.6.0 + + + org.apache.skywalking + apm-toolkit-logback-1.x-activation + 8.6.0 + + + org.springframework.boot + spring-boot-starter + 2.2.12.RELEASE + + + + org.springframework + spring-test + 5.0.9.RELEASE + test + + + org.apache.pdfbox + pdfbox + 2.0.26 + + + org.apache.pdfbox + pdfbox-tools + 2.0.26 + + + + org.springframework.boot + spring-boot-starter-web + + + com.aspose + aspose-pdf + 23.4 + system + ${project.basedir}/lib/aspose-pdf-23.4-crack.jar + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.redisson + redisson + 3.16.8 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + + junit + junit + 4.12 + + + mysql + mysql-connector-java + ${mysql-connector} + + + + + org.springframework.boot + spring-boot-starter-mail + + + + + io.netty + netty-all + 4.1.48.Final + + + org.springframework + spring-test + 5.1.7.RELEASE + + + + com.mpatric + mp3agic + 0.9.1 + + + + + org.apache.commons + commons-compress + 1.9 + + + + com.github.junrar + junrar + 4.0.0 + + + + org.jsoup + jsoup + 1.12.1 + + + + com.auth0 + java-jwt + 3.2.0 + + + io.jsonwebtoken + jjwt + 0.9.0 + + + commons-fileupload + commons-fileupload + 1.4 + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + 3.0.5 + + + commons-io + commons-io + 2.5 + + + + com.aliyun.oss + aliyun-sdk-oss + 3.8.0 + + + + org.apache.ant + ant + 1.10.5 + + + + net.sf.sevenzipjbinding + sevenzipjbinding + 9.20-2.00beta + + + net.sf.sevenzipjbinding + sevenzipjbinding-all-platforms + 9.20-2.00beta + + + + net.lingala.zip4j + zip4j + 2.11.5 + + + net.coobird + thumbnailator + 0.4.13 + + + + org.apache.pdfbox + pdfbox + 2.0.12 + + + org.apache.pdfbox + fontbox + 2.0.12 + + + + org.apache.poi + poi + 3.17 + + + + org.apache.poi + poi-ooxml + 3.17 + + + com.github.eljah + xmindjbehaveplugin + 0.8 + + + + + com.alibaba + druid + 1.1.10 + + + com.alibaba + fastjson + 1.2.83 + + + + + + + + + + com.belerweb + pinyin4j + 2.5.0 + + + + com.github.pagehelper + pagehelper + 4.1.6 + + + + eu.bitwalker + UserAgentUtils + 1.21 + + + + org.apache.httpcomponents + httpclient + 4.5.5 + + + org.apache.httpcomponents + httpmime + 4.5.6 + + + + org.projectlombok + lombok + 1.16.6 + + + + cn.jpush.api + jmessage-client + 1.1.8 + + + + com.google.code.gson + gson + 2.8.5 + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + org.springframework.boot + spring-boot-starter-aop + + + + + org.mybatis + mybatis-typehandlers-jsr310 + 1.0.2 + + + + cn.afterturn + easypoi-spring-boot-starter + 4.0.0 + + + org.apache.poi + poi + + + + + org.apache.poi + poi + 3.17 + + + + + + com.github.ben-manes.caffeine + caffeine + 2.8.0 + + + + com.aliyun + dingtalk + 1.5.58 + + + com.aliyun + alibaba-dingtalk-service-sdk + 2.0.0 + + + + + + + + + + com.baomidou + mybatis-plus-boot-starter + 3.1.0 + + + + com.ithit.webdav + webdav-server + 6.2.9090-Beta + system + ${project.basedir}/lib/webdav-server-6.2.9090-Beta.jar + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + net.java.dev.jna + jna-platform + 5.13.0 + + + net.java.dev.jna + jna + + + + + net.java.dev.jna + jna + 5.13.0 + + + + + org.apache.lucene + lucene-core + ${lucene-core.version} + + + org.apache.lucene + lucene-queryparser + ${lucene-core.version} + + + org.apache.lucene + lucene-highlighter + ${lucene-core.version} + + + + org.apache.tika + tika-parsers + ${tika-core.version} + + + cxf-core + org.apache.cxf + + + cxf-rt-rs-client + org.apache.cxf + + + httpservices + edu.ucar + + + maven-scm-provider-svnexe + org.apache.maven.scm + + + maven-scm-api + org.apache.maven.scm + + + slf4j-log4j12 + org.slf4j + + + c3p0 + c3p0 + + + httpclient + org.apache.httpcomponents + + + grib + edu.ucar + + + cdm + edu.ucar + + + unit-api + javax.measure + + + activation + javax.activation + + + org.apache.sis.storage + sis-netcdf + + + + + + + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + org.mybatis.generator + mybatis-generator-maven-plugin + 1.3.2 + + ${basedir}/src/main/resources/generatorConfig.xml + false + true + + + + mysql + mysql-connector-java + ${mysql.version} + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + copy-resources + compile + + copy-resources + + + + true + ${project.build.outputDirectory} + + + + + + src/main/resources/${package.environment} + false + + + + + + + + + + src/main/resources + false + + + lib + WEB-INF/lib/ + + **/*.jar + + + + + + + pufay + + + env + pufay + + + + pufay + + + + dev + + + env + dev + + + + dev + + + + pre + + + env + pre + + + + pre + + + + itest + + + env + itest + + + + itest + + + + pro + + + env + pro + + + + pro + + + + + diff --git a/src/main/java/com/svnlan/DiskApplication.java b/src/main/java/com/svnlan/DiskApplication.java new file mode 100644 index 0000000..ccbce1d --- /dev/null +++ b/src/main/java/com/svnlan/DiskApplication.java @@ -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> 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; + } + + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/Common/CommonHandler.java b/src/main/java/com/svnlan/NettyWebchat/Common/CommonHandler.java new file mode 100644 index 0000000..3c4a37c --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/Common/CommonHandler.java @@ -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 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 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()); + } + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/Common/SpringManager.java b/src/main/java/com/svnlan/NettyWebchat/Common/SpringManager.java new file mode 100644 index 0000000..28b7919 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/Common/SpringManager.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/NettyWebchat/Domain/ChannelSupervise.java b/src/main/java/com/svnlan/NettyWebchat/Domain/ChannelSupervise.java new file mode 100644 index 0000000..644c7e9 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/Domain/ChannelSupervise.java @@ -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> visitorRooms = new ConcurrentHashMap<>(); + //通用业务 + public static ConcurrentHashMap> commonRooms = new ConcurrentHashMap<>(); + //扫码登录业务 + public static ConcurrentHashMap> 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); + } + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/Domain/ClientInfo.java b/src/main/java/com/svnlan/NettyWebchat/Domain/ClientInfo.java new file mode 100644 index 0000000..8bffa68 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/Domain/ClientInfo.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/Domain/CommonReturnMessage.java b/src/main/java/com/svnlan/NettyWebchat/Domain/CommonReturnMessage.java new file mode 100644 index 0000000..24f8f5b --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/Domain/CommonReturnMessage.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/Domain/RoomMsg.java b/src/main/java/com/svnlan/NettyWebchat/Domain/RoomMsg.java new file mode 100644 index 0000000..c87d8a3 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/Domain/RoomMsg.java @@ -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 quarantineUid; + + /** 消息体 */ + private String message; + + /** 发送给多个用户id */ + private List 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 getQuarantineUid() { + return quarantineUid; + } + + public void setQuarantineUid(Set quarantineUid) { + this.quarantineUid = quarantineUid; + } + + public List getUserIdList() { + return userIdList; + } + + public void setUserIdList(List 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; + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/NettyApplication.java b/src/main/java/com/svnlan/NettyWebchat/NettyApplication.java new file mode 100644 index 0000000..a8f2857 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/NettyApplication.java @@ -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(); + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginMessage.java b/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginMessage.java new file mode 100644 index 0000000..f8b95be --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginMessage.java @@ -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; + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginQRDTO.java b/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginQRDTO.java new file mode 100644 index 0000000..6c3e61f --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginQRDTO.java @@ -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; + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginResult.java b/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginResult.java new file mode 100644 index 0000000..83e385b --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/dto/ScanLoginResult.java @@ -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; + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/dto/TempAuthDTO.java b/src/main/java/com/svnlan/NettyWebchat/dto/TempAuthDTO.java new file mode 100644 index 0000000..424bcf4 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/dto/TempAuthDTO.java @@ -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; + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/initializer/NettyServer.java b/src/main/java/com/svnlan/NettyWebchat/initializer/NettyServer.java new file mode 100644 index 0000000..ece29cb --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/initializer/NettyServer.java @@ -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服务器已关闭"); + } + } + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/initializer/WebSocketChannelInitializer.java b/src/main/java/com/svnlan/NettyWebchat/initializer/WebSocketChannelInitializer.java new file mode 100644 index 0000000..16e125a --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/initializer/WebSocketChannelInitializer.java @@ -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 { + 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 + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/NettyBroadcastService.java b/src/main/java/com/svnlan/NettyWebchat/service/NettyBroadcastService.java new file mode 100644 index 0000000..846a94e --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/NettyBroadcastService.java @@ -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); + + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/NettyLoginService.java b/src/main/java/com/svnlan/NettyWebchat/service/NettyLoginService.java new file mode 100644 index 0000000..8aa6408 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/NettyLoginService.java @@ -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); + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/WebSocketHandler.java b/src/main/java/com/svnlan/NettyWebchat/service/WebSocketHandler.java new file mode 100644 index 0000000..9698c49 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/WebSocketHandler.java @@ -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{ + 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); + } + + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/impl/HeartBeatServerHandler.java b/src/main/java/com/svnlan/NettyWebchat/service/impl/HeartBeatServerHandler.java new file mode 100644 index 0000000..8576ca8 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/impl/HeartBeatServerHandler.java @@ -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); + } + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/impl/HttpHandler.java b/src/main/java/com/svnlan/NettyWebchat/service/impl/HttpHandler.java new file mode 100644 index 0000000..5fb6033 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/impl/HttpHandler.java @@ -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 { + @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); + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/impl/NettyBroadcastServiceImpl.java b/src/main/java/com/svnlan/NettyWebchat/service/impl/NettyBroadcastServiceImpl.java new file mode 100644 index 0000000..9da3bf8 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/impl/NettyBroadcastServiceImpl.java @@ -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()); + } + } + } + } + } + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/service/impl/NettyLoginServiceImpl.java b/src/main/java/com/svnlan/NettyWebchat/service/impl/NettyLoginServiceImpl.java new file mode 100644 index 0000000..819bb82 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/service/impl/NettyLoginServiceImpl.java @@ -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 lcMap = hashOperations.entries(lcRelationRedisKey); + Iterator iterator = lcMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry) 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 lcMap = hashOperations.entries(lcRelationRedisKey); + Iterator iterator = lcMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry) 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); + } + } + } + } + +} diff --git a/src/main/java/com/svnlan/NettyWebchat/utils/RequestTransUtil.java b/src/main/java/com/svnlan/NettyWebchat/utils/RequestTransUtil.java new file mode 100644 index 0000000..dc3c06b --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/utils/RequestTransUtil.java @@ -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 paramMap = ParamUtil.getRequestParams(nettyRequest); + if(! CollectionUtils.isEmpty(paramMap)){ + for (Map.Entry 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; + } +} diff --git a/src/main/java/com/svnlan/NettyWebchat/utils/ResponseUtil.java b/src/main/java/com/svnlan/NettyWebchat/utils/ResponseUtil.java new file mode 100644 index 0000000..b39a578 --- /dev/null +++ b/src/main/java/com/svnlan/NettyWebchat/utils/ResponseUtil.java @@ -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); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/annotation/CreateGroup.java b/src/main/java/com/svnlan/annotation/CreateGroup.java new file mode 100644 index 0000000..7eaae29 --- /dev/null +++ b/src/main/java/com/svnlan/annotation/CreateGroup.java @@ -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 { +} diff --git a/src/main/java/com/svnlan/annotation/EnableVisitRecord.java b/src/main/java/com/svnlan/annotation/EnableVisitRecord.java new file mode 100644 index 0000000..a9be02f --- /dev/null +++ b/src/main/java/com/svnlan/annotation/EnableVisitRecord.java @@ -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 { +} diff --git a/src/main/java/com/svnlan/annotation/MyImportSelector.java b/src/main/java/com/svnlan/annotation/MyImportSelector.java new file mode 100644 index 0000000..cc04914 --- /dev/null +++ b/src/main/java/com/svnlan/annotation/MyImportSelector.java @@ -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()}; + } +} diff --git a/src/main/java/com/svnlan/annotation/SpecifiedValue.java b/src/main/java/com/svnlan/annotation/SpecifiedValue.java new file mode 100644 index 0000000..fbabc64 --- /dev/null +++ b/src/main/java/com/svnlan/annotation/SpecifiedValue.java @@ -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 { +} diff --git a/src/main/java/com/svnlan/annotation/UpdateGroup.java b/src/main/java/com/svnlan/annotation/UpdateGroup.java new file mode 100644 index 0000000..3db3306 --- /dev/null +++ b/src/main/java/com/svnlan/annotation/UpdateGroup.java @@ -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 { +} diff --git a/src/main/java/com/svnlan/annotation/VisitHandler.java b/src/main/java/com/svnlan/annotation/VisitHandler.java new file mode 100644 index 0000000..502f4f1 --- /dev/null +++ b/src/main/java/com/svnlan/annotation/VisitHandler.java @@ -0,0 +1,11 @@ +package com.svnlan.annotation; + +/** + * 当访问时的处理器 + * + * @author lingxu 2023/06/13 10:25 + */ +public interface VisitHandler { + + void handle(Object value); +} diff --git a/src/main/java/com/svnlan/annotation/VisitRecord.java b/src/main/java/com/svnlan/annotation/VisitRecord.java new file mode 100644 index 0000000..775369b --- /dev/null +++ b/src/main/java/com/svnlan/annotation/VisitRecord.java @@ -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>> getTimeList(LocalDateTime now) { + List>> 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; + } + } +} diff --git a/src/main/java/com/svnlan/common/CheckResult.java b/src/main/java/com/svnlan/common/CheckResult.java new file mode 100644 index 0000000..3b38944 --- /dev/null +++ b/src/main/java/com/svnlan/common/CheckResult.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/common/GlobalConfig.java b/src/main/java/com/svnlan/common/GlobalConfig.java new file mode 100644 index 0000000..0d288d1 --- /dev/null +++ b/src/main/java/com/svnlan/common/GlobalConfig.java @@ -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_"; + + + +} diff --git a/src/main/java/com/svnlan/common/HttpSessionUtil.java b/src/main/java/com/svnlan/common/HttpSessionUtil.java new file mode 100644 index 0000000..e287ab6 --- /dev/null +++ b/src/main/java/com/svnlan/common/HttpSessionUtil.java @@ -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 { + 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; + } + } + +} diff --git a/src/main/java/com/svnlan/common/I18nUtils.java b/src/main/java/com/svnlan/common/I18nUtils.java new file mode 100644 index 0000000..49094fa --- /dev/null +++ b/src/main/java/com/svnlan/common/I18nUtils.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/common/LogScheduleStateConstants.java b/src/main/java/com/svnlan/common/LogScheduleStateConstants.java new file mode 100644 index 0000000..2b8724c --- /dev/null +++ b/src/main/java/com/svnlan/common/LogScheduleStateConstants.java @@ -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"; +} diff --git a/src/main/java/com/svnlan/common/Result.java b/src/main/java/com/svnlan/common/Result.java new file mode 100644 index 0000000..fa5b7a9 --- /dev/null +++ b/src/main/java/com/svnlan/common/Result.java @@ -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); + } +} diff --git a/src/main/java/com/svnlan/config/MybatisConfig.java b/src/main/java/com/svnlan/config/MybatisConfig.java new file mode 100644 index 0000000..6ba89fb --- /dev/null +++ b/src/main/java/com/svnlan/config/MybatisConfig.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/config/RedisConfig.java b/src/main/java/com/svnlan/config/RedisConfig.java new file mode 100644 index 0000000..4aaec7d --- /dev/null +++ b/src/main/java/com/svnlan/config/RedisConfig.java @@ -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 redisTemplate(LettuceConnectionFactory factory) { + //String + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + + //JdkSerialization + //JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSgiterializationRedisSerializer(); + + //Jackson2Json + Jackson2JsonRedisSerializer 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 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 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); + } + +} diff --git a/src/main/java/com/svnlan/enums/AdminDocAuthEnum.java b/src/main/java/com/svnlan/enums/AdminDocAuthEnum.java new file mode 100644 index 0000000..31eb9b2 --- /dev/null +++ b/src/main/java/com/svnlan/enums/AdminDocAuthEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/AuthEnum.java b/src/main/java/com/svnlan/enums/AuthEnum.java new file mode 100644 index 0000000..91f6186 --- /dev/null +++ b/src/main/java/com/svnlan/enums/AuthEnum.java @@ -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 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 getUserAuthMap(String userAuth){ + List aList = !ObjectUtils.isEmpty(userAuth) ? Arrays.asList(userAuth.split(",")).stream().map(String::valueOf).collect(Collectors.toList()) : null; + Map 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; + } +} diff --git a/src/main/java/com/svnlan/enums/BusinessTypeEnum.java b/src/main/java/com/svnlan/enums/BusinessTypeEnum.java new file mode 100644 index 0000000..6fa9aa5 --- /dev/null +++ b/src/main/java/com/svnlan/enums/BusinessTypeEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/ClientTypeEnum.java b/src/main/java/com/svnlan/enums/ClientTypeEnum.java new file mode 100644 index 0000000..f10d6db --- /dev/null +++ b/src/main/java/com/svnlan/enums/ClientTypeEnum.java @@ -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 getCodeList() { + return Arrays.stream(ClientTypeEnum.values()).map(it -> it.code).collect(Collectors.toList()); + } + + /** + * 获取所有枚举的 code 集合 + * @param exclude 需要排除的类型 + */ + public static List getCodeList(List 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; + } +} diff --git a/src/main/java/com/svnlan/enums/DocumentTypeEnum.java b/src/main/java/com/svnlan/enums/DocumentTypeEnum.java new file mode 100644 index 0000000..ce124ae --- /dev/null +++ b/src/main/java/com/svnlan/enums/DocumentTypeEnum.java @@ -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 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; + } +} diff --git a/src/main/java/com/svnlan/enums/EventEnum.java b/src/main/java/com/svnlan/enums/EventEnum.java new file mode 100644 index 0000000..f60033a --- /dev/null +++ b/src/main/java/com/svnlan/enums/EventEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/FindTypeEnum.java b/src/main/java/com/svnlan/enums/FindTypeEnum.java new file mode 100644 index 0000000..cca90d1 --- /dev/null +++ b/src/main/java/com/svnlan/enums/FindTypeEnum.java @@ -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; + } + +} diff --git a/src/main/java/com/svnlan/enums/GroupMetaEnum.java b/src/main/java/com/svnlan/enums/GroupMetaEnum.java new file mode 100644 index 0000000..5582309 --- /dev/null +++ b/src/main/java/com/svnlan/enums/GroupMetaEnum.java @@ -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 keyList = Arrays.stream(values()).map(GroupMetaEnum::getValue).collect(Collectors.toList()); + + public static List 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; + } +} diff --git a/src/main/java/com/svnlan/enums/LogTypeEnum.java b/src/main/java/com/svnlan/enums/LogTypeEnum.java new file mode 100644 index 0000000..7efe2f0 --- /dev/null +++ b/src/main/java/com/svnlan/enums/LogTypeEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/MenuEnum.java b/src/main/java/com/svnlan/enums/MenuEnum.java new file mode 100644 index 0000000..667e04a --- /dev/null +++ b/src/main/java/com/svnlan/enums/MenuEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/MetaEnum.java b/src/main/java/com/svnlan/enums/MetaEnum.java new file mode 100644 index 0000000..8217549 --- /dev/null +++ b/src/main/java/com/svnlan/enums/MetaEnum.java @@ -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 keyList = Arrays.stream(values()).map(MetaEnum::getValue).collect(Collectors.toList()); + + public static List 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; + } +} diff --git a/src/main/java/com/svnlan/enums/MyMenuEnum.java b/src/main/java/com/svnlan/enums/MyMenuEnum.java new file mode 100644 index 0000000..97a5a00 --- /dev/null +++ b/src/main/java/com/svnlan/enums/MyMenuEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/OperatingSystemEnum.java b/src/main/java/com/svnlan/enums/OperatingSystemEnum.java new file mode 100644 index 0000000..49abba5 --- /dev/null +++ b/src/main/java/com/svnlan/enums/OperatingSystemEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/ScanLoginActionEnum.java b/src/main/java/com/svnlan/enums/ScanLoginActionEnum.java new file mode 100644 index 0000000..e9f2204 --- /dev/null +++ b/src/main/java/com/svnlan/enums/ScanLoginActionEnum.java @@ -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; + } + +} diff --git a/src/main/java/com/svnlan/enums/ScanLoginMsgTypeEnum.java b/src/main/java/com/svnlan/enums/ScanLoginMsgTypeEnum.java new file mode 100644 index 0000000..30d0a7b --- /dev/null +++ b/src/main/java/com/svnlan/enums/ScanLoginMsgTypeEnum.java @@ -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; + } + +} diff --git a/src/main/java/com/svnlan/enums/SecurityTypeEnum.java b/src/main/java/com/svnlan/enums/SecurityTypeEnum.java new file mode 100644 index 0000000..4685050 --- /dev/null +++ b/src/main/java/com/svnlan/enums/SecurityTypeEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/SendOperateTypeEnum.java b/src/main/java/com/svnlan/enums/SendOperateTypeEnum.java new file mode 100644 index 0000000..b959d70 --- /dev/null +++ b/src/main/java/com/svnlan/enums/SendOperateTypeEnum.java @@ -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; + } + +} diff --git a/src/main/java/com/svnlan/enums/ShareMenuEnum.java b/src/main/java/com/svnlan/enums/ShareMenuEnum.java new file mode 100644 index 0000000..02e4337 --- /dev/null +++ b/src/main/java/com/svnlan/enums/ShareMenuEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/SortEnum.java b/src/main/java/com/svnlan/enums/SortEnum.java new file mode 100644 index 0000000..89768b0 --- /dev/null +++ b/src/main/java/com/svnlan/enums/SortEnum.java @@ -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 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; } +} diff --git a/src/main/java/com/svnlan/enums/SortFieldEnum.java b/src/main/java/com/svnlan/enums/SortFieldEnum.java new file mode 100644 index 0000000..5cb16b9 --- /dev/null +++ b/src/main/java/com/svnlan/enums/SortFieldEnum.java @@ -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 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; } +} diff --git a/src/main/java/com/svnlan/enums/SourceFieldEnum.java b/src/main/java/com/svnlan/enums/SourceFieldEnum.java new file mode 100644 index 0000000..64244fc --- /dev/null +++ b/src/main/java/com/svnlan/enums/SourceFieldEnum.java @@ -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 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; } +} diff --git a/src/main/java/com/svnlan/enums/SourceSortEnum.java b/src/main/java/com/svnlan/enums/SourceSortEnum.java new file mode 100644 index 0000000..fb78ce0 --- /dev/null +++ b/src/main/java/com/svnlan/enums/SourceSortEnum.java @@ -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; } +} diff --git a/src/main/java/com/svnlan/enums/ToolsEnum.java b/src/main/java/com/svnlan/enums/ToolsEnum.java new file mode 100644 index 0000000..001ef44 --- /dev/null +++ b/src/main/java/com/svnlan/enums/ToolsEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/UserMetaEnum.java b/src/main/java/com/svnlan/enums/UserMetaEnum.java new file mode 100644 index 0000000..812c02b --- /dev/null +++ b/src/main/java/com/svnlan/enums/UserMetaEnum.java @@ -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 keyList = Arrays.stream(values()).map(UserMetaEnum::getValue).collect(Collectors.toList()); + + public static List 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; + } +} diff --git a/src/main/java/com/svnlan/enums/UserOptionEnum.java b/src/main/java/com/svnlan/enums/UserOptionEnum.java new file mode 100644 index 0000000..fb12fa3 --- /dev/null +++ b/src/main/java/com/svnlan/enums/UserOptionEnum.java @@ -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 keyList = Arrays.stream(values()).map(UserOptionEnum::getCode).collect(Collectors.toList()); + + public static List 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 setDefaultOptionList(Long userID){ + List 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; + } +} diff --git a/src/main/java/com/svnlan/enums/UserTypeEnum.java b/src/main/java/com/svnlan/enums/UserTypeEnum.java new file mode 100644 index 0000000..c0fbb79 --- /dev/null +++ b/src/main/java/com/svnlan/enums/UserTypeEnum.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/enums/UserTypeExactEnum.java b/src/main/java/com/svnlan/enums/UserTypeExactEnum.java new file mode 100644 index 0000000..44eab4d --- /dev/null +++ b/src/main/java/com/svnlan/enums/UserTypeExactEnum.java @@ -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; + } + +} diff --git a/src/main/java/com/svnlan/exception/CodeMessageEnum.java b/src/main/java/com/svnlan/exception/CodeMessageEnum.java new file mode 100644 index 0000000..41224af --- /dev/null +++ b/src/main/java/com/svnlan/exception/CodeMessageEnum.java @@ -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", "出错了!未识别的压缩文件格式;
请检查该文件是否为压缩文件或者是否损坏。"), + 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; + } +} diff --git a/src/main/java/com/svnlan/exception/DingCallbackCrypto.java b/src/main/java/com/svnlan/exception/DingCallbackCrypto.java new file mode 100644 index 0000000..029d30e --- /dev/null +++ b/src/main/java/com/svnlan/exception/DingCallbackCrypto.java @@ -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 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 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 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 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 getFieldValue(Class srcClazz, String fieldName, Object owner, Class dstClazz) throws Exception { + Field field = srcClazz.getDeclaredField(fieldName); + field.setAccessible(true); + return dstClazz.cast(field.get(owner)); + } + +} diff --git a/src/main/java/com/svnlan/exception/SvnlanRuntimeException.java b/src/main/java/com/svnlan/exception/SvnlanRuntimeException.java new file mode 100644 index 0000000..42540be --- /dev/null +++ b/src/main/java/com/svnlan/exception/SvnlanRuntimeException.java @@ -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; + } +} diff --git a/src/main/java/com/svnlan/home/controller/CommentController.java b/src/main/java/com/svnlan/home/controller/CommentController.java new file mode 100644 index 0000000..03be193 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/CommentController.java @@ -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); + } +} diff --git a/src/main/java/com/svnlan/home/controller/CommonLabelController.java b/src/main/java/com/svnlan/home/controller/CommonLabelController.java new file mode 100644 index 0000000..be55c73 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/CommonLabelController.java @@ -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 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 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 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); + } +} diff --git a/src/main/java/com/svnlan/home/controller/DingController.java b/src/main/java/com/svnlan/home/controller/DingController.java new file mode 100644 index 0000000..2125eee --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/DingController.java @@ -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 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 successMap = callbackCrypto.getEncryptedMap("success"); + LogUtil.info(successMap.toString()); + return successMap; + } + + @PostMapping("/api/disk/dingCallback") + public Map 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 successMap = callbackCrypto.getEncryptedMap("success"); + return successMap; + + } catch (DingCallbackCrypto.DingTalkEncryptException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/com/svnlan/home/controller/ExplorerFileController.java b/src/main/java/com/svnlan/home/controller/ExplorerFileController.java new file mode 100644 index 0000000..995b228 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/ExplorerFileController.java @@ -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); + } + +} diff --git a/src/main/java/com/svnlan/home/controller/ExplorerOperationsController.java b/src/main/java/com/svnlan/home/controller/ExplorerOperationsController.java new file mode 100644 index 0000000..3f9b919 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/ExplorerOperationsController.java @@ -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 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); + } + + +} diff --git a/src/main/java/com/svnlan/home/controller/FileDocConvertController.java b/src/main/java/com/svnlan/home/controller/FileDocConvertController.java new file mode 100644 index 0000000..0ec506b --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/FileDocConvertController.java @@ -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 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 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); + } +} diff --git a/src/main/java/com/svnlan/home/controller/FilePreViewController.java b/src/main/java/com/svnlan/home/controller/FilePreViewController.java new file mode 100644 index 0000000..1b7a4f2 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/FilePreViewController.java @@ -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 ""; + } +} diff --git a/src/main/java/com/svnlan/home/controller/HomeExplorerController.java b/src/main/java/com/svnlan/home/controller/HomeExplorerController.java new file mode 100644 index 0000000..e908fbb --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/HomeExplorerController.java @@ -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 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 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 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 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); + } +} + + diff --git a/src/main/java/com/svnlan/home/controller/M3u8Controller.java b/src/main/java/com/svnlan/home/controller/M3u8Controller.java new file mode 100644 index 0000000..cd4bab2 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/M3u8Controller.java @@ -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"; + } +} diff --git a/src/main/java/com/svnlan/home/controller/NoticeController.java b/src/main/java/com/svnlan/home/controller/NoticeController.java new file mode 100644 index 0000000..75d6138 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/NoticeController.java @@ -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 ids = Lists.asList(id, new Long[]{}); + List 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(); + } + +} diff --git a/src/main/java/com/svnlan/home/controller/ShareController.java b/src/main/java/com/svnlan/home/controller/ShareController.java new file mode 100644 index 0000000..d84f7ba --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/ShareController.java @@ -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 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(); + } +} diff --git a/src/main/java/com/svnlan/home/controller/UploadController.java b/src/main/java/com/svnlan/home/controller/UploadController.java new file mode 100644 index 0000000..b39fc90 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/UploadController.java @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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); + } +} diff --git a/src/main/java/com/svnlan/home/controller/VideoGetController.java b/src/main/java/com/svnlan/home/controller/VideoGetController.java new file mode 100644 index 0000000..1ac9061 --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/VideoGetController.java @@ -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 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 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 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 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 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 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 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 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 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 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 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 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); + } +} diff --git a/src/main/java/com/svnlan/home/controller/YzCallbackController.java b/src/main/java/com/svnlan/home/controller/YzCallbackController.java new file mode 100644 index 0000000..c08287a --- /dev/null +++ b/src/main/java/com/svnlan/home/controller/YzCallbackController.java @@ -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); + } + +} diff --git a/src/main/java/com/svnlan/home/dao/CommentDao.java b/src/main/java/com/svnlan/home/dao/CommentDao.java new file mode 100644 index 0000000..aa3f227 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/CommentDao.java @@ -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 getCommentList(Map map); + long getCountComment(Map map); + Integer checkCommentExist(Long commentID); + CommentVo getTargetIdByCommentId(Long commentID); +} diff --git a/src/main/java/com/svnlan/home/dao/CommonLabelDao.java b/src/main/java/com/svnlan/home/dao/CommonLabelDao.java new file mode 100644 index 0000000..4b3aa11 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/CommonLabelDao.java @@ -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 getUserLabelList(Long userID); + List getInfoLabelList(Long userID); + + Integer getMaxSort(@Param("userID") Long userID, @Param("tagType") Integer tagType); + int updateSort(@Param("labelId") Long labelId, @Param("sort") Integer sort); + + List checkLabelNameRepeat(@Param("labelName") String labelName, @Param("userID") Long userID, @Param("tagType") Integer tagType); +} diff --git a/src/main/java/com/svnlan/home/dao/CommonScheduleDao.java b/src/main/java/com/svnlan/home/dao/CommonScheduleDao.java new file mode 100644 index 0000000..08145aa --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/CommonScheduleDao.java @@ -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); + +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/dao/ExplorerOperationsDao.java b/src/main/java/com/svnlan/home/dao/ExplorerOperationsDao.java new file mode 100644 index 0000000..bd4804f --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/ExplorerOperationsDao.java @@ -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 getAllSourceList(Map paramMap); + int batchUpdateLevel(List list); + List getSourceListByLevelToContSize(@Param("parentLevel") String parentLevel, @Param("status") Integer status); + int batchUpdateSizeByCountSize(List list); + + + + +} diff --git a/src/main/java/com/svnlan/home/dao/HomeExplorerDao.java b/src/main/java/com/svnlan/home/dao/HomeExplorerDao.java new file mode 100644 index 0000000..ce76009 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/HomeExplorerDao.java @@ -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 getHomeExplorer(Map paramMap); + Long getCountHomeExplorer(Map paramMap); + /** 收藏夹*/ + List getUserFavExplorer(Map paramMap); + /** 回收站*/ + List getUserRecycleExplorer(Map paramMap); + /** 最近文档*/ + List getUserRencentExplorer(Map 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 getUserSpace(@Param("userID") Long userID, @Param("groupID") Long groupID); + List getSourceChileCont(List list); + + /** + * 修改云盘空间使用大小 + * + * @param paramMap + * @return + */ + void updateMemory(Map paramMap); + int updateMemoryList(Map paramMap); + void updateUserMemory(Map paramMap); + void updateSubtractUseUserMemory(Map paramMap); + int batchUpdateGroupMemoryList(@Param("list") List list); + HomeExplorerVO getOneSourceInfo(Long sourceID); + List getUserGroupSourceList(Long userID); + List getSystemGroupSourceList(); + Integer getUserIdentityInfo(Long userID); + String getParentName(Long sourceID); + List getParentNameList(@Param("list") List list); + Integer checkUserRecycleExplorer(Long userID); + String getGroupParentLevel(Long groupID); + List getGroupParentLevelList(@Param("list") List list); + List getImgAndAudioHomeExplorer(@Param("list") List list, @Param("lnkAudio") Integer lnkAudio); + List getFolderAndImgAndAudioHomeExplorer(@Param("list") List list, @Param("lnkAudio") Integer lnkAudio); + List getImgByFolderList(Map paramMap); +} diff --git a/src/main/java/com/svnlan/home/dao/IoFileDao.java b/src/main/java/com/svnlan/home/dao/IoFileDao.java new file mode 100644 index 0000000..7cf53d8 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoFileDao.java @@ -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 { + + CommonSource getFileAttachment(Long sourceID); + + int insert(IOFile ioFile); + int batchInsert(List list); + int insertMeta(IOFileMeta ioFile); + int batchInsertMeta(List list); + List getSameSourceEmptyInfo(@Param("hashMd5") String hashMd5, @Param("size") Long size); + int updateVideoConvert(CommonSource commonSource); + int updateSameFile(@Param("commonSource") CommonSource commonSource, @Param("list") List list); + int updateDocConvert(CommonSource commonSource); + + List getSameSourceEmptyInfoDoc(@Param("hashMd5") String hashMd5, @Param("size") Long size); + int updateSameFileSwf(@Param("map") Map updateMap, @Param("list") List list); + + void updateSameFileDoc(@Param("map") Map docPath, @Param("list") List 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 list); + int removeUserFileMeta(List list); + int removeUserFileContents(List list); + String getFileUrlValue(Long fileID); + List getFileUrlValueList(List list); + int updateFileUrlValue(List 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); +} diff --git a/src/main/java/com/svnlan/home/dao/IoSourceAuthDao.java b/src/main/java/com/svnlan/home/dao/IoSourceAuthDao.java new file mode 100644 index 0000000..e42a7e4 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoSourceAuthDao.java @@ -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 list); + int deleteSourceAuth(Long sourceID); + List getSourceAuthBySourceID(Long sourceID); + List getGroupNameListByGID(List list); + List getSourceAuthBySourceIDList(@Param("list") List list, @Param("targetID") Long targetID); +} diff --git a/src/main/java/com/svnlan/home/dao/IoSourceDao.java b/src/main/java/com/svnlan/home/dao/IoSourceDao.java new file mode 100644 index 0000000..55b4de8 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoSourceDao.java @@ -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 { + + int insert(IOSource source); + + int batchInsert(List list); + + CommonSource getSourceInfo(Long sourceID); + + List getSourceInfoList(List list); + + List copySourceList(List list); + + List copySourceListByLevel(List list); + + int deleteDirOrFile(List list); + + int deleteSourceByParent(List list); + + int restoreSourceByParent(@Param("list") List list, @Param("userID") Long userID); + + int batchFileRename(@Param("list") List list, @Param("userID") Long userID); + + int batchUpdateParent(List list); + + int restoreDirOrFile(@Param("list") List list, @Param("userID") Long userID); + + int removeUserSource(List list); + + int removeUserSourceByParent(List list); + + List getFileIDBySourceID(List list); + + List getFileCountBySourceID(List list); + + int updateSourceMemoryList(@Param("list") List list, @Param("memory") Long memory); + + int subtractSourceMemoryList(@Param("list") List list, @Param("memory") Long memory); + + int batchUpdateSourceMemoryList(@Param("list") List list); + + int batchSubtractSourceMemoryList(@Param("list") List list); + + Integer getMaxSort(Long parentID); + + int updateSort(@Param("sourceID") Long sourceID, @Param("sort") Integer sort); + + int updateSourceInfo(IOSource source); + + List copySourcePathList(List list); + + List copySourcePathListByLevel(List list); + + List getSourceFileInfoList(List list); + + int updateSourceModifyUser(IOSource source); + + int updateFileSize(IOSource source); + + List getSourceNameList(Long sourceID); + + List checkSourceNameList(Long sourceID); + + List fileCount(); + + @Select("SELECT COUNT(sourceID) count, `type` FROM io_source WHERE isFolder = 0 AND `type` IS NOT NULL GROUP BY `type`") + List getFileTypeProportion(); + + List getFileCountByPath(List list); + + + @Select("SELECT name FROM io_source WHERE sourceID = #{id}") + IOSource getSourceNameBySourceId(@Param("id") Long sourceID); + + List 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 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 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 getFileTypeProportionByUserId(@Param("userId") Long userId); + + int batchUpdateParentAndName(List 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 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 getParentPathDisplay(List 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 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 selectFileProportion(); + + + @Select("SELECT targetType ty, SUM(size) s FROM io_source WHERE isFolder = 0 GROUP BY targetType") + List getTargetTypeProportion(); + + List getParentPathDisplayByIds(List list); + int updateSourceDesc(@Param("sourceID") Long sourceID, @Param("description") String description); +} diff --git a/src/main/java/com/svnlan/home/dao/IoSourceEventDao.java b/src/main/java/com/svnlan/home/dao/IoSourceEventDao.java new file mode 100644 index 0000000..e533ea8 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoSourceEventDao.java @@ -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 list); + List 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 queryFileOperateCount(@Param("timeRange") Pair timeRange); + + List queryVideoFileOperateCount(@Param("timeRange") Pair timeRange); +} diff --git a/src/main/java/com/svnlan/home/dao/IoSourceHistoryDao.java b/src/main/java/com/svnlan/home/dao/IoSourceHistoryDao.java new file mode 100644 index 0000000..2bc2270 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoSourceHistoryDao.java @@ -0,0 +1,33 @@ +package com.svnlan.home.dao; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IoSourceHistory; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.home.vo.IoSourceHistoryVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/24 17:07 + */ +public interface IoSourceHistoryDao { + + int insert(IoSourceHistory ioSourceHistory); + int batchInsert(List list); + List getSourceHistoryBySourceID(Map hashMap); + Long getCountSourceHistoryBySourceID(Map hashMap); + int updateDetail(@Param("id") Long id, @Param("detail") String detail); + int updateVerDetail(IoSourceHistory ioSourceHistory); + int updateVerSource(IoSourceHistory ioSourceHistory); + IoSourceHistory getFileInfoBySourceID(@Param("sourceID") Long sourceID); + CommonSource getHistorySourceInfo(Long id); + int delByID(@Param("id") Long id); + int delBySourceID(@Param("sourceID") Long sourceID); + IoSourceHistory getHistoryInfo(@Param("id") Long id); + IoSourceHistory getHistoryInfoByFileId(@Param("sourceID") Long sourceID, @Param("fileID") Long fileID); + int updateSize(@Param("id") Long id, @Param("size") Long size, @Param("detail") String detail); +} diff --git a/src/main/java/com/svnlan/home/dao/IoSourceMetaDao.java b/src/main/java/com/svnlan/home/dao/IoSourceMetaDao.java new file mode 100644 index 0000000..a6faedc --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoSourceMetaDao.java @@ -0,0 +1,27 @@ +package com.svnlan.home.dao; + +import com.svnlan.home.domain.IOSourceMeta; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/13 16:01 + */ +public interface IoSourceMetaDao { + + int delMetaBySourceID(@Param("sourceID") Long sourceID, @Param("list")List list); + + int delMetaBySourceIDList(@Param("sourceIdList") List sourceIdList, @Param("list")List list); + + int batchInsert(List list); + int insert(IOSourceMeta iOSourceMeta); + List getSourceMetaListBySourceID(@Param("sourceID") Long sourceID, @Param("list")List list); + IOSourceMeta getSourceMetaVoBySourceID(@Param("sourceID") Long sourceID, @Param("key")String key); + List getSourceMetaListByParam(@Param("sourceIdList") List sourceIdList, @Param("list")List list); + int updateMetaByKey(@Param("sourceID") Long sourceID, @Param("key") String key, @Param("desc") String desc); + String getValueMetaByKey(@Param("sourceID") Long sourceID, @Param("key") String key); + String getSourceIDMetaByKey(@Param("value") String value, @Param("key") String key); +} diff --git a/src/main/java/com/svnlan/home/dao/IoSourceRecycleDao.java b/src/main/java/com/svnlan/home/dao/IoSourceRecycleDao.java new file mode 100644 index 0000000..40615f7 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/IoSourceRecycleDao.java @@ -0,0 +1,21 @@ +package com.svnlan.home.dao; + +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.domain.IoSourceRecycle; +import com.svnlan.home.dto.SourceOpDto; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/18 16:44 + */ +public interface IoSourceRecycleDao { + + int insert(IoSourceRecycle ioSourceRecycle); + int batchInsert(List list); + int deleteUserRecycle(@Param("userID")Long userID, @Param("targetType") Integer targetType, @Param("list") List list); + List getUserRecycleBinList(Long userID); +} diff --git a/src/main/java/com/svnlan/home/dao/LogScheduleDao.java b/src/main/java/com/svnlan/home/dao/LogScheduleDao.java new file mode 100644 index 0000000..6415a48 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/LogScheduleDao.java @@ -0,0 +1,35 @@ +package com.svnlan.home.dao; + +import com.svnlan.home.domain.LogSchedule; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.Map; + +/** + * 功能描述: + * + * @author: + * @date: + */ +public interface LogScheduleDao { + /** + * 功能描述: 添加日志 + * + * @param record + * @return int + */ + int insert(LogSchedule record); + + int updateByPrimaryKey(LogSchedule record); + + +// int updateLogSuccess(@Param("logScheduleId") Long logScheduleId, @Param("state") String state, @Param("remark") String remark); + + LogSchedule getLogScheduleInfo(@Param("commonScheduleId") String scheduleId, @Param("gmtStart") Date date); + + LogSchedule getLogScheduleInfoLock(@Param("commonScheduleId") String scheduleId, @Param("gmtStart") Date date); + + int updateLogSuccess(Map map); + +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/dao/ShareDao.java b/src/main/java/com/svnlan/home/dao/ShareDao.java new file mode 100644 index 0000000..63a78d3 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/ShareDao.java @@ -0,0 +1,41 @@ +package com.svnlan.home.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.svnlan.home.domain.Share; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.home.vo.ShareVo; +import com.svnlan.user.vo.UserVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/3 13:46 + */ +public interface ShareDao extends BaseMapper { + + int insert(Share share); + int update(Share share); + int updateNumView(@Param("shareID") Long shareID, @Param("numView") Integer numView); + int updateNumDownload(@Param("shareID") Long shareID, @Param("numDownload") Integer numDownload); + int delete(Long shareID); + int deleteList(List list); + ShareVo getShare(@Param("sourceID") Long sourceID, @Param("userID") Long userID, @Param("isShareTo") Integer isShareTo, @Param("isLink") Integer isLink); + ShareVo getShareById(Long shareID); + List getShareList(Map map); + List checkUserIsShare(@Param("userID") Long userID); + List getShareByCode(@Param("shareCode") String shareCode); + + HomeExplorerVO getLinkShareInfo(Long sourceID); + List getShareToMeList(Map map); + List getLinkShareList(Map map); + + List getSelectUserListByParam(Map map); + List getNotGroupUserListByParam(Map map); + List getShareByIdList(List list); + + void updateStatus(@Param("operateType") Integer operateType,@Param("ids") List ids); +} diff --git a/src/main/java/com/svnlan/home/dao/ShareToDao.java b/src/main/java/com/svnlan/home/dao/ShareToDao.java new file mode 100644 index 0000000..ee1abc7 --- /dev/null +++ b/src/main/java/com/svnlan/home/dao/ShareToDao.java @@ -0,0 +1,18 @@ +package com.svnlan.home.dao; + +import com.svnlan.home.domain.ShareTo; +import com.svnlan.home.vo.ShareToVo; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/8 13:11 + */ +public interface ShareToDao { + int batchInsert(List list); + int delete(Long shareID); + int deleteList(List list); + List getShareToList(Long shareID); +} diff --git a/src/main/java/com/svnlan/home/domain/CloudFile.java b/src/main/java/com/svnlan/home/domain/CloudFile.java new file mode 100644 index 0000000..6949f8a --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/CloudFile.java @@ -0,0 +1,354 @@ +package com.svnlan.home.domain; + +import java.util.Date; + +/** + * @Author: + * @Description: + */ +public class CloudFile { + private Long fileId; + private String fileName; + private String filePath; + private String filePathPre; + private Long directoryId; + private String directoryName; + private Long fileSize; + private String suffix; + private Date gmtCreate; + private Integer isM3u8; + private Integer appPreview; + private String previewUrl; + private String appPreviewUrl; + private String approvalState; + private Integer playLength; + private String directoryState; + private String thumb; + private Long userId; + private Long deleteId; + private String sourceType; + private Long busId; + private Long fkFileId; + private Integer isCamera; + private Integer isReview; + private String resolution; + private String checksum; + private String h264Path; + private Date gmtModified; + private String description; + + private Integer isDefault; + private String sequence; + private Integer subDirectoryCount; + private Integer isDirectory; + private Integer isCommon; + private Long commonSourceId; + private Long commonSourceCloudId; + private Long cloudUserId; + + private Integer isH264Preview; + + public Long getCloudUserId() { + return cloudUserId; + } + + public void setCloudUserId(Long cloudUserId) { + this.cloudUserId = cloudUserId; + } + + public Long getCommonSourceCloudId() { + return commonSourceCloudId; + } + + public void setCommonSourceCloudId(Long commonSourceCloudId) { + this.commonSourceCloudId = commonSourceCloudId; + } + + public Long getCommonSourceId() { + return commonSourceId; + } + + public void setCommonSourceId(Long commonSourceId) { + this.commonSourceId = commonSourceId; + } + + public Integer getIsCommon() { + return isCommon; + } + + public void setIsCommon(Integer isCommon) { + this.isCommon = isCommon; + } + + public Long getFileId() { + return fileId; + } + + public void setFileId(Long fileId) { + this.fileId = fileId; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Long getDirectoryId() { + return directoryId; + } + + public void setDirectoryId(Long directoryId) { + this.directoryId = directoryId; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFilePathPre() { + return filePathPre; + } + + public void setFilePathPre(String filePathPre) { + this.filePathPre = filePathPre; + } + + public String getDirectoryName() { + return directoryName; + } + + public void setDirectoryName(String directoryName) { + this.directoryName = directoryName; + } + + public Long getFileSize() { + return fileSize; + } + + public void setFileSize(Long fileSize) { + this.fileSize = fileSize; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public String getAppPreviewUrl() { + return appPreviewUrl; + } + + public void setAppPreviewUrl(String appPreviewUrl) { + this.appPreviewUrl = appPreviewUrl; + } + + public String getPreviewUrl() { + return previewUrl; + } + + public void setPreviewUrl(String previewUrl) { + this.previewUrl = previewUrl; + } + + public Integer getAppPreview() { + return appPreview; + } + + public void setAppPreview(Integer appPreview) { + this.appPreview = appPreview; + } + + public Integer getIsM3u8() { + return isM3u8; + } + + public void setIsM3u8(Integer isM3u8) { + this.isM3u8 = isM3u8; + } + + public String getApprovalState() { + return approvalState; + } + + public void setApprovalState(String approvalState) { + this.approvalState = approvalState; + } + + public Integer getPlayLength() { + return playLength; + } + + public void setPlayLength(Integer playLength) { + this.playLength = playLength; + } + + public String getDirectoryState() { + return directoryState; + } + + public void setDirectoryState(String directoryState) { + this.directoryState = directoryState; + } + + public String getThumb() { + return thumb; + } + + public void setThumb(String thumb) { + this.thumb = thumb; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getDeleteId() { + return deleteId; + } + + public void setDeleteId(Long deleteId) { + this.deleteId = deleteId; + } + + public String getSourceType() { + return sourceType; + } + + public void setSourceType(String sourceType) { + this.sourceType = sourceType; + } + + public Long getBusId() { + return busId; + } + + public void setBusId(Long busId) { + this.busId = busId; + } + + public Long getFkFileId() { + return fkFileId; + } + + public void setFkFileId(Long fkFileId) { + this.fkFileId = fkFileId; + } + + public Integer getIsCamera() { + return isCamera; + } + + public void setIsCamera(Integer isCamera) { + this.isCamera = isCamera; + } + + public Integer getIsReview() { + return isReview; + } + + public void setIsReview(Integer isReview) { + this.isReview = isReview; + } + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } + + public String getH264Path() { + return h264Path; + } + + public void setH264Path(String h264Path) { + this.h264Path = h264Path; + } + + public Date getGmtModified() { + return gmtModified; + } + + public void setGmtModified(Date gmtModified) { + this.gmtModified = gmtModified; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Integer getIsDefault() { + return isDefault; + } + + public void setIsDefault(Integer isDefault) { + this.isDefault = isDefault; + } + + public String getSequence() { + return sequence; + } + + public void setSequence(String sequence) { + this.sequence = sequence; + } + + public Integer getSubDirectoryCount() { + return subDirectoryCount; + } + + public void setSubDirectoryCount(Integer subDirectoryCount) { + this.subDirectoryCount = subDirectoryCount; + } + + public Integer getIsDirectory() { + return isDirectory; + } + + public void setIsDirectory(Integer isDirectory) { + this.isDirectory = isDirectory; + } + + public Integer getIsH264Preview() { + return isH264Preview; + } + + public void setIsH264Preview(Integer isH264Preview) { + this.isH264Preview = isH264Preview; + } +} diff --git a/src/main/java/com/svnlan/home/domain/Comment.java b/src/main/java/com/svnlan/home/domain/Comment.java new file mode 100644 index 0000000..7dfcea4 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/Comment.java @@ -0,0 +1,33 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/1 14:17 + */ +@Data +public class Comment { + /**评论id */ + private Long commentID; + /** 该评论上级ID */ + private Long pid; + /** 评论用户id */ + private Long userID; + /** 评论对象类型1分享2文件3文章4...... */ + private Integer targetType; + /** 评论对象id */ + private Long targetID; + /** 评论内容 */ + private String content; + /** 点赞统计 */ + private Integer praiseCount; + /** 评论统计 */ + private Integer commentCount; + /** 状态 1正常 2异常 3其他 */ + private Integer status; + private Long modifyTime; + private Long createTime; + +} diff --git a/src/main/java/com/svnlan/home/domain/CommonFile.java b/src/main/java/com/svnlan/home/domain/CommonFile.java new file mode 100644 index 0000000..7ba5edd --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/CommonFile.java @@ -0,0 +1,45 @@ +package com.svnlan.home.domain; + +/** + * @Author: + * @Description: + * @Date: + */ +public class CommonFile { + private String name; + private String path; + private Boolean isDirectory; + + public CommonFile() { + } + + public CommonFile(String name, String path, Boolean isDirectory) { + this.name = name; + this.path = path; + this.isDirectory = isDirectory; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public Boolean getDirectory() { + return isDirectory; + } + + public void setDirectory(Boolean directory) { + isDirectory = directory; + } +} diff --git a/src/main/java/com/svnlan/home/domain/CommonLabel.java b/src/main/java/com/svnlan/home/domain/CommonLabel.java new file mode 100644 index 0000000..b52fcbb --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/CommonLabel.java @@ -0,0 +1,25 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/14 17:22 + */ +@Data +public class CommonLabel { + + private Long labelId; + private Long userID; + private String labelName; + private String labelEnName; + private String enNameSimple; + private Integer status; + private Long createTime; + private Long modifyTime; + private String style; + private Integer sort; + private Integer tagType; + +} diff --git a/src/main/java/com/svnlan/home/domain/CommonSchedule.java b/src/main/java/com/svnlan/home/domain/CommonSchedule.java new file mode 100644 index 0000000..7c030d3 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/CommonSchedule.java @@ -0,0 +1,63 @@ +package com.svnlan.home.domain; + +import java.util.Date; + +public class CommonSchedule { + /** + * 定时任务标识 + */ + private String commonScheduleId; + + /** + * 定时任务名称 + */ + private String scheduleName; + + /** + * 任务重置时间 + */ + private Date gmtModified; + + private Integer frequency; + + public Integer getFrequency() { + return frequency; + } + + public void setFrequency(Integer frequency) { + this.frequency = frequency; + } + + public String getCommonScheduleId() { + return commonScheduleId; + } + + public void setCommonScheduleId(String commonScheduleId) { + this.commonScheduleId = commonScheduleId == null ? null : commonScheduleId.trim(); + } + + public String getScheduleName() { + return scheduleName; + } + + public void setScheduleName(String scheduleName) { + this.scheduleName = scheduleName == null ? null : scheduleName.trim(); + } + + public Date getGmtModified() { + return gmtModified; + } + + public void setGmtModified(Date gmtModified) { + this.gmtModified = gmtModified; + } + + @Override + public String toString() { + return "CommonSchedule{" + + "commonScheduleId='" + commonScheduleId + '\'' + + ", scheduleName='" + scheduleName + '\'' + + ", gmtModified=" + gmtModified + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/domain/CommonSource.java b/src/main/java/com/svnlan/home/domain/CommonSource.java new file mode 100644 index 0000000..68d5ff6 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/CommonSource.java @@ -0,0 +1,527 @@ +package com.svnlan.home.domain; + + +import lombok.ToString; + +@ToString +public class CommonSource { + + private Long groupID; + private Long sourceID; + private Long fileID; + + private String hashMd5; + + private String path; + + private String name; + + private String fileType; + + private Long size; + + private Integer isPreview; + + private Integer isM3u8; + + private String previewUrl; + + private Integer appPreview; + + private String appPreviewUrl; + + private String thumb; + + private Integer sourceLength; + + private Long userID; + + private Integer sourceType; + + private String approvalState; + + private Long commonPicClassifyId; + + // private String sourcePathPre; + + private String classifyType; + + private Long fkCommonSourceId; + + private Long sourceDeleteId; + + private Long newCommonSourceId; + + private String downloadUrl; + + private String resolution; + + //视频转h264的路径 + private String h264Path; + //视频转h264是否成功, 0未成功,1成功,2失败 + private Integer isH264Preview; + + private Long tempCommonSourceId; + private String docPreviewUrl; + private Long parentID; + private String parentLevel; + private String value; + private Integer isFolder; + /** 文档所属类型 (0-sys,1-user,2-group 3-资讯)*/ + private Integer targetType; + private String sourceName; + private String requestRootUrl; + + private String opType; + private Long createTime; + private String domain; + private String isEdit; + private String yzViewData; + private String yzEditData; + private String token; + private Integer type; + private Integer needHashMd5; + private String pdfPath; + private Long convertSize; + private Long thumbSize; + private Long fileConvertSize; + private Long fileThumbSize; + private String frame; + //合并文件成功与否 + private Boolean checkMerge; + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Boolean getCheckMerge() { + return checkMerge; + } + + public void setCheckMerge(Boolean checkMerge) { + this.checkMerge = checkMerge; + } + + public String getFrame() { + return frame; + } + + public void setFrame(String frame) { + this.frame = frame; + } + + public Long getFileConvertSize() { + return fileConvertSize; + } + + public void setFileConvertSize(Long fileConvertSize) { + this.fileConvertSize = fileConvertSize; + } + + public Long getFileThumbSize() { + return fileThumbSize; + } + + public void setFileThumbSize(Long fileThumbSize) { + this.fileThumbSize = fileThumbSize; + } + + public Long getConvertSize() { + return convertSize; + } + + public void setConvertSize(Long convertSize) { + this.convertSize = convertSize; + } + + public Long getThumbSize() { + return thumbSize; + } + + public void setThumbSize(Long thumbSize) { + this.thumbSize = thumbSize; + } + + public String getPdfPath() { + return pdfPath; + } + + public void setPdfPath(String pdfPath) { + this.pdfPath = pdfPath; + } + + private Integer canShare; + + public Integer getCanShare() { + return canShare; + } + + public void setCanShare(Integer canShare) { + this.canShare = canShare; + } + + public Integer getNeedHashMd5() { + return needHashMd5; + } + + public void setNeedHashMd5(Integer needHashMd5) { + this.needHashMd5 = needHashMd5; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getYzViewData() { + return yzViewData; + } + + public void setYzViewData(String yzViewData) { + this.yzViewData = yzViewData; + } + + public String getYzEditData() { + return yzEditData; + } + + public void setYzEditData(String yzEditData) { + this.yzEditData = yzEditData; + } + + public String getIsEdit() { + return isEdit; + } + + public void setIsEdit(String isEdit) { + this.isEdit = isEdit; + } + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public Long getCreateTime() { + return createTime; + } + + public void setCreateTime(Long createTime) { + this.createTime = createTime; + } + + public String getOpType() { + return opType; + } + + public void setOpType(String opType) { + this.opType = opType; + } + + public String getRequestRootUrl() { + return requestRootUrl; + } + + public void setRequestRootUrl(String requestRootUrl) { + this.requestRootUrl = requestRootUrl; + } + + public String getSourceName() { + return sourceName; + } + + public void setSourceName(String sourceName) { + this.sourceName = sourceName; + } + + public Integer getTargetType() { + return targetType; + } + + public void setTargetType(Integer targetType) { + this.targetType = targetType; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public Integer getIsFolder() { + return isFolder; + } + + public void setIsFolder(Integer isFolder) { + this.isFolder = isFolder; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getHashMd5() { + return hashMd5; + } + + public void setHashMd5(String hashMd5) { + this.hashMd5 = hashMd5; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public Long getParentID() { + return parentID; + } + + public void setParentID(Long parentID) { + this.parentID = parentID; + } + + public String getParentLevel() { + return parentLevel; + } + + public void setParentLevel(String parentLevel) { + this.parentLevel = parentLevel; + } + + public Long getFileID() { + return fileID; + } + + public void setFileID(Long fileID) { + this.fileID = fileID; + } + + public Long getGroupID() { + return groupID; + } + + public void setGroupID(Long groupID) { + this.groupID = groupID; + } + + public String getDocPreviewUrl() { + return docPreviewUrl; + } + + public void setDocPreviewUrl(String docPreviewUrl) { + this.docPreviewUrl = docPreviewUrl; + } + + public Long getTempCommonSourceId() { + return tempCommonSourceId; + } + + public void setTempCommonSourceId(Long tempCommonSourceId) { + this.tempCommonSourceId = tempCommonSourceId; + } + + public String getH264Path() { + return h264Path; + } + + public void setH264Path(String h264Path) { + this.h264Path = h264Path; + } + + public Integer getIsH264Preview() { + return isH264Preview; + } + + public void setIsH264Preview(Integer isH264Preview) { + this.isH264Preview = isH264Preview; + } + + public Integer getIsPreview() { + return isPreview; + } + + public void setIsPreview(Integer isPreview) { + this.isPreview = isPreview; + } + + public Integer getIsM3u8() { + return isM3u8; + } + + public void setIsM3u8(Integer isM3u8) { + this.isM3u8 = isM3u8; + } + + public String getPreviewUrl() { + return previewUrl; + } + + public void setPreviewUrl(String previewUrl) { + this.previewUrl = previewUrl; + } + + public Integer getAppPreview() { + return appPreview; + } + + public void setAppPreview(Integer appPreview) { + this.appPreview = appPreview; + } + + public String getAppPreviewUrl() { + return appPreviewUrl; + } + + public void setAppPreviewUrl(String appPreviewUrl) { + this.appPreviewUrl = appPreviewUrl; + } + + public String getThumb() { + return thumb; + } + + public void setThumb(String thumb) { + this.thumb = thumb; + } + + public Integer getSourceLength() { + return sourceLength; + } + + public void setSourceLength(Integer sourceLength) { + this.sourceLength = sourceLength; + } + + public Long getUserID() { + return userID; + } + + public void setUserID(Long userID) { + this.userID = userID; + } + + public Integer getSourceType() { + return sourceType; + } + + public void setSourceType(Integer sourceType) { + this.sourceType = sourceType; + } + + public String getApprovalState() { + return approvalState; + } + + public void setApprovalState(String approvalState) { + this.approvalState = approvalState; + } + + public Long getCommonPicClassifyId() { + return commonPicClassifyId; + } + + public void setCommonPicClassifyId(Long commonPicClassifyId) { + this.commonPicClassifyId = commonPicClassifyId; + } + + public String getClassifyType() { + return classifyType; + } + + public void setClassifyType(String classifyType) { + this.classifyType = classifyType; + } + + public Long getFkCommonSourceId() { + return fkCommonSourceId; + } + + public void setFkCommonSourceId(Long fkCommonSourceId) { + this.fkCommonSourceId = fkCommonSourceId; + } + + public Long getSourceDeleteId() { + return sourceDeleteId; + } + + public void setSourceDeleteId(Long sourceDeleteId) { + this.sourceDeleteId = sourceDeleteId; + } + + public Long getNewCommonSourceId() { + return newCommonSourceId; + } + + public void setNewCommonSourceId(Long newCommonSourceId) { + this.newCommonSourceId = newCommonSourceId; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/domain/FileHeaderRar.java b/src/main/java/com/svnlan/home/domain/FileHeaderRar.java new file mode 100644 index 0000000..bd51ceb --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/FileHeaderRar.java @@ -0,0 +1,68 @@ +package com.svnlan.home.domain; + +public class FileHeaderRar { + + private String fileNameW; + private Boolean isDirectory; + private Long size; + private Integer index; + private Boolean encrypted; + + public FileHeaderRar(String fileNameW, Boolean isDirectory, Long size) { + this.fileNameW = fileNameW; + this.isDirectory = isDirectory; + this.size = size; + } + public FileHeaderRar(String fileNameW, Boolean isDirectory, Long size, Integer index) { + this.fileNameW = fileNameW; + this.isDirectory = isDirectory; + this.size = size; + this.index = index; + } + public FileHeaderRar(String fileNameW, Boolean isDirectory, Long size, Integer index, Boolean encrypted) { + this.fileNameW = fileNameW; + this.isDirectory = isDirectory; + this.size = size; + this.index = index; + this.encrypted = encrypted; + } + public Boolean getEncrypted() { + return encrypted; + } + + public void setEncrypted(Boolean encrypted) { + this.encrypted = encrypted; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public String getFileNameW() { + return fileNameW; + } + + public void setFileNameW(String fileNameW) { + this.fileNameW = fileNameW; + } + + public Boolean getDirectory() { + return isDirectory; + } + + public void setDirectory(Boolean directory) { + isDirectory = directory; + } +} diff --git a/src/main/java/com/svnlan/home/domain/IOFile.java b/src/main/java/com/svnlan/home/domain/IOFile.java new file mode 100644 index 0000000..765e377 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IOFile.java @@ -0,0 +1,60 @@ +package com.svnlan.home.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/13 15:14 + */ +@Data +@TableName("io_file") +public class IOFile { + @TableId(value = "fileID", type = IdType.AUTO) + private Long fileID; + private String name; + private Long size; + @TableField("ioType") + private Long ioType; + private String path; + @TableField("hashSimple") + private String hashSimple; + @TableField("hashMd5") + private String hashMd5; + @TableField("linkCount") + private Long linkCount; + @TableField("createTime") + private Long createTime; + @TableField("modifyTime") + private Long modifyTime; + @TableField("is_preview") + private Integer isPreview; + @TableField("app_preview") + private Integer appPreview; + @TableField("is_h264_preview") + private Integer isH264Preview; + @TableField("is_m3u8") + private Integer isM3u8; + @TableField("fileName") + private String fileName; + @TableField("convertSize") + private Long convertSize; + @TableField("thumbSize") + private Long thumbSize; + + public static final IOFile NULL = new IOFile(); + + /* + +ALTER TABLE io_file ADD COLUMN `is_preview` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '是否支持预览,0否,1是'; +ALTER TABLE io_file ADD COLUMN `app_preview` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '是否支持APP上的文档预览,主要指doc转成pdf后的html5预览'; +ALTER TABLE io_file ADD COLUMN `is_h264_preview` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '视频转h264是否成功, 0未成功,1成功,2失败'; +ALTER TABLE io_file ADD COLUMN `is_m3u8` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '源文件为视频类型时,表示是否已经切片处理成m3u8格式,0否1是;文档类型(doc,ppt等)时,表示是否转成flash,0否1是'; + + */ + +} diff --git a/src/main/java/com/svnlan/home/domain/IOFileMeta.java b/src/main/java/com/svnlan/home/domain/IOFileMeta.java new file mode 100644 index 0000000..28d20fc --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IOFileMeta.java @@ -0,0 +1,19 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 16:21 + */ +@Data +public class IOFileMeta { + + private Long id; + private Long fileID; + private String key; + private String value; + private Long createTime; + private Long modifyTime; +} diff --git a/src/main/java/com/svnlan/home/domain/IOSource.java b/src/main/java/com/svnlan/home/domain/IOSource.java new file mode 100644 index 0000000..35d0373 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IOSource.java @@ -0,0 +1,157 @@ +package com.svnlan.home.domain; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.svnlan.home.utils.ObjUtil; +import lombok.Data; + +import java.util.Date; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/13 15:17 + */ +@Data +@TableName("io_source") +public class IOSource { + + @TableField(exist = false) + private Long id; + @TableId(value = "sourceID", type = IdType.AUTO) + private Long sourceID; + /** + * id的hash + */ + @TableField(value = "sourceHash") + private String sourceHash; + /** + * 文档所属类型 (0-sys,1-user,2-group) + */ + @TableField(value = "targetType") + private Integer targetType; + /** + * 拥有者对象id + */ + @TableField(value = "targetID") + private Long targetID; + /** + * 创建者id + */ + @TableField(value = "createUser") + private Long createUser; + /** + * 最后修改者 + */ + @TableField(value = "createUser") + private Long modifyUser; + /** + * 是否为文件夹(0否,1是) + */ + @TableField(value = "isFolder") + private Integer isFolder; + /** + * 文件名 + */ + @TableField(value = "name") + private String name; + /** + * 文件扩展名,文件夹则为空 + */ + @TableField(value = "fileType") + private String fileType; + /** + * 父级资源id,为0则为部门或用户根文件夹,添加用户部门时自动新建 + */ + @TableField(value = "parentID") + private Long parentID; + /** + * 父路径id; 例如: ,2,5,10, + */ + @TableField(value = "parentLevel") + private String parentLevel; + @TableField(exist = false) + private String oldSourceLevel; + @TableField(exist = false) + private String oldParentLevel; + @TableField(exist = false) + private Long oldParentID; + /** + * 对应存储资源id,文件夹则该处为0 + */ + @TableField(value = "fileID") + private Long fileID; + /** + * 是否删除(0-正常 1-已删除) + */ + @TableField(value = "isDelete") + private Integer isDelete; + /** + * 占用空间大小 + */ + @TableField(value = "size") + private Long size; + /** + * + */ + @TableField(value = "createTime") + private Long createTime; + /** + * + */ + @TableField(value = "modifyTime") + private Long modifyTime; + /** + * 最后访问时间 + */ + @TableField(value = "viewTime") + private Long viewTime; + /** + * 是否可以分享 1 正常 0 禁止分享 + */ + @TableField(value = "canShare") + private Integer canShare; + @TableField(exist = false) + private Long userID; + @TableField(exist = false) + private Long oldSourceID; + @TableField(exist = false) + private Long groupID; +// @TableField(exist = false) + private Integer type; + @TableField(exist = false) + private String hashMd5; + @TableField(exist = false) + private String icon; + @TableField(exist = false) + private String auth; + @TableField("convertSize") + private Long convertSize; + @TableField("thumbSize") + private Long thumbSize; + @TableField("storageID") + private Integer storageID; + private String namePinyin; + private String namePinyinSimple; + + public IOSource() { + } + + public IOSource(Long sourceID, Long size) { + this.sourceID = sourceID; + this.size = size; + } + + public IOSource(Long targetID, Integer isFolder, String name, Long parentID, String parentLevel) { + this.targetID = this.createUser = this.modifyUser = targetID; + this.isFolder = isFolder; + this.name = name; + this.parentID = parentID; + this.parentLevel = parentLevel; + this.createTime = this.modifyTime = System.currentTimeMillis(); + ObjUtil.initializefield(this); + } +} diff --git a/src/main/java/com/svnlan/home/domain/IOSourceMeta.java b/src/main/java/com/svnlan/home/domain/IOSourceMeta.java new file mode 100644 index 0000000..809472d --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IOSourceMeta.java @@ -0,0 +1,26 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/13 15:58 + */ +@Data +public class IOSourceMeta { + + private Long id; + private Long sourceID; + private Long createTime; + private Long modifyTime; + private String key; + private String value; + + public IOSourceMeta(){} + public IOSourceMeta(Long sourceID, String key, String value){ + this.sourceID = sourceID; + this.key = key; + this.value = value; + } +} diff --git a/src/main/java/com/svnlan/home/domain/IoSourceAuth.java b/src/main/java/com/svnlan/home/domain/IoSourceAuth.java new file mode 100644 index 0000000..47876f3 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IoSourceAuth.java @@ -0,0 +1,30 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/12 13:54 + */ +@Data +public class IoSourceAuth { + + private Long id; + private Long sourceID; + private Integer targetType; + private Long targetID; + private Integer authID; + private Integer authDefine; + private Long createTime; + private Long modifyTime; + + public IoSourceAuth(){} + public IoSourceAuth(Long sourceID,Integer targetType,Long targetID,Integer authID, Integer authDefine){ + this.sourceID = sourceID; + this.targetType = targetType; + this.targetID = targetID; + this.authID = authID; + this.authDefine = authDefine; + } +} diff --git a/src/main/java/com/svnlan/home/domain/IoSourceEvent.java b/src/main/java/com/svnlan/home/domain/IoSourceEvent.java new file mode 100644 index 0000000..c06b986 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IoSourceEvent.java @@ -0,0 +1,29 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/14 11:20 + */ +@Data +public class IoSourceEvent { + + private Long id; + private Long sourceID; + private Long sourceParent; + private Long userID; + private String type; + private String desc; + private Long createTime; + + public IoSourceEvent(){} + public IoSourceEvent(Long sourceID, Long sourceParent, Long userID, String type, String desc){ + this.sourceID = sourceID; + this.userID = userID; + this.sourceParent = sourceParent; + this.type = type; + this.desc = desc; + } +} diff --git a/src/main/java/com/svnlan/home/domain/IoSourceHistory.java b/src/main/java/com/svnlan/home/domain/IoSourceHistory.java new file mode 100644 index 0000000..9dfa671 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IoSourceHistory.java @@ -0,0 +1,38 @@ +package com.svnlan.home.domain; + +import com.svnlan.home.utils.ObjUtil; +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/24 17:07 + */ +@Data +public class IoSourceHistory { + private Long id; + private Long sourceID; + private Long userID; + private Long fileID; + private Long size; + private Long createTime; + private Long modifyTime; + private String detail; + private Long parentID; + private String parentLevel; + private String name; + private Integer targetType; + + public IoSourceHistory(){} + public IoSourceHistory(Long sourceID, Long fileID, Long userID, Long size){ + this.sourceID = sourceID; + this.fileID = fileID; + this.userID = userID; + this.size = size; + this.detail = ""; + } + public IoSourceHistory initializefield() { + ObjUtil.initializefield(this); + return this; + } +} diff --git a/src/main/java/com/svnlan/home/domain/IoSourceRecycle.java b/src/main/java/com/svnlan/home/domain/IoSourceRecycle.java new file mode 100644 index 0000000..30c4b0e --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/IoSourceRecycle.java @@ -0,0 +1,25 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/18 16:44 + */ +@Data +public class IoSourceRecycle { + + private Long id; + /** 文档所属类型 (0-sys,1-user,2-group)*/ + private Integer targetType; + /** 拥有者对象id */ + private Long targetID; + private Long sourceID; + /** 操作者id */ + private Long userID; + /** 文档上层关系;冗余字段,便于统计回收站信息 */ + private String parentLevel; + + +} diff --git a/src/main/java/com/svnlan/home/domain/LogSchedule.java b/src/main/java/com/svnlan/home/domain/LogSchedule.java new file mode 100644 index 0000000..615f8cd --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/LogSchedule.java @@ -0,0 +1,108 @@ +package com.svnlan.home.domain; + +import com.svnlan.home.utils.ObjUtil; + +import java.util.Date; + +/** + * 功能描述:定时任务日志 + * + * @author: + * @date: + */ +public class LogSchedule { + /** + * 任务执行日志主键 + */ + private Long logScheduleId; + + /** + * 定时任务标识 + */ + private String commonScheduleId; + + /** + * 任务执行开始时间 + */ + private Date gmtStart; + + /** + * 任务执行结束时间 + */ + private Date gmtEnd; + + /** + * 状态,0开始,1执行成功,2执行失败 + */ + private String state; + + /** + * 备注,如有执行异常,记录异常信息 + */ + private String remark; + + public Long getLogScheduleId() { + return logScheduleId; + } + + public void setLogScheduleId(Long logScheduleId) { + this.logScheduleId = logScheduleId; + } + + public String getCommonScheduleId() { + return commonScheduleId; + } + + public void setCommonScheduleId(String commonScheduleId) { + this.commonScheduleId = commonScheduleId == null ? null : commonScheduleId.trim(); + } + + public Date getGmtStart() { + return gmtStart; + } + + public void setGmtStart(Date gmtStart) { + this.gmtStart = gmtStart; + } + + public Date getGmtEnd() { + return gmtEnd; + } + + public void setGmtEnd(Date gmtEnd) { + this.gmtEnd = gmtEnd; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state == null ? null : state.trim(); + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark == null ? null : remark.trim(); + } + + public LogSchedule initializefield() { + ObjUtil.initializefield(this); + return this; + } + + @Override + public String toString() { + return "LogSchedule{" + + "logScheduleId=" + logScheduleId + + ", commonScheduleId='" + commonScheduleId + '\'' + + ", gmtStart=" + gmtStart + + ", gmtEnd=" + gmtEnd + + ", state='" + state + '\'' + + ", remark='" + remark + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/domain/ScaleInfo.java b/src/main/java/com/svnlan/home/domain/ScaleInfo.java new file mode 100644 index 0000000..79e56d1 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/ScaleInfo.java @@ -0,0 +1,56 @@ +package com.svnlan.home.domain; + +/** + * @Author: + * @Description: + */ +public class ScaleInfo { + private Double scale; + private Integer w; + private Integer h; + + private String typeString; + + public ScaleInfo(Double scale, String typeString){ + this.scale = scale; + this.typeString = typeString; + } + public ScaleInfo(Integer w, Integer h, String typeString){ + this.w = w; + this.h = h; + this.typeString = typeString; + } + + public Integer getW() { + return w; + } + + public void setW(Integer w) { + this.w = w; + } + + public Integer getH() { + return h; + } + + public void setH(Integer h) { + this.h = h; + } + + public Double getScale() { + return scale; + } + + public void setScale(Double scale) { + this.scale = scale; + } + + public String getTypeString() { + return typeString; + } + + public void setTypeString(String typeString) { + this.typeString = typeString; + } + +} diff --git a/src/main/java/com/svnlan/home/domain/Share.java b/src/main/java/com/svnlan/home/domain/Share.java new file mode 100644 index 0000000..eb6d01f --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/Share.java @@ -0,0 +1,56 @@ +package com.svnlan.home.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/3 13:47 + */ +@TableName("share") +@Data +public class Share { + @TableId(value = "shareID", type = IdType.AUTO) + private Long shareID; + /** 分享标题 */ + private String title; + /** shareid */ + private String shareHash; + /** 分享用户id */ + @TableField("userID") + private Long userID; + /** 用户数据id */ + private Long sourceID; + /** 分享文档路径 */ + private String sourcePath; + /** 分享别名,替代shareHash */ + private String url; + /** 是否外链分享;默认为0 */ + private Integer isLink; + /** + * 状态 1 正常 3 禁止分享 4 取消分享 + */ + private Integer status; + /** 是否为内部分享;默认为0 */ + private Integer isShareTo; + /** 访问密码,为空则无密码 */ + private String password; + /** 到期时间,0-永久生效*/ + private Long timeTo; + /** 预览次数 */ + private Integer numView; + /** 下载次数*/ + private Integer numDownload; + /** json 配置信息;是否可以下载,是否可以上传等*/ + private String options; + /** 创建时间 */ + private Long createTime; + /** 最后修改时间 */ + private Long modifyTime; + + +} diff --git a/src/main/java/com/svnlan/home/domain/ShareTo.java b/src/main/java/com/svnlan/home/domain/ShareTo.java new file mode 100644 index 0000000..70f966f --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/ShareTo.java @@ -0,0 +1,20 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/8 13:11 + */ +@Data +public class ShareTo { + private Long id; + private Long shareID; + private Integer targetType; + private Long targetID; + private Integer authID; + private Integer authDefine; + private Long createTime; + private Long modifyTime; +} diff --git a/src/main/java/com/svnlan/home/domain/UserFav.java b/src/main/java/com/svnlan/home/domain/UserFav.java new file mode 100644 index 0000000..e9fb338 --- /dev/null +++ b/src/main/java/com/svnlan/home/domain/UserFav.java @@ -0,0 +1,39 @@ +package com.svnlan.home.domain; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/20 10:20 + */ +@Data +public class UserFav { + + private Long id; + /** */ + private Long userID; + /** 标签id,收藏则为0 */ + private Integer tagID; + /** 收藏名称 */ + private String name; + /** 收藏路径,tag时则为sourceID */ + private String path; + /** source/path */ + private String type; + private Integer sort; + private Long modifyTime; + private Long createTime; + + public UserFav(){} + public UserFav(Long userID, Integer tagID, String name, String path, String type, Integer sort){ + this.userID = userID; + this.tagID = tagID; + this.path = path; + this.name = name; + this.type = type; + this.sort = sort; + } + + +} diff --git a/src/main/java/com/svnlan/home/dto/AddCloudDirectoryDTO.java b/src/main/java/com/svnlan/home/dto/AddCloudDirectoryDTO.java new file mode 100644 index 0000000..e36e797 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/AddCloudDirectoryDTO.java @@ -0,0 +1,50 @@ +package com.svnlan.home.dto; + +import java.util.List; + +/** + * @Author: + * @Description: + */ +public class AddCloudDirectoryDTO { + + private Long sourceID; + + private String name; + + private String busType; + + private List children; + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/svnlan/home/dto/AddSubCloudDirectoryDTO.java b/src/main/java/com/svnlan/home/dto/AddSubCloudDirectoryDTO.java new file mode 100644 index 0000000..768ae49 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/AddSubCloudDirectoryDTO.java @@ -0,0 +1,31 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +import java.util.List; + + +/** + * @Author: sulijuan + * @Description: + */ +@Data +public class AddSubCloudDirectoryDTO { + + private Long sourceID; + private String name; + private String oldName; + private List children; + private Integer targetType; + private Long targetID; + private Long createUser; + private Long modifyUser; + private Long parentID; + private Long fileID; + private Integer isFolder; + private String fileType; + private String parentLevel; + private Integer storageID; + private String namePinyin; + private String namePinyinSimple; +} diff --git a/src/main/java/com/svnlan/home/dto/CheckFileDTO.java b/src/main/java/com/svnlan/home/dto/CheckFileDTO.java new file mode 100644 index 0000000..dd914a6 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/CheckFileDTO.java @@ -0,0 +1,764 @@ +package com.svnlan.home.dto; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IoSourceAuth; +import com.svnlan.jwt.domain.LoginUser; +import lombok.ToString; + +import java.util.List; + +/** + * @Author: + * @Description: + */ +@ToString +public class CheckFileDTO { + + private List sourceIds; + private String hashMd5; + + private String name; + private String fileName; + + private String busType; + private String sourceLevel; + + private Long size; + private Long fileID; + + private String busTypeCode; + + //视频转h264的路径 + private String h264Path; + //视频转h264是否成功, 0未成功,1成功,2失败 + private Integer isH264Preview; + + private String operation; + private String thumb; + private String resolution; + private Integer isCommon; + private Long sourceID; + private String path; + private String desc; + + private String originHashMd5; + private Integer chunk; + private Integer chunks; + private Double ignoreFileSize; + + private Long busId; + private Long sourceId; + private Long parentID; + private String token; + private Boolean viewSwf; + private LoginUser loginUser; + private List dataArr; + private String type; + private String sourceName; + private String cover; + private Integer getInfo; + private Long userID; + private String finalFolderPath; + private CommonSource commonSource; + private String taskID; + private String uuid; + private String tempFolder; + private String finalFilePath; + private String fileType; + private String temp; + private Integer status; + private String content; + private String pathTo; + private Long sourceIDTo; + private String shareCode; + private String view; + private String suffix; + private Long f; + private Long id; + private String auth; + private List sourceAuthList; + private Boolean directory; + private String fullName; + private String password; + private Integer index; + + private String pUrl; + private Double beginTime; + private Double endTime; + private Integer level = 5; + + /* 视频设置 */ + // 转码后缀 + private String convertSuffix; + // 帧率 + private Integer frameRate; + private List cutList; + // 旋转类型 1 左转 2 右转 + private String rotateType; + private Integer rotate; + // 翻转 1 水平 2 垂直 + private String overturnType; + private String markText ; + private String markUrl; + private String markName; + // 字幕 + private List captionsList; + private String captions; + private String captionsUrl; + // 变速 + private String shifting; + // 变速 + private String volumeShifting; + // 音量 + private String volume; + // 防抖 减震 + // 设置视频的抖动程度以及相机的速度。它接受1-10范围内的整数,值1表示少量抖动,值10表示强烈颤抖。默认值为5。 + private String dampingShakiness; + // 设置检测过程的准确性。它必须是1-15范围内的值。值1表示精度低,值15表示高精度。默认值为15。 + private String dampingAccuracy = "15"; + /** 文档所属类型 (0-sys,1-user,2-group 3-资讯)*/ + private Integer targetType; + private String parentLevel; + + public String getParentLevel() { + return parentLevel; + } + + public void setParentLevel(String parentLevel) { + this.parentLevel = parentLevel; + } + + public Integer getTargetType() { + return targetType; + } + + public void setTargetType(Integer targetType) { + this.targetType = targetType; + } + + public String getVolumeShifting() { + return volumeShifting; + } + + public void setVolumeShifting(String volumeShifting) { + this.volumeShifting = volumeShifting; + } + + public String getCaptionsUrl() { + return captionsUrl; + } + + public void setCaptionsUrl(String captionsUrl) { + this.captionsUrl = captionsUrl; + } + + public Integer getRotate() { + return rotate; + } + + public void setRotate(Integer rotate) { + this.rotate = rotate; + } + + public String getVolume() { + return volume; + } + + public void setVolume(String volume) { + this.volume = volume; + } + + public String getRotateType() { + return rotateType; + } + + public void setRotateType(String rotateType) { + this.rotateType = rotateType; + } + + public String getOverturnType() { + return overturnType; + } + + public void setOverturnType(String overturnType) { + this.overturnType = overturnType; + } + + public String getMarkText() { + return markText; + } + + public void setMarkText(String markText) { + this.markText = markText; + } + + public String getMarkUrl() { + return markUrl; + } + + public void setMarkUrl(String markUrl) { + this.markUrl = markUrl; + } + + public String getMarkName() { + return markName; + } + + public void setMarkName(String markName) { + this.markName = markName; + } + + public List getCaptionsList() { + return captionsList; + } + + public void setCaptionsList(List captionsList) { + this.captionsList = captionsList; + } + + public String getCaptions() { + return captions; + } + + public void setCaptions(String captions) { + this.captions = captions; + } + + public String getShifting() { + return shifting; + } + + public void setShifting(String shifting) { + this.shifting = shifting; + } + + public String getDampingShakiness() { + return dampingShakiness; + } + + public void setDampingShakiness(String dampingShakiness) { + this.dampingShakiness = dampingShakiness; + } + + public String getDampingAccuracy() { + return dampingAccuracy; + } + + public void setDampingAccuracy(String dampingAccuracy) { + this.dampingAccuracy = dampingAccuracy; + } + + public Integer getFrameRate() { + return frameRate; + } + + public void setFrameRate(Integer frameRate) { + this.frameRate = frameRate; + } + + public String getConvertSuffix() { + return convertSuffix; + } + + public void setConvertSuffix(String convertSuffix) { + this.convertSuffix = convertSuffix; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public String getpUrl() { + return pUrl; + } + + public void setpUrl(String pUrl) { + this.pUrl = pUrl; + } + + public Double getBeginTime() { + return beginTime; + } + + public void setBeginTime(Double beginTime) { + this.beginTime = beginTime; + } + + public Double getEndTime() { + return endTime; + } + + public void setEndTime(Double endTime) { + this.endTime = endTime; + } + + public List getCutList() { + return cutList; + } + + public void setCutList(List cutList) { + this.cutList = cutList; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Boolean getDirectory() { + return directory; + } + + public void setDirectory(Boolean directory) { + this.directory = directory; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getSourceAuthList() { + return sourceAuthList; + } + + public void setSourceAuthList(List sourceAuthList) { + this.sourceAuthList = sourceAuthList; + } + + public String getAuth() { + return auth; + } + + public void setAuth(String auth) { + this.auth = auth; + } + + public Long getF() { + return f; + } + + public void setF(Long f) { + this.f = f; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public String getView() { + return view; + } + + public void setView(String view) { + this.view = view; + } + + public String getShareCode() { + return shareCode; + } + + public void setShareCode(String shareCode) { + this.shareCode = shareCode; + } + + public Long getSourceIDTo() { + return sourceIDTo; + } + + public void setSourceIDTo(Long sourceIDTo) { + this.sourceIDTo = sourceIDTo; + } + + public String getPathTo() { + return pathTo; + } + + public void setPathTo(String pathTo) { + this.pathTo = pathTo; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getTemp() { + return temp; + } + + public void setTemp(String temp) { + this.temp = temp; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getTempFolder() { + return tempFolder; + } + + public void setTempFolder(String tempFolder) { + this.tempFolder = tempFolder; + } + + public String getFinalFilePath() { + return finalFilePath; + } + + public void setFinalFilePath(String finalFilePath) { + this.finalFilePath = finalFilePath; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getTaskID() { + return taskID; + } + + public void setTaskID(String taskID) { + this.taskID = taskID; + } + + public CommonSource getCommonSource() { + return commonSource; + } + + public void setCommonSource(CommonSource commonSource) { + this.commonSource = commonSource; + } + + public String getFinalFolderPath() { + return finalFolderPath; + } + + public void setFinalFolderPath(String finalFolderPath) { + this.finalFolderPath = finalFolderPath; + } + + public Long getUserID() { + return userID; + } + + public void setUserID(Long userID) { + this.userID = userID; + } + + public Integer getGetInfo() { + return getInfo; + } + + public void setGetInfo(Integer getInfo) { + this.getInfo = getInfo; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getCover() { + return cover; + } + + public void setCover(String cover) { + this.cover = cover; + } + + public String getSourceName() { + return sourceName; + } + + public void setSourceName(String sourceName) { + this.sourceName = sourceName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getSourceLevel() { + return sourceLevel; + } + + public void setSourceLevel(String sourceLevel) { + this.sourceLevel = sourceLevel; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + public List getDataArr() { + return dataArr; + } + + public void setDataArr(List dataArr) { + this.dataArr = dataArr; + } + + public Long getParentID() { + return parentID; + } + + public void setParentID(Long parentID) { + this.parentID = parentID; + } + + public List getSourceIds() { + return sourceIds; + } + + public void setSourceIds(List sourceIds) { + this.sourceIds = sourceIds; + } + + public Long getBusId() { + return busId; + } + + public void setBusId(Long busId) { + this.busId = busId; + } + + public Long getSourceId() { + return sourceId; + } + + public void setSourceId(Long sourceId) { + this.sourceId = sourceId; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Boolean getViewSwf() { + return viewSwf; + } + + public void setViewSwf(Boolean viewSwf) { + this.viewSwf = viewSwf; + } + + public LoginUser getLoginUser() { + return loginUser; + } + + public void setLoginUser(LoginUser loginUser) { + this.loginUser = loginUser; + } + + public Double getIgnoreFileSize() { + return ignoreFileSize; + } + + public void setIgnoreFileSize(Double ignoreFileSize) { + this.ignoreFileSize = ignoreFileSize; + } + + public Integer getChunks() { + return chunks; + } + + public void setChunks(Integer chunks) { + this.chunks = chunks; + } + + public String getOriginHashMd5() { + return originHashMd5; + } + + public void setOriginHashMd5(String originHashMd5) { + this.originHashMd5 = originHashMd5; + } + + public Integer getChunk() { + return chunk; + } + + public void setChunk(Integer chunk) { + this.chunk = chunk; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getHashMd5() { + return hashMd5; + } + + public void setHashMd5(String hashMd5) { + this.hashMd5 = hashMd5; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getFileID() { + return fileID; + } + + public void setFileID(Long fileID) { + this.fileID = fileID; + } + + public Integer getIsCommon() { + return isCommon; + } + + public void setIsCommon(Integer isCommon) { + this.isCommon = isCommon; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public String getThumb() { + return thumb; + } + + public void setThumb(String thumb) { + this.thumb = thumb; + } + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } + + public String getH264Path() { + return h264Path; + } + + public void setH264Path(String h264Path) { + this.h264Path = h264Path; + } + + public Integer getIsH264Preview() { + return isH264Preview; + } + + public void setIsH264Preview(Integer isH264Preview) { + this.isH264Preview = isH264Preview; + } + + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public String getBusTypeCode() { + return busTypeCode; + } + + public void setBusTypeCode(String busTypeCode) { + this.busTypeCode = busTypeCode; + } + +} diff --git a/src/main/java/com/svnlan/home/dto/CommentDto.java b/src/main/java/com/svnlan/home/dto/CommentDto.java new file mode 100644 index 0000000..376ed9d --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/CommentDto.java @@ -0,0 +1,22 @@ +package com.svnlan.home.dto; + +import com.svnlan.utils.PageQuery; +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/1 14:17 + */ +@Data +public class CommentDto extends PageQuery { + /** 评论对象类型1分享2文件3文章4...... */ + private Integer targetType; + /** 评论对象id */ + private Long targetID; + /** 评论内容 */ + private String content; + private Long idFrom; + private Long pid; + private Long commentID; +} diff --git a/src/main/java/com/svnlan/home/dto/CompressFileDto.java b/src/main/java/com/svnlan/home/dto/CompressFileDto.java new file mode 100644 index 0000000..fe6c927 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/CompressFileDto.java @@ -0,0 +1,18 @@ +package com.svnlan.home.dto; + +import lombok.Data; +import net.sf.sevenzipjbinding.ExtractOperationResult; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/5 10:30 + */ +@Data +public class CompressFileDto { + + /** 1 解压成功 0 解压失败 2 密码错误 */ + private Integer status; + private Boolean success; + private ExtractOperationResult result; +} diff --git a/src/main/java/com/svnlan/home/dto/DingDto.java b/src/main/java/com/svnlan/home/dto/DingDto.java new file mode 100644 index 0000000..d1e6d4b --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/DingDto.java @@ -0,0 +1,16 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/28 14:56 + */ +@Data +public class DingDto { + private String signature; + private String msg_signature; + private String timestamp; + private String nonce; +} diff --git a/src/main/java/com/svnlan/home/dto/ExplorerOperationsDTO.java b/src/main/java/com/svnlan/home/dto/ExplorerOperationsDTO.java new file mode 100644 index 0000000..93c0387 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/ExplorerOperationsDTO.java @@ -0,0 +1,15 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @author KingMgg + * @data 2023/2/7 16:21 + */ +@Data +public class ExplorerOperationsDTO { + String name; + Long fileID; + Long sourceID; + +} diff --git a/src/main/java/com/svnlan/home/dto/ExplorerShareDTO.java b/src/main/java/com/svnlan/home/dto/ExplorerShareDTO.java new file mode 100644 index 0000000..61506de --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/ExplorerShareDTO.java @@ -0,0 +1,63 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @author KingMgg + * @data 2023/2/8 11:45 + */ +@Data +public class ExplorerShareDTO { + /** + * 自增id + */ + Long shareID; + /** + * 是否外链分享;默认为0 + */ + Long isLink; + /** + * 用户数据id + */ + Long sourceID; + /** + * 是否为内部分享;默认为0 + */ + Integer isShareTo; + /** + * 分享标题 + */ + String title; + /** + * 分享文档路径 + */ + String sourcePath; + /** + * 分享别名,替代shareHash + */ + String url; + /** + * shareid + */ + String shareHash; + /** + * 访问密码,为空则无密码 + */ + String password; + /** + * json 配置信息;是否可以下载,是否可以上传等 + */ + Options options; + /** + * 到期时间,0-永久生效 + */ + Long timeTo; + + @Data + public static class Options { + String login; + String preview; + String down; + String downNum; + } +} diff --git a/src/main/java/com/svnlan/home/dto/GetAttachmentDTO.java b/src/main/java/com/svnlan/home/dto/GetAttachmentDTO.java new file mode 100644 index 0000000..6bfd3ce --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/GetAttachmentDTO.java @@ -0,0 +1,175 @@ +package com.svnlan.home.dto; + +import javax.validation.constraints.NotNull; + +/** + * @Author: + * @Description: + */ +public class GetAttachmentDTO { + @NotNull + private Long busId; + @NotNull + private String busType; + + private Long sourceID; + @NotNull + private String key; + private Boolean viewSwf; + private String busTypeCode; + + private Boolean fromWareDown; + + private String attachmentType; + + //用于兼容组合主键的业务 + private String busCode; + private String targetServerNameForOverride; + + //获取word转pdf的文件 + private Integer forwtop = 0; + + private Integer getInfo = 0; + private Integer view ; + + private String s; + private String shareCode; + private String d; + private Long f; + + public Integer getView() { + return view; + } + + public void setView(Integer view) { + this.view = view; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } + + public Long getF() { + return f; + } + + public void setF(Long f) { + this.f = f; + } + + public String getShareCode() { + return shareCode; + } + + public void setShareCode(String shareCode) { + this.shareCode = shareCode; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public String getBusCode() { + return busCode; + } + + public void setBusCode(String busCode) { + this.busCode = busCode; + } + + public String getAttachmentType() { + return attachmentType; + } + + public void setAttachmentType(String attachmentType) { + this.attachmentType = attachmentType; + } + + public Long getBusId() { + return busId; + } + + public void setBusId(Long busId) { + this.busId = busId; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Boolean getViewSwf() { + return viewSwf; + } + + public void setViewSwf(Boolean viewSwf) { + this.viewSwf = viewSwf; + } + + public String getBusTypeCode() { + return busTypeCode; + } + + public void setBusTypeCode(String busTypeCode) { + this.busTypeCode = busTypeCode; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public Boolean getFromWareDown() { + return fromWareDown; + } + + public void setFromWareDown(Boolean fromWareDown) { + this.fromWareDown = fromWareDown; + } + + public String getTargetServerNameForOverride() { + return targetServerNameForOverride; + } + + public void setTargetServerNameForOverride(String targetServerNameForOverride) { + this.targetServerNameForOverride = targetServerNameForOverride; + } + + public Integer getForwtop() { + return forwtop; + } + + public void setForwtop(Integer forwtop) { + this.forwtop = forwtop; + } + + public Integer getGetInfo() { + return getInfo; + } + + public void setGetInfo(Integer getInfo) { + this.getInfo = getInfo; + } +} diff --git a/src/main/java/com/svnlan/home/dto/GetM3u8DTO.java b/src/main/java/com/svnlan/home/dto/GetM3u8DTO.java new file mode 100644 index 0000000..2c00497 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/GetM3u8DTO.java @@ -0,0 +1,54 @@ +package com.svnlan.home.dto; + +/** + * @Author: + * @Description: + * @Date: + */ +public class GetM3u8DTO { + private String token; + private Long sourceID; + private String idType; + private Integer isCamera; + private String idType2; + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public String getIdType() { + return idType; + } + + public void setIdType(String idType) { + this.idType = idType; + } + + public Integer getIsCamera() { + return isCamera; + } + + public void setIsCamera(Integer isCamera) { + this.isCamera = isCamera; + } + + public String getIdType2() { + return idType2; + } + + public void setIdType2(String idType2) { + this.idType2 = idType2; + } +} diff --git a/src/main/java/com/svnlan/home/dto/GetM3u8NewDTO.java b/src/main/java/com/svnlan/home/dto/GetM3u8NewDTO.java new file mode 100644 index 0000000..ca5a17d --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/GetM3u8NewDTO.java @@ -0,0 +1,28 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @Author: + * @Description: + * @Date: + */ +@Data +public class GetM3u8NewDTO { + @NotNull + private String key; + + private Long sourceID; + private String sourceType; + private String idType; + private String idType2; + private Integer isReview; + private Integer isCamera; + private Long busId; + + private Long userId; + private Long f; + +} diff --git a/src/main/java/com/svnlan/home/dto/GetMyM3u8DTO.java b/src/main/java/com/svnlan/home/dto/GetMyM3u8DTO.java new file mode 100644 index 0000000..8e162af --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/GetMyM3u8DTO.java @@ -0,0 +1,18 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2020/9/10 8:51 + */ +@Data +public class GetMyM3u8DTO { + + private String sourceType; + private String sourceID; + private String isCamera; + private String isReview; + private String key; +} diff --git a/src/main/java/com/svnlan/home/dto/HomeExplorerDTO.java b/src/main/java/com/svnlan/home/dto/HomeExplorerDTO.java new file mode 100644 index 0000000..5d82ddd --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/HomeExplorerDTO.java @@ -0,0 +1,85 @@ +package com.svnlan.home.dto; + +import com.svnlan.utils.PageQuery; +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/14 13:35 + */ +@Data +public class HomeExplorerDTO extends PageQuery { + + private Long id; + /** + * 对应存储资源id,文件夹则该处为0 + */ + private Long fileID; + private Long sourceID; + private String keyword; + private Long userID; + /** + * 父级资源id,为0则为部门或用户根文件夹,添加用户部门时自动新建 + */ + private Long parentID; + /** + * 占用空间大小 + */ + private Long usedSize; + /** + * 文件扩展名,文件夹则为空 + */ + private String fileType; + /** + * 父路径id; 例如: ,2,5,10, + */ + private String parentLevel; + /** + * 占用空间大小 最小 + */ + private Double minSize; + /** + * 占用空间大小 最大 + */ + private Double maxSize; + /** + * 创建时间 最小 + */ + private String timeFrom; + /** + * 创建时间 最大 + */ + private String timeTo; + + private String block; + + private Boolean fromType; + private Long tagID; + + /** 排序方式 string 倒序desc 正序asc */ + private String sortType; + /** 排序字段 */ + private String sortField; + private String shareCode; + private Integer isFolder; + + /** 是否禁用浏览 */ + private Integer notDownload; + /** 是否禁用下载 */ + private Integer notView; + private Integer isShareTo; + private Integer isLink; + private String detail; + private String authName; + private Integer authID; + private Long groupID; + private String label; + private String fullName; + private String password; + private Integer index; + private Long repeatSourceID; + private String hashMd5; + private String repeatName; + private Integer checkRecycle; +} diff --git a/src/main/java/com/svnlan/home/dto/HomeSettingDTO.java b/src/main/java/com/svnlan/home/dto/HomeSettingDTO.java new file mode 100644 index 0000000..ff8708f --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/HomeSettingDTO.java @@ -0,0 +1,24 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/20 11:01 + */ +@Data +public class HomeSettingDTO { + + private Long targetID; + private Long createUser; + private Long modifyUser; + private Integer isFolder; + + private String sourceID; + private String key; + private String value; + private String listViewKey; + private String listViewValue; + +} diff --git a/src/main/java/com/svnlan/home/dto/LabelDto.java b/src/main/java/com/svnlan/home/dto/LabelDto.java new file mode 100644 index 0000000..d94e280 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/LabelDto.java @@ -0,0 +1,21 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/2 11:02 + */ +@Data +public class LabelDto { + + private Long labelId; + private Long tagID; + private String labelName; + private String style; + private Integer sort; + private String block; + private String files; + private Integer tagType; +} diff --git a/src/main/java/com/svnlan/home/dto/MarkUrlDto.java b/src/main/java/com/svnlan/home/dto/MarkUrlDto.java new file mode 100644 index 0000000..d89a6d6 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/MarkUrlDto.java @@ -0,0 +1,67 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/15 11:06 + */ +@Data +public class MarkUrlDto { + + private String name; + private String url; + private String position; + private String colorchannelmixer; + private String format; + private String scale; + + public String getColorchannelmixer() { + return colorchannelmixer; + } + + public void setColorchannelmixer(String colorchannelmixer) { + this.colorchannelmixer = colorchannelmixer; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getScale() { + return scale; + } + + public void setScale(String scale) { + this.scale = scale; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } +} diff --git a/src/main/java/com/svnlan/home/dto/SaveUploadDTO.java b/src/main/java/com/svnlan/home/dto/SaveUploadDTO.java new file mode 100644 index 0000000..d0cbd01 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/SaveUploadDTO.java @@ -0,0 +1,195 @@ +package com.svnlan.home.dto; + +import org.springframework.web.multipart.MultipartFile; + +import java.math.BigDecimal; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/14 14:57 + */ +public class SaveUploadDTO { + + //分段文件 + private MultipartFile file; + + //文件md5 + private String hashMd5; + + //当前分段 + private Integer chunk; + + //分段数 + private Integer chunks; + + //文件业务类型 + private String busType; + + private Integer chunkSize; + + private Long userID; + + private BigDecimal score; + + private Long sourceID; + + //缩略图尺寸 + private String thumbSize; + private Integer isCommon; + private Long fileID; + private String path; + + private String overrideName; + private String content; + private Double ignoreFileSize; + + private Boolean pushMsgFlag; //是否推送消息 boolean 可选。不传默认为否 + private String taskID; + + public String getTaskID() { + return taskID; + } + + public void setTaskID(String taskID) { + this.taskID = taskID; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Double getIgnoreFileSize() { + return ignoreFileSize; + } + + public void setIgnoreFileSize(Double ignoreFileSize) { + this.ignoreFileSize = ignoreFileSize; + } + + public Boolean getPushMsgFlag() { + return pushMsgFlag; + } + + public void setPushMsgFlag(Boolean pushMsgFlag) { + this.pushMsgFlag = pushMsgFlag; + } + + public Long getFileID() { + return fileID; + } + + public void setFileID(Long fileID) { + this.fileID = fileID; + } +// private Long sourceId; + + + public Integer getIsCommon() { + return isCommon; + } + + public void setIsCommon(Integer isCommon) { + this.isCommon = isCommon; + } + + public MultipartFile getFile() { + return file; + } + + public void setFile(MultipartFile file) { + this.file = file; + } + + public String getHashMd5() { + return hashMd5; + } + + public void setHashMd5(String hashMd5) { + this.hashMd5 = hashMd5; + } + + public Integer getChunks() { + return chunks; + } + + public void setChunks(Integer chunks) { + this.chunks = chunks; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public Integer getChunkSize() { + return chunkSize; + } + + public void setChunkSize(Integer chunkSize) { + this.chunkSize = chunkSize; + } + + public Integer getChunk() { + return chunk; + } + + public void setChunk(Integer chunk) { + this.chunk = chunk; + } + + public Long getUserID() { + return userID; + } + + public void setUserID(Long userID) { + this.userID = userID; + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public String getThumbSize() { + return thumbSize; + } + + public void setThumbSize(String thumbSize) { + this.thumbSize = thumbSize; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public String getOverrideName() { + return overrideName; + } + + public void setOverrideName(String overrideName) { + this.overrideName = overrideName; + } +} diff --git a/src/main/java/com/svnlan/home/dto/ShareDTO.java b/src/main/java/com/svnlan/home/dto/ShareDTO.java new file mode 100644 index 0000000..5a43cb2 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/ShareDTO.java @@ -0,0 +1,47 @@ +package com.svnlan.home.dto; + +import com.svnlan.home.vo.ShareAuthDto; +import com.svnlan.utils.PageQuery; +import lombok.Data; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/3 13:40 + */ +@Data +public class ShareDTO extends PageQuery { + private Long shareID; + private Long userID; + private Long sourceID; + /** 排序方式 string 倒序desc 正序asc */ + private String sortType; + /** 排序字段 */ + private String sortField; + + private String title; + /** 分享文档路径 */ + private String sourcePath; + /** 分享别名,替代shareHash */ + private String url; + /** 是否外链分享;默认为0 */ + private Integer isLink; + /** 是否为内部分享;默认为0 */ + private Integer isShareTo; + /** 访问密码,为空则无密码 */ + private String password; + /** 到期时间,0-永久生效*/ + private Long timeTo = 0L; + /** 预览次数 */ + private Integer numView; + /** 下载次数*/ + private Integer numDownload; + /** json 配置信息;是否可以下载,是否可以上传等*/ + private String options; + private String shareCode; + private String shareHash; + private List authTo; + private String shareIDStr; +} diff --git a/src/main/java/com/svnlan/home/dto/SourceOpDto.java b/src/main/java/com/svnlan/home/dto/SourceOpDto.java new file mode 100644 index 0000000..30afb67 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/SourceOpDto.java @@ -0,0 +1,23 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/18 10:05 + */ +@Data +public class SourceOpDto { + private Long id; + private Long favID; + private Long sourceID; + private Long parentID; + private String type; + private String parentLevel; + private String name; + private String oldName; + private String path; + private String namePinyin; + private String namePinyinSimple; +} diff --git a/src/main/java/com/svnlan/home/dto/UploadDTO.java b/src/main/java/com/svnlan/home/dto/UploadDTO.java new file mode 100644 index 0000000..9ec34aa --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/UploadDTO.java @@ -0,0 +1,234 @@ +package com.svnlan.home.dto; + +import lombok.ToString; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * @Author: + * @Description: 上传文件DTO + */ +@ToString +public class UploadDTO { + + //分段文件 + @NotNull + private MultipartFile file; + + //文件md5 + private String hashMd5; + + //当前分段 + private Integer chunk; + + //分段数 + private Integer chunks; + + //文件业务类型 + @NotNull + private String busType; + + private Integer chunkSize; + private Long size; + + private Long userID; + + private BigDecimal score; + + private Long sourceID; + + //缩略图尺寸 + private String thumbSize; + private Integer isCommon; + private Long fileID; + private String path; + + private String overrideName; + private String name; + private String content; + private Double ignoreFileSize; + + private Boolean pushMsgFlag; //是否推送消息 boolean 可选。不传默认为否 + private String ext; + private Boolean hasMark; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public Boolean getHasMark() { + return hasMark; + } + + public void setHasMark(Boolean hasMark) { + this.hasMark = hasMark; + } + + public String getExt() { + return ext; + } + + public void setExt(String ext) { + this.ext = ext; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Double getIgnoreFileSize() { + return ignoreFileSize; + } + + public void setIgnoreFileSize(Double ignoreFileSize) { + this.ignoreFileSize = ignoreFileSize; + } + + public Boolean getPushMsgFlag() { + return pushMsgFlag; + } + + public void setPushMsgFlag(Boolean pushMsgFlag) { + this.pushMsgFlag = pushMsgFlag; + } + + public Long getFileID() { + return fileID; + } + + public void setFileID(Long fileID) { + this.fileID = fileID; + } +// private Long sourceId; + + + public Integer getIsCommon() { + return isCommon; + } + + public void setIsCommon(Integer isCommon) { + this.isCommon = isCommon; + } + + public MultipartFile getFile() { + return file; + } + + public void setFile(MultipartFile file) { + this.file = file; + } + + public String getHashMd5() { + return hashMd5; + } + + public void setHashMd5(String hashMd5) { + this.hashMd5 = hashMd5; + } + + public Integer getChunks() { + return chunks; + } + + public void setChunks(Integer chunks) { + this.chunks = chunks; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public Integer getChunkSize() { + return chunkSize; + } + + public void setChunkSize(Integer chunkSize) { + this.chunkSize = chunkSize; + } + + public Integer getChunk() { + return chunk; + } + + public void setChunk(Integer chunk) { + this.chunk = chunk; + } + + public Long getUserID() { + return userID; + } + + public void setUserID(Long userID) { + this.userID = userID; + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public String getThumbSize() { + return thumbSize; + } + + public void setThumbSize(String thumbSize) { + this.thumbSize = thumbSize; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public String getOverrideName() { + return overrideName; + } + + public void setOverrideName(String overrideName) { + this.overrideName = overrideName; + } + +// public Long getSourceId() { +// return sourceId; +// } +// +// public void setSourceId(Long sourceId) { +// this.sourceId = sourceId; +// } +} diff --git a/src/main/java/com/svnlan/home/dto/UploadStateDTO.java b/src/main/java/com/svnlan/home/dto/UploadStateDTO.java new file mode 100644 index 0000000..1413f74 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/UploadStateDTO.java @@ -0,0 +1,105 @@ +package com.svnlan.home.dto; + +/** + * @Author: + * @Description: 上传过程中信息 + */ +public class UploadStateDTO { + //单个分段成功与否 + private Boolean upState; + + //分段文件是否全部完成 + private Boolean partAllDone; + + //原始文件md5 + private String checksum; + + //临时文件目录 + private String tempPath; + + //分段数 + private Integer chunks; + + //合并文件成功与否 + private Boolean mergeState; + + //业务类型 + private String busType; + + //文件名 + private String fileName; + private String ext; + + public String getExt() { + return ext; + } + + public void setExt(String ext) { + this.ext = ext; + } + + public Boolean getUpState() { + return upState; + } + + public void setUpState(Boolean upState) { + this.upState = upState; + } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } + + public String getTempPath() { + return tempPath; + } + + public void setTempPath(String tempPath) { + this.tempPath = tempPath; + } + + public Boolean getPartAllDone() { + return partAllDone; + } + + public void setPartAllDone(Boolean partAllDone) { + this.partAllDone = partAllDone; + } + + + public Integer getChunks() { + return chunks; + } + + public void setChunks(Integer chunks) { + this.chunks = chunks; + } + + public Boolean getMergeState() { + return mergeState; + } + + public void setMergeState(Boolean mergeState) { + this.mergeState = mergeState; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } +} diff --git a/src/main/java/com/svnlan/home/dto/VideoCommonDto.java b/src/main/java/com/svnlan/home/dto/VideoCommonDto.java new file mode 100644 index 0000000..ae9d4ab --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/VideoCommonDto.java @@ -0,0 +1,337 @@ +package com.svnlan.home.dto; + +import com.svnlan.home.domain.CommonSource; +import lombok.Data; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/17 11:28 + */ +public class VideoCommonDto extends CheckFileDTO{ + + private String pUrl; + private String fileName; + private Double beginTime; + private Double endTime; + private String taskID; + private List cutList; + /** 1 剪切 2 拆分 */ + private String cutType = "1"; + /** 1 分 2 秒 3 帧 */ + private String timeType = "2"; + /** 1 剪辑,2 转码, 3 合并 */ + private String opType = "1"; + private String resolution; + private String convertSuffix; + private Integer frameRate; + private String finalFilePath; + private String videoPathOrg; + private String serverUrl; + private String otherType; + private String crop; + private Integer frame; + /** 封面图片url*/ + private String coverImg; + private String coverName; + private Long length; + private Integer num; + private Integer isFirst = 0; + private String cutTime; + private Integer regeneration; + private String checkName; + private List markTextList; + private List markUrlList; + private String key; + private Integer showPreview; + private String nameSuffix; + private Integer isDown; + private Integer mp4View; + private String audio; + + public String getAudio() { + return audio; + } + + public void setAudio(String audio) { + this.audio = audio; + } + + public Integer getMp4View() { + return mp4View; + } + + public void setMp4View(Integer mp4View) { + this.mp4View = mp4View; + } + + public Integer getIsDown() { + return isDown; + } + + public void setIsDown(Integer isDown) { + this.isDown = isDown; + } + + public String getNameSuffix() { + return nameSuffix; + } + + public void setNameSuffix(String nameSuffix) { + this.nameSuffix = nameSuffix; + } + + public Integer getShowPreview() { + return showPreview; + } + + public void setShowPreview(Integer showPreview) { + this.showPreview = showPreview; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public List getMarkTextList() { + return markTextList; + } + + public void setMarkTextList(List markTextList) { + this.markTextList = markTextList; + } + + public List getMarkUrlList() { + return markUrlList; + } + + public void setMarkUrlList(List markUrlList) { + this.markUrlList = markUrlList; + } + + public String getCheckName() { + return checkName; + } + + public void setCheckName(String checkName) { + this.checkName = checkName; + } + + public Integer getRegeneration() { + return regeneration; + } + + public void setRegeneration(Integer regeneration) { + this.regeneration = regeneration; + } + + public String getCutTime() { + return cutTime; + } + + public void setCutTime(String cutTime) { + this.cutTime = cutTime; + } + + public Integer getIsFirst() { + return isFirst; + } + + public void setIsFirst(Integer isFirst) { + this.isFirst = isFirst; + } + + public Long getLength() { + return length; + } + + public void setLength(Long length) { + this.length = length; + } + + public Integer getNum() { + return num; + } + + public void setNum(Integer num) { + this.num = num; + } + + public String getCoverName() { + return coverName; + } + + public void setCoverName(String coverName) { + this.coverName = coverName; + } + + List convertList; + + public String getCoverImg() { + return coverImg; + } + + public void setCoverImg(String coverImg) { + this.coverImg = coverImg; + } + + public Integer getFrame() { + return frame; + } + + public void setFrame(Integer frame) { + this.frame = frame; + } + + public String getCrop() { + return crop; + } + + public void setCrop(String crop) { + this.crop = crop; + } + + @Override + public String getpUrl() { + return pUrl; + } + + @Override + public void setpUrl(String pUrl) { + this.pUrl = pUrl; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Double getBeginTime() { + return beginTime; + } + + public void setBeginTime(Double beginTime) { + this.beginTime = beginTime; + } + + public Double getEndTime() { + return endTime; + } + + public void setEndTime(Double endTime) { + this.endTime = endTime; + } + + public String getTaskID() { + return taskID; + } + + public void setTaskID(String taskID) { + this.taskID = taskID; + } + + public List getCutList() { + return cutList; + } + + public void setCutList(List cutList) { + this.cutList = cutList; + } + + public String getCutType() { + return cutType; + } + + public void setCutType(String cutType) { + this.cutType = cutType; + } + + public String getTimeType() { + return timeType; + } + + public void setTimeType(String timeType) { + this.timeType = timeType; + } + + public String getOpType() { + return opType; + } + + public void setOpType(String opType) { + this.opType = opType; + } + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } + + public String getConvertSuffix() { + return convertSuffix; + } + + public void setConvertSuffix(String convertSuffix) { + this.convertSuffix = convertSuffix; + } + + public Integer getFrameRate() { + return frameRate; + } + + public void setFrameRate(Integer frameRate) { + this.frameRate = frameRate; + } + + public String getFinalFilePath() { + return finalFilePath; + } + + public void setFinalFilePath(String finalFilePath) { + this.finalFilePath = finalFilePath; + } + + public String getVideoPathOrg() { + return videoPathOrg; + } + + public void setVideoPathOrg(String videoPathOrg) { + this.videoPathOrg = videoPathOrg; + } + + public String getServerUrl() { + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public String getOtherType() { + return otherType; + } + + public void setOtherType(String otherType) { + this.otherType = otherType; + } + + public List getConvertList() { + return convertList; + } + + public void setConvertList(List convertList) { + this.convertList = convertList; + } +} diff --git a/src/main/java/com/svnlan/home/dto/VideoCutDto.java b/src/main/java/com/svnlan/home/dto/VideoCutDto.java new file mode 100644 index 0000000..8cc5baa --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/VideoCutDto.java @@ -0,0 +1,112 @@ +package com.svnlan.home.dto; + + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/18 13:12 + */ +public class VideoCutDto { + + private Double beginTime; + private Double duration; + private String name; + private String path; + private String pUrl; + private String fileName; + private String videoPathOrg; + private String captions; + /** 时长*/ + private Double length; + /** 过渡特效 */ + private String transition; + private String background; + + public String getBackground() { + return background; + } + + public void setBackground(String background) { + this.background = background; + } + + public Double getLength() { + return length; + } + + public void setLength(Double length) { + this.length = length; + } + + public String getTransition() { + return transition; + } + + public void setTransition(String transition) { + this.transition = transition; + } + + public Double getBeginTime() { + return beginTime; + } + + public void setBeginTime(Double beginTime) { + this.beginTime = beginTime; + } + + public Double getDuration() { + return duration; + } + + public void setDuration(Double duration) { + this.duration = duration; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getpUrl() { + return pUrl; + } + + public void setpUrl(String pUrl) { + this.pUrl = pUrl; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getVideoPathOrg() { + return videoPathOrg; + } + + public void setVideoPathOrg(String videoPathOrg) { + this.videoPathOrg = videoPathOrg; + } + + public String getCaptions() { + return captions; + } + + public void setCaptions(String captions) { + this.captions = captions; + } +} diff --git a/src/main/java/com/svnlan/home/dto/YzOfficDto.java b/src/main/java/com/svnlan/home/dto/YzOfficDto.java new file mode 100644 index 0000000..b3c2380 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/YzOfficDto.java @@ -0,0 +1,18 @@ +package com.svnlan.home.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/7 13:41 + */ +@Data +public class YzOfficDto { + + private List userId; + private String fileId; + private String filePath; +} diff --git a/src/main/java/com/svnlan/home/dto/convert/CancelDownloadTaskDTO.java b/src/main/java/com/svnlan/home/dto/convert/CancelDownloadTaskDTO.java new file mode 100644 index 0000000..69a9bf8 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/CancelDownloadTaskDTO.java @@ -0,0 +1,30 @@ +package com.svnlan.home.dto.convert; + +import javax.validation.constraints.NotNull; + +/** + * @Author: + * @Description: + */ +public class CancelDownloadTaskDTO { + @NotNull + private String url; + @NotNull + private String uuid; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/ConvertDTO.java b/src/main/java/com/svnlan/home/dto/convert/ConvertDTO.java new file mode 100644 index 0000000..57278c6 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/ConvertDTO.java @@ -0,0 +1,124 @@ +package com.svnlan.home.dto.convert; + +import com.svnlan.home.enums.BusTypeEnum; + +import javax.validation.constraints.NotNull; + +/** + * @Author: + * @Description: + */ +public class ConvertDTO { + //相关业务主键id + @NotNull + private Long busId; + //业务类型 + @NotNull + private String busType; + + //其他类型,s直播白板,c直播摄像头 + private String otherType; + + private String cdnType; + + private BusTypeEnum busTypeEnum; + + //业务类型 + private String businessType; + //业务ID + private String businessId; + + private String opType; + + private Long userID; + private String domain; + private Integer isNew; + + public Integer getIsNew() { + return isNew; + } + + public void setIsNew(Integer isNew) { + this.isNew = isNew; + } + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public Long getUserID() { + return userID; + } + + public void setUserID(Long userID) { + this.userID = userID; + } + + public BusTypeEnum getBusTypeEnum() { + return busTypeEnum; + } + + public void setBusTypeEnum(BusTypeEnum busTypeEnum) { + this.busTypeEnum = busTypeEnum; + } + + public String getOpType() { + return opType; + } + + public void setOpType(String opType) { + this.opType = opType; + } + + public String getBusinessType() { + return businessType; + } + + public void setBusinessType(String businessType) { + this.businessType = businessType; + } + + public String getBusinessId() { + return businessId; + } + + public void setBusinessId(String businessId) { + this.businessId = businessId; + } + + public Long getBusId() { + return busId; + } + + public void setBusId(Long busId) { + this.busId = busId; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public String getOtherType() { + return otherType; + } + + public void setOtherType(String otherType) { + this.otherType = otherType; + } + + public String getCdnType() { + return cdnType; + } + + public void setCdnType(String cdnType) { + this.cdnType = cdnType; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/H5CallBackDTO.java b/src/main/java/com/svnlan/home/dto/convert/H5CallBackDTO.java new file mode 100644 index 0000000..c7cd455 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/H5CallBackDTO.java @@ -0,0 +1,66 @@ +package com.svnlan.home.dto.convert; + +import org.springframework.web.multipart.MultipartFile; + +/** + * @Author: + * @Description: + */ +public class H5CallBackDTO { + private MultipartFile file; + private Long id; + private String name; + private String arg; + private Integer totalpage; + private Integer isppt2img; + + public MultipartFile getFile() { + return file; + } + + public void setFile(MultipartFile file) { + this.file = file; + } + + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getArg() { + return arg; + } + + public void setArg(String arg) { + this.arg = arg; + } + + public Integer getTotalpage() { + return totalpage; + } + + public void setTotalpage(Integer totalpage) { + this.totalpage = totalpage; + } + + public Integer getIsppt2img() { + return isppt2img; + } + + public void setIsppt2img(Integer isppt2img) { + this.isppt2img = isppt2img; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/HomeworkVideoConvertDTO.java b/src/main/java/com/svnlan/home/dto/convert/HomeworkVideoConvertDTO.java new file mode 100644 index 0000000..8ea0355 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/HomeworkVideoConvertDTO.java @@ -0,0 +1,19 @@ +package com.svnlan.home.dto.convert; + +import java.util.List; + +/** + * @Author: + * @Description: + */ +public class HomeworkVideoConvertDTO { + private List sourceIdList; + + public List getSourceIdList() { + return sourceIdList; + } + + public void setSourceIdList(List sourceIdList) { + this.sourceIdList = sourceIdList; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/KafkaSenderDTO.java b/src/main/java/com/svnlan/home/dto/convert/KafkaSenderDTO.java new file mode 100644 index 0000000..dcd49ee --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/KafkaSenderDTO.java @@ -0,0 +1,40 @@ +package com.svnlan.home.dto.convert; + +import javax.validation.constraints.NotBlank; + +/** + * @Author: + * @Description: + */ +public class KafkaSenderDTO { + @NotBlank + private String key; + @NotBlank + private String topic; + @NotBlank + private String message; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/LiveDownloadDTO.java b/src/main/java/com/svnlan/home/dto/convert/LiveDownloadDTO.java new file mode 100644 index 0000000..80ad459 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/LiveDownloadDTO.java @@ -0,0 +1,72 @@ +package com.svnlan.home.dto.convert; + +/** + * @Author: + * @Description: + */ +public class LiveDownloadDTO { + private Long courseWareId; + private String type; + private String FileUrl; + private Integer platformId; + private Integer schoolId; + private Long userId; + private String cdnType; + + + public Long getCourseWareId() { + return courseWareId; + } + + public void setCourseWareId(Long courseWareId) { + this.courseWareId = courseWareId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getFileUrl() { + return FileUrl; + } + + public void setFileUrl(String fileUrl) { + FileUrl = fileUrl; + } + + public Integer getPlatformId() { + return platformId; + } + + public void setPlatformId(Integer platformId) { + this.platformId = platformId; + } + + public Integer getSchoolId() { + return schoolId; + } + + public void setSchoolId(Integer schoolId) { + this.schoolId = schoolId; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getCdnType() { + return cdnType; + } + + public void setCdnType(String cdnType) { + this.cdnType = cdnType; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/Mp4H264DTO.java b/src/main/java/com/svnlan/home/dto/convert/Mp4H264DTO.java new file mode 100644 index 0000000..4dd8c91 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/Mp4H264DTO.java @@ -0,0 +1,37 @@ +package com.svnlan.home.dto.convert; + +import java.util.List; + +/** + * @Author: + * @Description: + */ +public class Mp4H264DTO { + private List sourceIdList; + private String busType; + private String cardBusType; + + public List getSourceIdList() { + return sourceIdList; + } + + public void setSourceIdList(List sourceIdList) { + this.sourceIdList = sourceIdList; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public String getCardBusType() { + return cardBusType; + } + + public void setCardBusType(String cardBusType) { + this.cardBusType = cardBusType; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/SwfCallBackDTO.java b/src/main/java/com/svnlan/home/dto/convert/SwfCallBackDTO.java new file mode 100644 index 0000000..bba9ef4 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/SwfCallBackDTO.java @@ -0,0 +1,35 @@ +package com.svnlan.home.dto.convert; + +/** + * @Author: + * @Description: + */ +public class SwfCallBackDTO { + private Long id; + private String name; + private String arg; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getArg() { + return arg; + } + + public void setArg(String arg) { + this.arg = arg; + } +} diff --git a/src/main/java/com/svnlan/home/dto/convert/VideoCutDTO.java b/src/main/java/com/svnlan/home/dto/convert/VideoCutDTO.java new file mode 100644 index 0000000..886c700 --- /dev/null +++ b/src/main/java/com/svnlan/home/dto/convert/VideoCutDTO.java @@ -0,0 +1,44 @@ +package com.svnlan.home.dto.convert; + +/** + * @Author: + * @Description: + */ +public class VideoCutDTO { + private Long sourceId; + private Double startTime; + private Double endTime; + private Long courseWareId; + + public Long getSourceId() { + return sourceId; + } + + public void setSourceId(Long sourceId) { + this.sourceId = sourceId; + } + + public Double getStartTime() { + return startTime; + } + + public void setStartTime(Double startTime) { + this.startTime = startTime; + } + + public Double getEndTime() { + return endTime; + } + + public void setEndTime(Double endTime) { + this.endTime = endTime; + } + + public Long getCourseWareId() { + return courseWareId; + } + + public void setCourseWareId(Long courseWareId) { + this.courseWareId = courseWareId; + } +} diff --git a/src/main/java/com/svnlan/home/enums/BusTypeEnum.java b/src/main/java/com/svnlan/home/enums/BusTypeEnum.java new file mode 100644 index 0000000..fdfcbb5 --- /dev/null +++ b/src/main/java/com/svnlan/home/enums/BusTypeEnum.java @@ -0,0 +1,94 @@ +package com.svnlan.home.enums; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 9:21 + */ +public enum BusTypeEnum { + + //图片 + IMAGE(1, "image"), + + CLOUD(2, "cloud"), + //头像 + AVATAR(3, "avatar"), + + ATTACHMENT(4, "attachment"), + + // 资讯图片 + HOMEPAGE_IMAGE(5 ,"homepage_image"), + //资讯附件 + HOMEPAGE_ATTACHMENT(6, "homepage_attachment"), + //资讯视频 + HOMEPAGE_VIDEO(7, "homepage_video"), + // 资讯导入 + BROCHURE_ATTACHMENT(8, "brochure_attachment"), + //主页装扮缩略图 + DESIGN_THUMB(9, "design_thumb"), + //主页装扮logo + DESIGN_LOGO(10, "design_logo"), + ; + + private static Map enumTypeMap = new HashMap<>(); + private static Map enumCodeMap = new HashMap<>(); + + private String busType; + private Integer typeCode; + + BusTypeEnum(Integer typeCode, String busType){ + this.typeCode = typeCode; + this.busType = busType; + } + + + public static BusTypeEnum getFromTypeName(String typeName){ + if (enumTypeMap.containsKey(typeName)){ + return enumTypeMap.get(typeName); + } + for (BusTypeEnum r : BusTypeEnum.values()){ + if (r.getBusType().equals(typeName)){ + enumTypeMap.put(typeName, r); + return r; + } + } + return null; + } + public static BusTypeEnum getFromTypeCode(Integer typeCode){ + if (enumCodeMap.containsKey(typeCode)){ + return enumCodeMap.get(typeCode); + } + for (BusTypeEnum r : BusTypeEnum.values()){ + if (r.getTypeCode().equals(typeCode)){ + enumCodeMap.put(typeCode, r); + return r; + } + } + return null; + } + + // 校验是否是资讯 + public static Boolean checkIsInfoType(String id){ + List typeList = Arrays.asList(HOMEPAGE_IMAGE.getBusType(), HOMEPAGE_ATTACHMENT.getBusType(), HOMEPAGE_VIDEO.getBusType()); + if(typeList.contains(id)) { + return true; + } + return false; + } + + public String getBusType() { + return busType; + } + + public Integer getTypeCode() { + return typeCode; + } + public String getTypeCodeString() { + return typeCode.toString(); + } +} diff --git a/src/main/java/com/svnlan/home/enums/CloudOperateEnum.java b/src/main/java/com/svnlan/home/enums/CloudOperateEnum.java new file mode 100644 index 0000000..c9b9e5f --- /dev/null +++ b/src/main/java/com/svnlan/home/enums/CloudOperateEnum.java @@ -0,0 +1,60 @@ +package com.svnlan.home.enums; + + +/** + * @Author: + * @Description: + */ +public enum CloudOperateEnum { + RENAME_FILE("rename", "重命名文件"), + FAV_RENAME_FILE("favRename", "收藏夹重命名"), + MOVE_FILE("move", "移动文件"), + COPY_FILE("copy", "复制文件"), + DELETE_FILE("recycle", "删除文件"), + RECYCLE_FILE("restore", "还原文件"), + DELETE_BIN("remove", "从回收站删除"), + SHARE_FILE("share", "是否分享文件"), + FAV_FILE("fav", "收藏夹"), + FAV_DEL("delFav", "取消收藏"), + FILE_DESC("desc", "添加描述"), + ADD_TOP("top", "置顶"), + CANCEL_TOP("cancelTop", "置顶"), + MAKE_FILE("mkfile", "新建文件"), + DELETE_BIN_ALL("removeAll", "彻底删除回收站所有"), + RECYCLE_FILE_ALL("restoreAll", "还原所有文件"), + FILE_COVER("fileCover", "修改封面"), + FILE_EDIT("editFile", "文件编辑"), + ; + + private String code; + private String operate; + CloudOperateEnum(String code, String operate){ + this.code = code; + this.operate = operate; + } + + public static CloudOperateEnum getOperateEnum(String code) { + for (CloudOperateEnum codeMsg : CloudOperateEnum.values()) { + if (codeMsg.code.equals(code)) { + return codeMsg; + } + } + return null; + } + + public String getOperate() { + return operate; + } + + public void setOperate(String operate) { + this.operate = operate; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/src/main/java/com/svnlan/home/enums/LogScheduleStateEnum.java b/src/main/java/com/svnlan/home/enums/LogScheduleStateEnum.java new file mode 100644 index 0000000..0131ed0 --- /dev/null +++ b/src/main/java/com/svnlan/home/enums/LogScheduleStateEnum.java @@ -0,0 +1,32 @@ +package com.svnlan.home.enums; + +/** + * @Author: + * @Description: + * @Date: + */ +public enum LogScheduleStateEnum { + + BEGIN("0", "开始"), + + SUCCESS("1", "执行成功"), + + FAILURE("2", "执行失败"); + + private String code; + + private String value; + + private LogScheduleStateEnum(String code, String value) { + this.code = code; + this.value = value; + } + + public String getCode() { + return code; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/svnlan/home/enums/UploadEnum.java b/src/main/java/com/svnlan/home/enums/UploadEnum.java new file mode 100644 index 0000000..a8c5caa --- /dev/null +++ b/src/main/java/com/svnlan/home/enums/UploadEnum.java @@ -0,0 +1,28 @@ +package com.svnlan.home.enums; + +/** + * @Author: + * @Description: 上传返回状态enum + */ +public enum UploadEnum { + uploadSuccess(0, "上传成功"), + uploadFailed(1, "上传失败"), + fileEmpty(2, "文件为空"), + fileExists(0, "文件已存在"), + fileNotExists(0, "文件不存在"); + + private Integer code; + private String msg; + UploadEnum(Integer code, String msg){ + this.code = code; + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public Integer getCode() { + return code; + } +} diff --git a/src/main/java/com/svnlan/home/schedule/ConvertSchedule.java b/src/main/java/com/svnlan/home/schedule/ConvertSchedule.java new file mode 100644 index 0000000..2d19b52 --- /dev/null +++ b/src/main/java/com/svnlan/home/schedule/ConvertSchedule.java @@ -0,0 +1,67 @@ +package com.svnlan.home.schedule; + +import com.svnlan.common.LogScheduleStateConstants; +import com.svnlan.home.dao.CommonScheduleDao; +import com.svnlan.home.service.LogScheduleService; +import com.svnlan.home.service.MonitorService; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: + * @Description: + * @Date: + */ +@Component +public class ConvertSchedule { + private static final String VIDEO_CONVERT_TIME = "video_convert_time"; + + @Resource + private LogScheduleService logScheduleService; + + @Resource + CommonScheduleDao commonScheduleDao; + + @Resource + private MonitorService monitorService; + + + //@Scheduled(cron = "0 0/1 * * * ?") + public void videoConvertTime(){ + LogUtil.info("检查转码时长任务开始"); + String remark = ""; + String state = LogScheduleStateConstants.SUCCESS; + //更新前任务时间 + Integer j = commonScheduleDao.updateOperateTime(VIDEO_CONVERT_TIME); + if (j < 1) { + LogUtil.error(VIDEO_CONVERT_TIME + " 检查转码时长 schedule表更新失败"); + return; + } + + Long body2 = logScheduleService.addLog(VIDEO_CONVERT_TIME); + + Map resultMap = new HashMap<>(); + try { + remark = monitorService.videoConvertTime(resultMap); + } catch (Exception e) { + remark = "检查转码时长:" + e.getMessage(); + state = LogScheduleStateConstants.FAILURE; + LogUtil.error(e, ""); + } + LogUtil.info("检查转码时长," + remark + ", " + JsonUtils.beanToJson(resultMap)); + //修改定时任务状态 + Integer body1 = logScheduleService.updateLog(body2, state, remark); + if (body1 != 1) { + LogUtil.error("检查转码时长失败"); + } + } + + + +} diff --git a/src/main/java/com/svnlan/home/schedule/SourceSchedule.java b/src/main/java/com/svnlan/home/schedule/SourceSchedule.java new file mode 100644 index 0000000..a0c20cc --- /dev/null +++ b/src/main/java/com/svnlan/home/schedule/SourceSchedule.java @@ -0,0 +1,65 @@ +package com.svnlan.home.schedule; + +import com.svnlan.common.LogScheduleStateConstants; +import com.svnlan.home.dao.CommonScheduleDao; +import com.svnlan.home.service.LogScheduleService; +import com.svnlan.home.utils.SourceDownUrlUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/15 11:41 + */ +@Component +public class SourceSchedule { + + private static final String CLOUD_DELETE_DOWNLOAD = "cloud_delete_download"; + + @Resource + private LogScheduleService logScheduleService; + + @Resource + CommonScheduleDao commonScheduleDao; + @Resource + SourceDownUrlUtils sourceDownUrlUtils; + + /** + * @Description: 删除下载定时器 + * @params: [] + * @Return: void + * @Modified: + */ + @Scheduled(cron = "${schedule.deleteCloudDownload}") + public void deleteCourseDownload(){ + LogUtil.info("删除下载文件开始"); + String remark = ""; + String state = LogScheduleStateConstants.SUCCESS; + //更新前任务时间 + Integer j = commonScheduleDao.updateOperateTime(CLOUD_DELETE_DOWNLOAD); + if (j < 1) { + LogUtil.error(CLOUD_DELETE_DOWNLOAD + "删除下载文件 schedule表更新失败"); + return; + } + + Long body2 = logScheduleService.addLog(CLOUD_DELETE_DOWNLOAD); + try { + int ret = sourceDownUrlUtils.deleteCommonDownload(); + remark = "删除下载文件,影响" + ret + "条"; + } catch (Exception e) { + remark = "删除下载文件, 失败:" + e.getMessage(); + state = LogScheduleStateConstants.FAILURE; + LogUtil.error(e, "删除下载文件失败"); + } + LogUtil.info("删除下载文件定时器," + remark); + //修改定时任务状态 + Integer body1 = logScheduleService.updateLog(body2, state, remark); + if (body1 != 1) { + LogUtil.error("删除下载文件失败"); + } + } +} diff --git a/src/main/java/com/svnlan/home/service/AuthService.java b/src/main/java/com/svnlan/home/service/AuthService.java new file mode 100644 index 0000000..b9a4a85 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/AuthService.java @@ -0,0 +1,18 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.vo.IoSourceAuthVo; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/11 17:16 + */ +public interface AuthService { + + void setAuth(CheckFileDTO checkFileDTO, LoginUser loginUser); + List getSourceAuth(CheckFileDTO checkFileDTO, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/BusTypeHandleService.java b/src/main/java/com/svnlan/home/service/BusTypeHandleService.java new file mode 100644 index 0000000..3d2ed9f --- /dev/null +++ b/src/main/java/com/svnlan/home/service/BusTypeHandleService.java @@ -0,0 +1,20 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.UploadDTO; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 10:15 + */ +public interface BusTypeHandleService { + + void doForImage(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource); + void doForCloud(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource); + void doForExtraImage(UploadDTO uploadDTO, CommonSource commonSource); + void checkForCloud(CheckFileDTO checkFileDTO, CommonSource commonSource); + + void doForWareAndAttachment(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource); +} diff --git a/src/main/java/com/svnlan/home/service/CommentService.java b/src/main/java/com/svnlan/home/service/CommentService.java new file mode 100644 index 0000000..f076d2d --- /dev/null +++ b/src/main/java/com/svnlan/home/service/CommentService.java @@ -0,0 +1,18 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.Comment; +import com.svnlan.home.dto.CommentDto; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.PageResult; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/1 14:19 + */ +public interface CommentService { + + Comment saveComment(CommentDto dto, LoginUser loginUser); + void delComment(CommentDto dto, LoginUser loginUser); + PageResult getCommentList(CommentDto dto, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/CommonLabelService.java b/src/main/java/com/svnlan/home/service/CommonLabelService.java new file mode 100644 index 0000000..4a083f5 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/CommonLabelService.java @@ -0,0 +1,33 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.LabelDto; +import com.svnlan.home.vo.CommonLabelVo; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.List; +import java.util.Map; + + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/2 10:53 + */ +public interface CommonLabelService { + + void addTag(LabelDto labelDto, LoginUser loginUser); + void editTag(LabelDto labelDto, LoginUser loginUser); + void delTag(LabelDto labelDto, LoginUser loginUser); + List getTagList(LabelDto labelDto, LoginUser loginUser); + void fileTag(LabelDto labelDto, LoginUser loginUser); + + + boolean moveTop(CheckFileDTO labelDto, Map resultMap, LoginUser loginUser); + boolean moveBottom(CheckFileDTO labelDto, Map resultMap, LoginUser loginUser); + + + boolean tagTop(LabelDto labelDto, LoginUser loginUser); + boolean tagBottom(LabelDto labelDto, LoginUser loginUser); + List getInfoLabelList(LabelDto labelDto, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/ConvertFileService.java b/src/main/java/com/svnlan/home/service/ConvertFileService.java new file mode 100644 index 0000000..1e29182 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/ConvertFileService.java @@ -0,0 +1,13 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.vo.CommonSourceVO; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/27 16:04 + */ +public interface ConvertFileService { + void tryToConvertFile(CommonSourceVO commonSourceVO, CommonSource commonSource, String busType); +} diff --git a/src/main/java/com/svnlan/home/service/ExplorerFileService.java b/src/main/java/com/svnlan/home/service/ExplorerFileService.java new file mode 100644 index 0000000..0d8beed --- /dev/null +++ b/src/main/java/com/svnlan/home/service/ExplorerFileService.java @@ -0,0 +1,21 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.utils.CompressFileReader; +import com.svnlan.jwt.domain.LoginUser; + + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/25 14:19 + */ +public interface ExplorerFileService { + + Object unzipList(HomeExplorerDTO homeExp, LoginUser loginUser); + + CompressFileReader.FileNode getFileNode(CommonSource source, String compressKey, CompressFileReader.FileNode fileNode ); + + Boolean checkZipIsEncrypted(HomeExplorerDTO homeExp); +} diff --git a/src/main/java/com/svnlan/home/service/ExplorerOperationsService.java b/src/main/java/com/svnlan/home/service/ExplorerOperationsService.java new file mode 100644 index 0000000..130ad40 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/ExplorerOperationsService.java @@ -0,0 +1,20 @@ +package com.svnlan.home.service; + + +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.Map; + +/** + * @author KingMgg + * @data 2023/2/7 16:13 + */ +public interface ExplorerOperationsService { + + + void initSourcePathLevel(Long sourceID); + + void countSize(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser); + +} diff --git a/src/main/java/com/svnlan/home/service/FavService.java b/src/main/java/com/svnlan/home/service/FavService.java new file mode 100644 index 0000000..1a227de --- /dev/null +++ b/src/main/java/com/svnlan/home/service/FavService.java @@ -0,0 +1,20 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/15 13:30 + */ +public interface FavService { + + boolean moveTop(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser); + boolean moveBottom(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser); + Map getPreviewEditInfo(CheckFileDTO getCloudPreviewDTO); + Map getPreviewRefreshInfo(CheckFileDTO getCloudPreviewDTO); + String getPreviewFileUrl(CheckFileDTO getCloudPreviewDTO); +} diff --git a/src/main/java/com/svnlan/home/service/FileDocConvertService.java b/src/main/java/com/svnlan/home/service/FileDocConvertService.java new file mode 100644 index 0000000..70261e9 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/FileDocConvertService.java @@ -0,0 +1,17 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/28 13:54 + */ +public interface FileDocConvertService { + + Map doc2Convert(CheckFileDTO updateFileDTO, LoginUser loginUser); + boolean taskAction(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/FilePreViewService.java b/src/main/java/com/svnlan/home/service/FilePreViewService.java new file mode 100644 index 0000000..f66d431 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/FilePreViewService.java @@ -0,0 +1,12 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.CheckFileDTO; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/26 16:41 + */ +public interface FilePreViewService { + String getPreviewXml(CheckFileDTO checkFileDTO); +} diff --git a/src/main/java/com/svnlan/home/service/HomeExplorerService.java b/src/main/java/com/svnlan/home/service/HomeExplorerService.java new file mode 100644 index 0000000..8efaed9 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/HomeExplorerService.java @@ -0,0 +1,47 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.dto.HomeSettingDTO; +import com.svnlan.home.vo.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.PageResult; + +import java.util.List; +import java.util.Map; + +/** + * @author KingMgg + * @data 2023/2/6 11:28 + */ +public interface HomeExplorerService { + + /** + * 首页的左侧分类列表 传递parentLevel 这个是子分类 + * + * @return + */ + HomeExplorerResult homeExplorer(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser); + + /** + * 创建文件夹 + * + * @return + */ + IOSource createDir(HomeExplorerVO homeExplorerVO, LoginUser loginUser ); + + + /** + * 获取文件详情 + * + * @return + */ + HomeFileDetailVO getFileDetail(HomeExplorerVO homeExplorerVO); + Boolean folderSetting(HomeSettingDTO homeExplorerVO, LoginUser loginUser ); + PageResult getPathLog(HomeExplorerDTO homeExplorerVO); + + Map systemOpenInfo(); + + HomeExplorerVO getHomeExplorer(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser); + HomeExplorerVO execImgVideoThumb(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/LogScheduleService.java b/src/main/java/com/svnlan/home/service/LogScheduleService.java new file mode 100644 index 0000000..7ed749f --- /dev/null +++ b/src/main/java/com/svnlan/home/service/LogScheduleService.java @@ -0,0 +1,21 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.LogSchedule; + +/** + * 功能描述:定时任务service + * + */ +public interface LogScheduleService { + /** + * 功能描述: 添加定时任务日志 + * + * @param commonScheduleId + * @return Long + */ + Long addLog(String commonScheduleId); + + int updateLog(Long logScheduleId, String state, String remark); + + LogSchedule logScheduleCheckAddTransaction(String scheduleId); +} diff --git a/src/main/java/com/svnlan/home/service/M3u8Service.java b/src/main/java/com/svnlan/home/service/M3u8Service.java new file mode 100644 index 0000000..9287545 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/M3u8Service.java @@ -0,0 +1,20 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.GetM3u8DTO; +import com.svnlan.home.dto.GetM3u8NewDTO; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Author: + * @Description: + */ +public interface M3u8Service { + void getKey(String key, HttpServletResponse response); + + void getM3u8(GetM3u8DTO getM3u8DTO, HttpServletResponse response, HttpServletRequest request); + + String getM3u8WithAuth(GetM3u8NewDTO getM3u8DTO, HttpServletResponse response, HttpServletRequest request, int isApi); + +} diff --git a/src/main/java/com/svnlan/home/service/MonitorService.java b/src/main/java/com/svnlan/home/service/MonitorService.java new file mode 100644 index 0000000..94e4ae2 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/MonitorService.java @@ -0,0 +1,12 @@ +package com.svnlan.home.service; + +import java.util.Map; + +/** + * @Author: + * @Description: + * @Date: + */ +public interface MonitorService { + String videoConvertTime(Map resultMap); +} diff --git a/src/main/java/com/svnlan/home/service/ShareService.java b/src/main/java/com/svnlan/home/service/ShareService.java new file mode 100644 index 0000000..d216b75 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/ShareService.java @@ -0,0 +1,33 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.dto.ShareDTO; +import com.svnlan.home.vo.HomeExplorerResult; +import com.svnlan.home.vo.ShareVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.dto.UserDTO; +import com.svnlan.user.vo.SelectAuthVo; +import com.svnlan.user.vo.UserGroupVo; +import com.svnlan.utils.PageResult; + +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/3 13:33 + */ +public interface ShareService { + + void saveShare(ShareDTO shareDTO, LoginUser loginUser); + void cancelShare(ShareDTO shareDTO, LoginUser loginUser); + ShareVo getShare(ShareDTO shareDTO, LoginUser loginUser); + HomeExplorerResult getShareList(HomeExplorerDTO shareDTO, LoginUser loginUser); + HomeExplorerResult shareToMeList(HomeExplorerDTO shareDTO, LoginUser loginUser); + ShareVo getShareFile(ShareDTO shareDTO, LoginUser loginUser); + HomeExplorerResult getLinkShareList(HomeExplorerDTO shareDTO); + SelectAuthVo userGroupList(HomeExplorerDTO shareDTO, LoginUser loginUser); + Map previewNum(ShareDTO shareDTO); + PageResult getUserList(LoginUser loginUser, UserDTO shareDTO); +} diff --git a/src/main/java/com/svnlan/home/service/SourceFileService.java b/src/main/java/com/svnlan/home/service/SourceFileService.java new file mode 100644 index 0000000..3e7da01 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/SourceFileService.java @@ -0,0 +1,21 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.AddCloudDirectoryDTO; +import com.svnlan.home.dto.AddSubCloudDirectoryDTO; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/7/3 9:40 + */ +public interface SourceFileService { + + List addBatchDirectory(AddCloudDirectoryDTO addCommonPicClassifyDTO, LoginUser loginUser); + + + List getImgList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/SourceHistoryService.java b/src/main/java/com/svnlan/home/service/SourceHistoryService.java new file mode 100644 index 0000000..7ce5328 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/SourceHistoryService.java @@ -0,0 +1,21 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.vo.HomeExplorerResult; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/31 11:28 + */ +public interface SourceHistoryService { + + HomeExplorerResult getSourceHistoryList(HomeExplorerDTO homeExplorerDTO); + void setHistoryDetail(HomeExplorerDTO homeExplorerDTO); + void deleteHistory(HomeExplorerDTO homeExplorerDTO); + void setHistoryRevision(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser); + List parentSourceList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/UploadService.java b/src/main/java/com/svnlan/home/service/UploadService.java new file mode 100644 index 0000000..d0096fe --- /dev/null +++ b/src/main/java/com/svnlan/home/service/UploadService.java @@ -0,0 +1,74 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.GetAttachmentDTO; +import com.svnlan.home.dto.SaveUploadDTO; +import com.svnlan.home.dto.UploadDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.vo.CommonSourceVO; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.jwt.domain.LoginUser; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 9:07 + */ +public interface UploadService { + + CommonSourceVO upload(UploadDTO uploadDTO, LoginUser loginUser, CommonSource commonSource); + + CommonSourceVO fileUpload(UploadDTO uploadDTO, LoginUser loginUser, CommonSource commonSource); + + Map checkFile(CheckFileDTO checkFileDTO, LoginUser loginUser); + + Map checkFileReplace(CheckFileDTO checkFileDTO, LoginUser loginUser); + + Map checkChunk(CheckFileDTO checkChunkDTO, LoginUser loginUser); + + String returnSource(CheckFileDTO checkChunkDTO, String passedFileName, HttpServletResponse response); + + Map getPreviewInfo(CheckFileDTO getCloudPreviewDTO); + + boolean updateFile(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser); + + String getAttachment(HttpServletResponse response, GetAttachmentDTO getAttachmentDTO, String passedFileName, Map resultMap); + + CommonSource fileSave(SaveUploadDTO uploadDTO, LoginUser loginUser); + + Map getFileContent(CheckFileDTO getCloudPreviewDTO); + + Map getFileContentBlob(CheckFileDTO getCloudPreviewDTO); + + Map getFileContentByte(CheckFileDTO getCloudPreviewDTO); + + /** + * 1. 上传前的操作 + */ + HomeExplorerVO beforeUpload(CommonSource commonSource, UploadDTO uploadDTO, LoginUser loginUser, BusTypeEnum busTypeEnum); + + /** + * 2. 验证文件名及后缀 + */ + void validateUploadFileName(String fileName); + + /** + * 3. 根据业务类型做处理 + */ + void doByBusType(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource, BusTypeEnum busTypeEnum, HomeExplorerVO disk); + + /** + * 4. 资源相关信息写入数据库 + */ + Long recordSourceDataToDb(CommonSource commonSource, UploadDTO uploadDTO, BusTypeEnum busTypeEnum); + + /** + * 5. 转码操作 + */ + void tryToConvertFile(CommonSourceVO commonSourceVO, CommonSource commonSource, String busType); +} diff --git a/src/main/java/com/svnlan/home/service/UploadZipService.java b/src/main/java/com/svnlan/home/service/UploadZipService.java new file mode 100644 index 0000000..568e469 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/UploadZipService.java @@ -0,0 +1,21 @@ +package com.svnlan.home.service; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/9 15:16 + */ +public interface UploadZipService { + + boolean zipFile(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser); + boolean taskAction(CheckFileDTO checkFileDTO, Map resultMap); + List unZip(CheckFileDTO checkFileDTO, LoginUser loginUser); + boolean taskActionUnZip(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/VideoGetService.java b/src/main/java/com/svnlan/home/service/VideoGetService.java new file mode 100644 index 0000000..3b15b51 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/VideoGetService.java @@ -0,0 +1,30 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.jwt.domain.LoginUser; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/17 11:29 + */ +public interface VideoGetService { + + List getVideoShearListAll(VideoCommonDto videoCommonDto); + boolean checkImgCut(VideoCommonDto videoCommonDto); + List getVideoShearList(VideoCommonDto videoCommonDto); + + Map cutVideo(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map cutVideoSave(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map splitVideoSave(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map mergeVideoSave(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map convertVideoSave(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map videoConfigSave(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map cutVideoImg(VideoCommonDto videoCommonDto, LoginUser loginUser); + Map copyAudio(VideoCommonDto videoCommonDto, LoginUser loginUser); + String getVideoShearImg(HttpServletResponse response, VideoCommonDto videoCommonDto, String passedFileName, Map resultMap); +} diff --git a/src/main/java/com/svnlan/home/service/VideoImagesService.java b/src/main/java/com/svnlan/home/service/VideoImagesService.java new file mode 100644 index 0000000..71e3015 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/VideoImagesService.java @@ -0,0 +1,18 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.jwt.domain.LoginUser; + +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/8 9:17 + */ +public interface VideoImagesService { + + Map imagesToVideo(VideoCommonDto videoCommonDto, LoginUser loginUser); + boolean taskAction(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser); +} diff --git a/src/main/java/com/svnlan/home/service/YzService.java b/src/main/java/com/svnlan/home/service/YzService.java new file mode 100644 index 0000000..5c7b4b7 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/YzService.java @@ -0,0 +1,14 @@ +package com.svnlan.home.service; + +import com.svnlan.home.dto.YzOfficDto; +import org.springframework.web.multipart.MultipartFile; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/10 16:31 + */ +public interface YzService { + + void yzCallback(YzOfficDto officDto, MultipartFile file); +} diff --git a/src/main/java/com/svnlan/home/service/impl/AuthServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/AuthServiceImpl.java new file mode 100644 index 0000000..ac7d177 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/AuthServiceImpl.java @@ -0,0 +1,129 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceAuthDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IoSourceAuth; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.service.AuthService; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.UserAuthTool; +import com.svnlan.home.vo.IoSourceAuthVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.dao.UserGroupDao; +import com.svnlan.user.vo.UserGroupVo; +import com.svnlan.user.vo.UserVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/11 17:17 + */ +@Service +public class AuthServiceImpl implements AuthService { + + @Resource + IoSourceAuthDao ioSourceAuthDao; + @Resource + UserGroupDao userGroupDao; + @Resource + UserAuthTool userAuthTool; + @Resource + FileOptionTool fileOptionTool; + + @Override + public void setAuth(CheckFileDTO checkFileDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getSourceID()) || checkFileDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List sourceAuthList = checkFileDTO.getSourceAuthList(); + + if (!CollectionUtils.isEmpty(sourceAuthList)) { + for (IoSourceAuth auth : sourceAuthList) { + if (ObjectUtils.isEmpty(auth.getTargetType()) + || ObjectUtils.isEmpty(auth.getTargetID())) { + LogUtil.error("setAuth 参数错误 param=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(auth.getAuthID()) + && ObjectUtils.isEmpty(auth.getAuthDefine())) { + LogUtil.error("setAuth 参数错误 param=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + auth.setAuthID(ObjectUtils.isEmpty(auth.getAuthID()) ? 0 : auth.getAuthID()); + auth.setSourceID(checkFileDTO.getSourceID()); + auth.setAuthDefine(ObjectUtils.isEmpty(auth.getAuthDefine()) ? -1 : auth.getAuthDefine()); + } + } + + CommonSource commonSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), "14", commonSource.getTargetType()); + + ioSourceAuthDao.deleteSourceAuth(checkFileDTO.getSourceID()); + + if (!CollectionUtils.isEmpty(sourceAuthList)){ + try { + ioSourceAuthDao.batchInsert(sourceAuthList); + }catch (Exception e){ + LogUtil.error(e, "setAuth error"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + } + + } + + @Override + public List getSourceAuth(CheckFileDTO checkFileDTO, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getSourceID()) || checkFileDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List list = ioSourceAuthDao.getSourceAuthBySourceID(checkFileDTO.getSourceID()); + + if (CollectionUtils.isEmpty(list)){ + return new ArrayList<>(); + } + + List userIdList = list.stream().filter(n-> n.getTargetType().intValue() == 1 && n.getTargetID() > 0).map(IoSourceAuthVo::getTargetID).collect(Collectors.toList()); + Set groupIDList = list.stream().filter(n-> n.getTargetType().intValue() == 2 && n.getParentID() > 0).map(IoSourceAuthVo::getParentID).collect(Collectors.toSet()); + + List userGroupList = CollectionUtils.isEmpty(userIdList) ? null : userGroupDao.getGroupNameListByUserIds(userIdList); + Map userMap = !CollectionUtils.isEmpty(userGroupList) ? userGroupList.stream().collect(Collectors.toMap(UserGroupVo::getUserID, UserGroupVo::getGroupName, (v1, v2) -> v2)) : null; + + List groupList = CollectionUtils.isEmpty(groupIDList) ? null : ioSourceAuthDao.getGroupNameListByGID(new ArrayList<>(groupIDList)); + Map groupMap = !CollectionUtils.isEmpty(groupList) ? groupList.stream().collect(Collectors.toMap(IoSourceAuthVo::getTargetID, IoSourceAuthVo::getParentGroupName, (v1, v2) -> v2)) : null; + + + for (IoSourceAuthVo authVo : list){ + + authVo.setNickname(ObjectUtils.isEmpty(authVo.getNickname()) ? "" : authVo.getNickname()); + authVo.setParentGroupName(""); + if (authVo.getTargetType().intValue() == 1){ + if (!ObjectUtils.isEmpty(userMap) && userMap.containsKey(authVo.getTargetID())){ + authVo.setParentGroupName(userMap.get(authVo.getTargetID())); + } + }else { + if (!ObjectUtils.isEmpty(groupMap) && groupMap.containsKey(authVo.getParentID())){ + authVo.setParentGroupName(groupMap.get(authVo.getParentID())); + } + } + + } + return list; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/BusTypeHandleServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/BusTypeHandleServiceImpl.java new file mode 100644 index 0000000..c620a34 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/BusTypeHandleServiceImpl.java @@ -0,0 +1,255 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +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.UploadDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.utils.ImageUtil; +import com.svnlan.user.dao.SystemOptionDao; +import com.svnlan.utils.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.Arrays; +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 10:15 + */ +@Slf4j +@Service +public class BusTypeHandleServiceImpl implements BusTypeHandleService { + + @Resource + LoginUserUtil loginUserUtil; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + SystemOptionDao systemOptionDao; + + /** + * @Description: 图片类型处理 + * @params: [uploadDTO, isBefore, commonSource] + * @Return: void + * @Modified: + */ + @Override + public void doForImage(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource) { + if (isBefore){ + String fileName; + try { + fileName = uploadDTO.getFile().getOriginalFilename(); + } catch (Exception e) { + log.warn("Did not derive the fileName, fallback to commonSource.getName()"); + fileName = commonSource.getName(); + } + String suffix = FileUtil.getFileExtension(fileName); + if (ObjectUtils.isEmpty(suffix) || !Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix)){ + // 图片类型不正确 + throw new SvnlanRuntimeException(CodeMessageEnum.userAvatarExt.getCode()); + } + } else { + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeCode(commonSource.getSourceType()); + String busType = busTypeEnum.getBusType(); + Float quality = null; + + String filePath = commonSource.getPath(); + try { +// LoginUser loginUser = loginUserUtil.getLoginUser(); + Long time1 = System.currentTimeMillis(); + boolean hasMark = false; + if (!ObjectUtils.isEmpty(uploadDTO)){ + if (ObjectUtils.isEmpty(uploadDTO.getHasMark())){ + /*String needMark = systemOptionDao.getSystemConfigByKey("needMark"); + hasMark = (!ObjectUtils.isEmpty(needMark) && "1".equals(needMark)) ? true : false;*/ + }else { + hasMark = uploadDTO.getHasMark(); + } + } + + String serverName = commonSource.getDomain(); + if (ObjectUtils.isEmpty(serverName)){ + serverName = loginUserUtil.getServerName(); + } + Long size = 0L; + //生成缩略图 + List thumbList = ImageUtil.createThumb(filePath, busType, "", null, + serverName, stringRedisTemplate, quality, hasMark); + LogUtil.info("thumbTime23333333: " + (System.currentTimeMillis() - time1) + ", " + filePath); + if (!CollectionUtils.isEmpty(thumbList)){ + File thumbFile = null; + for (String thumbPath : thumbList){ + thumbFile = new File(thumbPath); + if (thumbFile.exists()){ + size = size + thumbFile.length(); + } + } + if (size > 0){ + commonSource.setThumbSize(ObjectUtils.isEmpty(commonSource.getThumbSize()) ? 0L : commonSource.getThumbSize()); + commonSource.setThumbSize(commonSource.getThumbSize() + size); + } + } + } catch (Exception e){ + LogUtil.error(e, "缩略图生成失败"); + } + } + } + + /** + * @Description: 云盘 + * @params: [uploadDTO, isBefore, commonSource] + * @Return: void + * @Modified: + */ + @Override + public void doForCloud(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource) { + + + if (!isBefore){ + if (uploadDTO.getIgnoreFileSize() > 0 && commonSource.getSize() > uploadDTO.getIgnoreFileSize() * 1024 * 1024 * 1024 ){ + LogUtil.error("云盘文件超限," + JsonUtils.beanToJson(commonSource)); + throw new SvnlanRuntimeException(CodeMessageEnum.ignoreFileSizeTips.getCode()); + } + + String sourceSuffix = commonSource.getFileType(); + /*Map map = new HashMap<>(2); + + map.put("busId", commonSource.getFileID()); + map.put("busType", busType); + if ("doc".equals(sourceSuffix) + || "docx".equals(sourceSuffix) + || "ppt".equals(sourceSuffix) + || "pptx".equals(sourceSuffix) + || "pdf".equals(sourceSuffix)){ + ConvertDTO convertDTO = JSON.parseObject(JsonUtils.beanToJson(map), ConvertDTO.class); + // 转码放外面 + //convertService.doConvert(convertDTO, commonSource); + + /*if ("doc".equals(sourceSuffix) || "docx".equals(sourceSuffix)){ +将PDF、PPT、WORD、EXCEL原文件转成图片 homework + ConvertToPDFMsgDTO convertToPDFMsgDTO = new ConvertToPDFMsgDTO(RandomUtil.getuuid(), DateDUtil.getCurrentTime(), commonSource.getCommonSourceId()); + convertToPDFMsgDTO.setNoImage(true); + kafkaTemplate.send("convertToJPGKafka006", JsonUtils.beanToJson(convertToPDFMsgDTO)); + }* / + return; + }*/ + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(sourceSuffix)){ + this.doForImage(uploadDTO, isBefore, commonSource); + } /*else { + ConvertDTO convertDTO = JSON.parseObject(JsonUtils.beanToJson(map), ConvertDTO.class); + // 转码放外面 + // convertService.doConvert(convertDTO, commonSource); + }*/ + } + } + + @Override + public void doForExtraImage(UploadDTO uploadDTO, CommonSource commonSource) { + String filePath = commonSource.getPath(); + + try { + Long time1 = System.currentTimeMillis(); + String[] sizeStringArr = uploadDTO.getThumbSize().split(","); + if (sizeStringArr.length != 2){ + return; + } + boolean hasMark = false; + if (ObjectUtils.isEmpty(uploadDTO.getHasMark())){ + /*String needMark = systemOptionDao.getSystemConfigByKey("needMark"); + hasMark = (!ObjectUtils.isEmpty(needMark) && "1".equals(needMark)) ? true : false;*/ + }else { + hasMark = uploadDTO.getHasMark(); + } + + Long size = 0L; + +// LoginUser loginUser = loginUserUtil.getLoginUser(); + int[][] sizeArr = new int[][] {{Integer.parseInt(sizeStringArr[0]), Integer.parseInt(sizeStringArr[1])}}; + List thumbList = ImageUtil.createThumb(filePath, uploadDTO.getBusType(), null, sizeArr, loginUserUtil.getServerName() + , stringRedisTemplate, hasMark); + if (!CollectionUtils.isEmpty(thumbList)){ + File thumbFile = null; + for (String thumbPath : thumbList){ + thumbFile = new File(thumbPath); + if (thumbFile.exists()){ + size = size + thumbFile.length(); + } + } + if (size > 0){ + commonSource.setThumbSize(ObjectUtils.isEmpty(commonSource.getThumbSize()) ? 0L : commonSource.getThumbSize()); + commonSource.setThumbSize(commonSource.getThumbSize() + size); + } + } + LogUtil.info("thumbTime: " + (System.currentTimeMillis() - time1)); + } catch (Exception e){ + LogUtil.error(e, "缩略图生成失败"); + } + } + + @Override + public void checkForCloud(CheckFileDTO checkFileDTO, CommonSource commonSource) { + if (checkFileDTO.getIgnoreFileSize() > 0 && commonSource.getSize() > checkFileDTO.getIgnoreFileSize() * 1024 * 1024 * 1024 ){ + LogUtil.error("云盘文件超限," + JsonUtils.beanToJson(commonSource)); + throw new SvnlanRuntimeException(CodeMessageEnum.ignoreFileSizeTips.getCode()); + } + } + + @Override + public void doForWareAndAttachment(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource) { + + // 已改 + String pre = PropertiesUtil.getUpConfig(uploadDTO.getBusType() + ".savePath"); + String filename = commonSource.getName(); + String suffix = FileUtil.getFileExtension(filename); + String path = commonSource.getPath(); + String firstPath = FileUtil.getFirstStorageDevicePath(path); + String picPath = firstPath + "/mu/images/" + + commonSource.getPath().replace("." + suffix, ".jpg").replace(firstPath + pre, ""); + + +// if (isBefore){ + //设置截图字段 + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(suffix)) { + commonSource.setThumb(picPath); + }else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix)) { + + commonSource.setThumb(path.replace(firstPath + "/doc/", firstPath + "/common/doc/") + .replace(firstPath + "/attachment/", firstPath + "/common/attachment/") + .replace(firstPath + "/private/", firstPath + "/common/") + ); + } + //生成截图 + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(suffix)) { + if (!ObjectUtils.isEmpty(commonSource.getCheckMerge()) && commonSource.getCheckMerge() ){ + // 判断视频是否异步合并 + }else { + VideoUtil.getVideoPic(path, picPath, commonSource.getResolution()); + } + }else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix)) { + this.doForImage(uploadDTO, isBefore, commonSource); + }else if(Arrays.asList(GlobalConfig.AUDIO_SHOW_TYPE_ARR).contains(suffix)){ + boolean checkPic = VideoUtil.getAudioPic(path, picPath); + if (checkPic){ + commonSource.setThumb(picPath); + } + } +// } + File thumbFile = new File(picPath); + if (thumbFile.exists()){ + commonSource.setThumbSize(ObjectUtils.isEmpty(commonSource.getThumbSize()) ? 0L : commonSource.getThumbSize()); + commonSource.setThumbSize(commonSource.getThumbSize() + thumbFile.length()); + } + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/CommentServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/CommentServiceImpl.java new file mode 100644 index 0000000..6f4e944 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/CommentServiceImpl.java @@ -0,0 +1,153 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.CommentDao; +import com.svnlan.home.domain.Comment; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CommentDto; +import com.svnlan.home.service.CommentService; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.UserAuthTool; +import com.svnlan.home.vo.CommentVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.PageResult; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/1 14:19 + */ +@Service +public class CommentServiceImpl implements CommentService { + + @Resource + CommentDao commentDao; + + @Resource + UserAuthTool userAuthTool; + @Resource + FileOptionTool fileOptionTool; + + @Override + public Comment saveComment(CommentDto dto, LoginUser loginUser){ + if (ObjectUtils.isEmpty(dto.getTargetID()) || ObjectUtils.isEmpty(dto.getContent())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (dto.getContent().length() > 1024){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + // 评论权限校验 + checkCommentGroupAuth(dto.getTargetID(), loginUser, "8,12"); + + Comment comment = new Comment(); + comment.setPid(ObjectUtils.isEmpty(dto.getPid()) ? 0L : dto.getPid()); + comment.setUserID(loginUser.getUserID()); + comment.setTargetID(dto.getTargetID()); + comment.setTargetType(ObjectUtils.isEmpty(dto.getTargetType()) ? 2 : dto.getTargetType()); + comment.setContent(dto.getContent()); + comment.setPraiseCount(0); + comment.setCommentCount(0); + comment.setStatus(1); + if (!ObjectUtils.isEmpty(dto.getPid())) { + Integer check = commentDao.checkCommentExist(dto.getPid()); + if (ObjectUtils.isEmpty(check)){ + LogUtil.error("saveComment 添加失败,回复的评论已被删除 comment=" + JsonUtils.beanToJson(comment)); + return null; + } + } + try { + commentDao.insert(comment); + }catch (Exception e){ + LogUtil.error("添加评论失败!"); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + return comment; + } + @Override + public void delComment(CommentDto dto, LoginUser loginUser){ + if (ObjectUtils.isEmpty(dto.getCommentID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + CommentVo commentVo = commentDao.getTargetIdByCommentId(dto.getCommentID()); + if (ObjectUtils.isEmpty(commentVo)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 添加删除自己的评论:评论+编辑,删除他人的评论:管理权限 + String auth; + if (commentVo.getUserID().longValue() == loginUser.getUserID().longValue()){ + auth = "8,12"; + }else { + auth = "14"; + } + // 评论权限校验 + checkCommentGroupAuth(commentVo.getTargetID(), loginUser, auth); + + try { + commentDao.deleteComment(dto.getCommentID()); + }catch (Exception e){ + LogUtil.error("删除评论失败!"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + } + + @Override + public PageResult getCommentList(CommentDto dto, LoginUser loginUser){ + if (ObjectUtils.isEmpty(dto.getTargetID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 评论权限校验 + checkCommentGroupAuth(dto.getTargetID(), loginUser, "12"); + + dto.setTargetType(ObjectUtils.isEmpty(dto.getTargetType()) ? 2 : dto.getTargetType()); + Map paramMap = new HashMap<>(2); + paramMap.put("targetID", dto.getTargetID()); + paramMap.put("targetType", dto.getTargetType()); + if (!ObjectUtils.isEmpty(dto.getIdFrom())){ + paramMap.put("idFrom", dto.getIdFrom()); + } + paramMap.put("startIndex", dto.getStartIndex()); + paramMap.put("pageSize", dto.getPageSize()); + long total = commentDao.getCountComment(paramMap); + if (total <= 0){ + return new PageResult(0L, new ArrayList()); + } + + List list = commentDao.getCommentList(paramMap); + + for (CommentVo vo : list){ + vo.setTargetContent(ObjectUtils.isEmpty(vo.getTargetContent()) ? "" : vo.getTargetContent()); + vo.setTargetNickname(ObjectUtils.isEmpty(vo.getTargetNickname()) ? "" : vo.getTargetNickname()); + vo.setTargetUserName(ObjectUtils.isEmpty(vo.getTargetUserName()) ? "" : vo.getTargetUserName()); + vo.setAvatar(ObjectUtils.isEmpty(vo.getAvatar()) ? "" : vo.getAvatar()); + } + + PageResult pageResult = new PageResult(); + pageResult.setTotal(total); + pageResult.setList(list); + return pageResult; + } + + /** 1 查看 2 添加 3 删除*/ + private void checkCommentGroupAuth(Long sourceId, LoginUser loginUser, String auth){ + CommonSource commonSource = fileOptionTool.getSourceInfo(sourceId); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), auth, commonSource.getTargetType()); + + } + +} diff --git a/src/main/java/com/svnlan/home/service/impl/CommonLabelServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/CommonLabelServiceImpl.java new file mode 100644 index 0000000..64978df --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/CommonLabelServiceImpl.java @@ -0,0 +1,256 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.CommonLabelDao; +import com.svnlan.home.domain.CommonLabel; +import com.svnlan.home.domain.UserFav; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.LabelDto; +import com.svnlan.home.service.CommonLabelService; +import com.svnlan.home.vo.CommonLabelVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.dao.UserFavDao; +import com.svnlan.utils.ChinesUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/2 10:53 + */ +@Service +public class CommonLabelServiceImpl implements CommonLabelService { + + @Resource + CommonLabelDao commonLabelDao; + @Resource + UserFavDao userFavDao; + + + @Override + public void addTag(LabelDto labelDto, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(labelDto) || ObjectUtils.isEmpty(labelDto.getLabelName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (labelDto.getLabelName().trim().length() > 32){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + Integer tagType = !ObjectUtils.isEmpty(labelDto.getTagType()) ? labelDto.getTagType() : 1; + + Long userID = loginUser.getUserID(); + if (2 == tagType){ + userID = 0L; + } + + List repeatList = commonLabelDao.checkLabelNameRepeat(labelDto.getLabelName().trim(), userID, tagType); + if (!CollectionUtils.isEmpty(repeatList)){ + throw new SvnlanRuntimeException(CodeMessageEnum.repeatError.getCode()); + } + + CommonLabel commonLabel = new CommonLabel(); + commonLabel.setLabelName(labelDto.getLabelName().trim()); + commonLabel.setLabelEnName(ChinesUtil.getPingYin(labelDto.getLabelName())); + commonLabel.setEnNameSimple(ChinesUtil.getFirstSpell(labelDto.getLabelName())); + commonLabel.setUserID(2 == tagType ? 0 : loginUser.getUserID()); + commonLabel.setStyle(ObjectUtils.isEmpty(labelDto.getStyle()) ? "" : labelDto.getStyle()); + commonLabel.setSort(0); + commonLabel.setTagType(tagType); + try { + commonLabelDao.insert(commonLabel); + }catch (Exception e){ + LogUtil.error(e, "添加标签失败, dto=" + JsonUtils.beanToJson(labelDto) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + } + @Override + public void editTag(LabelDto labelDto, LoginUser loginUser){ + if (ObjectUtils.isEmpty(labelDto) || ObjectUtils.isEmpty(labelDto.getLabelId()) || ObjectUtils.isEmpty(labelDto.getLabelName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (labelDto.getLabelName().trim().length() > 32){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Integer tagType = !ObjectUtils.isEmpty(labelDto.getTagType()) ? labelDto.getTagType() : 1; + + Long userID = loginUser.getUserID(); + if (2 == tagType){ + userID = 0L; + } + List repeatList = commonLabelDao.checkLabelNameRepeat(labelDto.getLabelName().trim(), userID, tagType); + if (!CollectionUtils.isEmpty(repeatList)){ + if (repeatList.size() == 1 && repeatList.contains(labelDto.getLabelId())) { + // 排除 + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.repeatError.getCode()); + } + } + + CommonLabel commonLabel = new CommonLabel(); + commonLabel.setLabelId(labelDto.getLabelId()); + commonLabel.setLabelName(labelDto.getLabelName().trim()); + commonLabel.setLabelEnName(ChinesUtil.getPingYin(labelDto.getLabelName())); + commonLabel.setEnNameSimple(ChinesUtil.getFirstSpell(labelDto.getLabelName())); + commonLabel.setStyle(ObjectUtils.isEmpty(labelDto.getStyle()) ? "" : labelDto.getStyle()); + try { + commonLabelDao.update(commonLabel); + }catch (Exception e){ + LogUtil.error(e, "编辑标签失败, dto=" + JsonUtils.beanToJson(labelDto) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + } + + @Override + public List getTagList(LabelDto labelDto, LoginUser loginUser){ + List list = commonLabelDao.getUserLabelList(loginUser.getUserID()); + return CollectionUtils.isEmpty(list) ? new ArrayList<>() : list; + } + + @Override + public void fileTag(LabelDto labelDto, LoginUser loginUser){ + if (ObjectUtils.isEmpty(labelDto.getLabelId()) || ObjectUtils.isEmpty(labelDto.getFiles()) || ObjectUtils.isEmpty(labelDto.getBlock())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List files = Arrays.asList(labelDto.getFiles().split(",")).stream().map(String::valueOf).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(files)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if ("add".equals(labelDto.getBlock())){ + List list = new ArrayList<>(); + UserFav userFav = null; + Integer sort = userFavDao.getFavMaxSort(loginUser.getUserID()); + sort = ObjectUtils.isEmpty(sort) ? 0 : sort; + int i = 1; + for (String sourseID : files){ + + userFav = new UserFav(loginUser.getUserID(), labelDto.getLabelId().intValue(), "", sourseID, "source", sort + i); + i ++ ; + list.add(userFav); + } + try { + userFavDao.batchInsert(list); + }catch (Exception e){ + LogUtil.error(e, " 关联标签失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + }else { + try { + userFavDao.removeFileTag(labelDto.getLabelId().intValue(), files); + }catch (Exception e){ + LogUtil.error(e, " 取消关联标签失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + } + } + @Override + public void delTag(LabelDto labelDto, LoginUser loginUser){ + if (ObjectUtils.isEmpty(labelDto) || ObjectUtils.isEmpty(labelDto.getLabelId())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + try { + commonLabelDao.deleteTag(labelDto.getLabelId()); + + if (!ObjectUtils.isEmpty(labelDto.getTagType()) && 2 == labelDto.getTagType()) { + // 删除资讯关联关系 + userFavDao.removeInfoTag(labelDto.getLabelId().intValue()); + }else { + userFavDao.removeUserTag(labelDto.getLabelId().intValue(), loginUser.getUserID()); + } + }catch (Exception e){ + LogUtil.error(e, "编辑标签失败, dto=" + JsonUtils.beanToJson(labelDto) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + } + + @Override + public boolean moveTop(CheckFileDTO labelDto, Map resultMap, LoginUser loginUser) { + + if (ObjectUtils.isEmpty(labelDto.getSourceID()) || labelDto.getSourceID() <=0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Integer sort = userFavDao.getTagMaxSort(loginUser.getUserID()); + sort = ObjectUtils.isEmpty(sort) ? 1 : sort; + try { + // 先减所有再修改当前sourceID + userFavDao.subtractTagSortAll(loginUser.getUserID()); + userFavDao.updateTagSort(loginUser.getUserID(), labelDto.getSourceID().toString(), sort); + } catch (Exception e){ + LogUtil.error(e, "标签内的文件置顶失败" + JsonUtils.beanToJson(labelDto)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + return true; + } + + @Override + public boolean moveBottom(CheckFileDTO labelDto, Map resultMap, LoginUser loginUser) { + if (ObjectUtils.isEmpty(labelDto.getSourceID()) || labelDto.getSourceID() <=0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + try { + // 先加所有再修改当前sourceID + userFavDao.addTagSortAll(loginUser.getUserID()); + userFavDao.updateTagSort(loginUser.getUserID(), labelDto.getSourceID().toString(), 0); + } catch (Exception e){ + LogUtil.error(e, "标签内的文件置底失败" + JsonUtils.beanToJson(labelDto)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + return true; + } + + @Override + public boolean tagTop(LabelDto labelDto, LoginUser loginUser) { + if (ObjectUtils.isEmpty(labelDto.getTagID()) || labelDto.getTagID() <=0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Integer tagType = !ObjectUtils.isEmpty(labelDto.getTagType()) ? labelDto.getTagType() : 1; + Integer sort = commonLabelDao.getMaxSort(loginUser.getUserID(), tagType); + sort = ObjectUtils.isEmpty(sort) ? 1 : sort + 1; + try { + commonLabelDao.updateSort(labelDto.getTagID(), sort); + } catch (Exception e){ + LogUtil.error(e, "标签置顶失败" + JsonUtils.beanToJson(labelDto)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + return true; + } + + @Override + public boolean tagBottom(LabelDto labelDto, LoginUser loginUser) { + if (ObjectUtils.isEmpty(labelDto.getTagID()) || labelDto.getTagID() <=0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + try { + commonLabelDao.updateSort(labelDto.getTagID(), 0); + } catch (Exception e){ + LogUtil.error(e, "标签置底失败" + JsonUtils.beanToJson(labelDto)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + return true; + } + + @Override + public List getInfoLabelList(LabelDto labelDto, LoginUser loginUser){ + List list = commonLabelDao.getInfoLabelList(loginUser.getUserID()); + if (CollectionUtils.isEmpty(list)){ + return new ArrayList<>(); + } + list.forEach(n->{ + n.setLabelColor(n.getStyle()); + n.setStyle(null); + }); + return list; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/ConvertFileServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/ConvertFileServiceImpl.java new file mode 100644 index 0000000..6d57d1c --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/ConvertFileServiceImpl.java @@ -0,0 +1,66 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.convert.ConvertDTO; +import com.svnlan.home.service.ConvertFileService; +import com.svnlan.home.utils.ConvertUtil; +import com.svnlan.home.vo.CommonSourceVO; +import com.svnlan.utils.DateDUtil; +import com.svnlan.utils.HttpUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.Date; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/27 16:05 + */ +@Service +public class ConvertFileServiceImpl implements ConvertFileService { + + @Resource + ConvertUtil convertUtil; + + /** + * 试着转码 + */ + @Override + public void tryToConvertFile(CommonSourceVO commonSourceVO, CommonSource commonSource, String busType) { + if (commonSourceVO.getFileID() != null && !commonSourceVO.getFileID().equals(0L)) { + + ConvertDTO convertDTO = new ConvertDTO(); + convertDTO.setBusId(commonSourceVO.getSourceID()); + convertDTO.setBusType(busType); + convertDTO.setDomain(commonSource.getDomain()); + + LogUtil.info("doConvert commonSource=" + JsonUtils.beanToJson(commonSource)); + + + String sourceSuffix = commonSourceVO.getFileType(); + if (Arrays.asList(GlobalConfig.yongzhong_doc_type, GlobalConfig.yongzhong_excel_type + , GlobalConfig.yongzhong_ppt_type).contains(sourceSuffix)) { + // 转码放外面 + convertUtil.doConvert(convertDTO, commonSource); + } else { + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(sourceSuffix)) { + // 转码中记录 + convertUtil.saveVideoConvertRecord(commonSource, "0", ""); + } + + if (!Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(sourceSuffix)) { + // 转码放外面 + Date date = new Date(); + LogUtil.info("doConvert-- begin---" + JsonUtils.beanToJson(commonSourceVO) + ",time=" + DateDUtil.getYearMonthDayHMS(date, DateDUtil.YYYY_MM_DD_HH_MM_SS)); + convertUtil.doConvert(convertDTO, commonSource); + LogUtil.info("doConvert--end--" + JsonUtils.beanToJson(commonSourceVO) + ",time=" + DateDUtil.getYearMonthDayHMS(date, DateDUtil.YYYY_MM_DD_HH_MM_SS)); + } + } + } + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/ExplorerFileServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/ExplorerFileServiceImpl.java new file mode 100644 index 0000000..6cc02de --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/ExplorerFileServiceImpl.java @@ -0,0 +1,212 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CompressFileDto; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.service.ExplorerFileService; +import com.svnlan.home.utils.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.tools.OptionTool; +import com.svnlan.user.vo.PluginListVo; +import com.svnlan.utils.HttpUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.web.util.HtmlUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/25 14:19 + */ +@Service +public class ExplorerFileServiceImpl implements ExplorerFileService { + + @Resource + CompressFileReader compressFileReader; + @Resource + IoSourceDao ioSourceDao; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + FileOptionTool fileOptionTool; + @Resource + ConvertUtil convertUtil; + @Resource + OptionTool optionTool; + + @Override + public Object unzipList(HomeExplorerDTO homeExp, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(homeExp.getSourceID()) || homeExp.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + CommonSource source = ioSourceDao.getSourceInfo(homeExp.getSourceID()); + CompressFileReader.FileNode fileNode = null; + if (ObjectUtils.isEmpty(source) || ObjectUtils.isEmpty(source.getPath())){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String compressKey = GlobalConfig.FILE_PREVIEW_COMPRESS_KEY + source.getPath(); + String value = stringRedisTemplate.opsForValue().get(compressKey); + if (!ObjectUtils.isEmpty(value)){ + try { + fileNode = JsonUtils.jsonToBean(value, CompressFileReader.FileNode.class); + }catch (Exception e){ + LogUtil.error(e, "unzipList error value=" + value); + } + } + if (ObjectUtils.isEmpty(fileNode)){ + fileNode = getFileNode(source, compressKey, fileNode); + } + if (ObjectUtils.isEmpty(fileNode)){ + File f = new File(source.getPath()); + if (f.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.unzipErrorTips.getCode()); + } + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + if (!ObjectUtils.isEmpty(homeExp.getFullName())){ + String suffix = FileUtil.getFileExtension(homeExp.getFullName()); + + if (fileNode.getEncrypted() && ObjectUtils.isEmpty(homeExp.getPassword())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + } + if(ObjectUtils.isEmpty(homeExp.getIndex())){ + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + String extractPath = source.getPath().substring(0, source.getPath().lastIndexOf(".") ) + GlobalConfig.separatorTO; + String firstPath = FileUtil.getFirstStorageDevicePath(source.getPath()); + extractPath = extractPath.replace(firstPath + "/private", firstPath + "/common/down_temp"); + + String filePath = extractPath + homeExp.getFullName(); + // 单个解压 + CompressFileDto dto = CompressFileUtil.unzipOneFilePassword(source.getPath(), filePath, homeExp.getPassword(), homeExp.getIndex()); + if (ObjectUtils.isEmpty(dto) || !dto.getSuccess()){ + if (!ObjectUtils.isEmpty(homeExp.getPassword())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.unzipErrorTips.getCode()); + } + } + + String path = ""; + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix) || Arrays.asList("mp3","xmind","smm","mind","km","epub").contains(suffix)) { + // 预览单个文件则返回链接 + return filePath; + }else if (Arrays.asList("txt","md","json","css","java","cs","xml","sql","js","ts","less","scss","ejs","go","jsx","json5","ls","mysql" + ,"nginx","php","py","rb","rst","tsx","smm").contains(suffix)){ + return (FileUtil.textData(filePath)); + //return HtmlUtils.htmlEscape(FileUtil.textData(filePath)); + //return FileUtil.getFileContent(filePath, StandardCharsets.UTF_8); + }else if (Arrays.asList("html","htm").contains(suffix)) { + return FileUtil.parseDocumentFromFile(filePath); + }else { + // 获取预览插件配置 + List pluginList = optionTool.pluginList(); + boolean isWeb365 = false; + boolean isYz = false; + if (!CollectionUtils.isEmpty(pluginList)){ + for (PluginListVo vo : pluginList){ + if ("yzow".equals(vo.getType()) && 1 == vo.getStatus().intValue()){ + isYz = true; + } + if ("ow365".equals(vo.getType()) && 1 == vo.getStatus().intValue()){ + isWeb365 = true; + } + } + } + if (isYz){ + boolean isYongZhong = Arrays.asList(GlobalConfig.yongzhong_doc_excel_ppt_type).contains(suffix); + if (isYongZhong){ + CommonSource cs = new CommonSource(); + cs.setPath(filePath); + cs.setFileType(suffix); + String serverUrl = HttpUtil.getRequestRootUrl(null); + cs.setDomain(serverUrl); + cs.setName(fileNode.getOriginName()); + cs.setUserID(loginUser.getUserID()); + String yzViewData = convertUtil.yongZhongView(cs, false); + LogUtil.info("unzipList get yz url yzViewData=" + yzViewData); + if (!ObjectUtils.isEmpty(yzViewData)){ + try { + Map m = JsonUtils.jsonToMap(yzViewData); + if (!ObjectUtils.isEmpty(m) && m.containsKey("viewUrl")){ + path = m.get("viewUrl").toString(); + } + }catch (Exception e){ + LogUtil.error(e, "永中链接"); + } + } + } + } + if (!isYz && isWeb365){ + if (Arrays.asList(GlobalConfig.DOC_SHOW_TYPE_ARR).contains(suffix)){ + path = fileOptionTool.getPptPreviewUrl(filePath, "", false); + } + } + return path; + } + } + + fileNode.setFileName(source.getName()); + fileNode.setOriginName(source.getName()); + + return fileNode; + } + + @Override + public CompressFileReader.FileNode getFileNode(CommonSource source, String compressKey, CompressFileReader.FileNode fileNode ){ + String listStr = compressFileReader.unRar(source.getPath(), source.getName(), ""); + LogUtil.info("unzipList listStr=" + listStr); + if (!ObjectUtils.isEmpty(listStr)){ + try { + fileNode = JsonUtils.jsonToBean(listStr, CompressFileReader.FileNode.class); + }catch (Exception e){ + LogUtil.error(e, "unzipList error"); + } + // 放入缓存 + stringRedisTemplate.opsForValue().set(compressKey, listStr, 3, TimeUnit.HOURS); + try { + String firstPath = FileUtil.getFirstStorageDevicePath(source.getPath()); + String extractPath = source.getPath().substring(0, source.getPath().lastIndexOf(".") ) + GlobalConfig.separatorTO; + extractPath = extractPath.replace(firstPath + "/private", firstPath + "/common/down_temp"); + //路径缓存, 供定时任务删除使用 + stringRedisTemplate.opsForZSet().add(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, + extractPath, System.currentTimeMillis() + 86400000); + } catch (Exception e){ + LogUtil.error(e, "下载文件缓存失败"); + } + + } + return fileNode; + } + + + @Override + public Boolean checkZipIsEncrypted(HomeExplorerDTO homeExp){ + if (ObjectUtils.isEmpty(homeExp.getSourceID()) || homeExp.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + CommonSource source = ioSourceDao.getSourceInfo(homeExp.getSourceID()); + if (ObjectUtils.isEmpty(source)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + LogUtil.info("checkZipIsEncrypted source=" + JsonUtils.beanToJson(source)); + return CompressFileUtil.checkZipIsEncrypted(source.getPath()); + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/ExplorerOperationsServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/ExplorerOperationsServiceImpl.java new file mode 100644 index 0000000..3891098 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/ExplorerOperationsServiceImpl.java @@ -0,0 +1,117 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.home.dao.ExplorerOperationsDao; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.service.ExplorerOperationsService; +import com.svnlan.home.utils.AsyncCountSizeUtil; +import com.svnlan.home.vo.HomeExplorerShareDetailVO; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.Partition; +import com.svnlan.utils.RandomUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author KingMgg + * @data 2023/2/7 16:13 + */ +@Service +public class ExplorerOperationsServiceImpl implements ExplorerOperationsService { + + @Resource + ExplorerOperationsDao operationsDao; + @Resource + AsyncCountSizeUtil asyncCountSizeUtil; + @Resource + StringRedisTemplate stringRedisTemplate; + + @Override + public void initSourcePathLevel(Long sourceID) { + + Map paramMap = new HashMap<>(0); + if (!ObjectUtils.isEmpty(sourceID) && sourceID > 0){ + paramMap.put("sourceID", sourceID); + } + + List list = operationsDao.getAllSourceList(paramMap); + + Map levelMap = new HashMap<>(1); + levelMap.put(1L, ",0,1,"); + levelMap.put(0L, ",0,"); + + levelMap = checkList(levelMap, list); + + for (HomeExplorerShareDetailVO detailVO : list){ + if (detailVO.getParentID() <= 0 ){ + continue; + } + detailVO.setParentLevel(levelMap.get(detailVO.getParentID())); + } + + for (List subList : Partition.ofSize(list, 1500)) { + try { + // operationsDao.batchUpdateLevel(subList); + } catch (Exception e) { + LogUtil.error(e, "复制出错"); + } + } + + System.out.println(true); + + } + + private Map checkList(Map levelMap, List list){ + List childList = new ArrayList<>(); + List deList = new ArrayList<>(); + for (HomeExplorerShareDetailVO detailVO : list){ + if (1 == detailVO.getIsFolder()){ + if (detailVO.getParentID() <= 0){ + levelMap.put(detailVO.getSourceID(), ",0," + detailVO.getSourceID() + ","); + }else { + if (levelMap.containsKey(detailVO.getParentID())){ + levelMap.put(detailVO.getSourceID(), levelMap.get(detailVO.getParentID()) + detailVO.getSourceID() + ","); + }else { + + if (detailVO.getParentLevel().indexOf("," + detailVO.getParentID() + ",") >= 0) { + childList.add(detailVO); + }else { + deList.add(detailVO.getSourceID() + ""); + } + } + } + } + } + + if (!CollectionUtils.isEmpty(deList)){ + LogUtil.info("deList===========" + deList.stream().collect(Collectors.joining(",", "", ""))); + } + if (!CollectionUtils.isEmpty(childList)){ + levelMap = checkList(levelMap, childList); + } + return levelMap; + } + + @Override + public void countSize(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(updateFileDTO.getTaskID())){ + updateFileDTO.setTaskID(RandomUtil.getuuid()); + resultMap.put("taskID", updateFileDTO); + asyncCountSizeUtil.asyncCountSize(updateFileDTO); + }else { + String a = stringRedisTemplate.opsForValue().get("countSize_taskID_key_" + updateFileDTO.getTaskID() ); + resultMap.put("status", a); + if ("1".equals(a)){ + stringRedisTemplate.delete("countSize_taskID_key_" + updateFileDTO.getTaskID()); + } + } + + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/FavServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/FavServiceImpl.java new file mode 100644 index 0000000..d3f9a95 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/FavServiceImpl.java @@ -0,0 +1,145 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.enums.CloudOperateEnum; +import com.svnlan.home.service.FavService; +import com.svnlan.home.utils.ConvertUtil; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.dao.UserFavDao; +import com.svnlan.utils.HttpUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/15 13:30 + */ +@Service +public class FavServiceImpl implements FavService { + + @Resource + UserFavDao userFavDao; + @Resource + FileOptionTool fileOptionTool; + @Resource + ConvertUtil convertUtil; + @Resource + IoFileDao ioFileDao; + + @Override + public boolean moveTop(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser) { + + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID()) || updateFileDTO.getSourceID() <=0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Integer sort = userFavDao.getFavMaxSort(loginUser.getUserID()); + sort = ObjectUtils.isEmpty(sort) ? 1 : sort; + try { + // 先减所有再修改当前sourceID + userFavDao.subtractSortAll(loginUser.getUserID()); + userFavDao.updateFavSort(loginUser.getUserID(), updateFileDTO.getSourceID().toString(), sort); + } catch (Exception e){ + LogUtil.error(e, "收藏夹内置顶失败" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + return true; + } + + @Override + public boolean moveBottom(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser) { + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID()) || updateFileDTO.getSourceID() <=0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + try { + // 先加所有再修改当前sourceID + userFavDao.addSortAll(loginUser.getUserID()); + userFavDao.updateFavSort(loginUser.getUserID(), updateFileDTO.getSourceID().toString(), 0); + } catch (Exception e){ + LogUtil.error(e, "收藏夹内置顶失败" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + return true; + } + + @Override + public Map getPreviewEditInfo(CheckFileDTO getCloudPreviewDTO){ + + CommonSource cloudFile = fileOptionTool.getFileAttachment(getCloudPreviewDTO.getSourceID()); + if (cloudFile == null){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + Map reMap = new HashMap<>(1); + reMap.put("yzEditData", ""); + + LoginUser loginUser = getCloudPreviewDTO.getLoginUser(); + cloudFile.setUserID(loginUser.getUserID()); + // 永中 + boolean isYongZhong = Arrays.asList(GlobalConfig.yongzhong_doc_excel_ppt_type).contains(cloudFile.getFileType()); + if (isYongZhong){ + // 预览 + cloudFile.setDomain(HttpUtil.getRequestRootUrl(null)); + convertUtil.yongZhongPre(cloudFile, false); + reMap.put("yzEditData", ObjectUtils.isEmpty(cloudFile.getYzEditData()) ? "" : cloudFile.getYzEditData()); + + } + + return reMap; + } + @Override + public Map getPreviewRefreshInfo(CheckFileDTO getCloudPreviewDTO){ + + CommonSource cloudFile = fileOptionTool.getFileAttachment(getCloudPreviewDTO.getSourceID()); + if (cloudFile == null){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + Map reMap = new HashMap<>(1); + reMap.put("yzViewData", ""); + // 永中 + boolean isYongZhong = Arrays.asList(GlobalConfig.yongzhong_doc_excel_ppt_type).contains(cloudFile.getFileType()); + if (isYongZhong){ + // 预览 + cloudFile.setDomain(HttpUtil.getRequestRootUrl(null)); + convertUtil.yongZhongPre(cloudFile, true); + reMap.put("yzViewData", ObjectUtils.isEmpty(cloudFile.getYzViewData()) ? "" : cloudFile.getYzViewData()); + + } + + return reMap; + } + + @Override + public String getPreviewFileUrl(CheckFileDTO getCloudPreviewDTO){ + if (ObjectUtils.isEmpty(getCloudPreviewDTO.getSourceID()) || getCloudPreviewDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Long id = ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) ? 0L : getCloudPreviewDTO.getF(); + CommonSource commonSource = null; + if (!ObjectUtils.isEmpty(id) && id > 0){ + commonSource = ioFileDao.getHistoryFileAttachment(id); + }else { + commonSource = ioFileDao.getFileAttachment(getCloudPreviewDTO.getSourceID()); + } + if (!ObjectUtils.isEmpty(commonSource) && !ObjectUtils.isEmpty(commonSource.getPath())){ + String firstPath = FileUtil.getFirstStorageDevicePath(commonSource.getPath()); + return commonSource.getPath().replace(firstPath + "/private/cloud", firstPath + "/common/cloud"); + } + return ""; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/FileDocConvertServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/FileDocConvertServiceImpl.java new file mode 100644 index 0000000..12a92f8 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/FileDocConvertServiceImpl.java @@ -0,0 +1,178 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.service.FileDocConvertService; +import com.svnlan.home.utils.AsyncFileDocConvertUtil; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.service.StorageService; +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.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/28 13:57 + */ +@Service +public class FileDocConvertServiceImpl implements FileDocConvertService { + + @Resource + FileOptionTool fileOptionTool; + @Resource + SystemSortTool systemSortTool; + @Resource + IoSourceDao ioSourceDao; + @Resource + AsyncFileDocConvertUtil asyncFileDocConvertUtil; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + StorageService storageService; + @Resource + LoginUserUtil loginUserUtil; + + @Override + public Map doc2Convert(CheckFileDTO checkFileDTO, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getSourceID()) || checkFileDTO.getSourceID() <= 0 || ObjectUtils.isEmpty(checkFileDTO.getSuffix())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) && ObjectUtils.isEmpty(checkFileDTO.getPathTo())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Long sourceID = checkFileDTO.getSourceID(); + CommonSource commonSource = fileOptionTool.getSourceInfo(sourceID); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!Arrays.asList("doc","docx","jpg","jpeg","pdf","png","ppt","pptx").contains(commonSource.getFileType().toLowerCase())){ + LogUtil.error("doc2Convert 转换类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!Arrays.asList("doc","docx","jpg","jpeg","pdf","png").contains(checkFileDTO.getSuffix().toLowerCase())){ + LogUtil.error("doc2Convert 转换类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (Arrays.asList("jpg","jpeg","png").contains(commonSource.getFileType().toLowerCase()) && !"pdf".equals(checkFileDTO.getSuffix().toLowerCase())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String toSuffix = checkFileDTO.getSuffix().toLowerCase(); + if (commonSource.getFileType().toLowerCase().equals(toSuffix)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String defaultPath = storageService.getDefaultStorageDevicePath(); + /** 获取企业云盘 */ + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), checkFileDTO.getSourceID()); + fileOptionTool.checkMemory(disk, commonSource.getSize()); + + Integer targetType = commonSource.getTargetType(); + List sourceNameList = null; + CommonSource parentSource = null; + if (!ObjectUtils.isEmpty(checkFileDTO.getPathTo()) ){ + sourceNameList = ioSourceDao.getSourceNameList(commonSource.getParentID()); + parentSource = new CommonSource(); + parentSource.setName(fileOptionTool.checkRepeatName(checkFileDTO.getPathTo(), checkFileDTO.getPathTo(), sourceNameList, 1)); + parentSource.setParentID(commonSource.getParentID()); + parentSource.setParentLevel(commonSource.getParentLevel()); + parentSource.setTargetType(targetType); + parentSource.setFileType(""); + parentSource.setSize(0L); + fileOptionTool.addIoSourceDetail(parentSource, loginUser.getUserID(), 0L, EventEnum.mkdir); + + }else if(!ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) && checkFileDTO.getSourceIDTo() > 0){ + parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + targetType = parentSource.getTargetType(); + }else { + LogUtil.error("doc2Convert 目标目录不存在 checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + String fileNameDir = commonSource.getName().substring(0,commonSource.getName().lastIndexOf(".")); + // 文件名 + String fileName = fileNameDir + "." + toSuffix; + fileNameDir = fileOptionTool.checkRepeatName(fileNameDir, fileNameDir, sourceNameList, 1); + + // 转图片则创建文件夹 + if (Arrays.asList("jpg","jpeg","png").contains(checkFileDTO.getSuffix().toLowerCase())){ + CommonSource dirParentSource = parentSource; + parentSource = new CommonSource(); + parentSource.setName(fileNameDir); + parentSource.setParentID(dirParentSource.getSourceID()); + parentSource.setParentLevel(dirParentSource.getParentLevel() + dirParentSource.getSourceID() + ","); + parentSource.setTargetType(targetType); + parentSource.setFileType(""); + parentSource.setSize(0L); + fileOptionTool.addIoSourceDetail(parentSource, loginUser.getUserID(), 0L, EventEnum.mkdir); + }else { + // 新创建的目录下添加文件不需要查重 + fileName = fileOptionTool.checkRepeatName(fileName, fileName, toSuffix, sourceNameList, 1); + } + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_convert_doc_file + checkFileDTO.getTaskID(), "0", 1, TimeUnit.HOURS); + asyncFileDocConvertUtil.asyncFileDocConvert(toSuffix, commonSource, disk, fileName, parentSource, loginUser, checkFileDTO.getTaskID() ,defaultPath, loginUserUtil.getServerName()); + + Map reMap = new HashMap<>(3); + reMap.put("taskID", checkFileDTO.getTaskID()); + reMap.put("status", 0); + reMap.put("progress", 0); + + return reMap; + } + + + @Override + public boolean taskAction(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getTaskID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + resultMap.put("status", 0); + resultMap.put("taskID", checkFileDTO.getTaskID()); + String key = GlobalConfig.async_key_convert_doc_file + checkFileDTO.getTaskID(); + String denyString = stringRedisTemplate.opsForValue().get(key); + // 进度 + String progressKey = GlobalConfig.progress_key_convert_doc_file + checkFileDTO.getTaskID(); + String progressString = stringRedisTemplate.opsForValue().get(progressKey); + resultMap.put("progress", 0); + if (!ObjectUtils.isEmpty(progressString)){ + resultMap.put("progress", progressString); + } + + + LogUtil.info("convertTaskAction key=" + key +",denyString=" + denyString + ",progressString=" + progressString); + if (ObjectUtils.isEmpty(denyString)){ + resultMap.put("status", 1); + resultMap.put("progress", 100); + return true; + } + + if ("1".equals(denyString)) { + resultMap.put("status", 1); + resultMap.put("progress", 100); + stringRedisTemplate.delete(key); + stringRedisTemplate.delete(progressKey); + } + return true; + } + +} diff --git a/src/main/java/com/svnlan/home/service/impl/FilePreViewServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/FilePreViewServiceImpl.java new file mode 100644 index 0000000..4cc1b59 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/FilePreViewServiceImpl.java @@ -0,0 +1,44 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.service.FilePreViewService; +import com.svnlan.home.utils.FileUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.nio.charset.StandardCharsets; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/26 16:42 + */ +@Service +public class FilePreViewServiceImpl implements FilePreViewService { + @Resource + IoFileDao ioFileDao; + + @Override + public String getPreviewXml(CheckFileDTO checkFileDTO){ + if (ObjectUtils.isEmpty(checkFileDTO.getSourceID()) || checkFileDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Long id = ObjectUtils.isEmpty(checkFileDTO.getF()) ? 0L : checkFileDTO.getF(); + CommonSource commonSource = null; + if (!ObjectUtils.isEmpty(id) && id > 0){ + commonSource = ioFileDao.getHistoryFileAttachment(id); + }else { + commonSource = ioFileDao.getFileAttachment(checkFileDTO.getSourceID()); + } + if (!ObjectUtils.isEmpty(commonSource) && !ObjectUtils.isEmpty(commonSource.getPath())){ + + return FileUtil.getFileContent(commonSource.getPath(), StandardCharsets.UTF_8); + } + return ""; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/HomeExplorerServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/HomeExplorerServiceImpl.java new file mode 100644 index 0000000..b3acb79 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/HomeExplorerServiceImpl.java @@ -0,0 +1,1825 @@ +package com.svnlan.home.service.impl; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.I18nUtils; +import com.svnlan.enums.*; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.*; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.domain.IOSourceMeta; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.dto.HomeSettingDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.service.HomeExplorerService; +import com.svnlan.home.utils.*; +import com.svnlan.home.vo.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SourceOperateTool; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.dao.*; +import com.svnlan.user.domain.Role; +import com.svnlan.user.service.StorageService; +import com.svnlan.user.tools.OptionTool; +import com.svnlan.user.vo.OptionVo; +import com.svnlan.user.vo.UserGroupVo; +import com.svnlan.user.vo.UserVo; +import com.svnlan.utils.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author KingMgg + * @data 2023/2/6 11:48 + */ +@Service +public class HomeExplorerServiceImpl implements HomeExplorerService { + + @Resource + HomeExplorerDao homeExplorerDao; + @Resource + SourceOperateTool sourceOperateTool; + @Resource + SystemLogTool systemLogTool; + @Resource + CommonLabelDao commonLabelDao; + @Resource + SystemOptionDao systemOptionDao; + @Resource + SystemSortTool systemSortTool; + @Resource + UserOptionDao userOptionDao; + @Resource + IoSourceEventDao ioSourceEventDao; + @Resource + UserDao userDao; + @Resource + IoSourceMetaDao ioSourceMetaDao; + @Resource + FileOptionTool fileOptionTool; + @Resource + IoSourceDao ioSourceDao; + @Resource + RoleDao roleDao; + @Resource + OptionTool optionTool; + @Resource + ParamUtils paramUtils; + @Resource + GroupSourceDao groupSourceDao; + @Resource + StorageService storageService; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + AsyncCutImgUtil asyncCutImgUtil; + @Resource + UserAuthTool userAuthTool; + + @Value("${disk.default.size}") + private Long diskDefaultSize; + + + @Override + public HomeExplorerResult homeExplorer(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser) { + // 默认创建目录 + String treeOpen = systemOptionDao.getSystemConfigByKey("treeOpen"); + + // my 个人空间,myFav 收藏夹,rootGroup 企业云盘,recentDoc 最近文档,fileType 文件类型,fileTag 标签,shareLink 外链分享 + // my,myFav,rootGroup,recentDoc,fileType,fileTag,shareLink + List treeOpenList = ObjectUtils.isEmpty(treeOpen) ? new ArrayList<>() : Arrays.asList(treeOpen.split(",")).stream().map(String::valueOf).collect(Collectors.toList()); + + HomeExplorerResult result = null; + homeExplorerDTO.setBlock(ObjectUtils.isEmpty(homeExplorerDTO.getBlock()) ? "default" : homeExplorerDTO.getBlock()); + + switch (homeExplorerDTO.getBlock()){ + case "root": + result = this.getRootList(loginUser, treeOpenList); + break; + case "files": + result = this.getMyMenuList(loginUser, treeOpenList); + break; + case "tools": + result = this.getToolList(treeOpenList); + break; + case "fileType": + if (!treeOpenList.contains(homeExplorerDTO.getBlock())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorAdminAuth.getCode()); + } + result = this.getFileTypeList(); + break; + case "fileTag": + if (!treeOpenList.contains(homeExplorerDTO.getBlock())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorAdminAuth.getCode()); + } + result = this.getFileTagList(loginUser); + break; + case "fav": + // 收藏夹 + result = this.getUserFavList(homeExplorerDTO, loginUser); + break; + case "recycle": + // 回收站 + result = this.getRecycleList(homeExplorerDTO, loginUser); + break; + case "userRencent": + // 最近文档 + result = this.getUserRencentList(homeExplorerDTO, loginUser); + break; + case "default": + result = this.getHomeExplorerList(homeExplorerDTO, loginUser); + break; + default: + result = this.getHomeExplorerList(homeExplorerDTO, loginUser); + break; + } + return result; + } + /** 收藏夹*/ + private HomeExplorerResult getUserFavList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + List roleList = null; + boolean checkGet = false; + String auth = ""; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + auth = GlobalConfig.SYSTEM_GROUP_AUTH; + checkGet = true; + + Role role = roleDao.getSystemRoleInfo(); + roleList = new ArrayList<>(); + roleList.add(new IoSourceAuthVo(role.getRoleID(), role.getRoleName(), role.getLabel(), auth)); + } + + Map hashMap = new HashMap<>(4); + hashMap.put("userID", loginUser.getUserID()); + hashMap.put("opType", "userFav"); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getKeyword())) { + hashMap.put("keyword", homeExplorerDTO.getKeyword().toLowerCase()); + } + hashMap.put("sortType", SourceSortEnum.getSortType("")); + hashMap.put("sortField", "createTime"); + + PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + List list = homeExplorerDao.getUserFavExplorer(hashMap); + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + + FileMetaVo fileMetaVo = null; + String downloadKey = FileUtil.getDownloadKey(); + + int isLnkAudio = 0; + Set lnkSourceIDList = new HashSet<>(); + Set uidList = new HashSet<>(); + List idList = new ArrayList<>(); + List sourceIDs = new ArrayList<>(); + Set pLevelList = new HashSet<>(); + boolean isSelect = false; + Set gpidList = new HashSet<>(); + Set sidList = new HashSet<>(); + long spaceId = 0; + for (HomeExplorerVO vo2 : list){ + if (!ObjectUtils.isEmpty(vo2.getSourceID()) && vo2.getSourceID() > 0) { + isSelect = true; + if (vo2.getIsFolder().intValue() == 1) { + idList.add(vo2.getSourceID()); + } + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + pLevelList.add(vo2.getParentLevel()); + sourceIDs.add(vo2.getSourceID().toString()); + if (!checkGet && vo2.getTargetType().intValue() == 2){ + checkGet = true; + sidList.add(vo2.getSourceID()); + if (!",0,".equals(vo2.getParentLevel())) { + Set aList = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toSet()); + gpidList.addAll(aList); + sidList.addAll(aList); + } + } + if (spaceId == 0 && 1 == vo2.getTargetType() && !",0,".equals(vo2.getParentLevel())){ + List list1 = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + spaceId = list1.get(0); + } + } + } + if (spaceId == 0){ + HomeExplorerVO space = homeExplorerDao.getHomeSpace(loginUser.getUserID(), 0L); + spaceId = space.getSourceID(); + } + Map> gsFileAuthMap = new HashMap<>(1); + // 文件权限 + if (!CollectionUtils.isEmpty(sidList)){ + sourceOperateTool.getFileAuthByLevel(loginUser.getUserID(), sidList, gsFileAuthMap); + } + + Map gsAuthMap = new HashMap<>(); + Map gsAuthNameMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(gpidList)){ + sourceOperateTool.getUserAuthByLevel(loginUser.getUserID(), new ArrayList<>(gpidList), gsAuthMap, gsAuthNameMap); + } + + // 标签 + Map> sourceTagMap = isSelect ? fileOptionTool.getSourceTagMap(loginUser.getUserID(), sourceIDs) : null; + + // 链接分享 + List shareList = isSelect ? fileOptionTool.checkUserIsShare(loginUser.getUserID()) : null; + + List userList = isSelect ? userDao.getUserBaseInfo(new ArrayList<>(uidList)) : null; + Map userMap = !CollectionUtils.isEmpty(userList) ? userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)) : null; + + // 父级文件名称、位置 + Map parentPathDisplayMap = null; + // 文件位置 + if (!CollectionUtils.isEmpty(pLevelList)) { + parentPathDisplayMap = sourceOperateTool.getParentPathDisplayMap(pLevelList); + + } + List countList = CollectionUtils.isEmpty(idList) ? null : homeExplorerDao.getSourceChileCont(idList); + Map countMap = new HashMap<>(1); + if (!CollectionUtils.isEmpty(countList)) { + for (HomeExplorerVO home : countList) { + countMap.put(home.getParentID() + (home.getIsFolder().intValue() == 1 ? "_folder" : "_file"), home.getFileCount()); + } + } + for (HomeExplorerVO vo1 : list){ + vo1.setAuth(auth); + if (ObjectUtils.isEmpty(auth) && vo1.getTargetType().intValue() == 2 ){ + if (!ObjectUtils.isEmpty(gsFileAuthMap) && gsFileAuthMap.containsKey(vo1.getSourceID())){ + vo1.setRoleList(JsonUtils.beanToJson(gsFileAuthMap.get(vo1.getSourceID()))); + }else { + // 上级部门权限 + if (!ObjectUtils.isEmpty(gsAuthMap)) { + vo1.setAuth(sourceOperateTool.getAuthByLevel(vo1,vo1.getParentLevel(), gsAuthMap, gsAuthNameMap)); + } + } + if (ObjectUtils.isEmpty(vo1.getAuth()) || "0".equals(vo1.getAuth())){ + // 不可见 + continue; + } + if (!Arrays.asList(vo1.getAuth().split(",")).stream().collect(Collectors.toList()).contains("1")){ + // 无列表权限 + continue; + } + } + vo1.setHasFile(0); + vo1.setHasFolder(0); + // 是否收藏 + vo1.setIsFav(1); + vo1.setParentName(""); + vo1.setCreateUserJson(""); + vo1.setModifyUserJson(""); + vo1.setTagList(new ArrayList<>()); + if (!ObjectUtils.isEmpty(vo1.getSourceID()) && vo1.getSourceID() > 0) { + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_folder")) { + vo1.setHasFolder(countMap.get(vo1.getSourceID() + "_folder")); + } + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_file")) { + vo1.setHasFile(countMap.get(vo1.getSourceID() + "_file")); + } + if (1 == vo1.getTargetType().intValue() && 0 == vo1.getParentID().longValue()) { + // 个人空间 + vo1.setName(I18nUtils.i18n("explorer.toolbar.rootPath")); + } + if (vo1.getIsFolder() == 1) { + vo1.setIcon("folder"); + } else { + vo1.setIcon("file"); + } + // 是否分享 + vo1.setIsShare(!CollectionUtils.isEmpty(shareList) && shareList.contains(vo1.getSourceID()) ? 1 : 0); + // FileMeta value 处理 + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + // 父级文件名称 + if (!ObjectUtils.isEmpty(parentPathDisplayMap) && parentPathDisplayMap.containsKey(vo1.getParentID())) { + vo1.setParentName(parentPathDisplayMap.get(vo1.getParentID())); + } + vo1.setPathDisplay(""); + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + vo1.setPathDisplay(sourceOperateTool.setParentPathDisplay(parentPathDisplayMap, vo1.getParentLevel(), spaceId)); + } + // path 处理 + sourceOperateTool.opPath(vo1, downloadKey, vo1.getAuth()); + if (!ObjectUtils.isEmpty(vo1.getIsM3u8()) && vo1.getIsM3u8() == 0 && !ObjectUtils.isEmpty(vo1.getIsH264Preview()) && vo1.getIsH264Preview() == 1){ + vo1.setIsM3u8(1); + } + if (!ObjectUtils.isEmpty(vo1.getOexeSourceID())) { + lnkSourceIDList.add(vo1.getOexeSourceID()); + if (!ObjectUtils.isEmpty(vo1.getOexeFileType()) && Arrays.asList(GlobalConfig.AUDIO_SHOW_TYPE_ARR).contains(vo1.getOexeFileType())) { + isLnkAudio = 1; + } + } + // 已选标签 + if (!ObjectUtils.isEmpty(sourceTagMap) && sourceTagMap.containsKey(vo1.getSourceID().toString())) { + vo1.setTagList(sourceTagMap.get(vo1.getSourceID().toString())); + } + }else { + vo1.setName(vo1.getFavName()); + vo1.setPath(""); + vo1.setTargetType(0); + vo1.setSourceID(0L); + vo1.setIsFolder(0); + vo1.setFileType(""); + vo1.setParentID(0L); + vo1.setFileID(0L); + vo1.setParentLevel(""); + vo1.setIsDelete(0); + vo1.setSize(0L); + vo1.setCreateTime(0L); + vo1.setModifyTime(0L); + vo1.setSize(0L); + vo1.setValue(""); + vo1.setHashMd5(""); + vo1.setDescription(""); + vo1.setPathDisplay(""); + } + + folderVOList.add(vo1); + } + + oexeFilePath(downloadKey, lnkSourceIDList, isLnkAudio, folderVOList); + + } + PageInfo pageInfo = new PageInfo<>(list); + result.setTotal(pageInfo.getTotal()); + result.setFolderList(folderVOList); + result.setFileList(fileVOList); + + return result; + } + + + private void oexeFilePath(String downloadKey, Set lnkSourceIDList, int isLnkAudio, List fileVOList){ + if (!CollectionUtils.isEmpty(lnkSourceIDList)) { + List lnkFileList = homeExplorerDao.getFolderAndImgAndAudioHomeExplorer(new ArrayList<>(lnkSourceIDList), isLnkAudio); + if (!CollectionUtils.isEmpty(lnkFileList)) { + Map lnkFileMap = lnkFileList.stream().collect(Collectors.toMap(HomeExplorerVO::getSourceID, Function.identity(), (v1, v2) -> v2)); + for (HomeExplorerVO vo3 : fileVOList) { + if (lnkFileMap.containsKey(vo3.getOexeSourceID())) { + HomeExplorerVO vo4 = lnkFileMap.get(vo3.getOexeSourceID()); + vo4.setFileType(vo3.getOexeFileType()); + if (!ObjectUtils.isEmpty(vo3.getOexeFileType())){ + if (Arrays.asList("dcm").contains(vo3.getOexeFileType()) + || Arrays.asList(GlobalConfig.AUDIO_SHOW_TYPE_ARR).contains(vo3.getOexeFileType())) { + vo4.setDownloadUrl("/api/disk/attachment/" + FileUtil.encodeDownloadUrl(vo4.getName()) + + "?busId=" + vo4.getSourceID() + "&busType=" + BusTypeEnum.CLOUD.getBusType() + "&key=" + downloadKey); + vo4.setPath(""); + }else if (!ObjectUtils.isEmpty(vo3.getOexeFileType()) && "gif".equals(vo3.getOexeFileType())) { + vo4.setDownloadUrl("/api/disk/attachment/" + FileUtil.encodeDownloadUrl(vo4.getName()) + + "?busId=" + vo4.getSourceID() + "&busType=" + BusTypeEnum.CLOUD.getBusType() + "&key=" + downloadKey); + vo4.setPath(FileUtil.getShowImageUrl(vo4.getPath(), vo4.getSourceID() + "")); + }else if (!ObjectUtils.isEmpty(vo3.getOexeFileType()) && Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(vo3.getOexeFileType())) { + vo4.setPath(FileUtil.getShowImageUrl(vo4.getPath(), vo4.getSourceID() + "")); + } + }else { + vo4.setPath(""); + } + vo3.setSourceInfo(vo4); + } + } + } + } + } + + /** 回收站*/ + private HomeExplorerResult getRecycleList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + Map hashMap = new HashMap<>(3); + hashMap.put("userID", loginUser.getUserID()); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getKeyword())) { + hashMap.put("keyword", homeExplorerDTO.getKeyword().toLowerCase()); + } + SystemSortVo systemSortVo = systemSortTool.getUserSort(loginUser.getUserID()); + String key = "userRecycle"; + hashMap = systemSortTool.setSortAboutMap(systemSortVo,hashMap, loginUser.getUserID(), homeExplorerDTO.getSortField() + , homeExplorerDTO.getSortType(), key, "io."); + + + + PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + List list = homeExplorerDao.getUserRecycleExplorer(hashMap); + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + FileMetaVo fileMetaVo = null; + String downloadKey = FileUtil.getDownloadKey(); + long spaceId = 0; + + Set pLevelList = new HashSet<>(); + Set uidList = new HashSet<>(); + List idList = new ArrayList<>(); + List sourceIDs = new ArrayList<>(); + for (HomeExplorerVO vo2 : list){ + if (vo2.getIsFolder().intValue() == 1){ + idList.add(vo2.getSourceID()); + } + sourceIDs.add(vo2.getSourceID().toString()); + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + pLevelList.add(vo2.getParentLevel()); + if (spaceId == 0 && 1 == vo2.getTargetType() && !",0,".equals(vo2.getParentLevel())){ + List list1 = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + spaceId = list1.get(0); + } + } + if (spaceId == 0){ + HomeExplorerVO space = homeExplorerDao.getHomeSpace(loginUser.getUserID(), 0L); + spaceId = space.getSourceID(); + } + + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + + // 标签 + Map> sourceTagMap = fileOptionTool.getSourceTagMap(loginUser.getUserID(), sourceIDs); + // 收藏 + List myFavList = fileOptionTool.checkIsFavByUserId(loginUser.getUserID()); + // 链接分享 + List shareList = fileOptionTool.checkUserIsShare(loginUser.getUserID()); + Map parentPathDisplayMap = null; + // 文件位置 + if (!CollectionUtils.isEmpty(pLevelList)) { + parentPathDisplayMap = sourceOperateTool.getParentPathDisplayMap(pLevelList); + + } + List countList = CollectionUtils.isEmpty(idList) ? null : homeExplorerDao.getSourceChileCont(idList); + Map countMap = new HashMap<>(1); + if (!CollectionUtils.isEmpty(countList)) { + for (HomeExplorerVO home : countList) { + countMap.put(home.getParentID() + (home.getIsFolder().intValue() == 1 ? "_folder" : "_file"), home.getFileCount()); + } + } + for (HomeExplorerVO vo1 : list){ + vo1.setHasFile(0); + vo1.setHasFolder(0); + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_folder")){ + vo1.setHasFolder(countMap.get(vo1.getSourceID() + "_folder")); + } + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_file")){ + vo1.setHasFile(countMap.get(vo1.getSourceID() + "_file")); + } + // 是否收藏 + vo1.setIsFav(!CollectionUtils.isEmpty(myFavList) && myFavList.contains(vo1.getSourceID().toString()) ? 1 : 0); + + // 是否分享 + vo1.setIsShare(!CollectionUtils.isEmpty(shareList) && shareList.contains(vo1.getSourceID()) ? 1 : 0); + // FileMeta value 处理 + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + + // path 处理 + sourceOperateTool.opPath( vo1, downloadKey, ""); + if (!ObjectUtils.isEmpty(vo1.getIsM3u8()) && vo1.getIsM3u8() == 0 && !ObjectUtils.isEmpty(vo1.getIsH264Preview()) && vo1.getIsH264Preview() == 1){ + vo1.setIsM3u8(1); + } + // 已选标签 + vo1.setTags(""); + vo1.setTagList(new ArrayList<>()); + if (!ObjectUtils.isEmpty(sourceTagMap) && sourceTagMap.containsKey(vo1.getSourceID().toString())){ + vo1.setTagList(sourceTagMap.get(vo1.getSourceID().toString())); + } + vo1.setPathDisplay(""); + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + vo1.setPathDisplay(sourceOperateTool.setParentPathDisplay(parentPathDisplayMap, vo1.getParentLevel(), spaceId)); + } + if (vo1.getIsFolder() == 1) { + vo1.setIcon("folder"); + folderVOList.add(vo1); + } else { + vo1.setIcon("file"); + fileVOList.add(vo1); + } + } + } + PageInfo pageInfo = new PageInfo<>(list); + result.setTotal(pageInfo.getTotal()); + result.setFolderList(folderVOList); + result.setFileList(fileVOList); + + return sourceOperateTool.setSystemReturn(result, systemSortVo, "userRecycle"); + } + /** 最近文档*/ + private HomeExplorerResult getUserRencentList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + List roleList = null; + boolean isSystem = false; + String auth = ""; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + auth = GlobalConfig.SYSTEM_GROUP_AUTH; + isSystem = true; + Role role = roleDao.getSystemRoleInfo(); + roleList = new ArrayList<>(); + roleList.add(new IoSourceAuthVo(role.getRoleID(), role.getRoleName(), role.getLabel(), auth)); + } + Map hashMap = new HashMap<>(3); + hashMap.put("userID", loginUser.getUserID()); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getKeyword())) { + hashMap.put("keyword", homeExplorerDTO.getKeyword().toLowerCase()); + } + SystemSortVo systemSortVo = systemSortTool.getUserSort(loginUser.getUserID()); + + String key = "recentDoc"; + hashMap = systemSortTool.setSortAboutMap(systemSortVo,hashMap, loginUser.getUserID(), homeExplorerDTO.getSortField() + , homeExplorerDTO.getSortType(), key, "io."); + + + PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + List list = homeExplorerDao.getUserRencentExplorer(hashMap); + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + FileMetaVo fileMetaVo = null; + String downloadKey = FileUtil.getDownloadKey(); + Set uidList = new HashSet<>(); + Set gpidList = new HashSet<>(); + Set sidList = new HashSet<>(); + Set pLevelList = new HashSet<>(); + long spaceId = 0; + for (HomeExplorerVO vo2 : list){ + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + if (!isSystem && vo2.getTargetType().intValue() == 2) { + sidList.add(vo2.getSourceID()); + if (!",0,".equals(vo2.getParentLevel())) { + Set aList = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toSet()); + gpidList.addAll(aList); + sidList.addAll(aList); + } + } + if (spaceId == 0 && 1 == vo2.getTargetType() && !",0,".equals(vo2.getParentLevel())){ + List list1 = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + spaceId = list1.get(0); + } + pLevelList.add(vo2.getParentLevel()); + } + if (spaceId == 0){ + HomeExplorerVO space = homeExplorerDao.getHomeSpace(loginUser.getUserID(), 0L); + spaceId = space.getSourceID(); + } + Map> gsFileAuthMap = new HashMap<>(1); + // 文件权限 + if (!CollectionUtils.isEmpty(sidList)){ + sourceOperateTool.getFileAuthByLevel(loginUser.getUserID(), sidList, gsFileAuthMap); + } + + Map gsAuthMap = new HashMap<>(); + Map gsAuthNameMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(gpidList)){ + sourceOperateTool.getUserAuthByLevel(loginUser.getUserID(), new ArrayList<>(gpidList), gsAuthMap, gsAuthNameMap); + } + + // 链接分享 + List shareList = fileOptionTool.checkUserIsShare(loginUser.getUserID()); + // 收藏 + List myFavList = fileOptionTool.checkIsFavByUserId(loginUser.getUserID()); + + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + Map parentPathDisplayMap = null; + // 文件位置 + if (!CollectionUtils.isEmpty(pLevelList)) { + parentPathDisplayMap = sourceOperateTool.getParentPathDisplayMap(pLevelList); + + } + + for (HomeExplorerVO vo1 : list){ + vo1.setAuth(auth); + if (!isSystem && vo1.getTargetType().intValue() == 2 ){ + if (!ObjectUtils.isEmpty(gsFileAuthMap) && gsFileAuthMap.containsKey(vo1.getSourceID())){ + vo1.setRoleList(JsonUtils.beanToJson(gsFileAuthMap.get(vo1.getSourceID()))); + }else { + // 上级部门权限 + if (!ObjectUtils.isEmpty(gsAuthMap)) { + vo1.setAuth(sourceOperateTool.getAuthByLevel(vo1,vo1.getParentLevel(), gsAuthMap, gsAuthNameMap)); + } + } + if (ObjectUtils.isEmpty(vo1.getAuth()) || "0".equals(vo1.getAuth())){ + // 不可见 + continue; + } + if (!Arrays.asList(vo1.getAuth().split(",")).stream().collect(Collectors.toList()).contains("1")){ + // 无列表权限 + continue; + } + } + vo1.setHasFile(0); + vo1.setHasFolder(0); + // 是否收藏 + vo1.setIsFav(!CollectionUtils.isEmpty(myFavList) && myFavList.contains(vo1.getSourceID().toString()) ? 1 : 0); + // 是否分享 + vo1.setIsShare(!CollectionUtils.isEmpty(shareList) && shareList.contains(vo1.getSourceID()) ? 1 : 0); + // FileMeta value 处理 + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + vo1.setPathDisplay(""); + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + vo1.setPathDisplay(sourceOperateTool.setParentPathDisplay(parentPathDisplayMap, vo1.getParentLevel(), spaceId)); + } + // path 处理 + sourceOperateTool.opPath(vo1, downloadKey, vo1.getAuth()); + if (!ObjectUtils.isEmpty(vo1.getIsM3u8()) && vo1.getIsM3u8() == 0 && !ObjectUtils.isEmpty(vo1.getIsH264Preview()) && vo1.getIsH264Preview() == 1){ + vo1.setIsM3u8(1); + } + vo1.setIcon("file"); + fileVOList.add(vo1); + } + } + PageInfo pageInfo = new PageInfo<>(list); + result.setTotal(pageInfo.getTotal()); + result.setFolderList(folderVOList); + fileVOList = fileVOList.stream().sorted(Comparator.comparing(HomeExplorerVO::getModifyTime).reversed()).collect(Collectors.toList()); + result.setFileList(fileVOList); + + return sourceOperateTool.setSystemReturn(result, systemSortVo, "userRecycle"); + } + + private Boolean searchNameRepeatParam(HomeExplorerDTO homeExplorerDTO, Map hashMap, LoginUser loginUser){ + boolean searchRepeat = false; + if (!ObjectUtils.isEmpty(homeExplorerDTO.getRepeatSourceID()) && homeExplorerDTO.getRepeatSourceID() > 0){ + CommonSource commonSource = fileOptionTool.getSourceInfo(homeExplorerDTO.getRepeatSourceID()); + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), "2", commonSource.getTargetType()); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getRepeatName())){ + hashMap.put("repeatName", homeExplorerDTO.getRepeatName()); + searchRepeat = true; + }else { + if (ObjectUtils.isEmpty(homeExplorerDTO.getHashMd5())){ + + if (!ObjectUtils.isEmpty(commonSource) && !ObjectUtils.isEmpty(commonSource.getHashMd5())){ + hashMap.put("repeatHashMd5", commonSource.getHashMd5()); + searchRepeat = true; + } + }else { + hashMap.put("repeatHashMd5", homeExplorerDTO.getHashMd5()); + searchRepeat = true; + } + } + } + return searchRepeat; + } + private void searchAll(LoginUser loginUser, boolean isSystem, Map hashMap, HomeExplorerVO space){ + // 全局搜索 + List diskList = null; + if (isSystem){ + diskList = systemSortTool.getSystemGroupSourceList(); + }else { + diskList = systemSortTool.getUserGroupSourceList(loginUser.getUserID()); + } + List parentLevelList = new ArrayList<>(); + parentLevelList.add("," + space.getSourceID() + ","); + if (!CollectionUtils.isEmpty(diskList)){ + diskList.forEach(n->parentLevelList.add("," + n.getSourceID() + ",")); + } + hashMap.put("parentLevelList", parentLevelList); + + } + private HomeExplorerResult getHomeExplorerList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + HomeExplorerResult result = null; + HashOperations operations = stringRedisTemplate.opsForHash(); + String homeExplorerKey = GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(); + + String secondKey = paramUtils.getHomeExplorerSecondKey(homeExplorerDTO); + LogUtil.info("getHomeExplorerList secondKey=" + secondKey); + String homeExplorerKeyValue = ""; + if (!ObjectUtils.isEmpty(secondKey)){ + homeExplorerKeyValue = operations.get(homeExplorerKey, secondKey); + if (!ObjectUtils.isEmpty(homeExplorerKeyValue)){ + LogUtil.info("getHomeExplorerList secondKey=" + secondKey + ",value is not null" ); + try { + result = JsonUtils.jsonToBean(homeExplorerKeyValue, HomeExplorerResult.class); + }catch (Exception e){ + LogUtil.error(e, "getHomeExplorerList error secondKey=" + secondKey + ",homeExplorerKeyValue=" + homeExplorerKeyValue); + } + } + } + + if (!ObjectUtils.isEmpty(result) && !ObjectUtils.isEmpty(result.getTotal())){ + return result; + } + + result = new HomeExplorerResult(); + + HomeExplorerVO space = homeExplorerDao.getHomeSpace(loginUser.getUserID(), 0L); + Map systemConfigMap = optionTool.getSystemConfigMap(); + + boolean searchRepeat = false; + boolean showFileMd5 = true; + if (!ObjectUtils.isEmpty(systemConfigMap) && !ObjectUtils.isEmpty(systemConfigMap.containsKey("showFileMd5")) && "0".equals(systemConfigMap.get("showFileMd5"))){ + showFileMd5 = false; + } + + List roleList = null; + boolean isGroup = false; + boolean isSystem = false; + String auth = ""; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + roleList = new ArrayList<>(); + Role role = roleDao.getSystemRoleInfo(); + auth = GlobalConfig.SYSTEM_GROUP_AUTH; + isSystem = true; + roleList.add(new IoSourceAuthVo(role.getRoleID(), role.getRoleName(), role.getLabel(), auth)); + } + + boolean isGroupMenu = false; + String key = ""; + String parentName = ""; + List groupSourceIDs = null; + Map hashMap = new HashMap<>(3); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getSourceID()) && homeExplorerDTO.getSourceID() > 0){ + hashMap.put("sourceID", homeExplorerDTO.getSourceID()); + key = homeExplorerDTO.getSourceID().toString(); + HomeExplorerVO parentInfo = homeExplorerDao.getOneSourceInfo(homeExplorerDTO.getSourceID()); + if (ObjectUtils.isEmpty(parentInfo)){ + homeExplorerDTO.setSourceID(space.getSourceID()); + parentInfo = homeExplorerDao.getOneSourceInfo(space.getSourceID()); + } + parentName = parentInfo.getName(); + if (parentInfo.getTargetType().intValue() == 2){ + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFileType()) && "folder".equals(homeExplorerDTO.getFileType())){ + groupSourceIDs = groupSourceDao.getGroupSourceIDs(homeExplorerDTO.getSourceID()); + if (!CollectionUtils.isEmpty(groupSourceIDs)) { + isGroupMenu = true; + } + }else { + // 排除左侧栏目录 + hashMap.put("targetType", 2); + } + if(!isSystem){ + auth = sourceOperateTool.getUserAuthByLevel(loginUser.getUserID(), parentInfo.getParentLevel() , homeExplorerDTO); + roleList = new ArrayList<>(); + roleList.add(new IoSourceAuthVo(homeExplorerDTO.getAuthID(), homeExplorerDTO.getAuthName(), homeExplorerDTO.getLabel(), auth)); + isGroup = true; + } + } + }else { + // 全局搜索 + if (ObjectUtils.isEmpty(homeExplorerDTO.getTagID())){ + if(ObjectUtils.isEmpty(homeExplorerDTO.getFileType())){ + LogUtil.info("getHomeExplorerList null homeExplorerDTO=" + JsonUtils.beanToJson(homeExplorerDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFileType()) && !Arrays.asList("allFile","folder", "all").contains(homeExplorerDTO.getFileType())) { + // + if (homeExplorerDTO.getFileType().indexOf("txt,") >= 0){ + key = "recentDoc"; + }else if (homeExplorerDTO.getFileType().indexOf("jpg,") >= 0){ + key = "image"; + }else if (homeExplorerDTO.getFileType().indexOf("mp3,") >= 0){ + key = "music"; + }else if (homeExplorerDTO.getFileType().indexOf("mp4,") >= 0){ + key = "movie"; + }else if (homeExplorerDTO.getFileType().indexOf("zip,") >= 0){ + key = "zip"; + }else if (homeExplorerDTO.getFileType().indexOf("psd,") >= 0){ + key = "other"; + } + } + } + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getUserID()) && homeExplorerDTO.getUserID() > 0) { + hashMap.put("userID", homeExplorerDTO.getUserID()); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getKeyword())) { + hashMap.put("keyword", homeExplorerDTO.getKeyword().toLowerCase()); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getUserID())) { + hashMap.put("userID", homeExplorerDTO.getUserID()); + hashMap.put("isSearch", 1); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getTagID())) { + hashMap.put("tagID", homeExplorerDTO.getTagID()); + key = "userFileTag:" + homeExplorerDTO.getTagID(); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFileType())) { + this.searchAll(loginUser, isSystem, hashMap, space); + // + switch (homeExplorerDTO.getFileType()){ + case "allFile": + hashMap.put("isFolder", 0); + break; + case "folder": + hashMap.put("isFolder", 1); + break; + case "all": + break; + default: + hashMap.put("isFolder", 0); + hashMap.put("fileTypeList", Arrays.asList(homeExplorerDTO.getFileType().split(",")).stream().map(String::valueOf).collect(Collectors.toList())); + paramUtils.docSearchParam(homeExplorerDTO.getFileType(), hashMap); + + // hashMap.put("targetType", 1); 个人空间 + 部门与我有关的 + hashMap.put("userID", loginUser.getUserID()); + hashMap.put("isSearch", 1); + break; + } + // 文件、文件名查重 + searchRepeat = this.searchNameRepeatParam(homeExplorerDTO, hashMap, loginUser); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFromType()) && homeExplorerDTO.getFromType()) { + hashMap.put("isFolder", 1); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getMinSize())) { + hashMap.put("minSize", homeExplorerDTO.getMinSize()); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getMaxSize())) { + hashMap.put("maxSize", homeExplorerDTO.getMaxSize()); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getTimeFrom())) { + + Date timeFrom = DateDUtil.strToDate("yyyy-MM-dd", homeExplorerDTO.getTimeFrom()); + hashMap.put("minDate", timeFrom.getTime()/1000); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getTimeTo())) { + + Date timeTo = DateDUtil.strToDate("yyyy-MM-dd HH:mm:ss", homeExplorerDTO.getTimeTo() + " 23:59:59"); + hashMap.put("maxDate", timeTo.getTime()/1000); + } + SystemSortVo systemSortVo = systemSortTool.getUserSort(loginUser.getUserID()); + hashMap = systemSortTool.setSortAboutMap(systemSortVo,hashMap, loginUser.getUserID(), homeExplorerDTO.getSortField() + , homeExplorerDTO.getSortType(), key); + + FileMetaVo fileMetaVo = null; + + + hashMap.put("startIndex", homeExplorerDTO.getStartIndex()); + hashMap.put("pageSize", homeExplorerDTO.getPageSize()); + + Long total = homeExplorerDao.getCountHomeExplorer(hashMap); + List list = null; + //PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + if(0 < total.longValue()) { + list = homeExplorerDao.getHomeExplorer(hashMap); + } + List rList = null; + Set lnkSourceIDList = new HashSet<>(); + int isLnkAudio = 0; + + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + String downloadKey = FileUtil.getDownloadKey(); + Set gpidList = new HashSet<>(); + List idList = new ArrayList<>(); + Set sidList = new HashSet<>(); + List sourceIDs = new ArrayList<>(); + Set uidList = new HashSet<>(); + //Set pidList = new HashSet<>(); + Set pLevelList = new HashSet<>(); + for (HomeExplorerVO vo2 : list) { + // 判断是否显示md5 + if (!showFileMd5) { + vo2.setHashMd5(""); + } + if (vo2.getIsFolder().intValue() == 1) { + idList.add(vo2.getSourceID()); + } + pLevelList.add(vo2.getParentLevel()); + sourceIDs.add(vo2.getSourceID().toString()); + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + //pidList.add(vo2.getParentID()); + if (!isSystem && vo2.getTargetType().intValue() == 2) { + sidList.add(vo2.getSourceID()); + if (!",0,".equals(vo2.getParentLevel())) { + Set parentIdList = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toSet()); + gpidList.addAll(parentIdList); + sidList.addAll(parentIdList); + } + } + } + Map> gsFileAuthMap = new HashMap<>(1); + // 文件权限 + if (!CollectionUtils.isEmpty(sidList)) { + sourceOperateTool.getFileAuthByLevel(loginUser.getUserID(), sidList, gsFileAuthMap); + LogUtil.info("checkRoleAuth getFileAuthByLevel sidList=" + JsonUtils.beanToJson(sidList) + " gsFileAuthMap=" + JsonUtils.beanToJson(gsFileAuthMap)); + } + + + Map gsAuthMap = new HashMap<>(1); + Map gsAuthNameMap = new HashMap<>(1); + // 文件上级权限 + if (!isGroup && !CollectionUtils.isEmpty(gpidList)) { + sourceOperateTool.getUserAuthByLevel(loginUser.getUserID(), new ArrayList<>(gpidList), gsAuthMap, gsAuthNameMap); + } + // 标签 + Map> sourceTagMap = fileOptionTool.getSourceTagMap(loginUser.getUserID(), sourceIDs); + // 收藏 + List myFavList = fileOptionTool.checkIsFavByUserId(loginUser.getUserID()); + // 链接分享 + List shareList = fileOptionTool.checkUserIsShare(loginUser.getUserID()); + + // 父级文件名称 + //List parentNameList = homeExplorerDao.getParentNameList(new ArrayList<>(pidList)); + //Map parentNameMap = CollectionUtils.isEmpty(parentNameList) ? null : parentNameList.stream().collect(Collectors.toMap(HomeExplorerVO::getSourceID, HomeExplorerVO::getParentName, (v1, v2) -> v2)); + + Map parentPathDisplayMap = null; + // 文件位置 + if (!CollectionUtils.isEmpty(pLevelList)) { + parentPathDisplayMap = sourceOperateTool.getParentPathDisplayMap(pLevelList); + + } + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + List countList = CollectionUtils.isEmpty(idList) ? null : homeExplorerDao.getSourceChileCont(idList); + Map countMap = new HashMap<>(1); + if (!CollectionUtils.isEmpty(countList)) { + for (HomeExplorerVO home : countList) { + countMap.put(home.getParentID() + (home.getIsFolder().intValue() == 1 ? "_folder" : "_file"), home.getFileCount()); + } + } + for (HomeExplorerVO vo1 : list) { + if (isSystem) { + vo1.setRoleList(JsonUtils.beanToJson(roleList)); + } + vo1.setAuth(auth); + if (!isSystem && vo1.getTargetType().intValue() == 2) { + boolean separately = false; + // 单独设置权限 + if (!ObjectUtils.isEmpty(gsFileAuthMap)) { + LogUtil.info("checkRoleAuth getFileAuthByLevel checkSeparately=" + (gsFileAuthMap.containsKey(vo1.getSourceID())) + " gsFileAuthMap=" + JsonUtils.beanToJson(gsFileAuthMap)); + if (gsFileAuthMap.containsKey(vo1.getSourceID())) { + separately = true; + rList = gsFileAuthMap.get(vo1.getSourceID()); + vo1.setRoleList(JsonUtils.beanToJson(rList)); + vo1.setAuth(rList.get(0).getAuth()); + }else { + List pList = Arrays.asList(vo1.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(pList)){ + for (int i = pList.size(); i-- > 0; ) { + Long p = pList.get(i); + LogUtil.info("checkRoleAuth getFileAuthByLevel p=" + p + " checkParentSeparately=" + (gsFileAuthMap.containsKey(p)) + " gsFileAuthMap=" + JsonUtils.beanToJson(gsFileAuthMap)); + if (gsFileAuthMap.containsKey(p)) { + separately = true; + rList = gsFileAuthMap.get(p); + vo1.setRoleList(JsonUtils.beanToJson(rList)); + vo1.setAuth(rList.get(0).getAuth()); + break; + } + } + } + } + } + // 没有单独设置 + if (!separately) { + if (isGroup) { + vo1.setRoleList(JsonUtils.beanToJson(roleList)); + } else { + // 上级部门权限 + if (ObjectUtils.isEmpty(auth) && !ObjectUtils.isEmpty(gsAuthMap)) { + vo1.setAuth(sourceOperateTool.getAuthByLevel(vo1, vo1.getParentLevel(), gsAuthMap, gsAuthNameMap)); + } + } + } + if (ObjectUtils.isEmpty(vo1.getAuth()) || "0".equals(vo1.getAuth())){ + // 不可见 + continue; + } + if (!Arrays.asList(vo1.getAuth().split(",")).stream().collect(Collectors.toList()).contains("1")){ + // 无列表权限 + continue; + } + } + + vo1.setDownloadUrl(""); + vo1.setHasFile(0); + vo1.setHasFolder(0); + vo1.setResolution(""); + vo1.setLength(0); + vo1.setThumb(""); + vo1.setCover(""); + vo1.setParentName(""); + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_folder")) { + vo1.setHasFolder(countMap.get(vo1.getSourceID() + "_folder")); + } + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_file")) { + vo1.setHasFile(countMap.get(vo1.getSourceID() + "_file")); + // vo1.setCreateTime(vo1.getFileCreateTime()); + } + + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + + // path 处理 + sourceOperateTool.opPath(vo1, downloadKey, vo1.getAuth()); + if (!ObjectUtils.isEmpty(vo1.getIsM3u8()) && vo1.getIsM3u8() == 0 && !ObjectUtils.isEmpty(vo1.getIsH264Preview()) && vo1.getIsH264Preview() == 1){ + vo1.setIsM3u8(1); + } + if (!ObjectUtils.isEmpty(vo1.getOexeSourceID())) { + lnkSourceIDList.add(vo1.getOexeSourceID()); + if (!ObjectUtils.isEmpty(vo1.getOexeFileType()) && Arrays.asList(GlobalConfig.AUDIO_SHOW_TYPE_ARR).contains(vo1.getOexeFileType())) { + isLnkAudio = 1; + } + } + + // 是否收藏 + vo1.setIsFav(!CollectionUtils.isEmpty(myFavList) && myFavList.contains(vo1.getSourceID().toString()) ? 1 : 0); + // 已选标签 + vo1.setTags(""); + vo1.setTagList(new ArrayList<>()); + if (!ObjectUtils.isEmpty(sourceTagMap) && sourceTagMap.containsKey(vo1.getSourceID().toString())) { + vo1.setTagList(sourceTagMap.get(vo1.getSourceID().toString())); + } + // 是否分享 + vo1.setIsShare(!CollectionUtils.isEmpty(shareList) && shareList.contains(vo1.getSourceID()) ? 1 : 0); + + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? vo1.getThumb() : vo1.getPath()); + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? "" : vo1.getPath()); + + // 父级文件名称 + if (!ObjectUtils.isEmpty(parentName)) { + vo1.setParentName(parentName); + } else if (!ObjectUtils.isEmpty(parentPathDisplayMap) && parentPathDisplayMap.containsKey(vo1.getParentID())) { + vo1.setParentName(parentPathDisplayMap.get(vo1.getParentID())); + } + // 是否是部门文件(左侧栏) + vo1.setIsGroup(0); + if (isGroupMenu && groupSourceIDs.contains(vo1.getSourceID())) { + vo1.setIsGroup(1); + } + + vo1.setPathDisplay(""); + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + vo1.setPathDisplay(sourceOperateTool.setParentPathDisplay(parentPathDisplayMap, vo1.getParentLevel(), space.getSourceID())); + } + if (vo1.getIsFolder() == 1) { + vo1.setIcon("folder"); + folderVOList.add(vo1); + } else { + vo1.setIcon("file"); + fileVOList.add(vo1); + } + } + oexeFilePath(downloadKey, lnkSourceIDList, isLnkAudio, fileVOList); + } + if (isGroupMenu){ + folderVOList = folderVOList.stream().sorted(Comparator.comparing(HomeExplorerVO::getIsGroup).thenComparing(HomeExplorerVO::getName).thenComparing(HomeExplorerVO::getSourceID)).collect(Collectors.toList()); + } + + result.setTotal(total); + result.setFolderList(folderVOList); + result.setFileList(fileVOList); + // 查询回收站是否有文件 + if (!ObjectUtils.isEmpty(homeExplorerDTO.getCheckRecycle()) && 1 == homeExplorerDTO.getCheckRecycle() ){ + Map currentMap = new HashMap<>(1); + Integer count = homeExplorerDao.checkUserRecycleExplorer(loginUser.getUserID()); + currentMap.put("recycleCount", count); + result.setCurrent(currentMap); + } + sourceOperateTool.setSystemReturn(result, systemSortVo, String.valueOf(homeExplorerDTO.getSourceID())); + + if (!ObjectUtils.isEmpty(secondKey)) { + operations.put(homeExplorerKey, secondKey, JsonUtils.beanToJson(result)); + operations.getOperations().expire(homeExplorerKey, 5, TimeUnit.SECONDS); + } + return result; + } + + @Override + public IOSource createDir(HomeExplorerVO homeExplorerVO, LoginUser loginUser ) { + if (ObjectUtils.isEmpty(homeExplorerVO.getName()) || homeExplorerVO.getName().length() > 256 ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(homeExplorerVO.getParentID()) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + HomeExplorerVO parent = homeExplorerDao.getOneSourceInfo(homeExplorerVO.getParentID()); + if (ObjectUtils.isEmpty(parent) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, parent.getSourceID(), parent.getParentLevel(), "9", parent.getTargetType()); + + List sourceNameList = ioSourceDao.getSourceNameList(homeExplorerVO.getParentID()); + /*if (!CollectionUtils.isEmpty(sourceNameList) && sourceNameList.contains(homeExplorerVO.getName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathExists.getCode()); + }*/ + homeExplorerVO.setName(fileOptionTool.checkRepeatName(homeExplorerVO.getName(), homeExplorerVO.getName(), sourceNameList, 1)); + + IOSource source = new IOSource(); + source.setName(homeExplorerVO.getName()); + source.setParentLevel(parent.getParentLevel() + homeExplorerVO.getParentID() + "," ); + source.setTargetID(homeExplorerVO.getTargetID()); + source.setCreateUser(homeExplorerVO.getCreateUser()); + source.setModifyUser(homeExplorerVO.getModifyUser()); + source.setIsFolder(homeExplorerVO.getIsFolder()); + source.setTargetType(parent.getTargetType()); + source.setFileType(""); + source.setFileID(0L); + source.setParentID(homeExplorerVO.getParentID()); + source.setStorageID(storageService.getDefaultStorageDeviceId()); + source.setNamePinyin(ChinesUtil.getPingYin(source.getName())); + source.setNamePinyinSimple(ChinesUtil.getFirstSpell(source.getName())); + + if (source.getParentID() <= 0){ + LogUtil.error("创建文件夹失败,不可创建根目录文件"); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + try { + homeExplorerDao.createDir(source); + }catch (Exception e){ + LogUtil.error(e, " createDir error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + if (!ObjectUtils.isEmpty(source.getSourceID()) && source.getSourceID() > 0){ + sourceOperateTool.setSourcePinYin(source.getSourceID(), homeExplorerVO.getName()); + + if (parent.getTargetType().intValue() == 2) { + String groupSource = ioSourceMetaDao.getValueMetaByKey(homeExplorerVO.getParentID(), "groupSource"); + if (!ObjectUtils.isEmpty(groupSource)) { + ioSourceMetaDao.insert(new IOSourceMeta(source.getSourceID(), "groupSource", groupSource)); + } + } + } + + // 添加文档操作event + fileOptionTool.addSourceEvent(source.getSourceID(), source.getParentID(), loginUser.getUserID(), source.getName(), EventEnum.mkdir); + + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", source.getSourceID()); + reMap.put("sourceParent", source.getParentID()); + reMap.put("type", "mkdir"); + reMap.put("pathName", source.getName()); + paramList.add(reMap); + + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileMkDir.getCode(), paramList, systemLogTool.getRequest()); + return source; + + } + + + @Override + public HomeFileDetailVO getFileDetail(HomeExplorerVO homeExplorerVO) { + if (ObjectUtils.isEmpty(homeExplorerVO.getFileID()) || homeExplorerVO.getFileID() <= 0 ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + HomeFileDetailVO homeFileDetailVO = homeExplorerDao.getFileDetail(homeExplorerVO.getFileID()); + if (!ObjectUtils.isEmpty(homeFileDetailVO) && !ObjectUtils.isEmpty(homeFileDetailVO.getPath())){ + String firstPath = FileUtil.getFirstStorageDevicePath(homeFileDetailVO.getPath()); + homeFileDetailVO.setPath(homeFileDetailVO.getPath().replace(firstPath + "/doc/", firstPath + "/common/doc/") + .replace(firstPath + "/attachment/", firstPath + "/common/attachment/") + .replace(firstPath + "/private/", firstPath + "/common/") + + ); + } + return homeFileDetailVO; + } + + /** + * @Description: 位置 + * @params: [homeExplorerDTO] + * @Return: com.svnlan.home.vo.HomeExplorerResult + * @Author: sulijuan + * @Date: 2023/2/14 16:35 + * @Modified: + */ + private HomeExplorerResult getMyMenuList(LoginUser loginUser, List treeOpenList){ + + // 用户群组权限 + //List userGroupList = sourceOperateTool.getUserGroupAuth(loginUser.getUserID()); + List sourceIDs= new ArrayList<>(); + List sourceIDList= new ArrayList<>(); + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + // my 个人空间,myFav 收藏夹,rootGroup 企业云盘 + UserVo userVo = userDao.getUserInfo(loginUser.getUserID()); + HomeExplorerVO vo = null; + for (MyMenuEnum typeEnum : MyMenuEnum.values()){ + if ("fav".equals(typeEnum.getIcon())){ + if (CollectionUtils.isEmpty(treeOpenList) || !treeOpenList.contains("myFav")){ + continue; + } + } + if ("space".equals(typeEnum.getIcon())){ + if (CollectionUtils.isEmpty(treeOpenList) || !treeOpenList.contains("my")){ + continue; + } + } + vo = new HomeExplorerVO(); + vo.setIsChildren(true); + vo.setCanDownload(false); + vo.setIsTruePath(false); + vo.setName(I18nUtils.tryI18n(typeEnum.getCode())); + vo.setPathDesc(""); + if (!ObjectUtils.isEmpty(typeEnum.getDesc())) { + vo.setPathDesc(I18nUtils.tryI18n(typeEnum.getDesc())); + } + // 个人空间 + if ("1".equals(typeEnum.getIsRoot())){ + HomeExplorerVO space = homeExplorerDao.getHomeSpace(loginUser.getUserID(), 0L); + + vo.setSizeMax(userVo.getSizeMax() <= 0 ? diskDefaultSize.doubleValue() : userVo.getSizeMax()); + vo.setSizeUse(space.getSize()); + vo.setSourceID(space.getSourceID()); + sourceIDs.add(vo.getSourceID().toString()); + sourceIDList.add(vo.getSourceID()); + vo.setDescription(space.getDescription()); + vo.setCreateTime(space.getCreateTime()); + vo.setModifyTime(space.getModifyTime()); + vo.setParentID(space.getParentID()); + vo.setParentLevel(space.getParentLevel()); + vo.setTargetType(1); + } + vo.setPathDisplay("/" + vo.getName()); + vo.setType("folder"); + vo.setIcon(typeEnum.getIcon()); + folderVOList.add(vo); + } + loginUser.setUserType(ObjectUtils.isEmpty(loginUser.getUserType()) ? 2 :loginUser.getUserType()); + // 企业云盘 + boolean system = false; + List roleList = new ArrayList<>(); + if (1 == loginUser.getUserType()){ + Integer val = homeExplorerDao.getUserIdentityInfo(loginUser.getUserID()); + if (!ObjectUtils.isEmpty(val) && val.intValue() == 1){ + system = true; + } + } + List diskList = null; + if (system){ + diskList = systemSortTool.getSystemGroupSourceList(); + }else { + diskList = systemSortTool.getUserGroupSourceList(loginUser.getUserID()); + } + if (!CollectionUtils.isEmpty(diskList)) { + + boolean isSystem = false; + // 文件权限 + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + String auth = GlobalConfig.SYSTEM_GROUP_AUTH; + Role role = roleDao.getSystemRoleInfo(); + isSystem = true; + roleList.add(new IoSourceAuthVo(role.getRoleID(), role.getRoleName(), role.getLabel(), auth)); + } + Map> gsFileAuthMap = new HashMap<>(1); + if (!isSystem){ + Set gpidList = diskList.stream().map(HomeExplorerVO::getSourceID).collect(Collectors.toSet()); + // 文件权限 + if (!CollectionUtils.isEmpty(gpidList)){ + sourceOperateTool.getFileAuthByLevel(loginUser.getUserID(), gpidList, gsFileAuthMap); + } + + } + List rList = null; + for (HomeExplorerVO disk : diskList) { + if (isSystem){ + disk.setAuth(GlobalConfig.SYSTEM_GROUP_AUTH); + disk.setRoleList(JsonUtils.beanToJson(roleList)); + }else { + if (!ObjectUtils.isEmpty(gsFileAuthMap) && gsFileAuthMap.containsKey(disk.getSourceID())){ + rList = gsFileAuthMap.get(disk.getSourceID()); + disk.setAuth(rList.stream().map(IoSourceAuthVo::getAuth).collect(Collectors.joining(","))); + disk.setRoleList(JsonUtils.beanToJson(rList)); + }else { + disk.setRoleList(JsonUtils.beanToJson(Arrays.asList(new IoSourceAuthVo(disk.getAuthID(), disk.getAuthName(), disk.getLabel(), disk.getAuth())))); + } + } + + if (("," + disk.getAuth() + ",").indexOf(",1,") >= 0) { + sourceIDs.add(disk.getSourceID().toString()); + sourceIDList.add(disk.getSourceID()); + disk.setIcon("box"); + disk.setTargetType(2); + disk.setIsChildren(true); + disk.setSizeMax(disk.getSizeMax() <= 0 ? diskDefaultSize.doubleValue() : disk.getSizeMax()); + folderVOList.add(disk); + } + } + } + if (!CollectionUtils.isEmpty(treeOpenList) && treeOpenList.contains("information")) { + if (1 == loginUser.getUserType() + || (!ObjectUtils.isEmpty(userVo.getAuth()) && userVo.getAuth().indexOf("explorer.informationView") >= 0)){ + // 资讯 + folderVOList.add(systemSortTool.infoToMeMenu()); + } + } + // 与我协作 + // folderVOList.add(systemSortTool.shareToMeMenu()); + + + // 标签 + Map> sourceTagMap = CollectionUtils.isEmpty(sourceIDs) ? null : fileOptionTool.getSourceTagMap(loginUser.getUserID(), sourceIDs); + // 收藏 + List myFavList = fileOptionTool.checkIsFavByUserId(loginUser.getUserID()); + + for (HomeExplorerVO forder : folderVOList){ + if (ObjectUtils.isEmpty(forder.getSourceID())){ + continue; + } + // 是否收藏 + forder.setIsFav(!CollectionUtils.isEmpty(myFavList) && myFavList.contains(forder.getSourceID().toString()) ? 1 : 0); + // 已选标签 + forder.setTags(""); + forder.setTagList(new ArrayList<>()); + if (!ObjectUtils.isEmpty(sourceTagMap) && sourceTagMap.containsKey(forder.getSourceID().toString())){ + forder.setTagList(sourceTagMap.get(forder.getSourceID().toString())); + } + + /** desc */ + forder.setDescription(ObjectUtils.isEmpty(forder.getDescription()) ? "" : forder.getDescription()); + } + + Map map = new HashMap<>(2); + map.put("isChildren", true); + map.put("canDownload", false); + String name = I18nUtils.tryI18n(MenuEnum.position.getCode()); + map.put("name", name); + map.put("pathDesc", ""); + map.put("type", "folder"); + map.put("pathDisplay","/" + name); + map.put("icon",MenuEnum.position.getIcon()); + result.setCurrent(map); + result.setFolderList(folderVOList); + result.setFileList(new ArrayList<>()); + return result; + } + + /** + * @Description: 文件类型 + * @params: [homeExplorerDTO] + * @Return: com.svnlan.home.vo.HomeExplorerResult + * @Author: sulijuan + * @Date: 2023/2/14 14:48 + * @Modified: + */ + private HomeExplorerResult getFileTypeList(){ + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + HomeExplorerVO vo = null; + for (DocumentTypeEnum typeEnum : DocumentTypeEnum.values()){ + vo = new HomeExplorerVO(); + vo.setCanDownload(false); + vo.setIsTruePath(false); + vo.setName(I18nUtils.tryI18n(typeEnum.getValue())); + vo.setExt(typeEnum.getExt()); + vo.setExtType(typeEnum.getCode()); + vo.setType("folder"); + vo.setIcon(typeEnum.getIcon()); + folderVOList.add(vo); + } + Map map = new HashMap<>(2); + map.put("isChildren", true); + map.put("canDownload", false); + String name = I18nUtils.tryI18n(MenuEnum.fileType.getCode()); + map.put("name", name); + map.put("pathDesc", I18nUtils.tryI18n(MenuEnum.fileType.getDesc())); + map.put("type", "folder"); + map.put("pathDisplay","/" + name); + map.put("icon",MenuEnum.fileType.getIcon()); + result.setCurrent(map); + result.setFolderList(folderVOList); + result.setFileList(new ArrayList<>()); + return result; + } + + /** + * @Description: 工具 + * @params: [homeExplorerDTO] + * @Return: com.svnlan.home.vo.HomeExplorerResult + * @Author: sulijuan + * @Date: 2023/2/14 14:48 + * @Modified: + */ + private HomeExplorerResult getToolList(List treeOpenList){ + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + // // my 个人空间,myFav 收藏夹,rootGroup 企业云盘,recentDoc 最近文档,fileType 文件类型,fileTag 标签,shareLink 外链分享 + HomeExplorerVO vo = null; + for (ToolsEnum toolsEnum : ToolsEnum.values()){ + if (Arrays.asList("recentDoc", "shareLink", "toolbox").contains(toolsEnum.getIcon())){ + if (!treeOpenList.contains(toolsEnum.getIcon())){ + continue; + } + } + vo = new HomeExplorerVO(); + vo.setCanDownload(false); + vo.setIsTruePath(false); + vo.setName(I18nUtils.tryI18n(toolsEnum.getCode())); + vo.setPathDesc(I18nUtils.tryI18n(toolsEnum.getValue())); + vo.setType("folder"); + vo.setIcon(toolsEnum.getIcon()); + folderVOList.add(vo); + } + Map map = new HashMap<>(2); + map.put("isChildren", true); + map.put("canDownload", false); + String name = I18nUtils.tryI18n(MenuEnum.tools.getCode()); + map.put("name", name); + map.put("pathDesc", ""); + map.put("type", "folder"); + map.put("pathDisplay","/" + name); + map.put("icon",MenuEnum.tools.getIcon()); + result.setCurrent(map); + result.setFolderList(folderVOList); + result.setFileList(new ArrayList<>()); + return result; + } + + + /** + * @Description: root + * @params: [homeExplorerDTO] + * @Return: com.svnlan.home.vo.HomeExplorerResult + * @Author: sulijuan + * @Date: 2023/2/14 14:48 + * @Modified: + */ + private HomeExplorerResult getRootList(LoginUser loginUser, List treeOpenList){ + + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + HomeExplorerVO vo = null; + // // my 个人空间,myFav 收藏夹,rootGroup 企业云盘,recentDoc 最近文档,fileType 文件类型,fileTag 标签,shareLink 外链分享 + + for (MenuEnum menuEnum : MenuEnum.values()){ + if (Arrays.asList("fileType", "fileTag").contains(menuEnum.getType())){ + if (CollectionUtils.isEmpty(treeOpenList) || !treeOpenList.contains(menuEnum.getType())){ + continue; + } + } + vo = new HomeExplorerVO(); + switch (menuEnum.getType()){ + case "files": + vo.setChildren(this.getMyMenuList(loginUser, treeOpenList)); + break; + case "tools": + vo.setChildren(this.getToolList(treeOpenList)); + break; + case "fileType": + vo.setChildren(this.getFileTypeList()); + break; + case "fileTag": + vo.setChildren(this.getFileTagList(loginUser)); + break; + } + vo.setCanDownload(false); + vo.setIsTruePath(false); + vo.setIsParent(true); + vo.setOpen(menuEnum.getOpen()); + vo.setType(menuEnum.getType()); + vo.setIcon(menuEnum.getIcon()); + vo.setName(I18nUtils.tryI18n(menuEnum.getCode())); + vo.setPathDesc(""); + if (!ObjectUtils.isEmpty(menuEnum.getDesc())) { + vo.setPathDesc(I18nUtils.tryI18n(menuEnum.getDesc())); + } + + vo.setPathDisplay("/" + vo.getName()); + vo.setType("folder"); + folderVOList.add(vo); + } + Map map = new HashMap<>(2); + map.put("isChildren", true); + map.put("canDownload", false); + map.put("isTruePath", false); + map.put("isParent", true); + map.put("name", "root"); + map.put("pathDesc", ""); + map.put("type", "folder"); + map.put("pathDisplay","/root" ); + result.setCurrent(map); + result.setFolderList(folderVOList); + result.setFileList(new ArrayList<>()); + return result; + } + + + /** + * @Description: 标签 + * @params: [] + * @Return: com.svnlan.home.vo.HomeExplorerResult + * @Author: sulijuan + * @Date: 2023/2/14 16:50 + * @Modified: + */ + private HomeExplorerResult getFileTagList(LoginUser loginUser){ + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + + List list = commonLabelDao.getUserLabelList(loginUser.getUserID()); + HomeExplorerVO vo = null; + boolean isChildren = false; + if (!CollectionUtils.isEmpty(list)){ + isChildren = true; + for (CommonLabelVo labelVo : list){ + vo = new HomeExplorerVO(); + vo.setName(labelVo.getLabelName()); + vo.setLabelId(labelVo.getLabelId()); + vo.setStyle(labelVo.getStyle()); + folderVOList.add(vo); + } + } + + Map map = new HashMap<>(2); + map.put("isChildren", isChildren); + map.put("canDownload", false); + map.put("isTruePath", false); + map.put("isParent", true); + map.put("pathDesc", ""); + map.put("type", "folder"); + String name = I18nUtils.tryI18n(MenuEnum.tag.getCode()); + map.put("name", name); + map.put("pathDisplay","/" + name); + map.put("icon",MenuEnum.tag.getIcon()); + result.setCurrent(map); + result.setFolderList(folderVOList); + result.setFileList(new ArrayList<>()); + return result; + } + + @Override + public Boolean folderSetting(HomeSettingDTO homeExplorerVO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(homeExplorerVO.getKey()) || ObjectUtils.isEmpty(homeExplorerVO.getSourceID())|| ObjectUtils.isEmpty(homeExplorerVO.getValue())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + switch (homeExplorerVO.getKey()){ + case "listType": + // 列表类型 + this.listType(homeExplorerVO, loginUser); + break; + case "filePanel": + // 详情板块 + this.updateSystemOption(homeExplorerVO, loginUser); + break; + case "listSortField": + this.listOpSet(homeExplorerVO, loginUser); + // 排序 + break; + case "fileIconSize": + this.listOpSet(homeExplorerVO, loginUser); + // 图标大小 + break; + default: + } + return true; + } + + private void listType(HomeSettingDTO homeExplorerVO, LoginUser loginUser){ + this.updateSystemOption(homeExplorerVO, loginUser); + if ("icon".equals(homeExplorerVO.getValue())){ + Map map = new HashMap<>(1); + String value = userOptionDao.getUserOtherConfigByKey(loginUser.getUserID(), "folderInfo", homeExplorerVO.getKey()); + try { + if (!ObjectUtils.isEmpty(value)){ + map = JsonUtils.jsonToMap(value); + } + map.put(homeExplorerVO.getSourceID(), homeExplorerVO.getListViewValue()); + userOptionDao.updateOptionValueByKey(loginUser.getUserID(), homeExplorerVO.getKey(), JsonUtils.beanToJson(map),"folderInfo"); + }catch (Exception e){ + LogUtil.error(e, " folderSetting listType error " + JsonUtils.beanToJson(homeExplorerVO) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + } + } + } + private void updateSystemOption(HomeSettingDTO homeExplorerVO, LoginUser loginUser){ + try { + userOptionDao.updateSystemOptionValueByKey(loginUser.getUserID(), homeExplorerVO.getKey(), ObjectUtils.isEmpty(homeExplorerVO.getValue()) ? "" : homeExplorerVO.getValue()); + }catch (Exception e){ + LogUtil.error(e, " folderSetting error " + JsonUtils.beanToJson(homeExplorerVO) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + } + private void listOpSet(HomeSettingDTO homeExplorerVO, LoginUser loginUser){ + this.updateSystemOption(homeExplorerVO, loginUser); + // update listSortOrder + if(!ObjectUtils.isEmpty(homeExplorerVO.getListViewValue())){ + List listView = Arrays.asList(homeExplorerVO.getListViewValue().split(":")).stream().map(String::valueOf).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(listView) && listView.size() > 1){ + String listSortOrder = listView.get(1); + try { + userOptionDao.updateSystemOptionValueByKey(loginUser.getUserID(), "listSortOrder", listSortOrder); + }catch (Exception e){ + LogUtil.error(e, " folderSetting listOpSet listSortOrder error " + JsonUtils.beanToJson(homeExplorerVO) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + } + } + } + + Map map = new HashMap<>(1); + String value = userOptionDao.getUserOtherConfigByKey(loginUser.getUserID(), "folderInfo", homeExplorerVO.getListViewKey()); + try { + if (!ObjectUtils.isEmpty(value)){ + map = JsonUtils.jsonToMap(value); + } + map.put(homeExplorerVO.getSourceID(), homeExplorerVO.getListViewValue()); + userOptionDao.updateOptionValueByKey(loginUser.getUserID(), homeExplorerVO.getListViewKey(), JsonUtils.beanToJson(map),"folderInfo"); + }catch (Exception e){ + LogUtil.error(e, " folderSetting error " + JsonUtils.beanToJson(homeExplorerVO) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + } + } + @Override + public PageResult getPathLog(HomeExplorerDTO homeExplorerVO){ + if (ObjectUtils.isEmpty(homeExplorerVO.getSourceID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + PageResult pageResult = new PageResult<>(); + int isFolder = 0; + if (!ObjectUtils.isEmpty(homeExplorerVO.getIsFolder()) && homeExplorerVO.getIsFolder().intValue() == 1){ + isFolder = 1; + } + + PageHelper.startPage(homeExplorerVO.getCurrentPage(), homeExplorerVO.getPageSize()); + List list = ioSourceEventDao.getSourceEventBySourceID(homeExplorerVO.getSourceID(), isFolder); + if (CollectionUtils.isEmpty(list)){ + pageResult.setList(new ArrayList<>()); + pageResult.setTotal(0L); + return pageResult; + } + + for (IoSourceEventVo vo : list){ + if (ObjectUtils.isEmpty(vo.getNickname())){ + vo.setNickname("已删除"); + vo.setSex(1); + vo.setStatus(2); + vo.setAvatar(""); + } + } + PageInfo pageInfo = new PageInfo<>(list); + pageResult.setTotal(pageInfo.getTotal()); + pageResult.setList(pageInfo.getList()); + return pageResult; + } + + @Override + public Map systemOpenInfo(){ + Map reMap = new HashMap<>(6); + + List list = systemOptionDao.getSystemConfigByKeyList(Arrays.asList("systemName","systemDesc","passwordRule","needCheckCode", "seo", "seoDesc", "meta", "systemLogo", "browserLogo" + , "thirdLoginConfig", "registerConfig", "globalIcp","defaultHome")); + for (OptionVo vo : list){ + if (Arrays.asList("browserLogo","systemLogo").contains(vo.getKey()) && !ObjectUtils.isEmpty(vo.getValue())){ + reMap.put(vo.getKey(), FileUtil.getShowImageUrl(vo.getValue(), vo.getKey()+".png")); + }else { + reMap.put(vo.getKey(), ObjectUtils.isEmpty(vo.getValue()) ? "" : vo.getValue()); + } + + } + + if (!reMap.containsKey("defaultHome")){ + reMap.put("defaultHome", 2); + } + /** 插件列表 */ + reMap.put("pluginList", optionTool.pluginList()); + return reMap; + } + @Override + public HomeExplorerVO getHomeExplorer(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + + if(ObjectUtils.isEmpty(homeExplorerDTO.getSourceID()) || homeExplorerDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + HashOperations operationsOne = stringRedisTemplate.opsForHash(); + String homeExplorerKey = GlobalConfig.homeExplorerOneRedisKey + loginUser.getUserID(); + String secondKey = homeExplorerDTO.getSourceID() + ""; + HomeExplorerVO homeExplorerVO = null; + String valueOne = operationsOne.get(homeExplorerKey, secondKey); + if (!ObjectUtils.isEmpty(valueOne)) { + + try { + homeExplorerVO = JsonUtils.jsonToBean(valueOne, HomeExplorerVO.class); + }catch (Exception e){ + LogUtil.error(e, "getHomeExplorer 解析失败 valueOne=" +valueOne); + } + } + if (!ObjectUtils.isEmpty(homeExplorerVO)){ + + if (ObjectUtils.isEmpty(homeExplorerVO.getName())){ + homeExplorerVO.setName(null); + } + if (ObjectUtils.isEmpty(homeExplorerVO.getDescription())){ + homeExplorerVO.setDescription(null); + } + return homeExplorerVO; + } + + CommonSource commonSource = fileOptionTool.getSourceInfo(homeExplorerDTO.getSourceID()); + if(ObjectUtils.isEmpty(commonSource) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + homeExplorerVO = new HomeExplorerVO(); + homeExplorerVO.setSourceID(commonSource.getSourceID()); + homeExplorerVO.setFileID(commonSource.getFileID()); + homeExplorerVO.setParentID(commonSource.getParentID()); + homeExplorerVO.setParentLevel(commonSource.getParentLevel()); + homeExplorerVO.setName(commonSource.getName()); + homeExplorerVO.setDescription(commonSource.getDescription()); + homeExplorerVO.setPathDisplay(""); + if (!",0,".equals(commonSource.getParentLevel())) { + Long spaceID = 0L; + if (commonSource.getTargetType().intValue() == 1) { + List parentIDs = Arrays.asList(commonSource.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + spaceID = parentIDs.get(0); + } + Set pList = new HashSet<>(); + pList.add(commonSource.getParentLevel()); + Map parentPathDisplayMap = systemLogTool.getParentPathDisplayMap(pList); + + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + homeExplorerVO.setPathDisplay(systemLogTool.setParentPathDisplay(parentPathDisplayMap, commonSource.getParentLevel(), spaceID)); + } + } + + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()) + || Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType()) + || Arrays.asList(GlobalConfig.CAMERA_TYPE_ARR).contains(commonSource.getFileType())){ + HashOperations operations = stringRedisTemplate.opsForHash(); + String value = operations.get(GlobalConfig.temp_img_video_key, homeExplorerDTO.getSourceID() + ""); + if (ObjectUtils.isEmpty(value)) { + operations.put(GlobalConfig.temp_img_video_key, commonSource.getSourceID()+"", "0"); + + asyncCutImgUtil.AsyncExecVideoImgThumb(commonSource, stringRedisTemplate, true); + + operations.getOperations().expire(GlobalConfig.temp_img_video_key, 24, TimeUnit.HOURS); + } + } + + operationsOne.put(homeExplorerKey, secondKey, JsonUtils.beanToJson(homeExplorerVO)); + operationsOne.getOperations().expire(homeExplorerKey, 5, TimeUnit.MINUTES); + + if (ObjectUtils.isEmpty(homeExplorerVO.getName())){ + homeExplorerVO.setName(null); + } + if (ObjectUtils.isEmpty(homeExplorerVO.getDescription())){ + homeExplorerVO.setDescription(null); + } + return homeExplorerVO; + } + + + @Override + public HomeExplorerVO execImgVideoThumb(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + + if (1 != loginUser.getUserType()){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if(ObjectUtils.isEmpty(homeExplorerDTO.getSourceID()) || homeExplorerDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + CommonSource commonSource = fileOptionTool.getSourceInfo(homeExplorerDTO.getSourceID()); + if(ObjectUtils.isEmpty(commonSource) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + HomeExplorerVO homeExplorerVO = new HomeExplorerVO(); + homeExplorerVO.setSourceID(commonSource.getSourceID()); + homeExplorerVO.setParentID(commonSource.getParentID()); + homeExplorerVO.setParentLevel(commonSource.getParentLevel()); + homeExplorerVO.setName(commonSource.getName()); + homeExplorerVO.setDescription(commonSource.getDescription()); + homeExplorerVO.setPathDisplay(""); + if (!",0,".equals(commonSource.getParentLevel())) { + Long spaceID = 0L; + if (commonSource.getTargetType().intValue() == 1) { + List parentIDs = Arrays.asList(commonSource.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + spaceID = parentIDs.get(0); + } + Set pList = new HashSet<>(); + pList.add(commonSource.getParentLevel()); + Map parentPathDisplayMap = systemLogTool.getParentPathDisplayMap(pList); + + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + homeExplorerVO.setPathDisplay(systemLogTool.setParentPathDisplay(parentPathDisplayMap, commonSource.getParentLevel(), spaceID)); + } + } + + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()) + || Arrays.asList(GlobalConfig.CAMERA_TYPE_ARR).contains(commonSource.getFileType()) + || Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType())){ + asyncCutImgUtil.AsyncExecVideoImgThumb(commonSource, stringRedisTemplate, false); + } + homeExplorerVO.setPath(commonSource.getPath()); + return homeExplorerVO; + } + +} diff --git a/src/main/java/com/svnlan/home/service/impl/LogScheduleServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/LogScheduleServiceImpl.java new file mode 100644 index 0000000..332b3ed --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/LogScheduleServiceImpl.java @@ -0,0 +1,104 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.LogScheduleStateConstants; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.LogScheduleDao; +import com.svnlan.home.domain.LogSchedule; +import com.svnlan.home.enums.LogScheduleStateEnum; +import com.svnlan.home.service.LogScheduleService; +import com.svnlan.utils.LogUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: + * @Date: + * @Description: + */ +@Service +public class LogScheduleServiceImpl implements LogScheduleService { + + private static final Logger log = LoggerFactory.getLogger("error"); + + @Resource + LogScheduleDao logScheduleDao; + + /** + * 功能描述: 添加定时任务日志 + * + * @param commonScheduleId + * @return int + */ + @Override + public Long addLog(String commonScheduleId) { + LogSchedule logSchedule = new LogSchedule(); + logSchedule.setCommonScheduleId(commonScheduleId); + logSchedule.setState(LogScheduleStateConstants.UNSTART); + + int insert; + Date date = new Date(); + logSchedule.setGmtStart(date); + logSchedule.setGmtEnd(date); + try { + insert = logScheduleDao.insert(logSchedule.initializefield()); + } catch (Exception e) { + log.error("addLog error=" + e.getMessage()); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode(), e.getMessage()); + } + if (insert != 1) { + log.error("添加定时任务失败" + logSchedule); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode(), CodeMessageEnum.system_error.getMsg()); + } + return logSchedule.getLogScheduleId(); + } + + @Override + public int updateLog(Long logScheduleId, String state, String remark) { + int affectedCount = 0; + + Map map = new HashMap<>(); + map.put("logScheduleId", logScheduleId); + map.put("state", state); + map.put("gmtEnd", new Date()); + map.put("remark", remark); + // + affectedCount = this.logScheduleDao.updateLogSuccess(map); + + //执行失败才发送告警 + if(LogScheduleStateEnum.FAILURE.getCode().equals(state)) { + //发送钉钉机器人告警消息 + //this.sendDingTalkMsgForSchedule("发送钉钉机器人告警消息", logScheduleId); + } + return affectedCount; + } + + @Override +// @Transactional(value = tx,rollbackFor = Exception.class) + public LogSchedule logScheduleCheckAddTransaction(String scheduleId){ +// LogSchedule logSchedule = logScheduleDao.getLogScheduleInfoLock(scheduleId, new Date()); +// if (ObjectUtils.isEmpty(logSchedule)){ + //2021-06-17 固定插一条好了, 因为现在完成定时, log update的时候, 也只有其中一个实例里的结果数据会写进去 + //还不如所有实例都插一条数据 + LogSchedule logSchedule = new LogSchedule(); + logSchedule.setCommonScheduleId(scheduleId); + logSchedule.setState(LogScheduleStateConstants.UNSTART); + logSchedule.setRemark("本次读取日志文件 "); + long i = this.addLog(scheduleId); + if (i < 1) { + LogUtil.error("读取流量统计定时任务,添加定时任务logSchedule日志失败"); + return null; + } + log.info("Add log schedule {} ", logSchedule.toString()); +// } + return logSchedule; + } + +} diff --git a/src/main/java/com/svnlan/home/service/impl/M3u8ServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/M3u8ServiceImpl.java new file mode 100644 index 0000000..ed26f58 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/M3u8ServiceImpl.java @@ -0,0 +1,262 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.GetM3u8NewDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.service.M3u8Service; +import com.svnlan.home.utils.CommonConvertUtil; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.home.dto.*; +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.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Author: + * @Description: + * @Date: + */ +@Service +public class M3u8ServiceImpl implements M3u8Service { + @Resource + FileOptionTool fileOptionTool; + + @Resource + private LoginUserUtil loginUserUtil; + @Resource + private CommonConvertUtil commonConvertUtil; + + @Value("${ppt.replace.need}") + private String needReplace; + @Value("${cdn.domain}") + private String cdnDomain; + + private static Pattern tsPattern = Pattern.compile("(\\.ts$)", Pattern.MULTILINE); + private static Pattern oldServerPattern = Pattern.compile(GlobalConfig.oldInnerServer); + private static Pattern urlPattern = Pattern.compile(GlobalConfig.m3u8ConvertUrlPlaceholder); + private static String tsIdentifyKey = "wjsourcedomain"; + /** + * @Description: 获取m3u8加密的key + * @params: [key] + * @Return: void + * @Modified: + */ + @Override + public void getKey(String key,HttpServletResponse response) { + if (StringUtil.isEmpty(key)){ + return; + } + String decodeStr = AESUtil.decrypt(key, GlobalConfig.M3U8_AES_PASSWORD); + String[] decodeArr; + try { + decodeStr = URLDecoder.decode(decodeStr, "UTF-8"); + decodeArr = decodeStr.split(GlobalConfig.M3U8_KEY_INFO_SEPARATOR); + } catch (Exception e){ + LogUtil.error("解码失败,key:" + key); + return; + } + if (StringUtil.isEmpty(decodeArr[0]) || StringUtil.isEmpty(decodeArr[1])){ + LogUtil.error("解码数据不正确" + JsonUtils.beanToJson(decodeArr)); + return; + } + String filePath = decodeArr[1]; + String ext = filePath.substring(filePath.lastIndexOf(".") + 1); + File file = new File(filePath); + try (FileInputStream fis = new FileInputStream(file); ServletOutputStream sos = response.getOutputStream()) { + String mineType = MimeTypeEnum.getContentType(ext); + response.setContentType(mineType); + + IOUtils.copy(fis, sos); + fis.close(); + } catch (Exception e) { + e.printStackTrace(); + LogUtil.error("getVideoImgAttachmentWithName 拷贝文件流出错 filePath=" + filePath); + } + + /*try { +// LogUtil.info("KEY解码后内容:" + decodeStr); + //HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + FileUtil.responseFile(response, decodeArr[1], System.currentTimeMillis()+".m3u8", false); + } catch (Exception e){ + LogUtil.error(e, "获取key失败," + JsonUtils.beanToJson(decodeArr)); + }*/ + } + + private static boolean isApp(String ua) { + boolean check = false; + if (ua.toLowerCase().contains("ijkplayer")){ + check = true; + }else if (ua.toLowerCase().contains("Lavf")){ + check = true; + } + return check; + } + /** + * @Description: 获取m3u8文件 + * @params: [getM3u8DTO] + * @Return: void + * @Modified: + */ + @Override + public void getM3u8(GetM3u8DTO getM3u8DTO, HttpServletResponse response, HttpServletRequest request) { + String ua = request.getHeader("User-Agent"); + LogUtil.info("使用了老的m3u8接口, " + ua + ", " + request.getHeader("Referer") + + ", " + JsonUtils.beanToJson(getM3u8DTO) + ", " + IpUtil.getIp(request)); + // 20200927 老接口废弃,app暂时使用 VUL-9040 播放老接口废弃 + if (!isApp(ua)){ + return; + } + String filePath = null; + CommonSource commonSource = fileOptionTool.getFileAttachment(getM3u8DTO.getSourceID()); + + if (commonSource == null){ + // 记录不存在 + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + filePath = commonSource.getPreviewUrl(); + if (ObjectUtils.isEmpty(filePath)){ + LogUtil.error("m3u8查询失败" + JsonUtils.beanToJson(getM3u8DTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + //todo 等各端改造 +// this.checkM3u8Permission(m3u8, loginUser); + try { + //HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + LogUtil.info("m3u8文件路径:" + filePath); + if (!"m3u8".equals(FileUtil.getFileExtension(filePath))){ + // "类型不正确" + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + FileUtil.responseFile(response, filePath, System.currentTimeMillis() + ".m3u8", false); + } catch (Exception e){ + LogUtil.error(e, "m3u8获取失败"); + } + } + + /** + * @Description: 获取m3u8 + * @params: [getM3u8NewDTO, response, request] + * @Return: void + * @Modified: + */ + @Override + public String getM3u8WithAuth(GetM3u8NewDTO getM3u8NewDTO, HttpServletResponse response, HttpServletRequest request, int isApi) { + //免费的, 直接拥有权限 + boolean hasPermission = true; + LoginUser loginUser = null; + if (!hasPermission) { + if (StringUtil.isEmpty(getM3u8NewDTO.getKey())) { + // , "验证失败" + throw new SvnlanRuntimeException(CodeMessageEnum.errorAdminAuth.getCode()); + } + + //从key解密 + String keyString = AESUtil.decrypt(getM3u8NewDTO.getKey(), GlobalConfig.M3U8_PLAY_AES_KEY, true); + if (keyString == null) { + // "验证错误" + throw new SvnlanRuntimeException(CodeMessageEnum.errorAdminAuth.getCode()); + } + //[token, timestamp] + String[] keyArr = keyString.split(GlobalConfig.M3U8_PLAY_KEY_SEPARATOR); + String token = keyArr[0]; + loginUser = commonConvertUtil.getApiLoginUser(request, token, loginUserUtil); + // loginUserUtil.getLoginUserByToken(request, token); + if (loginUser == null || loginUser.getUserID() == null) { + // 用户验证失败 + throw new SvnlanRuntimeException(CodeMessageEnum.loginFirst.getCode()); + } + Long time = Long.parseLong(keyArr[1]); + //时间超过一天, 先记录, 暂不限制 + if (time + 86400000 < System.currentTimeMillis()) { + LogUtil.info("获取m3u8, key时间超限" + time + "+86400000 < " + System.currentTimeMillis() + + JsonUtils.beanToJson(getM3u8NewDTO)); + } + } + CommonSource commonSource = fileOptionTool.getFileAttachment(getM3u8NewDTO.getSourceID(), getM3u8NewDTO.getF()); + if (commonSource == null){ + // 记录不存在 + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + String filePath = commonSource.getPreviewUrl(); + if (ObjectUtils.isEmpty(filePath)){ + LogUtil.error("my_m3u8查询失败" + JsonUtils.beanToJson(getM3u8NewDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + try { + //HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + LogUtil.info("m3u8文件路径:" + filePath); + if (!"m3u8".equals(FileUtil.getFileExtension(filePath))){ + // 类型不正确 + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + File f = new File(filePath); + if (!f.exists()){ + // 文件不存在 + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String fileContent = FileUtil.getFileContent(f); + //String fileContent = FileUtil.getM3u8LineContent(filePath, commonSource.getSourceID() + "_" + commonSource.getFileID()); + if (fileContent != null){ + // 转码老域名处理url + return this.handleOldRootUrl(fileContent); + } + } catch (Exception e){ + LogUtil.error(e, "m3u8获取失败"); + } + return null; + } + + private String handleOldRootUrl(String fileContent){ + Matcher matcher = null; + String rootUrl = null; + if (!ObjectUtils.isEmpty(cdnDomain)){ + rootUrl = "//" + cdnDomain; + }else { + rootUrl = HttpUtil.getReqRootUrl(null); + } + //String rootUrl = ObjectUtils.isEmpty(this.cdnDomain) ? HttpUtil.getReqRootUrl(null) : "https://" + this.cdnDomain; + if ("1".equals(needReplace)){ + matcher = oldServerPattern.matcher(fileContent); + if (matcher.find()){ + return matcher.replaceAll(rootUrl); + } + } + matcher = urlPattern.matcher(fileContent); + if (matcher.find()){ + return matcher.replaceAll(rootUrl); + } + return fileContent; + } + + private String getTsWithDomainIdentify(String fileContent) { + Matcher matcher = tsPattern.matcher(fileContent); + if (matcher.find()){ + return matcher.replaceAll("$1\\?" + tsIdentifyKey +"=" + loginUserUtil.getServerName()); + } + return fileContent; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/MonitorServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/MonitorServiceImpl.java new file mode 100644 index 0000000..0161272 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/MonitorServiceImpl.java @@ -0,0 +1,112 @@ +package com.svnlan.home.service.impl; + +import com.aliyun.oss.common.utils.DateUtil; +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.I18nUtils; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.home.service.MonitorService; +import com.svnlan.user.domain.Email; +import com.svnlan.user.service.MailService; +import com.svnlan.utils.DateDUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.util.*; + +/** + * @Author: + * @Description: + * @Date: + */ +@Service +public class MonitorServiceImpl implements MonitorService { + + @Resource + private StringRedisTemplate stringRedisTemplate; + + @Resource + private RestTemplate restTemplate; + @Resource + MailService mailService; + @Value("${mail.encode.fail}") + private String convertFailMail; + + + /** + * @Description: 转码时长监控 + * @params: [resultMap] + * @Return: java.lang.String + * @Modified: + */ + @Override + public String videoConvertTime(Map resultMap) { + long nowTimestamp = System.currentTimeMillis(); + long startTimestamp = nowTimestamp - 7200 * 1000; + Set resultSet = stringRedisTemplate.opsForZSet().rangeByScore(GlobalConfig.CONVERT_TIME_KEY, startTimestamp, nowTimestamp); + if (CollectionUtils.isEmpty(resultSet)){ + return "最近2小时发起的转码, 没有还在继续的"; + } + //40分钟以上的 + List fortyMinutesList = new ArrayList<>(); + //一小时以上的 + List hourList = new ArrayList<>(); + //一个半小时以上的 + List hourAndHalfList = new ArrayList<>(); + List otherList = new ArrayList<>(); + for (String result : resultSet){ + String timeStr = result.substring(result.length() - 13); + long timestamp = Long.valueOf(timeStr); + if (nowTimestamp - timestamp > 5400 * 1000){//1个半小时 + hourAndHalfList.add(result); + } else if (nowTimestamp - timestamp > 3600 * 1000){//1个小时 + hourList.add(result); + } else if (nowTimestamp - timestamp > 2400 * 1000){//40分钟 + fortyMinutesList.add(result); + } else { + otherList.add(result); + } + } + resultMap.put("fortyMinutesList", fortyMinutesList); + resultMap.put("hourList", hourList); + resultMap.put("hourAndHalfList", hourAndHalfList); + resultMap.put("otherList", otherList); + + if (!ObjectUtils.isEmpty(convertFailMail)){ + try {//发送邮件 + if (fortyMinutesList.size() > 0 || hourList.size() > 0 || hourAndHalfList.size() > 0){ + + String text = "转码时长报表: 1小时, " + JsonUtils.beanToJson(hourList) + + ", 1个半小时, " + JsonUtils.beanToJson(hourAndHalfList) + ", 40分钟, " + JsonUtils.beanToJson(fortyMinutesList); + + String time = DateDUtil.getYearMonthDayHMS(new Date(), "yyyy-MM-dd HH:mm:ss"); + + Email email = new Email(); + email.setSubject("【转码异常】"); + email.setContent("视频ID: " + text + " 转码失败,失败时间: " + time); + + try { + mailService.sendEncodeFailNotify(email); + LogUtil.info("videoConvertTime sendEncodeFailNotify 转码时长报表发送成功, paramMap=" + JsonUtils.beanToJson(email)); + } catch (Exception e) { + LogUtil.error(e, "videoConvertTime sendEncodeFailNotify=>邮箱发送异常 paramMap=" + JsonUtils.beanToJson(email)); + } + } + } catch (Exception e){ + LogUtil.error(e, "videoConvertTime 转码时长报表邮件失败"); + } + } + + return "转码时长报表 40分钟 " + fortyMinutesList.size() + "个" + ", " + + "1小时 " + hourList.size() + "个" + ", " + + "1个半小时 " + hourAndHalfList.size() + "个" + ", " + + "其他 " + otherList.size() + "个"; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/ShareServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/ShareServiceImpl.java new file mode 100644 index 0000000..5d8d53f --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/ShareServiceImpl.java @@ -0,0 +1,1197 @@ +package com.svnlan.home.service.impl; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.I18nUtils; +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.LogTypeEnum; +import com.svnlan.enums.SourceFieldEnum; +import com.svnlan.enums.SourceSortEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.HomeExplorerDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.dao.ShareDao; +import com.svnlan.home.dao.ShareToDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IoSourceEvent; +import com.svnlan.home.domain.Share; +import com.svnlan.home.domain.ShareTo; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.dto.ShareDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.service.ShareService; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.utils.UserAuthTool; +import com.svnlan.home.vo.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SourceOperateTool; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.dao.GroupDao; +import com.svnlan.user.dao.RoleDao; +import com.svnlan.user.dao.UserDao; +import com.svnlan.user.dao.UserGroupDao; +import com.svnlan.user.domain.Group; +import com.svnlan.user.domain.Role; +import com.svnlan.user.dto.GroupDTO; +import com.svnlan.user.dto.UserDTO; +import com.svnlan.user.service.ShareReportService; +import com.svnlan.user.service.UserManageService; +import com.svnlan.user.vo.SelectAuthVo; +import com.svnlan.user.vo.UserGroupVo; +import com.svnlan.user.vo.UserVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.PageResult; +import com.svnlan.utils.RandomUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/3 13:33 + */ +@Service +public class ShareServiceImpl implements ShareService { + + @Resource + ShareDao shareDao; + @Resource + SystemSortTool systemSortTool; + @Resource + SourceOperateTool sourceOperateTool; + @Resource + FileOptionTool fileOptionTool; + @Resource + UserDao userDao; + @Resource + UserGroupDao userGroupDao; + @Resource + HomeExplorerDao homeExplorerDao; + @Resource + ShareToDao shareToDao; + @Resource + GroupDao groupDao; + + @Resource + SystemLogTool systemLogTool; + @Resource + IoSourceDao ioSourceDao; + @Resource + UserManageService userManageService; + @Resource + RoleDao roleDao; + @Resource + UserAuthTool userAuthTool; + + @Override + public void saveShare(ShareDTO shareDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(shareDTO.getSourceID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!ObjectUtils.isEmpty(shareDTO.getTitle()) && shareDTO.getTitle().length() > 255){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + shareDTO.setIsLink(ObjectUtils.isEmpty(shareDTO.getIsLink()) ? 1 : shareDTO.getIsLink()); + shareDTO.setIsShareTo(ObjectUtils.isEmpty(shareDTO.getIsShareTo()) ? 0 : shareDTO.getIsShareTo()); + if (1 == shareDTO.getIsShareTo()){ + shareDTO.setIsLink(0); + } + + CommonSource commonSource = fileOptionTool.getSourceInfo(shareDTO.getSourceID()); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + // 判断是否可以分享 + if (!Objects.equals(commonSource.getCanShare(), 1)) { + throw new SvnlanRuntimeException(CodeMessageEnum.sourceShareDisabled.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), "11", commonSource.getTargetType()); + + Share share = new Share(); + share.setUserID(loginUser.getUserID()); + share.setTitle(ObjectUtils.isEmpty(shareDTO.getTitle()) ? commonSource.getName() : shareDTO.getTitle()); + share.setUrl(""); + share.setSourceID(shareDTO.getSourceID()); + share.setOptions(ObjectUtils.isEmpty(shareDTO.getOptions()) ? "" : shareDTO.getOptions()); + share.setSourcePath(commonSource.getParentLevel()); + share.setIsLink(shareDTO.getIsLink()); + share.setIsShareTo(shareDTO.getIsShareTo()); + share.setTimeTo(ObjectUtils.isEmpty(shareDTO.getTimeTo()) ? 0L : shareDTO.getTimeTo()); + share.setNumDownload(0); + share.setNumView(0); + share.setPassword(ObjectUtils.isEmpty(shareDTO.getPassword()) ? "" : shareDTO.getPassword()); + String msg = (1 == shareDTO.getIsShareTo()) ? "内部协作" : "分享链接"; + + String logCode = null; + EventEnum eventEnum = null; + + ShareVo vo = shareDao.getShare(shareDTO.getSourceID(), loginUser.getUserID(), shareDTO.getIsShareTo(), shareDTO.getIsLink()); + if (!ObjectUtils.isEmpty(vo)){ + shareDTO.setShareID(vo.getShareID()); + share.setShareID(vo.getShareID()); + } + + if (!ObjectUtils.isEmpty(shareDTO.getShareID()) && shareDTO.getShareID() > 0){ + share.setShareID(shareDTO.getShareID()); + if (1 == shareDTO.getIsShareTo()) { + logCode = LogTypeEnum.fileshareEdit.getCode(); + eventEnum = EventEnum.shareEdit; + }else { + logCode = LogTypeEnum.fileShareLinkEdit.getCode(); + eventEnum = EventEnum.shareLinkEdit; + } + try { + // 可分享状态 + share.setStatus(1); + shareDao.update(share); + }catch (Exception e){ + LogUtil.error("编辑" + msg + "失败!shareDTO=" + JsonUtils.beanToJson(shareDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + }else { + + + // 内部协作authTo + if (1 == shareDTO.getIsShareTo()) { + logCode = LogTypeEnum.fileShareToAdd.getCode(); + eventEnum = EventEnum.shareToAdd; + }else { + logCode = LogTypeEnum.fileShareLinkAdd.getCode(); + eventEnum = EventEnum.shareLinkAdd; + } + + share.setShareHash(ObjectUtils.isEmpty(shareDTO.getShareHash()) ? RandomUtil.getStringAndNum(10) : shareDTO.getShareHash()); + try { + shareDao.insert(share); + }catch (Exception e){ + LogUtil.error("添加" + msg + "接失败!"); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + } + + // 内部协作authTo + if (1 == shareDTO.getIsShareTo() && !ObjectUtils.isEmpty(share.getShareID())){ + // 删除后添加 + shareToDao.delete(share.getShareID()); + + if (!CollectionUtils.isEmpty(shareDTO.getAuthTo())){ + List toList = new ArrayList<>(); + ShareTo shareTo = null; + for (ShareAuthDto authDto : shareDTO.getAuthTo()){ + if (ObjectUtils.isEmpty(authDto.getAuthID()) || ObjectUtils.isEmpty(authDto.getTargetID()) || ObjectUtils.isEmpty(authDto.getTargetType())){ + continue; + } + shareTo = new ShareTo(); + shareTo.setShareID(share.getShareID()); + shareTo.setAuthDefine(-1); + shareTo.setAuthID(authDto.getAuthID()); + shareTo.setTargetID(authDto.getTargetID()); + shareTo.setTargetType(authDto.getTargetType()); + toList.add(shareTo); + } + + if (!CollectionUtils.isEmpty(toList)){ + try { + shareToDao.batchInsert(toList); + }catch (Exception e){ + LogUtil.error("添加" + msg + " shareTo insert 失败!"); + + } + } + } + + } + + + + // 添加文档操作event + fileOptionTool.addSourceEvent(commonSource.getSourceID(), commonSource.getParentID(), loginUser.getUserID(), commonSource.getName(), eventEnum); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + reMap.put("type", "share"); + reMap.put("pathName", commonSource.getSourceName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, logCode, paramList, systemLogTool.getRequest()); + + } + + @Override + public void cancelShare(ShareDTO shareDTO, LoginUser loginUser){ + + List deleteList = null; + if (!ObjectUtils.isEmpty(shareDTO.getShareID())){ + deleteList = Arrays.asList(shareDTO.getShareID()); + } + if (!ObjectUtils.isEmpty(shareDTO.getShareIDStr())){ + deleteList = Arrays.asList(shareDTO.getShareIDStr().split(",")).stream().map(Long::parseLong).collect(Collectors.toList()); + } + if (CollectionUtils.isEmpty(deleteList) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List list = shareDao.getShareByIdList(deleteList); + if (CollectionUtils.isEmpty(list) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + ShareVo vo = list.get(0); + try { + shareDao.deleteList(deleteList); + }catch (Exception e){ + LogUtil.error("删除分享链接失败!shareDTO=" + JsonUtils.beanToJson(shareDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + if (!ObjectUtils.isEmpty(vo) && !ObjectUtils.isEmpty(vo.getIsShareTo()) && 1 == vo.getIsShareTo()){ + // 删除分享关系 + shareToDao.deleteList(deleteList); + } + + List sourceIDs = list.stream().map(ShareVo::getSourceID).collect(Collectors.toList()); + List sourceList = ioSourceDao.getSourceInfoList(sourceIDs); + if (CollectionUtils.isEmpty(sourceList)){ + return; + } + EventEnum eventEnum = EventEnum.shareLinkRemove; + String logCode = LogTypeEnum.shareLinkRemove.getCode(); + // 内部协作authTo + if (0 == vo.getIsLink()) { + eventEnum = EventEnum.shareToRemove; + logCode = LogTypeEnum.fileShareToRemove.getCode(); + } + List eventList = new ArrayList<>(); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + for (CommonSource data : sourceList){ + eventList.add(new IoSourceEvent(data.getSourceID(), data.getParentID(), loginUser.getUserID(), eventEnum.getCode(), FileOptionTool.getSourceEventDesc(eventEnum, "", ""))); + + reMap = new HashMap<>(4); + reMap.put("sourceID", data.getSourceID()); + reMap.put("sourceParent", data.getParentID()); + reMap.put("type", "share"); + reMap.put("pathName", data.getSourceName()); + paramList.add(reMap); + } + // 添加文档操作event + fileOptionTool.addSourceEventList(eventList); + /** 操作日志 */ + systemLogTool.setSysLog(loginUser, logCode, paramList, systemLogTool.getRequest()); + } + + @Override + public ShareVo getShare(ShareDTO shareDTO, LoginUser loginUser){ + ShareVo vo = null; + shareDTO.setIsLink(ObjectUtils.isEmpty(shareDTO.getIsLink()) ? 1 : shareDTO.getIsLink()); + shareDTO.setIsShareTo(0); + if (!ObjectUtils.isEmpty(shareDTO.getIsShareTo()) && 1 == shareDTO.getIsShareTo()){ + shareDTO.setIsLink(0); + shareDTO.setIsShareTo(1); + } + if (!ObjectUtils.isEmpty(shareDTO.getSourceID()) && shareDTO.getSourceID() > 0){ + vo = shareDao.getShare(shareDTO.getSourceID(), loginUser.getUserID(), shareDTO.getIsShareTo(), shareDTO.getIsLink()); + }else if (!ObjectUtils.isEmpty(shareDTO.getShareID()) && shareDTO.getShareID() > 0){ + vo = shareDao.getShareById(shareDTO.getShareID()); + } + if (ObjectUtils.isEmpty(vo)){ + return new ShareVo(); + } + vo.setAuthTo(new ArrayList<>()); + // 获取被分享的部门或者个人 + if (1 == shareDTO.getIsShareTo()){ + List shareToList = shareToDao.getShareToList(vo.getShareID()); + if (!CollectionUtils.isEmpty(shareToList)){ + vo.setAuthTo(shareToList); + } + } + return vo; + } + + @Override + public HomeExplorerResult getShareList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + boolean checkGet = false; + List roleList = null; + String auth = ""; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + auth = GlobalConfig.SYSTEM_GROUP_AUTH; + checkGet = true; + + Role role = roleDao.getSystemRoleInfo(); + roleList = new ArrayList<>(); + roleList.add(new IoSourceAuthVo(role.getRoleID(), role.getRoleName(), role.getLabel(), auth)); + } + Map hashMap = new HashMap<>(3); + hashMap.put("userID", loginUser.getUserID()); + + homeExplorerDTO.setIsLink(ObjectUtils.isEmpty(homeExplorerDTO.getIsLink()) ? 1 : homeExplorerDTO.getIsLink()); + homeExplorerDTO.setIsShareTo(0); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getIsShareTo()) && 1 == homeExplorerDTO.getIsShareTo()){ + homeExplorerDTO.setIsLink(0); + homeExplorerDTO.setIsShareTo(1); + } + hashMap.put("isShareTo", homeExplorerDTO.getIsShareTo()); + hashMap.put("isLink", homeExplorerDTO.getIsLink()); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getKeyword())){ + hashMap.put("keyword", homeExplorerDTO.getKeyword().toLowerCase()); + } + + SystemSortVo systemSortVo = systemSortTool.getUserSort(loginUser.getUserID()); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getSortField()) && !ObjectUtils.isEmpty(homeExplorerDTO.getSortType())){ + hashMap.put("sortType", SourceSortEnum.getSortType(homeExplorerDTO.getSortType())); + hashMap.put("sortField", "io." + SourceFieldEnum.getSortField(homeExplorerDTO.getSortField())); + }else { + String sortType = systemSortVo.getListSortOrder(); + String sortField = systemSortVo.getListSortField(); + hashMap.put("sortType", SourceSortEnum.getSortType(sortType)); + hashMap.put("sortField", "io." + SourceFieldEnum.getSortField(sortField)); + if ("1".equals(systemSortVo.getListSortKeep()) && !CollectionUtils.isEmpty(systemSortVo.getListSortList())){ + for (SystemSortVo vo : systemSortVo.getListSortList()){ + if (vo.getSourceID().equals(String.valueOf(homeExplorerDTO.getSourceID()))){ + if (!ObjectUtils.isEmpty(vo.getListSortOrder())) { + hashMap.put("sortType", SourceSortEnum.getSortType(vo.getListSortOrder())); + } + if (!ObjectUtils.isEmpty(vo.getListSortField())) { + hashMap.put("sortField", "io." + SourceFieldEnum.getSortField(vo.getListSortField())); + } + break; + } + } + } + } + PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + List list = this.shareDao.getShareList(hashMap); + + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + FileMetaVo fileMetaVo = null; + String downloadKey = FileUtil.getDownloadKey(); + List idList = new ArrayList<>(); + List sourceIDs= new ArrayList<>(); + Set uidList = new HashSet<>(); + Set gpidList = new HashSet<>(); + Set sidList = new HashSet<>(); + Set pLevelList = new HashSet<>(); + long spaceId = 0; + for (HomeExplorerVO vo2 : list){ + if (vo2.getIsFolder().intValue() == 1){ + idList.add(vo2.getSourceID()); + } + sourceIDs.add(vo2.getSourceID().toString()); + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + + if (!checkGet && vo2.getTargetType().intValue() == 2){ + checkGet = true; + sidList.add(vo2.getSourceID()); + if (!",0,".equals(vo2.getParentLevel())) { + Set aList = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toSet()); + gpidList.addAll(aList); + sidList.addAll(aList); + } + } + if (spaceId == 0 && 1 == vo2.getTargetType() && !",0,".equals(vo2.getParentLevel())){ + List list1 = Arrays.asList(vo2.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + spaceId = list1.get(0); + } + pLevelList.add(vo2.getParentLevel()); + } + + Map> gsFileAuthMap = new HashMap<>(1); + // 文件权限 + if (!CollectionUtils.isEmpty(sidList)){ + sourceOperateTool.getFileAuthByLevel(loginUser.getUserID(), sidList, gsFileAuthMap); + } + + Map gsAuthMap = new HashMap<>(); + Map gsAuthNameMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(gpidList)){ + sourceOperateTool.getUserAuthByLevel(loginUser.getUserID(), new ArrayList<>(gpidList), gsAuthMap, gsAuthNameMap); + } + Map parentPathDisplayMap = null; + // 文件位置 + if (!CollectionUtils.isEmpty(pLevelList)) { + parentPathDisplayMap = sourceOperateTool.getParentPathDisplayMap(pLevelList); + + } + if (spaceId == 0){ + HomeExplorerVO space = homeExplorerDao.getHomeSpace(loginUser.getUserID(), 0L); + spaceId = space.getSourceID(); + } + // 标签 + Map> sourceTagMap = fileOptionTool.getSourceTagMap(loginUser.getUserID(), sourceIDs); + // 收藏 + List myFavList = fileOptionTool.checkIsFavByUserId(loginUser.getUserID()); + + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + List countList = CollectionUtils.isEmpty(idList) ? null : homeExplorerDao.getSourceChileCont(idList); + Map countMap = new HashMap<>(1); + if (!CollectionUtils.isEmpty(countList)) { + for (HomeExplorerVO home : countList) { + countMap.put(home.getParentID() + (home.getIsFolder().intValue() == 1 ? "_folder" : "_file"), home.getFileCount()); + } + } + for (HomeExplorerVO vo1 : list){ + vo1.setAuth(auth); + if (ObjectUtils.isEmpty(auth) && vo1.getTargetType().intValue() == 2 ){ + if (!ObjectUtils.isEmpty(gsFileAuthMap) && gsFileAuthMap.containsKey(vo1.getSourceID())){ + vo1.setRoleList(JsonUtils.beanToJson(gsFileAuthMap.get(vo1.getSourceID()))); + }else { + // 上级部门权限 + if (!ObjectUtils.isEmpty(gsAuthMap)) { + vo1.setAuth(sourceOperateTool.getAuthByLevel(vo1,vo1.getParentLevel(), gsAuthMap, gsAuthNameMap)); + } + } + if (ObjectUtils.isEmpty(vo1.getAuth()) || "0".equals(vo1.getAuth())){ + // 不可见 + continue; + } + if (!Arrays.asList(vo1.getAuth().split(",")).stream().collect(Collectors.toList()).contains("1")){ + // 无列表权限 + continue; + } + } + vo1.setDownloadUrl(""); + vo1.setHasFile(0); + vo1.setHasFolder(0); + vo1.setResolution(""); + vo1.setLength(0); + vo1.setThumb(""); + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_folder")){ + vo1.setHasFolder(countMap.get(vo1.getSourceID() + "_folder")); + } + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_file")){ + vo1.setHasFile(countMap.get(vo1.getSourceID() + "_file")); + } + + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + + // path 处理 + sourceOperateTool.opPath( vo1, downloadKey, vo1.getShareHash(),"4"); + + // 是否收藏 + vo1.setIsFav(!CollectionUtils.isEmpty(myFavList) && myFavList.contains(vo1.getSourceID().toString()) ? 1 : 0); + // 已选标签 + vo1.setTags(""); + vo1.setTagList(new ArrayList<>()); + if (!ObjectUtils.isEmpty(sourceTagMap) && sourceTagMap.containsKey(vo1.getSourceID().toString())){ + vo1.setTagList(sourceTagMap.get(vo1.getSourceID().toString())); + } + // 是否分享 + vo1.setIsShare(1); + + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? vo1.getThumb() : vo1.getPath()); + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? "" : vo1.getPath()); + vo1.setPathDisplay(""); + if (!ObjectUtils.isEmpty(parentPathDisplayMap)) { + vo1.setPathDisplay(sourceOperateTool.setParentPathDisplay(parentPathDisplayMap, vo1.getParentLevel(), spaceId)); + } + if (vo1.getIsFolder() == 1) { + vo1.setIcon("folder"); + folderVOList.add(vo1); + } else { + vo1.setIcon("file"); + fileVOList.add(vo1); + } + + } + } + PageInfo pageInfo = new PageInfo<>(list); + result.setTotal(pageInfo.getTotal()); + result.setFolderList(folderVOList); + result.setFileList(fileVOList); + + return sourceOperateTool.setSystemReturn(result, systemSortVo, String.valueOf(homeExplorerDTO.getSourceID())); + } + + @Resource + private ShareReportService shareReportService; + + @Override + public ShareVo getShareFile(ShareDTO shareDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(shareDTO.getShareCode())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareNotExist.getCode()); + } + List list = shareDao.getShareByCode(shareDTO.getShareCode()); + if (CollectionUtils.isEmpty(list) || list.size() > 1){ + //throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorPathTips.getCode()); + return null; + } + ShareVo vo = list.get(0); + String password = vo.getPassword(); + vo.setPassword(null); + vo.setNeedPwd(0); + if (ObjectUtils.isEmpty(vo.getNickname())){ + vo.setNickname(vo.getUserName()); + } + // 密码 + if (!ObjectUtils.isEmpty(password)){ + if (ObjectUtils.isEmpty(shareDTO.getPassword()) || !password.equals(shareDTO.getPassword())){ + vo.setNeedPwd(1); + vo.setSuccess(false); + vo.setMessage(I18nUtils.i18n(CodeMessageEnum.ERROR_USER_PASSWORD_ERROR.getCode())); + return vo; + } + } + // 是否过期 + if (!ObjectUtils.isEmpty(vo.getTimeTo()) && vo.getTimeTo() > 0 && vo.getTimeTo() < System.currentTimeMillis() / 1000){ + vo.setSuccess(false); + vo.setMessage(I18nUtils.i18n(CodeMessageEnum.shareExpiredTips.getCode())); + return vo; + } + Map optionsMap = new HashMap<>(); + if (!ObjectUtils.isEmpty(vo.getOptions())){ + optionsMap = JsonUtils.jsonToBean(vo.getOptions(), Map.class); + } + vo.setLogin(0); + vo.setDown(0); + vo.setPreview(0); + vo.setDownNum(0); + vo.setShareToTimeout(0L); + boolean checkDown = false; + + // notView 是否禁用浏览 + if (optionsMap.containsKey("preview")) { + String previewStr = optionsMap.get("preview").toString(); + if (!ObjectUtils.isEmpty(previewStr)) { + vo.setPreview(Integer.parseInt(previewStr)); + } + } + // notDownload 是否禁用下载 + if (optionsMap.containsKey("down")) { + String downStr = optionsMap.get("down").toString(); + if (!ObjectUtils.isEmpty(downStr)) { + vo.setDown(Integer.parseInt(downStr)); + } + } + + if (vo.getDown().intValue() == 1 && optionsMap.containsKey("downNum")){ + String downNumStr = optionsMap.get("downNum").toString(); + if (!ObjectUtils.isEmpty(downNumStr)){ + int downNum = Integer.parseInt(downNumStr); + vo.setDownNum(downNum); + if ("0".equals(downNumStr) || downNum > vo.getNumDownload()){ + checkDown = true; + } + }else { + checkDown = true; + } + } + + // 判断该分享链接是否有效 + shareReportService.checkIfShareLinkPermit(vo); + + // login 是否需要登录 1 是 0 否 + if (optionsMap.containsKey("login")) { + String login = optionsMap.get("login").toString(); + if (!ObjectUtils.isEmpty(login) && "1".equals(login) && ObjectUtils.isEmpty(loginUser)) { + vo.setLogin(1); + vo.setSuccess(false); + vo.setMessage(I18nUtils.i18n(CodeMessageEnum.shareLoginTips.getCode())); + return vo; + } + } + + HomeExplorerVO homeExplorerVO = shareDao.getLinkShareInfo(vo.getSourceID()); + if (ObjectUtils.isEmpty(homeExplorerVO)){ + vo.setSuccess(false); + vo.setMessage(I18nUtils.i18n(CodeMessageEnum.shareNotExist.getCode())); + return vo; + } + Set uidList = new HashSet<>(); + uidList.add(homeExplorerVO.getCreateUser()); + uidList.add(homeExplorerVO.getModifyUser()); + + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + + FileMetaVo fileMetaVo = null; + homeExplorerVO.setDownloadUrl(""); + homeExplorerVO.setHasFile(0); + homeExplorerVO.setHasFolder(0); + homeExplorerVO.setResolution(""); + homeExplorerVO.setLength(0); + homeExplorerVO.setThumb(""); + sourceOperateTool.setFileMetaValue(fileMetaVo, homeExplorerVO); + + + + // 用户信息 + homeExplorerVO.setCreateUserJson(JsonUtils.beanToJson(userMap.get(homeExplorerVO.getCreateUser()))); + homeExplorerVO.setModifyUserJson(JsonUtils.beanToJson(userMap.get(homeExplorerVO.getModifyUser()))); + String downloadKey = FileUtil.getDownloadKey(); + sourceOperateTool.opPath(homeExplorerVO, downloadKey, shareDTO.getShareCode(), "4"); + // 是否分享 + homeExplorerVO.setIsShare(1); + + homeExplorerVO.setPath(ObjectUtils.isEmpty(homeExplorerVO.getPath()) ? homeExplorerVO.getThumb() : homeExplorerVO.getPath()); + homeExplorerVO.setPath(ObjectUtils.isEmpty(homeExplorerVO.getPath()) ? "" : homeExplorerVO.getPath()); + if (!checkDown){ + homeExplorerVO.setDownloadUrl(""); + } + if (vo.getPreview().intValue() == 1){ + if (Arrays.asList(GlobalConfig.DOC_SHOW_TYPE_ARR).contains(homeExplorerVO.getFileType())) { + String downloadUrl = "/api/disk/attachment/" + FileUtil.encodeDownloadUrl(homeExplorerVO.getName()) + + "?busId=" + homeExplorerVO.getSourceID() + "&busType=" + BusTypeEnum.CLOUD.getBusType() + "&key=" + downloadKey; + String pptPreviewUrl = fileOptionTool.getPptPreviewUrl(downloadUrl, homeExplorerVO.getHashMd5()); + homeExplorerVO.setPptPreviewUrl(pptPreviewUrl); + } + } + vo.setShareFile(homeExplorerVO); + // downNum 下载次数 + if (!checkDown){ + vo.setSuccess(false); + // 抱歉,该分享下载次数超过分享者设置的上限 + vo.setMessage(I18nUtils.i18n(CodeMessageEnum.shareDownExceedTips.getCode())); + return vo; + } + + vo.setSuccess(true); + return vo; + } + + + @Override + public HomeExplorerResult getLinkShareList(HomeExplorerDTO homeExplorerDTO){ + if (ObjectUtils.isEmpty(homeExplorerDTO.getShareCode()) || ObjectUtils.isEmpty(homeExplorerDTO.getSourceID()) + || homeExplorerDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareNotExist.getCode()); + } + List shareList = shareDao.getShareByCode(homeExplorerDTO.getShareCode()); + if (CollectionUtils.isEmpty(shareList) || shareList.size() > 1){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorPathTips.getCode()); + } + ShareVo vo = shareList.get(0); + Map optionsMap = new HashMap<>(); + if (!ObjectUtils.isEmpty(vo.getOptions())){ + optionsMap = JsonUtils.jsonToBean(vo.getOptions(), Map.class); + } + try { + shareDao.updateNumView(vo.getShareID(), vo.getNumView() + 1); + }catch (Exception e){ + LogUtil.error("getLinkShareList updateNumView error"); + } + + vo.setDown(0); + vo.setPreview(0); + boolean checkDown = false; + // notView 是否禁用浏览 + if (optionsMap.containsKey("preview")) { + String previewStr = optionsMap.get("preview").toString(); + if (!ObjectUtils.isEmpty(previewStr)) { + vo.setPreview(Integer.parseInt(previewStr)); + } + } + // notDownload 是否禁用下载 + if (optionsMap.containsKey("down")) { + String downStr = optionsMap.get("down").toString(); + if (!ObjectUtils.isEmpty(downStr)) { + vo.setDown(Integer.parseInt(downStr)); + } + } + if (vo.getDown().intValue() ==1){ + Object downNumStr = optionsMap.get("downNum"); + if (!ObjectUtils.isEmpty(downNumStr)){ + int downNum = Integer.parseInt(downNumStr.toString()); + vo.setDownNum(downNum); + if ("0".equals(downNumStr) || downNum > vo.getNumDownload()){ + checkDown = true; + } + }else { + checkDown = true; + } + } + + Map hashMap = new HashMap<>(3); + hashMap.put("parentID", homeExplorerDTO.getSourceID()); + hashMap.put("sortType", SourceSortEnum.asc.getValue()); + hashMap.put("sortField", SourceFieldEnum.name.getValue()); + // 左边菜单时 + if (!ObjectUtils.isEmpty(homeExplorerDTO.getIsFolder())){ + hashMap.put("isFolder", homeExplorerDTO.getIsFolder()); + } + + PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + List list = this.shareDao.getLinkShareList(hashMap); + + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + FileMetaVo fileMetaVo = null; + String downloadKey = FileUtil.getDownloadKey(); + List idList = new ArrayList<>(); + List sourceIDs= new ArrayList<>(); + Set uidList = new HashSet<>(); + for (HomeExplorerVO vo2 : list){ + if (vo2.getIsFolder().intValue() == 1){ + idList.add(vo2.getSourceID()); + } + sourceIDs.add(vo2.getSourceID().toString()); + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + } + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + List countList = CollectionUtils.isEmpty(idList) ? null : homeExplorerDao.getSourceChileCont(idList); + Map countMap = new HashMap<>(1); + if (!CollectionUtils.isEmpty(countList)) { + for (HomeExplorerVO home : countList) { + countMap.put(home.getParentID() + (home.getIsFolder().intValue() == 1 ? "_folder" : "_file"), home.getFileCount()); + } + } + for (HomeExplorerVO vo1 : list){ + + vo1.setDown(vo.getDown()); + vo1.setPreview(vo.getPreview()); + + vo1.setDownloadUrl(""); + vo1.setHasFile(0); + vo1.setHasFolder(0); + vo1.setResolution(""); + vo1.setLength(0); + vo1.setThumb(""); + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_folder")){ + vo1.setHasFolder(countMap.get(vo1.getSourceID() + "_folder")); + } + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_file")){ + vo1.setHasFile(countMap.get(vo1.getSourceID() + "_file")); + } + + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + vo1.setYzEditData(""); + if (vo1.getPreview().intValue() == 0){ + vo1.setYzViewData(""); + } + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + if (vo1.getIsFolder() == 0) { + // path 处理 + sourceOperateTool.opPath(vo1, downloadKey, homeExplorerDTO.getShareCode(), "4"); + } + // 是否分享 + vo1.setIsShare(1); + + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? vo1.getThumb() : vo1.getPath()); + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? "" : vo1.getPath()); + + if (vo1.getIsFolder() == 1) { + vo1.setIcon("folder"); + folderVOList.add(vo1); + } else { + + vo1.setIcon("file"); + fileVOList.add(vo1); + } + + } + } + PageInfo pageInfo = new PageInfo<>(list); + result.setTotal(pageInfo.getTotal()); + result.setFolderList(folderVOList); + result.setFileList(fileVOList); + + return result; + } + + @Override + public HomeExplorerResult shareToMeList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + + Map hashMap = new HashMap<>(3); + hashMap.put("userID", loginUser.getUserID()); + hashMap.put("isShareTo", 1); + hashMap.put("isLink", 0); + + SystemSortVo systemSortVo = systemSortTool.getUserSort(loginUser.getUserID()); + systemSortTool.setSortAboutMap(systemSortVo,hashMap, loginUser.getUserID(), homeExplorerDTO.getSortField(), homeExplorerDTO.getSortType() + , "shareToMe"); + + /* + 该部门成员协作分享时,可以选择其他所有部门(及用户) all-所有 hide-仅支持选择当前部门及子部门(及用户) select-指定部门 + private String authShowType; + authShowType 指定部门的id,多个部门用英文逗号隔开 + private String authShowGroup; + */ + List groupIDList = null; + // 用户部门权限 + List userGroupList = userAuthTool.getUserGroupAuth(loginUser.getUserID()); + if (!CollectionUtils.isEmpty(userGroupList)){ + groupIDList = userGroupList.stream().map(UserGroupVo::getGroupID).collect(Collectors.toList()); + hashMap.put("list", groupIDList); + } + PageHelper.startPage(homeExplorerDTO.getCurrentPage(), homeExplorerDTO.getPageSize()); + List list = this.shareDao.getShareToMeList(hashMap); + + HomeExplorerResult result = new HomeExplorerResult(); + List folderVOList = new ArrayList<>(); + List fileVOList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)) { + FileMetaVo fileMetaVo = null; + String downloadKey = FileUtil.getDownloadKey(); + List idList = new ArrayList<>(); + List sourceIDs= new ArrayList<>(); + Set uidList = new HashSet<>(); + for (HomeExplorerVO vo2 : list){ + if (vo2.getIsFolder().intValue() == 1){ + idList.add(vo2.getSourceID()); + } + sourceIDs.add(vo2.getSourceID().toString()); + uidList.add(vo2.getCreateUser()); + uidList.add(vo2.getModifyUser()); + } + // 标签 + Map> sourceTagMap = fileOptionTool.getSourceTagMap(loginUser.getUserID(), sourceIDs); + // 收藏 + List myFavList = fileOptionTool.checkIsFavByUserId(loginUser.getUserID()); + + List userList = userDao.getUserBaseInfo(new ArrayList<>(uidList)); + Map userMap = userList.stream().collect(Collectors.toMap(UserVo::getUserID, Function.identity(), (v1, v2) -> v2)); + List countList = CollectionUtils.isEmpty(idList) ? null : homeExplorerDao.getSourceChileCont(idList); + Map countMap = new HashMap<>(1); + if (!CollectionUtils.isEmpty(countList)) { + for (HomeExplorerVO home : countList) { + countMap.put(home.getParentID() + (home.getIsFolder().intValue() == 1 ? "_folder" : "_file"), home.getFileCount()); + } + } + for (HomeExplorerVO vo1 : list){ + vo1.setDownloadUrl(""); + vo1.setHasFile(0); + vo1.setHasFolder(0); + vo1.setResolution(""); + vo1.setLength(0); + vo1.setThumb(""); + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_folder")){ + vo1.setHasFolder(countMap.get(vo1.getSourceID() + "_folder")); + } + if (!ObjectUtils.isEmpty(countMap) && countMap.containsKey(vo1.getSourceID() + "_file")){ + vo1.setHasFile(countMap.get(vo1.getSourceID() + "_file")); + } + + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + + // 用户信息 + vo1.setCreateUserJson(JsonUtils.beanToJson(userMap.get(vo1.getCreateUser()))); + vo1.setModifyUserJson(JsonUtils.beanToJson(userMap.get(vo1.getModifyUser()))); + + // path 处理 + sourceOperateTool.opPath( vo1, downloadKey, "4"); + + // 是否收藏 + vo1.setIsFav(!CollectionUtils.isEmpty(myFavList) && myFavList.contains(vo1.getSourceID().toString()) ? 1 : 0); + // 已选标签 + vo1.setTags(""); + vo1.setTagList(new ArrayList<>()); + if (!ObjectUtils.isEmpty(sourceTagMap) && sourceTagMap.containsKey(vo1.getSourceID().toString())){ + vo1.setTagList(sourceTagMap.get(vo1.getSourceID().toString())); + } + // 是否分享 + vo1.setIsShare(0); + + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? vo1.getThumb() : vo1.getPath()); + vo1.setPath(ObjectUtils.isEmpty(vo1.getPath()) ? "" : vo1.getPath()); + + if (vo1.getIsFolder() == 1) { + vo1.setIcon("folder"); + folderVOList.add(vo1); + } else { + vo1.setIcon("file"); + fileVOList.add(vo1); + } + + } + } + PageInfo pageInfo = new PageInfo<>(list); + result.setTotal(pageInfo.getTotal()); + result.setFolderList(folderVOList); + result.setFileList(fileVOList); + + return sourceOperateTool.setSystemReturn(result, systemSortVo, String.valueOf(homeExplorerDTO.getSourceID())); + } + + @Override + public SelectAuthVo userGroupList(HomeExplorerDTO shareDTO, LoginUser loginUser){ + + if (!ObjectUtils.isEmpty(shareDTO.getGroupID()) && shareDTO.getGroupID() > 0){ + return userGroupListByGroup(shareDTO, loginUser); + } + + // 获取列表 + List list = userGroupListBySearch(shareDTO, loginUser); + SelectAuthVo vo = new SelectAuthVo(); + vo.setGroupList(list); + + Map map = new HashMap<>(2); + if (!ObjectUtils.isEmpty(shareDTO.getKeyword())) { + map.put("keyword", shareDTO.getKeyword().toLowerCase()); + } + // 判断是否是顶层group + map.put("groupID", 0); + + List userList = this.shareDao.getNotGroupUserListByParam(map); + + vo.setUserList(CollectionUtils.isEmpty(userList) ? new ArrayList<>() : userList); + return vo; + } + + public List userGroupListBySearch(HomeExplorerDTO shareDTO, LoginUser loginUser){ + // 系统管理员 + boolean isSystem = false; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + isSystem = true; + } + + List list = new ArrayList<>(); + // 用户部门权限 + List userGroupList = null; + if (!isSystem) { + if (!ObjectUtils.isEmpty(shareDTO.getKeyword())) { + userGroupList = userGroupDao.getUserGroupInfoListByParam(Arrays.asList(loginUser.getUserID()), shareDTO.getKeyword().toLowerCase()); + } else { + userGroupList = userGroupDao.getUserGroupInfoList(Arrays.asList(loginUser.getUserID())); + } + } + Set groupIDList = null; + String authShowType = ""; + List groupAuthList = null; + if (!CollectionUtils.isEmpty(userGroupList)){ + for (UserGroupVo userGroupVo : userGroupList){ + // systemGroupSource:1__namePinyin:qiyeyunpan__namePinyinSimple:qyyp__authShowType:all__authShowGroup: + if (!ObjectUtils.isEmpty(userGroupVo.getGroupAuth()) && userGroupVo.getGroupAuth().indexOf("authShowType:all__") >= 0){ + authShowType = "all"; + } + } + if (!"all".equals(authShowType)){ + groupIDList = new HashSet<>(); + for (UserGroupVo userGroup : userGroupList){ + + list.add(userGroup); + + groupAuthList = !ObjectUtils.isEmpty(userGroup.getGroupAuth()) ? Arrays.asList(userGroup.getGroupAuth().split("__")).stream().map(String::valueOf).collect(Collectors.toList()) : null; + if (!ObjectUtils.isEmpty(groupAuthList)){ + for (String groupAuth : groupAuthList){ + if (groupAuth.indexOf("authShowGroup:")>=0 && groupAuth.length() > 14 ){ + groupIDList.addAll(Arrays.asList(groupAuth.substring(groupAuth.indexOf("authShowGroup:") + 14, groupAuth.length()).split(",")).stream().map(Long::valueOf).collect(Collectors.toSet())); + } + } + } + } + if (!CollectionUtils.isEmpty(groupIDList)){ + for (UserGroupVo userGroup : userGroupList){ + if (groupIDList.contains(userGroup.getGroupID())){ + groupIDList.remove(userGroup.getGroupID()); + } + } + List list2 = groupDao.getGroupVoList(new ArrayList<>(groupIDList)); + if (!CollectionUtils.isEmpty(list2)){ + list.addAll(list2); + } + } + }else { + // 获取所有部门 + list = groupDao.getMainGroupVoList(shareDTO); + } + }else if (isSystem){ + list = groupDao.getMainGroupVoList(shareDTO); + } + + Group g = groupDao.getTopGroup(); + + if (!CollectionUtils.isEmpty(list)){ + List gidList = new ArrayList<>(); + for (UserGroupVo group : list){ + if (!ObjectUtils.isEmpty(group.isHasChildren()) && !group.isHasChildren()){ + gidList.add(group.getGroupID()); + } + } + if (!CollectionUtils.isEmpty(gidList)){ + List countList = groupDao.getGroupUserCountList(gidList); + Map countMap = CollectionUtils.isEmpty(countList) ? null : countList.stream().collect(Collectors.toMap(Group::getGroupID, Group::getHasChildren, (v1, v2) -> v2)); + if (!ObjectUtils.isEmpty(countMap)){ + for (UserGroupVo group : list){ + if (countMap.containsKey(group.getGroupID())){ + group.setHasChildren(true); + } + } + } + } + for (UserGroupVo vo : list){ + vo.setParentName(g.getName()); + } + }else { + list = new ArrayList<>(); + } + return list; + } + public SelectAuthVo userGroupListByGroup(HomeExplorerDTO shareDTO, LoginUser loginUser){ + List list = null; + List userList = null; + Group g = groupDao.getGroupInfoByID(shareDTO.getGroupID()); + + + GroupDTO paramDto = new GroupDTO(); + paramDto.setStatus(1); + paramDto.setParentID(shareDTO.getGroupID()); + + if (!ObjectUtils.isEmpty(shareDTO.getKeyword())) { + paramDto.setKeyword(shareDTO.getKeyword()); + } + + list = groupDao.getGroupList(paramDto); + + Map map = new HashMap<>(2); + if (!ObjectUtils.isEmpty(shareDTO.getKeyword())) { + map.put("keyword", shareDTO.getKeyword().toLowerCase()); + } + // 判断是否是顶层group + map.put("groupID", shareDTO.getGroupID()); + userList = this.shareDao.getSelectUserListByParam(map); + List groupList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(list)){ + List gidList = new ArrayList<>(); + for (Group group : list){ + boolean hasChildren = (group.getHasChildren().intValue() > 0 ? true : false); + if (!hasChildren){ + gidList.add(group.getGroupID()); + } + groupList.add(new UserGroupVo(group.getGroupID(), group.getParentID(), group.getName(), g.getName(), hasChildren)); + } + if (!CollectionUtils.isEmpty(gidList)){ + List countList = groupDao.getGroupUserCountList(gidList); + Map countMap = CollectionUtils.isEmpty(countList) ? null : countList.stream().collect(Collectors.toMap(Group::getGroupID, Group::getHasChildren, (v1, v2) -> v2)); + if (!ObjectUtils.isEmpty(countMap)){ + for (UserGroupVo group : groupList){ + if (countMap.containsKey(group.getGroupID())){ + group.setHasChildren(true); + } + } + } + } + } + + SelectAuthVo vo = new SelectAuthVo(); + vo.setGroupList(groupList); + vo.setUserList(userList); + return vo; + } + + + @Override + public Map previewNum(ShareDTO shareDTO){ + Map map = new HashMap<>(1); + map.put("numView",0); + if (!ObjectUtils.isEmpty(shareDTO.getShareCode())){ + List list = shareDao.getShareByCode(shareDTO.getShareCode()); + if (CollectionUtils.isEmpty(list) || list.size() > 1){ + return map; + } + ShareVo vo = list.get(0); + map.put("numView", vo.getNumView() + 1); + vo.setPassword(null); + try { + shareDao.updateNumView(vo.getShareID(), vo.getNumView() + 1); + }catch (Exception e){ + LogUtil.error("getPreviewInfo updateNumView error"); + } + } + return map; + } + + @Override + public PageResult getUserList(LoginUser loginUser, UserDTO userDTO){ + userDTO.setStatus(1); + PageResult data = null; + + // 系统管理员 + boolean isSystem = false; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + isSystem = true; + } + + List list = new ArrayList<>(); + // 用户部门权限 + List userGroupList = null; + if (!isSystem) { + if (!ObjectUtils.isEmpty(userDTO.getKeyword())) { + userGroupList = userGroupDao.getUserGroupInfoListByParam(Arrays.asList(loginUser.getUserID()), userDTO.getKeyword().toLowerCase()); + } else { + userGroupList = userGroupDao.getUserGroupInfoList(Arrays.asList(loginUser.getUserID())); + } + } + Set groupIDList = null; + String authShowType = ""; + List groupAuthList = null; + if (!CollectionUtils.isEmpty(userGroupList)){ + for (UserGroupVo userGroupVo : userGroupList){ + // systemGroupSource:1__namePinyin:qiyeyunpan__namePinyinSimple:qyyp__authShowType:all__authShowGroup: + if (!ObjectUtils.isEmpty(userGroupVo.getGroupAuth()) && userGroupVo.getGroupAuth().indexOf("authShowType:all__") >= 0){ + authShowType = "all"; + } + } + if (!"all".equals(authShowType)){ + groupIDList = new HashSet<>(); + for (UserGroupVo userGroup : userGroupList){ + list.add(userGroup); + groupAuthList = !ObjectUtils.isEmpty(userGroup.getGroupAuth()) ? Arrays.asList(userGroup.getGroupAuth().split("__")).stream().map(String::valueOf).collect(Collectors.toList()) : null; + if (!ObjectUtils.isEmpty(groupAuthList)){ + for (String groupAuth : groupAuthList){ + if (groupAuth.indexOf("authShowGroup:")>=0 && groupAuth.length() > 14 ){ + groupIDList.addAll(Arrays.asList(groupAuth.substring(groupAuth.indexOf("authShowGroup:") + 14, groupAuth.length()).split(",")).stream().map(Long::valueOf).collect(Collectors.toSet())); + } + } + } + } + if (!CollectionUtils.isEmpty(groupIDList)){ + for (UserGroupVo userGroup : userGroupList){ + if (groupIDList.contains(userGroup.getGroupID())){ + groupIDList.remove(userGroup.getGroupID()); + } + } + List list2 = groupDao.getGroupVoList(new ArrayList<>(groupIDList)); + if (!CollectionUtils.isEmpty(list2)){ + list.addAll(list2); + } + } + }else { + // 获取所有部门 + data = userManageService.getUserList(loginUser, userDTO); + } + }else if (isSystem){ + data = userManageService.getUserList(loginUser, userDTO); + } + + if (!ObjectUtils.isEmpty(data)){ + return data; + } + + if (!CollectionUtils.isEmpty(list)){ + List groupLevelList = list.stream().map(UserGroupVo::getParentLevel).collect(Collectors.toList()); + userDTO.setGroupLevelList(groupLevelList); + return userManageService.getUserList(loginUser, userDTO); + }else { + return new PageResult(0L, new ArrayList()); + } + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/SourceFileServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/SourceFileServiceImpl.java new file mode 100644 index 0000000..4ac9209 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/SourceFileServiceImpl.java @@ -0,0 +1,93 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.HomeExplorerDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.AddCloudDirectoryDTO; +import com.svnlan.home.dto.AddSubCloudDirectoryDTO; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.service.SourceFileService; +import com.svnlan.home.utils.DirectoryUtil; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/7/3 9:41 + */ +@Service +public class SourceFileServiceImpl implements SourceFileService { + + @Resource + HomeExplorerDao homeExplorerDao; + @Resource + IoSourceDao ioSourceDao; + @Resource + DirectoryUtil directoryUtil; + @Resource + SystemLogTool systemLogTool; + + @Override + public List addBatchDirectory(AddCloudDirectoryDTO addCloudDirectoryDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(addCloudDirectoryDTO) || CollectionUtils.isEmpty(addCloudDirectoryDTO.getChildren()) + || ObjectUtils.isEmpty(addCloudDirectoryDTO.getSourceID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + for (AddSubCloudDirectoryDTO dto : addCloudDirectoryDTO.getChildren()){ + if (ObjectUtils.isEmpty(dto) || ObjectUtils.isEmpty(dto.getName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + } + + CommonSource commonSource = ioSourceDao.getSourceInfo(addCloudDirectoryDTO.getSourceID()); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + + List list = null; + try { + /************批量添加文件夹**********************************/ + list = directoryUtil.addBatchDirectory(addCloudDirectoryDTO.getChildren(), loginUser, commonSource, systemLogTool.getRequest()); + + } catch (SvnlanRuntimeException e){ + throw new SvnlanRuntimeException(e.getErrorCode(), e.getMessage()); + } catch (Exception e){ + LogUtil.error(e, "目录添加失败" + JsonUtils.beanToJson(addCloudDirectoryDTO) + "," + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + + return CollectionUtils.isEmpty(list) ? new ArrayList<>() : list; + } + + @Override + public List getImgList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(homeExplorerDTO.getSourceID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + Map paramMap = new HashMap<>(2); + List fileTypeList = Arrays.asList("jpg","png","jpeg","JPG","PNG","JPEG"); + paramMap.put("fileTypeList", fileTypeList); + paramMap.put("parentID", homeExplorerDTO.getSourceID()); + List list = homeExplorerDao.getImgByFolderList(paramMap); + if (CollectionUtils.isEmpty(list)){ + return new ArrayList(); + } + for (HomeExplorerVO explorerVO : list){ + explorerVO.setPath(FileUtil.getShowImageUrl(explorerVO.getPath(), explorerVO.getSourceID()+ "_" + explorerVO.getFileType() +".jpg")); + } + return list; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/SourceHistoryServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/SourceHistoryServiceImpl.java new file mode 100644 index 0000000..8ca8808 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/SourceHistoryServiceImpl.java @@ -0,0 +1,383 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.I18nUtils; +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.MyMenuEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.dao.IoSourceHistoryDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.domain.IoSourceHistory; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.service.SourceHistoryService; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.utils.SourceHistoryUtil; +import com.svnlan.home.utils.UserAuthTool; +import com.svnlan.home.vo.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SourceOperateTool; +import com.svnlan.user.dao.UserDao; +import com.svnlan.user.vo.UserGroupVo; +import com.svnlan.user.vo.UserVo; +import com.svnlan.utils.DateDUtil; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.LoginUserUtil; +import com.svnlan.utils.VideoUtil; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/31 11:28 + */ +@Service +public class SourceHistoryServiceImpl implements SourceHistoryService { + + @Resource + IoSourceHistoryDao ioSourceHistoryDao; + @Resource + SourceOperateTool sourceOperateTool; + @Resource + FileOptionTool fileOptionTool; + @Resource + UserDao userDao; + @Resource + IoSourceDao ioSourceDao; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + SourceHistoryUtil sourceHistoryUtil; + @Resource + UserAuthTool userAuthTool; + @Resource + LoginUserUtil loginUserUtil; + + @Override + public HomeExplorerResult getSourceHistoryList(HomeExplorerDTO homeExplorerDTO){ + if (ObjectUtils.isEmpty(homeExplorerDTO.getSourceID()) || homeExplorerDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Map hashMap = new HashMap<>(3); + hashMap.put("sourceID", homeExplorerDTO.getSourceID()); + hashMap.put("startIndex", homeExplorerDTO.getStartIndex()); + hashMap.put("pageSize", homeExplorerDTO.getPageSize()); + CommonSource cloudFile = fileOptionTool.getFileAttachment(homeExplorerDTO.getSourceID(), 0L); + + if (cloudFile == null || ObjectUtils.isEmpty(cloudFile.getName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + Long total = ioSourceHistoryDao.getCountSourceHistoryBySourceID(hashMap); + + String downloadKey = FileUtil.getDownloadKey(); + List list = null; + List fileList = new ArrayList<>(); + if(0 < total.longValue()) { + FileMetaVo fileMetaVo = null; + list = ioSourceHistoryDao.getSourceHistoryBySourceID(hashMap); + for (HomeExplorerVO vo1 : list){ + if (vo1.getFileID().equals(cloudFile.getFileID())){ + continue; + } + // FileMeta value 处理 + sourceOperateTool.setFileMetaValue(fileMetaVo, vo1); + // path 处理 + sourceOperateTool.opHistoryPath(vo1, downloadKey); + fileList.add(vo1); + } + } + HomeExplorerResult result = new HomeExplorerResult(); + result.setTotal(total); + result.setFolderList(null); + result.setFileList(fileList); + + String downloadUrl = "/api/disk/attachment/" + FileUtil.encodeDownloadUrl(cloudFile.getName()) + + fileOptionTool.getDownloadParam(cloudFile.getSourceID(), downloadKey, "") ; + + String m3u8Key = FileUtil.getM3u8Key(); + Map reMap = new HashMap<>(1); + + Long userId = cloudFile.getUserID(); + IoSourceHistory orgHistory = ioSourceHistoryDao.getHistoryInfoByFileId(cloudFile.getSourceID(), cloudFile.getFileID()); + if (!ObjectUtils.isEmpty(orgHistory)){ + userId = orgHistory.getUserID(); + } + //String domain = HttpUtil.getRequestRootUrl(null); + reMap.put("sourceID", cloudFile.getSourceID()); + reMap.put("fileID", cloudFile.getFileID()); + reMap.put("fileType", cloudFile.getFileType()); + reMap.put("h5Url", cloudFile.getAppPreviewUrl()); + reMap.put("createTime", cloudFile.getCreateTime()); + UserVo userVo =userDao.getUserBaseOneInfo(userId); + reMap.put("nickname", !ObjectUtils.isEmpty(userVo.getNickname()) ? userVo.getNickname() : userVo.getName()); + reMap.put("avatar", userVo.getAvatar()); + + reMap.put("resolution", ObjectUtils.isEmpty(cloudFile.getResolution()) ? "" : cloudFile.getResolution()); + reMap.put("isPreview", cloudFile.getIsPreview()); + reMap.put("previewUrl", ""); + reMap.put("isSwf", 0); + reMap.put("swfUrl", ""); + Integer videoLength = ObjectUtils.isEmpty(cloudFile.getSourceLength()) ? 0 : cloudFile.getSourceLength(); + reMap.put("name", cloudFile.getName()); + reMap.put("size", cloudFile.getSize()); + reMap.put("length", videoLength); + reMap.put("isM3u8", cloudFile.getIsM3u8()); + + if (cloudFile.getIsM3u8().equals(1)){//转码完成的 + //文档类 + if (Arrays.asList(GlobalConfig.DOC_TYPE_ARR).contains(cloudFile.getFileType())){ + reMap.put("isSwf", 1); + reMap.put("swfUrl", cloudFile.getPreviewUrl()); + } else {//视频 + String m3u8Url = "/api/disk/mu/getMyM3u8.m3u8" + fileOptionTool.getM3u8Param(cloudFile.getSourceID(), m3u8Key); + reMap.put("previewUrl", m3u8Url); + } + } + //未完成的. 视频转码进度 + else if (!cloudFile.getIsM3u8().equals(-1) + && Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(cloudFile.getFileType())){ + String sourcePath = cloudFile.getPath(); + //获取视频长度 + + if (videoLength.equals(0)){ + videoLength = VideoUtil.getVideoLength(sourcePath); + if (videoLength.equals(0)){ + //获取转码进度 + int dotPosition = sourcePath.lastIndexOf("."); + String m3u8Path = sourcePath.substring(0, dotPosition) + ".m3u8"; + Integer progress = FileUtil.getConvertedLength(m3u8Path, videoLength, true); + reMap.put("convertProgress", progress); + + }else { + reMap.put("convertProgress", videoLength); + } + } + } + reMap.put("isH5", cloudFile.getAppPreview()); + reMap.put("downloadUrl", downloadUrl ); + //到前端页面 + if (Arrays.asList(GlobalConfig.DOC_SHOW_TYPE_ARR).contains(cloudFile.getFileType())) { + reMap.put("pdfPreviewUrl", fileOptionTool.getPptPdfPreview2(cloudFile.getFileType(), cloudFile.getIsH264Preview(), downloadUrl)); + String pptPreviewUrl = fileOptionTool.getPptPreviewUrl(downloadUrl, cloudFile.getHashMd5()); + reMap.put("pptPreviewUrl", pptPreviewUrl);// HttpUtil.getRequestRootUrl(null) + downloadUrl + } + reMap.put("yzViewData", ""); + /*if(!ObjectUtils.isEmpty(cloudFile.getYzViewData())) { + reMap.put("yzViewData", cloudFile.getYzViewData()); + }*/ + + // path 处理 + if (!ObjectUtils.isEmpty(cloudFile.getPath()) && Arrays.asList(GlobalConfig.list_path_source_type).contains(cloudFile.getFileType())){ + if (!"svg".equals(cloudFile.getFileType())){ + //String firstPath = FileUtil.getFirstStorageDevicePath(cloudFile.getPath()); + //reMap.put("path", cloudFile.getPath().replace(firstPath + "/private/cloud", firstPath + "/common/cloud")); + reMap.put("path", FileUtil.getShowImageUrl(cloudFile.getPath(), ""+cloudFile.getSourceID()+"." + cloudFile.getFileType())); + } + }else if("oexe".equals(cloudFile.getFileType())){ + reMap.put("path", ""); + reMap.put("oexeContent", FileUtil.getFileContent(cloudFile.getPath(), StandardCharsets.UTF_8)); + }else { + reMap.put("path", ""); + } + reMap.put("thumb", ""); + if (!ObjectUtils.isEmpty(cloudFile.getThumb())){ + reMap.put("thumb", FileUtil.getShowImageUrl(cloudFile.getThumb(), "thumb"+cloudFile.getSourceID()+".jpg")); + } + + result.setCurrent(reMap); + return result; + } + + @Override + public void setHistoryDetail(HomeExplorerDTO homeExplorerDTO){ + if (ObjectUtils.isEmpty(homeExplorerDTO.getId()) || homeExplorerDTO.getId() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + checkHistoryAuth(homeExplorerDTO.getId(), null); + + homeExplorerDTO.setDetail(ObjectUtils.isEmpty(homeExplorerDTO.getDetail()) ? "" : homeExplorerDTO.getDetail()); + try { + ioSourceHistoryDao.updateDetail(homeExplorerDTO.getId(), homeExplorerDTO.getDetail()); + }catch (Exception e){ + LogUtil.error(e, "setHistoryDetail error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + + } + + @Override + public void setHistoryRevision(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(homeExplorerDTO.getId()) || homeExplorerDTO.getId() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 获取历史记录 + IoSourceHistory history = ioSourceHistoryDao.getHistoryInfo(homeExplorerDTO.getId()); + if (ObjectUtils.isEmpty(history)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 获取原本source的file信息 + IoSourceHistory file = ioSourceHistoryDao.getFileInfoBySourceID(history.getSourceID()); + if (ObjectUtils.isEmpty(file) || file.getFileID().longValue() == history.getFileID().longValue()){ + return; + } + userAuthTool.checkGroupDocAuth(loginUser, history.getSourceID(), file.getParentLevel(), "14", file.getTargetType()); + + Long userId = file.getUserID(); + IoSourceHistory orgHistory = ioSourceHistoryDao.getHistoryInfoByFileId(homeExplorerDTO.getSourceID(), file.getFileID()); + if (!ObjectUtils.isEmpty(orgHistory)){ + userId = orgHistory.getUserID(); + } + + // 添加历史记录 sourceID, `userID`,`fileID`, `size`, `detail` + IoSourceHistory ioSourceHistory = new IoSourceHistory(); + ioSourceHistory.setSourceID(history.getSourceID()); + ioSourceHistory.setUserID(ObjectUtils.isEmpty(userId) ? loginUser.getUserID() : userId); + ioSourceHistory.setFileID(file.getFileID()); + ioSourceHistory.setSize(file.getSize()); + ioSourceHistory.setDetail(I18nUtils.i18n("explorer.history.setCurrent")); + + history.setUserID(loginUser.getUserID()); + try { + // 修改source的fileID、size + ioSourceHistoryDao.updateVerSource(history); + + // 删除历史版本再添加一条最新的记录、不删,用于查询历史userId getHistoryInfoByFileId + //ioSourceHistoryDao.delByID(homeExplorerDTO.getId()); + + // 判断是否存在并保证size正确 + sourceHistoryUtil.changeCheckSourceHistory(null, ioSourceHistory); + + + }catch (Exception e){ + LogUtil.error(e, "setHistoryDetail error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + + String time = DateDUtil.LongTimeToString(history.getCreateTime(),DateDUtil.yyyy_MM_dd_HH_mm_ss); + fileOptionTool.addSourceEvent(history.getSourceID(), file.getParentID(), loginUser.getUserID(), file.getName(), EventEnum.rollBack, time); + } + + @Override + public void deleteHistory(HomeExplorerDTO homeExplorerDTO){ + + checkHistoryAuth(homeExplorerDTO.getId(), null); + + // 删除当前版本记录 + if (!ObjectUtils.isEmpty(homeExplorerDTO.getId()) && homeExplorerDTO.getId() > 0){ + ioSourceHistoryDao.delByID(homeExplorerDTO.getId()); + } + // 删除所有版本记录 + else if(!ObjectUtils.isEmpty(homeExplorerDTO.getSourceID()) && homeExplorerDTO.getSourceID() > 0){ + ioSourceHistoryDao.delBySourceID(homeExplorerDTO.getSourceID()); + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + } + + @Override + public List parentSourceList(HomeExplorerDTO homeExplorerDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(homeExplorerDTO.getParentLevel())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + List parentIDs = Arrays.asList(homeExplorerDTO.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(parentIDs)){ + if (!ObjectUtils.isEmpty(homeExplorerDTO.getParentID())) { + CommonSource commonSource = fileOptionTool.getSourceInfo(homeExplorerDTO.getParentID()); + parentIDs = Arrays.asList(commonSource.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(parentIDs)) { + parentIDs = new ArrayList<>(); + } + parentIDs.add(homeExplorerDTO.getParentID()); + }else { + return new ArrayList(); + } + } + + + + List copyList = ioSourceDao.copySourceList(parentIDs); + if (CollectionUtils.isEmpty(copyList)) { + throw new SvnlanRuntimeException(CodeMessageEnum.rptSelectTips.getCode()); + } + + boolean isSystem = false; + String auth = ""; + if (!ObjectUtils.isEmpty(loginUser) && 1 == loginUser.getUserType()){ + auth = GlobalConfig.SYSTEM_GROUP_AUTH; + isSystem = true; + } + Map gsAuthMap = null; + Map gsAuthNameMap = null; + if (!isSystem){ + List groupSourceId = copyList.stream().filter(n->n.getTargetType().intValue() == 2).map(IOSource::getSourceID).collect(Collectors.toList()); + + if (!isSystem){ + gsAuthMap = new HashMap<>(1); + gsAuthNameMap = new HashMap<>(1); + // 文件上级权限 + if (!isSystem && !CollectionUtils.isEmpty(groupSourceId)){ + sourceOperateTool.getUserAuthByLevel(loginUser.getUserID(), new ArrayList<>(groupSourceId), gsAuthMap, gsAuthNameMap); + } + } + } + Map parentMap = copyList.stream().collect(Collectors.toMap(IOSource::getSourceID, Function.identity(), (v1, v2) -> v2)); + IOSource ioSource = null; + List list = new ArrayList<>(); + for (Long sourceID : parentIDs){ + if (!ObjectUtils.isEmpty(parentMap) && parentMap.containsKey(sourceID)) { + ioSource = parentMap.get(sourceID); + if (ioSource.getTargetType().intValue() == 1){ + if (ioSource.getParentID().longValue() == 0){ + ioSource.setName(I18nUtils.tryI18n(MyMenuEnum.rootPath.getCode())); + } + ioSource.setIcon(MyMenuEnum.rootPath.getIcon()); + }else { + ioSource.setIcon("box"); + } + ioSource.setAuth(auth); + if (!isSystem && !ObjectUtils.isEmpty(gsAuthMap) && gsAuthMap.containsKey(sourceID)){ + if (gsAuthMap.containsKey(sourceID)){ + ioSource.setAuth(gsAuthMap.get(sourceID)); + } + } + list.add(ioSource); + } + } + return list; + } + + private void checkHistoryAuth(Long id, LoginUser loginUser){ + // 获取历史记录 + IoSourceHistory history = ioSourceHistoryDao.getHistoryInfo(id); + if (ObjectUtils.isEmpty(history)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 获取原本source的file信息 + IoSourceHistory file = ioSourceHistoryDao.getFileInfoBySourceID(history.getSourceID()); + if (ObjectUtils.isEmpty(file) || file.getFileID().longValue() == history.getFileID().longValue()){ + return; + } + if (ObjectUtils.isEmpty(loginUser)){ + loginUser = loginUserUtil.getLoginUser(); + } + userAuthTool.checkGroupDocAuth(loginUser, history.getSourceID(), file.getParentLevel(), "14", file.getTargetType()); + + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/UploadServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/UploadServiceImpl.java new file mode 100644 index 0000000..b148db6 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/UploadServiceImpl.java @@ -0,0 +1,2330 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.LogTypeEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.dao.IoSourceHistoryDao; +import com.svnlan.home.dao.ShareDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.domain.IoSourceHistory; +import com.svnlan.home.dto.*; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.enums.CloudOperateEnum; +import com.svnlan.home.enums.UploadEnum; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.service.ConvertFileService; +import com.svnlan.home.service.UploadService; +import com.svnlan.home.utils.*; +import com.svnlan.home.vo.CommonSourceVO; +import com.svnlan.home.vo.FileMetaVo; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.home.vo.ShareVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import com.svnlan.webdav.FileProperties; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.lang.reflect.Field; +import java.net.URLEncoder; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import static com.svnlan.home.utils.FileUtil.specificExtList; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 9:07 + */ +@Service +public class UploadServiceImpl implements UploadService { + + @Resource + BusTypeHandleService busTypeHandleService; + @Resource + SystemSortTool systemSortTool; + @Resource + FileOptionTool fileOptionTool; + @Resource + LoginUserUtil loginUserUtil; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + IoSourceDao ioSourceDao; + @Resource + ConvertUtil convertUtil; + @Resource + IoSourceHistoryDao ioSourceHistoryDao; + @Resource + SystemLogTool systemLogTool; + @Resource + ShareDao shareDao; + @Resource + ShareTool shareTool; + @Resource + UserAuthTool userAuthTool; + + @Resource + FileContentTool fileContentTool; + @Resource + StorageService storageService; + @Resource + AsyncDoMergeFileUtil asyncDoMergeFileUtil; + @Resource + ConvertFileService convertFileService; + @Resource + SourceHistoryUtil sourceHistoryUtil; + + @Value("${cdn.domain}") + private String cdnDomain; + @Value("${environment.type}") + private String environmentType; + + /** + * 上传文件主流程 + * + * @Description: + * @params: [uploadDTO] + * @Return: com.svnlan.upload.enumpack.UploadEnum + * @Modified: + */ + @Override + public CommonSourceVO upload(UploadDTO uploadDTO, LoginUser loginUser, CommonSource commonSource) { + + // 参数错误 + if (ObjectUtils.isEmpty(uploadDTO) || ObjectUtils.isEmpty(uploadDTO.getBusType())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + String busType = uploadDTO.getBusType(); + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(busType); + if (busTypeEnum == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 上传前的操作 + HomeExplorerVO disk = beforeUpload(commonSource, uploadDTO, loginUser, busTypeEnum); + + Long sourceId = 0L; + CommonSourceVO commonSourceVO = new CommonSourceVO(); + commonSourceVO.setState(0); + + MultipartFile file = uploadDTO.getFile(); + if (file == null) { + commonSourceVO.setMsg(UploadEnum.fileEmpty.getMsg()); + return commonSourceVO; + } + if (ObjectUtils.isEmpty(uploadDTO.getSize())){ + uploadDTO.setSize(file.getSize()); + } + commonSource.setSize(uploadDTO.getSize()); + // 判断容量是否足够 + fileOptionTool.checkMemory(disk, commonSource.getSize()); + //传参覆盖文件名 (小程序分片场景不能改文件名) + if (!StringUtil.isEmpty(uploadDTO.getOverrideName())) { + try { + Field field = file.getClass().getDeclaredField("filename"); + field.setAccessible(true); + field.set(file, uploadDTO.getOverrideName()); + } catch (Exception e) { + LogUtil.error(e, "upload 设置名称出错, " + uploadDTO.getOverrideName()); + } + } + + // 验证文件名及后缀 + validateUploadFileName(file.getOriginalFilename()); + // 对不同上传业务做验证 + doByBusType(uploadDTO, true, commonSource, busTypeEnum, disk); + //是否是分段 + Boolean isDoChunk = true; + Boolean isDone = false; + + UploadStateDTO uploadStateDTO = new UploadStateDTO(); + uploadStateDTO.setChecksum(uploadDTO.getHashMd5()); + //非分段,直接上传的类型 + if (uploadDTO.getChunk() == null || uploadDTO.getChunks() == null || uploadDTO.getChunks().equals(0) || uploadDTO.getChunks().equals(1)) { + commonSource = this.doSaveDirect(uploadDTO, commonSource); + isDoChunk = false; + isDone = true; + } else { + //保存临时文件 + if (!file.isEmpty()) { + uploadStateDTO = this.doSaveTemp(uploadDTO); + } + //全部分段完成,执行合并操作 + if (uploadStateDTO.getUpState() && uploadStateDTO.getPartAllDone()) { + commonSource = this.doMergeFile(uploadStateDTO, commonSource); + isDone = true; + } + } + + + //完成合并或直接上传,添加数据 && !StringUtil.isEmpty(commonSource.getHashMd5()) + if (isDone && commonSource != null) { + // 同名处理 + // 资源相关信息写入数据库 + sourceId = recordSourceDataToDb(commonSource, uploadDTO, busTypeEnum); + + } + + boolean finalSuccess = false; + //设置返回前端的值 + if (sourceId != null && !sourceId.equals(0L)) { + finalSuccess = true; + commonSourceVO.setSourceID(commonSource.getSourceID()); + commonSourceVO.setFileID(sourceId); + commonSourceVO.setFileType(commonSource.getFileType()); + commonSourceVO.setName(commonSource.getName()); + commonSourceVO.setHashMd5(commonSource.getHashMd5()); + commonSourceVO.setPath(commonSource.getPath()); + commonSourceVO.setSourceLength(commonSource.getSourceLength()); + commonSourceVO.setIsM3u8(commonSource.getIsM3u8()); + //返回path + commonSourceVO.setPath(FileUtil.returnPath(commonSourceVO.getPath(), uploadDTO.getBusType(), commonSource.getThumb())); + LogUtil.info("上传成功等待返回, " + JsonUtils.beanToJson(commonSourceVO) + ", " + uploadDTO.getChunk()); + + //根据业务类型,处理后续 + this.doByBusType(uploadDTO, false, commonSource, busTypeEnum, disk); + + // + commonSourceVO.setThumb(commonSource.getThumb()); + commonSourceVO.setResolution(commonSource.getResolution()); + + //处理返回预览URL + // this.doPreviewUrlByBusType(commonSource, busTypeEnum, commonSourceVO); + } + //分段上传的 + if (isDoChunk && uploadStateDTO.getUpState() && !uploadStateDTO.getPartAllDone()) { + commonSourceVO.setState(1); + } else { + //合并或者直接上传的 + commonSourceVO.setState(sourceId == null || sourceId.equals(0L) ? 0 : 1); + commonSourceVO.setRemark(sourceId == null || sourceId.equals(0L) ? "保存数据失败" : ""); + } + if (finalSuccess) { + LogUtil.info("上传再看次VO的数据" + JsonUtils.beanToJson(commonSourceVO)); + } + // 图片内容安全校验 + /*if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSourceVO.getSourceSuffix()) + && BusTypeEnum.HOMEPAGE_IMAGE.getBusType().equals(busType)){ + Map paramMap = new HashMap<>(0); + /** 只检查图片* / + setImgSecCheckValue(commonSourceVO, paramMap); + wxTool.imgSecCheck(" 资讯图片内容安全校验 ", paramMap); + }*/ + + if (isDone) { + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + if (!ObjectUtils.isEmpty(commonSource.getParentLevel())) { + reMap.put("sourceParentLevel", commonSource.getParentLevel()); + } + reMap.put("type", "upload"); + reMap.put("status", commonSourceVO.getState()); + reMap.put("remark", ObjectUtils.isEmpty(commonSourceVO.getRemark()) ? "" : commonSourceVO.getRemark()); + reMap.put("userID", loginUser.getUserID()); + reMap.put("pathName", commonSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileUpload.getCode(), paramList, systemLogTool.getRequest()); + } + if (!ObjectUtils.isEmpty(commonSource.getCheckMerge()) && commonSource.getCheckMerge()) { + + String serverUrl = HttpUtil.getRequestRootUrl(null); + commonSource.setDomain(serverUrl); + commonSource.setUserID(loginUser.getUserID()); + asyncDoMergeFileUtil.asyncDoMergeFileUtil(uploadStateDTO, commonSource, commonSourceVO, uploadDTO.getBusType()); + } + return commonSourceVO; + } + + /** + * 上传前的操作 + */ + @Override + public HomeExplorerVO beforeUpload(CommonSource commonSource, UploadDTO uploadDTO, LoginUser loginUser, BusTypeEnum busTypeEnum) { + + //设置默认值 + fileOptionTool.setDefault(commonSource, loginUser); + commonSource.setSourceType(busTypeEnum.getTypeCode()); + uploadDTO.setIgnoreFileSize(0.0); + commonSource.setGroupID(0L); + HomeExplorerVO disk = null; + if (busTypeEnum.equals(BusTypeEnum.CLOUD)) { + if (ObjectUtils.isEmpty(uploadDTO.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + /** 获取企业云盘 */ + disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), uploadDTO.getSourceID()); + uploadDTO.setIgnoreFileSize(disk.getIgnoreFileSize()); + commonSource.setGroupID(disk.getGroupID()); + commonSource.setTargetType(disk.getTargetType()); + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, uploadDTO.getSourceID(), disk.getParentLevel(), "5", disk.getTargetType()); + } + + commonSource.setParentID(ObjectUtils.isEmpty(uploadDTO.getSourceID()) ? 0L : uploadDTO.getSourceID()); + commonSource.setUserID(loginUser.getUserID()); + return disk; + } + + /** + * 资源相关信息写入数据库 + */ + @Override + public Long recordSourceDataToDb(CommonSource commonSource, UploadDTO uploadDTO, BusTypeEnum busTypeEnum) { + List sourceNameList = ioSourceDao.getSourceNameList(uploadDTO.getSourceID()); + commonSource.setName(fileOptionTool.checkRepeatName(commonSource.getName(), commonSource.getName(), commonSource.getFileType(), sourceNameList, 1)); + //验证学生文件大小 + this.doBeforeInsert(uploadDTO, commonSource); + Long sourceId = this.addData(commonSource, busTypeEnum); + LogUtil.info("上传入库完成, " + sourceId + "@" + JsonUtils.beanToJson(commonSource)); + return sourceId; + } + + /** + * 验证文件名及后缀 + */ + @Override + public void validateUploadFileName(String fileName) { + if (fileName == null) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + /*if (fileName.startsWith(".")) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + }*/ + //验证后缀 + String suffix = FileUtil.getFileExtension(fileName); + if (StringUtil.isEmpty(suffix)) { + // 文件名不符合规范, 请修改 + //throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } else { + Pattern pattern = Pattern.compile("[^a-zA-Z0-9]", Pattern.CASE_INSENSITIVE); + // 文件名不符合规范, 请修改 + if (pattern.matcher(suffix).find()) { + // 有可能是 tar.gz 这样的后缀 + if (specificExtList.stream().noneMatch(it -> it.equals(suffix))) { + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + } + } + } + + /** + * 试着转码 + */ + @Override + public void tryToConvertFile(CommonSourceVO commonSourceVO, CommonSource commonSource, String busType) { + convertFileService.tryToConvertFile(commonSourceVO, commonSource, busType); + } + + @Override + public CommonSourceVO fileUpload(UploadDTO uploadDTO, LoginUser loginUser, CommonSource commonSourceRe) { + // 参数错误 + if (ObjectUtils.isEmpty(uploadDTO) || ObjectUtils.isEmpty(uploadDTO.getBusType()) || !StringUtil.isNumeric(uploadDTO.getPath())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String busType = uploadDTO.getBusType(); + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(busType); + if (busTypeEnum == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + MultipartFile file = uploadDTO.getFile(); + CommonSourceVO commonSourceVO = new CommonSourceVO(); + if (file == null || file.getSize() <= 0) { + commonSourceVO.setMsg(UploadEnum.fileEmpty.getMsg()); + return commonSourceVO; + } + if (file.getOriginalFilename() == null) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + long size = file.getSize(); + /*if (file.getOriginalFilename().startsWith(".")) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + }*/ + CommonSource commonSource = fileOptionTool.getSourceInfo(Long.parseLong(uploadDTO.getPath())); + if (ObjectUtils.isEmpty(commonSource)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), "8", commonSource.getTargetType()); + + commonSourceRe.setSourceType(busTypeEnum.getTypeCode()); + commonSource.setDomain(commonSourceRe.getDomain()); + commonSource.setSourceType(busTypeEnum.getTypeCode()); + commonSource.setIsM3u8(0); + + Long userId = commonSource.getUserID(); + IoSourceHistory orgHistory = ioSourceHistoryDao.getHistoryInfoByFileId(commonSource.getSourceID(), commonSource.getFileID()); + if (!ObjectUtils.isEmpty(orgHistory)){ + userId = orgHistory.getUserID(); + } + + // 添加历史记录 sourceID, `userID`,`fileID`, `size`, `detail` + IoSourceHistory ioSourceHistory = new IoSourceHistory(); + ioSourceHistory.setSourceID(commonSource.getSourceID()); + ioSourceHistory.setUserID(ObjectUtils.isEmpty(userId) ? loginUser.getUserID() : userId); + ioSourceHistory.setFileID(commonSource.getFileID()); + ioSourceHistory.setSize(commonSource.getSize()); + ioSourceHistory.setDetail(""); + + commonSource.setHashMd5(null); + + commonSourceVO.setState(0); + uploadDTO.setIgnoreFileSize(0.0); + uploadDTO.setSourceID(commonSource.getParentID()); + commonSource.setGroupID(0L); + commonSource.setUserID(loginUser.getUserID()); + HomeExplorerVO disk = null; + if (busTypeEnum.equals(BusTypeEnum.CLOUD)) { + if (ObjectUtils.isEmpty(uploadDTO.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + /** 获取企业云盘 */ + disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), uploadDTO.getSourceID()); + uploadDTO.setIgnoreFileSize(disk.getIgnoreFileSize()); + commonSource.setGroupID(disk.getGroupID()); + commonSource.setTargetType(disk.getTargetType()); + } + //验证 + fileOptionTool.checkMemory(disk, size); + + //验证后缀 + String suffix = FileUtil.getFileExtension(file.getOriginalFilename()); + if (StringUtil.isEmpty(suffix)) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } else { + Pattern pattern = Pattern.compile("[^a-zA-Z0-9]", Pattern.CASE_INSENSITIVE); + // 文件名不符合规范, 请修改 + if (pattern.matcher(suffix).find()) { + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + } + /*if (!commonSource.getFileType().toLowerCase().equals(suffix.toLowerCase())){ + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType().toLowerCase()) && Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix.toLowerCase())){ + }else if (Arrays.asList("doc", "docx").contains(commonSource.getFileType().toLowerCase()) && Arrays.asList("doc", "docx").contains(suffix.toLowerCase())){ + }else if (Arrays.asList("ppt", "pptx").contains(commonSource.getFileType().toLowerCase()) && Arrays.asList("ppt", "pptx").contains(suffix.toLowerCase())){ + }else if (Arrays.asList("xls", "xlsx").contains(commonSource.getFileType().toLowerCase()) && Arrays.asList("xls", "xlsx").contains(suffix.toLowerCase())){ + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + }*/ + boolean isDone = false; + + UploadStateDTO uploadStateDTO = new UploadStateDTO(); + //非分段,直接上传的类型 + if (uploadDTO.getChunk() == null || uploadDTO.getChunks() == null || uploadDTO.getChunks().equals(0) || uploadDTO.getChunks().equals(1)) { + isDone = true; + commonSource = this.doSaveDirect(uploadDTO, commonSource); + } else { + //保存临时文件 + if (!file.isEmpty()) { + uploadStateDTO = this.doSaveTemp(uploadDTO); + } + //全部分段完成,执行合并操作 + if (uploadStateDTO.getUpState() && uploadStateDTO.getPartAllDone()) { + commonSource = this.doMergeFile(uploadStateDTO, commonSource); + isDone = true; + } + } + + + Long sourceId = 0L; + //完成合并或直接上传,添加数据 + if (commonSource != null && !StringUtil.isEmpty(commonSource.getHashMd5())) { + //验证文件大小 + this.doBeforeInsert(uploadDTO, commonSource); + sourceId = this.updateData(commonSource); + LogUtil.info("上传入库完成, " + sourceId + "@" + JsonUtils.beanToJson(commonSource)); + } + + boolean finalSuccess = false; + //设置返回前端的值 + if (sourceId != null && !sourceId.equals(0L)) { + + commonSourceVO.setState(1); + finalSuccess = true; + commonSourceVO.setSourceID(commonSource.getSourceID()); + commonSourceVO.setFileID(sourceId); + commonSourceVO.setFileType(commonSource.getFileType()); + commonSourceVO.setName(commonSource.getName()); + commonSourceVO.setHashMd5(commonSource.getHashMd5()); + commonSourceVO.setPath(commonSource.getPath()); + commonSourceVO.setSourceLength(commonSource.getSourceLength()); + commonSourceVO.setIsM3u8(commonSource.getIsM3u8()); + //返回path + commonSourceVO.setPath(FileUtil.returnPath(commonSourceVO.getPath(), uploadDTO.getBusType(), commonSource.getThumb())); + LogUtil.info("上传成功等待返回, " + JsonUtils.beanToJson(commonSourceVO) + ", " + uploadDTO.getChunk()); + + //根据业务类型,处理后续 + this.doByBusType(uploadDTO, false, commonSource, busTypeEnum, disk); + // + commonSourceVO.setThumb(commonSource.getThumb()); + commonSourceVO.setResolution(commonSource.getResolution()); + + + if (isDone) { + // 添加历史记录 保证size正确 + sourceHistoryUtil.changeCheckSourceHistory(new IoSourceHistory(commonSourceVO.getSourceID(),commonSourceVO.getFileID(),loginUser.getUserID(),size), ioSourceHistory); + + } + + + } + if (finalSuccess) { + LogUtil.info("fileUpload 上传再看次VO的数据" + JsonUtils.beanToJson(commonSourceVO)); + } + if (isDone) { + // 添加文档操作event + fileOptionTool.addSourceEvent(commonSource.getSourceID(), commonSource.getParentID(), loginUser.getUserID(), commonSource.getName(), EventEnum.uploadNew); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + reMap.put("type", "editFile"); + reMap.put("userID", loginUser.getUserID()); + reMap.put("pathName", commonSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileEdit.getCode(), paramList, systemLogTool.getRequest()); + } + + BeanUtils.copyProperties(commonSource, commonSourceRe); + + if (!ObjectUtils.isEmpty(commonSource.getCheckMerge()) && commonSource.getCheckMerge()) { + commonSource.setUserID(loginUser.getUserID()); + asyncDoMergeFileUtil.asyncDoMergeFileUtil(uploadStateDTO, commonSource, commonSourceVO, uploadDTO.getBusType()); + } + return commonSourceVO; + } + + /** + * @Description: 文件信息入库 + * @params: [uploadStateDTO] + * @Return: java.lang.Boolean + * @Modified: + */ + private Long addData(CommonSource commonSource, BusTypeEnum busTypeEnum) { + + if (!ObjectUtils.isEmpty(commonSource.getParentID()) && commonSource.getParentID() > 0) { + CommonSource parentSource = fileOptionTool.getSourceInfo(commonSource.getParentID()); + if (ObjectUtils.isEmpty(parentSource)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + commonSource.setParentLevel(parentSource.getParentLevel() + commonSource.getParentID() + ","); + commonSource.setTargetType(parentSource.getTargetType()); + } else { + commonSource.setParentLevel(",0,"); + commonSource.setTargetType(0); + if (BusTypeEnum.checkIsInfoType(busTypeEnum.getBusType())) { + commonSource.setTargetType(3); + } + } + Long sourceId; + try { + fileOptionTool.addCommonSource(commonSource.getUserID(), commonSource, EventEnum.upload, commonSource.getFileID()); + sourceId = commonSource.getFileID(); + } catch (Exception e) { + LogUtil.error(e, "source入库失败" + JsonUtils.beanToJson(commonSource)); + return 0L; + } + return sourceId; + } + + private Long addCheckData(CommonSource commonSource, Long opUserId) { + + if (!ObjectUtils.isEmpty(commonSource.getParentID()) && commonSource.getParentID() > 0) { + CommonSource parentSource = fileOptionTool.getSourceInfo(commonSource.getParentID()); + if (ObjectUtils.isEmpty(parentSource)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + commonSource.setParentLevel(parentSource.getParentLevel() + commonSource.getParentID() + ","); + commonSource.setTargetType(parentSource.getTargetType()); + } else { + commonSource.setParentLevel(",0,"); + commonSource.setTargetType(0); + } + Long sourceId; + try { + IOSource source = fileOptionTool.addIoSourceDetail(commonSource, opUserId, commonSource.getFileID(), EventEnum.upload); + sourceId = commonSource.getFileID(); + } catch (Exception e) { + LogUtil.error(e, "source入库失败" + JsonUtils.beanToJson(commonSource)); + return 0L; + } + return sourceId; + } + + + private Long updateData(CommonSource commonSource) { + Long sourceId; + try { + fileOptionTool.updateCommonSource(commonSource.getUserID(), commonSource); + sourceId = commonSource.getFileID(); + } catch (Exception e) { + LogUtil.error(e, "source fileUpload updateData入库失败" + JsonUtils.beanToJson(commonSource)); + return 0L; + } + return sourceId; + } + + + /** + * @Description: 入库前的一些处理 + * @params: [commonSource] + * @Return: void + * @Modified: + */ + private void doBeforeInsert(UploadDTO uploadDTO, CommonSource commonSource) { + //MP3长度 + if (commonSource.getFileType().equals("mp3")) { + Integer length = VideoUtil.getVideoLength(commonSource.getPath()); + commonSource.setSourceLength(length); + } + //加上媒体号短视频 + if (StringUtil.isEmpty(commonSource.getThumb()) + || uploadDTO.getBusType().equals(BusTypeEnum.CLOUD.getTypeCode()) + || uploadDTO.getBusType().equals(BusTypeEnum.HOMEPAGE_VIDEO.getTypeCode()) + ) { + busTypeHandleService.doForWareAndAttachment(uploadDTO, false, commonSource); + } + //图片 + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType())) { + //分辨率 + String resolution = ImageUtil.getResolution(commonSource.getPath()); + commonSource.setResolution(resolution); + } else if (Arrays.asList(GlobalConfig.CAMERA_TYPE_ARR).contains(commonSource.getFileType())) { + // 相机文件 + + } else if (commonSource.getResolution() == null) { + commonSource.setResolution(""); + } + } + + @Resource + private FileProperties fileProperties; + + @Resource + private Environment environment; + + /** + * @Description: 非分段,直接保存文件 + * @params: [uploadDTO] + * @Return: com.svnlan.upload.domain.CommonSource + * @Modified: + */ + private CommonSource doSaveDirect(UploadDTO uploadDTO, CommonSource commonSource) { + + MultipartFile file = uploadDTO.getFile(); + if (file == null) { + return null; + } + String busType = uploadDTO.getBusType(); + String finalTopPath = null; + //最终文件目录路径 + if (Arrays.asList("image","avatar").contains(busType)){ + finalTopPath = PropertiesUtil.getUpConfig(busType + ".savePath"); + }else { + String defaultPath = storageService.getDefaultStorageDevicePath(); + finalTopPath = defaultPath + PropertiesUtil.getUpConfig(busType + ".savePath"); + } + + if (Arrays.asList(environment.getActiveProfiles()).contains("local")) { + // 表示是我本机环境的话 + finalTopPath = fileProperties.getFilePathRoot(); + } + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + LogUtil.info("doSaveDirect finalFolderPath=" + finalFolderPath); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + String originalFilename = file.getOriginalFilename(); + //文件后缀 + String fileExtension = ""; + if (!ObjectUtils.isEmpty(uploadDTO.getExt()) && "drawio".equals(uploadDTO.getExt())) { + fileExtension = "drawio"; + originalFilename = originalFilename.replaceAll(".txt", ".drawio"); + } else { + fileExtension = FileUtil.getFileExtension(FileUtil.removeIllegalSymbol(originalFilename)); + } + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + commonSource.getUserID() + "." + fileExtension; + //最终文件 + File finalFile = new File(finalFilePath); + String serverChecksum = ""; + FileInputStream fis = null; + try { + this.writeFile(finalFile, file.getBytes()); + fis = new FileInputStream(finalFile); + if (!ObjectUtils.isEmpty(uploadDTO.getHashMd5())) { + serverChecksum = uploadDTO.getHashMd5(); + } else if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileExtension)) { + serverChecksum = DigestUtils.md5DigestAsHex(fis); + } else { + commonSource.setNeedHashMd5(1); + } + //serverChecksum = DigestUtils.md5DigestAsHex(fis); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage(), " 上传文件失败"); + return null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + + commonSource.setName(originalFilename); + Integer typeCode = BusTypeEnum.getFromTypeName(busType).getTypeCode(); + commonSource.setSourceType(typeCode); + commonSource.setSize(file.getSize()); + commonSource.setHashMd5(serverChecksum); + //commonSource.setPath(StringUtil.replaceFirst(finalFilePath, finalTopPath, "")); + commonSource.setPath(finalFilePath); + //todo 文件后缀太长 + commonSource.setFileType(fileExtension); + LogUtil.info("doSaveDirect commonSource=" + JsonUtils.beanToJson(commonSource)); + return commonSource; + } + + /** + * @Description: 根据业务类型做处理 + * @params: [uploadDTO, isBefore, commonSource, busTypeEnum] + * @Return: void + * @Author: sulijuan + * @Date: 2023/2/16 10:14 + * @Modified: + */ + @Override + public void doByBusType(UploadDTO uploadDTO, boolean isBefore, CommonSource commonSource, BusTypeEnum busTypeEnum, HomeExplorerVO disk) { + if (isBefore) { + + } else if (!isBefore) { + /** 更新 企业云盘 memory */ + if (!ObjectUtils.isEmpty(disk)) { + fileOptionTool.updateMemory(commonSource); + } + } + + switch (busTypeEnum) { + case IMAGE: + case AVATAR: + busTypeHandleService.doForImage(uploadDTO, isBefore, commonSource); + break; + case CLOUD: + busTypeHandleService.doForCloud(uploadDTO, isBefore, commonSource); + break; + default: + break; + } + //额外的缩略图处理 + if (uploadDTO.getThumbSize() != null && !isBefore) { + busTypeHandleService.doForExtraImage(uploadDTO, commonSource); + } + } + + /** + * @Description: 文件是否存在 + * @params: [fileName] + * @Return: java.lang.Boolean + * @Modified: + */ + private Boolean fileExists(String fileName) { + return new File(fileName).exists(); + } + + /** + * @Description: 写文件 + * @params: [file, fileBytes] + * @Return: java.lang.Boolean + * @Modified: + */ + private Boolean writeFile(File file, byte[] fileBytes) { + try (FileOutputStream fileOutputStream = new FileOutputStream(file); + BufferedOutputStream out = new BufferedOutputStream(fileOutputStream);) { + out.write(fileBytes); + out.flush(); + } catch (IOException e) { + LogUtil.error(e, "写入文件失败, " + file.getAbsolutePath()); + return false; + } + return true; + } + + /** + * @Description: 分段路径 md5第一位/md5第二位/ + * @params: [checksum] + * @Return: java.lang.String + * @Modified: + */ + private String getPartPath(String checksum) { + return checksum.substring(0, 1) + "/" + checksum.substring(1, 2) + "/"; + } + + private String getTempFolderPath(String tempFolderPath, String checksum) { + return tempFolderPath + getPartPath(checksum) + checksum + "/"; + } + + /** + * @Description: 执行保存分段文件 + * @params: [uploadDTO] + * @Return: boolean + * @Modified: + */ + private UploadStateDTO doSaveTemp(UploadDTO uploadDTO) { + UploadStateDTO uploadStateDTO = new UploadStateDTO(); + //完成状态false + uploadStateDTO.setUpState(false); + //分段全部完成false + uploadStateDTO.setPartAllDone(false); + //业务类型 + String busType = uploadDTO.getBusType(); + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(busType); + if (busTypeEnum == null) { + return uploadStateDTO; + } + uploadStateDTO.setExt(uploadDTO.getExt()); + //读取临时文件路径配置 + uploadStateDTO.setBusType(busType); + String defaultPath = storageService.getDefaultStorageDevicePath(); + String tempFolderPath = defaultPath + PropertiesUtil.getUpConfig(busType + ".savePath") + "tmp/"; + + //原始文件md5 + String checksum = uploadDTO.getHashMd5(); + //临时文件目录:基础路径+分段路径 基础路径/md5第一位/md5第二位/ + tempFolderPath = this.getTempFolderPath(tempFolderPath, checksum); + try { + File folder = new File(tempFolderPath); +// System.out.println(tempFolderPath); + //新建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败 path:" + tempFolderPath); +// return uploadStateDTO; + } + } + + MultipartFile file = uploadDTO.getFile(); + //当前分段号 + Integer curChunk = uploadDTO.getChunk(); + //md5_分段号.part + String tempFileName = checksum + "_" + curChunk + ".part"; + + File tempFile = new File(tempFolderPath + tempFileName); + + //写入文件 + Boolean writeSuccess = this.writeFile(tempFile, file.getBytes()); + //分段文件md5 +// FileInputStream fis = new FileInputStream(tempFile); +// String chunkMd5 = DigestUtils.md5DigestAsHex(fis); +// fis.close(); + //todo 单片段md5 + + if (!writeSuccess) { + LogUtil.error("写入文件失败"); + return uploadStateDTO; + } +// String md5File = tempFolderPath + checksum + "_md5.txt"; +// FileUtil.putFileContent(md5File,chunkMd5); + + + //分段数 + Integer chunks = uploadDTO.getChunks(); + //分段是否全部完成 + Boolean allDone = true; + for (int i = 0; i < chunks; i++) { + String idxFileName = tempFolderPath + checksum + "_" + i + ".part"; + //某个分段不存在,则表示未完成 + if (!fileExists(idxFileName)) { + allDone = false; + break; + } + } + if (allDone) { + String doneName = tempFolderPath + "done.txt"; + allDone = this.lockForDone(doneName); + } + System.out.println("allDone:" + allDone.toString()); + if (allDone) { + uploadStateDTO.setChecksum(checksum); + uploadStateDTO.setTempPath(tempFolderPath); + uploadStateDTO.setChunks(chunks); + uploadStateDTO.setFileName(FileUtil.removeIllegalSymbol(file.getOriginalFilename())); + } + uploadStateDTO.setPartAllDone(allDone); + uploadStateDTO.setUpState(true); + return uploadStateDTO; + + } catch (Exception e) { + LogUtil.error(e, "保存temp失败"); + } + return uploadStateDTO; + } + + /** + * @Description: 文件锁,防止2次合并 + * @params: [fileName] + * @Return: java.lang.Boolean + * @Modified: + */ + private Boolean lockForDone(String fileName) { + try { + File file = new File(fileName); + if (!file.exists()) { + if (!file.createNewFile()) { + LogUtil.error("创建done文件失败"); + return false; + } + } + + try (RandomAccessFile fis = new RandomAccessFile(file, "rw"); + FileChannel fCin = fis.getChannel(); + FileLock fLin = fCin.tryLock()) { + if (fLin == null) { + LogUtil.error("获取锁失败, " + fileName); + return false; + } + byte[] buf = new byte[1024]; +// StringBuilder sb = new StringBuilder(); + String doneContent = ""; + if ((fis.read(buf)) != -1) { + doneContent = new String(buf, "utf-8"); + } + boolean trueDone = false; + if ("".equals(doneContent) || "done".equals(doneContent)) { + doneContent = "done"; + fis.write(doneContent.getBytes("utf-8")); + trueDone = true; + } + return trueDone; + } + } catch (Exception e) { + LogUtil.error(e, "done处理失败"); + } + return false; + } + + /** + * @Description: 合并临时文件 + * @params: [uploadStateDTO] + * @Return: com.svnlan.common.dto.UploadStateDTO + * @Modified: + */ + private CommonSource doMergeFile(UploadStateDTO uploadStateDTO, CommonSource commonSource) { + LogUtil.info("merge start. time:" + new Date()); + //业务类型 + String busType = uploadStateDTO.getBusType(); + Integer typeCode = BusTypeEnum.getFromTypeName(busType).getTypeCode(); + String checksum = uploadStateDTO.getChecksum(); + String tempPath = uploadStateDTO.getTempPath(); + Integer chunks = uploadStateDTO.getChunks(); + //合并状态失败 + if (StringUtil.isEmpty(checksum) || StringUtil.isEmpty(tempPath) || chunks.equals(0)) { + uploadStateDTO.setMergeState(false); + return null; + } + String defaultPath = storageService.getDefaultStorageDevicePath(); + //最终文件目录路径 + String finalTopPath = defaultPath + PropertiesUtil.getUpConfig(busType + ".savePath"); + + //基础路径+平台网校路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + //文件后缀 + String fileExtension = ""; + if (!ObjectUtils.isEmpty(uploadStateDTO.getExt()) && "drawio".equals(uploadStateDTO.getExt())) { + fileExtension = "drawio"; + uploadStateDTO.setFileName(uploadStateDTO.getFileName().replaceAll(".txt", ".drawio")); + } else { + fileExtension = FileUtil.getFileExtension(uploadStateDTO.getFileName()); + } + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + FileUtil.getRealFileName(commonSource.getUserID(), fileExtension); + //最终文件 ---------------- 更改为异步合并 异步调用则放入库后:上一层 + + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource)){ + //最终文件 + File finalFile = new File(finalFilePath); + //临时文件数组 + File[] tempFiles = new File[chunks]; + try (FileChannel finalFileChannel = new FileOutputStream(finalFile, true).getChannel();) { + StringBuilder tempFilePath; + //将临时文件合并到最终文件 + LogUtil.info("merge break1. time:" + new Date()); + for (int i = 0; i < chunks; i++) { + //拼接临时文件路径 + tempFilePath = new StringBuilder(); + tempFilePath.append(tempPath); + tempFilePath.append(checksum); + tempFilePath.append("_"); + tempFilePath.append(i); + tempFilePath.append(".part"); + //通过FileChannel + tempFiles[i] = new File(tempFilePath.toString()); + try (FileChannel tempFileChannel = new FileInputStream(tempFiles[i]).getChannel();) { + tempFileChannel.transferTo(0, tempFileChannel.size(), finalFileChannel); + } + } + LogUtil.info("merge break2. time:" + new Date()); + //设置合并状态为true + uploadStateDTO.setMergeState(true); + } catch (Exception e) { + LogUtil.error(e, "合并文件失败" + JsonUtils.beanToJson(commonSource)); + return null; + } + commonSource.setSize(finalFile.length()); + + + //删除临时文件 + for (int i = 0; i < chunks; i++) { + tempFiles[i].delete(); + } + try { + new File(tempPath + "done.txt").delete(); + } catch (Exception e){ + LogUtil.error(e, "删除done文件失败"); + } + + + }else { + commonSource.setCheckMerge(true); + } + + try { + //设置合并状态为true + uploadStateDTO.setMergeState(true); + //最终合并文件md5 + LogUtil.info("merge break2.5time:" + new Date()); + commonSource.setHashMd5(""); + if (!ObjectUtils.isEmpty(uploadStateDTO.getChecksum())) { + commonSource.setHashMd5(uploadStateDTO.getChecksum()); + } else { + commonSource.setNeedHashMd5(1); + } + + //todo 最终md5与前端传过来的对比,考虑是否要失败 + //todo 23-05-31 视频 md5通过前端入参,如果不入参则异步修改 + + //设置文件名,相对路径,md5 + commonSource.setName(uploadStateDTO.getFileName()); + // commonSource.setPath(StringUtil.replaceFirst(finalFilePath, finalTopPath, "")); + commonSource.setPath(finalFilePath); + commonSource.setFileType(fileExtension); + commonSource.setSourceType(typeCode); + LogUtil.info("file info : " + JsonUtils.beanToJson(commonSource)); + + } catch (Exception e) { + LogUtil.error(e, "合并文件失败" + JsonUtils.beanToJson(commonSource)); + return null; + } + LogUtil.info("merge finished. time:" + new Date()); + return commonSource; + } + + /** + * @Description: 验证文件是否存在,通过md5 + * @params: [checksum] * @Return: com.svnlan.upload.enumpack.UploadEnum + * @Modified: + */ + @Override + public Map checkFile(CheckFileDTO checkFileDTO, LoginUser loginUser) { + + Map resultMap = new HashMap<>(2); + // 参数错误 + if (ObjectUtils.isEmpty(checkFileDTO) || ObjectUtils.isEmpty(checkFileDTO.getHashMd5()) || ObjectUtils.isEmpty(checkFileDTO.getSize()) + || ObjectUtils.isEmpty(checkFileDTO.getSourceID())) { + return this.reUploadMap(resultMap, checkFileDTO); + } + //验证业务类型 + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(checkFileDTO.getBusType()); + if (busTypeEnum == null) { + return this.reUploadMap(resultMap, checkFileDTO); + } + if (Arrays.asList("image","avatar").contains(checkFileDTO.getBusType())){ + return this.reUploadMap(resultMap, checkFileDTO); + } + + String busType = busTypeEnum.getBusType(); + /** 获取企业云盘 */ + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), checkFileDTO.getSourceID()); + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, checkFileDTO.getSourceID(), disk.getParentLevel(), "5", disk.getTargetType()); + + fileOptionTool.checkMemory(disk, checkFileDTO.getSize()); + + List sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceID()); + + Long time = null; + if (Arrays.asList("dev", "itest").contains(environmentType) ) { + time = 1678723200L; + } + + CommonSource commonSource = fileOptionTool.selectByChecksum(checkFileDTO.getHashMd5(), checkFileDTO.getSize(), time); + if (commonSource == null) { + return this.reUploadMap(resultMap, checkFileDTO); + } + int isM3u8 = ObjectUtils.isEmpty(commonSource.getIsM3u8()) ? 0 : commonSource.getIsM3u8(); + if ((isM3u8 <= 0 && Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()))) { + return this.reUploadMap(resultMap, checkFileDTO); + } + if (Arrays.asList("dev", "itest").contains(environmentType) && commonSource.getCreateTime() < 1678723200) { + return this.reUploadMap(resultMap, checkFileDTO); + } + String finalFilePath = commonSource.getPath(); + if (!fileExists(finalFilePath)) { + LogUtil.error("checkFile 下载文件不存在" + finalFilePath); + return this.reUploadMap(resultMap, checkFileDTO); + } + + commonSource.setUserID(loginUser.getUserID()); + /** 获取企业云盘 */ + UploadDTO uploadDTO = new UploadDTO(); + checkFileDTO.setIgnoreFileSize(disk.getIgnoreFileSize()); + uploadDTO.setChunk(checkFileDTO.getChunk()); + uploadDTO.setChunks(checkFileDTO.getChunks()); + + commonSource.setTargetType(disk.getTargetType()); + if (BusTypeEnum.checkIsInfoType(busTypeEnum.getBusType())) { + commonSource.setTargetType(3); + } + resultMap.put("fileExists", true); + resultMap.put("chunkList", new ArrayList<>()); + CommonSource newSource = new CommonSource(); + newSource.setGroupID(disk.getGroupID()); + newSource.setFileID(commonSource.getFileID()); + //设置默认值 + fileOptionTool.setDefault(newSource, loginUser); + //云盘验证 + if (busTypeEnum.equals(BusTypeEnum.CLOUD)) { + checkFileDTO.setBusTypeCode(BusTypeEnum.CLOUD.getTypeCode().toString()); + } + commonSource.setSourceLength(0); + if (!ObjectUtils.isEmpty(commonSource.getValue())) { + try { + FileMetaVo fileMetaVo = JsonUtils.jsonToBean(commonSource.getValue(), FileMetaVo.class); + if (!ObjectUtils.isEmpty(fileMetaVo)) { + if (!ObjectUtils.isEmpty(fileMetaVo.getLength()) && fileMetaVo.getLength() > 0) { + commonSource.setSourceLength(fileMetaVo.getLength()); + } + commonSource.setThumb(ObjectUtils.isEmpty(fileMetaVo.getThumb()) ? "" : fileMetaVo.getThumb()); + commonSource.setAppPreviewUrl(ObjectUtils.isEmpty(fileMetaVo.getAppViewUrl()) ? "" : fileMetaVo.getAppViewUrl()); + commonSource.setH264Path(ObjectUtils.isEmpty(fileMetaVo.getH264Path()) ? "" : fileMetaVo.getH264Path()); + commonSource.setResolution(ObjectUtils.isEmpty(fileMetaVo.getResolution()) ? "" : fileMetaVo.getResolution()); + commonSource.setPreviewUrl(ObjectUtils.isEmpty(fileMetaVo.getViewUrl()) ? "" : fileMetaVo.getViewUrl()); + commonSource.setYzEditData(fileMetaVo.getYzEditData()); + commonSource.setYzViewData(fileMetaVo.getYzViewData()); + } + } catch (Exception e) { + LogUtil.error(e, " jsonToBean error fileMeta desc value=" + commonSource.getValue()); + } + } + try { + //MP3长度 + if (!ObjectUtils.isEmpty(commonSource.getFileType()) && commonSource.getFileType().equals("mp3") && commonSource.getSourceLength().equals(0)) { + Integer length = VideoUtil.getVideoLength(commonSource.getPath()); + newSource.setSourceLength(length); + } else { + newSource.setSourceLength(commonSource.getSourceLength()); + } + } catch (Exception e) { + newSource.setSourceLength(0); + LogUtil.error(e, " mp3 value=" + commonSource.getValue()); + } + + newSource.setParentID(checkFileDTO.getSourceID()); + newSource.setParentLevel(disk.getParentLevel()); + newSource.setUserID(loginUser.getUserID()); + newSource.setHashMd5(commonSource.getHashMd5()); + newSource.setPath(commonSource.getPath()); + if (!ObjectUtils.isEmpty(checkFileDTO.getName())) { + newSource.setName(checkFileDTO.getName()); + newSource.setFileType(FileUtil.getFileExtension(checkFileDTO.getName())); + } else if (!ObjectUtils.isEmpty(checkFileDTO.getFileName())) { + newSource.setName(checkFileDTO.getFileName()); + newSource.setFileType(FileUtil.getFileExtension(checkFileDTO.getFileName())); + } else { + newSource.setName(commonSource.getName()); + newSource.setFileType(commonSource.getFileType()); + } + String firstPath = FileUtil.getFirstStorageDevicePath(newSource.getPath()); + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + + newSource.setName(fileOptionTool.checkRepeatName(newSource.getName(), newSource.getName(), newSource.getFileType(), sourceNameList, 1)); + newSource.setSourceType(busTypeEnum.getTypeCode()); + newSource.setSize(commonSource.getSize()); + newSource.setIsPreview(commonSource.getIsPreview()); + newSource.setIsM3u8(commonSource.getIsM3u8()); + newSource.setAppPreview(commonSource.getAppPreview()); + newSource.setAppPreviewUrl(commonSource.getAppPreviewUrl()); + newSource.setPreviewUrl(commonSource.getPreviewUrl()); + newSource.setThumbSize(commonSource.getThumbSize()); + newSource.setConvertSize(commonSource.getConvertSize()); + //将原文件的视频转码信息直接拿来置下 + newSource.setH264Path(commonSource.getH264Path()); + newSource.setIsH264Preview(commonSource.getIsH264Preview()); + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(newSource.getFileType())) { + if (!ObjectUtils.isEmpty(commonSource.getResolution()) && !"0*0".equals(commonSource.getResolution())) { + newSource.setResolution(commonSource.getResolution()); + } else { + String resolution = ImageUtil.getResolution(newSource.getPath()); + newSource.setResolution(resolution); + } + } else { + newSource.setResolution(commonSource.getResolution()); + } + boolean checkPic = false; + // 已改 + String prePath = PropertiesUtil.getUpConfig(busType + ".savePath"); + String audioPicPath = defaultFirstPath + "/mu/images/" + + newSource.getPath().replace("." + newSource.getFileType(), ".jpg").replace(firstPath + prePath, ""); + //缩略图 + newSource.setThumb(commonSource.getThumb()); + if (StringUtil.isEmpty(newSource.getThumb())) { + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(newSource.getFileType())) { + busTypeHandleService.doForImage(null, false, newSource); + newSource.setThumb((newSource.getPath()) + .replace(firstPath + "/doc/", firstPath + "/common/doc/") + .replace(firstPath + "/attachment/", firstPath + "/common/attachment/") + .replace(firstPath + "/private/", firstPath + "/common/") + ); + } else if (Arrays.asList(GlobalConfig.AUDIO_SHOW_TYPE_ARR).contains(newSource.getFileType())) { + checkPic = VideoUtil.getAudioPic(newSource.getPath(), audioPicPath); + if (checkPic) { + newSource.setThumb(audioPicPath); + File checkPicFile = new File(audioPicPath); + if (checkPicFile.exists()){ + newSource.setThumbSize(ObjectUtils.isEmpty(newSource.getThumbSize()) ? 0L : newSource.getThumbSize()); + newSource.setThumbSize(newSource.getThumbSize() + checkPicFile.length()); + } + } + } + + + } + + String filename = commonSource.getName(); + String suffix = FileUtil.getFileExtension(filename); + String path = commonSource.getPath(); + //若是视频且分辨率为空时 + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(suffix) + && StringUtil.isEmpty(newSource.getResolution())) { + int[] heightAndWidth = VideoUtil.getHeightAndWidth(path); + String resolution = "1280*720"; + if (heightAndWidth[0] != 0 && heightAndWidth[1] != 0) { + resolution = heightAndWidth[1] + "*" + heightAndWidth[0]; + } + newSource.setResolution(resolution); + } + // + Long sourceId = this.addCheckData(newSource, loginUser.getUserID()); + + if (checkPic) { + convertUtil.setCheckFileOther(checkFileDTO.getHashMd5(), checkFileDTO.getSize(), audioPicPath); + } + + resultMap.put("sourceID", newSource.getSourceID()); + resultMap.put("fileID", sourceId); + resultMap.put("resolution", newSource.getResolution()); + resultMap.put("sourcePath", FileUtil.returnPath(newSource.getPath(), busTypeEnum.getBusType(), newSource.getThumb())); + resultMap.put("thumb", newSource.getThumb()); + //处理返回文档预览URL + CommonSourceVO commonSourceVO = new CommonSourceVO(); + // + // this.doPreviewUrlByBusType(newSource, busTypeEnum, commonSourceVO); + String previewUrl = commonSourceVO.getPath(); + if (!StringUtil.isEmpty(previewUrl)) { + resultMap.put("sourcePath", previewUrl); + } + //第三方预览地址 + String newPreviewUrl = commonSourceVO.getPreviewUrl(); + if (!StringUtil.isEmpty(newPreviewUrl)) { + resultMap.put("previewUrl", newPreviewUrl); + } + // 更新容量 + fileOptionTool.updateMemory(newSource); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", newSource.getSourceID()); + reMap.put("sourceParent", newSource.getParentID()); + if (!ObjectUtils.isEmpty(newSource.getParentLevel())) { + reMap.put("sourceParentLevel", newSource.getParentLevel()); + } + reMap.put("type", "upload"); + reMap.put("status", "1"); + reMap.put("userID", loginUser.getUserID()); + reMap.put("pathName", newSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileUpload.getCode(), paramList, systemLogTool.getRequest()); + + return resultMap; + } + + private Map reUploadMap(Map resultMap, CheckFileDTO checkFileDTO) { + resultMap.put("fileExists", false); + resultMap.put("sourceId", 0); + resultMap.put("checkFile", JsonUtils.beanToJson(checkFileDTO)); + //获取已上传的分片序号 + List chunkList = this.getChunkFileIndex(checkFileDTO); + resultMap.put("chunkList", chunkList); + return resultMap; + } + + private List getChunkFileIndex(CheckFileDTO checkFileDTO) { + String defaultPath = storageService.getDefaultStorageDevicePath(); + String tempFolderPath = defaultPath + PropertiesUtil.getUpConfig(checkFileDTO.getBusType() + ".savePath") + "tmp/"; + //原始文件md5 + String checksum = checkFileDTO.getHashMd5(); + //临时文件目录:基础路径+分段路径 基础路径/md5第一位/md5第二位/ + tempFolderPath = this.getTempFolderPath(tempFolderPath, checksum); + File tmpFileDir = new File(tempFolderPath); + File[] chunkFiles = tmpFileDir.listFiles(); + List chunkList = new ArrayList<>(); + if (chunkFiles == null || chunkFiles.length == 0) { + return chunkList; + } + for (File f : chunkFiles) { + if (f.length() != GlobalConfig.CHUNK_FILE_SIZE) { + continue; + } + String fileName = f.getName(); + if (fileName.length() <= 7 || !fileName.substring(fileName.length() - 5).equals(".part")) { + continue; + } + String indexStr = fileName.substring(fileName.indexOf("_") + 1, fileName.length() - 5); + try { + + chunkList.add(Integer.parseInt(indexStr)); + } catch (Exception e) { + LogUtil.error("分片上传, 文件名解析错误"); + } + } + + return chunkList; + } + + @Override + public Map checkChunk(CheckFileDTO checkChunkDTO, LoginUser loginUser) { + + return null; + } + + @Override + public String returnSource(CheckFileDTO previewAttachDTO, String passedFileName, HttpServletResponse response) { + + if (previewAttachDTO.getBusType() == null || previewAttachDTO.getBusId() == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(previewAttachDTO.getBusType()); + if (busTypeEnum == null) { + LogUtil.error("业务类型错误"); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + previewAttachDTO.setBusTypeCode(busTypeEnum.getTypeCode().toString()); + CommonSource commonSource = fileOptionTool.getFileAttachment(previewAttachDTO.getBusId()); + + if (commonSource == null) { + // 记录不存在 + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String finalFilePath = commonSource.getPath(); + if (!fileExists(finalFilePath)) { + LogUtil.error("下载文件不存在" + finalFilePath); + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String fileName = passedFileName == null ? commonSource.getName() : passedFileName; + try { + fileName = URLEncoder.encode(fileName, "UTF-8"); + fileName = fileName.replaceAll("\\+", "%20"); + } catch (Exception e) { + LogUtil.error(e, "下载文件,编码失败"); + } + boolean isSwf = "swf".equals(commonSource.getFileType()) && Boolean.TRUE.equals(previewAttachDTO.getViewSwf()); + + try { + FileUtil.responseFile(response, finalFilePath, fileName, isSwf); + } catch (Exception e) { + LogUtil.error(e, "资源获取失败"); + } + return ""; + } + + @Override + public Map getPreviewInfo(CheckFileDTO getCloudPreviewDTO) { + + String code = ""; + // 分享 + if (!ObjectUtils.isEmpty(getCloudPreviewDTO.getShareCode())) { + List list = shareDao.getShareByCode(getCloudPreviewDTO.getShareCode()); + if (CollectionUtils.isEmpty(list) || list.size() > 1) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorPathTips.getCode()); + } + ShareVo vo = list.get(0); + vo.setPassword(null); + getCloudPreviewDTO.setBusType(BusTypeEnum.CLOUD.getBusType()); + try { + code = "&shareCode=" + URLEncoder.encode(getCloudPreviewDTO.getShareCode(), "UTF-8"); + shareDao.updateNumView(vo.getShareID(), vo.getNumView() + 1); + } catch (Exception e) { + LogUtil.error("getPreviewInfo updateNumView error"); + } + } + if (ObjectUtils.isEmpty(getCloudPreviewDTO.getSourceID()) || getCloudPreviewDTO.getSourceID() <= 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + //验证业务类型 + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(getCloudPreviewDTO.getBusType()); + if (busTypeEnum == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + getCloudPreviewDTO.setF(ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) ? 0L : getCloudPreviewDTO.getF()); + CommonSource cloudFile = fileOptionTool.getFileAttachment(getCloudPreviewDTO.getSourceID(), getCloudPreviewDTO.getF()); + + if (cloudFile == null || ObjectUtils.isEmpty(cloudFile.getName())) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String downloadKey = FileUtil.getDownloadKey(); + String downloadUrl = null; + if (!ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) && getCloudPreviewDTO.getF() > 0) { + downloadUrl = "/api/disk/attachment/" + FileUtil.encodeDownloadUrl(cloudFile.getName()) + + fileOptionTool.getDownloadParam(cloudFile.getSourceID(), downloadKey, code) + "&f=" + getCloudPreviewDTO.getF(); + } else { + downloadUrl = "/api/disk/attachment/" + FileUtil.encodeDownloadUrl(cloudFile.getName()) + + fileOptionTool.getDownloadParam(cloudFile.getSourceID(), downloadKey, code); + } + String m3u8Key = FileUtil.getM3u8Key(); + Map reMap = new HashMap<>(1); + + String domain = HttpUtil.getRequestRootUrl(null); + reMap.put("sourceID", cloudFile.getSourceID()); + reMap.put("fileID", cloudFile.getFileID()); + reMap.put("fileType", cloudFile.getFileType()); + reMap.put("h5Url", cloudFile.getAppPreviewUrl()); + + Map videoInfo = new HashMap<>(); + boolean checkGetVideo = false; + if ( cloudFile.getIsM3u8().equals(1) && Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(cloudFile.getFileType()) + && (ObjectUtils.isEmpty(cloudFile.getFrame()) || ObjectUtils.isEmpty(cloudFile.getResolution())) + ){ + videoInfo = VideoUtil.getVideoInfo(cloudFile.getPath()); + checkGetVideo = true; + } + /* 视频原文件、图片(用作选择水印)*/ + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(cloudFile.getFileType()) + || Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(cloudFile.getFileType()) + // 字幕文件 + || Arrays.asList("srt","ass").contains(cloudFile.getFileType()) + ) { + + + String fileName = cloudFile.getPath().substring(cloudFile.getPath().lastIndexOf("/") + 1); + String pUrl = cloudFile.getPath().substring(0, cloudFile.getPath().lastIndexOf("/") + 1); + + reMap.put("pUrl", pUrl.replace("/private/", GlobalConfig.private_replace_key)); + reMap.put("fileName", fileName); + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(cloudFile.getFileType())){ + + reMap.put("frame", cloudFile.getFrame()); + if (ObjectUtils.isEmpty(cloudFile.getFrame())){ + if (!ObjectUtils.isEmpty(videoInfo)) { + int frame = VideoUtil.getVideoFrameRate(cloudFile.getPath(), videoInfo, false); + reMap.put("frame", frame); + }else { + reMap.put("frame", 24); + } + } + + } + } + + //若是视频且分辨率为空时 + if ((Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(cloudFile.getFileType()) || Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(cloudFile.getFileType())) + && StringUtil.isEmpty(cloudFile.getResolution())) { + + String resolution = "1280*720"; + if (!ObjectUtils.isEmpty(videoInfo)) { + int[] heightAndWidth = VideoUtil.getHeightAndWidth(cloudFile.getPath(), videoInfo, false); + if (heightAndWidth[0] != 0 && heightAndWidth[1] != 0) { + resolution = heightAndWidth[1] + "*" + heightAndWidth[0]; + } + } + cloudFile.setResolution(resolution); + } + + if(!ObjectUtils.isEmpty(cloudFile.getPath()) && "mp4".equals(cloudFile.getFileType().toLowerCase())) { + String viewKey = FileUtil.getVideoImgDownloadKey(cloudFile.getPath()); + reMap.put("viewKey", viewKey); + reMap.put("viewUrl", "/api/disk/video/img/" + cloudFile.getSourceID() + "." + cloudFile.getFileType() + "?showPreview=1&key=" + viewKey); + } + reMap.put("resolution", ObjectUtils.isEmpty(cloudFile.getResolution()) ? "" : cloudFile.getResolution().replace("x","*")); + reMap.put("isPreview", cloudFile.getIsPreview()); + reMap.put("previewUrl", ""); + reMap.put("isSwf", 0); + reMap.put("swfUrl", ""); + Integer videoLength = ObjectUtils.isEmpty(cloudFile.getSourceLength()) ? 0 : cloudFile.getSourceLength(); + reMap.put("name", cloudFile.getName()); + reMap.put("size", cloudFile.getSize()); + reMap.put("length", videoLength); + reMap.put("isM3u8", cloudFile.getIsM3u8()); + + if (cloudFile.getIsM3u8().equals(1)) {//转码完成的 + //文档类 + if (Arrays.asList(GlobalConfig.DOC_TYPE_ARR).contains(cloudFile.getFileType())) { + reMap.put("isSwf", 1); + reMap.put("swfUrl", cloudFile.getPreviewUrl()); + } else {//视频 + String m3u8Url = "/api/disk/mu/getMyM3u8.m3u8" + fileOptionTool.getM3u8Param(cloudFile.getSourceID(), m3u8Key) + + ((!ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) && getCloudPreviewDTO.getF().longValue() > 0) ? "&f=" + getCloudPreviewDTO.getF().longValue() : ""); + reMap.put("previewUrl", m3u8Url); + } + } + //未完成的. 视频转码进度 + else if (!cloudFile.getIsM3u8().equals(-1) + && Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(cloudFile.getFileType())) { + String sourcePath = cloudFile.getPath(); + //获取视频长度 + + if (videoLength.equals(0)) { + if (checkGetVideo){ + videoLength = VideoUtil.getVideoLength(sourcePath, videoInfo, false); + }else { + videoLength = VideoUtil.getVideoLength(sourcePath); + } + + if (videoLength.equals(0)) { + //获取转码进度 + int dotPosition = sourcePath.lastIndexOf("."); + String m3u8Path = sourcePath.substring(0, dotPosition) + ".m3u8"; + Integer progress = FileUtil.getConvertedLength(m3u8Path, videoLength, true); + reMap.put("convertProgress", progress); + } else { + reMap.put("convertProgress", videoLength); + } + } + } + reMap.put("isH5", cloudFile.getAppPreview()); + reMap.put("downloadUrl", downloadUrl); +// vo.setPptPreviewUrl(pptUtil.getPptPreviewUrl(downloadUrl, cloudFile.getChecksum())); + //到前端页面 + if (Arrays.asList(GlobalConfig.DOC_SHOW_TYPE_ARR).contains(cloudFile.getFileType())) { + reMap.put("pdfPreviewUrl", fileOptionTool.getPptPdfPreview2(cloudFile.getFileType(), cloudFile.getIsH264Preview(), downloadUrl)); + String pptPreviewUrl = fileOptionTool.getPptPreviewUrl(downloadUrl, cloudFile.getHashMd5()); + reMap.put("pptPreviewUrl", pptPreviewUrl);// HttpUtil.getRequestRootUrl(null) + downloadUrl + /*if ("pdf".equals(cloudFile.getFileType())){ + //到前端页面 + String pptPreviewPath = domain + "/business/shareFolder.html?" + + "fileIds=" + cloudFile.getFileID() + + "&sourceID=" + cloudFile.getSourceID() + + "&sl=" + Base64.encodeBase64String(String.valueOf(System.currentTimeMillis() + 86400000 * 7).getBytes()) + + "&isApp=1"; + reMap.put("pptPreviewPath", pptPreviewPath); + }*/ + } + /** .txt .js .json .css .sql .xml .java .cs(c#), 返回text */ + reMap.put("text", ""); + fileContentTool.getFileContent(cloudFile, reMap); + /** ***/ + if (cloudFile.getIsPreview().intValue() == 0) { + // 永中 + boolean isYongZhong = Arrays.asList(GlobalConfig.yongzhong_doc_excel_ppt_type).contains(cloudFile.getFileType()); + if (isYongZhong) { + // 预览 + cloudFile.setDomain(domain); + convertUtil.yongZhongPre(cloudFile, true); + reMap.put("yzViewData", ObjectUtils.isEmpty(cloudFile.getYzViewData()) ? "" : cloudFile.getYzViewData()); + reMap.put("yzEditData", ""); + } + } else { + reMap.put("yzViewData", cloudFile.getYzViewData()); + } + return reMap; + } + + /** + * @Description: 操作文件 + * @params: [updateFileDTO, resultMap] + * @Return: boolean + * @Author: sulijuan + * @Date: 2023/2/17 15:26 + * @Modified: + */ + @Override + public boolean updateFile(CheckFileDTO updateFileDTO, Map resultMap, LoginUser loginUser) { + + CloudOperateEnum operateEnum = CloudOperateEnum.getOperateEnum(updateFileDTO.getOperation()); + if (ObjectUtils.isEmpty(operateEnum)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!ObjectUtils.isEmpty(updateFileDTO.getSourceLevel()) && !ObjectUtils.isEmpty(updateFileDTO.getSourceID())) { + if (updateFileDTO.getSourceLevel().indexOf("," + updateFileDTO.getSourceID() + ",") < 0) { + updateFileDTO.setSourceLevel(updateFileDTO.getSourceLevel() + updateFileDTO.getSourceID() + ","); + } + } + // 锁定 + fileOptionTool.getLock(updateFileDTO.getSourceID()); + + /*if (Arrays.asList(environment.getActiveProfiles()).contains("pro") + || Arrays.asList(environment.getActiveProfiles()).contains("pre") + || Arrays.asList(environment.getActiveProfiles()).contains("test")) { + // 这几个环境需要校验权限 + // 权限校验 + userAuthTool.checkUserPermission(loginUser, updateFileDTO); + }*/ + // 权限校验 + userAuthTool.checkUserPermission(loginUser, updateFileDTO); + + try { + LogUtil.info("云盘操作文件" + JsonUtils.beanToJson(updateFileDTO) + "," + JsonUtils.beanToJson(loginUser)); + switch (operateEnum) { + case RENAME_FILE: + fileOptionTool.renameFile(updateFileDTO, loginUser); + break; + case FAV_RENAME_FILE: + fileOptionTool.favRenameFile(updateFileDTO, loginUser); + break; + case COPY_FILE: + // 锁定 + String concurrentKey = GlobalConfig.CLOUD_OPERATION_LOCK_KEY + updateFileDTO.getSourceID(); + // 锁定 + Boolean setSuccess = this.stringRedisTemplate.opsForValue().setIfAbsent(concurrentKey, "1", 2, TimeUnit.SECONDS); + if(!setSuccess) { + LogUtil.error( "频繁操作 updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + return true; + } + List list = fileOptionTool.copyFile(updateFileDTO, loginUser); + resultMap.put("sourceList", list); + this.stringRedisTemplate.delete(concurrentKey); + break; + case MOVE_FILE: + fileOptionTool.moveFile(updateFileDTO, loginUser); + break; + case DELETE_FILE: + // + Integer removedFileCount = fileOptionTool.deleteFile(updateFileDTO, loginUser); + LogUtil.info("网校资源: 删除文件,数量:" + removedFileCount + ", " + JsonUtils.beanToJson(loginUser) + ", " + + JsonUtils.beanToJson(updateFileDTO) + "," + JsonUtils.beanToJson(updateFileDTO)); + break; + case RECYCLE_FILE: + fileOptionTool.recycleFile(updateFileDTO, loginUser, false); + LogUtil.info("网校资源: 还原文件, " + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case RECYCLE_FILE_ALL: + fileOptionTool.recycleFile(updateFileDTO, loginUser, true); + LogUtil.info("网校资源: 还原文件, " + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case DELETE_BIN: + fileOptionTool.deleteBin(updateFileDTO, loginUser, false); + LogUtil.info("网校资源: 彻底删除 删除回收站," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case DELETE_BIN_ALL: + fileOptionTool.deleteBin(updateFileDTO, loginUser, true); + LogUtil.info("网校资源: 彻底删除回收站所有 删除回收站," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case SHARE_FILE: + fileOptionTool.shareFile(updateFileDTO); + LogUtil.info("网校资源: 分享," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case FAV_FILE: + fileOptionTool.favFile(updateFileDTO, loginUser); + stringRedisTemplate.delete(GlobalConfig.my_fav_key + loginUser.getUserID()); + LogUtil.info("网校资源: 添加收藏," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case FAV_DEL: + fileOptionTool.delFavFile(updateFileDTO, loginUser); + stringRedisTemplate.delete(GlobalConfig.my_fav_key + loginUser.getUserID()); + LogUtil.info("网校资源: 取消收藏," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case FILE_DESC: + fileOptionTool.saveDesc(updateFileDTO, loginUser); + LogUtil.info("网校资源: 添加描述," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case ADD_TOP: + fileOptionTool.addTop(updateFileDTO, loginUser); + LogUtil.info("置顶," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case CANCEL_TOP: + fileOptionTool.cancelTop(updateFileDTO, loginUser); + LogUtil.info("取消置顶," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + case MAKE_FILE: + String concurrentKey1 = GlobalConfig.CLOUD_OPERATION_LOCK_KEY + updateFileDTO.getSourceID() + "_" + updateFileDTO.getName(); + // 锁定 + Boolean setSuccess1 = this.stringRedisTemplate.opsForValue().setIfAbsent(concurrentKey1, "1", 1, TimeUnit.SECONDS); + if(!setSuccess1) { + LogUtil.error( "频繁操作 updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + return true; + } + fileOptionTool.makeFile(updateFileDTO, loginUser, resultMap); + LogUtil.info("新建文件," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + this.stringRedisTemplate.delete(concurrentKey1); + break; + case FILE_COVER: + fileOptionTool.updateFileCover(updateFileDTO, loginUser); + LogUtil.info("修改文件封面," + JsonUtils.beanToJson(loginUser) + ", " + JsonUtils.beanToJson(updateFileDTO)); + break; + default: + LogUtil.info(" default 云盘操作文件" + JsonUtils.beanToJson(updateFileDTO) + "," + JsonUtils.beanToJson(loginUser)); + return false; + } + } catch (SvnlanRuntimeException e) { + throw new SvnlanRuntimeException(e.getErrorCode(), e.getMessage(), true); + } catch (Exception e) { + LogUtil.error(e, "云盘操作失败" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } finally { + //操作完成删除key + fileOptionTool.delLock(updateFileDTO.getSourceID()); + } + return true; + } + + /** + * @Description: 获取附件等文件资源 + * @params: [response, getAttachmentDTO, fileName] + * @Return: java.lang.String + * @Modified: + */ + @Override + public String getAttachment(HttpServletResponse response, GetAttachmentDTO getAttachmentDTO, String fileName, Map resultMap) { + + boolean isShare = false; + // 分享 + if (!ObjectUtils.isEmpty(getAttachmentDTO.getShareCode())) { + isShare = true; + shareTool.checkShareLink(getAttachmentDTO); + } + //获取业务类型 + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(getAttachmentDTO.getBusType()); + if (busTypeEnum == null) { + LogUtil.error("下载文件业务类型错误, " + JsonUtils.beanToJson(getAttachmentDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + //权限 + Boolean hasPermission = true; + LoginUser loginUser = null; + CommonSource commonSourceAttach = null; + if (!ObjectUtils.isEmpty(getAttachmentDTO.getF()) && getAttachmentDTO.getF() > 0) { + commonSourceAttach = ioSourceHistoryDao.getHistorySourceInfo(getAttachmentDTO.getF()); + } else { + commonSourceAttach = fileOptionTool.getSourceInfo(getAttachmentDTO.getBusId()); + } + if (commonSourceAttach == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + boolean down = false; + if (!ObjectUtils.isEmpty(getAttachmentDTO.getD()) && "1".equals(getAttachmentDTO.getD())) { + down = true; + } + + if (down) { + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSourceAttach.getSourceID(), commonSourceAttach.getParentLevel(), "4", commonSourceAttach.getTargetType()); + } + + if (!isShare && !Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSourceAttach.getFileType()) + && !"mp3".equals(commonSourceAttach.getFileType()) + && !Arrays.asList(GlobalConfig.DOC_TYPE_ARR).contains(commonSourceAttach.getFileType()) + // && !pptUtil.checkIpWhiteList() + && !"swf".equals(commonSourceAttach.getFileType()) && Boolean.TRUE.equals(getAttachmentDTO.getViewSwf()) + ) { + hasPermission = false; + } + if (!ObjectUtils.isEmpty(getAttachmentDTO.getKey())) { + String token = fileOptionTool.getAttachmentToken2(getAttachmentDTO.getKey()); + loginUser = loginUserUtil.getLoginUserByToken(HttpUtil.getRequest(), token); + } + if (!hasPermission) { + //从key获取token + if (loginUser == null || loginUser.getUserID() == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.errorAdminAuth.getCode()); + } + } + fileName = ObjectUtils.isEmpty(fileName) ? commonSourceAttach.getName() : fileName; + //是否swf + boolean isSwf = "swf".equals(commonSourceAttach.getFileType()) && Boolean.TRUE.equals(getAttachmentDTO.getViewSwf()); + boolean isMp3 = "isMp3".equals(commonSourceAttach.getFileType()); + + //String basePath = PropertiesUtil.getUpConfig(busTypeEnum.getBusType() + ".savePath"); + //文件实际路径 + String finalFilePath = commonSourceAttach.getPath(); + /*if (commonSourceAttach.getPath().indexOf(basePath) == 0) { + finalFilePath = commonSourceAttach.getPath(); + } else { + finalFilePath = basePath + commonSourceAttach.getPath(); + }*/ + //word看pdf + if (getAttachmentDTO.getForwtop().equals(1) && + (commonSourceAttach.getFileType().equals("doc") || commonSourceAttach.getFileType().equals("docx"))) { + int lastSlash = finalFilePath.lastIndexOf("/"); + finalFilePath = finalFilePath.substring(0, lastSlash) + "/pdf" + finalFilePath.substring(lastSlash); + int dotPosition = finalFilePath.lastIndexOf("."); + finalFilePath = finalFilePath.substring(0, dotPosition) + ".pdf"; + } + + boolean isDown = true; + if (!ObjectUtils.isEmpty(getAttachmentDTO.getGetInfo()) && getAttachmentDTO.getGetInfo().intValue() == 1) { + isDown = false; + } + if (isDown && !ObjectUtils.isEmpty(getAttachmentDTO.getView()) && getAttachmentDTO.getView().intValue() == 1) { + isDown = false; + } + + + + File finalFile = new File(finalFilePath); + if (!finalFile.exists()) { + LogUtil.error("下载文件不存在" + finalFilePath); + this.setDownSystemLogInfo(commonSourceAttach, down, loginUser, 0, "下载文件不存在"); + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + //替换非法字符 + fileName = FileUtil.replaceIllegalSymbol(fileName); + String encodedFileName = fileName; + //url encode + try { + encodedFileName = URLEncoder.encode(fileName, "UTF-8"); + encodedFileName = encodedFileName.replaceAll("\\+", "%20"); + } catch (Exception e) { + LogUtil.error(e, "下载文件,编码失败"); + } + //swf直接返回资源 + if (getAttachmentDTO.getGetInfo() != 2 && !isMp3 && isDown) { + try { + FileUtil.responseFile(response, finalFilePath, encodedFileName, isSwf, isDown); + } catch (Exception e) { + LogUtil.error(e, "资源获取失败"); + } + } + + //有效时间12小时 + //Integer time = (int)(System.currentTimeMillis() / 1000) + 3600 * 12; + //String hex = Integer.toHexString(time).toUpperCase(); + + String firstPath = FileUtil.getFirstStorageDevicePath(finalFilePath); + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + + String hardLinkPath = null; + if (getAttachmentDTO.getGetInfo() == 2) { + // 添加日志 + this.setDownSystemLogInfo(commonSourceAttach, down, loginUser, 1, ""); + return finalFilePath; + }else { + //硬链接地址 + hardLinkPath = finalFilePath.replace(firstPath + "/private/", defaultFirstPath + "/common/down_temp/"); + + File linkFile = new File(hardLinkPath); + + if (!linkFile.getParentFile().exists()) { + linkFile.getParentFile().mkdirs(); + } + try {//创建硬链 + if (!linkFile.exists()) { + Files.createLink(Paths.get(hardLinkPath), Paths.get(finalFilePath)); + } + } catch (FileAlreadyExistsException e) {//文件已存在, 忽略 + LogUtil.error(e, "创建硬链接失败"); + } catch (Exception e) { + LogUtil.error(e, "创建硬链接失败"); + // 添加日志 + this.setDownSystemLogInfo(commonSourceAttach, down, loginUser, 0, "创建硬链接失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.downError.getCode()); + } + try { + //路径缓存, 供定时任务删除使用 + stringRedisTemplate.opsForZSet().add(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, + hardLinkPath, System.currentTimeMillis() + 86400000); + } catch (Exception e) { + LogUtil.error(e, "下载文件缓存失败"); + } + //使用转义后的文件路径 + /*String encodedHardLinkPath = preHardLinkPath + "/" + encodedFileName; + String key = org.apache.commons.codec.digest.DigestUtils.md5Hex(aliAuthMainKey + encodedHardLinkPath + hex); +*/ + //下载key不作为缓存key参数 + getAttachmentDTO.setKey(null); + } + + String cdnPath = ""; + if (ObjectUtils.isEmpty(cdnDomain)) { + cdnPath = HttpUtil.getRequestRootUrl(null) + hardLinkPath; + } else { + cdnPath = HttpUtil.getRequestRootUrl(null) + hardLinkPath; + } + resultMap.put("filePath", cdnPath); + resultMap.put("fileSize", finalFile.length()); + + // 添加日志 + this.setDownSystemLogInfo(commonSourceAttach, down, loginUser, 1, ""); + + return cdnPath; + } + + public void setDownSystemLogInfo(CommonSource commonSourceAttach, boolean down, LoginUser loginUser, Integer status, String remark) { + if (down && !ObjectUtils.isEmpty(loginUser)) { + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSourceAttach.getSourceID()); + reMap.put("fileID", commonSourceAttach.getFileID()); + reMap.put("pathName", ObjectUtils.isEmpty(commonSourceAttach.getSourceName()) ? commonSourceAttach.getName() : commonSourceAttach.getSourceName()); + if (!ObjectUtils.isEmpty(commonSourceAttach.getParentLevel())) { + reMap.put("sourceParentLevel", commonSourceAttach.getParentLevel()); + } + reMap.put("type", "file"); + reMap.put("status", status); + reMap.put("remark", remark); + reMap.put("fromSourceID", commonSourceAttach.getParentID()); + reMap.put("fromName", ""); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileDownload.getCode(), paramList, systemLogTool.getRequest()); + } + } + + @Override + public CommonSource fileSave(SaveUploadDTO uploadDTO, LoginUser loginUser) { + // 参数错误 + if (ObjectUtils.isEmpty(uploadDTO) || ObjectUtils.isEmpty(uploadDTO.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + CommonSource source = fileOptionTool.getSourceInfo(uploadDTO.getSourceID()); + if (source == null) { + LogUtil.error("fileSave source is null"); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (source.getTargetType().intValue() == 2) { + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, source.getSourceID(), source.getParentLevel(), "8", source.getTargetType()); + } + uploadDTO.setContent(ObjectUtils.isEmpty(uploadDTO.getContent()) ? "" : uploadDTO.getContent()); + Long fileID = source.getFileID(); + + String key = GlobalConfig.file_edit_key + loginUser.getUserID() + "_" + uploadDTO.getSourceID() + "_" + uploadDTO.getTaskID(); + ValueOperations operations = stringRedisTemplate.opsForValue(); + String value = operations.get(key); + boolean isOne = false; + if (!ObjectUtils.isEmpty(value) && "1".equals(value)) { + isOne = true; + } else { + operations.set(key, "1", 8, TimeUnit.HOURS); + } + String path = ""; + String fileExtension = source.getFileType(); + if (isOne) { + path = source.getPath(); + File finalFile = new File(path); + if ("svg".equals(source.getFileType().toLowerCase())) { + byte[] size = uploadDTO.getContent().getBytes(StandardCharsets.UTF_8); + FileUtil.writeSvgFile(finalFile, size); + } else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(source.getFileType().toLowerCase())) { + byte[] t = FileUtil.fromHexString(uploadDTO.getContent()); + //转成保存图片 + FileUtil.byte2image(t, path); + } else if (Arrays.asList("doc", "docx").contains(fileExtension.toLowerCase())) { + FileUtil.writeDocFile(finalFile, uploadDTO.getContent()); + } else if (Arrays.asList("ppt", "pptx").contains(fileExtension.toLowerCase())) { + FileUtil.writePptFile(finalFile, uploadDTO.getContent()); + } else if ("html".equals(fileExtension.toLowerCase())) { + FileUtil.writeHTMLFile(finalFile, uploadDTO.getContent()); + } else if (Arrays.asList("xls", "xlsx").contains(fileExtension.toLowerCase())) { + // FileUtil.writeExcelFile(finalFile); + } else { + FileUtil.putFileContent(path, uploadDTO.getContent()); + } + } else { + /** 新增file记录,上条记录插入历史表 */ + CommonSource commonSource2 = new CommonSource(); + saveNewFile(uploadDTO, loginUser, source, commonSource2); + path = commonSource2.getPath(); + fileID = commonSource2.getFileID(); + } + + File finalFile = new File(path); + if (finalFile.exists()) { + // 文件大小 + long size = finalFile.length(); + + long updateSize = size; + if (isOne){ + updateSize = source.getSize() - size; + } + if (size > 0) { + Long groupID = 0L; + if (2 == source.getTargetType().intValue()) { + /** 获取企业云盘 */ + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), uploadDTO.getSourceID()); + groupID = disk.getGroupID(); + } + if (updateSize != 0) { + // 更新容量 + fileOptionTool.updateMemory(size, groupID, loginUser.getUserID(), source.getTargetType(), source.getParentLevel()); + } + } + + // 修改size + if (!ObjectUtils.isEmpty(source.getFileThumbSize()) && source.getFileThumbSize() > 0 && size > source.getFileThumbSize()){ + size = size - source.getFileThumbSize(); + } + IOSource sourceUpdate = new IOSource(); + sourceUpdate.setSize(size); + sourceUpdate.setModifyUser(loginUser.getUserID()); + sourceUpdate.setSourceID(uploadDTO.getSourceID()); + sourceUpdate.setFileID(fileID); + + // 修改文件source修改人、file文件大小 + try { + ioSourceDao.updateFileSize(sourceUpdate); + } catch (Exception e) { + LogUtil.error(e, " fileSave updateFileSize error"); + } + + try { + ioSourceDao.updateSourceModifyUser(sourceUpdate); + } catch (Exception e) { + LogUtil.error(e, " fileSave updateSourceModifyUser error"); + } + } + + if (Arrays.asList(1, 2).contains(source.getTargetType())) { + // 添加文档操作event + fileOptionTool.addSourceEvent(source.getSourceID(), source.getParentID(), loginUser.getUserID(), source.getName(), EventEnum.edit); + } + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", source.getSourceID()); + reMap.put("sourceParent", source.getParentID()); + reMap.put("type", "editFile"); + reMap.put("pathName", source.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileEdit.getCode(), paramList, systemLogTool.getRequest()); + + return source; + } + + private void saveNewFile(SaveUploadDTO uploadDTO, LoginUser loginUser, CommonSource source, CommonSource commonSource2) { + + /** 新增file记录,上条记录插入历史表 */ + + //设置默认值 + fileOptionTool.setDefault(commonSource2, loginUser); + String busType = BusTypeEnum.CLOUD.getBusType(); + commonSource2.setSourceType(BusTypeEnum.CLOUD.getTypeCode()); + commonSource2.setParentLevel(source.getParentLevel()); + commonSource2.setParentID(source.getParentID()); + commonSource2.setSourceID(source.getSourceID()); + commonSource2.setIsEdit("1"); + + + Map resultMap = new HashMap<>(1); + + CheckFileDTO updateFileDTO = new CheckFileDTO(); + updateFileDTO.setContent(uploadDTO.getContent()); + updateFileDTO.setSourceID(uploadDTO.getSourceID()); + fileOptionTool.saveFileDetail(commonSource2, updateFileDTO, busType, source.getFileType(), source.getName(), resultMap, "fileSave"); + + Long userId = source.getUserID(); + IoSourceHistory orgHistory = ioSourceHistoryDao.getHistoryInfoByFileId(source.getSourceID(), source.getFileID()); + if (!ObjectUtils.isEmpty(orgHistory)){ + userId = orgHistory.getUserID(); + } + + // 添加历史记录 sourceID, `userID`,`fileID`, `size`, `detail` + IoSourceHistory ioSourceHistory = new IoSourceHistory(); + ioSourceHistory.setSourceID(source.getSourceID()); + ioSourceHistory.setUserID(ObjectUtils.isEmpty(userId) ? loginUser.getUserID() : userId); + ioSourceHistory.setFileID(source.getFileID()); + ioSourceHistory.setSize(source.getSize()); + ioSourceHistory.setDetail(""); + + // 添加历史记录 + try { + // 保证size正确 + sourceHistoryUtil.changeCheckSourceHistory(new IoSourceHistory(commonSource2.getSourceID(),commonSource2.getFileID(),loginUser.getUserID(),commonSource2.getSize()), ioSourceHistory); + + } catch (Exception e) { + LogUtil.error(e, "添加历史记录失败 uploadDTO=" + JsonUtils.beanToJson(uploadDTO)); + } + } + + @Override + public Map checkFileReplace(CheckFileDTO checkFileDTO, LoginUser loginUser) { + Map resultMap = new HashMap<>(2); + // 参数错误 + if (ObjectUtils.isEmpty(checkFileDTO) || ObjectUtils.isEmpty(checkFileDTO.getHashMd5()) + || ObjectUtils.isEmpty(checkFileDTO.getSize()) + || ObjectUtils.isEmpty(checkFileDTO.getSourceID())) { + return this.reUploadMap(resultMap, checkFileDTO); + } + // 参数错误 + if (!StringUtil.isNumeric(checkFileDTO.getPath())) { + return this.reUploadMap(resultMap, checkFileDTO); + } + + //验证业务类型 + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(checkFileDTO.getBusType()); + if (busTypeEnum == null) { + return this.reUploadMap(resultMap, checkFileDTO); + } + + + /** 获取企业云盘 */ + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), checkFileDTO.getSourceID()); + + fileOptionTool.checkMemory(disk, checkFileDTO.getSize()); + + CommonSource replaceSource = fileOptionTool.getSourceInfo(Long.parseLong(checkFileDTO.getPath())); + if (ObjectUtils.isEmpty(replaceSource)) { + return this.reUploadMap(resultMap, checkFileDTO); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, disk.getSourceID(), disk.getParentLevel(), "8", disk.getTargetType()); + + replaceSource.setSourceType(busTypeEnum.getTypeCode()); + + Long time = null; + if (Arrays.asList("dev", "itest").contains(environmentType) ) { + // 测试环境2023-03-14日之前的服务器文件清理过 + time = 1678723200L; + } + + CommonSource commonSource = fileOptionTool.selectByChecksum(checkFileDTO.getHashMd5(), checkFileDTO.getSize(), time); + + if (commonSource == null) { + return this.reUploadMap(resultMap, checkFileDTO); + } + Long userId = replaceSource.getUserID(); + IoSourceHistory orgHistory = ioSourceHistoryDao.getHistoryInfoByFileId(replaceSource.getSourceID(), replaceSource.getFileID()); + if (!ObjectUtils.isEmpty(orgHistory)){ + userId = orgHistory.getUserID(); + } + // 添加历史记录 sourceID, `userID`,`fileID`, `size`, `detail` + IoSourceHistory ioSourceHistory = new IoSourceHistory(); + ioSourceHistory.setSourceID(replaceSource.getSourceID()); + ioSourceHistory.setUserID(ObjectUtils.isEmpty(userId) ? loginUser.getUserID() : userId); + ioSourceHistory.setFileID(replaceSource.getFileID()); + ioSourceHistory.setSize(replaceSource.getSize()); + ioSourceHistory.setDetail(""); + + // 格式不相同 + /*if (!commonSource.getFileType().equals(replaceSource.getFileType())){ + return this.reUploadMap(resultMap, checkFileDTO); + } + + if (!commonSource.getFileType().toLowerCase().equals(replaceSource.getFileType().toLowerCase())){ + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType().toLowerCase()) && Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(replaceSource.getFileType().toLowerCase())){ + }else if (Arrays.asList("doc", "docx").contains(commonSource.getFileType().toLowerCase()) && Arrays.asList("doc", "docx").contains(replaceSource.getFileType().toLowerCase())){ + }else if (Arrays.asList("ppt", "pptx").contains(commonSource.getFileType().toLowerCase()) && Arrays.asList("ppt", "pptx").contains(replaceSource.getFileType().toLowerCase())){ + }else if (Arrays.asList("xls", "xlsx").contains(commonSource.getFileType().toLowerCase()) && Arrays.asList("xls", "xlsx").contains(replaceSource.getFileType().toLowerCase())){ + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + }*/ + + + int isM3u8 = ObjectUtils.isEmpty(commonSource.getIsM3u8()) ? 0 : commonSource.getIsM3u8(); + if ((isM3u8 <= 0 && Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()))) { + return this.reUploadMap(resultMap, checkFileDTO); + } + if (Arrays.asList("dev", "itest").contains(environmentType) && commonSource.getCreateTime() < 1678723200) { + return this.reUploadMap(resultMap, checkFileDTO); + } + String finalFilePath = commonSource.getPath(); + if (!fileExists(finalFilePath)) { + LogUtil.error("checkFile 下载文件不存在" + finalFilePath); + return this.reUploadMap(resultMap, checkFileDTO); + } + + commonSource.setUserID(loginUser.getUserID()); + UploadDTO uploadDTO = new UploadDTO(); + checkFileDTO.setIgnoreFileSize(disk.getIgnoreFileSize()); + uploadDTO.setChunk(checkFileDTO.getChunk()); + uploadDTO.setChunks(checkFileDTO.getChunks()); + + replaceSource.setGroupID(disk.getGroupID()); + replaceSource.setTargetType(disk.getTargetType()); + replaceSource.setUserID(loginUser.getUserID()); + + resultMap.put("fileExists", true); + resultMap.put("chunkList", new ArrayList<>()); + + //云盘验证 + if (busTypeEnum.equals(BusTypeEnum.CLOUD)) { + checkFileDTO.setBusTypeCode(BusTypeEnum.CLOUD.getTypeCode().toString()); + } + + + replaceSource.setFileID(commonSource.getFileID()); + replaceSource.setSize(commonSource.getSize()); + + resultMap.put("sourceID", replaceSource.getSourceID()); + resultMap.put("fileID", replaceSource.getFileID()); + resultMap.put("resolution", replaceSource.getResolution()); + resultMap.put("sourcePath", FileUtil.returnPath(commonSource.getPath(), busTypeEnum.getBusType(), commonSource.getThumb())); + resultMap.put("thumb", commonSource.getThumb()); + String previewUrl = commonSource.getPath(); + if (!StringUtil.isEmpty(previewUrl)) { + resultMap.put("sourcePath", previewUrl); + } + //第三方预览地址 + String newPreviewUrl = commonSource.getPreviewUrl(); + if (!StringUtil.isEmpty(newPreviewUrl)) { + resultMap.put("previewUrl", newPreviewUrl); + } + + // 添加历史记录 + try { + sourceHistoryUtil.changeCheckSourceHistory(new IoSourceHistory(replaceSource.getSourceID(),replaceSource.getFileID(),loginUser.getUserID(),replaceSource.getSize()), ioSourceHistory); + + } catch (Exception e) { + LogUtil.error(e, "添加历史记录失败 uploadDTO=" + JsonUtils.beanToJson(uploadDTO)); + } + + try { + fileOptionTool.editIoSourceDetail(replaceSource, loginUser.getUserID()); + } catch (Exception e) { + LogUtil.error(e, "添加历史记录失败 uploadDTO=" + JsonUtils.beanToJson(uploadDTO)); + } + + // 更新容量 + fileOptionTool.updateMemory(replaceSource); + + // 添加文档操作event + fileOptionTool.addSourceEvent(replaceSource.getSourceID(), replaceSource.getParentID(), loginUser.getUserID(), replaceSource.getName(), EventEnum.uploadNew); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", replaceSource.getSourceID()); + reMap.put("sourceParent", replaceSource.getParentID()); + reMap.put("type", "uploadNew"); + reMap.put("userID", loginUser.getUserID()); + reMap.put("pathName", replaceSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileUpload.getCode(), paramList, systemLogTool.getRequest()); + + return resultMap; + } + + @Override + public Map getFileContent(CheckFileDTO getCloudPreviewDTO) { + Map reMap = new HashMap<>(); + reMap.put("fileData", ""); + if (ObjectUtils.isEmpty(getCloudPreviewDTO.getSourceID())) { + return reMap; + } + getCloudPreviewDTO.setF(ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) ? 0L : getCloudPreviewDTO.getF()); + CommonSource cloudFile = fileOptionTool.getFileAttachment(getCloudPreviewDTO.getSourceID(), getCloudPreviewDTO.getF()); + + if (cloudFile == null || ObjectUtils.isEmpty(cloudFile.getPath())) { + return reMap; + } + /** 返回十六进制 */ + reMap.put("fileData", FileUtil.getImageContent(cloudFile.getPath())); + + return reMap; + } + + @Override + public Map getFileContentBlob(CheckFileDTO getCloudPreviewDTO) { + Map reMap = new HashMap<>(); + reMap.put("fileData", ""); + if (ObjectUtils.isEmpty(getCloudPreviewDTO.getSourceID())) { + return reMap; + } + getCloudPreviewDTO.setF(ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) ? 0L : getCloudPreviewDTO.getF()); + CommonSource cloudFile = fileOptionTool.getFileAttachment(getCloudPreviewDTO.getSourceID(), getCloudPreviewDTO.getF()); + + if (cloudFile == null || ObjectUtils.isEmpty(cloudFile.getPath())) { + return reMap; + } + /** 返回Blob */ + reMap.put("fileData", FileUtil.getImageContentBlob(cloudFile.getPath())); + + return reMap; + } + + @Override + public Map getFileContentByte(CheckFileDTO getCloudPreviewDTO) { + Map reMap = new HashMap<>(); + reMap.put("fileData", ""); + if (ObjectUtils.isEmpty(getCloudPreviewDTO.getSourceID())) { + return reMap; + } + getCloudPreviewDTO.setF(ObjectUtils.isEmpty(getCloudPreviewDTO.getF()) ? 0L : getCloudPreviewDTO.getF()); + CommonSource cloudFile = fileOptionTool.getFileAttachment(getCloudPreviewDTO.getSourceID(), getCloudPreviewDTO.getF()); + + if (cloudFile == null || ObjectUtils.isEmpty(cloudFile.getPath())) { + return reMap; + } + /** 返回Byte */ + reMap.put("fileData", FileUtil.getFileByte(cloudFile.getPath())); + + return reMap; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/UploadZipServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/UploadZipServiceImpl.java new file mode 100644 index 0000000..d5982fd --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/UploadZipServiceImpl.java @@ -0,0 +1,885 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.LogTypeEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.CompressFileDto; +import com.svnlan.home.dto.SourceOpDto; +import com.svnlan.home.dto.GetAttachmentDTO; +import com.svnlan.home.dto.UploadDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.service.ExplorerFileService; +import com.svnlan.home.service.UploadZipService; +import com.svnlan.home.utils.*; +import com.svnlan.home.utils.zip.*; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.home.vo.IOSourceVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import net.sf.sevenzipjbinding.IInArchive; +import net.sf.sevenzipjbinding.SevenZip; +import net.sf.sevenzipjbinding.SevenZipException; +import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; +import net.sf.sevenzipjbinding.simple.ISimpleInArchive; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/9 15:16 + */ +@Service +public class UploadZipServiceImpl implements UploadZipService { + @Resource + FileOptionTool fileOptionTool; + @Resource + SystemSortTool systemSortTool; + @Resource + IoSourceDao ioSourceDao; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + SystemLogTool systemLogTool; + @Resource + ExplorerFileService explorerFileService; + @Resource + BusTypeHandleService busTypeHandleService; + @Resource + AsyncUtil asyncUtil; + @Resource + StorageService storageService; + @Resource + AsyncUnZipFileUtil asyncUnZipFileUtil; + @Resource + UserAuthTool userAuthTool; + @Resource + ShareTool shareTool; + + @Override + public boolean zipFile(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getSourceID()) || checkFileDTO.getSourceID() <= 0 + || CollectionUtils.isEmpty(checkFileDTO.getDataArr())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Long sourceID = checkFileDTO.getSourceID(); + CommonSource commonSource = fileOptionTool.getSourceInfo(sourceID); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + boolean isDown = false; + if (!ObjectUtils.isEmpty(checkFileDTO.getOperation()) && "down".equals(checkFileDTO.getOperation())){ + resultMap.put("operation", "down"); + isDown = true; + } + boolean isShare = false; + // 分享 + if (!ObjectUtils.isEmpty(checkFileDTO.getShareCode())) { + isShare = true; + GetAttachmentDTO getAttachmentDTO = new GetAttachmentDTO(); + getAttachmentDTO.setShareCode(checkFileDTO.getShareCode()); + getAttachmentDTO.setD("1"); + shareTool.checkShareLink(getAttachmentDTO); + } + if (!isShare && ObjectUtils.isEmpty(loginUser)){ + throw new SvnlanRuntimeException(CodeMessageEnum.bindSignError.getCode()); + } + // 压缩权限 + String auth = "6"; + if (isDown){ + auth = "4"; + } + long userID = ObjectUtils.isEmpty(loginUser) || ObjectUtils.isEmpty(loginUser.getUserID()) ? 0 : loginUser.getUserID(); + List copyListByLevel = null; + if (!isShare && commonSource.getTargetType().intValue() == 2) { + if (!isDown) { + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), "9", commonSource.getTargetType()); + } + + // 校验被压缩的文件权限 + List sourceIDList = new ArrayList<>(); + List sourceLevelList = new ArrayList<>(); + int i = 0; + for (SourceOpDto dto : checkFileDTO.getDataArr()) { + sourceIDList.add(dto.getSourceID()); + if ("folder".equals(dto.getType())) { + sourceLevelList.add(dto.getParentLevel() + dto.getSourceID() + ","); + } + + userAuthTool.checkGroupDocAuth(loginUser, dto.getSourceID(), dto.getParentLevel(), auth, commonSource.getTargetType(), i==0 ? true : false); + i ++; + } + List otherSourceIds = null; + if (!CollectionUtils.isEmpty(sourceLevelList)) { + copyListByLevel = ioSourceDao.copySourcePathListByLevel(sourceLevelList); + if (!CollectionUtils.isEmpty(copyListByLevel)) { + otherSourceIds = copyListByLevel.stream().map(IOSourceVo::getSourceID).collect(Collectors.toList()); + userAuthTool.checkGroupDocAuthOther(loginUser, otherSourceIds, auth, commonSource.getTargetType()); + } + } + + // 校验被压缩的文件权限end + } + String suffix = ObjectUtils.isEmpty(checkFileDTO.getSuffix()) ? "zip" : checkFileDTO.getSuffix(); + if (!Arrays.asList(GlobalConfig.ZIP_SHOW_TYPE_ARR).contains(suffix)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + String uuid = RandomUtil.getuuid(); + checkFileDTO.setTaskID(ObjectUtils.isEmpty(checkFileDTO.getTaskID()) ? uuid : checkFileDTO.getTaskID()); + + if (!isDown) { + /** 获取企业云盘 */ + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(userID, checkFileDTO.getSourceID()); + // 个人空间 + if (disk.getTargetType().intValue() == 1) { + Long userSizeUse = disk.getUserSizeUse(); + // 0 为不限制容量 + if (disk.getUserSizeMax().doubleValue() > 0 && userSizeUse >= (disk.getUserSizeMax() * 1024 * 1024 * 1024)) { + throw new SvnlanRuntimeException(CodeMessageEnum.spaceIsFull.getCode()); + } + } else { + // 部门 + Long sizeUse = disk.getSizeUse(); + // 0 为不限制容量 + if (disk.getSizeMax().doubleValue() > 0 && sizeUse >= (disk.getSizeMax() * 1024 * 1024 * 1024)) { + throw new SvnlanRuntimeException(CodeMessageEnum.spaceIsFull.getCode()); + } + } + } + String fileName = ObjectUtils.isEmpty(checkFileDTO.getName()) ? commonSource.getSourceName() + "." + suffix : checkFileDTO.getName(); + + if (!fileName.endsWith("." + suffix)){ + fileName = fileName + "." + suffix; + } + // String zipSavePath = "/uploads/common/zip_task/" + FileUtil.getDatePath() + RandomUtil.getuuid() + "/"; + //基础路径+日期路径 + String finalFolderPath = storageService.getDefaultStorageDevicePath() + PropertiesUtil.getUpConfig("cloud.savePath") + FileUtil.getDatePath(); + + if (!ObjectUtils.isEmpty(checkFileDTO.getOperation()) && "down".equals(checkFileDTO.getOperation())){ + // 只下载 + finalFolderPath = finalFolderPath.replace("/private/", "/common/down_temp/"); + } + // 存放复制文件的临时文件名 + String tempFolder = uuid + System.currentTimeMillis() + "_" + userID ; + String finalFilePath = null; + if (isDown){ + // 压缩包的路径及名称 + finalFilePath = finalFolderPath + fileName; + }else { + // 压缩包的路径及名称 + finalFilePath = finalFolderPath + tempFolder + "." + suffix; + } + + checkFileDTO.setFinalFolderPath(finalFolderPath); + checkFileDTO.setCommonSource(commonSource); + checkFileDTO.setUuid(uuid); + checkFileDTO.setTempFolder(tempFolder); + checkFileDTO.setFinalFilePath(finalFilePath); + checkFileDTO.setTemp(finalFolderPath + tempFolder + "/"); + checkFileDTO.setFileName(fileName); + checkFileDTO.setUserID(userID); + checkFileDTO.setSourceID(sourceID); + checkFileDTO.setStatus(1); + checkFileDTO.setFileType(suffix); + + resultMap.put("taskID", checkFileDTO.getTaskID()); + resultMap.put("finalFilePath", finalFilePath); + resultMap.put("fileName", fileName); + resultMap.put("userID", userID); + resultMap.put("sourceID", sourceID); + resultMap.put("status", 0); + resultMap.put("temp", finalFolderPath + tempFolder + "/"); + resultMap.put("fileType", suffix); + + + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_zip_file + checkFileDTO.getTaskID(), "0", 5, TimeUnit.HOURS); + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_zip_file_info + checkFileDTO.getTaskID(), JsonUtils.beanToJson(resultMap), 5, TimeUnit.HOURS); + + /** 异步 文件压缩*/ + checkFileDTO.setLoginUser(loginUser); + checkFileDTO.setContent(JsonUtils.beanToJson(resultMap)); + + if (!isDown && !ObjectUtils.isEmpty(loginUser)) { + // 完成后操作 入库 + this.addSourceInfo(checkFileDTO, loginUser, resultMap); + } + long ms = System.currentTimeMillis(); + LogUtil.info("zipFile asyncZipFile begin " + ms); + // 压缩 + asyncUtil.asyncZipFile(checkFileDTO, copyListByLevel); + + String key = GlobalConfig.async_key_zip_file + checkFileDTO.getTaskID(); + String denyString = stringRedisTemplate.opsForValue().get(key); + if ("1".equals(denyString)) { + // 完成 + resultMap.put("status", 1); + } + if (isDown && !ObjectUtils.isEmpty(loginUser)){ + // 下载文件夹日志 + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("fileID", commonSource.getFileID()); + reMap.put("pathName", fileName); + if (!ObjectUtils.isEmpty(commonSource.getSourceID())){ + reMap.put("sourceParentLevel", commonSource.getParentLevel() + "," + commonSource.getSourceID()); + } + reMap.put("status", "1"); + reMap.put("type", "folder"); + reMap.put("fromSourceID", commonSource.getSourceID()); + reMap.put("fromName", commonSource.getSourceName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.zipDownload.getCode(), paramList, systemLogTool.getRequest()); + } + LogUtil.info("zipFile asyncZipFile end" + (System.currentTimeMillis() - ms) + " ms. " + ms); + return true; + } + + + @Override + public boolean taskAction(CheckFileDTO checkFileDTO, Map resultMap){ + if (ObjectUtils.isEmpty(checkFileDTO.getTaskID())){ + resultMap.put("status", 0); + resultMap.put("taskID", checkFileDTO.getTaskID()); + resultMap.put("zipProgress", 0); + return false; + } + resultMap.put("status", 0); + resultMap.put("taskID", checkFileDTO.getTaskID()); + String key = GlobalConfig.async_key_zip_file + checkFileDTO.getTaskID(); + String denyString = stringRedisTemplate.opsForValue().get(key); + + // 压缩进度 + String progressKey = GlobalConfig.progress_key_zip_file + checkFileDTO.getTaskID(); + String progressString = stringRedisTemplate.opsForValue().get(progressKey); + resultMap.put("zipProgress", 0); + if (!ObjectUtils.isEmpty(progressString)){ + resultMap.put("zipProgress", progressString); + } + + LogUtil.info("taskAction key=" + key +",denyString=" + denyString + ",progressString=" + progressString); + if (ObjectUtils.isEmpty(denyString)){ + resultMap.put("status", 1); + return true; + } + + if ("1".equals(denyString)) { + resultMap.put("status", 1); + resultMap.put("zipProgress", 100); + + String infoKey = GlobalConfig.async_key_zip_file_info + checkFileDTO.getTaskID(); + String info = stringRedisTemplate.opsForValue().get(infoKey); + if (ObjectUtils.isEmpty(info)){ + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + LogUtil.info("taskAction key=" + key +",info=" + info); + CheckFileDTO paramVo = JsonUtils.jsonToBean(info, CheckFileDTO.class); + if (ObjectUtils.isEmpty(checkFileDTO.getOperation())){ + if (!ObjectUtils.isEmpty(checkFileDTO.getOperation()) && "down".equals(checkFileDTO.getOperation())){ + paramVo.setOperation("down"); + } + } + if (!ObjectUtils.isEmpty(checkFileDTO.getOperation()) && "down".equals(checkFileDTO.getOperation())){ + // 只下载 + resultMap.put("taskID", paramVo.getTaskID()); + resultMap.put("finalFilePath", paramVo.getFinalFilePath()); + resultMap.put("fileName", paramVo.getFileName()); + resultMap.put("userID", paramVo.getUserID()); + resultMap.put("sourceID", paramVo.getSourceID()); + resultMap.put("temp", paramVo.getTemp()); + resultMap.put("fileType", paramVo.getFileType()); + }else { + // 入库 + //this.addSourceInfo(paramVo, loginUser, resultMap); + } + + try { + ZipUtils.deleteFile(new File(paramVo.getTemp())); + }catch (Exception e){ + LogUtil.error(e,"taskAction 删除临时文件夹失败 "); + } + + stringRedisTemplate.delete(key); + stringRedisTemplate.delete(infoKey); + stringRedisTemplate.delete(progressKey); + }else { + // 转码进度 + //获取转码进度 + /*int dotPosition = sourcePath.lastIndexOf("."); + String m3u8Path = sourcePath.substring(0, dotPosition) + ".m3u8"; + Integer progress = FileUtil.getConvertedLength(m3u8Path, videoLength, true); + reMap.put("convertProgress", progress);*/ + } + return true; + } + + private void addSourceInfo(CheckFileDTO paramVo, LoginUser loginUser, Map resultMap){ + + CommonSource commonSource = new CommonSource(); + //设置默认值 + fileOptionTool.setDefault(commonSource, loginUser); + commonSource.setSourceType(BusTypeEnum.CLOUD.getTypeCode()); + // 入库 + commonSource.setUserID(paramVo.getUserID()); + commonSource.setName(paramVo.getFileName()); + commonSource.setParentID(paramVo.getSourceID()); + commonSource.setSize(0L); + commonSource.setPath(paramVo.getFinalFilePath()); + commonSource.setFileType(paramVo.getFileType()); + + if (!ObjectUtils.isEmpty(commonSource.getParentID()) && commonSource.getParentID() > 0) { + CommonSource parentSource = fileOptionTool.getSourceInfo(commonSource.getParentID()); + if (ObjectUtils.isEmpty(parentSource)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + commonSource.setParentLevel(parentSource.getParentLevel() + commonSource.getParentID() + ","); + commonSource.setTargetType(parentSource.getTargetType()); + } else { + commonSource.setParentLevel(",0,"); + commonSource.setTargetType(1); + } + commonSource.setSize(0L); + commonSource.setHashMd5(""); + + try { + fileOptionTool.addCommonSource(loginUser.getUserID(), commonSource, EventEnum.upload); + resultMap.put("source", commonSource); + paramVo.setBusId(commonSource.getSourceID()); + paramVo.setFileID(commonSource.getFileID()); + paramVo.setTargetType(commonSource.getTargetType()); + paramVo.setParentLevel(commonSource.getParentLevel()); + } catch (Exception e) { + LogUtil.error(e, "addSourceInfo source入库失败" + JsonUtils.beanToJson(commonSource)); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + reMap.put("type", "editFile"); + reMap.put("pathName", commonSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileEdit.getCode(), paramList, systemLogTool.getRequest()); + } + + @Override + public List unZip(CheckFileDTO checkFileDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getSourceID()) || checkFileDTO.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) && ObjectUtils.isEmpty(checkFileDTO.getPathTo())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Long sourceID = checkFileDTO.getSourceID(); + CommonSource commonSource = fileOptionTool.getSourceInfo(sourceID); + if (ObjectUtils.isEmpty(commonSource)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getSourceID(), commonSource.getParentLevel(), "7", commonSource.getTargetType()); + + if (!Arrays.asList(GlobalConfig.UNZIP_SHOW_TYPE_ARR).contains(commonSource.getFileType())){ + LogUtil.error("unZip 解压缩类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + UploadDTO uploadDTO = new UploadDTO(); + /*String needMark = systemOptionDao.getSystemConfigByKey("needMark"); + uploadDTO.setHasMark((!ObjectUtils.isEmpty(needMark) && "1".equals(needMark)) ? true : false);*/ + uploadDTO.setHasMark(false); + List convertList = new ArrayList<>(); + Integer targetType = commonSource.getTargetType(); + + List sourceNameList = null; + CommonSource parentSource = null; + if (!ObjectUtils.isEmpty(checkFileDTO.getPathTo()) ){ + /* if (StringUtil.isSpecialChar(checkFileDTO.getPathTo())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + }*/ + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, commonSource.getParentID(), commonSource.getParentLevel(), "9", commonSource.getTargetType()); + parentSource = new CommonSource(); + parentSource.setName(checkFileDTO.getPathTo()); + parentSource.setParentID(commonSource.getParentID()); + parentSource.setParentLevel(commonSource.getParentLevel()); + parentSource.setTargetType(targetType); + parentSource.setFileType(""); + parentSource.setSize(0L); + fileOptionTool.addIoSourceDetail(parentSource, loginUser.getUserID(), 0L, EventEnum.mkdir); + + }else if(!ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) && checkFileDTO.getSourceIDTo() > 0){ + parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + userAuthTool.checkGroupDocAuth(loginUser, checkFileDTO.getSourceIDTo(), parentSource.getParentLevel(), "9", parentSource.getTargetType()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + targetType = parentSource.getTargetType(); + + }else { + LogUtil.error("unZip 目标目录不存在 checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO) + ",loginUser=" + JsonUtils.beanToJson(loginUser)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + String finalTopPath = storageService.getDefaultStorageDevicePath() + PropertiesUtil.getUpConfig("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath() + parentSource.getSourceID() + "/"; + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + + List fileList = new ArrayList<>(); + + + if (ObjectUtils.isEmpty(checkFileDTO.getFullName())){ + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_unzip_file + checkFileDTO.getTaskID(), "0", 1, TimeUnit.HOURS); + stringRedisTemplate.opsForValue().set(GlobalConfig.progress_key_unzip_file + checkFileDTO.getTaskID(), "0", 1, TimeUnit.HOURS); + HttpServletRequest request = HttpUtil.getRequest(); + String serverUrl = HttpUtil.getRequestRootUrl(request); + loginUser.setServerName(HttpUtil.getServerName(request)); + loginUser.setUserAgent(HttpUtil.getUA(request)); + asyncUnZipFileUtil.asyncUnZipFile(commonSource, checkFileDTO, loginUser, stringRedisTemplate, finalFolderPath, fileList + , systemLogTool,fileOptionTool, busTypeHandleService, uploadDTO, parentSource, sourceNameList, targetType, serverUrl); + + return null; + /** 解压整个文件 流程放异步进行 */ + /* CompressFileDto dto = CompressFileUtil.unzipFilePassword(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID() + , checkFileDTO.getPassword(), checkFileDTO.getTaskID(), true, stringRedisTemplate ); + if (ObjectUtils.isEmpty(dto) || !dto.getSuccess()){ + if (!ObjectUtils.isEmpty(checkFileDTO.getPassword())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.unzipErrorTips.getCode()); + } + }*/ + // CompressFileUtil.compressFileBySource(commonSource, finalFolderPath, fileList, loginUser, checkFileDTO.getPassword()); + }else { + // 解压单个文件或者文件夹 + this.compressFileByFile(commonSource, finalFolderPath, fileList, loginUser, checkFileDTO); + + } + + + LogUtil.info("unZip parentSource=" + JsonUtils.beanToJson(parentSource)); + LogUtil.info("unZip fileList=" + JsonUtils.beanToJson(fileList)); + + // 返回前端 + List sourceIds = new ArrayList<>(); + if (!ObjectUtils.isEmpty(parentSource) && !CollectionUtils.isEmpty(fileList)){ + List sourceFileVos = new ArrayList<>(); + List sourceDirVos = new ArrayList<>(); + for (ChangeSourceVo entry: fileList) { + if (entry.getIsFolder().intValue() == 1){ + if (entry.getFilePath().indexOf("//") >= 0){ + entry.setFilePath(entry.getFilePath().replaceAll("//","/")); + } + sourceDirVos.add(entry); + }else { + sourceFileVos.add(entry); + } + } + + Map parentMap = new HashMap<>(1); + parentMap.put(finalFolderPath, parentSource); + // 文件夹 + if (!CollectionUtils.isEmpty(sourceDirVos)){ + //finalFolderPath + sourceDirVos = sourceDirVos.stream().sorted(Comparator.comparing(ChangeSourceVo::getPathLength)).collect(Collectors.toList()); + for (ChangeSourceVo changeVo : sourceDirVos){ + String parentPath = changeVo.getFilePath().substring(0, changeVo.getFilePath().indexOf(changeVo.getName())); + if (parentMap.containsKey(parentPath)) { + CommonSource pSource = parentMap.get(parentPath); + CommonSource dir = new CommonSource(); + if (parentPath.equals(finalFolderPath)) { + dir.setName(fileOptionTool.checkRepeatName(changeVo.getName(), changeVo.getName(), sourceNameList, 1)); + }else { + dir.setName(changeVo.getName()); + } + dir.setParentID(pSource.getSourceID()); + dir.setParentLevel(pSource.getParentLevel() + pSource.getSourceID() + ","); + dir.setTargetType(targetType); + dir.setFileType(""); + dir.setSize(0L); + fileOptionTool.addIoSourceDetail(dir, loginUser.getUserID(), 0L, EventEnum.mkdir); + if (parentPath.equals(finalFolderPath)){ + sourceIds.add(dir.getSourceID()); + } + parentMap.put(changeVo.getFilePath(), dir); + } + } + } + + LogUtil.info("unZip parentMap=" + JsonUtils.beanToJson(parentMap)); + LogUtil.info("unZip sourceDirVos=" + JsonUtils.beanToJson(sourceDirVos)); + LogUtil.info("unZip sourceFileVos=" + JsonUtils.beanToJson(sourceFileVos)); + + // 文件 + if (!CollectionUtils.isEmpty(sourceFileVos)){ + + Map sourceSizeMap = new HashMap<>(); + + List pIdSizeList = null; + + for (ChangeSourceVo changeVo : sourceFileVos){ + String parentPath ; + if (changeVo.getFilePath().equals(changeVo.getName())){ + parentPath = finalFolderPath; + }else { + parentPath = finalFolderPath + changeVo.getFilePath().substring(0, changeVo.getFilePath().indexOf(changeVo.getName())); + } + LogUtil.info("unZip check=" + parentMap.containsKey(parentPath) + " parentPath=" + parentPath); + if (parentMap.containsKey(parentPath)) { + CommonSource pSource = parentMap.get(parentPath); + CommonSource fileSource = new CommonSource(); + if (parentPath.equals(finalFolderPath)) { + fileSource.setName(fileOptionTool.checkRepeatName(changeVo.getName(), changeVo.getName(), changeVo.getFileType(), sourceNameList, 1)); + }else { + fileSource.setName(changeVo.getName()); + } + fileSource.setParentID(pSource.getSourceID()); + fileSource.setParentLevel(pSource.getParentLevel() + pSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(changeVo.getFileType()); + fileSource.setSize(changeVo.getSize()); + fileSource.setHashMd5(changeVo.getHashMd5()); + fileSource.setPath(changeVo.getPath()); + + /*pIdSizeList = Arrays.asList(fileSource.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + for (Long pId : pIdSizeList) { + if (sourceSizeMap.containsKey(pId)) { + sourceSizeMap.put(pId, sourceSizeMap.get(pId) + fileSource.getSize()); + } else { + sourceSizeMap.put(pId, fileSource.getSize()); + } + }*/ + + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + if (parentPath.equals(finalFolderPath)){ + sourceIds.add(fileSource.getSourceID()); + } + + if (!ObjectUtils.isEmpty(checkFileDTO.getFullName())) { + fileSource.setNeedHashMd5(1); + } + LogUtil.info("unZip fileSource=" + JsonUtils.beanToJson(fileSource)); + if (Arrays.asList(GlobalConfig.VIDEO_AUDIO_TYPE_CONVERT).contains(changeVo.getFileType())){ + // 转码、图片加缩略图 + convertList.add(fileSource); + }else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(changeVo.getFileType())){ + // "cloud" + fileSource.setSourceType(2); + busTypeHandleService.doForImage(uploadDTO, false, fileSource); + if (!ObjectUtils.isEmpty(checkFileDTO.getFullName())) { + convertList.add(fileSource); + } + } else { + if (!ObjectUtils.isEmpty(checkFileDTO.getFullName())) { + convertList.add(fileSource); + } + } + } + } + /*if (!ObjectUtils.isEmpty(sourceSizeMap)){ + List sourceList = new ArrayList<>(); + IOSource vo = null; + for (Map.Entry entry : sourceSizeMap.entrySet()) { + if (!ObjectUtils.isEmpty(entry.getKey())){ + vo = new IOSource(entry.getKey(), entry.getValue()); + sourceList.add(vo); + } + } + try { + if (!CollectionUtils.isEmpty(sourceList)) { + LogUtil.info("解压缩 batchUpdateSourceMemoryList sourceSizeMap=" + JsonUtils.beanToJson(sourceSizeMap)); + ioSourceDao.batchUpdateSourceMemoryList(sourceList); + } + }catch (Exception e){ + LogUtil.error(e,"解压缩 error batchUpdateSourceMemoryList sourceSizeMap=" + JsonUtils.beanToJson(sourceSizeMap)); + } + }*/ + } + } + + checkFileDTO.setSourceIds(sourceIds); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + reMap.put("type", "upload"); + reMap.put("pathName", commonSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileUpload.getCode(), paramList, systemLogTool.getRequest()); + return convertList; + } + + /** 解压单个文件或者文件夹 */ + public void compressFileByFile(CommonSource commonSource, String finalFolderPath, List fileList, LoginUser loginUser, CheckFileDTO checkFileDTO){ + String compressKey = GlobalConfig.FILE_PREVIEW_COMPRESS_KEY + commonSource.getPath(); + String value = stringRedisTemplate.opsForValue().get(compressKey); + LogUtil.info("compressFileByFile compressKey=" + compressKey + " ,value=" + value); + CompressFileReader.FileNode fileNode = null; + if (!ObjectUtils.isEmpty(value)){ + try { + fileNode = JsonUtils.jsonToBean(value, CompressFileReader.FileNode.class); + }catch (Exception e){ + LogUtil.error(e, "unzipList error value=" + value); + } + } + if (ObjectUtils.isEmpty(fileNode)){ + fileNode = explorerFileService.getFileNode(commonSource, compressKey, fileNode); + } + if (ObjectUtils.isEmpty(fileNode) || CollectionUtils.isEmpty(fileNode.getChildList())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (fileNode.getEncrypted() && ObjectUtils.isEmpty(checkFileDTO.getPassword())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + } + String extractPath = commonSource.getPath().substring(0, commonSource.getPath().lastIndexOf(".") ) + GlobalConfig.separatorTO; + String firstPath = FileUtil.getFirstStorageDevicePath(commonSource.getPath()); + extractPath = extractPath.replace(firstPath + "/private", firstPath + "/common/down_temp"); + int i = 0; + CompressFileDto dto = null; + + RandomAccessFile randomAccessFile = null; + IInArchive inArchive = null; + try { + randomAccessFile = new RandomAccessFile(commonSource.getPath(), "r"); + if (!ObjectUtils.isEmpty(checkFileDTO.getPassword()) && checkFileDTO.getPassword().length() > 0) { + inArchive = SevenZip.openInArchive(null, + new RandomAccessFileInStream(randomAccessFile), checkFileDTO.getPassword()); + }else { + inArchive = SevenZip.openInArchive(null, + new RandomAccessFileInStream(randomAccessFile)); + } + ISimpleInArchive iSimpleInArchive = inArchive.getSimpleInterface(); + + //验证后缀 + String suffix = FileUtil.getFileExtension(checkFileDTO.getFullName()); + boolean directory = false; + if (StringUtil.isEmpty(suffix)){ + // 文件夹 + directory = true; + } else { + Pattern pattern = Pattern.compile("[^a-zA-Z0-9]", Pattern.CASE_INSENSITIVE); + // 文件名不符合规范, 请修改 + if (pattern.matcher(suffix).find()){ + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + } + + // 解压单个文件 + dto = new CompressFileDto(); + dto.setSuccess(false); + dto.setStatus(0); + // 解压文件夹 + this.compressFileCopy(fileNode.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO, extractPath, i, iSimpleInArchive, dto); + + LogUtil.info("fileList=" + JsonUtils.beanToJson(fileList)); + } catch (Exception e) { + e.printStackTrace(); + LogUtil.error(e, " getSimpleInArchiveByPath Exception : " + e); + } finally { + if (inArchive != null) { + try { + inArchive.close(); + } catch (SevenZipException e) { + LogUtil.error(e, "Error closing archive: " + e); + e.printStackTrace(); + } + } + if (randomAccessFile != null) { + try { + randomAccessFile.close(); + } catch (IOException e) { + LogUtil.error(e, "Error closing file " ); + e.printStackTrace(); + } + } + } + + if (ObjectUtils.isEmpty(dto) || !dto.getSuccess()){ + if (!ObjectUtils.isEmpty(checkFileDTO.getPassword())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.unzipErrorTips.getCode()); + } + } + + } + + private void compressFileCopy(List fileNodeList, String finalFolderPath, List fileList, LoginUser loginUser, CheckFileDTO checkFileDTO + , String extractPath, int i, ISimpleInArchive iSimpleInArchive, CompressFileDto dto){ + if (!CollectionUtils.isEmpty(fileList)){ + return; + } + fileNodeList = fileNodeList.stream().sorted(Comparator.comparing(CompressFileReader.FileNode::isDirectory)).collect(Collectors.toList()); + + for (CompressFileReader.FileNode node : fileNodeList){ + i ++; + LogUtil.info(checkFileDTO.getFullName() + "-----compressFileCopy-------" + node.getFileName()); + if (checkFileDTO.getFullName().equals(node.getFileName())){ + if (node.isDirectory()){ + fileList.add(new ChangeSourceVo(node.getOriginName().endsWith("/") ? node.getOriginName().substring(0,node.getOriginName().length() -1) : node.getOriginName(), + 1, finalFolderPath + node.getFullName() + "/")); + this.compressFileCopyChangeList(node.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO, extractPath, i, iSimpleInArchive, dto); + return; + }else { + String suffix = FileUtil.getFileExtension(node.getOriginName()); + String finalFilePath = finalFolderPath + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + loginUser.getUserID()+ "." + suffix; + + // 单个解压 + CompressFileDto dto1 = CompressFileUtil.unzipOneFilePassword(iSimpleInArchive, finalFilePath, checkFileDTO.getPassword(), node.getIndex()); + + + fileList.add(new ChangeSourceVo(node.getOriginName(), 0, suffix + , finalFilePath , node.getOriginName() + , node.getSize(), "")); + + dto.setStatus(dto1.getStatus()); + dto.setSuccess(dto1.getSuccess()); + dto.setResult(dto1.getResult()); + + LogUtil.info("compressFileCopy dto=" + JsonUtils.beanToJson(dto)); + /*File linkFile = new File(finalFilePath); + try {//创建硬链 + if (!linkFile.exists()){ + Files.createLink(Paths.get(finalFilePath), Paths.get(extractPath + node.getFileName())); + fileList.add(new ChangeSourceVo(node.getOriginName(), 0, suffix + , finalFilePath , node.getFullName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO) + , node.getSize(), "")); + } + } catch (FileAlreadyExistsException e){//文件已存在, 忽略 + LogUtil.error(e, "compressFileCopy 创建硬链接失败 finalFilePath=" + finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + } catch (Exception e){ + LogUtil.error(e, "compressFileCopy error 创建硬链接失败 finalFilePath="+ finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + }*/ + return; + } + }else if (!CollectionUtils.isEmpty(node.getChildList())){ + compressFileCopy(node.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO + , extractPath, i, iSimpleInArchive, dto); + } + } + } + + + private void compressFileCopyChangeList(List fileNodeList, String finalFolderPath, List fileList, LoginUser loginUser, CheckFileDTO checkFileDTO + , String extractPath, int i, ISimpleInArchive iSimpleInArchive, CompressFileDto dto){ + fileNodeList = fileNodeList.stream().sorted(Comparator.comparing(CompressFileReader.FileNode::isDirectory)).collect(Collectors.toList()); + + for (CompressFileReader.FileNode node : fileNodeList) { + if (node.isDirectory()) { + fileList.add(new ChangeSourceVo(node.getOriginName().endsWith("/") ? node.getOriginName().substring(0, node.getOriginName().length() - 1) : node.getOriginName(), + 1, finalFolderPath + node.getFullName() + "/")); + if (!CollectionUtils.isEmpty(node.getChildList())) { + compressFileCopyChangeList(node.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO + , extractPath, i, iSimpleInArchive, dto); + } + } else { + String suffix = FileUtil.getFileExtension(node.getOriginName()); + String finalFilePath = finalFolderPath + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + loginUser.getUserID() + "." + suffix; + + fileList.add(new ChangeSourceVo(node.getOriginName(), 0, suffix + , finalFilePath, node.getFullName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO) + , node.getSize(), "")); + // 单个解压 + CompressFileDto dto1 = CompressFileUtil.unzipOneFilePassword(iSimpleInArchive, finalFilePath, checkFileDTO.getPassword(), node.getIndex()); + + dto.setStatus(dto1.getStatus()); + dto.setSuccess(dto1.getSuccess()); + dto.setResult(dto1.getResult()); + LogUtil.info("compressFileCopyChangeList dto=" + JsonUtils.beanToJson(dto)); + + /*File linkFile = new File(finalFilePath); + try {//创建硬链 + if (!linkFile.exists()) { + Files.createLink(Paths.get(finalFilePath), Paths.get(extractPath + node.getFileName())); + fileList.add(new ChangeSourceVo(node.getOriginName(), 0, suffix + , finalFilePath, node.getFullName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO) + , node.getSize(), "")); + } + } catch (FileAlreadyExistsException e) {//文件已存在, 忽略 + LogUtil.error(e, "compressFileCopy 创建硬链接失败 finalFilePath=" + finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + } catch (Exception e) { + LogUtil.error(e, "compressFileCopy error 创建硬链接失败 finalFilePath" + finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + + }*/ + } + } + } + + @Override + public boolean taskActionUnZip(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getTaskID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + resultMap.put("status", 0); + resultMap.put("taskID", checkFileDTO.getTaskID()); + String key = GlobalConfig.async_key_unzip_file + checkFileDTO.getTaskID(); + String denyString = stringRedisTemplate.opsForValue().get(key); + // 进度 + String progressKey = GlobalConfig.progress_key_unzip_file + checkFileDTO.getTaskID(); + String progressString = stringRedisTemplate.opsForValue().get(progressKey); + resultMap.put("progress", 0); + resultMap.put("zipProgress", 0); + if (!ObjectUtils.isEmpty(progressString)){ + resultMap.put("progress", progressString); + resultMap.put("zipProgress", progressString); + } + LogUtil.info("taskActionUnZip key=" + key +",denyString=" + denyString + ",progressString=" + progressString); + if (ObjectUtils.isEmpty(denyString)){ + resultMap.put("status", 1); + resultMap.put("progress", 100); + resultMap.put("zipProgress", 100); + return true; + } + if ("1".equals(denyString)) { + resultMap.put("status", 1); + resultMap.put("progress", 100); + resultMap.put("zipProgress", 100); + stringRedisTemplate.delete(key); + stringRedisTemplate.delete(progressKey); + } + return true; + } +} + + diff --git a/src/main/java/com/svnlan/home/service/impl/VideoGetServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/VideoGetServiceImpl.java new file mode 100644 index 0000000..67b1df1 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/VideoGetServiceImpl.java @@ -0,0 +1,1154 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.home.dto.VideoCutDto; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.service.VideoGetService; +import com.svnlan.home.utils.*; +import com.svnlan.home.utils.video.VideoGetUtil; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.Future; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/17 11:29 + */ +@Service +public class VideoGetServiceImpl implements VideoGetService { + + @Resource + AsyncUtil asyncUtil; + @Resource + FileOptionTool fileOptionTool; + @Resource + IoSourceDao ioSourceDao; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + StorageService storageService; + + @Resource + AsyncCutImgUtil asyncCutImgUtil; + @Resource + BusTypeHandleService busTypeHandleService; + + @Value("${cdn.domain}") + private String cdnDomain; + @Resource(name = "threadPoolDefault") + private ThreadPoolTaskExecutor executor; + + public String getOrgPath(String url, String fileName){ + if (url.indexOf(GlobalConfig.private_replace_key) >= 0){ + return url.replace(GlobalConfig.private_replace_key, "/private/") + fileName; + }else { + return GlobalConfig.default_disk_path_pre + "/private" + url + fileName; + } + } + + @Override + public List getVideoShearListAll(VideoCommonDto videoCommonDto){ + if (ObjectUtils.isEmpty(videoCommonDto.getpUrl()) || ObjectUtils.isEmpty(videoCommonDto.getFileName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // length 单位:秒 + if (ObjectUtils.isEmpty(videoCommonDto.getLength()) || videoCommonDto.getLength() <= 0 || ObjectUtils.isEmpty(videoCommonDto.getNum())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List list = new ArrayList(); + + videoCommonDto.setTaskID(ObjectUtils.isEmpty(videoCommonDto.getTaskID()) ? RandomUtil.getuuid() : videoCommonDto.getTaskID()); + + String videoPathOrg = getOrgPath(videoCommonDto.getpUrl(), videoCommonDto.getFileName()); + + LogUtil.info("getVideoShearListAll videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String nameDir = videoPathOrg.substring(videoPathOrg.lastIndexOf("/") + 1); + String tempPath = videoPathOrg.substring(0,videoPathOrg.lastIndexOf(".") ) + "/" ; + + String firstPath = FileUtil.getFirstStorageDevicePath(videoPathOrg); + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + + String tempPathFinish = tempPath.replace(firstPath + "/private/", defaultFirstPath + "/common/down_temp/") ; + File destinationFolder = new File(tempPathFinish); + if (!destinationFolder.exists()) { + destinationFolder.mkdirs(); + } + + + String firstCutPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_first_1.jpg"; + File firstCutFile = new File(firstCutPath); + boolean isExist = false; + if (firstCutFile.exists()) { + // 已存在截图文件 + isExist = true; + } + Boolean first = (!ObjectUtils.isEmpty(videoCommonDto.getIsFirst()) && 1 == videoCommonDto.getIsFirst()) ? true : false; + + if (!first){ + return getVideoShearList(videoCommonDto); + } + + + // covPicBatch(String tempVideoPath, String tempImgPath, String beginN) + // 毫秒 + Long lengthTime = videoCommonDto.getLength() * 1000; + int num = videoCommonDto.getNum(); + Long eachTime = lengthTime / num; + LogUtil.info("getVideoShearListAll lengthTime=" + lengthTime + ",eachTime=" + eachTime); + + //使用Future方式执行多任务 + //生成一个集合 + List futures = new ArrayList<>(); + + if (first){ + + // 按分取 + LogUtil.info("getVideoShearListAll tempPathFinish=" + tempPathFinish ); + for (int i = 0 ; i < num; i++){ + // 从视频中截取多张图片 + String tempImgPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_first_" + (i+1) + ".jpg"; + if (!isExist) { + LogUtil.info("cutList tempImgPath=" + tempImgPath + ", beginTime=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + long timeParam = eachTime * i; + Future future = executor.submit(() -> { + String beginN = DateDUtil.msecToTime(timeParam); + Boolean check = VideoGetUtil.covPicBatch(videoPathOrg, tempImgPath, beginN); + }); + LogUtil.info("cutList tempImgPath=" + tempImgPath + ", endTime=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + futures.add(future); + } + list.add(tempImgPath); + } + + if (!CollectionUtils.isEmpty(futures)){ + try { + //查询任务执行的结果 + for (Future future : futures) { + while (true) {//CPU高速轮询:每个future都并发轮循,判断完成状态然后获取结果,这一行,是本实现方案的精髓所在。即有10个future在高速轮询,完成一个future的获取结果,就关闭一个轮询 + if (future.isDone() && !future.isCancelled()) {//获取future成功完成状态,如果想要限制每个任务的超时时间,取消本行的状态判断+future.get(1000*1, TimeUnit.MILLISECONDS)+catch超时异常使用即可。 + + LogUtil.info("getVideoShearListAll 任务i=" + future.get() + "获取完成!" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS)); + break;//当前future获取结果完毕,跳出while + } else { + Thread.sleep(1);//每次轮询休息1毫秒(CPU纳秒级),避免CPU高速轮循耗空CPU + } + } + } + }catch (Exception e){ + LogUtil.error(e, "getVideoShearListAll error "); + } + } + } + + //路径缓存, 供定时任务删除使用 + stringRedisTemplate.opsForZSet().add(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, + tempPathFinish, System.currentTimeMillis() + 86400000); + asyncCutImgUtil.AsyncExecVideoShearList(videoCommonDto); + + + String downloadKey = FileUtil.getVideoImgDownloadKey(tempPathFinish); + List vList = new ArrayList<>(); + for (String path : list){ + String name = path.substring(path.lastIndexOf("/") + 1); + vList.add("/api/disk/video/img/"+name+"?key=" + downloadKey); + } + return vList; + } + + @Override + public String getVideoShearImg(HttpServletResponse response, VideoCommonDto videoCommonDto, String passedFileName, Map resultMap){ + + if (ObjectUtils.isEmpty(passedFileName) || ObjectUtils.isEmpty(videoCommonDto.getKey())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String tempPathFinish = fileOptionTool.getAttachmentToken3(videoCommonDto.getKey()); + String videoPathOrg = ""; + if (!ObjectUtils.isEmpty(videoCommonDto.getShowPreview()) && 1 == videoCommonDto.getShowPreview()){ + videoPathOrg = tempPathFinish ; + }else if (!ObjectUtils.isEmpty(videoCommonDto.getFileName())){ + videoPathOrg = tempPathFinish + videoCommonDto.getFileName(); + }else { + videoPathOrg = tempPathFinish + passedFileName; + } + String firstPath = FileUtil.getFirstStorageDevicePath(videoPathOrg); + File file = null; + if (!ObjectUtils.isEmpty(videoCommonDto.getNameSuffix()) && videoPathOrg.indexOf(firstPath + "/private/cloud") >= 0){ + String suffix = videoPathOrg.substring(videoPathOrg.lastIndexOf(".") + 1); + String videoPathOrgThumb = videoPathOrg.replace("." + suffix, "!" + videoCommonDto.getNameSuffix() + "." + suffix) + .replace(firstPath + "/private/cloud", firstPath + "/common/cloud"); + + file = new File(videoPathOrgThumb); + if (!file.exists()){ + LogUtil.info("getVideoShearImg img is no exists videoPathOrgThumb=" + videoPathOrgThumb); + file = new File(videoPathOrg); + }else { + videoPathOrg = videoPathOrgThumb; + LogUtil.info("getVideoShearImg img is exists videoPathOrgThumb=" + videoPathOrgThumb + ", videoPathOrg=" + videoPathOrg + ", fileSize=" + file.length()); + } + }else { + file = new File(videoPathOrg); + } + + if (!file.exists()){ + LogUtil.error("getVideoShearImg videoPathOrg=" + videoPathOrg); + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String cdnPath = ""; + if (ObjectUtils.isEmpty(cdnDomain)) { + cdnPath = HttpUtil.getRequestRootUrl(null) + videoPathOrg; + } else { + cdnPath = "//" + cdnDomain + videoPathOrg; + } + resultMap.put("filePath", cdnPath); + resultMap.put("fileSize", file.length()); + resultMap.put("videoPathOrg", videoPathOrg); + + return videoPathOrg; + } + + @Override + public boolean checkImgCut(VideoCommonDto videoCommonDto){ + if (ObjectUtils.isEmpty(videoCommonDto.getpUrl()) || ObjectUtils.isEmpty(videoCommonDto.getFileName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // l + String videoPathOrg = getOrgPath(videoCommonDto.getpUrl(), videoCommonDto.getFileName()); + + LogUtil.info("checkImgCut videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + String firstPath = FileUtil.getFirstStorageDevicePath(videoPathOrg); + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + + String tempPath = videoPathOrg.substring(0,videoPathOrg.lastIndexOf(".") ) + "/" ; + String tempPathFinish = tempPath.replace(firstPath + "/private/", defaultFirstPath + "/common/down_temp/") ; + File destinationFolder = new File(tempPathFinish); + if (!destinationFolder.exists()) { + return false; + } + + + if (!ObjectUtils.isEmpty(videoCommonDto.getCheckName())){ + String firstCutPath = tempPathFinish + videoCommonDto.getCheckName(); + File firstCutFile = new File(firstCutPath); + boolean isExist = false; + if (firstCutFile.exists()) { + // 已存在截图文件 + isExist = true; + } + return isExist; + } + + String nameDir = videoPathOrg.substring(videoPathOrg.lastIndexOf("/") + 1); + Long lengthTime = videoCommonDto.getLength() * 1000; + + // 一次切两分钟 + long eachTime = 120 * 1000; + long num; + num = lengthTime / eachTime; + if (lengthTime % eachTime != 0){ + num ++; + } + + String endPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_frame_" + num + "_1.jpg"; + File endPathFile = new File(endPath); + if (endPathFile.exists()) { + // 已存在截图文件 + return true; + } + + endPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_frame_" + num + "_01.jpg"; + endPathFile = new File(endPath); + if (endPathFile.exists()) { + // 已存在截图文件 + return true; + } + return false; + } + + @Override + public List getVideoShearList(VideoCommonDto videoCommonDto){ + + if (ObjectUtils.isEmpty(videoCommonDto.getpUrl()) || ObjectUtils.isEmpty(videoCommonDto.getFileName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(videoCommonDto.getLength()) || videoCommonDto.getLength() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List list = new ArrayList(); + + videoCommonDto.setTaskID(ObjectUtils.isEmpty(videoCommonDto.getTaskID()) ? RandomUtil.getuuid() : videoCommonDto.getTaskID()); + + String videoPathOrg = getOrgPath(videoCommonDto.getpUrl(), videoCommonDto.getFileName()) ; + + LogUtil.info("getVideoShearList videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String nameDir = videoPathOrg.substring(videoPathOrg.lastIndexOf("/") + 1); + String tempPath = videoPathOrg.substring(0,videoPathOrg.lastIndexOf(".") ) + "/" ; + + String firstPath = FileUtil.getFirstStorageDevicePath(videoPathOrg); + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + // taskID 防止多人剪辑的情况 + String tempTaskPath = tempPath.replace(firstPath + "/private/", defaultFirstPath + "/common/down_temp/") + + this.getTaskIDUrl(videoCommonDto.getTaskID()) ; + + + + /** 防止每次取图被覆盖,用时间类型加时间作为文件夹*/ + String tempPathFinish = tempTaskPath + this.getTimeTypePath(videoCommonDto); + File destinationFolder = new File(tempPathFinish); + if (!destinationFolder.exists()) { + destinationFolder.mkdirs(); + } + // 从视频中截取多张图片 + String tempImgPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_%02d.jpg"; + + Double begin = videoCommonDto.getBeginTime(); + Double end = videoCommonDto.getEndTime(); + if (ObjectUtils.isEmpty(begin) || begin < 0){ + begin = 0.0; + } + if (ObjectUtils.isEmpty(end) || end < begin){ + end = begin + 1; + } + + // ffmpeg 默认 24 帧 + int frame = ObjectUtils.isEmpty(videoCommonDto.getFrame()) ? 24 : videoCommonDto.getFrame(); + + // 间隔多少取图 + int frameInterval = 1; + + Integer beginN = 0; + Integer endN = 1; + + // /** 1 分 2 秒 3 帧 */ + if ("1".equals(videoCommonDto.getTimeType())){ + frameInterval = frame * 60; + beginN = (int)Math.ceil(begin * frameInterval); + endN = (int)Math.ceil(end * frameInterval); + }else if("3".equals(videoCommonDto.getTimeType())){ + beginN = begin.intValue(); + endN = end.intValue(); + }else { + frameInterval = frame; + beginN = (int)Math.ceil(begin * frameInterval); + endN = (int)Math.ceil(end * frameInterval); + } + + LogUtil.info("getVideoShearList tempImgPath=" + tempImgPath ); + Boolean check = VideoGetUtil.covPicBatch( videoPathOrg, tempImgPath, beginN, endN, frameInterval); + + if (!check){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + + int num = 1; + if (endN > beginN) { + double n = (endN - beginN); + num = (int) Math.ceil(n / frameInterval); + } + LogUtil.info("getVideoShearList num=" + num + ",beginN=" + beginN + ",endN=" + endN+ ",frameInterval=" + frameInterval); + for (int i = 1; i <= num ; i ++){ + list.add(String.format(tempImgPath, i)); + } + + //路径缓存, 供定时任务删除使用 + stringRedisTemplate.opsForZSet().add(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, + tempPathFinish, System.currentTimeMillis() + 86400000); + + // 异步删除文件或者文件夹 已解析在cutVideo中 + //stringRedisTemplate.opsForValue().set(GlobalConfig.video_edit_getVideoShearList + videoCommonDto.getTaskID(), tempPathFinish, 5, TimeUnit.HOURS); + + return list; + } + + private String getTimeTypePath(VideoCommonDto videoCommonDto){ + return videoCommonDto.getTimeType() + "_" + videoCommonDto.getBeginTime() + "_" + videoCommonDto.getEndTime() + "/"; + } + + /** + * 视频剪辑 (剪切、拆分)(拆分的转码放controller,剪切的转码放这个方法内因需要合并视频) + * @param videoCommonDto + * @param loginUser + * @return + */ + @Override + public Map cutVideo(VideoCommonDto videoCommonDto, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(videoCommonDto.getpUrl()) || ObjectUtils.isEmpty(videoCommonDto.getFileName()) + || ObjectUtils.isEmpty(videoCommonDto.getTaskID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (CollectionUtils.isEmpty(videoCommonDto.getCutList())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + /** 1 剪切 2 拆分 */ + if (!Arrays.asList("1","2").contains(videoCommonDto.getCutType())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + // 原始文件路径 + String videoPathOrg = getOrgPath(videoCommonDto.getpUrl(), videoCommonDto.getFileName()); + + LogUtil.info("cutVideo videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + Map reMap = new HashMap<>(1); + String suffix = videoPathOrg.substring(videoPathOrg.lastIndexOf(".") + 1 ); + videoCommonDto.setSuffix(suffix); + + //最终文件目录路径 + String finalTopPath = defaultFirstPath + PropertiesUtil.getUpConfig("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + suffix; + + + // 从视频中剪切 + List cutList = null; + if (videoCommonDto.getCutList().size() > 1){ + + String nameDir = videoPathOrg.substring(videoPathOrg.lastIndexOf("/") + 1); + String tempPath = videoPathOrg.substring(0,videoPathOrg.lastIndexOf(".") ) + "/" ; + String tempPathFinish = ""; + String tempCutPath = null; + /** 1 剪切 2 拆分 */ + if ("1".equals(videoCommonDto.getCutType())){ + // taskID 防止多人剪辑的情况 + + String firstPath = FileUtil.getFirstStorageDevicePath(videoPathOrg); + tempPathFinish = tempPath.replace(firstPath + "/private/", defaultFirstPath +"/common/down_temp/") + this.getTaskIDUrl(videoCommonDto.getTaskID()) ; + File destinationFolder = new File(tempPathFinish); + if (!destinationFolder.exists()) { + destinationFolder.mkdirs(); + } + //路径缓存, 供定时任务删除使用 + /*stringRedisTemplate.opsForZSet().add(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, + tempPathFinish, System.currentTimeMillis() + 86400000);*/ + + tempCutPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_%02d." + suffix; + + reMap.put("tempDirPath", tempPathFinish); + reMap.put("cutPath", finalFilePath); + }else { + tempCutPath = finalFilePath.replace("." + suffix, "")+"_%02d." + suffix; + reMap.put("cutPath", tempCutPath); + } + List cutListParam = videoCommonDto.getCutList(); + LogUtil.info("cutVideo suffix=" + suffix + " tempImgPath=" + tempCutPath ); + cutList = VideoGetUtil.covCutBatch(videoPathOrg, tempCutPath, cutListParam, videoCommonDto, executor); + reMap.put("cutDtoList", cutListParam); + + // 剪切多视频需要合并 根据tempPathFinish判断是否需要合并 + if (!CollectionUtils.isEmpty(cutList) && !ObjectUtils.isEmpty(tempPathFinish)) { + asyncUtil.cutVideoMerge(cutList, finalFilePath, suffix, tempPathFinish, videoCommonDto.getConvertList(), videoCommonDto.getOtherType() + ,fileOptionTool, loginUser.getUserID()); + } + + }else { + List cutListParam = videoCommonDto.getCutList(); + reMap.put("cutPath", finalFilePath); + // 只有一个 + cutList = VideoGetUtil.covCutBatch(videoPathOrg, finalFilePath, cutListParam, videoCommonDto, executor); + reMap.put("cutDtoList", cutListParam); + } + reMap.put("cutList", cutList); + reMap.put("success", CollectionUtils.isEmpty(cutList) ? false : true); + reMap.put("cutType", videoCommonDto.getCutType()); + + if ("1".equals(videoCommonDto.getCutType())){ + LogUtil.info("cutVideo cutVideoSave reMap=" + JsonUtils.beanToJson(reMap)); + }else { + LogUtil.info("cutVideo splitVideoSave reMap=" + JsonUtils.beanToJson(reMap)); + } + return reMap; + } + + @Override + public Map cutVideoSave(VideoCommonDto checkFileDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getName()) || ObjectUtils.isEmpty(checkFileDTO.getFileName()) + || ObjectUtils.isEmpty(checkFileDTO.getpUrl())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (CollectionUtils.isEmpty(checkFileDTO.getCutList())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + for (VideoCutDto dto : checkFileDTO.getCutList()){ + if (ObjectUtils.isEmpty(dto.getBeginTime()) || ObjectUtils.isEmpty(dto.getDuration())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + } + String serverUrl = HttpUtil.getRequestRootUrl(null); + int size = checkFileDTO.getCutList().size(); + String fileType = checkFileDTO.getFileName().substring(checkFileDTO.getFileName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("cutVideoSave 视频编辑类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + String fileName = checkFileDTO.getName(); + /** 操作剪辑 */ + checkFileDTO.setCutType("1"); + + + checkFileDTO.setOtherType("cutVideo"); + + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(fileName, fileName, fileType, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(fileType); + fileSource.setSize(0L); + fileSource.setHashMd5(""); + fileSource.setPath(""); + fileSource.setDomain(serverUrl); + // 需要获取md5并修改 + fileSource.setNeedHashMd5(1); + List convertList = new ArrayList<>(); + + if (size > 1) { + convertList.add(fileSource); + checkFileDTO.setConvertList(convertList); + } + Map cutMap = this.cutVideo(checkFileDTO, loginUser); + if (ObjectUtils.isEmpty(cutMap)){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + if (!cutMap.containsKey("success") || "false".equals(cutMap.get("success").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + if (size > 1){ + return cutMap; + } + + if (cutMap.containsKey("cutPath")) { + String cutPath = cutMap.get("cutPath").toString(); + fileSource.setPath(cutPath); + try { + File f = new File(cutPath); + if (f.exists()){ + fileSource.setSize(f.length()); + } + }catch (Exception e){ + + } + } + + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + // 需要获取md5并修改 + fileSource.setNeedHashMd5(1); + convertList.add(fileSource); + cutMap.put("convertList", convertList); + // 修改file的path + + return cutMap; + } + + @Override + public Map splitVideoSave(VideoCommonDto checkFileDTO, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) || ObjectUtils.isEmpty(checkFileDTO.getFileName()) + || ObjectUtils.isEmpty(checkFileDTO.getpUrl())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (CollectionUtils.isEmpty(checkFileDTO.getCutList())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + for (VideoCutDto dto : checkFileDTO.getCutList()){ + if (ObjectUtils.isEmpty(dto.getBeginTime()) || ObjectUtils.isEmpty(dto.getDuration()) + || ObjectUtils.isEmpty(dto.getName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + } + String fileType = checkFileDTO.getFileName().substring(checkFileDTO.getFileName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("cutVideoSave 视频编辑类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + + /** 操作剪辑 */ + checkFileDTO.setCutType("2"); + Map cutMap = this.cutVideo(checkFileDTO, loginUser); + if (ObjectUtils.isEmpty(cutMap)){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + if (!cutMap.containsKey("success") || "false".equals(cutMap.get("success").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + List cutList = ObjUtil.objectToList(cutMap.get("cutDtoList"), VideoCutDto.class); + List convertList = new ArrayList<>(); + LogUtil.info("splitVideoSave addCommonSource beginTime=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS)); + for (VideoCutDto cutDto : cutList) { + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(cutDto.getName(), cutDto.getName(), fileType, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(fileType); + fileSource.setSize(0L); + fileSource.setHashMd5(""); + fileSource.setPath(cutDto.getPath()); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + // 需要获取md5并修改 + fileSource.setNeedHashMd5(1); + convertList.add(fileSource); + } + LogUtil.info("splitVideoSave addCommonSource endTime=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS)); + cutMap.put("convertList",convertList); + return cutMap; + } + + + @Override + public Map mergeVideoSave(VideoCommonDto checkFileDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) || ObjectUtils.isEmpty(checkFileDTO.getName()) + || ObjectUtils.isEmpty(checkFileDTO.getResolution()) || ObjectUtils.isEmpty(checkFileDTO.getConvertSuffix())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (CollectionUtils.isEmpty(checkFileDTO.getCutList())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List cutList = new ArrayList<>(); + for (VideoCutDto dto : checkFileDTO.getCutList()){ + if (ObjectUtils.isEmpty(dto.getpUrl()) || ObjectUtils.isEmpty(dto.getFileName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + dto.setVideoPathOrg( getOrgPath(dto.getpUrl(), dto.getFileName())); + File file = new File(dto.getVideoPathOrg()); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + cutList.add(dto.getVideoPathOrg()); + } + String fileType = checkFileDTO.getConvertSuffix(); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("cutVideoSave 视频编辑类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + + //最终文件目录路径 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + checkFileDTO.getConvertSuffix(); + + + String serverUrl = HttpUtil.getRequestRootUrl(null); + List convertList = new ArrayList<>(); + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(checkFileDTO.getName(), checkFileDTO.getName(), fileType, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(fileType); + fileSource.setSize(0L); + fileSource.setHashMd5(""); + fileSource.setDomain(serverUrl); + fileSource.setPath(finalFilePath); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + // 需要获取md5并修改 + fileSource.setNeedHashMd5(1); + convertList.add(fileSource); + Map reMap = new HashMap<>(3); + reMap.put("sourceID", fileSource.getSourceID()); + reMap.put("fileType", fileSource.getFileType()); + reMap.put("name", fileSource.getName()); + + // 异步合并 并转码 + VideoCommonDto videoCommonDto = new VideoCommonDto(); + videoCommonDto.setTaskID(checkFileDTO.getTaskID()); + videoCommonDto.setFinalFilePath(finalFilePath); + videoCommonDto.setOpType("3"); + videoCommonDto.setResolution(checkFileDTO.getResolution()); + videoCommonDto.setServerUrl(serverUrl); + // 转码 + asyncUtil.cutVideoMerge(cutList, finalFilePath, fileType, "", convertList, "mergeVideo", null, 0L); + + return reMap; + } + + @Override + public Map convertVideoSave(VideoCommonDto checkFileDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) || ObjectUtils.isEmpty(checkFileDTO.getFileName()) + || ObjectUtils.isEmpty(checkFileDTO.getpUrl()) || ObjectUtils.isEmpty(checkFileDTO.getName()) + || ObjectUtils.isEmpty(checkFileDTO.getResolution()) || ObjectUtils.isEmpty(checkFileDTO.getFrameRate()) + || ObjectUtils.isEmpty(checkFileDTO.getConvertSuffix())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(checkFileDTO.getConvertSuffix())){ + LogUtil.error("convertVideoSave 转换格式错误 checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String fileType = checkFileDTO.getConvertSuffix(); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("cutVideoSave 视频编辑类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + // 原始文件路径 + String videoPathOrg = getOrgPath(checkFileDTO.getpUrl(), checkFileDTO.getFileName()) ; + LogUtil.info("convertVideoSave videoPathOrg=" + videoPathOrg + ", checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + //最终文件目录路径 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + + String serverUrl = HttpUtil.getRequestRootUrl(null); + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + fileType; + + List convertList = new ArrayList<>(); + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(checkFileDTO.getName(), checkFileDTO.getName(), fileType, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(fileType); + fileSource.setSize(0L); + fileSource.setHashMd5(""); + fileSource.setPath(finalFilePath); + fileSource.setDomain(serverUrl); + fileSource.setResolution(checkFileDTO.getResolution()); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + // 需要获取md5并修改 + fileSource.setNeedHashMd5(1); + convertList.add(fileSource); + + Map reMap = new HashMap<>(3); + reMap.put("sourceID", fileSource.getSourceID()); + reMap.put("fileType", fileSource.getFileType()); + reMap.put("name", fileSource.getName()); + + /** 操作剪辑-转码 */ + VideoCommonDto videoCommonDto = new VideoCommonDto(); + videoCommonDto.setTaskID(checkFileDTO.getTaskID()); + videoCommonDto.setFinalFilePath(finalFilePath); + videoCommonDto.setVideoPathOrg(videoPathOrg); + videoCommonDto.setOpType("2"); + videoCommonDto.setResolution(checkFileDTO.getResolution().replace("x","*")); + videoCommonDto.setFrameRate(checkFileDTO.getFrameRate()); + videoCommonDto.setServerUrl(serverUrl); + // 转码 + asyncUtil.convertVideoMerge(videoCommonDto, convertList); + + return reMap; + } + + @Override + public Map videoConfigSave(VideoCommonDto checkFileDTO, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) || ObjectUtils.isEmpty(checkFileDTO.getFileName()) + || ObjectUtils.isEmpty(checkFileDTO.getpUrl()) || ObjectUtils.isEmpty(checkFileDTO.getName()) + || ObjectUtils.isEmpty(checkFileDTO.getConvertSuffix())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(checkFileDTO.getConvertSuffix())){ + LogUtil.error("convertVideoSave 转换格式错误 checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String fileType = checkFileDTO.getConvertSuffix(); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("cutVideoSave 视频编辑类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 原始文件路径 + String videoPathOrg = getOrgPath(checkFileDTO.getpUrl(), checkFileDTO.getFileName()); + LogUtil.info("convertVideoSave videoPathOrg=" + videoPathOrg + ", checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + + //最终文件目录路径 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + + String serverUrl = HttpUtil.getRequestRootUrl(null); + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + fileType; + + List convertList = new ArrayList<>(); + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(checkFileDTO.getName(), checkFileDTO.getName(), fileType, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(fileType); + fileSource.setSize(0L); + fileSource.setHashMd5(""); + fileSource.setPath(finalFilePath); + fileSource.setDomain(serverUrl); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + // 需要获取md5并修改 + fileSource.setNeedHashMd5(1); + convertList.add(fileSource); + + Map reMap = new HashMap<>(3); + reMap.put("sourceID", fileSource.getSourceID()); + reMap.put("fileType", fileSource.getFileType()); + reMap.put("name", fileSource.getName()); + + /** 操作剪辑-各种设置 */ + checkFileDTO.setTaskID(checkFileDTO.getTaskID()); + checkFileDTO.setFinalFilePath(finalFilePath); + checkFileDTO.setVideoPathOrg(videoPathOrg); + checkFileDTO.setOpType("2"); + checkFileDTO.setResolution(checkFileDTO.getResolution()); + checkFileDTO.setFrameRate(checkFileDTO.getFrameRate()); + checkFileDTO.setServerUrl(serverUrl); + // 转码 + asyncUtil.settingVideo(checkFileDTO, convertList); + + return reMap; + } + + private String getTaskIDUrl(String taskID){ + if (!ObjectUtils.isEmpty(taskID)){ + return taskID + "/"; + } + return ""; + } + + /** + * 视频剪辑 (照相)(切一张图片) + * @param checkFileDTO + * @param loginUser + * @return + */ + @Override + public Map cutVideoImg(VideoCommonDto checkFileDTO, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getName()) || ObjectUtils.isEmpty(checkFileDTO.getFileName()) + || ObjectUtils.isEmpty(checkFileDTO.getpUrl()) || ObjectUtils.isEmpty(checkFileDTO.getCutTime())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String fileType = checkFileDTO.getFileName().substring(checkFileDTO.getFileName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("cutVideoImg 原视频类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String suffix = checkFileDTO.getName().substring(checkFileDTO.getName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix)){ + LogUtil.error("cutVideoImg 视频照相图片类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + String fileName = checkFileDTO.getName(); + /** 操作剪辑照相 */ + // 原始文件路径 + String videoPathOrg = getOrgPath(checkFileDTO.getpUrl(), checkFileDTO.getFileName()); + + LogUtil.info("cutVideoImg videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(checkFileDTO)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + //最终文件目录路径 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + suffix; + +// ffmpeg -i input.mp4 -vn -c:a copy output.aac + + Boolean check = VideoGetUtil.covPicBatch(videoPathOrg, finalFilePath, checkFileDTO.getCutTime(), false); + + if (!check){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + String serverUrl = HttpUtil.getRequestRootUrl(null); + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(fileName, fileName, suffix, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(suffix); + fileSource.setPath(finalFilePath); + fileSource.setDomain(serverUrl); + + Long size = 0L; + String md5 = ""; + + //最终文件 + File finalFile = new File(finalFilePath); + FileInputStream fis = null; + try { + fis = new FileInputStream(finalFile); + md5 = org.springframework.util.DigestUtils.md5DigestAsHex(fis); + size = finalFile.length(); + fis.close(); + } catch (IOException e) { + md5 = ""; + LogUtil.error(e.getMessage(), " 获取图片md5失败 失败 commonSource=" + JsonUtils.beanToJson(fileSource)); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + fileSource.setSize(size); + fileSource.setHashMd5(md5); + fileSource.setSourceType(BusTypeEnum.CLOUD.getTypeCode()); + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix)) { + String firstPath = FileUtil.getFirstStorageDevicePath(fileSource.getPath()); + busTypeHandleService.doForImage(null, false, fileSource); + fileSource.setThumb((fileSource.getPath()) + .replace(firstPath + "/doc/", firstPath + "/common/doc/") + .replace(firstPath + "/attachment/", firstPath + "/common/attachment/") + .replace(firstPath + "/private/", firstPath + "/common/") + ); + } + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + + + Map reMap = new HashMap<>(3); + reMap.put("path",finalFilePath); + reMap.put("sourceID",fileSource.getSourceID()); + reMap.put("name",fileSource.getName()); + return reMap; + } + + @Override + public Map copyAudio(VideoCommonDto checkFileDTO, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getName()) || ObjectUtils.isEmpty(checkFileDTO.getFileName()) + || ObjectUtils.isEmpty(checkFileDTO.getpUrl()) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String fileType = checkFileDTO.getFileName().substring(checkFileDTO.getFileName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("copyAudio 原视频类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String suffix = checkFileDTO.getName().substring(checkFileDTO.getName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.AUDIO_SHOW_TYPE_ARR).contains(suffix)){ + LogUtil.error("copyAudio 视频照相图片类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + + + List sourceNameList = null; + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + String fileName = checkFileDTO.getName(); + /** 操作剪辑照相 */ + // 原始文件路径 + String videoPathOrg = getOrgPath(checkFileDTO.getpUrl(), checkFileDTO.getFileName()); + LogUtil.info("copyAudio videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(checkFileDTO)); + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + //最终文件目录路径 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + suffix; + + Boolean check = VideoGetUtil.copyAudioBatch(videoPathOrg, finalFilePath); + + if (!check){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + String serverUrl = HttpUtil.getRequestRootUrl(null); + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(fileName, fileName, suffix, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(suffix); + fileSource.setPath(finalFilePath); + fileSource.setDomain(serverUrl); + + Long size = 0L; + String md5 = ""; + + //最终文件 + File finalFile = new File(finalFilePath); + FileInputStream fis = null; + try { + fis = new FileInputStream(finalFile); + md5 = org.springframework.util.DigestUtils.md5DigestAsHex(fis); + size = finalFile.length(); + fis.close(); + } catch (IOException e) { + md5 = ""; + LogUtil.error(e.getMessage(), " copyAudio 获取音频md5失败 失败 commonSource=" + JsonUtils.beanToJson(fileSource)); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + fileSource.setSize(size); + fileSource.setHashMd5(md5); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + + Map reMap = new HashMap<>(3); + reMap.put("path",finalFilePath); + reMap.put("sourceID",fileSource.getSourceID()); + reMap.put("name",fileSource.getName()); + return reMap; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/VideoImagesServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/VideoImagesServiceImpl.java new file mode 100644 index 0000000..7bf1fb6 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/VideoImagesServiceImpl.java @@ -0,0 +1,175 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.home.dto.VideoCutDto; +import com.svnlan.home.service.VideoImagesService; +import com.svnlan.home.utils.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.*; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/8 9:17 + */ +@Service +public class VideoImagesServiceImpl implements VideoImagesService { + + @Resource + FileOptionTool fileOptionTool; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + ImageToVideoUtil imageToVideoUtil; + + @Override + public Map imagesToVideo(VideoCommonDto checkFileDTO, LoginUser loginUser){ + + if (ObjectUtils.isEmpty(checkFileDTO.getName()) || ObjectUtils.isEmpty(checkFileDTO.getSourceIDTo()) + || ObjectUtils.isEmpty(checkFileDTO.getCutList()) ){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String fileType = checkFileDTO.getName().substring(checkFileDTO.getName().lastIndexOf(".") + 1 ); + if (!Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(fileType)){ + LogUtil.error("imagesToVideo 视频类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List cutList = checkFileDTO.getCutList(); + for (VideoCutDto dto : cutList){ + if (ObjectUtils.isEmpty(dto) || ObjectUtils.isEmpty(dto.getpUrl()) || ObjectUtils.isEmpty(dto.getFileName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String ft = dto.getFileName().substring(dto.getFileName().lastIndexOf(".") + 1 ); + if (!Arrays.asList("jpg","png","jpeg","JPG","PNG","JPEG").contains(ft)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(dto.getDuration())){ + dto.setDuration(1.5); + } + if (ObjectUtils.isEmpty(dto.getLength())){ + dto.setLength(3.0); + } + if (ObjectUtils.isEmpty(dto.getBackground())){ + dto.setBackground("#000000"); + } + if (ObjectUtils.isEmpty(dto.getTransition())){ + dto.setTransition("rectcrop"); + } + } + File file = new File("/Cheerfulness.mp3"); + if (!file.exists()) { + Mp3InitUtils mp3Init = new Mp3InitUtils(); + } + + //最终文件目录路径 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); + } + } + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "." + fileType; + + String redisKey = GlobalConfig.async_key_convert_img_video + checkFileDTO.getTaskID(); + String redisProgressKey = GlobalConfig.progress_key_convert_img_video + checkFileDTO.getTaskID(); + + String serverUrl = HttpUtil.getRequestRootUrl(null); + stringRedisTemplate.opsForValue().set(redisKey, "0", 1, TimeUnit.HOURS); + + imageToVideoUtil.execImageToVideo(finalFilePath, checkFileDTO, redisKey, fileType, serverUrl, loginUser, redisProgressKey); + + + Map reMap = new HashMap<>(3); + reMap.put("taskID", checkFileDTO.getTaskID()); + reMap.put("status", 0); + reMap.put("progress", 0); + return reMap; + } + + @Override + public boolean taskAction(CheckFileDTO checkFileDTO, Map resultMap, LoginUser loginUser){ + if (ObjectUtils.isEmpty(checkFileDTO.getTaskID())){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String proKey = GlobalConfig.async_key_convert_img_video+"_pro" + checkFileDTO.getTaskID(); + String proString = stringRedisTemplate.opsForValue().get(proKey); + + int progress = 0; + if (!ObjectUtils.isEmpty(proString)){ + progress = Integer.valueOf(proString); + } + resultMap.put("taskID", checkFileDTO.getTaskID()); + resultMap.put("status", 0); + resultMap.put("taskID", checkFileDTO.getTaskID()); + String key = GlobalConfig.async_key_convert_img_video + checkFileDTO.getTaskID(); + String denyString = stringRedisTemplate.opsForValue().get(key); + // 进度 + String progressKey = GlobalConfig.progress_key_convert_img_video + checkFileDTO.getTaskID(); + String progressString = stringRedisTemplate.opsForValue().get(progressKey); + resultMap.put("progress", 0); + if (!ObjectUtils.isEmpty(progressString)){ + int p = Integer.valueOf(progressString); + if (p >= 90){ + if (p == 100){ + resultMap.put("status", 1); + } + resultMap.put("progress", p); + }else { + if (p <= progress){ + int p1 = progress > 90 ? progress : progress + 1; + resultMap.put("progress", p1); + stringRedisTemplate.opsForValue().set(proKey, "" + p1, 1, TimeUnit.HOURS); + }else { + resultMap.put("progress", p); + stringRedisTemplate.opsForValue().set(proKey, "" + p, 1, TimeUnit.HOURS); + } + } + }else { + resultMap.put("progress", progress); + } + + + LogUtil.info("convertTaskAction key=" + key +",denyString=" + denyString + ",progressString=" + progressString); + if (ObjectUtils.isEmpty(denyString)){ + resultMap.put("status", 1); + resultMap.put("progress", 100); + return true; + } + if ("1".equals(denyString)) { + resultMap.put("status", 1); + resultMap.put("progress", 100); + stringRedisTemplate.delete(key); + stringRedisTemplate.delete(progressKey); + stringRedisTemplate.delete(proKey); + }else if ("2".equals(denyString)) { + resultMap.put("status", 2); + resultMap.put("progress", 0); + stringRedisTemplate.delete(key); + stringRedisTemplate.delete(progressKey); + stringRedisTemplate.delete(proKey); + } + return true; + } +} diff --git a/src/main/java/com/svnlan/home/service/impl/YzServiceImpl.java b/src/main/java/com/svnlan/home/service/impl/YzServiceImpl.java new file mode 100644 index 0000000..64979a3 --- /dev/null +++ b/src/main/java/com/svnlan/home/service/impl/YzServiceImpl.java @@ -0,0 +1,259 @@ +package com.svnlan.home.service.impl; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.dao.IoSourceHistoryDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.domain.IoSourceHistory; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.YzOfficDto; +import com.svnlan.home.service.YzService; +import com.svnlan.home.utils.AsyncUtil; +import com.svnlan.home.utils.ConvertUtil; +import com.svnlan.home.utils.FileOptionTool; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/10 16:31 + */ +@Service +public class YzServiceImpl implements YzService { + + @Resource + FileOptionTool fileOptionTool; + @Resource + IoSourceDao ioSourceDao; + @Resource + ConvertUtil convertUtil; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + IoSourceHistoryDao ioSourceHistoryDao; + @Resource + AsyncUtil asyncUtil; + @Resource + StorageService storageService; + @Value("${yz.fileId.prefix}") + private String yzFileIdPreFix; + + + @Override + public void yzCallback(YzOfficDto officDto, MultipartFile file){ + + if (file == null || ObjectUtils.isEmpty(officDto) || ObjectUtils.isEmpty(officDto.getFileId())) { + LogUtil.error("yzCallback file is null officDto=" + JsonUtils.beanToJson(officDto)); + return ; + } + Long userID = 0L; + if (!CollectionUtils.isEmpty(officDto.getUserId())){ + userID = Long.parseLong(officDto.getUserId().get(0)); + } + String fileIDUUID = null; + if (officDto.getFileId().startsWith(yzFileIdPreFix)){ + fileIDUUID = officDto.getFileId().replaceFirst(yzFileIdPreFix, ""); + }else { + fileIDUUID = officDto.getFileId(); + } + String uuid = ""; + String prefix = ""; + Long sourceID = null; + int index = fileIDUUID.indexOf("_"); + if (index >= 0){ + sourceID = Long.parseLong(fileIDUUID.substring(0, index)); + uuid = fileIDUUID.substring(index + 1, fileIDUUID.length()); + prefix = "_"; + }else { + sourceID = Long.parseLong(fileIDUUID); + } + + String key = GlobalConfig.yzwo_file_edit_key + sourceID + prefix + uuid; + String value = stringRedisTemplate.opsForValue().get(key); + int count = 0; + if (!ObjectUtils.isEmpty(value)){ + count = Integer.valueOf(value); + }else { + stringRedisTemplate.opsForValue().set(key, "1", 5, TimeUnit.HOURS); + } + + + CommonSource commonSource = fileOptionTool.getSourceInfo(sourceID); + if (ObjectUtils.isEmpty(commonSource)) { + LogUtil.error("yzCallback commonSource is null officDto=" + JsonUtils.beanToJson(officDto)); + return ; + } + + LogUtil.info("yzCallback count==========" + count + ",officDto=" + JsonUtils.beanToJson(officDto)); + + if (ObjectUtils.isEmpty(userID) || userID <= 0){ + String userKey = GlobalConfig.yzwo_file_edit_user_key + uuid; + String userMapString = stringRedisTemplate.opsForValue().get(userKey); + LogUtil.info("yzCallback count==========" + count + ",userMapString=" + userMapString); + Map userMap = new HashMap<>(1); + if (!ObjectUtils.isEmpty(userMapString)){ + try { + userMap = JsonUtils.jsonToMap(userMapString); + }catch (Exception e){ + LogUtil.error(e, "yzCallback join error"); + } + } + if (!ObjectUtils.isEmpty(userMap) && userMap.containsKey("userID")){ + userID = Long.parseLong(userMap.get("userID").toString()); + }else { + userID = commonSource.getUserID(); + } + } + commonSource.setUserID(userID); + if (count <= 0){ + LogUtil.info("yzCallback newFileSave ===== commonSource=" + JsonUtils.beanToJson(commonSource)); + // 新版本 + newFileSave(commonSource, file, userID, sourceID); + }else { + LogUtil.info("yzCallback thisFileSave ===== commonSource=" + JsonUtils.beanToJson(commonSource)); + // 老版本 + thisFileSave(commonSource, file, userID, sourceID); + } + + + return ; + } + + + public void newFileSave(CommonSource commonSource, MultipartFile file, Long userID, Long sourceID) { + + Long fileID = commonSource.getFileID(); + Long sizeOld = commonSource.getSize(); + + // 已改 + String finalTopPath = fileOptionTool.getPropertiesFilePathAll("cloud.savePath"); + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败, path:" + finalFolderPath); +// return null; + } + } + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + commonSource.getUserID() + "." + commonSource.getFileType(); + + Long size = file.getSize(); + //最终文件 + File finalFile = new File(finalFilePath); + FileInputStream fis = null; + try { + FileUtil.writeFile(finalFile, file.getBytes()); + fis = new FileInputStream(finalFile); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage() , " yzCallback 上传文件失败"); + return ; + } finally { + if (fis != null){ + try { + fis.close(); + } catch (Exception e){ + LogUtil.error(e); + } + } + } + + commonSource.setSize(size); + //commonSource.setHashMd5(serverChecksum); + commonSource.setPath(finalFilePath); + + LogUtil.info("editIoSourceDetail------addCommonSource---------commonSource=" + JsonUtils.beanToJson(commonSource)); + commonSource.setIsEdit("1"); + fileOptionTool.addCommonSource(commonSource.getUserID(), commonSource, EventEnum.edit); + // 添加历史记录 + asyncUtil.asyncAddSourceHistory(commonSource, userID, fileID, sizeOld); + + asyncUtil.asyncUpdateFileMd5(finalFilePath); + + String domain = HttpUtil.getRequestRootUrl(null); + // 预览 + commonSource.setDomain(domain); + convertUtil.yongZhongPre(commonSource, true); + + } + public void thisFileSave(CommonSource commonSource, MultipartFile file, Long userID, Long sourceID) { + + String finalFilePath = commonSource.getPath(); + Long size = file.getSize(); + //最终文件 + File finalFile = new File(finalFilePath); + String serverChecksum; + FileInputStream fis = null; + try { + FileUtil.writeFile(finalFile, file.getBytes()); + fis = new FileInputStream(finalFile); + serverChecksum = DigestUtils.md5DigestAsHex(fis); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage() , " yzCallback 上传文件失败"); + return ; + } finally { + if (fis != null){ + try { + fis.close(); + } catch (Exception e){ + LogUtil.error(e); + } + } + } + + String domain = HttpUtil.getRequestRootUrl(null); + // 预览 + commonSource.setDomain(domain); + convertUtil.yongZhongPre(commonSource, true); + // 修改size + if (!ObjectUtils.isEmpty(commonSource.getFileThumbSize()) && commonSource.getFileThumbSize() > 0 && size > commonSource.getFileThumbSize()){ + size = size - commonSource.getFileThumbSize(); + } + IOSource sourceUpdate = new IOSource(); + sourceUpdate.setSize(size); + sourceUpdate.setModifyUser(userID); + sourceUpdate.setSourceID(sourceID); + sourceUpdate.setFileID(commonSource.getFileID()); + sourceUpdate.setHashMd5(serverChecksum); + + + // 修改文件source修改人、file文件大小 + try { + ioSourceDao.updateFileSize(sourceUpdate); + }catch (Exception e){ + LogUtil.error(e, " yzCallback updateFileSize error"); + } + + try { + ioSourceDao.updateSourceModifyUser(sourceUpdate); + }catch (Exception e){ + LogUtil.error(e, " yzCallback updateSourceModifyUser error"); + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncConvertPicUtil.java b/src/main/java/com/svnlan/home/utils/AsyncConvertPicUtil.java new file mode 100644 index 0000000..5d63b71 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncConvertPicUtil.java @@ -0,0 +1,96 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.Result; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.manage.vo.ConvertToJPGDTO; +import com.svnlan.manage.vo.ConvertToPDFMsgDTO; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/30 13:58 + */ +@Component +public class AsyncConvertPicUtil { + @Resource + ConvertPicUtil convertPicUtil; + @Resource + StringRedisTemplate stringRedisTemplate; + + @Async(value = "asyncTaskExecutor") + public void asyncConvertToJPG(ConvertToPDFMsgDTO msgDTO, CommonSource commonSource) { + String prefix = "@将PDF、PPT、WORD、EXCEL原文件转成图片@convertToJPGKafka006 >>> "; + StringBuilder msgBuilder = new StringBuilder(); + String paramTip = ""; + String taskId = ""; + String sendTime = ""; + Long sourceID = 0L; + try { + sendTime = msgDTO.getSendTime(); + sourceID = msgDTO.getSourceID(); + + taskId = msgDTO.getTaskId(); + msgBuilder.append("asyncConvertToJPG:") + .append(sourceID).append("-").append(sendTime) + .append(",").append(taskId).append(";"); + paramTip = "->消息记录:" + msgBuilder.toString(); + LogUtil.info(prefix + "消费开始," + paramTip); + } + catch (Exception e) { + LogUtil.error(e, prefix + " 消费失败!原因:消息格式有误"); + // + return; + } + + String concurrentKey = String.format(GlobalConfig.concurrentConvertToJPGKey, commonSource.getSourceID()); + // + Boolean setSuccess = this.stringRedisTemplate.opsForValue().setIfAbsent(concurrentKey, "1", 20, TimeUnit.MINUTES); + if(!setSuccess) { + LogUtil.error( prefix + " 有转码任务进行中!" + paramTip); + return; + } + String cacheKey = String.format(GlobalConfig.infoConvertToJPGKey, commonSource.getSourceID()); + + try { + ConvertToJPGDTO convertToJPGDTO = new ConvertToJPGDTO("0", null); + //进行中 + this.stringRedisTemplate.opsForValue().set(cacheKey, JsonUtils.beanToJson(convertToJPGDTO), 20, TimeUnit.MINUTES); + + + Result result = this.convertPicUtil.convertToPDF(prefix, commonSource, msgDTO); + String code = result.getCode(); + String regionFilePath = commonSource.getPath(); + String pdfPath = commonSource.getPdfPath(); + String lastImagePath = commonSource.getH264Path(); + String tip = String.format("文件ID:%d,原文件路径:%s,PDF文件路径:%s,最后1张图片路径:%s", sourceID, + regionFilePath, pdfPath, lastImagePath); + String status = "1"; //状态:0-进行中,1-成功,2-失败 + if("200".equals(code)) { + LogUtil.info(prefix + "消费成功。" + tip); + } else if("AlreadySuccess".equals(code)) { + LogUtil.info(prefix + "消费成功。原先已转过," + tip); + } else { + LogUtil.info(prefix + "消费失败。转换失败," + tip); + } + + convertToJPGDTO = new ConvertToJPGDTO(status, lastImagePath); + //结果 + this.stringRedisTemplate.opsForValue().set(cacheKey, JsonUtils.beanToJson(convertToJPGDTO), 2, TimeUnit.MINUTES); + + } catch (Exception e) { + LogUtil.error(e, prefix + " 消费失败!" + paramTip); + } + + //删除并发锁 + this.stringRedisTemplate.delete(concurrentKey); + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncCountSizeUtil.java b/src/main/java/com/svnlan/home/utils/AsyncCountSizeUtil.java new file mode 100644 index 0000000..4336a32 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncCountSizeUtil.java @@ -0,0 +1,76 @@ +package com.svnlan.home.utils; + +import com.svnlan.home.dao.ExplorerOperationsDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/9/9 11:33 + */ +@Component +public class AsyncCountSizeUtil { + @Resource + ExplorerOperationsDao operationsDao; + @Resource + IoSourceDao ioSourceDao; + @Resource + StringRedisTemplate stringRedisTemplate; + + @Async(value = "asyncTaskExecutor") + public void asyncCountSize(CheckFileDTO updateFileDTO) { + String key = "countSize_taskID_key_" + updateFileDTO.getTaskID(); + stringRedisTemplate.opsForValue().set(key, "0", 1, TimeUnit.HOURS ); + List sourceIds = Arrays.asList(updateFileDTO.getOperation().split(",")).stream().map(Long::parseLong).collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(sourceIds)){ + stringRedisTemplate.opsForValue().set("countSize_taskID_key_" + updateFileDTO.getTaskID(), "2", 1, TimeUnit.HOURS ); + return; + } + List countUpdateList = null; + List countList = null; + Map countMap = null; + List list = ioSourceDao.copySourceList(sourceIds); + for (IOSource source : list){ + countMap = new HashMap<>(); + countList = operationsDao.getSourceListByLevelToContSize(source.getParentLevel()+source.getSourceID()+",", ObjectUtils.isEmpty(updateFileDTO.getStatus()) ? 0 : updateFileDTO.getStatus()); + try { + for (IOSource vo : countList){ + List fromSourceIds = Arrays.asList(vo.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + for (Long pId : fromSourceIds){ + if (countMap.containsKey(pId)){ + countMap.put(pId, (countMap.get(pId) + vo.getSize())); + }else { + countMap.put(pId, vo.getSize()); + } + } + } + if (!ObjectUtils.isEmpty(countMap)){ + countUpdateList = new ArrayList<>(); + for (Map.Entry entry : countMap.entrySet()) { + countUpdateList.add(new IOSource(entry.getKey(), entry.getValue())); + } + operationsDao.batchUpdateSizeByCountSize(countUpdateList); + } + }catch (Exception e){ + LogUtil.error(e, " 统计错误 source=" + JsonUtils.beanToJson(source)); + } + } + stringRedisTemplate.opsForValue().set(key, "1", 1, TimeUnit.HOURS ); + } + +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncCutImgUtil.java b/src/main/java/com/svnlan/home/utils/AsyncCutImgUtil.java new file mode 100644 index 0000000..fe6e849 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncCutImgUtil.java @@ -0,0 +1,180 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.UploadDTO; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.home.utils.video.VideoGetUtil; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.*; +import java.util.concurrent.Future; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/13 15:36 + */ +@Component +public class AsyncCutImgUtil { + + @Resource + StorageService storageService; + @Resource + IoFileDao ioFileDao; + @Resource + ConvertUtil convertUtil; + + @Resource(name = "threadPoolDefault") + private ThreadPoolTaskExecutor executor; + + @Async(value = "asyncTaskExecutor") + public List AsyncExecVideoShearList(VideoCommonDto videoCommonDto){ + + videoCommonDto.setTaskID(ObjectUtils.isEmpty(videoCommonDto.getTaskID()) ? RandomUtil.getuuid() : videoCommonDto.getTaskID()); + + String videoPathOrg; + if (videoCommonDto.getpUrl().indexOf(GlobalConfig.private_replace_key) >= 0){ + videoPathOrg = videoCommonDto.getpUrl().replace(GlobalConfig.private_replace_key, "/private/") + videoCommonDto.getFileName(); + }else { + videoPathOrg = GlobalConfig.default_disk_path_pre + "/private" + videoCommonDto.getpUrl() + videoCommonDto.getFileName(); + } + LogUtil.info("AsyncExecVideoShearList videoPathOrg=" + videoPathOrg + ", videoCommonDto=" + JsonUtils.beanToJson(videoCommonDto)); + + String firstPath = FileUtil.getFirstStorageDevicePath(videoPathOrg); + String defaultFirstPath = storageService.getDefaultStorageDevicePath(); + + + File file = new File(videoPathOrg); + if (!file.exists()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String nameDir = videoPathOrg.substring(videoPathOrg.lastIndexOf("/") + 1); + String tempPath = videoPathOrg.substring(0,videoPathOrg.lastIndexOf(".") ) + "/" ; + String tempPathFinish = tempPath.replace(firstPath + "/private/", defaultFirstPath + "/common/down_temp/") ; + File destinationFolder = new File(tempPathFinish); + if (!destinationFolder.exists()) { + destinationFolder.mkdirs(); + } + + // = 1 则重新生成 + if (ObjectUtils.isEmpty(videoCommonDto.getRegeneration()) || videoCommonDto.getRegeneration().intValue() != 1) { + + String firstCutPath = tempPathFinish + nameDir.replace(".", "_") + "_cut_frame_1.jpg"; + File firstCutFile = new File(firstCutPath); + if (firstCutFile.exists()) { + // 已存在截图文件 + return null; + } + } + // ffmpeg 默认 24 帧 + String frameInterval = ObjectUtils.isEmpty(videoCommonDto.getFrame()) ? "24" : String.valueOf(videoCommonDto.getFrame()); + // + Long lengthTime = videoCommonDto.getLength() * 1000; + + // 一次切两分钟 + long eachTime = 120 * 1000; + long num; + num = lengthTime / eachTime; + if (lengthTime % eachTime != 0){ + num ++; + } + String endN = DateDUtil.msecToTime(eachTime); + LogUtil.info("AsyncExecVideoShearList lengthTime=" + lengthTime + ",eachTime=" + eachTime); + + //使用Future方式执行多任务 + //生成一个集合 + List futures = new ArrayList<>(); + // 按分取 + LogUtil.info("AsyncExecVideoShearList tempPathFinish=" + tempPathFinish ); + for (int i = 0 ; i < num; i++){ + // 从视频中截取多张图片 + String tempImgPath = tempPathFinish + nameDir.replace(".", "_")+"_cut_frame_" + (i+1) + "_%02d.jpg"; + long timeParam = eachTime * i; + Future future = executor.submit(() -> { + String beginN = DateDUtil.msecToTime(timeParam); + + VideoGetUtil.covPicBatch(videoPathOrg, tempImgPath, beginN, endN, frameInterval); + }); + futures.add(future); + } + + if (!CollectionUtils.isEmpty(futures)){ + try { + //查询任务执行的结果 + for (Future future : futures) { + while (true) {//CPU高速轮询:每个future都并发轮循,判断完成状态然后获取结果,这一行,是本实现方案的精髓所在。即有10个future在高速轮询,完成一个future的获取结果,就关闭一个轮询 + if (future.isDone() && !future.isCancelled()) {//获取future成功完成状态,如果想要限制每个任务的超时时间,取消本行的状态判断+future.get(1000*1, TimeUnit.MILLISECONDS)+catch超时异常使用即可。 + + LogUtil.info("AsyncExecVideoShearList 任务i=" + future.get() + "获取完成!" + new Date()); + break;//当前future获取结果完毕,跳出while + } else { + Thread.sleep(1);//每次轮询休息1毫秒(CPU纳秒级),避免CPU高速轮循耗空CPU + } + } + } + }catch (Exception e){ + LogUtil.error(e, "AsyncExecVideoShearList error "); + } + } + return null; + } + + @Async(value = "asyncTaskExecutor") + public void AsyncExecVideoImgThumb(CommonSource commonSource, StringRedisTemplate stringRedisTemplate, boolean check){ + String filePath = commonSource.getPath(); + File f = new File(filePath); + if (!f.exists()) { + LogUtil.error("AsyncExecVideoImgThumb filePath is null fileID=" + commonSource.getFileID()); + if (check) { + stringRedisTemplate.opsForHash().put(GlobalConfig.temp_img_video_key, commonSource.getSourceID() + "", "1"); + } + return; + } + + try { + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType())){ + String value = ioFileDao.getFileUrlValue(commonSource.getFileID()); + Map map = null; + if (!ObjectUtils.isEmpty(value)) { + map = JsonUtils.jsonToMap(value); + } + if (!ObjectUtils.isEmpty(map) && map.containsKey("thumb") && !ObjectUtils.isEmpty(map.get("thumb"))) { + commonSource.setThumb(map.get("thumb").toString()); + // 需要重新查出 thumb 的路径 + UploadDTO uploadDTO = new UploadDTO(); + uploadDTO.setBusType("cloud"); + + String resolution = null; + if (map.containsKey("resolution") && !ObjectUtils.isEmpty(map.get("resolution"))){ + resolution = map.get("resolution").toString(); + } + VideoUtil.getVideoPic(commonSource.getPath(), commonSource.getThumb(), resolution); + } + }else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType())){ + ImageUtil.createThumb(filePath, "cloud", "", null, + "" , stringRedisTemplate, null, false); + }else if (Arrays.asList(GlobalConfig.CAMERA_TYPE_ARR).contains(commonSource.getFileType())){ + convertUtil.convertCameraToImgCommon("", commonSource); + } + + }catch (Exception e){ + LogUtil.error(e, "AsyncExecVideoImgThumb 失败"); + } + if (check) { + stringRedisTemplate.opsForHash().put(GlobalConfig.temp_img_video_key, commonSource.getSourceID()+ "", "1"); + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncDoMergeFileUtil.java b/src/main/java/com/svnlan/home/utils/AsyncDoMergeFileUtil.java new file mode 100644 index 0000000..5c8833a --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncDoMergeFileUtil.java @@ -0,0 +1,80 @@ +package com.svnlan.home.utils; + +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.UploadStateDTO; +import com.svnlan.home.service.ConvertFileService; +import com.svnlan.home.vo.CommonSourceVO; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.channels.FileChannel; +import java.util.Date; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/27 15:37 + */ +@Component +public class AsyncDoMergeFileUtil { + + @Resource + ConvertFileService convertFileService; + /** + * @Description: 异步合并文件 + * @params: [uploadStateDTO, commonSource] + * @Return: void + * @Modified: + */ + @Async(value = "asyncTaskExecutor") + public void asyncDoMergeFileUtil(UploadStateDTO uploadStateDTO, CommonSource commonSource, CommonSourceVO commonSourceVO, String busType){ + String checksum = uploadStateDTO.getChecksum(); + String tempPath = uploadStateDTO.getTempPath(); + Integer chunks = uploadStateDTO.getChunks(); + String finalFilePath = commonSource.getPath(); + File finalFile = new File(finalFilePath); + //临时文件数组 + File[] tempFiles = new File[chunks]; + try (FileChannel finalFileChannel = new FileOutputStream(finalFile, true).getChannel();) { + StringBuilder tempFilePath; + //将临时文件合并到最终文件 + LogUtil.info("merge break1. time:" + new Date()); + for (int i = 0; i < chunks; i++) { + //拼接临时文件路径 + tempFilePath = new StringBuilder(); + tempFilePath.append(tempPath); + tempFilePath.append(checksum); + tempFilePath.append("_"); + tempFilePath.append(i); + tempFilePath.append(".part"); + //通过FileChannel + tempFiles[i] = new File(tempFilePath.toString()); + try (FileChannel tempFileChannel = new FileInputStream(tempFiles[i]).getChannel();) { + tempFileChannel.transferTo(0, tempFileChannel.size(), finalFileChannel); + } + } + LogUtil.info("merge break2. time:" + new Date()); + + //删除临时文件 + for (int i = 0; i < chunks; i++) { + tempFiles[i].delete(); + } + try { + new File(tempPath + "done.txt").delete(); + } catch (Exception e) { + LogUtil.error(e, "删除done文件失败"); + } + } catch (Exception e) { + LogUtil.error(e, "合并文件失败" + JsonUtils.beanToJson(commonSource)); + return ; + } + + convertFileService.tryToConvertFile(commonSourceVO, commonSource, busType); + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncFileDocConvertUtil.java b/src/main/java/com/svnlan/home/utils/AsyncFileDocConvertUtil.java new file mode 100644 index 0000000..72e6f08 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncFileDocConvertUtil.java @@ -0,0 +1,165 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.UploadDTO; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.utils.office.LibreOfficeDUtil; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.manage.vo.ConvertToPDFMsgDTO; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.PropertiesUtil; +import com.svnlan.utils.RandomUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/6/29 13:22 + */ +@Component +public class AsyncFileDocConvertUtil { + @Resource + BusTypeHandleService busTypeHandleService; + @Resource + FileOptionTool fileOptionTool; + @Resource + StringRedisTemplate stringRedisTemplate; + + @Value("${office.libreOfficeVersion}") + private String libreOfficeVersion; + + @Async(value = "asyncTaskExecutor") + public void asyncFileDocConvert(String toSuffix, CommonSource commonSource, HomeExplorerVO disk, String fileName, CommonSource parentSource + , LoginUser loginUser ,String taskID, String defaultPath, String serviceName) { + + List convertList = new ArrayList<>(); + String finalTopPath = defaultPath + PropertiesUtil.getUpConfig("cloud.savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("doc2Convert 创建目录失败, path:" + finalFolderPath); + } + } + String namePath = RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + commonSource.getUserID(); + + //文件后缀 + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + namePath ; + + String prefix = commonSource.getFileType() + " to " + toSuffix + " : "; + Integer targetType = commonSource.getTargetType(); + + String redisKey = GlobalConfig.progress_key_convert_doc_file + taskID; + List filePathList = new ArrayList<>(); + //最终文件 + switch (toSuffix){ + case "doc": + case "docx": + PdfDUtil.pdf2Doc(prefix, commonSource.getPath(), finalFilePath + "." + toSuffix, "docx".equals(toSuffix), + redisKey, true, + stringRedisTemplate); + filePathList.add(finalFilePath + "." + toSuffix); + break; + case "jpg": + case "png": + int progressRate = 100; + String convertPath = null; + if (!"pdf".equals(commonSource.getFileType())){ + progressRate = 50; + String pdfPath = commonSource.getPath().substring(commonSource.getPath().lastIndexOf("/") + 1).replace("." + commonSource.getFileType(), ".pdf"); + LibreOfficeDUtil.libreOfficeCommand(prefix, this.libreOfficeVersion, "pdf", + commonSource.getPath(), finalFilePath); + convertPath = finalFilePath + "/" + pdfPath; + }else { + convertPath = commonSource.getPath(); + } + PdfDUtil.pdfToPngOrJpgConverter(prefix, convertPath, finalFilePath + "_", true, filePathList, + redisKey, true, toSuffix, stringRedisTemplate, progressRate); + if (!"pdf".equals(commonSource.getFileType())){ + File f = new File(convertPath); + if (f.exists()){ + try { + f.delete(); + }catch (Exception e){ + } + } + } + break; + case "pdf": + File folderPdf = new File(finalFilePath); + //创建目录 + if (!folderPdf.exists()) { + if (!folderPdf.mkdirs()) { + LogUtil.error("doc2Convert 创建目录失败, path:" + finalFolderPath); + } + } + String pdfPath = commonSource.getPath().substring(commonSource.getPath().lastIndexOf("/") + 1).replace("." + commonSource.getFileType(), ".pdf"); + LibreOfficeDUtil.libreOfficeCommand(prefix, this.libreOfficeVersion, "pdf", + commonSource.getPath(), finalFilePath); + filePathList.add(finalFilePath + "/" + pdfPath); + stringRedisTemplate.opsForValue().set(redisKey, 99+"", 60, TimeUnit.SECONDS); + break; + default: + break; + } + + UploadDTO uploadDTO = new UploadDTO(); + uploadDTO.setHasMark(false); + CommonSource fileSource = null; + File file = null; + if (!CollectionUtils.isEmpty(filePathList)){ + int i = 0; + for (String path : filePathList){ + fileSource = new CommonSource(); + fileSource.setGroupID(disk.getGroupID()); + fileSource.setName(fileName ); + if ((i > 0)){ + fileSource.setName(fileName.replace("." + toSuffix, "") + "(" + i + ")." + toSuffix); + } + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setUserID(loginUser.getUserID()); + fileSource.setFileType(toSuffix); + file = new File(path); + fileSource.setSize(file.length()); + fileSource.setHashMd5(""); + fileSource.setNeedHashMd5(1); + fileSource.setPath(path); + fileSource.setDomain(serviceName); + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(toSuffix)){ + fileSource.setSourceType(2); + busTypeHandleService.doForImage(uploadDTO, false, fileSource); + } + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + + convertList.add(fileSource); + i ++; + + fileOptionTool.updateMemory(fileSource); + } + } + stringRedisTemplate.opsForValue().set(redisKey, String.valueOf(100), 60, TimeUnit.SECONDS); + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_convert_doc_file + taskID, "1", 20, TimeUnit.MINUTES); + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncSourceFileOtherUtil.java b/src/main/java/com/svnlan/home/utils/AsyncSourceFileOtherUtil.java new file mode 100644 index 0000000..8c214f6 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncSourceFileOtherUtil.java @@ -0,0 +1,237 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.MetaEnum; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.dao.IoSourceEventDao; +import com.svnlan.home.dao.IoSourceMetaDao; +import com.svnlan.home.domain.*; +import com.svnlan.home.dto.UploadDTO; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.vo.FileMetaVo; +import com.svnlan.utils.*; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.*; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/7/7 13:42 + */ +@Component +public class AsyncSourceFileOtherUtil { + + @Resource + BusTypeHandleService busTypeHandleService; + @Resource + IoFileDao ioFileDao; + @Resource + IoSourceMetaDao ioSourceMetaDao; + @Resource + IoSourceEventDao ioSourceEventDao; + + @Async(value = "asyncTaskExecutor") + public void asyncAddFileMeta(CommonSource commonSource, IOFile ioFile) { + + IOFileMeta fileMeta = new IOFileMeta(); + fileMeta.setFileID(ioFile.getFileID()); + fileMeta.setKey("fileInfoMore"); + FileMetaVo fileMetaVo = new FileMetaVo(); + fileMetaVo.setThumb(ObjectUtils.isEmpty(commonSource.getThumb()) ? "" : commonSource.getThumb()); + fileMetaVo.setAppViewUrl(ObjectUtils.isEmpty(commonSource.getAppPreviewUrl()) ? "" : commonSource.getAppPreviewUrl()); + fileMetaVo.setH264Path(ObjectUtils.isEmpty(commonSource.getH264Path()) ? "" : commonSource.getH264Path()); + fileMetaVo.setResolution(ObjectUtils.isEmpty(commonSource.getResolution()) ? "" : commonSource.getResolution()); + fileMetaVo.setViewUrl(ObjectUtils.isEmpty(commonSource.getPreviewUrl()) ? "" : commonSource.getPreviewUrl()); + fileMetaVo.setLength(ObjectUtils.isEmpty(commonSource.getSourceLength()) ? 0 : commonSource.getSourceLength()); + if (Arrays.asList(GlobalConfig.AUDIO_VIDEO_SHOW_TYPE_ARR).contains(commonSource.getFileType().toLowerCase()) + && !ObjectUtils.isEmpty(commonSource.getPath())) { + File f = new File(commonSource.getPath()); + if (f.exists()) { + if (StringUtil.isEmpty(fileMetaVo.getThumb()) && Arrays.asList(1, 2).contains(commonSource.getTargetType())) { + UploadDTO uploadDTO = new UploadDTO(); + uploadDTO.setBusType("cloud"); + busTypeHandleService.doForWareAndAttachment(uploadDTO, false, commonSource); + fileMetaVo.setThumb(ObjectUtils.isEmpty(commonSource.getThumb()) ? "" : commonSource.getThumb()); + } + } + // 其他的异步执行 + } + fileMeta.setValue(!ObjectUtils.isEmpty(fileMetaVo) ? JsonUtils.beanToJson(fileMetaVo) : ""); + try { + ioFileDao.insertMeta(fileMeta); + } catch (Exception e) { + LogUtil.error(e, " setUserDefaultSource insertMeta error"); + } + + + if (Arrays.asList(GlobalConfig.AUDIO_VIDEO_SHOW_TYPE_ARR).contains(commonSource.getFileType().toLowerCase()) + && !ObjectUtils.isEmpty(commonSource.getPath())) { + asyncUpdateH264InfoOperate(commonSource, fileMeta); + } + + } + + @Async(value = "asyncTaskExecutor") + public void asyncUpdateH264InfoOperate(CommonSource commonSource, IOFileMeta meta ) { + + FileMetaVo fileMetaVo = null; + if (!ObjectUtils.isEmpty(meta) && !ObjectUtils.isEmpty(meta.getValue())){ + fileMetaVo = JsonUtils.jsonToBean(meta.getValue(), FileMetaVo.class); + } + if (ObjectUtils.isEmpty(fileMetaVo)){ + fileMetaVo = new FileMetaVo(); + } + boolean check = false; + + File file = new File(commonSource.getPath()); + if (file.exists()) { + if (StringUtil.isEmpty(fileMetaVo.getThumb()) && Arrays.asList(1, 2).contains(commonSource.getTargetType())) { + UploadDTO uploadDTO = new UploadDTO(); + uploadDTO.setBusType("cloud"); + busTypeHandleService.doForWareAndAttachment(uploadDTO, false, commonSource); + fileMetaVo.setThumb(ObjectUtils.isEmpty(commonSource.getThumb()) ? "" : commonSource.getThumb()); + } + check = true; + Map videoInfoMap = VideoUtil.getVideoInfo(commonSource.getPath()); + Map basicMap = VideoUtil.getVideoBasicInfoMap(commonSource.getPath(), videoInfoMap, false); + if (!ObjectUtils.isEmpty(basicMap)) { + if (basicMap.containsKey("codecName")) { + fileMetaVo.setCodecName(basicMap.get("codecName")); + } + if (basicMap.containsKey("avgFrameRate")) { + fileMetaVo.setAvgFrameRate(basicMap.get("avgFrameRate")); + } + if (basicMap.containsKey("frameRate")) { + fileMetaVo.setFrameRate(basicMap.get("frameRate")); + } + if (basicMap.containsKey("sampleRate")) { + fileMetaVo.setSampleRate(basicMap.get("sampleRate")); + } + if (basicMap.containsKey("channels")) { + fileMetaVo.setChannels(basicMap.get("channels")); + } + if (basicMap.containsKey("audioCodecName")) { + fileMetaVo.setAudioCodecName(basicMap.get("audioCodecName")); + } + } + if (ObjectUtils.isEmpty(fileMetaVo.getResolution())){ + int[] heightAndWidth = VideoUtil.getHeightAndWidth(commonSource.getPath(), videoInfoMap, false); + String resolution = "1280*720"; + if (heightAndWidth[0] != 0 && heightAndWidth[1] != 0) { + resolution = heightAndWidth[1] + "*" + heightAndWidth[0]; + } + commonSource.setResolution(resolution); + fileMetaVo.setResolution(resolution); + } + Integer length = VideoUtil.getVideoLength(videoInfoMap); + fileMetaVo.setLength(length); + } + + if (check && !ObjectUtils.isEmpty(fileMetaVo)) { + ioFileDao.updateOneFileUrlValue(commonSource.getFileID(), JsonUtils.beanToJson(fileMetaVo)); + } + } + + + @Async(value = "asyncTaskExecutor") + public void asyncUpdateH264InfoOperateList(List list) { + Map videoInfoMap = VideoUtil.getVideoInfo(list.get(0).getPath()); + + for (CommonSource commonSource:list) { + + boolean check = false; + IOFileMeta meta = ioFileDao.getFileValue(commonSource.getSourceID()); + FileMetaVo fileMetaVo = null; + if (!ObjectUtils.isEmpty(meta) && !ObjectUtils.isEmpty(meta.getValue())) { + fileMetaVo = JsonUtils.jsonToBean(meta.getValue(), FileMetaVo.class); + } + if (ObjectUtils.isEmpty(fileMetaVo)) { + fileMetaVo = new FileMetaVo(); + } + File file = new File(commonSource.getPath()); + if (file.exists()) { + if (StringUtil.isEmpty(fileMetaVo.getThumb()) && Arrays.asList(1, 2).contains(commonSource.getTargetType())) { + UploadDTO uploadDTO = new UploadDTO(); + uploadDTO.setBusType("cloud"); + busTypeHandleService.doForWareAndAttachment(uploadDTO, false, commonSource); + fileMetaVo.setThumb(ObjectUtils.isEmpty(commonSource.getThumb()) ? "" : commonSource.getThumb()); + } + check = true; + Map basicMap = VideoUtil.getVideoBasicInfoMap(commonSource.getPath(), videoInfoMap, false); + if (!ObjectUtils.isEmpty(basicMap)) { + if (basicMap.containsKey("codecName")) { + fileMetaVo.setCodecName(basicMap.get("codecName")); + } + if (basicMap.containsKey("avgFrameRate")) { + fileMetaVo.setAvgFrameRate(basicMap.get("avgFrameRate")); + } + if (basicMap.containsKey("frameRate")) { + fileMetaVo.setFrameRate(basicMap.get("frameRate")); + } + if (basicMap.containsKey("sampleRate")) { + fileMetaVo.setSampleRate(basicMap.get("sampleRate")); + } + if (basicMap.containsKey("channels")) { + fileMetaVo.setChannels(basicMap.get("channels")); + } + if (basicMap.containsKey("audioCodecName")) { + fileMetaVo.setAudioCodecName(basicMap.get("audioCodecName")); + } + } + if (ObjectUtils.isEmpty(fileMetaVo.getResolution())) { + int[] heightAndWidth = VideoUtil.getHeightAndWidth(commonSource.getPath(), videoInfoMap, false); + String resolution = "1280*720"; + if (heightAndWidth[0] != 0 && heightAndWidth[1] != 0) { + resolution = heightAndWidth[1] + "*" + heightAndWidth[0]; + } + commonSource.setResolution(resolution); + fileMetaVo.setResolution(resolution); + } + } + + if (check && !ObjectUtils.isEmpty(fileMetaVo)) { + ioFileDao.updateOneFileUrlValue(commonSource.getFileID(), JsonUtils.beanToJson(fileMetaVo)); + } + } + } + + @Async(value = "asyncTaskExecutor") + public void asyncAddSourceMeta(CommonSource source) { + List pyList = new ArrayList<>(); + pyList.add(new IOSourceMeta(source.getSourceID(), MetaEnum.namePinyin.getValue(), ChinesUtil.getPingYin(source.getName()))); + pyList.add(new IOSourceMeta(source.getSourceID(), MetaEnum.namePinyinSimple.getValue(), ChinesUtil.getFirstSpell(source.getName()))); + + if (!CollectionUtils.isEmpty(pyList)) { + // 拼音 + try { + ioSourceMetaDao.batchInsert(pyList); + } catch (Exception e) { + LogUtil.error(e, " setUserDefaultSource setSourcePinYin meta error pyList=" + JsonUtils.beanToJson(pyList)); + } + } + } + + @Async(value = "asyncTaskExecutor") + public void asyncAddSourceEvent(IoSourceEvent event) { + try { + ioSourceEventDao.insert(event); + } catch (Exception e) { + LogUtil.error(e, " addSourceEvent error paramList=" + JsonUtils.beanToJson(event)); + } + } + + @Async(value = "asyncTaskExecutor") + public void asyncAddSourceEventList(List list) { + try { + ioSourceEventDao.batchInsert(list); + } catch (Exception e) { + LogUtil.error(e, " addSourceEventList error paramList=" + JsonUtils.beanToJson(list)); + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncUnZipFileUtil.java b/src/main/java/com/svnlan/home/utils/AsyncUnZipFileUtil.java new file mode 100644 index 0000000..8e7e380 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncUnZipFileUtil.java @@ -0,0 +1,200 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.LogTypeEnum; +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.CompressFileDto; +import com.svnlan.home.dto.UploadDTO; +import com.svnlan.home.dto.convert.ConvertDTO; +import com.svnlan.home.service.BusTypeHandleService; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.utils.HttpUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/7/20 13:19 + */ +@Component +public class AsyncUnZipFileUtil { + + @Resource + ConvertUtil convertUtil; + + + @Async(value = "asyncTaskExecutor") + public void asyncUnZipFile(CommonSource commonSource, CheckFileDTO checkFileDTO, LoginUser loginUser, StringRedisTemplate stringRedisTemplate + , String finalFolderPath, List fileList, SystemLogTool systemLogTool, FileOptionTool fileOptionTool, BusTypeHandleService busTypeHandleService + , UploadDTO uploadDTO, CommonSource parentSource, List sourceNameList, Integer targetType, String serverUrl) { + + /** 解压整个文件 */ + CompressFileDto dto = CompressFileUtil.unzipFilePassword(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID() + , checkFileDTO.getPassword(), checkFileDTO.getTaskID(), true, stringRedisTemplate ); + if (ObjectUtils.isEmpty(dto) || !dto.getSuccess()){ + if (!ObjectUtils.isEmpty(checkFileDTO.getPassword())){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.unzipErrorTips.getCode()); + } + } + List convertList = new ArrayList<>(); + + + + LogUtil.info("unZip asyncUnZipFile parentSource=" + JsonUtils.beanToJson(parentSource)); + LogUtil.info("unZip asyncUnZipFile fileList=" + JsonUtils.beanToJson(fileList)); + + // 返回前端 + List sourceIds = new ArrayList<>(); + if (!ObjectUtils.isEmpty(parentSource) && !CollectionUtils.isEmpty(fileList)){ + List sourceFileVos = new ArrayList<>(); + List sourceDirVos = new ArrayList<>(); + for (ChangeSourceVo entry: fileList) { + if (entry.getIsFolder().intValue() == 1){ + if (entry.getFilePath().indexOf("//") >= 0){ + entry.setFilePath(entry.getFilePath().replaceAll("//","/")); + } + sourceDirVos.add(entry); + }else { + sourceFileVos.add(entry); + } + } + + Map parentMap = new HashMap<>(1); + parentMap.put(finalFolderPath, parentSource); + // 文件夹 + if (!CollectionUtils.isEmpty(sourceDirVos)){ + //finalFolderPath + sourceDirVos = sourceDirVos.stream().sorted(Comparator.comparing(ChangeSourceVo::getPathLength)).collect(Collectors.toList()); + for (ChangeSourceVo changeVo : sourceDirVos){ + String parentPath = changeVo.getFilePath().substring(0, changeVo.getFilePath().indexOf(changeVo.getName())); + if (parentMap.containsKey(parentPath)) { + CommonSource pSource = parentMap.get(parentPath); + CommonSource dir = new CommonSource(); + if (parentPath.equals(finalFolderPath)) { + dir.setName(fileOptionTool.checkRepeatName(changeVo.getName(), changeVo.getName(), sourceNameList, 1)); + }else { + dir.setName(changeVo.getName()); + } + dir.setParentID(pSource.getSourceID()); + dir.setParentLevel(pSource.getParentLevel() + pSource.getSourceID() + ","); + dir.setTargetType(targetType); + dir.setFileType(""); + dir.setSize(0L); + fileOptionTool.addIoSourceDetail(dir, loginUser.getUserID(), 0L, EventEnum.mkdir); + if (parentPath.equals(finalFolderPath)){ + sourceIds.add(dir.getSourceID()); + } + parentMap.put(changeVo.getFilePath(), dir); + } + } + } + + LogUtil.info("unZip asyncUnZipFile parentMap=" + JsonUtils.beanToJson(parentMap)); + LogUtil.info("unZip asyncUnZipFile sourceDirVos=" + JsonUtils.beanToJson(sourceDirVos)); + LogUtil.info("unZip asyncUnZipFile sourceFileVos=" + JsonUtils.beanToJson(sourceFileVos)); + + // 文件 + if (!CollectionUtils.isEmpty(sourceFileVos)){ + for (ChangeSourceVo changeVo : sourceFileVos){ + String parentPath ; + if (changeVo.getFilePath().equals(changeVo.getName())){ + parentPath = finalFolderPath; + }else { + parentPath = finalFolderPath + changeVo.getFilePath().substring(0, changeVo.getFilePath().indexOf(changeVo.getName())); + } + LogUtil.info("unZip asyncUnZipFile check=" + parentMap.containsKey(parentPath) + " parentPath=" + parentPath); + if (parentMap.containsKey(parentPath)) { + CommonSource pSource = parentMap.get(parentPath); + CommonSource fileSource = new CommonSource(); + if (parentPath.equals(finalFolderPath)) { + fileSource.setName(fileOptionTool.checkRepeatName(changeVo.getName(), changeVo.getName(), changeVo.getFileType(), sourceNameList, 1)); + }else { + fileSource.setName(changeVo.getName()); + } + fileSource.setParentID(pSource.getSourceID()); + fileSource.setParentLevel(pSource.getParentLevel() + pSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(changeVo.getFileType()); + fileSource.setSize(changeVo.getSize()); + fileSource.setHashMd5(changeVo.getHashMd5()); + fileSource.setPath(changeVo.getPath()); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + if (parentPath.equals(finalFolderPath)){ + sourceIds.add(fileSource.getSourceID()); + } + + if (ObjectUtils.isEmpty(changeVo.getHashMd5())) { + fileSource.setNeedHashMd5(1); + } + LogUtil.info("unZip asyncUnZipFile fileSource=" + JsonUtils.beanToJson(fileSource)); + if (Arrays.asList(GlobalConfig.VIDEO_AUDIO_TYPE_CONVERT).contains(changeVo.getFileType())){ + // 转码、图片加缩略图 + convertList.add(fileSource); + }else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(changeVo.getFileType())){ + // "cloud" + fileSource.setSourceType(2); + busTypeHandleService.doForImage(uploadDTO, false, fileSource); + if (!ObjectUtils.isEmpty(changeVo.getHashMd5())) { + convertList.add(fileSource); + } + } else { + if (!ObjectUtils.isEmpty(changeVo.getHashMd5())) { + convertList.add(fileSource); + } + } + } + } + } + } + + checkFileDTO.setSourceIds(sourceIds); + + stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + loginUser.getUserID(), 1, TimeUnit.MILLISECONDS); + + LogUtil.info("解压缩:转码:convertList=" + JsonUtils.beanToJson(convertList)); + // 视频转码 + if (!CollectionUtils.isEmpty(convertList)) { + for (CommonSource source : convertList) { + ConvertDTO convertDTO = new ConvertDTO(); + convertDTO.setBusId(source.getSourceID()); + convertDTO.setBusType("cloud"); + convertDTO.setOtherType("unZip"); + + source.setDomain(serverUrl); + convertDTO.setDomain(serverUrl); + convertUtil.doConvertMain(convertDTO, source); + } + } + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + reMap.put("type", "upload"); + reMap.put("pathName", commonSource.getName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileUpload.getCode(), paramList, null); + + } +} diff --git a/src/main/java/com/svnlan/home/utils/AsyncUtil.java b/src/main/java/com/svnlan/home/utils/AsyncUtil.java new file mode 100644 index 0000000..b64ea44 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/AsyncUtil.java @@ -0,0 +1,805 @@ +package com.svnlan.home.utils; + +import com.google.common.base.Joiner; +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.HomeExplorerDao; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.dao.IoSourceHistoryDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.domain.IoSourceHistory; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.SourceOpDto; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.home.dto.convert.ConvertDTO; +import com.svnlan.home.utils.video.VideoGetUtil; +import com.svnlan.home.utils.zip.ZipUtils; +import com.svnlan.home.vo.IOSourceVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.manage.dao.CommonInfoDao; +import com.svnlan.manage.domain.CommonSeo; +import com.svnlan.manage.dto.CommonInfoDto; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.dao.GroupSourceDao; +import com.svnlan.user.dao.SystemOptionDao; +import com.svnlan.user.domain.GroupSource; +import com.svnlan.user.vo.GroupSizeVo; +import com.svnlan.utils.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/12 13:06 + */ +@Component +public class AsyncUtil { + + @Resource + IoSourceDao ioSourceDao; + @Resource + SystemSortTool systemSortTool; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + HomeExplorerDao homeExplorerDao; + @Resource + GroupSourceDao groupSourceDao; + @Resource + IoSourceHistoryDao ioSourceHistoryDao; + @Resource + IoFileDao ioFileDao; + @Resource + CommonInfoDao commonInfoDao; + @Resource + SystemOptionDao systemOptionDao; + @Resource + ConvertUtil convertUtil; + @Resource + SourceHistoryUtil sourceHistoryUtil; + + @Value("${cdn.domain}") + private String cdnDomain; + @Value("${info.common.htmlPath.name}") + private String infoHtmlPath; + + /** + * @Description: 初始化装扮保存路径 + * @Modified: + */ + private String designBasePath; + private String pathDefault; + private String templatePath; + @PostConstruct + public void setDesignBasePath(){ + // 已改 + try { + Properties properties = PropertiesUtil.getConfig("upconfig.properties"); + pathDefault = properties.getProperty("home.path.default"); + designBasePath = properties.getProperty("home.savePath"); + templatePath = properties.getProperty("template.savePath"); + } catch (Exception e){ + designBasePath = "/uploads/design/home/"; + templatePath = "/uploads/design/template/"; + pathDefault = "/uploads"; + + } + } + + /** + * @Description: 文件压缩 + */ + @Async(value = "asyncTaskExecutor") + public void asyncZipFile(CheckFileDTO checkFileDTO, List copyListByLevel) { + long ms = System.currentTimeMillis(); + LogUtil.info(" asyncZipFile begin " + ms); + if (!Arrays.asList(GlobalConfig.ZIP_SHOW_TYPE_ARR).contains(checkFileDTO.getFileType())){ + LogUtil.error("asyncZipFile 压缩类型不正确checkFileDTO=" + JsonUtils.beanToJson(checkFileDTO)); + return; + } + + boolean isDown = false; + if (!ObjectUtils.isEmpty(checkFileDTO.getOperation()) && "down".equals(checkFileDTO.getOperation())){ + isDown = true; + } + + String finalFolderPath = checkFileDTO.getFinalFolderPath(); + // 存放复制文件的临时文件名 + String tempFolder = checkFileDTO.getTempFolder() ; + // 压缩包的路径及名称 + String finalFilePath = checkFileDTO.getFinalFilePath(); + + CommonSource commonSource = checkFileDTO.getCommonSource(); + + // 获取需要打包压缩的文件列表 + List sourceIDList = new ArrayList<>(); + List sourceLevelList = new ArrayList<>(); + for (SourceOpDto dto : checkFileDTO.getDataArr()) { + sourceIDList.add(dto.getSourceID()); + if ("folder".equals(dto.getType())) { + sourceLevelList.add(dto.getParentLevel() + dto.getSourceID() + ","); + } + } + List attachments = ioSourceDao.copySourcePathList(sourceIDList); + if (CollectionUtils.isEmpty(attachments)) { + throw new SvnlanRuntimeException(CodeMessageEnum.rptSelectTips.getCode()); + } + Map mainAttsMap = attachments.stream().collect(Collectors.toMap(IOSourceVo::getSourceID, Function.identity(), (v1, v2) -> v2)); + if (CollectionUtils.isEmpty(copyListByLevel) && !CollectionUtils.isEmpty(sourceLevelList)) { + copyListByLevel = ioSourceDao.copySourcePathListByLevel(sourceLevelList); + } + if (!CollectionUtils.isEmpty(copyListByLevel)) { + attachments.addAll(copyListByLevel); + } + // 按父类升序 + attachments = attachments.stream().sorted(Comparator.comparing(IOSourceVo::getParentLevel)).collect(Collectors.toList()); + + LogUtil.info("zip attachments=" + JsonUtils.beanToJson(attachments)); + // path结构 + List levelList = null; + List parentList = null; + Map pathMap = new HashMap<>(0); + pathMap.put(commonSource.getSourceID(), commonSource.getSourceName()); + for (IOSourceVo vo : attachments){ + if (1 == vo.getIsFolder()){ + pathMap.put(vo.getSourceID(), vo.getName()); + } + // 填充目录 + vo.setPathDisplay(systemSortTool.getSourcePathDisplay(vo.getParentLevel().replace(commonSource.getParentLevel()+ commonSource.getSourceID() + ",", ""), pathMap, levelList, parentList)); + } + + LogUtil.info("asyncZipFile attachments=" + JsonUtils.beanToJson(attachments)); + + /* 优化zip 按目录结构创建并复制文件 + ZipUtils.addFile(attachments, finalFolderPath + tempFolder + "/");*/ + // 按目录结构创建 + ZipUtils.addFileNew(attachments, finalFolderPath + tempFolder + "/"); + + long totalLength = 0; + for (IOSourceVo vo : attachments){ + if (0 == vo.getIsFolder()){ + totalLength = totalLength + vo.getSize(); + } + } + LogUtil.info("zipFile finalFilePath=" + finalFilePath + ",attachments=" + JsonUtils.beanToJson(attachments)); + /** 打包 */ + try { + + /* 优化zip 根据fileType创建不同压缩包 + switch (checkFileDTO.getFileType()){ + case "zip": + ZipUtils.toZip(finalFolderPath + tempFolder + "/", finalFilePath, false, true, stringRedisTemplate + , checkFileDTO.getTaskID(), totalLength); + break; + case "tar": + TarUtils.toZip(finalFolderPath + tempFolder + "/", finalFilePath, false, true); + break; + }*/ + + ZipUtils.toZipNewList(finalFolderPath + tempFolder + "/", finalFilePath, stringRedisTemplate + , checkFileDTO, true, attachments, mainAttsMap); + + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_zip_file + checkFileDTO.getTaskID(), "1", 20, TimeUnit.MINUTES); + }catch (Exception e){ + LogUtil.error(e); + stringRedisTemplate.delete(GlobalConfig.async_key_zip_file + checkFileDTO.getTaskID()); + } + // 修改属性 + + Long size = 0L; + String serverChecksum = ""; + //最终文件 + File finalFile = new File(finalFilePath); + FileInputStream fis = null; + try { + fis = new FileInputStream(finalFile); + serverChecksum = DigestUtils.md5DigestAsHex(fis); + size = finalFile.length(); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage(), " addSourceInfo 压缩文件失败"); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + if (size > 0 && !isDown){ + // 更新 + Map paramMap = new HashMap<>(5); + paramMap.put("size", size); + paramMap.put("fileSize", size); + paramMap.put("modifyUser", checkFileDTO.getUserID()); + paramMap.put("sourceID", checkFileDTO.getBusId()); + paramMap.put("fileID", checkFileDTO.getFileID()); + paramMap.put("hashMd5", serverChecksum); + + + IOSource sourceUpdate = new IOSource(); + sourceUpdate.setSize(size); + sourceUpdate.setModifyUser(checkFileDTO.getUserID()); + sourceUpdate.setSourceID(checkFileDTO.getBusId()); + sourceUpdate.setFileID(checkFileDTO.getFileID()); + sourceUpdate.setHashMd5(serverChecksum); + + // 修改文件source修改人、file文件大小 + try { + ioSourceDao.updateFileSize(sourceUpdate); + }catch (Exception e){ + LogUtil.error(e, " asyncZipFile updateFileSize error paramMap=" + JsonUtils.beanToJson(paramMap)); + } + try { + ioSourceDao.updateSourceModifyUser(sourceUpdate); + }catch (Exception e){ + LogUtil.error(e, " asyncZipFile updateSourceModifyUser error paramMap=" + JsonUtils.beanToJson(paramMap)); + } + // 修改上层文件夹size + updateMemory(size, 0L, checkFileDTO.getUserID(), checkFileDTO.getTargetType(), checkFileDTO.getParentLevel()); + } + stringRedisTemplate.opsForValue().set(GlobalConfig.progress_key_zip_file + checkFileDTO.getTaskID(), String.valueOf(100), 60, TimeUnit.SECONDS); + + try { + ZipUtils.deleteFile(new File(checkFileDTO.getTemp())); + }catch (Exception e){ + LogUtil.error(e,"taskAction 删除临时文件夹失败 "); + } + LogUtil.info(" asyncZipFile end" + (System.currentTimeMillis() - ms) + " ms. " + ms); + } + + + @Async(value = "asyncTaskExecutor") + public void asyncDeleteFileUpdateMemory (LoginUser loginUser, List copyList, List sourceIdList, List dList ) { + + LogUtil.info("deleteFileUpdateMemory copyList " + JsonUtils.beanToJson(copyList) + ",sourceIdList=" + JsonUtils.beanToJson(sourceIdList)); + + /** 获取企业云盘 */ + long uSize = 0; + long userID = loginUser.getUserID(); + // 更新容量 筛选出是否已经包含的文件 sourceIdList + List pList = null; + Set gList = new HashSet<>(); + List pSourceList = new ArrayList<>(); + Map groupSizeMap = new HashMap<>(1); + + for (CommonSource vo : copyList){ + if (vo.getSize() <= 0){ + continue; + } + pList = Arrays.asList(vo.getParentLevel().split(",")).stream().filter(n->!ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(pList) && !Collections.disjoint(pList, sourceIdList)){ + + LogUtil.info("deleteFileUpdateMemory CommonSource " + JsonUtils.beanToJson(vo) + ",isCheck=" + !Collections.disjoint(pList, sourceIdList) + ",pList=" + JsonUtils.beanToJson(pList)); + continue; + } + + pSourceList.add(vo); + + if (1 == vo.getTargetType().intValue()){ + uSize = uSize + vo.getSize(); + }else { + if (CollectionUtils.isEmpty(pList)){ + gList.add(vo.getSourceID()); + if (!ObjectUtils.isEmpty(groupSizeMap) && groupSizeMap.containsKey(vo.getSourceID())){ + groupSizeMap.put(vo.getSourceID(), groupSizeMap.get(vo.getSourceID()) + vo.getSize().longValue()); + }else { + groupSizeMap.put(vo.getSourceID(), vo.getSize()); + } + }else { + + gList.addAll(pList); + for (Long p : pList){ + if (!ObjectUtils.isEmpty(groupSizeMap) && groupSizeMap.containsKey(p)){ + groupSizeMap.put(p, groupSizeMap.get(p) + vo.getSize().longValue()); + }else { + groupSizeMap.put(p, vo.getSize()); + } + } + } + } + } + // 根据sourceID获取groupID + if (!ObjectUtils.isEmpty(groupSizeMap)) { + List allReList = groupSourceDao.getGroupSourceList(new ArrayList<>(gList)); + Map gsMap = allReList.stream().collect(Collectors.toMap(GroupSource::getSourceID, GroupSource::getGroupID, (v1, v2) -> v2)); + + try { + List gSource = new ArrayList<>(); + groupSizeMap.forEach((key,value)->{ + if (value > 0 && !ObjectUtils.isEmpty(gsMap) && gsMap.containsKey(key)) { + gSource.add(new GroupSizeVo(gsMap.get(key), value)); + } + }); + + if (!CollectionUtils.isEmpty(gSource)) { + LogUtil.info("deleteFileUpdateMemory batchUpdateGroupMemoryList gSource=" + JsonUtils.beanToJson(gSource)); + homeExplorerDao.batchUpdateGroupMemoryList(gSource); + } + } catch (Exception e) { + LogUtil.error(e, "更新 deleteFileUpdateMemory batchUpdateGroupMemoryList企业云盘 sources memory失败"); + } + } + + LogUtil.info("deleteFileUpdateMemory uSize=" + uSize+ ", copyList " + JsonUtils.beanToJson(copyList)); + if (uSize > 0) { + Map paramMap = new HashMap<>(2); + paramMap.put("memory", uSize); + paramMap.put("userID", userID); + LogUtil.info("deleteFileUpdateMemory updateSubtractUseUserMemory paramMap=" + JsonUtils.beanToJson(paramMap)); + try { + homeExplorerDao.updateSubtractUseUserMemory(paramMap); + } catch (Exception e) { + LogUtil.error(e, "更新 deleteFileUpdateMemory updateSubtractUseUserMemory 企业云盘 sources memory失败"); + } + } + // source updateSourceMemoryList + if (!CollectionUtils.isEmpty(pSourceList)) { + try { + List sourceList = new ArrayList<>(); + Map sourceSizeMap = new HashMap<>(); + for (CommonSource source : pSourceList) { + List sourceIds = Arrays.asList(source.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(sourceIds)) { + for (Long id : sourceIds) { + long size = (!ObjectUtils.isEmpty(sourceSizeMap) && sourceSizeMap.containsKey(id) ) ? sourceSizeMap.get(id) + source.getSize() : source.getSize(); + sourceSizeMap.put(id, size); + } + } + } + if(!ObjectUtils.isEmpty(sourceSizeMap)){ + IOSource vo = null; + for (Map.Entry entry : sourceSizeMap.entrySet()) { + if (!ObjectUtils.isEmpty(entry.getKey())){ + vo = new IOSource(entry.getKey(), entry.getValue()); + sourceList.add(vo); + } + } + } + if (!CollectionUtils.isEmpty(sourceList)) { + LogUtil.info("deleteFileUpdateMemory batchSubtractSourceMemoryList sourceList=" + JsonUtils.beanToJson(sourceList)); + ioSourceDao.batchSubtractSourceMemoryList(sourceList); + } + } catch (Exception e) { + LogUtil.error(e, " deleteFileUpdateMemory updateMemory error "); + } + } + + if (!CollectionUtils.isEmpty(dList)) { + for (IOSourceVo vo : dList) { + if (vo.getFileCount().intValue() == 1) { + try { + //删除文件 + new File(vo.getPath()).delete(); + LogUtil.info("deleteFileUpdateMemory path=" + vo.getPath()); + } catch (Exception e) { + LogUtil.error(e, "deleteFileUpdateMemory 删除文件失败"); + } + } + } + } + } + + @Async(value = "asyncTaskExecutor") + public void asyncUpdateFileMd5(String path) { + File f = new File(path); + //如果不是文件夹,数据流输出,生成文件 + String serverChecksum = ""; + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(f); + serverChecksum = DigestUtils.md5DigestAsHex(inputStream); + }catch (Exception e){ + LogUtil.error(e, "asyncUpdateFileMd5 error"); + }finally { + try { + if (null != inputStream){ + inputStream.close(); + } + }catch (Exception e){ + LogUtil.error(e, "asyncUpdateFileMd5 inputStream close error"); + } + } + + if (!ObjectUtils.isEmpty(serverChecksum)){ + ioFileDao.updateFileMd5ByPath(serverChecksum, path); + } + } + + @Async(value = "asyncTaskExecutor") + public void asyncAddSourceHistory(CommonSource commonSource, Long userID, Long fileID, Long size) { + + Long uid = userID; + IoSourceHistory orgHistory = ioSourceHistoryDao.getHistoryInfoByFileId(commonSource.getSourceID(), commonSource.getFileID()); + if (!ObjectUtils.isEmpty(orgHistory)){ + uid = orgHistory.getUserID(); + } + // 添加历史记录 sourceID, `userID`,`fileID`, `size`, `detail` + IoSourceHistory ioSourceHistory = new IoSourceHistory(); + ioSourceHistory.setSourceID(commonSource.getSourceID()); + ioSourceHistory.setUserID(uid); + ioSourceHistory.setFileID(fileID); + ioSourceHistory.setSize(size); + ioSourceHistory.setDetail(""); + // 添加历史记录 + try {// 保证size正确 + sourceHistoryUtil.changeCheckSourceHistory(new IoSourceHistory(commonSource.getSourceID(),commonSource.getFileID(),userID,commonSource.getSize()), ioSourceHistory); + } catch (Exception e) { + LogUtil.error(e, "添加历史记录失败 uploadDTO=" + JsonUtils.beanToJson(ioSourceHistory)); + } + } + + @Async(value = "asyncTaskExecutor") + public void genInformationPage(CommonInfoDto infoDto, LoginUser loginUser) { + List infoList = commonInfoDao.getSimpleInfoForSEO(infoDto.getInfoIdList()); + if (CollectionUtils.isEmpty(infoList)){ + LogUtil.error("资讯静态化, 资讯不存在, " + JsonUtils.beanToJson(infoDto) + "," + JsonUtils.beanToJson(loginUser)); + return; + } + this.handleSEO(infoList); + + //修改了detail + if (infoDto.getInfoIdList().size() == 1 && !StringUtil.isEmpty(infoDto.getDetail())) { + infoList.get(0).setDetail(infoDto.getDetail()); + infoList.get(0).setSingle(true); + } + LogUtil.info("资讯静态化 genInformationPage infoList=" + JsonUtils.beanToJson(infoList)); + + + this.saveForSEO(infoList); + try { + commonInfoDao.updateInfoGmtPage(infoList); + } catch (Exception e){ + LogUtil.error(e, "更新文件生成时间失败"); + } + } + + public void saveForSEO(List seoList) { + // /uploads/design/pubinfo/pc/pubinfo/30035.shtml + if (CollectionUtils.isEmpty(seoList)) { + return; + } + CommonSeo first = seoList.get(0); + + //是否链接,如果是链接,则不生成具体的页面内容,只作为承载页 + boolean isUrlInfo = (null != first.getIsUrlInfo() && first.getIsUrlInfo() == 1); + + String tempLatePath = templatePath + seoList.get(0).getTypeStr() +"/index.html"; + String mobileTempLatePath = templatePath + seoList.get(0).getTypeStr() + "/wap.html"; + String pcHtml = FileUtil.getFileContent(tempLatePath); + String mobileHtml = FileUtil.getFileContent(mobileTempLatePath); + String infoTip = "生成静态页," + JsonUtils.beanToJson(seoList) ; + + LogUtil.info(infoTip); + boolean isInformation = seoList.get(0).getTypeStr().equals("information"); + //资讯, 使用网校的keyword + String seoKeyword = ""; + if (isInformation){ + seoKeyword = systemOptionDao.getSystemConfigByKey("seo"); + } + //域名循环 + long timeTotal = System.currentTimeMillis(); + String blackMobileHtml = null; + + //客户端类型循环 + for (String clientType : GlobalConfig.DESIGN_WEB_CLIENT_TYPE_ARR) { + //String domainAndClientPath = infoHtmlPath + "/" + clientType; + //循环 + for (CommonSeo seo : seoList) { + + long time = System.currentTimeMillis(); + String html ; + //手机短视频, 背景黑色 + if (!ObjectUtils.isEmpty(seo.getInfoType()) && seo.getInfoType().equals("1") && clientType.equals("mb")){ + if (blackMobileHtml == null){ + blackMobileHtml = mobileHtml.replace("", ""); + blackMobileHtml = blackMobileHtml.replace("", ""); + } + html = blackMobileHtml; + } else { + html = clientType.equals("pc") ? pcHtml : mobileHtml; + } + if (!isUrlInfo ) { //并且非动态的 + if (!StringUtil.isEmpty(seo.getDetail())){ + html = html.replace("", this.handleDetail(seo)); + } + html = html.replace("", seo.getDescription()); + html = html.replace("", seo.getTitle()); + } + + //替换标题 + html = html.replaceFirst("(?<=)([\\s\\S]*?)(?=)", seo.getTitle()); + //替换seo + if (!seo.getKeyword().trim().equals("")) { + html = html.replaceFirst("(?<=)", StringUtil.isEmpty(seo.getKeyword()) ? seoKeyword : seo.getKeyword()); + } + if (!seo.getDescription().trim().equals("")) { + html = html.replaceFirst("(?<=)", seo.getDescription()); + } + + if (isUrlInfo) { //并且非动态的 + //如果是链接,将body标签中的内容替换为空 + String[] list = html.split("", 2); + if (list.length == 2 && list[0].length() > 0 && list[1].length() > 0) { + final int end = list[1].indexOf(""); + if (end >= 0) { + html = list[0] + "" + list[1].substring(end); + } + } + } + String pubPath = pathDefault + "/design/pubinfo/" + clientType + "/pubinfo/" + seo.getId() + ".shtml"; + + File file = null; + if (!ObjectUtils.isEmpty(pubPath)) { + file = new File(pubPath); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + FileUtil.putFileContent(pubPath, html); + } + LogUtil.info("saveForSeo单次时长, " + (System.currentTimeMillis() - time)); + } + } + LogUtil.info("saveForSeo总时长, " + (System.currentTimeMillis() - timeTotal) + + ", infoHtmlPath: " + infoHtmlPath + + ", seoSize: " + seoList.size()); + } + private void handleSEO(List seoList) { + for (CommonSeo commonSeo : seoList){ + if (!commonSeo.getSeoJson().equals("")){ + try { + CommonSeo seo = JsonUtils.jsonToBean(commonSeo.getSeoJson(), CommonSeo.class); + if (!StringUtil.isEmpty(seo.getKeyword())){ + commonSeo.setKeyword(seo.getKeyword()); + } else if (!StringUtil.isEmpty(seo.getSeoKeyword())){ + commonSeo.setKeyword(seo.getSeoKeyword()); + } + if (!StringUtil.isEmpty(seo.getDescription())){ + commonSeo.setDescription(seo.getDescription()); + } else if (!StringUtil.isEmpty(seo.getDescription())) { + commonSeo.setDescription(seo.getSeoDescription()); + } + } catch (Exception e){ + LogUtil.error(e, "seo 解析失败"); + } + } + } + } + private String handleDetail(CommonSeo seo) { + String detail = ""; + //资讯detail 存到一个文件 /uploads/design/home/filesbox/pc/information/__detail_30035__.txt + if (seo.getTypeStr().equals("information")) { + String detailFilePath = designBasePath + infoHtmlPath + "/pc/" + seo.getTypeStr() + "/__detail_" + seo.getId() + "__.txt"; + File file = new File(detailFilePath); + LogUtil.info("handleDetail detailFilePath=" + detailFilePath); + //如果是单个操作 + if (Boolean.TRUE.equals(seo.getSingle())){ + if (!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + FileUtil.putFileContent(detailFilePath, seo.getDetail()); + } else { + detail = FileUtil.getFileContent(file); + } + } + if (StringUtil.isEmpty(detail)){ + detail = seo.getDetail(); + } + return "\n
" + detail + "
"; + } + + + /** 删除临时的文件/文件夹*/ + @Async(value = "asyncTaskExecutor") + public void deleteDirOrFile(File file) { + if (file.isDirectory()) { + File[] subFiles = file.listFiles(); + if (subFiles != null) { + for (File subFile : subFiles) { + deleteDirOrFile(subFile); + } + } + if (file.exists()) + file.delete(); // 删除文件夹 + } else { + if (file.exists()) + file.delete(); + } + } + + /** + * @Description: 异步合并剪切的视频 + * @params: cutList 剪切的视频路径列表 + * @params: finishPath 合并完成的最终视频 + * @params: suffix 文件后缀 + * @params: tempPath temp路径 + */ + @Async(value = "asyncTaskExecutor") + public void cutVideoMerge(List cutList, String finishPath, String suffix, String tempPath, List convertList, String otherType + , FileOptionTool fileOptionTool, long userID) { + + List tsList = new ArrayList<>(); + boolean check = VideoGetUtil.cutVideoMerge(cutList, finishPath, suffix, tempPath, tsList); + + // 合并完再添加数据 + if ("cutVideo".equals(otherType) && !CollectionUtils.isEmpty(convertList) && convertList.size() == 1) { + CommonSource s = convertList.get(0); + s.setPath(finishPath); + try { + File f = new File(finishPath); + if (f.exists()){ + s.setSize(f.length()); + } + }catch (Exception e){ + } + fileOptionTool.addCommonSource(userID, s, EventEnum.mkfile); + convertList = new ArrayList<>(); + convertList.add(s); + } + + if (check && !CollectionUtils.isEmpty(convertList)){ + for (CommonSource source : convertList){ + ConvertDTO convertDTO = new ConvertDTO(); + convertDTO.setBusId(source.getSourceID()); + convertDTO.setBusType("cloud"); + convertDTO.setOtherType(otherType); + convertDTO.setDomain(source.getDomain()); + if (ObjectUtils.isEmpty(source.getPath())){ + source.setPath(finishPath); + } + convertUtil.doConvertMain(convertDTO, source); + } + } + + if (!ObjectUtils.isEmpty(tempPath)) { + File destinationFolder = new File(tempPath); + if (destinationFolder.exists()) { + // 异步删除文件或者文件夹 + deleteDirOrFile(destinationFolder); + } + } + + if (!CollectionUtils.isEmpty(tsList)){ + for (String p : tsList) { + File tsFile = new File(p); + // 删除文件 + if (tsFile.exists()) { + tsFile.delete(); + } + } + } + } + + /** + * @Description: 转码 + * @params: [path, finishPath, resolution, frameRate] + * @Return: void + * @Modified: + */ + @Async(value = "asyncTaskExecutor") + public void convertVideoMerge(VideoCommonDto videoCommonDto, List convertList) { + Boolean check = VideoGetUtil.convertVideoMerge(videoCommonDto.getVideoPathOrg(), videoCommonDto.getFinalFilePath(), videoCommonDto.getResolution(), videoCommonDto.getFrameRate()); + if (check && !CollectionUtils.isEmpty(convertList)){ + for (CommonSource source : convertList){ + ConvertDTO convertDTO = new ConvertDTO(); + convertDTO.setBusId(source.getSourceID()); + convertDTO.setBusType("cloud"); + convertDTO.setOtherType("convertVideo"); + source.setDomain(videoCommonDto.getServerUrl()); + convertDTO.setDomain(videoCommonDto.getServerUrl()); + convertUtil.doConvertMain(convertDTO, source); + } + } + } + + @Async(value = "asyncTaskExecutor") + public void settingVideo(VideoCommonDto videoCommonDto, List convertList) { + Boolean check = VideoGetUtil.configVideoMerge(videoCommonDto); + if (check && !CollectionUtils.isEmpty(convertList)){ + for (CommonSource source : convertList){ + ConvertDTO convertDTO = new ConvertDTO(); + convertDTO.setBusId(source.getSourceID()); + convertDTO.setBusType("cloud"); + convertDTO.setOtherType("settingVideo"); + source.setDomain(videoCommonDto.getServerUrl()); + convertDTO.setDomain(videoCommonDto.getServerUrl()); + convertUtil.doConvertMain(convertDTO, source); + } + } + } + + public void updateMemory(CommonSource commonSource) { + updateMemory(commonSource.getSize(), commonSource.getGroupID(), commonSource.getUserID(), commonSource.getTargetType(), commonSource.getParentLevel()); + } + + public void updateMemory(long size, long groupID, long userID, Integer targetType, String parentLevel) { + if (size > 0 && !ObjectUtils.isEmpty(targetType)) { + Map paramMap = new HashMap<>(2); + paramMap.put("groupID", groupID); + paramMap.put("memory", size); + paramMap.put("userID", userID); + LogUtil.info("updateMemory paramMap=" + JsonUtils.beanToJson(paramMap) + ",targetType=" + targetType + ", parentLevel=" + parentLevel); + try { + if (targetType.intValue() == 1) { + homeExplorerDao.updateUserMemory(paramMap); + } else { + if (!ObjectUtils.isEmpty(parentLevel)) { + this.updateGroupMemoryCopyBySearch(paramMap, parentLevel); + }else if(groupID > 0){ + this.updateGroupMemoryCopy(paramMap, groupID); + }else { + LogUtil.error("更新企业云盘云盘memory 失败 groupID=" + groupID + ",parentLevel=" + parentLevel); + } + } + } catch (Exception e) { + LogUtil.error(e, "更新 企业云盘 memory失败"); + } + // source updateSourceMemoryList + if (!ObjectUtils.isEmpty(parentLevel)) { + try { + List sourceIds = Arrays.asList(parentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(sourceIds)) { + ioSourceDao.updateSourceMemoryList(sourceIds, size); + } + } catch (Exception e) { + LogUtil.error(e, " updateMemory updateSourceMemoryList error "); + } + + } + } + } + + public void updateGroupMemoryCopyBySearch(Map paramMap, String parentLevel) { + List sourcePIDs = Arrays.asList(parentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)) + .map(Long::parseLong).collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(sourcePIDs)){ + return; + } + List gpList = homeExplorerDao.getGroupParentLevelList(sourcePIDs); + if (CollectionUtils.isEmpty(gpList)){ + return; + } + String groupParentLevel = Joiner.on(",").join(gpList); + List groupIDs = Arrays.asList(groupParentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)) + .map(Long::parseLong).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(groupIDs)){ + return; + } + paramMap.put("list", groupIDs); + homeExplorerDao.updateMemoryList(paramMap); + } + public void updateGroupMemoryCopy(Map paramMap, Long groupID) { + String groupParentLevel = homeExplorerDao.getGroupParentLevel(groupID); + List groupIDs = Arrays.asList(groupParentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)) + .map(Long::parseLong).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(groupIDs)) { + groupIDs = new ArrayList<>(); + } + groupIDs.add(groupID); + paramMap.put("list", groupIDs); + homeExplorerDao.updateMemoryList(paramMap); + } + +} diff --git a/src/main/java/com/svnlan/home/utils/CommonConvertUtil.java b/src/main/java/com/svnlan/home/utils/CommonConvertUtil.java new file mode 100644 index 0000000..4f19543 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/CommonConvertUtil.java @@ -0,0 +1,63 @@ +package com.svnlan.home.utils; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dto.GetM3u8NewDTO; +import com.svnlan.home.dto.GetMyM3u8DTO; +import com.svnlan.jwt.constant.SystemConstant; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.LoginUserUtil; +import com.svnlan.utils.StringUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import javax.servlet.http.HttpServletRequest; + + +/** + * @Author: sulijuan + * @Description: + * @Date: 2020/9/7 10:17 + */ +@Component +public class CommonConvertUtil { + + public GetM3u8NewDTO convertGetM3u8NewDTO(GetMyM3u8DTO getMyM3u8DTO){ + GetM3u8NewDTO dto = new GetM3u8NewDTO(); + String sourceType = getMyM3u8DTO.getSourceType(); + if (!ObjectUtils.isEmpty(sourceType)){ + dto.setSourceType(sourceType); + } + String sourceIdStr = getMyM3u8DTO.getSourceID(); + if (!ObjectUtils.isEmpty(sourceIdStr)){ + if (!StringUtil.isNumeric(sourceIdStr)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + dto.setSourceID(Long.valueOf(sourceIdStr)); + } + String isCamera = getMyM3u8DTO.getIsCamera(); + if (!ObjectUtils.isEmpty(isCamera)){ + if (!StringUtil.isNumeric(isCamera)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + dto.setIsCamera(Integer.valueOf(isCamera)); + } + String isReview = getMyM3u8DTO.getIsReview(); + if (!ObjectUtils.isEmpty(isReview)){ + if (!StringUtil.isNumeric(isReview)){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + dto.setIsReview(Integer.valueOf(isReview)); + } + String key = getMyM3u8DTO.getKey(); + if (!ObjectUtils.isEmpty(key)){ + dto.setKey(key); + } + return dto; + } + + public LoginUser getApiLoginUser(HttpServletRequest request, String token, LoginUserUtil loginUserUtil){ + + return loginUserUtil.getLoginUserByToken(request, token); + } +} diff --git a/src/main/java/com/svnlan/home/utils/CompressFileReader.java b/src/main/java/com/svnlan/home/utils/CompressFileReader.java new file mode 100644 index 0000000..c20792d --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/CompressFileReader.java @@ -0,0 +1,729 @@ +package com.svnlan.home.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.junrar.Archive; +import com.github.junrar.exception.RarException; +import com.github.junrar.rarfile.FileHeader; +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.domain.FileHeaderRar; +import com.svnlan.home.utils.zip.FileType; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import net.sf.sevenzipjbinding.*; +import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; +import net.sf.sevenzipjbinding.simple.ISimpleInArchive; +import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.io.*; +import java.math.BigDecimal; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.text.CollationKey; +import java.text.Collator; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author + * create + */ +@Component +public class CompressFileReader { + + private static final Pattern pattern = Pattern.compile("^\\d+"); + private final ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + private final String fileDir = ConfigUtils.getHomePath() + File.separator + "file" + File.separator; + + public static byte[] getUTF8BytesFromGBKString(String gbkStr) { + int n = gbkStr.length(); + byte[] utfBytes = new byte[3 * n]; + int k = 0; + for (int i = 0; i < n; i++) { + int m = gbkStr.charAt(i); + if (m < 128 && m >= 0) { + utfBytes[k++] = (byte) m; + continue; + } + utfBytes[k++] = (byte) (0xe0 | (m >> 12)); + utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f)); + utfBytes[k++] = (byte) (0x80 | (m & 0x3f)); + } + if (k < utfBytes.length) { + byte[] tmp = new byte[k]; + System.arraycopy(utfBytes, 0, tmp, 0, k); + return tmp; + } + return utfBytes; + } + + public String getUtf8String(String str) { + if (str != null && str.length() > 0) { + String needEncodeCode = "ISO-8859-1"; + String neeEncodeCode = "ISO-8859-2"; + String gbkEncodeCode = "GBK"; + try { + if (Charset.forName(needEncodeCode).newEncoder().canEncode(str)) { + str = new String(str.getBytes(needEncodeCode), StandardCharsets.UTF_8); + } + if (Charset.forName(neeEncodeCode).newEncoder().canEncode(str)) { + str = new String(str.getBytes(neeEncodeCode), StandardCharsets.UTF_8); + } + if (Charset.forName(gbkEncodeCode).newEncoder().canEncode(str)) { + str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + return str; + } + /** + * 判断是否是中日韩文字 + */ + private static boolean isChinese(char c) { + Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); + if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A + || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION + || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION + || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { + return true; + } + return false; + } + public static boolean judge(char c){ + if((c >='0' && c<='9')||(c >='a' && c<='z' || c >='A' && c<='Z')){ + return true; + } + return false; + } + public static boolean isMessyCode(String strName) { + //去除字符串中的空格 制表符 换行 回车 + Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*"); + Matcher m = p.matcher(strName); + String after = m.replaceAll("").replaceAll("\\+", "").replaceAll("#", "").replaceAll("&", ""); + //去除字符串中的标点符号 + String temp = after.replaceAll("\\p{P}", ""); + //处理之后转换成字符数组 + char[] ch = temp.trim().toCharArray(); + for (int i = 0; i < ch.length; i++) { + char c = ch[i]; + //判断是否是数字或者英文字符 + if (!judge(c)) { + //判断是否是中日韩文 + if (!isChinese(c)) { + //如果不是数字或者英文字符也不是中日韩文则表示是乱码返回true + return true; + } + } + } + //表示不是乱码 返回false + return false; + } + + public String unRar(String filePath, String fileKey, String baseUrl) { + LogUtil.info("unRar filePath=" + filePath); + Map appender = new HashMap<>(); + //List imgUrls = new ArrayList<>(); + try { + Boolean isEncrypted = false; + List items = new ArrayList<>(); + isEncrypted = getRar4Paths(filePath, items); + + LogUtil.info("unRar isEncrypted=" + isEncrypted + ",items=" + JsonUtils.beanToJson(items)); + //items = getRar4Paths2(filePath); + if (!CollectionUtils.isEmpty(items)){ + items = items.stream().sorted(Comparator.comparing(FileHeaderRar::getFileNameW)) + .collect(Collectors.toList()); + } + String archiveFileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1); + //List> headersToBeExtract = new ArrayList<>(); + // 根目录 + for (FileHeaderRar header : items) { + String fullName = header.getFileNameW().replaceAll(GlobalConfig.separator,"/"); + String originName = getLastFileName(fullName); + String childName = originName; + boolean directory = header.getDirectory(); + //FileType type = null; + if (!directory) { + childName = archiveFileName + "_" + fullName.replaceAll(GlobalConfig.separator,"_").replaceAll("/", "_"); + //headersToBeExtract.add(Collections.singletonMap(childName, header)); + // type = FileType.typeFromUrl(childName); + }else { + // type = FileType.FOLDER; + } + String parentName = getLast2FileName(fullName, archiveFileName); + /*if (type.equals(FileType.PICTURE)) { + imgUrls.add(baseUrl + childName); + }*/ + FileNode node = + new FileNode(originName, childName, parentName, new ArrayList<>(), directory, fileKey, fullName, header.getSize(), header.getEncrypted(), header.getIndex()); + addNodes(appender, parentName, node, archiveFileName, fullName, fileKey, isEncrypted, 0); + appender.put(childName, node); + } + LogUtil.info("unRar appender=" + JsonUtils.beanToJson(appender)); + //executors.submit(new RarExtractorWorker(headersToBeExtract, filePath)); + return new ObjectMapper().writeValueAsString(appender.get("")); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public Boolean getRar4Paths(String paths, List itemPath) { + RandomAccessFile randomAccessFile = null; + IInArchive inArchive = null; + + boolean isEncrypted = false; + try { + randomAccessFile = new RandomAccessFile(paths, "r"); + LogUtil.info("unRar getRar4Paths randomAccessFile" ); + inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile)); + LogUtil.info("unRar getRar4Paths openInArchive"); + String firstPath = FileUtil.getFirstStorageDevicePath(paths); + //String folderName = paths.substring(paths.lastIndexOf(File.separator) + 1); + String extractPath = paths.substring(0, paths.lastIndexOf(".") ) + GlobalConfig.separatorTO; + extractPath = extractPath.replace(firstPath + "/private", firstPath + "/common/down_temp"); + + LogUtil.info("unRar getRar4Paths extractPath=" + extractPath); + File extractPathFile = new File(extractPath); + if (!extractPathFile.exists()) { + extractPathFile.mkdirs(); + } + + ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); + int i = 0; + for (final ISimpleInArchiveItem o : simpleInArchive.getArchiveItems()) { + try { + String path = getUtf8String(o.getPath()); + if (isMessyCode(path)){ + path = new String(o.getPath().getBytes(StandardCharsets.ISO_8859_1), "GBK"); + } + LogUtil.info("unRar getRar4Paths path=" + path); + if (!isEncrypted && !o.isFolder()){ + if (Boolean.TRUE.equals(inArchive.getProperty(i,PropID.ENCRYPTED))) { + LogUtil.info("unRar getRar4Paths isEncrypted is true"); + isEncrypted = true; + break; + } + } + itemPath.add(new FileHeaderRar(path, o.isFolder(), o.getSize(), o.getItemIndex(), isEncrypted)); + i ++; + } catch (SevenZipException e) { + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + } catch (Exception e) { + LogUtil.error(e, "unRar getRar4Paths Error occurs: " + e); + } finally { + if (inArchive != null) { + try { + inArchive.close(); + } catch (SevenZipException e) { + LogUtil.error(e, "unRar getRar4Paths Error closing archive: " + e); + } + } + if (randomAccessFile != null) { + try { + randomAccessFile.close(); + } catch (IOException e) { + LogUtil.error(e, "unRar getRar4Paths Error closing file: " + e); + } + } + } + return isEncrypted; + } + + public List getRar4Paths2(String paths) { + RandomAccessFile randomAccessFile = null; + IInArchive inArchive = null; + List itemPath = null; + try { + randomAccessFile = new RandomAccessFile(paths, "r"); + + inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile)); + Object a = inArchive.getProperty(0,PropID.ENCRYPTED); + LogUtil.info("是否需要密码" + a ); + String folderName = paths.substring(paths.lastIndexOf(File.separator) + 1); + String extractPath = paths.substring(0, paths.lastIndexOf(".") ) + GlobalConfig.separatorTO; + String firstPath = FileUtil.getFirstStorageDevicePath(paths); + extractPath = extractPath.replace(firstPath + "/private", firstPath + "/common/down_temp"); + inArchive.extract(null, false, new ExtractCallback(inArchive, extractPath, folderName + "_")); + ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); + itemPath = Arrays.stream(simpleInArchive.getArchiveItems()).map(o -> { + try { + String path = getUtf8String(o.getPath()); + if (isMessyCode(path)){ + path = new String(o.getPath().getBytes(StandardCharsets.ISO_8859_1), "GBK"); + } + return new FileHeaderRar(path, o.isFolder(), o.getSize()); + } catch (SevenZipException e) { + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + }) + .collect(Collectors.toList()) + .stream() + .sorted(Comparator.comparing(FileHeaderRar::getFileNameW)) + .collect(Collectors.toList()); + } catch (Exception e) { + LogUtil.error(e, "getRar4Paths Error occurs: " + e); + } finally { + if (inArchive != null) { + try { + inArchive.close(); + } catch (SevenZipException e) { + LogUtil.error(e, "getRar4Paths Error closing archive: " + e); + } + } + if (randomAccessFile != null) { + try { + randomAccessFile.close(); + } catch (IOException e) { + LogUtil.error(e, "getRar4Paths Error closing file: " + e); + } + } + } + return itemPath; + } + + /** 原始压缩包名称 archiveFileName */ + private void addNodes(Map appender, String parentName, FileNode node, String archiveFileName + , String fullName, String fileKey, Boolean isEncrypted, Integer index) { + if (appender.containsKey(parentName)) { + appender.get(parentName).getChildList().add(node); + appender.get(parentName).getChildList().sort(sortComparator); + } else { + if (!ObjectUtils.isEmpty(appender)){ + fileProberParent(appender, parentName, node, archiveFileName + , fullName, fileKey, isEncrypted, index); + }else { + // 根节点 + if (archiveFileName.equals(parentName)) { + FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true, isEncrypted, index); + nodeRoot.getChildList().add(node); + appender.put("", nodeRoot); + appender.put(parentName, nodeRoot); + }else { + FileNode nodeRoot = new FileNode(archiveFileName, archiveFileName, "", new ArrayList<>(), true, isEncrypted, index); + fileProberParentRoot(appender, parentName, node, archiveFileName + , fullName, fileKey, isEncrypted, index, nodeRoot); + } + } + } + } + + private static void fileProberParentRoot(Map appender, String parentName, FileNode node, String archiveFileName + , String fullName, String fileKey, Boolean isEncrypted, Integer index, FileNode nodeRoot) { + + List parentList = Arrays.asList(fullName.split(GlobalConfig.separator)).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + if (fullName.indexOf("/") >= 0){ + parentList = Arrays.asList(fullName.split(GlobalConfig.separatorTO)).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + } + if (!CollectionUtils.isEmpty(parentList)){ + LogUtil.info("fileProberParent archiveFileName="+archiveFileName+" appender=" + JsonUtils.beanToJson(appender)); + LogUtil.info("fileProberParent fullName="+fullName+" parentList=" + JsonUtils.beanToJson(parentList)); + + int i = 0; + StringBuilder sb = new StringBuilder(); + for (String parent : parentList) { + sb.append(parent + "/"); + if (parent.endsWith(FileType.suffixFromFileName(node.getOriginName()))) { + appender.get(parentName).getChildList().add(node); + appender.get(parentName).getChildList().sort(sortComparator); + continue; + } + if (appender.containsKey(parent)) { + i++; + continue; + } + FileNode node1 = + new FileNode(parent, parent, i == 0 ? archiveFileName : parentList.get(i - 1), new ArrayList<>(), true, fileKey, sb.toString(), 0L, isEncrypted, index); + if (i == 0){ + nodeRoot.getChildList().add(node1); + appender.put("", nodeRoot); + appender.put(archiveFileName, nodeRoot); + } + appender.put(parent, node1); + if (i > 0) { + appender.get(node1.getParentFileName()).getChildList().add(node1); + appender.get(node1.getParentFileName()).getChildList().sort(sortComparator); + } + i++; + } + } + } + private static void fileProberParent(Map appender, String parentName, FileNode node, String archiveFileName + , String fullName, String fileKey, Boolean isEncrypted, Integer index) { + + List parentList = Arrays.asList(fullName.split(GlobalConfig.separator)).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + if (fullName.indexOf("/") >= 0){ + parentList = Arrays.asList(fullName.split(GlobalConfig.separatorTO)).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + } + if (!CollectionUtils.isEmpty(parentList)){ + + LogUtil.info("fileProberParent archiveFileName="+archiveFileName+" appender=" + JsonUtils.beanToJson(appender)); + LogUtil.info("fileProberParent fullName="+fullName+" parentList=" + JsonUtils.beanToJson(parentList)); + if (parentList.size() == 1 && node.directory){ + appender.get("").getChildList().add(node); + appender.get("").getChildList().sort(sortComparator); + }else { + int i = 0; + StringBuilder sb = new StringBuilder(); + for (String parent : parentList) { + sb.append(parent + "/"); + if (parent.endsWith(FileType.suffixFromFileName(node.getOriginName()))) { + appender.get(parentName).getChildList().add(node); + appender.get(parentName).getChildList().sort(sortComparator); + continue; + } + if (appender.containsKey(parent)) { + i++; + continue; + } + FileNode node1 = + new FileNode(parent, parent, i == 0 ? archiveFileName : parentList.get(i - 1), new ArrayList<>(), true, fileKey, sb.toString(), 0L, isEncrypted, index); + appender.put(parent, node1); + appender.get(node1.getParentFileName()).getChildList().add(node1); + appender.get(node1.getParentFileName()).getChildList().sort(sortComparator); + i++; + } + } + } + } + + + private static String getLast2FileName(String fullName, String rootName) { + String split = File.separator; + + if (fullName.indexOf(File.separator) < 0 && fullName.indexOf(GlobalConfig.separatorTO) >= 0) { + split = GlobalConfig.separatorTO; + } + if (fullName.endsWith(split)) { + fullName = fullName.substring(0, fullName.length() - 1); + } + // 1.获取剩余部分 + int endIndex = fullName.lastIndexOf(split); + String leftPath = fullName.substring(0, endIndex == -1 ? 0 : endIndex); + if (leftPath.length() > 1) { + // 2.获取倒数第二个 + return getLastFileName(leftPath); + } else { + return rootName; + } + } + + private static String getLastFileName(String fullName) { + String split = File.separator; + + if (fullName.indexOf(File.separator) < 0 && fullName.indexOf(GlobalConfig.separatorTO) >= 0) { + split = GlobalConfig.separatorTO; + } + if (fullName.endsWith(split)) { + fullName = fullName.substring(0, fullName.length() - 1); + } + String newName = fullName; + if (fullName.contains(split)) { + newName = fullName.substring(fullName.lastIndexOf(split) + 1); + } + return newName; + } + + public static Comparator sortComparator = new Comparator() { + final Collator cmp = Collator.getInstance(Locale.US); + + @Override + public int compare(FileNode o1, FileNode o2) { + // 判断两个对比对象是否是开头包含数字,如果包含数字则获取数字并按数字真正大小进行排序 + BigDecimal num1, num2; + if (null != (num1 = isStartNumber(o1)) + && null != (num2 = isStartNumber(o2))) { + return num1.subtract(num2).intValue(); + } + CollationKey c1 = cmp.getCollationKey(o1.getOriginName()); + CollationKey c2 = cmp.getCollationKey(o2.getOriginName()); + return cmp.compare(c1.getSourceString(), c2.getSourceString()); + } + }; + + private static BigDecimal isStartNumber(FileNode src) { + Matcher matcher = pattern.matcher(src.getOriginName()); + if (matcher.find()) { + return new BigDecimal(matcher.group()); + } + return null; + } + + public static class FileNode { + + private String originName; + private String fileName; + private String parentFileName; + private String fullName; + private Long size; + private boolean directory; + //用于图片预览时寻址 + private String fileKey; + private List childList; + private Boolean encrypted; + private Integer index; + + public FileNode(){} + + public FileNode(String originName, String fileName, String parentFileName, List childList, boolean directory, Boolean encrypted, Integer index) { + this.originName = originName; + this.fileName = fileName; + this.parentFileName = parentFileName; + this.childList = childList; + this.directory = directory; + this.encrypted = encrypted; + this.index = index; + } + + public FileNode(String originName, String fileName, String parentFileName, List childList, boolean directory, String fileKey + , String fullName, Long size, Boolean encrypted, Integer index) { + this.originName = originName; + this.fileName = fileName; + this.parentFileName = parentFileName; + this.childList = childList; + this.directory = directory; + this.fileKey = fileKey; + this.fullName = fullName; + this.size = size; + this.encrypted = encrypted; + this.index = index; + } + + public Boolean getEncrypted() { + return encrypted; + } + + public void setEncrypted(Boolean encrypted) { + this.encrypted = encrypted; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getFileKey() { + return fileKey; + } + + public void setFileKey(String fileKey) { + this.fileKey = fileKey; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getParentFileName() { + return parentFileName; + } + + public void setParentFileName(String parentFileName) { + this.parentFileName = parentFileName; + } + + public List getChildList() { + return childList; + } + + public void setChildList(List childList) { + this.childList = childList; + } + + @Override + public String toString() { + try { + return new ObjectMapper().writeValueAsString(this); + } catch (JsonProcessingException e) { + e.printStackTrace(); + return ""; + } + } + + public String getOriginName() { + return originName; + } + + public void setOriginName(String originName) { + this.originName = originName; + } + + public boolean isDirectory() { + return directory; + } + + public void setDirectory(boolean directory) { + this.directory = directory; + } + } + + class RarExtractorWorker implements Runnable { + private final List> headersToBeExtracted; + + private final List> headersToBeExtract; + + private final Archive archive; + /** + * 用以删除源文件 + */ + private final String filePath; + + public RarExtractorWorker( + List> headersToBeExtracted, Archive archive, String filePath) { + this.headersToBeExtracted = headersToBeExtracted; + this.archive = archive; + this.filePath = filePath; + headersToBeExtract = null; + } + + public RarExtractorWorker( + List> headersToBeExtract, String filePath) { + this.headersToBeExtract = headersToBeExtract; + this.filePath = filePath; + archive = null; + headersToBeExtracted = null; + } + + @Override + public void run() { + for (Map entryMap : headersToBeExtracted) { + String childName = entryMap.keySet().iterator().next(); + extractRarFile(childName, entryMap.values().iterator().next(), archive); + } + try { + archive.close(); + } catch (IOException e) { + e.printStackTrace(); + } + //KkFileUtils.deleteFileByPath(filePath); + } + + private void extractRarFile(String childName, FileHeader header, Archive archive) { + String outPath = fileDir + childName; + try (OutputStream ot = new FileOutputStream(outPath)) { + archive.extractFile(header, ot); + } catch (IOException | RarException e) { + e.printStackTrace(); + } + } + } + + + + + private static class ExtractCallback implements IArchiveExtractCallback { + private final IInArchive inArchive; + + private final String extractPath; + private final String folderName; + + public ExtractCallback(IInArchive inArchive, String extractPath, String folderName) { + this.inArchive = inArchive; + if (!extractPath.endsWith("/") && !extractPath.endsWith("\\")) { + extractPath += File.separator; + } + this.extractPath = extractPath; + this.folderName = folderName; + } + + @Override + public void setTotal(long total) { + + } + + @Override + public void setCompleted(long complete) { + + } + + @Override + public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException { + String filePath = inArchive.getStringProperty(index, PropID.PATH); + String real = folderName + filePath.replaceAll(GlobalConfig.separator,"_").replaceAll("/", "_"); + + LogUtil.info("getStream-----------------filePath=" + (filePath)); + LogUtil.info("getStream-----------------extractPath=" + (extractPath)); + LogUtil.info("getStream-----------------real=" + (real)); + File f = new File(extractPath + real); + f.delete(); + return data -> { + FileOutputStream fos = null; + try { + File path = new File(extractPath + real); + if (!path.getParentFile().exists()) { + path.getParentFile().mkdirs(); + } + if (!path.exists()) { + path.createNewFile(); + } + fos = new FileOutputStream(path, true); + fos.write(data); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.flush(); + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return data.length; + }; + } + + @Override + public void prepareOperation(ExtractAskMode extractAskMode) { + + } + + @Override + public void setOperationResult(ExtractOperationResult extractOperationResult) { + } + } + +} diff --git a/src/main/java/com/svnlan/home/utils/CompressFileUtil.java b/src/main/java/com/svnlan/home/utils/CompressFileUtil.java new file mode 100644 index 0000000..582585a --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/CompressFileUtil.java @@ -0,0 +1,547 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.FileHeaderRar; +import com.svnlan.home.dto.CompressFileDto; +import com.svnlan.home.utils.zip.UnBz2Utils; +import com.svnlan.home.utils.zip.UnRarUtils; +import com.svnlan.home.utils.zip.UnTarUtils; +import com.svnlan.home.utils.zip.UnZipUtils; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import net.sf.sevenzipjbinding.*; +import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; +import net.sf.sevenzipjbinding.simple.ISimpleInArchive; +import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.text.NumberFormat; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/26 13:32 + */ +@Component +public class CompressFileUtil { + + + /** 解压整个压缩包 */ + public static void compressFileBySource(CommonSource commonSource, String finalFolderPath, List fileList, LoginUser loginUser, String password){ + try { + + // 根据fileType解压 + switch (commonSource.getFileType()){ + case "zip": + UnZipUtils.decompress(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID()); + break; + case "tar": + UnTarUtils.decompress(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID()); + break; + case "bz2": + UnBz2Utils.decompress(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID()); + break; + case "rar": + UnRarUtils.decompress(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID()); + break; + case "gzip": + case "7z": + case "gz": + case "iso": + case "ar": + case "bz": + case "xz": + case "arj": + default: + /** 解压整个文件 */ + CompressFileDto dto = CompressFileUtil.unzipFilePassword(commonSource.getPath(), finalFolderPath, fileList, loginUser.getUserID(), password + , "", false, null); + if (ObjectUtils.isEmpty(dto) || !dto.getSuccess()){ + if (!ObjectUtils.isEmpty(password)){ + throw new SvnlanRuntimeException(CodeMessageEnum.errorPwd.getCode()); + }else { + throw new SvnlanRuntimeException(CodeMessageEnum.unzipErrorTips.getCode()); + } + } + break; + } + + } catch (Exception e) { + LogUtil.error(e, "unZip decompress 解压error."); + } + + } + + /** + * @Description: + * @params: [sourceZipFile 压缩包文件, extractPath 解压路径, password 密码, index ] + * @Return: com.svnlan.home.dto.CompressFileDto + * @Author: sulijuan + * @Modified: + */ + public static CompressFileDto unzipOneFilePassword(String sourceZipFile, String filePath, final String password, int index) { + CompressFileDto dto = null; + RandomAccessFile randomAccessFile = null; + IInArchive inArchive = null; + try { + randomAccessFile = new RandomAccessFile(sourceZipFile, "r"); + if (!ObjectUtils.isEmpty(password) && password.length() > 0) { + inArchive = SevenZip.openInArchive(null, + new RandomAccessFileInStream(randomAccessFile), password); + }else { + inArchive = SevenZip.openInArchive(null, + new RandomAccessFileInStream(randomAccessFile)); + } + ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); + dto = unzipOneFilePassword(simpleInArchive, filePath, password, index); + } catch (Exception e) { + dto = new CompressFileDto(); + dto.setSuccess(false); + dto.setStatus(0); + e.printStackTrace(); + LogUtil.error(e, " getSimpleInArchiveByPath Exception : " + e); + } finally { + if (inArchive != null) { + try { + inArchive.close(); + } catch (SevenZipException e) { + LogUtil.error(e, "Error closing archive: " + e); + e.printStackTrace(); + } + } + if (randomAccessFile != null) { + try { + randomAccessFile.close(); + } catch (IOException e) { + LogUtil.error(e, "Error closing file " ); + e.printStackTrace(); + } + } + } + return dto; + } + public static CompressFileDto unzipOneFilePassword(ISimpleInArchive simpleInArchive, String filePath, final String password, int index) { + + CompressFileDto dto = new CompressFileDto(); + dto.setSuccess(true); + dto.setStatus(1); + if (ObjectUtils.isEmpty(simpleInArchive)){ + dto.setSuccess(false); + dto.setStatus(0); + return dto; + } + try { + // 存在则返回 + File file = new File(filePath); + if (file.exists()) { + file.delete(); + } + ISimpleInArchiveItem item = simpleInArchive.getArchiveItem(index); + String path = getUtf8String(item.getPath()); + if (isMessyCode(path)){ + path = new String(item.getPath().getBytes(StandardCharsets.ISO_8859_1), "GBK"); + } + final int[] hash = new int[]{0}; + if (!item.isFolder()) { + ExtractOperationResult result; + final long[] sizeArray = new long[1]; + + //被解压的文件 + OutputStream out = new FileOutputStream(filePath); + if (!ObjectUtils.isEmpty(password) && password.length() > 0) { + //如果文件很大用这个方法可以解压完整,当然文件小用这个也没毛病 + result = item.extractSlow(new ISequentialOutStream() { + @Override + public int write(final byte[] data) throws SevenZipException { + try { + out.write(data); + } catch (Exception e) { + e.printStackTrace(); + } + hash[0] |= Arrays.hashCode(data); + sizeArray[0] += data.length; + return data.length; + } + }, password); + }else { + + //如果文件很大用这个方法可以解压完整,当然文件小用这个也没毛病 + result = item.extractSlow(new ISequentialOutStream() { + @Override + public int write(final byte[] data) throws SevenZipException { + try { + out.write(data); + } catch (Exception e) { + e.printStackTrace(); + } + hash[0] |= Arrays.hashCode(data); + sizeArray[0] += data.length; + return data.length; + } + }); + } + out.close(); + + if (result == ExtractOperationResult.OK) { + LogUtil.info("unzipOneFilePassword success " + String.format("%9X | %10s | %s", // + hash[0], sizeArray[0], path)); + } else { + dto.setSuccess(false); + dto.setStatus(0); + dto.setResult(result); + LogUtil.info("unzipOneFilePassword Error extracting item: " + result); + } + } + } catch (Exception e) { + LogUtil.error(e, " unzipOneFilePassword Exception : " + e); + e.printStackTrace(); + dto.setSuccess(false); + dto.setStatus(0); + } + return dto; + } + + /** + * @Description: + * @params: [sourceZipFile 压缩包文件, extractPath 解压路径, password 密码 ] + * @Return: com.svnlan.home.dto.CompressFileDto + * @Author: sulijuan + * @Modified: + */ + public static CompressFileDto unzipFilePassword(String sourceZipFile, String unzipPath, List fileList, Long userID + , final String password, String taskID, Boolean isProgress, + StringRedisTemplate stringRedisTemplate) { + + Map reMap = new HashMap<>(1); + CompressFileDto dto = new CompressFileDto(); + dto.setSuccess(true); + dto.setStatus(1); + + RandomAccessFile randomAccessFile = null; + IInArchive inArchive = null; + try { + //如果解压到的目标文件夹不存在,则新建 + File destinationFolder = new File(unzipPath); + if (!destinationFolder.exists()) { + destinationFolder.mkdirs(); + } + randomAccessFile = new RandomAccessFile(sourceZipFile, "r"); + if (!ObjectUtils.isEmpty(password) && password.length() > 0) { + inArchive = SevenZip.openInArchive(null, + new RandomAccessFileInStream(randomAccessFile), password); + }else { + inArchive = SevenZip.openInArchive(null, + new RandomAccessFileInStream(randomAccessFile)); + } + long totalSize = randomAccessFile.length(); + ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); + int i = 0; + final long[] sizeArray = new long[1]; + final int[] hash = new int[] { 0 }; + for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) { + + if (!item.isFolder()) { + ExtractOperationResult result; + + + String path = getUtf8String(item.getPath()); + if (isMessyCode(path)){ + path = new String(item.getPath().getBytes(StandardCharsets.ISO_8859_1), "GBK"); + } + String suffix = FileUtil.getFileExtension(path); + + String filePath = path.replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + + //递归检查文件路径,路径上没有文件夹则创建,保证整条路径在本地存在 + fileProberParent(filePath.replace(fileName, ""), destinationFolder.getPath() + File.separator, suffix, fileList, reMap); + + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = unzipPath + (unzipPath.endsWith("/") ? "" : File.separator) + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + userID + "." + suffix; + byte[] b = new byte[1024]; + File fileExisting = new File(finalFilePath); + fileList.add(new ChangeSourceVo(fileName, 0, suffix, finalFilePath , filePath + , item.getSize(), "")); + //被解压的文件 + OutputStream out = new FileOutputStream(fileExisting); + if (!ObjectUtils.isEmpty(password) && password.length() > 0) { + //如果文件很大用这个方法可以解压完整,当然文件小用这个也没毛病 + result = item.extractSlow(new ISequentialOutStream() { + @Override + public int write(final byte[] data) throws SevenZipException { + int l = b.length; + int length = data.length; + int totalPage = (length + l - 1) / l; + try { + for (int i = 0; i < totalPage; i ++){ + if (i == totalPage -1){ + sizeArray[0] += length - (i*l); + out.write(data, i * l, length - (i*l)); + // out.write(data); + }else { + sizeArray[0] += l; + out.write(data, i * l, l); + } + // 计算进度 + if (isProgress) { + unZipProgressCalculate(taskID, stringRedisTemplate, sizeArray[0], totalSize); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + hash[0] |= Arrays.hashCode(data); + + return data.length; + } + }, password); + }else { + result = item.extractSlow(new ISequentialOutStream() { + @Override + public int write(final byte[] data) throws SevenZipException { + int l = b.length; + int length = data.length; + int totalPage = (length + l - 1) / l; + try { + for (int i = 0; i < totalPage; i ++){ + if (i == totalPage -1){ + sizeArray[0] += length - (i*l); + out.write(data, i * l, length - (i*l)); + // out.write(data); + }else { + sizeArray[0] += l; + out.write(data, i * l, l); + } + // 计算进度 + if (isProgress) { + unZipProgressCalculate(taskID, stringRedisTemplate, sizeArray[0], totalSize); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + hash[0] |= Arrays.hashCode(data); + return data.length; + } + }); + } + i ++; + out.close(); + + + if (result == ExtractOperationResult.OK) { + LogUtil.info("unzipOneFilePassword success " + String.format("%9X | %10s | %s", // + hash[0], sizeArray[0], path)); + } else { + dto.setSuccess(false); + dto.setStatus(0); + dto.setResult(result); + LogUtil.info("unzipOneFilePassword Error extracting item: " + result); + } + } + } + } catch (Exception e) { + LogUtil.error(e, " unzipOneFilePassword Exception : " + e); + e.printStackTrace(); + dto.setSuccess(false); + dto.setStatus(0); + } + if (isProgress){ + stringRedisTemplate.opsForValue().set(GlobalConfig.async_key_unzip_file + taskID, "1", 1, TimeUnit.HOURS); + } + return dto; + } + + public static void unZipProgressCalculate(String taskID, StringRedisTemplate stringRedisTemplate, long count, long total){ + String p = calculateProgress( count, total,1); + LogUtil.info("unZipProgressCalculate taskID=" + taskID + ",count=" + count + ",total=" + total + ", progress=" + p); + stringRedisTemplate.opsForValue().set(GlobalConfig.progress_key_unzip_file + taskID, p, 1, TimeUnit.HOURS); + + } + + public static String calculateProgress(long num, long total, int dis){ + NumberFormat numberFormat = NumberFormat.getInstance(); + numberFormat.setMaximumFractionDigits(dis); //保留几位小数填写几 + //注意需要将long转换为float进行计算 + String percent = numberFormat.format((float) num / (float) total * 100); + return percent; + } + + + public static void fileProberParent(String parentPath, String destPath, String suffix, List fileList, Map reMap) { + if (!ObjectUtils.isEmpty(reMap) && reMap.containsKey(parentPath)){ + return; + } + List parentList = Arrays.asList(parentPath.split("/")).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(parentList)){ + StringBuilder sb = new StringBuilder(); + for (String parent : parentList){ + if (parent.endsWith(suffix)){ + continue; + } + sb.append(parent + "/"); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(sb.toString())) { + fileList.add(new ChangeSourceVo(parent, 1, destPath + sb.toString())); + } + reMap.put(sb.toString(), 1); + } + } + } + + public static Boolean checkZipIsEncrypted(String paths) { + LogUtil.info("checkZipIsEncrypted paths=" + paths); + RandomAccessFile randomAccessFile = null; + IInArchive inArchive = null; + + boolean isEncrypted = false; + try { + randomAccessFile = new RandomAccessFile(paths, "r"); + + inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile)); + + ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); + int i = 0; + for (final ISimpleInArchiveItem o : simpleInArchive.getArchiveItems()) { + if (!isEncrypted && !o.isFolder()){ + if (Boolean.TRUE.equals(inArchive.getProperty(i,PropID.ENCRYPTED))) { + isEncrypted = true; + break; + } + break; + } + i ++; + } + } catch (Exception e) { + LogUtil.error(e, "checkZipIsEncrypted Error occurs: " + e); + } finally { + if (inArchive != null) { + try { + inArchive.close(); + } catch (SevenZipException e) { + LogUtil.error(e, "checkZipIsEncrypted Error closing archive: " + e); + } + } + if (randomAccessFile != null) { + try { + randomAccessFile.close(); + } catch (IOException e) { + LogUtil.error(e, "checkZipIsEncrypted Error closing file: " + e); + } + } + } + return isEncrypted; + } + + public static byte[] getUTF8BytesFromGBKString(String gbkStr) { + int n = gbkStr.length(); + byte[] utfBytes = new byte[3 * n]; + int k = 0; + for (int i = 0; i < n; i++) { + int m = gbkStr.charAt(i); + if (m < 128 && m >= 0) { + utfBytes[k++] = (byte) m; + continue; + } + utfBytes[k++] = (byte) (0xe0 | (m >> 12)); + utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f)); + utfBytes[k++] = (byte) (0x80 | (m & 0x3f)); + } + if (k < utfBytes.length) { + byte[] tmp = new byte[k]; + System.arraycopy(utfBytes, 0, tmp, 0, k); + return tmp; + } + return utfBytes; + } + + public static String getUtf8String(String str) { + if (str != null && str.length() > 0) { + String needEncodeCode = "ISO-8859-1"; + String neeEncodeCode = "ISO-8859-2"; + String gbkEncodeCode = "GBK"; + try { + if (Charset.forName(needEncodeCode).newEncoder().canEncode(str)) { + str = new String(str.getBytes(needEncodeCode), StandardCharsets.UTF_8); + } + if (Charset.forName(neeEncodeCode).newEncoder().canEncode(str)) { + str = new String(str.getBytes(neeEncodeCode), StandardCharsets.UTF_8); + } + if (Charset.forName(gbkEncodeCode).newEncoder().canEncode(str)) { + str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + return str; + } + /** + * 判断是否是中日韩文字 + */ + public static boolean isChinese(char c) { + Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); + if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A + || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION + || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION + || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { + return true; + } + return false; + } + public static boolean judge(char c){ + if((c >='0' && c<='9')||(c >='a' && c<='z' || c >='A' && c<='Z')){ + return true; + } + return false; + } + public static boolean isMessyCode(String strName) { + //去除字符串中的空格 制表符 换行 回车 + Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*"); + Matcher m = p.matcher(strName); + String after = m.replaceAll("").replaceAll("\\+", "").replaceAll("#", "").replaceAll("&", ""); + //去除字符串中的标点符号 + String temp = after.replaceAll("\\p{P}", ""); + //处理之后转换成字符数组 + char[] ch = temp.trim().toCharArray(); + for (int i = 0; i < ch.length; i++) { + char c = ch[i]; + //判断是否是数字或者英文字符 + if (!judge(c)) { + //判断是否是中日韩文 + if (!isChinese(c)) { + //如果不是数字或者英文字符也不是中日韩文则表示是乱码返回true + return true; + } + } + } + //表示不是乱码 返回false + return false; + } + + +} diff --git a/src/main/java/com/svnlan/home/utils/ConfigUtils.java b/src/main/java/com/svnlan/home/utils/ConfigUtils.java new file mode 100644 index 0000000..de5b962 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ConfigUtils.java @@ -0,0 +1,100 @@ +package com.svnlan.home.utils; + + +import com.svnlan.utils.PropertiesUtil; + +import java.io.File; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +/** + * @author : + **/ +public class ConfigUtils { + + private static final String MAIN_DIRECTORY_NAME = "server"; + + public static String getHomePath() { + // 还没改,目前没有用到 + String userDir = PropertiesUtil.getUpConfig("cloud.savePath"); + + if (userDir.endsWith("bin")) { + userDir = userDir.substring(0, userDir.length() - 4); + } else { + String separator = File.separator; + if (userDir.endsWith(MAIN_DIRECTORY_NAME)) { + userDir = userDir + separator + "src" + separator + "main"; + } else { + userDir = userDir + separator + MAIN_DIRECTORY_NAME + separator + "src" + separator + "main"; + } + } + return userDir; + } + + // 获取环境变量,如果找不到则返回默认值 + @SuppressWarnings("SameParameterValue") + private static String getEnvOrDefault(String key, String def) { + String value = System.getenv(key); + return value == null ? def : value; + } + + // 返回参数列表中第一个真实存在的路径,或者 null + private static String firstExists(File... paths) { + for (File path : paths) { + if (path.exists()) { + return path.getAbsolutePath(); + } + } + return null; + } + + public static String getUserDir() { + // 还没改,目前没有用到 + String binFolder = PropertiesUtil.getUpConfig("cloud.savePath"); + + File pluginPath = new File(binFolder); + + // 如果指定了 bin 或其父目录,则返回父目录 + if (new File(pluginPath, "bin").exists()) { + return pluginPath.getAbsolutePath(); + + } else if (pluginPath.exists() && pluginPath.getName().equals("bin")) { + return pluginPath.getParentFile().getAbsolutePath(); + + } else { + return firstExists(new File(pluginPath, MAIN_DIRECTORY_NAME), + new File(pluginPath.getParentFile(), MAIN_DIRECTORY_NAME)); + } + } + + public static String getCustomizedConfigPath() { + String homePath = getHomePath(); + String separator = File.separator; + return homePath + separator + "config" + separator + "application.properties"; + } + + public synchronized static void restorePropertiesFromEnvFormat(Properties properties) { + Iterator> iterator = properties.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + String key = entry.getKey().toString(); + String value = entry.getValue().toString(); + if (value.trim().startsWith("${") && value.trim().endsWith("}")) { + int beginIndex = value.indexOf(":"); + if (beginIndex < 0) { + beginIndex = value.length() - 1; + } + int endIndex = value.length() - 1; + String envKey = value.substring(2, beginIndex); + String envValue = System.getenv(envKey); + if (envValue == null || "".equals(envValue.trim())) { + value = value.substring(beginIndex + 1, endIndex); + } else { + value = envValue; + } + properties.setProperty(key, value); + } + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/ConvertPicUtil.java b/src/main/java/com/svnlan/home/utils/ConvertPicUtil.java new file mode 100644 index 0000000..b5e0425 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ConvertPicUtil.java @@ -0,0 +1,198 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.Result; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOFileMeta; +import com.svnlan.home.utils.office.LibreOfficeDUtil; +import com.svnlan.manage.vo.ConvertToPDFMsgDTO; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.StringUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/30 14:20 + */ +@Component +public class ConvertPicUtil { + + @Resource + IoFileDao ioFileDao; + + @Value("${office.libreOfficeVersion}") + private String libreOfficeVersion; + + + public Result convertToPDF(String prefix, CommonSource commonSource, ConvertToPDFMsgDTO convertToPDFMsgDTO) { + Long sourceID = convertToPDFMsgDTO.getSourceID(); + Result result = null; + String code = "200"; + String message = ""; + Boolean success = Boolean.FALSE; + if(null == sourceID || sourceID <= 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if(null == commonSource) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String regionFilePath = commonSource.getPath(); + File file = new File(regionFilePath); + if(!file.exists()) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + String fileName = file.getName(); + String fileExtension = FileUtil.getFileExtension(fileName); + if(!Arrays.asList("pdf", "ppt", "pptx", "xls", "xlsx", "doc", "docx").contains(fileExtension)) { + // "只支持pdf、ppt、pptx、xls、xlsx、doc、docx转换" + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode() ); + } + + String targetDir = file.getParent() + "/" + "pdf"; + String pdfPath = targetDir + "/" + fileName.substring(0, fileName.length() - fileExtension.length()) + "pdf"; + //转的最后1张图片路径 + + String firstPath = FileUtil.getFirstStorageDevicePath(regionFilePath); + + String lastImagePath = file.getParent() + "/image/"; + if (lastImagePath.indexOf(firstPath + "/private/cloud/") >= 0){ + lastImagePath = lastImagePath.replace(firstPath + "/private/cloud/", firstPath + "/common/brochure_attachment/"); + } + File lastFile = new File(lastImagePath); + if(!lastFile.exists()) { + lastFile.mkdirs(); + } + lastImagePath += fileName.substring(0, fileName.length() - fileExtension.length() - 1) + "@"; + + Integer isH264Preview = commonSource.getIsH264Preview(); + String regionH264Path = commonSource.getH264Path(); + //若已转过 并且 H264不为空,则判断下 + if(!ObjectUtils.isEmpty(isH264Preview) && 1 == isH264Preview.intValue() && !StringUtil.isEmpty(regionH264Path) + && !Boolean.TRUE.equals(convertToPDFMsgDTO.getNoImage())) { + String regionH264Extension = FileUtil.getFileExtension(regionH264Path); + //若非jpg + if(!"jpg".equals(regionH264Extension)) { + isH264Preview = 0; + commonSource.setIsH264Preview(isH264Preview); + commonSource.setH264Path(""); + // + this.updateH264InfoOperate(commonSource); + } + } + String h264Path = ""; + if (1 == isH264Preview.intValue()){ + // 获取h264Path + IOFileMeta meta = ioFileDao.getFileValue(commonSource.getSourceID()); + Map map = null; + if (!ObjectUtils.isEmpty(meta) && !ObjectUtils.isEmpty(meta.getValue())){ + map = JsonUtils.jsonToMap(meta.getValue()); + } + if (!ObjectUtils.isEmpty(map) && map.containsKey("h264Path") && !ObjectUtils.isEmpty(map.get("h264Path"))){ + h264Path = map.get("h264Path").toString(); + } + } + //若是已有转换过的,则跳过 + if(1 == isH264Preview.intValue() && !ObjectUtils.isEmpty(h264Path)) { + code = "AlreadySuccess"; + message = ""; + lastImagePath = h264Path; + } else { + //若原文件非pdf,则先转成pdf + if(!"pdf".equals(fileExtension)) { + //转换成PDF + Boolean isSuccess = LibreOfficeDUtil.libreOfficeCommand(prefix, this.libreOfficeVersion, "pdf", + regionFilePath, targetDir); + if (!isSuccess) { + isH264Preview = 2; + } else { + isH264Preview = 1; + } + } else { + pdfPath = regionFilePath; + } + + //未转失败时,则再转图片下 + if(2 != isH264Preview.intValue() && !Boolean.TRUE.equals(convertToPDFMsgDTO.getNoImage())) { + //将PDF转PNG或JPG(有压缩) + lastImagePath = PdfDUtil.pdfToPngOrJpg(prefix, pdfPath, lastImagePath, 0.2, 6600, 1900); + //为NULL则失败 + if(null == lastImagePath) { + isH264Preview = 2; + } else { + isH264Preview = 1; + } + } + + commonSource.setIsH264Preview(isH264Preview); + //转成功才将 + if(1 == isH264Preview.intValue()) { + commonSource.setH264Path(lastImagePath); + } else { + commonSource.setH264Path(""); + } + + //执行更新状态等 + this.updateH264InfoOperate(commonSource); + + //若是失败,则 + if(2 == isH264Preview.intValue()) { + code = "ConvertFail"; + message = "转换失败"; + } + } + commonSource.setPdfPath(pdfPath); + commonSource.setH264Path(lastImagePath); + + if(!"200".equals(code)) { + success = Boolean.FALSE; + } + result = new Result(success, code, message, commonSource); + return result; + } + + + /** 保存h264Path */ + public void updateH264InfoOperate(CommonSource commonSource) { + this.ioFileDao.updateH264Info(commonSource); + if (!ObjectUtils.isEmpty(commonSource.getH264Path())){ + if (ObjectUtils.isEmpty(commonSource.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + IOFileMeta meta = ioFileDao.getFileValue(commonSource.getSourceID()); + Map map = null; + if (!ObjectUtils.isEmpty(meta) && !ObjectUtils.isEmpty(meta.getValue())){ + map = JsonUtils.jsonToMap(meta.getValue()); + } + if (ObjectUtils.isEmpty(map)){ + map = new HashMap<>(1); + } + map.put("h264Path", commonSource.getH264Path()); + + try { + if (!ObjectUtils.isEmpty(meta)){ + ioFileDao.updateOneFileUrlValue(meta.getFileID(), JsonUtils.beanToJson(map)); + }else { + IOFileMeta fileMeta = new IOFileMeta(); + fileMeta.setFileID(meta.getFileID()); + fileMeta.setKey("fileInfoMore"); + fileMeta.setValue(JsonUtils.beanToJson(map)); + ioFileDao.insertMeta(fileMeta); + } + }catch (Exception e){ + LogUtil.error(e, " 保存h264Path失败!commonSource=" + JsonUtils.beanToJson(commonSource)); + } + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/ConvertUtil.java b/src/main/java/com/svnlan/home/utils/ConvertUtil.java new file mode 100644 index 0000000..fe5d2b3 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ConvertUtil.java @@ -0,0 +1,1314 @@ +package com.svnlan.home.utils; + +import com.google.common.base.Joiner; +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.dao.HomeExplorerDao; +import com.svnlan.home.dao.IoFileDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOFileMeta; +import com.svnlan.home.dto.convert.ConvertDTO; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.vo.FileMetaVo; +import com.svnlan.home.vo.YzEditParamsDto; +import com.svnlan.user.dao.CommonConvertDao; +import com.svnlan.user.domain.CommonConvert; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.*; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.net.URLEncoder; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 10:47 + */ +@Component +public class ConvertUtil { + @Resource + private DocUtil docUtil; + @Resource + IoFileDao ioFileDao; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + CommonConvertDao commonConvertDao; + @Resource + StorageService storageService; + @Resource + IoSourceDao ioSourceDao; + @Resource + HomeExplorerDao homeExplorerDao; + + + + @Value("${m3u8.buildkey}") + private String buildKey; + @Value("${m3u8.buildkey2}") + private String buildKey2; + + + @Value("${yz.view.convert.url}") + private String yongZhongConvertUrl; + @Value("${yz.edit.convert.url}") + private String yongZhongEditUrl; + @Value("${yz.edit.post.url}") + private String yongZhongGetEditPostUrl; + @Value("${yz.fileId.prefix}") + private String yzFileIdPreFix; + + + + private static String[] VideoType = {"flv","avi","mpeg","mpg","mp4","rmvb","rm","mov","3gp","f4v","wmv"}; + private static String[] DocType = {"doc", "docx", "ppt", "pptx", "pdf"}; + private static String[] AudioType = {"mp3", "wav", "flac"}; + + /** + * @Description: 视频转码 + * @params: [videoConvert] + * @Return: com.svnlan.upload.vo.VideoConvertVO + * @Modified: + */ + @Async(value = "asyncTaskExecutor") + public void doConvert(ConvertDTO convertDTO, CommonSource commonSource) { + doConvertMain(convertDTO, commonSource); + } + + public void doConvertMain(ConvertDTO convertDTO, CommonSource commonSource) { + LogUtil.info("doConvert begin进入转码流程 : "+ JsonUtils.beanToJson(convertDTO) + + ",time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) + ", commonSource=" + (!ObjectUtils.isEmpty(commonSource) ? JsonUtils.beanToJson(commonSource) : " is null") ); + + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(convertDTO.getBusType()); + if (busTypeEnum == null){ + LogUtil.error("业务类型不正确:"+ JsonUtils.beanToJson(convertDTO)); + return; + } + switch (busTypeEnum) { + case CLOUD: + /** 后台转码时使用 + CommonSource commonSource = this.getAttachment(convertDTO.getBusId());*/ + if ((ObjectUtils.isEmpty(commonSource) || ObjectUtils.isEmpty(commonSource.getSourceID())) && !ObjectUtils.isEmpty(convertDTO.getBusId())) { + commonSource = ioFileDao.findCommonSourceById(convertDTO.getBusId()); + if (ObjectUtils.isEmpty(commonSource)) { + LogUtil.error("附件不存在,id:" + convertDTO.getBusId()); + return; + } + } + if (ObjectUtils.isEmpty(commonSource.getDomain())){ + commonSource.setDomain(convertDTO.getDomain()); + } + // 转码类型 // 1 手动执行 2 定时任务执行 + if (ObjectUtils.isEmpty(commonSource.getOpType())) { + commonSource.setOpType(convertDTO.getOpType()); + } + if (!ObjectUtils.isEmpty(commonSource.getOpType()) && "1".equals(commonSource.getOpType())) { + // 转码手动执行人 + commonSource.setUserID(convertDTO.getUserID()); + } + + if (ObjectUtils.isEmpty(commonSource.getSourceType())){ + commonSource.setSourceType(busTypeEnum.getTypeCode()); + } + + File pathFile = new File(commonSource.getPath()); + if (!pathFile.exists()){ + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()) && + !ObjectUtils.isEmpty(convertDTO.getOtherType()) + && Arrays.asList("unZip","cutVideo","splitVideo","mergeVideo","convertVideo","settingVideo").contains(convertDTO.getOtherType())){ + this.saveVideoConvertRecord(commonSource, "2", "源文件还未生成"); + } + return; + } + + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()) && + !ObjectUtils.isEmpty(convertDTO.getOtherType()) + && Arrays.asList("unZip","cutVideo","splitVideo","mergeVideo","convertVideo","settingVideo").contains(convertDTO.getOtherType())){ + this.saveVideoConvertRecord(commonSource, "0", ""); + } + // + if (!ObjectUtils.isEmpty(convertDTO.getIsNew()) && 1 == convertDTO.getIsNew()){ + // 强制转码 + commonSource.setIsM3u8(0); + } + this.doAttachment(commonSource); + break; + default: + LogUtil.error("非转码业务, busType:" + convertDTO.getBusType() + ", busId" + convertDTO.getBusId()); + } + stringRedisTemplate.opsForHash().getOperations().expire(GlobalConfig.homeExplorerRedisKey + commonSource.getUserID(), 1, TimeUnit.MILLISECONDS); + } + + /** + * @Description: 处理附件 + * @params: [commonSource] + * @Return: void + * @Modified: + */ + private void doAttachment(CommonSource commonSource) { + // boolean isVideo = Arrays.asList(VideoType).contains(commonSource.getFileType()); + boolean isVideo = Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()); + boolean isAudio = Arrays.asList(AudioType).contains(commonSource.getFileType()); + boolean isYongZhong = Arrays.asList(GlobalConfig.yongzhong_doc_excel_ppt_type).contains(commonSource.getFileType()); + boolean isCamera = Arrays.asList(GlobalConfig.CAMERA_TYPE_ARR).contains(commonSource.getFileType()); + if (isVideo){ + if (commonSource.getIsM3u8() != null && commonSource.getIsM3u8().equals(1)){ + // 转码完成记录 + this.saveVideoConvertRecord(commonSource, "1", ""); + return; + } + this.video(commonSource); + } else if (isAudio){ + convertAudioCommon("", commonSource); + } else if (isYongZhong){ + this.yongZhong(commonSource); + }else if (isCamera) { + // 相机文件 + convertCameraToImgCommon("相机文件转Img", commonSource); + } + + if (!ObjectUtils.isEmpty(commonSource.getNeedHashMd5()) && commonSource.getNeedHashMd5().intValue() == 1){ + // 需修改文件md5 + this.updateFileHashMd5(commonSource); + } + + /* + boolean isH5Doc = Arrays.asList(DocType).contains(commonSource.getFileType()); + if (isH5Doc){ + this.h5Doc(commonSource); + } + */ + } + + public void updateFileHashMd5(CommonSource commonSource) { + Long size = 0L; + String serverChecksum = ""; + //最终文件 + File finalFile = new File(commonSource.getPath()); + FileInputStream fis = null; + try { + fis = new FileInputStream(finalFile); + serverChecksum = org.springframework.util.DigestUtils.md5DigestAsHex(fis); + size = finalFile.length(); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage(), " updateFileHashMd5 失败 commonSource=" + JsonUtils.beanToJson(commonSource)); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + if (!ObjectUtils.isEmpty(serverChecksum)){ + ioFileDao.updateFileMd5AndSizeByFileID(serverChecksum, commonSource.getFileID(), size); + Long sourceSize = ioSourceDao.getSourceSize(commonSource.getSourceID()); + if (!ObjectUtils.isEmpty(sourceSize) && sourceSize <= 0){ + try { + ioSourceDao.updateSourceSize(commonSource.getSourceID(), size); + }catch (Exception e){ + LogUtil.error(e,"updateSourceSize error"); + } + commonSource.setGroupID(0L); + this.updateMemory(commonSource); + } + } + + } + + public void updateMemory(CommonSource commonSource) { + updateMemory(commonSource.getSize(), commonSource.getGroupID(), commonSource.getUserID(), commonSource.getTargetType(), commonSource.getParentLevel()); + } + + public void updateMemory(long size, long groupID, long userID, Integer targetType, String parentLevel) { + if (size > 0 && !ObjectUtils.isEmpty(targetType)) { + Map paramMap = new HashMap<>(2); + paramMap.put("groupID", groupID); + paramMap.put("memory", size); + paramMap.put("userID", userID); + LogUtil.info("updateMemory paramMap=" + JsonUtils.beanToJson(paramMap) + ",targetType=" + targetType + ", parentLevel=" + parentLevel); + try { + if (targetType.intValue() == 1) { + homeExplorerDao.updateUserMemory(paramMap); + } else { + if (groupID > 0) { + this.updateGroupMemoryCopy(paramMap, groupID); + }else { + this.updateGroupMemoryCopyBySearch(paramMap, parentLevel); + } + } + } catch (Exception e) { + LogUtil.error(e, "更新 企业云盘 memory失败"); + } + // source updateSourceMemoryList + if (!ObjectUtils.isEmpty(parentLevel)) { + try { + List sourceIds = Arrays.asList(parentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(sourceIds)) { + ioSourceDao.updateSourceMemoryList(sourceIds, size); + } + } catch (Exception e) { + LogUtil.error(e, " updateMemory updateSourceMemoryList error "); + } + + } + } + } + + public void updateGroupMemoryCopyBySearch(Map paramMap, String parentLevel) { + List sourcePIDs = Arrays.asList(parentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)) + .map(Long::parseLong).collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(sourcePIDs)){ + return; + } + List gpList = homeExplorerDao.getGroupParentLevelList(sourcePIDs); + if (CollectionUtils.isEmpty(gpList)){ + return; + } + String groupParentLevel = Joiner.on(",").join(gpList); + List groupIDs = Arrays.asList(groupParentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)) + .map(Long::parseLong).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(groupIDs)){ + return; + } + paramMap.put("list", groupIDs); + homeExplorerDao.updateMemoryList(paramMap); + } + public void updateGroupMemoryCopy(Map paramMap, Long groupID) { + String groupParentLevel = homeExplorerDao.getGroupParentLevel(groupID); + List groupIDs = Arrays.asList(groupParentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)) + .map(Long::parseLong).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(groupIDs)){ + groupIDs = new ArrayList<>(); + } + groupIDs.add(groupID); + paramMap.put("list", groupIDs); + homeExplorerDao.updateMemoryList(paramMap); + } + + public void yongZhong(CommonSource commonSource) { + if (ObjectUtils.isEmpty(commonSource.getDomain())){ + LogUtil.error("yongZhong domain is null !"); + return; + } + // 预览 + String yzViewData = yongZhongView(commonSource, true); + // 编辑 + //String yzEditData = yongZhongEdit(commonSource); + commonSource.setYzViewData(yzViewData); + //commonSource.setYzEditData(yzEditData); + + /** 更新文档其他信息 */ + this.updateYZPreviewUrlValue(Arrays.asList(commonSource.getFileID()), yzViewData); + } + + public void yongZhongPre(CommonSource commonSource, boolean isView) { + if (ObjectUtils.isEmpty(commonSource.getDomain())){ + LogUtil.error("yongZhong domain is null !"); + return; + } + String urlData = ""; + + if (isView){ + // 预览 + urlData = yongZhongView(commonSource, true); + commonSource.setYzViewData(urlData); + /** 更新文档其他信息 */ + this.updateYZPreviewUrlValue(Arrays.asList(commonSource.getFileID()), urlData, isView); + }else { + commonSource.setToken(RandomUtil.getuuid()); + // 编辑 + urlData = yongZhongEdit(commonSource); + commonSource.setYzEditData(urlData); + } + } + + + + public String yongZhongEdit(CommonSource commonSource) { + String downloadKey = FileUtil.getDownloadKey(""); + String yzEditData = ""; + String downloadUrl = "/api/disk/attachment/" + FileUtil.encodeDownloadUrl(commonSource.getName()) + + "?busId=" + commonSource.getSourceID() + "&busType=" + BusTypeEnum.CLOUD.getBusType() + "&key=" ; + // 编辑 + String filePath = commonSource.getDomain() + downloadUrl; + String uuid = ObjectUtils.isEmpty(commonSource.getToken()) ? "" : "_" + commonSource.getToken(); + + if (!ObjectUtils.isEmpty(commonSource.getToken())){ + Map editMap = new HashMap<>(1); + editMap.put("userID", commonSource.getUserID().toString()); + String userKey = GlobalConfig.yzwo_file_edit_user_key + commonSource.getToken(); + stringRedisTemplate.opsForValue().set(userKey, JsonUtils.beanToJson(editMap), 5, TimeUnit.HOURS); + } + //String filePath = commonSource.getDomain() + commonSource.getPath(); + String callbackUrl = commonSource.getDomain() + "/api/disk/yzwo/office"; + Map param = new HashMap<>(2); + param.put("method", 1); + param.put("params", new YzEditParamsDto(commonSource.getUserID().toString(), yzFileIdPreFix + commonSource.getSourceID() + uuid, commonSource.getName(), filePath, callbackUrl)); + try { + String postUrl = yongZhongGetEditPostUrl + "?jsonParams=" + URLEncoder.encode(JsonUtils.beanToJson(param),"UTF-8") ; + + String res1 = docUtil.postYZFile(postUrl); + LogUtil.info("yongZhong yongZhongEdit return retry : " + res1 + "postUrl : " + postUrl ); + Map resMap = JsonUtils.jsonToMap(res1); + if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorCode") && "0".equals(resMap.get("errorCode").toString())){ + yzEditData = this.yzEditUrl(resMap); + }else if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorcode") && "0".equals(resMap.get("errorcode").toString())){ + yzEditData = this.yzEditUrl(resMap); + } + LogUtil.info("yongZhong yongZhongEdit resMap=" + JsonUtils.beanToJson(resMap)); + } catch (Exception e){ + LogUtil.error(e, "yongZhong yongZhongEdit 失败 , o:" + filePath); + } + return yzEditData; + } + + private String yzEditUrl(Map resMap){ + String data = resMap.get("result").toString(); + Map urlMap = JsonUtils.jsonToMap(data); + if (!ObjectUtils.isEmpty(urlMap) && urlMap.containsKey("urls")){ + String urls = urlMap.get("urls").toString(); + int index = urls.indexOf("/s/"); + if (index >= 0){ + return yongZhongEditUrl + urls.substring(index, urls.length()); + } + } + return ""; + } + + private String getYzConvertType(String fileType){ + switch (fileType){ + case "zip": + case "gz": + case "rar": + case "iso": + case "tar": + case "7z": + case "ar": + case "bz": + case "bz2": + case "xz": + case "arj": + return "19"; + case "pdf": + return "20"; + default: + return "61"; + } + + + } + + public String yongZhongView(CommonSource commonSource, boolean save) { + String yzViewData = ""; + String convertType = getYzConvertType(commonSource.getFileType()); + // 预览 + String viewKey = FileUtil.getVideoImgDownloadKey(commonSource.getPath()); + + String filePath = commonSource.getDomain() + "/api/disk/video/img/"+ commonSource.getSourceID()+ "." + commonSource.getFileType() +"?showPreview=1&key=" + viewKey; + try { // %20 为空格 + String postUrl = yongZhongConvertUrl + "?noCache=1&convertType=" + convertType + "&htmlName=%20&htmlTitle=%20&fileUrl=" + URLEncoder.encode(filePath,"UTF-8"); + String res1 = docUtil.postYZFile(postUrl); + LogUtil.info("yongZhong h5 api return retry : " + res1 + "filePath : " + filePath + ", o:" + commonSource.getName()); + Map resMap = JsonUtils.jsonToMap(res1); + if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorcode") && "0".equals(resMap.get("errorcode").toString())){ + yzViewData = resMap.get("data").toString(); + if (save) { + commonSource.setIsPreview(1); + commonSource.setIsM3u8(0); + ioFileDao.updateVideoConvert(commonSource); + } + }else{ + LogUtil.info("yongZhong 转码失败 res1=" + res1 + ", commonSource=" + JsonUtils.beanToJson(commonSource)); + } + } catch (Exception e){ + LogUtil.error(e, "yongZhong 转码失败失败 , o:" + commonSource.getName()); + } + return yzViewData; + } + + private void h5Doc(CommonSource commonSource) { + LogUtil.info("进入h5流程 source:" + JsonUtils.beanToJson(commonSource)); + String sourcePath; + String fileName; + String sourceSuffix; + CommonSource cs = new CommonSource(); + + boolean isAttachment; + + Integer h5ConvertState; + Integer swfConverState; + String pdfPageRedisKey; + //处理附件 + h5ConvertState = commonSource.getAppPreview(); + swfConverState = commonSource.getIsM3u8(); + sourcePath = commonSource.getPath(); + //云盘 + fileName = DigestUtils.md5Hex(String.valueOf(System.currentTimeMillis())) + commonSource.getFileID(); + String basePath = "";// commonSource.getSourcePathPre().equals("") ? PropertiesUtil.getUpConfig("cloud.savePath") : commonSource.getSourcePathPre(); + + sourceSuffix = commonSource.getFileType(); + cs.setName(commonSource.getName()); + cs.setFileID(commonSource.getFileID()); + isAttachment = true; + pdfPageRedisKey = commonSource.getHashMd5() + "_" + commonSource.getSize(); + + //源文件 + String sourceFileName = basePath + sourcePath; + //目标目录路径 + String filePath = this.getDestFilePath(sourcePath); + //是否已转 + boolean converted = !this.checkConvertFile(sourceFileName, isAttachment); + //是否需要h5转码 + boolean needH5Convert = (!converted || h5ConvertState.equals(-2)) && !h5ConvertState.equals(1); + //是否需要swf转码 + boolean needSwfConvert = (!converted || swfConverState.equals(-2)) && !swfConverState.equals(1); + String targetFileName = null; + String imagePath = filePath + fileName + "/"; + try { + switch (sourceSuffix){ + case "doc": + case "docx": + if (needH5Convert) { +// docUtil.doc2Image(sourceFileName, cs); + } + if (needSwfConvert) { + docUtil.pdf2Swf(sourceFileName, cs); + } + break; + case "ppt": + case "pptx": + if (needH5Convert) { +// docUtil.doc2Image(sourceFileName, cs); + } + if (needSwfConvert) { + docUtil.pdf2Swf(sourceFileName, cs); + } + break; + case "pdf": + if (needH5Convert) { + int pageCount = docUtil.pdf2image(sourceFileName, imagePath, pdfPageRedisKey); + if (pageCount == 0) { + LogUtil.info("转pdf,页数为0. source:" + JsonUtils.beanToJson(commonSource)); + } + targetFileName = imagePath + "[" + (pageCount) + "].png"; + } + if (needSwfConvert) { + docUtil.pdf2Swf(sourceFileName, cs); + } + default: + break; + } + //完成,数据入库 + if (targetFileName != null) { + this.finishDoc(commonSource, targetFileName); + } + } catch (Exception e){ + LogUtil.error(e, "doc转码失败 source:" + JsonUtils.beanToJson(commonSource)); + } + } + + private String getDestFilePath(String sourcePath) { + // 已改 + String h5Path = PropertiesUtil.getUpConfig("h5doc.savePath"); + String relativePath = sourcePath.substring(0, sourcePath.lastIndexOf("/") + 1); + String firstPath = FileUtil.getFirstStorageDevicePath(sourcePath); + return relativePath.replace(firstPath + "/private/cloud/", firstPath + h5Path); + } + private String getPathByBusType(Integer sourceType, String sourcePathPre) { + // 上级方法已改 + String basePath; + if (sourceType.equals(BusTypeEnum.CLOUD.getTypeCode()) ) { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("cloud.savePath") : sourcePathPre; + }else if (sourceType.equals(BusTypeEnum.ATTACHMENT.getTypeCode()) ) { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("attachment.savePath") : sourcePathPre; + }else if (sourceType.equals(BusTypeEnum.HOMEPAGE_IMAGE.getTypeCode()) ) { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("homepage_image.savePath") : sourcePathPre; + }else if (sourceType.equals(BusTypeEnum.HOMEPAGE_ATTACHMENT.getTypeCode()) ) { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("homepage_attachment.savePath") : sourcePathPre; + }else if (sourceType.equals(BusTypeEnum.HOMEPAGE_VIDEO.getTypeCode()) ) { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("homepage_video.savePath") : sourcePathPre; + }else if (sourceType.equals(BusTypeEnum.BROCHURE_ATTACHMENT.getTypeCode()) ) { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("brochure_attachment.savePath") : sourcePathPre; + }else { + basePath = sourcePathPre.equals("") ? PropertiesUtil.getUpConfig("attachment.savePath") : sourcePathPre; + } + return basePath; + } + + /** + * @Description: 视频转码 + * @params: [sourcePath, fileType] + * @Return: void + * @Modified: + */ + + private void video(CommonSource commonSource){ + LogUtil.info("doConvert" + commonSource.getFileID() + " video begin : time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + + //获得保存文件的路径 + String basePath; + String muPath; + String muShowPath; + String sourcePath; + Long id; + Integer videoLength = null; + boolean isAttachment; + + id = commonSource.getSourceID(); + sourcePath = commonSource.getPath(); + String defaultPath = storageService.getDefaultStorageDevicePath(); + //记录了业务目录pre的,使用pre + basePath = defaultPath + this.getPathByBusType(commonSource.getSourceType(), ""); + + muPath = defaultPath + PropertiesUtil.getUpConfig("attachment.muPath"); + muShowPath = defaultPath + PropertiesUtil.getUpConfig("attachment.muShowPath"); + isAttachment = true; + + Map videoInfoMap = VideoUtil.getVideoInfo(sourcePath); + videoLength = VideoUtil.getVideoLength( sourcePath, videoInfoMap, false); + + if (videoLength <= 0){ + this.saveVideoConvertRecord(commonSource, "2", "文件损坏或者转换失败"); + return; + } + + commonSource.setSourceLength(videoLength); + // 转码类型 // 1 手动执行 2 定时任务执行 + if (ObjectUtils.isEmpty(commonSource.getOpType()) || !Arrays.asList("1","2").contains(commonSource.getOpType())) { + if (videoLength > 3600 *6){ + LogUtil.error(" doConvert" + commonSource.getFileID() + " video 转码时长超过6小时, " + id + ", " + sourcePath); + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType())) { + // 记录转码 + this.saveVideoConvertRecord(commonSource, "2", "转码时长超过6小时"); + } + return ; + } + } + //文件名 + String fileName = sourcePath.substring(0,sourcePath.lastIndexOf(".")).replace(basePath, ""); + String fileNameWithoutPath = fileName.substring(fileName.lastIndexOf("/") + 1); + //待转码的文件路径 + String filePath = sourcePath; + //校验相同文件重复转码 redis + if (!this.checkConvertFile(filePath, isAttachment)){ + LogUtil.info("doConvert" + commonSource.getFileID() + " video error checkCovertFile false time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + return; + } + //转换后待mp4文件路径 + //String mp4FilePath = basePath + fileName + ".mp4"; + //转换后的ts文件路径 + String tsPath = muPath + "ts/" + fileName + ".ts"; + //ts切片文件路径 + //String tsCutDirPath = muPath + "m3u8/" + fileName + "/"; + String tsCutPath = muPath + "m3u8/" + fileName + "/" + fileNameWithoutPath + "-%04d.ts"; + String muPre = GlobalConfig.m3u8ConvertUrlPlaceholder + muShowPath + "m3u8/" + fileName + "/"; + //m3u8索引文件路径 + String m3u8Path = basePath + fileName + ".m3u8"; + //视频截图文件路径 + String mediaPicPath =""; + if (ObjectUtils.isEmpty(commonSource.getThumb())){ + mediaPicPath = muPath + "images/" + fileName + "/" + fileNameWithoutPath + ".jpg"; //设置上传视频截图的保存路径 + }else { + File ff = new File(commonSource.getThumb()); + if (!ff.exists()) { + mediaPicPath = commonSource.getThumb(); //设置上传视频截图的保存路径 + } + } + + String smallPicPath = muPath + "images/" + fileName + "/" + "scut/%04d.jpg"; //设置上传视频截图的保存路径 + // 转换工具(ffmpeg)的存放路径 + String ffmpegPath = "ffmpeg"; + + String remark = ""; + String state = null; + try { + boolean flag; //转码成功与否的标记 + + List muPathList = new ArrayList<>(); + muPathList.add(tsPath); + muPathList.add(tsCutPath); + muPathList.add(m3u8Path); + if (!ObjectUtils.isEmpty(mediaPicPath)){ + muPathList.add(mediaPicPath); + } + muPathList.add(smallPicPath); + //创建目录 + VideoUtil.mkMuDir(muPathList); + //key info + String keyInfoPath = this.buildTsKey(id, filePath, false); + LogUtil.info("doConvert" + commonSource.getFileID() + " video 开始转码 : time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + + //mp4视频文件转码、切片、截图 + flag = VideoUtil.executeCodecs(ffmpegPath,filePath,tsCutPath,m3u8Path,mediaPicPath, keyInfoPath, muPre, fileNameWithoutPath, smallPicPath); + LogUtil.info("doConvert" + commonSource.getFileID() + " video 切片截图完成 : time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + + if(flag){ + state = "1"; + //转码成功,向数据表中添加该视频信息 + LogUtil.info("doConvert" + commonSource.getFileID() + " video 视频转码成功: commonSource:" + JsonUtils.beanToJson(commonSource)); + // + this.finishVideo(commonSource, m3u8Path, filePath, mediaPicPath, videoInfoMap); + LogUtil.info("doConvert" + commonSource.getFileID() + " video 视频转码入库成功: commonSource:" + JsonUtils.beanToJson(commonSource)); + + //cdn预热 + try { +// String tsPathWithPre = tsCutPath + "/" + fileNameWithoutPath; +// tencentApiUtil.pushUrlsCache(tsPathWithPre , cdnDomain); + } catch (Exception e){ + + } + } else { + + remark = "文件打不开"; + state = "2"; + // 失败处理 + this.convertFail(commonSource, false); + } + } catch (Exception e) { + remark = "文件打不开"; + state = "2"; + LogUtil.error(e, "转码失败 doConvert" + commonSource.getFileID() + " commonSource:" + JsonUtils.beanToJson(commonSource)); + // 失败处理 + this.convertFail(commonSource, false); + } + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType())) { + // 记录转码 + this.saveVideoConvertRecord(commonSource, state, remark); + } + + } + + public void saveStateConvertIngRecord(Long sourceID, Long fileID, String state){ + Long convertID = commonConvertDao.checkExist(sourceID, ObjectUtils.isEmpty(fileID) ? 0L : fileID); + if (!ObjectUtils.isEmpty(convertID)){ + try { + commonConvertDao.updateStatus(convertID, state); + }catch (Exception e){ + LogUtil.error(e, "记录修改为转码中,修改失败"); + } + + } + } + public void saveVideoConvertRecord(CommonSource commonSource, String state, String remark){ + if (ObjectUtils.isEmpty(commonSource.getSourceID())){ + LogUtil.info("saveVideoConvertRecord sourceID is null state=" + state + ",commonSource=" + JsonUtils.beanToJson(commonSource)); + return; + } + Long convertID = commonConvertDao.checkExist(commonSource.getSourceID(), commonSource.getFileID()); + String opType = ObjectUtils.isEmpty(commonSource.getOpType()) ? "0" : commonSource.getOpType(); + if (ObjectUtils.isEmpty(convertID)){ + CommonConvert commonConvert = new CommonConvert(); + commonConvert.setSourceID(commonSource.getSourceID()); + commonConvert.setFileID(commonSource.getFileID()); + commonConvert.setUserID(commonSource.getUserID()); + commonConvert.setName(ObjectUtils.isEmpty(commonSource.getName()) ? "" : commonSource.getName()); + commonConvert.setState(state); + commonConvert.setFrequencyCount("1".equals(opType) ? 1 : 0); + commonConvert.setRemark(remark); + try { + commonConvertDao.insert(commonConvert.initializefield()); + }catch (Exception e){ + LogUtil.error(e, "记录转码失败"); + } + }else { + + LogUtil.info("saveVideoConvertRecord convertID=" + convertID + ",opType=" + opType + ",state=" + state); + try { + switch (opType){ + case "0": + // 上传 + commonConvertDao.updateStatus(convertID, state); + break; + case "1": + // 手动执行 + commonConvertDao.updateStatusAndCount(convertID, commonSource.getUserID(), state, remark); + break; + case "2": + // 定时任务执行 + commonConvertDao.updateScheduleStatus(convertID, state); + break; + } + }catch (Exception e){ + LogUtil.error(e, "记录转码失败"); + } + } + } + + /** + * @Description: 失败处理 + * @params: [courseWare, commonSource] + * @Return: void + * @Modified: + */ + private void convertFail(CommonSource commonSource, boolean onlyEmail) { + + // + //发送站内信 + try { + this.sendNotice(commonSource, onlyEmail); + } catch (Exception e){ + LogUtil.error(e, "发送转码失败站内信失败"); + } + /* try { + String idString = ""; + String code = "cl:"; + idString = code + commonSource.getFileID(); + + Map paramMap = new HashMap<>(); + paramMap.put("courseId", idString); + paramMap.put("time", new Date()); + paramMap.put("onlyEmail", true); //只发邮件了 + // String result = restTemplate.postForEntity("http://SCHOOL/service/sms/sendEncodeFailNotify", paramMap, String.class).getBody(); + // LogUtil.info("转码失败发送短信结果, ", result); + } catch (Exception e){ + LogUtil.error(e, "请求发送短信失败, commonSource:" + JsonUtils.beanToJson(commonSource)); + }*/ + } + + private void sendNotice(CommonSource commonSource, boolean onlyEmail) { + + // String result = restTemplate.postForEntity("http://COMMON/service/common/sendSpecifiedNotice", sendNoticeServiceDTO, String.class).getBody(); + // LogUtil.info("发送转发失败站内信结果: " + result); + } + + /** + * @Description: 转码完成入库处理 + * @params: [m3u8Path] + * @Modified: + */ + private void finishVideo(CommonSource commonSource, String m3u8Path, String mp4FilePath, String mediaPicPath, Map videoInfoMap) { + try { + String checksum = commonSource.getHashMd5(); + Long fileSize = commonSource.getSize(); + //更新文件表 + //获取视频长度 + Integer playLength = VideoUtil.getVideoLength(mp4FilePath, videoInfoMap , false); + //转码完成的实际长度 + Integer convertedLength = VideoUtil.getConvertedLength(m3u8Path); + if (Math.abs(playLength - convertedLength) > 10){ + LogUtil.error("转码时长与视频信息时长差距过大, playLength:" + + playLength + ", convertedLength:" + convertedLength + ", " + JsonUtils.beanToJson(commonSource)); + } + commonSource.setIsPreview(1); + commonSource.setIsM3u8(1); + commonSource.setPreviewUrl(m3u8Path); + if (!ObjectUtils.isEmpty(mediaPicPath)) { + commonSource.setThumb(mediaPicPath); + } + commonSource.setSourceLength(playLength); + + commonSource.setThumbSize(ObjectUtils.isEmpty(commonSource.getThumbSize()) ? 0L : commonSource.getThumbSize()); + commonSource.setConvertSize(ObjectUtils.isEmpty(commonSource.getFileConvertSize()) ? 0L : commonSource.getFileConvertSize()); + // 缩略图 + if (!ObjectUtils.isEmpty(commonSource.getThumb())) { + try { + File f = new File(commonSource.getThumb()); + if (f.exists()) { + commonSource.setThumbSize(commonSource.getThumbSize() + f.length()); + } + f = new File(m3u8Path); + if (f.exists()) { + String fileContent = FileUtil.getFileContent(m3u8Path); + if (fileContent != null) { + // 转码老域名处理url + commonSource.setConvertSize(f.length() + getM3u8LineSize(m3u8Path)); + } + } + } catch (Exception e) { + } + } + + String resolution = ""; + String frame = ""; + //若是视频且分辨率为空时 + if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(commonSource.getFileType()) + && StringUtil.isEmpty(commonSource.getResolution())) { + int[] heightAndWidth = VideoUtil.getHeightAndWidth(commonSource.getPath(), videoInfoMap, false); + resolution = "1280*720"; + if (heightAndWidth[0] != 0 && heightAndWidth[1] != 0) { + resolution = heightAndWidth[1] + "*" + heightAndWidth[0]; + } + } + + if (Arrays.asList(GlobalConfig.VIDEO_TYPE_ARR).contains(commonSource.getFileType()) && + (StringUtil.isEmpty(commonSource.getResolution()) || StringUtil.isEmpty(commonSource.getFrame()))){ + int[] heightAndWidthAndFrame = VideoUtil.getHeightAndWidthAndFrame(commonSource.getPath(), videoInfoMap, false); + if (StringUtil.isEmpty(commonSource.getResolution())) { + resolution = "1280*720"; + if (heightAndWidthAndFrame[0] != 0 && heightAndWidthAndFrame[1] != 0) { + resolution = heightAndWidthAndFrame[1] + "*" + heightAndWidthAndFrame[0]; + } + } + if (StringUtil.isEmpty(commonSource.getFrame())){ + frame = heightAndWidthAndFrame[2] + ""; + } + } + ioFileDao.updateVideoConvert(commonSource); + List fileIDList = new ArrayList<>(); + fileIDList.add(commonSource.getFileID()); + + if (!ObjectUtils.isEmpty(checksum) && fileSize > 0) { + //获取缺失转码信息的相同附件 + List toUpdateCommonSourceList = ioFileDao.getSameSourceEmptyInfo(checksum, fileSize); + + //更新相同的附件 转码信息 todo + if (!CollectionUtils.isEmpty(toUpdateCommonSourceList) && toUpdateCommonSourceList.size() > 0) { + fileIDList.addAll(toUpdateCommonSourceList); + ioFileDao.updateSameFile(commonSource, toUpdateCommonSourceList); + } + } + + + /** 更新视频其他信息 */ + this.updatePreviewUrlValue2(fileIDList, m3u8Path, mediaPicPath, playLength, resolution, frame); + } catch (Exception e){ + LogUtil.error(e, "转码入库失败, commonSource:"+ JsonUtils.beanToJson(commonSource)); + } + } + + public static Long getM3u8LineSize(String path) { + Long size = 0L; + List pathList = FileUtil.getM3u8LineList(path); + if (!CollectionUtils.isEmpty(pathList)){ + File file = null; + for (String p : pathList){ + String pf = p.replace(GlobalConfig.oldInnerServer, "").replace(GlobalConfig.m3u8ConvertUrlPlaceholder, ""); + file = new File(pf); + if (file.exists()){ + size = size + file.length(); + } + } + } + return size; + } + + private boolean checkConvertFile(String filePath, boolean isAttachment) { + String key = GlobalConfig.CONVERT_FILE_REDIS_KEY_PRE + filePath; + String exists = stringRedisTemplate.opsForValue().get(key); + RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); + Long pStartTime = bean.getStartTime(); + //有转码记录,且项目运行时长超过10分钟 + if (exists != null && System.currentTimeMillis() - pStartTime > GlobalConfig.RUN_TIME_OFFSET){ + LogUtil.info("相同文件重复转码:" + filePath + ", 是否附件" + isAttachment); + return false; + } else { + LogUtil.info("记录转码文件到redis:" + filePath + ", 是否附件" + isAttachment); + stringRedisTemplate.opsForValue().set(key, isAttachment ? "1" : "0", GlobalConfig.CONVERT_FILE_REDIS_TTL, TimeUnit.SECONDS); + } + return true; + } + + private String buildTsKey(Long id, String filePath, boolean isStrKey) throws Exception { + String preUrl = filePath.substring(0, filePath.lastIndexOf(".")); + String keyPath = preUrl + ".key"; + String keyInfoPath = preUrl + ".keyinfo"; + String keyUri = VideoUtil.buildKeyUri(id, filePath); + if (isStrKey){ + VideoUtil.buildTsKey(buildKey2, keyUri, keyPath, keyInfoPath); + } else { + VideoUtil.buildTsKey(buildKey, keyUri, keyPath, keyInfoPath); + } + return keyInfoPath; + } + + /** + * @Description: 文档类转码成功入库 + * @params: [courseWare, docPath] + * @Return: void + * @Modified: + */ + private void finishDoc(CommonSource commonSource, String docPath){ + try { + //更新文件表 + + commonSource.setIsPreview(1); + commonSource.setAppPreview(1); + commonSource.setAppPreviewUrl(docPath); + //更新文件表 + ioFileDao.updateDocConvert(commonSource); + + String checksum = commonSource.getHashMd5(); + Long fileSize = commonSource.getSize(); + this.updateSameDoc(checksum, fileSize, docPath, false, commonSource.getFileID()); + + LogUtil.info("文档类转码入库成功, commonsource" + JsonUtils.beanToJson(commonSource) ); + } catch (Exception e){ + LogUtil.error("转码入库失败, commonsource" + JsonUtils.beanToJson(commonSource)); + } + } + + private void updateSameDoc(String checksum, Long fileSize, String docPath, Boolean isSwf, Long fileID) { + //获取缺失转码信息的相同附件 + List toUpdateCommonSourceList = ioFileDao.getSameSourceEmptyInfoDoc(checksum, fileSize); + if (CollectionUtils.isEmpty(toUpdateCommonSourceList)){ + // 没有则只更新此文件的 appPreviewUrl + this.updatePreviewUrlValue(Arrays.asList(fileID), docPath, isSwf); + return; + } + Map updateMap = new HashMap<>(); + updateMap.put("now", new Date()); + updateMap.put("fileSize", fileSize); + updateMap.put("docPath", docPath); + // app_preview_url = #{appPreviewUrl}, + //更新相同的附件 转码信息 + if (isSwf && toUpdateCommonSourceList.size() > 0){ + // preview_url = #{map.docPath}, + ioFileDao.updateSameFileSwf(updateMap, toUpdateCommonSourceList); + this.updatePreviewUrlValue(toUpdateCommonSourceList, docPath, isSwf); + return; + } + if (toUpdateCommonSourceList.size() > 0) { + // app_preview_url = #{map.docPath}, + ioFileDao.updateSameFileDoc(updateMap, toUpdateCommonSourceList); + this.updatePreviewUrlValue(toUpdateCommonSourceList, docPath, isSwf); + } + } + + private void updatePreviewUrlValue(List fileIDList, String docPath, boolean isSwf){ + if (CollectionUtils.isEmpty(fileIDList)){ + return; + } + List list = ioFileDao.getFileUrlValueList(fileIDList); + if (!CollectionUtils.isEmpty(list)){ + try { + FileMetaVo fileMetaVo = null; + for (IOFileMeta meta : list) { + if (ObjectUtils.isEmpty(meta.getValue())){ + fileMetaVo = new FileMetaVo(); + }else { + fileMetaVo = JsonUtils.jsonToBean(meta.getValue(), FileMetaVo.class); + } + if (isSwf){ + fileMetaVo.setViewUrl(docPath); + }else { + fileMetaVo.setAppViewUrl(docPath); + } + meta.setValue(JsonUtils.beanToJson(fileMetaVo)); + } + ioFileDao.updateFileUrlValue(list); + }catch (Exception e){ + LogUtil.error(e, "updatePreviewUrlValue fileMeta error " + JsonUtils.beanToJson(list)); + } + } + } + private void updatePreviewUrlValue2(List fileIDList, String docPath, String thumb, Integer convertedLength, String resolution, String frame){ + if (CollectionUtils.isEmpty(fileIDList)){ + return; + } + List list = ioFileDao.getFileUrlValueList(fileIDList); + if (!CollectionUtils.isEmpty(list)){ + try { + FileMetaVo fileMetaVo = null; + for (IOFileMeta meta : list) { + if (ObjectUtils.isEmpty(meta.getValue())){ + fileMetaVo = new FileMetaVo(); + }else { + fileMetaVo = JsonUtils.jsonToBean(meta.getValue(), FileMetaVo.class); + } + if (!ObjectUtils.isEmpty(convertedLength)) { + fileMetaVo.setLength(convertedLength); + } + if (!ObjectUtils.isEmpty(docPath)) { + fileMetaVo.setViewUrl(docPath); + } + if (ObjectUtils.isEmpty(fileMetaVo.getResolution()) && !ObjectUtils.isEmpty(resolution)) { + fileMetaVo.setResolution(resolution); + } + if (ObjectUtils.isEmpty(fileMetaVo.getFrame()) && !ObjectUtils.isEmpty(frame)) { + fileMetaVo.setFrame(frame); + } + if (!ObjectUtils.isEmpty(thumb)){ + if (ObjectUtils.isEmpty(fileMetaVo.getThumb())){ + fileMetaVo.setThumb(thumb); + }else { + if (!fileMetaVo.getThumb().equals(thumb)){ + try { + File f = new File(fileMetaVo.getThumb()); + if (f.exists()){ + //new File(thumb).delete(); + }else { + fileMetaVo.setThumb(thumb); + } + }catch (Exception e){ + LogUtil.error(e, "delete file error f=" +thumb + ",fileMetaVo= " + JsonUtils.beanToJson(fileMetaVo)); + } + } + } + } + meta.setValue(JsonUtils.beanToJson(fileMetaVo)); + } + ioFileDao.updateFileUrlValue(list); + }catch (Exception e){ + LogUtil.error(e, "updatePreviewUrlValue2 fileMeta error " + JsonUtils.beanToJson(list)); + } + } + } + + @Async(value = "asyncTaskExecutor") + public void updateYZPreviewUrlValue(List fileIDList, String urlData, boolean isValue){ + updateYZPreviewUrlValue(fileIDList, urlData); + } + + private void updateYZPreviewUrlValue(List fileIDList, String yzViewData){ + if (CollectionUtils.isEmpty(fileIDList)){ + return; + } + List list = ioFileDao.getFileUrlValueList(fileIDList); + if (!CollectionUtils.isEmpty(list)){ + try { + FileMetaVo fileMetaVo = null; + for (IOFileMeta meta : list) { + if (ObjectUtils.isEmpty(meta.getValue())){ + fileMetaVo = new FileMetaVo(); + }else { + fileMetaVo = JsonUtils.jsonToBean(meta.getValue(), FileMetaVo.class); + } + if (!ObjectUtils.isEmpty(yzViewData)) { + fileMetaVo.setYzViewData(yzViewData); + } + meta.setValue(JsonUtils.beanToJson(fileMetaVo)); + } + ioFileDao.updateFileUrlValue(list); + }catch (Exception e){ + LogUtil.error(e, "updateYZPreviewUrlValue fileMeta error " + JsonUtils.beanToJson(list)); + } + } + } + + private void updateAudioValue(List fileIDList, String sourceMp3Path){ + if (CollectionUtils.isEmpty(fileIDList)){ + return; + } + Integer length = VideoUtil.getVideoLength(sourceMp3Path); + + List list = ioFileDao.getFileUrlValueList(fileIDList); + if (!CollectionUtils.isEmpty(list)){ + try { + FileMetaVo fileMetaVo = null; + for (IOFileMeta meta : list) { + if (ObjectUtils.isEmpty(meta.getValue())){ + fileMetaVo = new FileMetaVo(); + }else { + fileMetaVo = JsonUtils.jsonToBean(meta.getValue(), FileMetaVo.class); + } + if (!ObjectUtils.isEmpty(length) && length > 0){ + fileMetaVo.setLength(length); + } + if (!ObjectUtils.isEmpty(sourceMp3Path)) { + fileMetaVo.setH264Path(sourceMp3Path); + } + meta.setValue(JsonUtils.beanToJson(fileMetaVo)); + } + ioFileDao.updateFileUrlValue(list); + }catch (Exception e){ + LogUtil.error(e, "updatePreviewUrlValue2 fileMeta error " + JsonUtils.beanToJson(list)); + } + } + } + + public void setCheckFileOther(String checksum, Long fileSize, String audioPicPath) { + + //获取缺失转码信息的相同附件 + List toUpdateCommonSourceList = ioFileDao.getSameSourceEmptyInfo(checksum, fileSize); + + if (!CollectionUtils.isEmpty(toUpdateCommonSourceList) && toUpdateCommonSourceList.size() > 1) { + /** 更新file其他信息 */ + this.updatePreviewUrlValue2(toUpdateCommonSourceList, "", audioPicPath, null, null, null); + } + } + + + /** + * @description: 转换音频方法 + * @param prefix + * @param commonSource + * @return void + */ + private void convertAudioCommon(String prefix, CommonSource commonSource) { + boolean isAudio = Arrays.asList(AudioType).contains(commonSource.getFileType()); + if (isAudio){ + if (commonSource.getIsH264Preview() != null && commonSource.getIsH264Preview().equals(1)){ + return; + } + //获得保存文件的路径 + //String basePath = ""; + String sourcePath; + sourcePath = commonSource.getPath(); + //记录了业务目录pre的,使用pre + //basePath = this.getPathByBusType(commonSource.getSourceType(), ""); + //文件名 + String fileName = sourcePath.substring(0,sourcePath.lastIndexOf(".")); + //待转码的文件路径 + String filePath = commonSource.getPath(); + // + if (!this.checkConvertFile(filePath, true)){ + return; + } + Long convertSize = 0L; + //转换后待mp3文件路径 + String mp3FilePath = ""; + //若是mp3,则无需要转码,直接用原有的 + if("mp3".equals(commonSource.getFileType().toLowerCase())) { + mp3FilePath = commonSource.getPath(); + } else { //转码下 已改 + mp3FilePath = storageService.getDefaultStorageDevicePath() + (PropertiesUtil.getUpConfig("audio.savePath") + fileName + ".mp3").replace("/private/cloud/", ""); + List audioPathList = new ArrayList<>(); + audioPathList.add(mp3FilePath); + //创建目录 + VideoUtil.mkMuDir(audioPathList); + + //转换工具(ffmpeg)的存放路径 + String ffmpegPath = "ffmpeg"; + // + boolean flag = VideoUtil.convertToMp3(prefix, ffmpegPath, filePath, mp3FilePath); + if(!flag){ + //转码失败的处理 + this.convertFail(commonSource, false); + // + return; + } + try { + File m = new File(mp3FilePath); + if (m.exists()){ + convertSize = m.length(); + } + }catch (Exception e){ + } + + //转码成功 + LogUtil.info(prefix+ "音频转码成功。commonSource:" + JsonUtils.beanToJson(commonSource)); + } + //音频转码成功后的处理 + this.finishAudio(prefix, commonSource, mp3FilePath, convertSize); + // + LogUtil.info(prefix+ "音频转码入库成功。commonSource:" + JsonUtils.beanToJson(commonSource)); + } else { + LogUtil.error(prefix + "不支持的文件类型里:" + commonSource.getFileType() + + ",参数:" + JsonUtils.beanToJson(commonSource)); + } + } + + /** + * @description: 音频转码成功后的处理 + * @param prefix + * @param commonSource + * @param sourceMp3Path + * @return void + */ + private void finishAudio(String prefix, CommonSource commonSource, String sourceMp3Path, Long convertSize) { + + if (convertSize > 0){ + commonSource.setConvertSize(convertSize); + try { + ioSourceDao.updateSourceConvertSize(commonSource.getSourceID(), convertSize); + }catch (Exception e){ + LogUtil.error(e, "finishAudio updateSourceConvertSize error"); + } + } + + try { + //更新文件表 + commonSource.setIsH264Preview(1); + commonSource.setH264Path(sourceMp3Path); + // + this.ioFileDao.updateAudioConvert(commonSource); + //特定业务的处理 + + this.updateAudioValue(Arrays.asList(commonSource.getFileID()), sourceMp3Path); + + } catch (Exception e){ + LogUtil.error(e, prefix + "转码入库失败, commonSource:"+ JsonUtils.beanToJson(commonSource) + + "mp3FilePath:"+ sourceMp3Path); + } + } + + public void convertCameraToImgCommon(String prefix, CommonSource commonSource) { + boolean isCamera = Arrays.asList(GlobalConfig.CAMERA_TYPE_ARR).contains(commonSource.getFileType()); + if (isCamera){ + if (commonSource.getIsH264Preview() != null && commonSource.getIsH264Preview().equals(1)){ + return; + } + + //获得保存文件的路径 + //String basePath = ""; + String sourcePath = commonSource.getPath(); + String suffix = FileUtil.getFileExtension(sourcePath); + //待转码的文件路径 + String filePath = commonSource.getPath(); + // + Long convertSize = 0L; + boolean flag = CameraUtil.cameraToImg(prefix, filePath); + //转换后待img文件路径 + String finishFilePath = filePath + ".thumb.jpg"; + File f = new File(finishFilePath); + if (!f.exists()){ + String tempPath = finishFilePath.replace(".thumb.jpg",".thumb.ppm"); + f = new File(tempPath); + if (!f.exists()){ + tempPath = tempPath.replace(".thumb.ppm",".ppm"); + f = new File(tempPath); + if (!f.exists()){ + LogUtil.error("convertCameraToImgCommon .thumb.jpg and .thumb.ppm and .ppm is all exist sourcePath=" + sourcePath); + return; + } + } + flag = CameraUtil.ppmConvertToJpg(tempPath, finishFilePath); + if (flag) { + try { + new File(tempPath).delete(); + } catch (Exception e) { + } + } + } + + + if(!flag){ + //转码失败的处理 + this.convertFail(commonSource, false); + // + return; + } + try { + File m = new File(finishFilePath); + if (m.exists()){ + convertSize = m.length(); + } + }catch (Exception e){ + } + + //转码成功 + LogUtil.info(prefix+ "相机文件成功。commonSource:" + JsonUtils.beanToJson(commonSource)); + //转码成功后的处理 + CameraUtil.finishCameraToImg(prefix, commonSource, finishFilePath, convertSize, ioSourceDao, ioFileDao); + // + + ImageUtil.createThumb(finishFilePath, "cloud", "", null, + "" , stringRedisTemplate, null, false); + + LogUtil.info(prefix+ " 入库成功。commonSource:" + JsonUtils.beanToJson(commonSource)); + } else { + LogUtil.error(prefix + "不支持的文件类型里:" + commonSource.getFileType() + + ",参数:" + JsonUtils.beanToJson(commonSource)); + } + + } + + +} diff --git a/src/main/java/com/svnlan/home/utils/CopyFileSaveUtil.java b/src/main/java/com/svnlan/home/utils/CopyFileSaveUtil.java new file mode 100644 index 0000000..953883f --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/CopyFileSaveUtil.java @@ -0,0 +1,95 @@ +package com.svnlan.home.utils; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.ChinesUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/9/8 17:10 + */ +@Component +public class CopyFileSaveUtil { + + public void saveParentLevelSource(CheckFileDTO updateFileDTO, Map parentMap, IoSourceDao ioSourceDao , LoginUser loginUser + , Integer targetType, List copyListByLevelCo, int s){ + + LogUtil.info("saveParentLevelSource s=" + s + ",parenatMp=" + JsonUtils.beanToJson(parentMap) + ",copyListByLevelCo=" + JsonUtils.beanToJson(copyListByLevelCo)); + if (s >= 50){ + LogUtil.info("saveParentLevelSource s=" + s); + return; + } + List copyListByLevel = new ArrayList<>(); + List nextCopyListByLevel = new ArrayList<>(); + if (!CollectionUtils.isEmpty(copyListByLevelCo)) { + for (IOSource source : copyListByLevelCo) { + + if (source.getParentID() > 0) { + source.setOldParentID(source.getParentID()); + source.setOldSourceID(source.getSourceID()); + source.setOldSourceLevel(source.getParentLevel() + source.getSourceID() + ","); + source.setOldParentLevel(source.getParentLevel()); + } + source.setParentID(0L); + source.setParentLevel(",0,"); + + source.setTargetID(loginUser.getUserID()); + source.setCreateUser(loginUser.getUserID()); + source.setModifyUser(loginUser.getUserID()); + source.setTargetType(targetType); + + source.setNamePinyin(ChinesUtil.getPingYin(source.getName())); + source.setNamePinyinSimple(ChinesUtil.getFirstSpell(source.getName())); + + if (!ObjectUtils.isEmpty(parentMap) && parentMap.containsKey(source.getOldParentLevel())) { + IOSource so = parentMap.get(source.getOldParentLevel()); + source.setParentID(so.getSourceID()); + source.setParentLevel(so.getParentLevel() + so.getSourceID() + ","); + } + LogUtil.info("saveParentLevelSource 移动 parentID=" + source.getParentID() +" updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO) + " copyListByLevelCo source=" + JsonUtils.beanToJson(source)); + if (source.getParentID() <= 0) { + LogUtil.error("saveParentLevelSource 移动出错 updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO) + " copyListByLevelCo source=" + JsonUtils.beanToJson(source)); + nextCopyListByLevel.add(source); + continue; + } + source.setSourceID(null); + + copyListByLevel.add(source); + } + } + + if (!CollectionUtils.isEmpty(copyListByLevel)) { + try { + ioSourceDao.batchInsert(copyListByLevel); + } catch (Exception e) { + LogUtil.error(e, "复制出错 copyListByLevel"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + for (IOSource source : copyListByLevel) { + parentMap.put(source.getOldSourceLevel(), source); + } + + LogUtil.info("saveParentLevelSource 移动 nextCopyListByLevel=" + JsonUtils.beanToJson(nextCopyListByLevel) +" updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO) ); + if (!CollectionUtils.isEmpty(nextCopyListByLevel)){ + saveParentLevelSource(updateFileDTO, parentMap, ioSourceDao , loginUser + , targetType, nextCopyListByLevel, s+1); + } + } + + + } +} diff --git a/src/main/java/com/svnlan/home/utils/DirectoryUtil.java b/src/main/java/com/svnlan/home/utils/DirectoryUtil.java new file mode 100644 index 0000000..ae4d796 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/DirectoryUtil.java @@ -0,0 +1,148 @@ +package com.svnlan.home.utils; + +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.LogTypeEnum; +import com.svnlan.enums.MetaEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.HomeExplorerDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.dao.IoSourceMetaDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.domain.IOSourceMeta; +import com.svnlan.home.domain.IoSourceEvent; +import com.svnlan.home.dto.AddSubCloudDirectoryDTO; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.ChinesUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + * @Author: sulijuan + * @Description: + */ +@Component +public class DirectoryUtil { + + @Resource + IoSourceDao ioSourceDao; + @Resource + FileOptionTool fileOptionTool; + @Resource + HomeExplorerDao homeExplorerDao; + @Resource + StorageService storageService; + @Resource + IoSourceMetaDao ioSourceMetaDao; + @Resource + SystemLogTool systemLogTool; + + + /** 批量添加文件夹 */ + public List addBatchDirectory(List list, LoginUser loginUser, CommonSource commonSource, HttpServletRequest request){ + + Integer targetType = commonSource.getTargetType(); + Long opUserId = loginUser.getUserID(); + // top第一层 + List sourceNameList = ioSourceDao.getSourceNameList(commonSource.getSourceID()); + List sourceMetaList = new ArrayList<>(); + List> paramList = new ArrayList<>(); + List eventList = new ArrayList<>(); + EventEnum eventEnum = EventEnum.mkdir; + AddSubCloudDirectoryDTO addSubCloudDirectoryDTO = new AddSubCloudDirectoryDTO(); + addSubCloudDirectoryDTO.setSourceID(commonSource.getSourceID()); + addSubCloudDirectoryDTO.setParentLevel(commonSource.getParentLevel()); + Integer storageID = storageService.getDefaultStorageDeviceId(); + + + this.addSubDir(list, addSubCloudDirectoryDTO, targetType, opUserId + , sourceNameList, eventEnum, eventList, sourceMetaList, storageID, paramList); + LogUtil.info("addBatchDir list=" + JsonUtils.beanToJson(list)); + + if (!CollectionUtils.isEmpty(sourceMetaList)){ + try { + ioSourceMetaDao.batchInsert(sourceMetaList); + }catch (Exception e){ + LogUtil.error(e, " sourceMetaList meta error paramList=" + JsonUtils.beanToJson(list) + ",sourceMetaList=" + JsonUtils.beanToJson(sourceMetaList)); + } + } + if (!CollectionUtils.isEmpty(eventList)){ + fileOptionTool.addSourceEventList(eventList); + } + + + + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileMkDir.getCode(), paramList, request); + return list; + } + + + private void addSubDir(List list, AddSubCloudDirectoryDTO addSubCloudDirectoryDTO, Integer targetType, Long opUserId + , List sourceNameList,EventEnum eventEnum, List eventList, List sourceMetaList, Integer storageID + ,List> paramList){ + + /** 操作日志 */ + Map reMap = null; + for (AddSubCloudDirectoryDTO firstSource : list){ + if (!CollectionUtils.isEmpty(sourceNameList)){ + firstSource.setOldName(firstSource.getName()); + firstSource.setName(fileOptionTool.checkRepeatName(firstSource.getName(), firstSource.getName(), sourceNameList, 1)); + } + firstSource.setParentLevel(addSubCloudDirectoryDTO.getParentLevel() + addSubCloudDirectoryDTO.getSourceID() + ","); + firstSource.setTargetID(opUserId); + firstSource.setCreateUser(opUserId); + firstSource.setModifyUser(opUserId); + firstSource.setIsFolder(1); + firstSource.setTargetType(targetType); + firstSource.setFileType(""); + firstSource.setFileID(0L); + firstSource.setParentID(addSubCloudDirectoryDTO.getSourceID()); + firstSource.setStorageID(storageID); + firstSource.setNamePinyin(ChinesUtil.getPingYin(firstSource.getName())); + firstSource.setNamePinyinSimple(ChinesUtil.getFirstSpell(firstSource.getName())); + if (firstSource.getParentID() <= 0){ + LogUtil.error("创建文件夹失败,不可创建根目录文件"); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + try { + homeExplorerDao.createDirectory(firstSource); + }catch (Exception e){ + LogUtil.error(e, " createDirectory error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + if (ObjectUtils.isEmpty(firstSource.getSourceID()) && firstSource.getSourceID() <= 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + Long saveTopSourceID = firstSource.getSourceID(); + // 第一层文件夹拼音 + sourceMetaList.add(new IOSourceMeta(saveTopSourceID, MetaEnum.namePinyin.getValue(), ChinesUtil.getPingYin(firstSource.getName()))); + sourceMetaList.add(new IOSourceMeta(saveTopSourceID, MetaEnum.namePinyinSimple.getValue(), ChinesUtil.getFirstSpell(firstSource.getName()))); + // 第一层文件夹动态 + eventList.add(new IoSourceEvent(saveTopSourceID, firstSource.getParentID(), opUserId, eventEnum.getCode(), FileOptionTool.getSourceEventDesc(eventEnum, "", ""))); + + // 日志 + reMap = new HashMap<>(4); + reMap.put("sourceID", firstSource.getSourceID()); + reMap.put("sourceParent", firstSource.getParentID()); + reMap.put("type", "mkdir"); + reMap.put("pathName", firstSource.getName()); + paramList.add(reMap); + + if (!CollectionUtils.isEmpty(firstSource.getChildren())){ + addSubDir(firstSource.getChildren(), firstSource , targetType, opUserId + , null,eventEnum, eventList, sourceMetaList,storageID, paramList); + + } + } + } + +} diff --git a/src/main/java/com/svnlan/home/utils/EncodingDetects.java b/src/main/java/com/svnlan/home/utils/EncodingDetects.java new file mode 100644 index 0000000..01b619f --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/EncodingDetects.java @@ -0,0 +1,4621 @@ +package com.svnlan.home.utils; + +import java.io.*; +import java.net.URL; + +/** + * 自动获取文件的编码 + */ +public class EncodingDetects { + + /** + * 得到文件的编码 + * @param filePath 文件路径 + * @return 文件的编码 + */ + public static String getJavaEncode(String filePath){ + BytesEncodingDetect s = new BytesEncodingDetect(); + String fileCode = BytesEncodingDetect.javaname[s.detectEncoding(new File(filePath))]; + return fileCode; + } + + public static void readFile(String file, String code) { + + BufferedReader fr; + try { + String myCode = code!=null&&!"".equals(code) ? code : "UTF8"; + InputStreamReader read = new InputStreamReader(new FileInputStream( + file), myCode); + + fr = new BufferedReader(read); + String line = null; + int flag=1; + // 读取每一行,如果结束了,line会为空 + while ((line = fr.readLine()) != null && line.trim().length() > 0) { + if(flag==1) { + line=line.substring(1);//去掉文件头 + flag++; + } + // 每一行创建一个Student对象,并存入数组中 + System.out.println(line); + } + fr.close(); + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} + +class BytesEncodingDetect extends Encoding { + // Frequency tables to hold the GB, Big5, and EUC-TW character + // frequencies + int GBFreq[][]; + + int GBKFreq[][]; + + int Big5Freq[][]; + + int Big5PFreq[][]; + + int EUC_TWFreq[][]; + + int KRFreq[][]; + + int JPFreq[][]; + + // int UnicodeFreq[94][128]; + // public static String[] nicename; + // public static String[] codings; + public boolean debug; + + public BytesEncodingDetect() { + super(); + debug = false; + GBFreq = new int[94][94]; + GBKFreq = new int[126][191]; + Big5Freq = new int[94][158]; + Big5PFreq = new int[126][191]; + EUC_TWFreq = new int[94][94]; + KRFreq = new int[94][94]; + JPFreq = new int[94][94]; + // Initialize the Frequency Table for GB, GBK, Big5, EUC-TW, KR, JP + initialize_frequencies(); + } + + public static void main(String argc[]) { + BytesEncodingDetect sinodetector; + int result = OTHER; + int i; + sinodetector = new BytesEncodingDetect(); + for (i = 0; i < argc.length; i++) { + if (argc[i].startsWith("http://") == true) { + try { + result = sinodetector.detectEncoding(new URL(argc[i])); + } catch (Exception e) { + System.err.println("Bad URL " + e.toString()); + } + } else if (argc[i].equals("-d")) { + sinodetector.debug = true; + continue; + } else { + result = sinodetector.detectEncoding(new File(argc[i])); + } + System.out.println(nicename[result]); + } + } + + /** + * Function : detectEncoding Aruguments: URL Returns : One of the encodings from the Encoding enumeration (GB2312, HZ, BIG5, + * EUC_TW, ASCII, or OTHER) Description: This function looks at the URL contents and assigns it a probability score for each + * encoding type. The encoding type with the highest probability is returned. + */ + public int detectEncoding(URL testurl) { + byte[] rawtext = new byte[10000]; + int bytesread = 0, byteoffset = 0; + int guess = OTHER; + InputStream chinesestream; + try { + chinesestream = testurl.openStream(); + while ((bytesread = chinesestream.read(rawtext, byteoffset, rawtext.length - byteoffset)) > 0) { + byteoffset += bytesread; + } + ; + chinesestream.close(); + guess = detectEncoding(rawtext); + } catch (Exception e) { + System.err.println("Error loading or using URL " + e.toString()); + guess = -1; + } + return guess; + } + + /** + * Function : detectEncoding Aruguments: File Returns : One of the encodings from the Encoding enumeration (GB2312, HZ, BIG5, + * EUC_TW, ASCII, or OTHER) Description: This function looks at the file and assigns it a probability score for each encoding + * type. The encoding type with the highest probability is returned. + */ + public int detectEncoding(File testfile) { + FileInputStream chinesefile; + byte[] rawtext; + rawtext = new byte[(int) testfile.length()]; + try { + chinesefile = new FileInputStream(testfile); + chinesefile.read(rawtext); + chinesefile.close(); + } catch (Exception e) { + System.err.println("Error: " + e); + } + return detectEncoding(rawtext); + } + + /** + * Function : detectEncoding Aruguments: byte array Returns : One of the encodings from the Encoding enumeration (GB2312, HZ, + * BIG5, EUC_TW, ASCII, or OTHER) Description: This function looks at the byte array and assigns it a probability score for + * each encoding type. The encoding type with the highest probability is returned. + */ + public int detectEncoding(byte[] rawtext) { + int[] scores; + int index, maxscore = 0; + int encoding_guess = OTHER; + scores = new int[TOTALTYPES]; + // Assign Scores + scores[GB2312] = gb2312_probability(rawtext); + scores[GBK] = gbk_probability(rawtext); + scores[GB18030] = gb18030_probability(rawtext); + scores[HZ] = hz_probability(rawtext); + scores[BIG5] = big5_probability(rawtext); + scores[CNS11643] = euc_tw_probability(rawtext); + scores[ISO2022CN] = iso_2022_cn_probability(rawtext); + scores[UTF8] = utf8_probability(rawtext); + scores[UNICODE] = utf16_probability(rawtext); + scores[EUC_KR] = euc_kr_probability(rawtext); + scores[CP949] = cp949_probability(rawtext); + scores[JOHAB] = 0; + scores[ISO2022KR] = iso_2022_kr_probability(rawtext); + scores[ASCII] = ascii_probability(rawtext); + scores[SJIS] = sjis_probability(rawtext); + scores[EUC_JP] = euc_jp_probability(rawtext); + scores[ISO2022JP] = iso_2022_jp_probability(rawtext); + scores[UNICODET] = 0; + scores[UNICODES] = 0; + scores[ISO2022CN_GB] = 0; + scores[ISO2022CN_CNS] = 0; + scores[OTHER] = 0; + // Tabulate Scores + for (index = 0; index < TOTALTYPES; index++) { + if (debug) + System.err.println("Encoding " + nicename[index] + " score " + scores[index]); + if (scores[index] > maxscore) { + encoding_guess = index; + maxscore = scores[index]; + } + } + // Return OTHER if nothing scored above 50 + if (maxscore <= 50) { + encoding_guess = OTHER; + } + return encoding_guess; + } + + /* + * Function: gb2312_probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text + * in array uses GB-2312 encoding + */ + int gb2312_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, gbchars = 1; + long gbfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xF7 && (byte) 0xA1 <= rawtext[i + 1] + && rawtext[i + 1] <= (byte) 0xFE) { + gbchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + if (GBFreq[row][column] != 0) { + gbfreq += GBFreq[row][column]; + } else if (15 <= row && row < 55) { + // In GB high-freq character range + gbfreq += 200; + } + } + i++; + } + } + rangeval = 50 * ((float) gbchars / (float) dbchars); + freqval = 50 * ((float) gbfreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + /* + * Function: gbk_probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text in + * array uses GBK encoding + */ + int gbk_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, gbchars = 1; + long gbfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xF7 && // Original GB range + (byte) 0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE) { + gbchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + // System.out.println("original row " + row + " column " + column); + if (GBFreq[row][column] != 0) { + gbfreq += GBFreq[row][column]; + } else if (15 <= row && row < 55) { + gbfreq += 200; + } + } else if ((byte) 0x81 <= rawtext[i] + && rawtext[i] <= (byte) 0xFE + && // Extended GB range + (((byte) 0x80 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE) || ((byte) 0x40 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0x7E))) { + gbchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0x81; + if (0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) { + column = rawtext[i + 1] - 0x40; + } else { + column = rawtext[i + 1] + 256 - 0x40; + } + // System.out.println("extended row " + row + " column " + column + " rawtext[i] " + rawtext[i]); + if (GBKFreq[row][column] != 0) { + gbfreq += GBKFreq[row][column]; + } + } + i++; + } + } + rangeval = 50 * ((float) gbchars / (float) dbchars); + freqval = 50 * ((float) gbfreq / (float) totalfreq); + // For regular GB files, this would give the same score, so I handicap it slightly + return (int) (rangeval + freqval) - 1; + } + + /* + * Function: gb18030_probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text + * in array uses GBK encoding + */ + int gb18030_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, gbchars = 1; + long gbfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xF7 && // Original GB range + i + 1 < rawtextlen && (byte) 0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE) { + gbchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + // System.out.println("original row " + row + " column " + column); + if (GBFreq[row][column] != 0) { + gbfreq += GBFreq[row][column]; + } else if (15 <= row && row < 55) { + gbfreq += 200; + } + } else if ((byte) 0x81 <= rawtext[i] && rawtext[i] <= (byte) 0xFE + && // Extended GB range + i + 1 < rawtextlen + && (((byte) 0x80 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE) || ((byte) 0x40 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0x7E))) { + gbchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0x81; + if (0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) { + column = rawtext[i + 1] - 0x40; + } else { + column = rawtext[i + 1] + 256 - 0x40; + } + // System.out.println("extended row " + row + " column " + column + " rawtext[i] " + rawtext[i]); + if (GBKFreq[row][column] != 0) { + gbfreq += GBKFreq[row][column]; + } + } else if ((byte) 0x81 <= rawtext[i] + && rawtext[i] <= (byte) 0xFE + && // Extended GB range + i + 3 < rawtextlen && (byte) 0x30 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0x39 + && (byte) 0x81 <= rawtext[i + 2] && rawtext[i + 2] <= (byte) 0xFE && (byte) 0x30 <= rawtext[i + 3] + && rawtext[i + 3] <= (byte) 0x39) { + gbchars++; + /* + * totalfreq += 500; row = rawtext[i] + 256 - 0x81; if (0x40 <= rawtext[i+1] && rawtext[i+1] <= 0x7E) { column = + * rawtext[i+1] - 0x40; } else { column = rawtext[i+1] + 256 - 0x40; } //System.out.println("extended row " + row + " + * column " + column + " rawtext[i] " + rawtext[i]); if (GBKFreq[row][column] != 0) { gbfreq += GBKFreq[row][column]; } + */ + } + i++; + } + } + rangeval = 50 * ((float) gbchars / (float) dbchars); + freqval = 50 * ((float) gbfreq / (float) totalfreq); + // For regular GB files, this would give the same score, so I handicap it slightly + return (int) (rangeval + freqval) - 1; + } + + /* + * Function: hz_probability Argument: byte array Returns : number from 0 to 100 representing probability text in array uses HZ + * encoding + */ + int hz_probability(byte[] rawtext) { + int i, rawtextlen; + int hzchars = 0, dbchars = 1; + long hzfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int hzstart = 0, hzend = 0; + int row, column; + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen; i++) { + if (rawtext[i] == '~' && i < rawtextlen - 1) { + if (rawtext[i + 1] == '{') { + hzstart++; + i += 2; + while (i < rawtextlen - 1) { + if (rawtext[i] == 0x0A || rawtext[i] == 0x0D) { + break; + } else if (rawtext[i] == '~' && rawtext[i + 1] == '}') { + hzend++; + i++; + break; + } else if ((0x21 <= rawtext[i] && rawtext[i] <= 0x77) && (0x21 <= rawtext[i + 1] && rawtext[i + 1] <= 0x77)) { + hzchars += 2; + row = rawtext[i] - 0x21; + column = rawtext[i + 1] - 0x21; + totalfreq += 500; + if (GBFreq[row][column] != 0) { + hzfreq += GBFreq[row][column]; + } else if (15 <= row && row < 55) { + hzfreq += 200; + } + } else if ((0xA1 <= rawtext[i] && rawtext[i] <= 0xF7) && (0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= 0xF7)) { + hzchars += 2; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + totalfreq += 500; + if (GBFreq[row][column] != 0) { + hzfreq += GBFreq[row][column]; + } else if (15 <= row && row < 55) { + hzfreq += 200; + } + } + dbchars += 2; + i += 2; + } + } else if (rawtext[i + 1] == '}') { + hzend++; + i++; + } else if (rawtext[i + 1] == '~') { + i++; + } + } + } + if (hzstart > 4) { + rangeval = 50; + } else if (hzstart > 1) { + rangeval = 41; + } else if (hzstart > 0) { // Only 39 in case the sequence happened to occur + rangeval = 39; // in otherwise non-Hz text + } else { + rangeval = 0; + } + freqval = 50 * ((float) hzfreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + /** + * Function: big5_probability Argument: byte array Returns : number from 0 to 100 representing probability text in array uses + * Big5 encoding + */ + int big5_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, bfchars = 1; + float rangeval = 0, freqval = 0; + long bffreq = 0, totalfreq = 1; + int row, column; + // Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0xA1 <= rawtext[i] + && rawtext[i] <= (byte) 0xF9 + && (((byte) 0x40 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0x7E) || ((byte) 0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE))) { + bfchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + if (0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) { + column = rawtext[i + 1] - 0x40; + } else { + column = rawtext[i + 1] + 256 - 0x61; + } + if (Big5Freq[row][column] != 0) { + bffreq += Big5Freq[row][column]; + } else if (3 <= row && row <= 37) { + bffreq += 200; + } + } + i++; + } + } + rangeval = 50 * ((float) bfchars / (float) dbchars); + freqval = 50 * ((float) bffreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + /* + * Function: big5plus_probability Argument: pointer to unsigned char array Returns : number from 0 to 100 representing + * probability text in array uses Big5+ encoding + */ + int big5plus_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, bfchars = 1; + long bffreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 128) { + // asciichars++; + } else { + dbchars++; + if (0xA1 <= rawtext[i] && rawtext[i] <= 0xF9 && // Original Big5 range + ((0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) || (0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= 0xFE))) { + bfchars++; + totalfreq += 500; + row = rawtext[i] - 0xA1; + if (0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) { + column = rawtext[i + 1] - 0x40; + } else { + column = rawtext[i + 1] - 0x61; + } + // System.out.println("original row " + row + " column " + column); + if (Big5Freq[row][column] != 0) { + bffreq += Big5Freq[row][column]; + } else if (3 <= row && row < 37) { + bffreq += 200; + } + } else if (0x81 <= rawtext[i] && rawtext[i] <= 0xFE && // Extended Big5 range + ((0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) || (0x80 <= rawtext[i + 1] && rawtext[i + 1] <= 0xFE))) { + bfchars++; + totalfreq += 500; + row = rawtext[i] - 0x81; + if (0x40 <= rawtext[i + 1] && rawtext[i + 1] <= 0x7E) { + column = rawtext[i + 1] - 0x40; + } else { + column = rawtext[i + 1] - 0x40; + } + // System.out.println("extended row " + row + " column " + column + " rawtext[i] " + rawtext[i]); + if (Big5PFreq[row][column] != 0) { + bffreq += Big5PFreq[row][column]; + } + } + i++; + } + } + rangeval = 50 * ((float) bfchars / (float) dbchars); + freqval = 50 * ((float) bffreq / (float) totalfreq); + // For regular Big5 files, this would give the same score, so I handicap it slightly + return (int) (rangeval + freqval) - 1; + } + + /* + * Function: euc_tw_probability Argument: byte array Returns : number from 0 to 100 representing probability text in array + * uses EUC-TW (CNS 11643) encoding + */ + int euc_tw_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, cnschars = 1; + long cnsfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Check to see if characters fit into acceptable ranges + // and have expected frequency of use + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + if (rawtext[i] >= 0) { // in ASCII range + // asciichars++; + } else { // high bit set + dbchars++; + if (i + 3 < rawtextlen && (byte) 0x8E == rawtext[i] && (byte) 0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xB0 + && (byte) 0xA1 <= rawtext[i + 2] && rawtext[i + 2] <= (byte) 0xFE && (byte) 0xA1 <= rawtext[i + 3] + && rawtext[i + 3] <= (byte) 0xFE) { // Planes 1 - 16 + cnschars++; + // System.out.println("plane 2 or above CNS char"); + // These are all less frequent chars so just ignore freq + i += 3; + } else if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xFE && // Plane 1 + (byte) 0xA1 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE) { + cnschars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + if (EUC_TWFreq[row][column] != 0) { + cnsfreq += EUC_TWFreq[row][column]; + } else if (35 <= row && row <= 92) { + cnsfreq += 150; + } + i++; + } + } + } + rangeval = 50 * ((float) cnschars / (float) dbchars); + freqval = 50 * ((float) cnsfreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + /* + * Function: iso_2022_cn_probability Argument: byte array Returns : number from 0 to 100 representing probability text in + * array uses ISO 2022-CN encoding WORKS FOR BASIC CASES, BUT STILL NEEDS MORE WORK + */ + int iso_2022_cn_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, isochars = 1; + long isofreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Check to see if characters fit into acceptable ranges + // and have expected frequency of use + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + if (rawtext[i] == (byte) 0x1B && i + 3 < rawtextlen) { // Escape char ESC + if (rawtext[i + 1] == (byte) 0x24 && rawtext[i + 2] == 0x29 && rawtext[i + 3] == (byte) 0x41) { // GB Escape $ ) A + i += 4; + while (rawtext[i] != (byte) 0x1B) { + dbchars++; + if ((0x21 <= rawtext[i] && rawtext[i] <= 0x77) && (0x21 <= rawtext[i + 1] && rawtext[i + 1] <= 0x77)) { + isochars++; + row = rawtext[i] - 0x21; + column = rawtext[i + 1] - 0x21; + totalfreq += 500; + if (GBFreq[row][column] != 0) { + isofreq += GBFreq[row][column]; + } else if (15 <= row && row < 55) { + isofreq += 200; + } + i++; + } + i++; + } + } else if (i + 3 < rawtextlen && rawtext[i + 1] == (byte) 0x24 && rawtext[i + 2] == (byte) 0x29 + && rawtext[i + 3] == (byte) 0x47) { + // CNS Escape $ ) G + i += 4; + while (rawtext[i] != (byte) 0x1B) { + dbchars++; + if ((byte) 0x21 <= rawtext[i] && rawtext[i] <= (byte) 0x7E && (byte) 0x21 <= rawtext[i + 1] + && rawtext[i + 1] <= (byte) 0x7E) { + isochars++; + totalfreq += 500; + row = rawtext[i] - 0x21; + column = rawtext[i + 1] - 0x21; + if (EUC_TWFreq[row][column] != 0) { + isofreq += EUC_TWFreq[row][column]; + } else if (35 <= row && row <= 92) { + isofreq += 150; + } + i++; + } + i++; + } + } + if (rawtext[i] == (byte) 0x1B && i + 2 < rawtextlen && rawtext[i + 1] == (byte) 0x28 && rawtext[i + 2] == (byte) 0x42) { // ASCII: + // ESC + // ( B + i += 2; + } + } + } + rangeval = 50 * ((float) isochars / (float) dbchars); + freqval = 50 * ((float) isofreq / (float) totalfreq); + // System.out.println("isochars dbchars isofreq totalfreq " + isochars + " " + dbchars + " " + isofreq + " " + totalfreq + " + // " + rangeval + " " + freqval); + return (int) (rangeval + freqval); + // return 0; + } + + /* + * Function: utf8_probability Argument: byte array Returns : number from 0 to 100 representing probability text in array uses + * UTF-8 encoding of Unicode + */ + int utf8_probability(byte[] rawtext) { + int score = 0; + int i, rawtextlen = 0; + int goodbytes = 0, asciibytes = 0; + // Maybe also use UTF8 Byte Order Mark: EF BB BF + // Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen; i++) { + if ((rawtext[i] & (byte) 0x7F) == rawtext[i]) { // One byte + asciibytes++; + // Ignore ASCII, can throw off count + } else if (-64 <= rawtext[i] && rawtext[i] <= -33 && // Two bytes + i + 1 < rawtextlen && -128 <= rawtext[i + 1] && rawtext[i + 1] <= -65) { + goodbytes += 2; + i++; + } else if (-32 <= rawtext[i] && rawtext[i] <= -17 + && // Three bytes + i + 2 < rawtextlen && -128 <= rawtext[i + 1] && rawtext[i + 1] <= -65 && -128 <= rawtext[i + 2] + && rawtext[i + 2] <= -65) { + goodbytes += 3; + i += 2; + } + } + if (asciibytes == rawtextlen) { + return 0; + } + score = (int) (100 * ((float) goodbytes / (float) (rawtextlen - asciibytes))); + // System.out.println("rawtextlen " + rawtextlen + " goodbytes " + goodbytes + " asciibytes " + asciibytes + " score " + + // score); + // If not above 98, reduce to zero to prevent coincidental matches + // Allows for some (few) bad formed sequences + if (score > 98) { + return score; + } else if (score > 95 && goodbytes > 30) { + return score; + } else { + return 0; + } + } + + /* + * Function: utf16_probability Argument: byte array Returns : number from 0 to 100 representing probability text in array uses + * UTF-16 encoding of Unicode, guess based on BOM // NOT VERY GENERAL, NEEDS MUCH MORE WORK + */ + int utf16_probability(byte[] rawtext) { + // int score = 0; + // int i, rawtextlen = 0; + // int goodbytes = 0, asciibytes = 0; + if (rawtext.length > 1 && ((byte) 0xFE == rawtext[0] && (byte) 0xFF == rawtext[1]) || // Big-endian + ((byte) 0xFF == rawtext[0] && (byte) 0xFE == rawtext[1])) { // Little-endian + return 100; + } + return 0; + /* + * // Check to see if characters fit into acceptable ranges rawtextlen = rawtext.length; for (i = 0; i < rawtextlen; i++) { + * if ((rawtext[i] & (byte)0x7F) == rawtext[i]) { // One byte goodbytes += 1; asciibytes++; } else if ((rawtext[i] & + * (byte)0xDF) == rawtext[i]) { // Two bytes if (i+1 < rawtextlen && (rawtext[i+1] & (byte)0xBF) == rawtext[i+1]) { + * goodbytes += 2; i++; } } else if ((rawtext[i] & (byte)0xEF) == rawtext[i]) { // Three bytes if (i+2 < rawtextlen && + * (rawtext[i+1] & (byte)0xBF) == rawtext[i+1] && (rawtext[i+2] & (byte)0xBF) == rawtext[i+2]) { goodbytes += 3; i+=2; } } } + * + * score = (int)(100 * ((float)goodbytes/(float)rawtext.length)); // An all ASCII file is also a good UTF8 file, but I'd + * rather it // get identified as ASCII. Can delete following 3 lines otherwise if (goodbytes == asciibytes) { score = 0; } // + * If not above 90, reduce to zero to prevent coincidental matches if (score > 90) { return score; } else { return 0; } + */ + } + + /* + * Function: ascii_probability Argument: byte array Returns : number from 0 to 100 representing probability text in array uses + * all ASCII Description: Sees if array has any characters not in ASCII range, if so, score is reduced + */ + int ascii_probability(byte[] rawtext) { + int score = 75; + int i, rawtextlen; + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen; i++) { + if (rawtext[i] < 0) { + score = score - 5; + } else if (rawtext[i] == (byte) 0x1B) { // ESC (used by ISO 2022) + score = score - 5; + } + if (score <= 0) { + return 0; + } + } + return score; + } + + /* + * Function: euc_kr__probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text + * in array uses EUC-KR encoding + */ + int euc_kr_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, krchars = 1; + long krfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xFE && (byte) 0xA1 <= rawtext[i + 1] + && rawtext[i + 1] <= (byte) 0xFE) { + krchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + if (KRFreq[row][column] != 0) { + krfreq += KRFreq[row][column]; + } else if (15 <= row && row < 55) { + krfreq += 0; + } + } + i++; + } + } + rangeval = 50 * ((float) krchars / (float) dbchars); + freqval = 50 * ((float) krfreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + /* + * Function: cp949__probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text + * in array uses Cp949 encoding + */ + int cp949_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, krchars = 1; + long krfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0x81 <= rawtext[i] + && rawtext[i] <= (byte) 0xFE + && ((byte) 0x41 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0x5A || (byte) 0x61 <= rawtext[i + 1] + && rawtext[i + 1] <= (byte) 0x7A || (byte) 0x81 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFE)) { + krchars++; + totalfreq += 500; + if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xFE && (byte) 0xA1 <= rawtext[i + 1] + && rawtext[i + 1] <= (byte) 0xFE) { + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + if (KRFreq[row][column] != 0) { + krfreq += KRFreq[row][column]; + } + } + } + i++; + } + } + rangeval = 50 * ((float) krchars / (float) dbchars); + freqval = 50 * ((float) krfreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + int iso_2022_kr_probability(byte[] rawtext) { + int i; + for (i = 0; i < rawtext.length; i++) { + if (i + 3 < rawtext.length && rawtext[i] == 0x1b && (char) rawtext[i + 1] == '$' && (char) rawtext[i + 2] == ')' + && (char) rawtext[i + 3] == 'C') { + return 100; + } + } + return 0; + } + + /* + * Function: euc_jp_probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text + * in array uses EUC-JP encoding + */ + int euc_jp_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, jpchars = 1; + long jpfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xFE && (byte) 0xA1 <= rawtext[i + 1] + && rawtext[i + 1] <= (byte) 0xFE) { + jpchars++; + totalfreq += 500; + row = rawtext[i] + 256 - 0xA1; + column = rawtext[i + 1] + 256 - 0xA1; + if (JPFreq[row][column] != 0) { + jpfreq += JPFreq[row][column]; + } else if (15 <= row && row < 55) { + jpfreq += 0; + } + } + i++; + } + } + rangeval = 50 * ((float) jpchars / (float) dbchars); + freqval = 50 * ((float) jpfreq / (float) totalfreq); + return (int) (rangeval + freqval); + } + + int iso_2022_jp_probability(byte[] rawtext) { + int i; + for (i = 0; i < rawtext.length; i++) { + if (i + 2 < rawtext.length && rawtext[i] == 0x1b && (char) rawtext[i + 1] == '$' && (char) rawtext[i + 2] == 'B') { + return 100; + } + } + return 0; + } + + /* + * Function: sjis_probability Argument: pointer to byte array Returns : number from 0 to 100 representing probability text in + * array uses Shift-JIS encoding + */ + int sjis_probability(byte[] rawtext) { + int i, rawtextlen = 0; + int dbchars = 1, jpchars = 1; + long jpfreq = 0, totalfreq = 1; + float rangeval = 0, freqval = 0; + int row, column, adjust; + // Stage 1: Check to see if characters fit into acceptable ranges + rawtextlen = rawtext.length; + for (i = 0; i < rawtextlen - 1; i++) { + // System.err.println(rawtext[i]); + if (rawtext[i] >= 0) { + // asciichars++; + } else { + dbchars++; + if (i + 1 < rawtext.length + && (((byte) 0x81 <= rawtext[i] && rawtext[i] <= (byte) 0x9F) || ((byte) 0xE0 <= rawtext[i] && rawtext[i] <= (byte) 0xEF)) + && (((byte) 0x40 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0x7E) || ((byte) 0x80 <= rawtext[i + 1] && rawtext[i + 1] <= (byte) 0xFC))) { + jpchars++; + totalfreq += 500; + row = rawtext[i] + 256; + column = rawtext[i + 1] + 256; + if (column < 0x9f) { + adjust = 1; + if (column > 0x7f) { + column -= 0x20; + } else { + column -= 0x19; + } + } else { + adjust = 0; + column -= 0x7e; + } + if (row < 0xa0) { + row = ((row - 0x70) << 1) - adjust; + } else { + row = ((row - 0xb0) << 1) - adjust; + } + row -= 0x20; + column = 0x20; + // System.out.println("original row " + row + " column " + column); + if (row < JPFreq.length && column < JPFreq[row].length && JPFreq[row][column] != 0) { + jpfreq += JPFreq[row][column]; + } + i++; + } else if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xDF) { + // half-width katakana, convert to full-width + } + } + } + rangeval = 50 * ((float) jpchars / (float) dbchars); + freqval = 50 * ((float) jpfreq / (float) totalfreq); + // For regular GB files, this would give the same score, so I handicap it slightly + return (int) (rangeval + freqval) - 1; + } + + void initialize_frequencies() { + int i, j; + for (i = 0; i < 94; i++) { + for (j = 0; j < 94; j++) { + GBFreq[i][j] = 0; + } + } + for (i = 0; i < 126; i++) { + for (j = 0; j < 191; j++) { + GBKFreq[i][j] = 0; + } + } + for (i = 0; i < 94; i++) { + for (j = 0; j < 158; j++) { + Big5Freq[i][j] = 0; + } + } + for (i = 0; i < 126; i++) { + for (j = 0; j < 191; j++) { + Big5PFreq[i][j] = 0; + } + } + for (i = 0; i < 94; i++) { + for (j = 0; j < 94; j++) { + EUC_TWFreq[i][j] = 0; + } + } + for (i = 0; i < 94; i++) { + for (j = 0; j < 94; j++) { + JPFreq[i][j] = 0; + } + } + GBFreq[20][35] = 599; + GBFreq[49][26] = 598; + GBFreq[41][38] = 597; + GBFreq[17][26] = 596; + GBFreq[32][42] = 595; + GBFreq[39][42] = 594; + GBFreq[45][49] = 593; + GBFreq[51][57] = 592; + GBFreq[50][47] = 591; + GBFreq[42][90] = 590; + GBFreq[52][65] = 589; + GBFreq[53][47] = 588; + GBFreq[19][82] = 587; + GBFreq[31][19] = 586; + GBFreq[40][46] = 585; + GBFreq[24][89] = 584; + GBFreq[23][85] = 583; + GBFreq[20][28] = 582; + GBFreq[42][20] = 581; + GBFreq[34][38] = 580; + GBFreq[45][9] = 579; + GBFreq[54][50] = 578; + GBFreq[25][44] = 577; + GBFreq[35][66] = 576; + GBFreq[20][55] = 575; + GBFreq[18][85] = 574; + GBFreq[20][31] = 573; + GBFreq[49][17] = 572; + GBFreq[41][16] = 571; + GBFreq[35][73] = 570; + GBFreq[20][34] = 569; + GBFreq[29][44] = 568; + GBFreq[35][38] = 567; + GBFreq[49][9] = 566; + GBFreq[46][33] = 565; + GBFreq[49][51] = 564; + GBFreq[40][89] = 563; + GBFreq[26][64] = 562; + GBFreq[54][51] = 561; + GBFreq[54][36] = 560; + GBFreq[39][4] = 559; + GBFreq[53][13] = 558; + GBFreq[24][92] = 557; + GBFreq[27][49] = 556; + GBFreq[48][6] = 555; + GBFreq[21][51] = 554; + GBFreq[30][40] = 553; + GBFreq[42][92] = 552; + GBFreq[31][78] = 551; + GBFreq[25][82] = 550; + GBFreq[47][0] = 549; + GBFreq[34][19] = 548; + GBFreq[47][35] = 547; + GBFreq[21][63] = 546; + GBFreq[43][75] = 545; + GBFreq[21][87] = 544; + GBFreq[35][59] = 543; + GBFreq[25][34] = 542; + GBFreq[21][27] = 541; + GBFreq[39][26] = 540; + GBFreq[34][26] = 539; + GBFreq[39][52] = 538; + GBFreq[50][57] = 537; + GBFreq[37][79] = 536; + GBFreq[26][24] = 535; + GBFreq[22][1] = 534; + GBFreq[18][40] = 533; + GBFreq[41][33] = 532; + GBFreq[53][26] = 531; + GBFreq[54][86] = 530; + GBFreq[20][16] = 529; + GBFreq[46][74] = 528; + GBFreq[30][19] = 527; + GBFreq[45][35] = 526; + GBFreq[45][61] = 525; + GBFreq[30][9] = 524; + GBFreq[41][53] = 523; + GBFreq[41][13] = 522; + GBFreq[50][34] = 521; + GBFreq[53][86] = 520; + GBFreq[47][47] = 519; + GBFreq[22][28] = 518; + GBFreq[50][53] = 517; + GBFreq[39][70] = 516; + GBFreq[38][15] = 515; + GBFreq[42][88] = 514; + GBFreq[16][29] = 513; + GBFreq[27][90] = 512; + GBFreq[29][12] = 511; + GBFreq[44][22] = 510; + GBFreq[34][69] = 509; + GBFreq[24][10] = 508; + GBFreq[44][11] = 507; + GBFreq[39][92] = 506; + GBFreq[49][48] = 505; + GBFreq[31][46] = 504; + GBFreq[19][50] = 503; + GBFreq[21][14] = 502; + GBFreq[32][28] = 501; + GBFreq[18][3] = 500; + GBFreq[53][9] = 499; + GBFreq[34][80] = 498; + GBFreq[48][88] = 497; + GBFreq[46][53] = 496; + GBFreq[22][53] = 495; + GBFreq[28][10] = 494; + GBFreq[44][65] = 493; + GBFreq[20][10] = 492; + GBFreq[40][76] = 491; + GBFreq[47][8] = 490; + GBFreq[50][74] = 489; + GBFreq[23][62] = 488; + GBFreq[49][65] = 487; + GBFreq[28][87] = 486; + GBFreq[15][48] = 485; + GBFreq[22][7] = 484; + GBFreq[19][42] = 483; + GBFreq[41][20] = 482; + GBFreq[26][55] = 481; + GBFreq[21][93] = 480; + GBFreq[31][76] = 479; + GBFreq[34][31] = 478; + GBFreq[20][66] = 477; + GBFreq[51][33] = 476; + GBFreq[34][86] = 475; + GBFreq[37][67] = 474; + GBFreq[53][53] = 473; + GBFreq[40][88] = 472; + GBFreq[39][10] = 471; + GBFreq[24][3] = 470; + GBFreq[27][25] = 469; + GBFreq[26][15] = 468; + GBFreq[21][88] = 467; + GBFreq[52][62] = 466; + GBFreq[46][81] = 465; + GBFreq[38][72] = 464; + GBFreq[17][30] = 463; + GBFreq[52][92] = 462; + GBFreq[34][90] = 461; + GBFreq[21][7] = 460; + GBFreq[36][13] = 459; + GBFreq[45][41] = 458; + GBFreq[32][5] = 457; + GBFreq[26][89] = 456; + GBFreq[23][87] = 455; + GBFreq[20][39] = 454; + GBFreq[27][23] = 453; + GBFreq[25][59] = 452; + GBFreq[49][20] = 451; + GBFreq[54][77] = 450; + GBFreq[27][67] = 449; + GBFreq[47][33] = 448; + GBFreq[41][17] = 447; + GBFreq[19][81] = 446; + GBFreq[16][66] = 445; + GBFreq[45][26] = 444; + GBFreq[49][81] = 443; + GBFreq[53][55] = 442; + GBFreq[16][26] = 441; + GBFreq[54][62] = 440; + GBFreq[20][70] = 439; + GBFreq[42][35] = 438; + GBFreq[20][57] = 437; + GBFreq[34][36] = 436; + GBFreq[46][63] = 435; + GBFreq[19][45] = 434; + GBFreq[21][10] = 433; + GBFreq[52][93] = 432; + GBFreq[25][2] = 431; + GBFreq[30][57] = 430; + GBFreq[41][24] = 429; + GBFreq[28][43] = 428; + GBFreq[45][86] = 427; + GBFreq[51][56] = 426; + GBFreq[37][28] = 425; + GBFreq[52][69] = 424; + GBFreq[43][92] = 423; + GBFreq[41][31] = 422; + GBFreq[37][87] = 421; + GBFreq[47][36] = 420; + GBFreq[16][16] = 419; + GBFreq[40][56] = 418; + GBFreq[24][55] = 417; + GBFreq[17][1] = 416; + GBFreq[35][57] = 415; + GBFreq[27][50] = 414; + GBFreq[26][14] = 413; + GBFreq[50][40] = 412; + GBFreq[39][19] = 411; + GBFreq[19][89] = 410; + GBFreq[29][91] = 409; + GBFreq[17][89] = 408; + GBFreq[39][74] = 407; + GBFreq[46][39] = 406; + GBFreq[40][28] = 405; + GBFreq[45][68] = 404; + GBFreq[43][10] = 403; + GBFreq[42][13] = 402; + GBFreq[44][81] = 401; + GBFreq[41][47] = 400; + GBFreq[48][58] = 399; + GBFreq[43][68] = 398; + GBFreq[16][79] = 397; + GBFreq[19][5] = 396; + GBFreq[54][59] = 395; + GBFreq[17][36] = 394; + GBFreq[18][0] = 393; + GBFreq[41][5] = 392; + GBFreq[41][72] = 391; + GBFreq[16][39] = 390; + GBFreq[54][0] = 389; + GBFreq[51][16] = 388; + GBFreq[29][36] = 387; + GBFreq[47][5] = 386; + GBFreq[47][51] = 385; + GBFreq[44][7] = 384; + GBFreq[35][30] = 383; + GBFreq[26][9] = 382; + GBFreq[16][7] = 381; + GBFreq[32][1] = 380; + GBFreq[33][76] = 379; + GBFreq[34][91] = 378; + GBFreq[52][36] = 377; + GBFreq[26][77] = 376; + GBFreq[35][48] = 375; + GBFreq[40][80] = 374; + GBFreq[41][92] = 373; + GBFreq[27][93] = 372; + GBFreq[15][17] = 371; + GBFreq[16][76] = 370; + GBFreq[51][12] = 369; + GBFreq[18][20] = 368; + GBFreq[15][54] = 367; + GBFreq[50][5] = 366; + GBFreq[33][22] = 365; + GBFreq[37][57] = 364; + GBFreq[28][47] = 363; + GBFreq[42][31] = 362; + GBFreq[18][2] = 361; + GBFreq[43][64] = 360; + GBFreq[23][47] = 359; + GBFreq[28][79] = 358; + GBFreq[25][45] = 357; + GBFreq[23][91] = 356; + GBFreq[22][19] = 355; + GBFreq[25][46] = 354; + GBFreq[22][36] = 353; + GBFreq[54][85] = 352; + GBFreq[46][20] = 351; + GBFreq[27][37] = 350; + GBFreq[26][81] = 349; + GBFreq[42][29] = 348; + GBFreq[31][90] = 347; + GBFreq[41][59] = 346; + GBFreq[24][65] = 345; + GBFreq[44][84] = 344; + GBFreq[24][90] = 343; + GBFreq[38][54] = 342; + GBFreq[28][70] = 341; + GBFreq[27][15] = 340; + GBFreq[28][80] = 339; + GBFreq[29][8] = 338; + GBFreq[45][80] = 337; + GBFreq[53][37] = 336; + GBFreq[28][65] = 335; + GBFreq[23][86] = 334; + GBFreq[39][45] = 333; + GBFreq[53][32] = 332; + GBFreq[38][68] = 331; + GBFreq[45][78] = 330; + GBFreq[43][7] = 329; + GBFreq[46][82] = 328; + GBFreq[27][38] = 327; + GBFreq[16][62] = 326; + GBFreq[24][17] = 325; + GBFreq[22][70] = 324; + GBFreq[52][28] = 323; + GBFreq[23][40] = 322; + GBFreq[28][50] = 321; + GBFreq[42][91] = 320; + GBFreq[47][76] = 319; + GBFreq[15][42] = 318; + GBFreq[43][55] = 317; + GBFreq[29][84] = 316; + GBFreq[44][90] = 315; + GBFreq[53][16] = 314; + GBFreq[22][93] = 313; + GBFreq[34][10] = 312; + GBFreq[32][53] = 311; + GBFreq[43][65] = 310; + GBFreq[28][7] = 309; + GBFreq[35][46] = 308; + GBFreq[21][39] = 307; + GBFreq[44][18] = 306; + GBFreq[40][10] = 305; + GBFreq[54][53] = 304; + GBFreq[38][74] = 303; + GBFreq[28][26] = 302; + GBFreq[15][13] = 301; + GBFreq[39][34] = 300; + GBFreq[39][46] = 299; + GBFreq[42][66] = 298; + GBFreq[33][58] = 297; + GBFreq[15][56] = 296; + GBFreq[18][51] = 295; + GBFreq[49][68] = 294; + GBFreq[30][37] = 293; + GBFreq[51][84] = 292; + GBFreq[51][9] = 291; + GBFreq[40][70] = 290; + GBFreq[41][84] = 289; + GBFreq[28][64] = 288; + GBFreq[32][88] = 287; + GBFreq[24][5] = 286; + GBFreq[53][23] = 285; + GBFreq[42][27] = 284; + GBFreq[22][38] = 283; + GBFreq[32][86] = 282; + GBFreq[34][30] = 281; + GBFreq[38][63] = 280; + GBFreq[24][59] = 279; + GBFreq[22][81] = 278; + GBFreq[32][11] = 277; + GBFreq[51][21] = 276; + GBFreq[54][41] = 275; + GBFreq[21][50] = 274; + GBFreq[23][89] = 273; + GBFreq[19][87] = 272; + GBFreq[26][7] = 271; + GBFreq[30][75] = 270; + GBFreq[43][84] = 269; + GBFreq[51][25] = 268; + GBFreq[16][67] = 267; + GBFreq[32][9] = 266; + GBFreq[48][51] = 265; + GBFreq[39][7] = 264; + GBFreq[44][88] = 263; + GBFreq[52][24] = 262; + GBFreq[23][34] = 261; + GBFreq[32][75] = 260; + GBFreq[19][10] = 259; + GBFreq[28][91] = 258; + GBFreq[32][83] = 257; + GBFreq[25][75] = 256; + GBFreq[53][45] = 255; + GBFreq[29][85] = 254; + GBFreq[53][59] = 253; + GBFreq[16][2] = 252; + GBFreq[19][78] = 251; + GBFreq[15][75] = 250; + GBFreq[51][42] = 249; + GBFreq[45][67] = 248; + GBFreq[15][74] = 247; + GBFreq[25][81] = 246; + GBFreq[37][62] = 245; + GBFreq[16][55] = 244; + GBFreq[18][38] = 243; + GBFreq[23][23] = 242; + GBFreq[38][30] = 241; + GBFreq[17][28] = 240; + GBFreq[44][73] = 239; + GBFreq[23][78] = 238; + GBFreq[40][77] = 237; + GBFreq[38][87] = 236; + GBFreq[27][19] = 235; + GBFreq[38][82] = 234; + GBFreq[37][22] = 233; + GBFreq[41][30] = 232; + GBFreq[54][9] = 231; + GBFreq[32][30] = 230; + GBFreq[30][52] = 229; + GBFreq[40][84] = 228; + GBFreq[53][57] = 227; + GBFreq[27][27] = 226; + GBFreq[38][64] = 225; + GBFreq[18][43] = 224; + GBFreq[23][69] = 223; + GBFreq[28][12] = 222; + GBFreq[50][78] = 221; + GBFreq[50][1] = 220; + GBFreq[26][88] = 219; + GBFreq[36][40] = 218; + GBFreq[33][89] = 217; + GBFreq[41][28] = 216; + GBFreq[31][77] = 215; + GBFreq[46][1] = 214; + GBFreq[47][19] = 213; + GBFreq[35][55] = 212; + GBFreq[41][21] = 211; + GBFreq[27][10] = 210; + GBFreq[32][77] = 209; + GBFreq[26][37] = 208; + GBFreq[20][33] = 207; + GBFreq[41][52] = 206; + GBFreq[32][18] = 205; + GBFreq[38][13] = 204; + GBFreq[20][18] = 203; + GBFreq[20][24] = 202; + GBFreq[45][19] = 201; + GBFreq[18][53] = 200; + /* + * GBFreq[39][0] = 199; GBFreq[40][71] = 198; GBFreq[41][27] = 197; GBFreq[15][69] = 196; GBFreq[42][10] = 195; + * GBFreq[31][89] = 194; GBFreq[51][28] = 193; GBFreq[41][22] = 192; GBFreq[40][43] = 191; GBFreq[38][6] = 190; + * GBFreq[37][11] = 189; GBFreq[39][60] = 188; GBFreq[48][47] = 187; GBFreq[46][80] = 186; GBFreq[52][49] = 185; + * GBFreq[50][48] = 184; GBFreq[25][1] = 183; GBFreq[52][29] = 182; GBFreq[24][66] = 181; GBFreq[23][35] = 180; + * GBFreq[49][72] = 179; GBFreq[47][45] = 178; GBFreq[45][14] = 177; GBFreq[51][70] = 176; GBFreq[22][30] = 175; + * GBFreq[49][83] = 174; GBFreq[26][79] = 173; GBFreq[27][41] = 172; GBFreq[51][81] = 171; GBFreq[41][54] = 170; + * GBFreq[20][4] = 169; GBFreq[29][60] = 168; GBFreq[20][27] = 167; GBFreq[50][15] = 166; GBFreq[41][6] = 165; + * GBFreq[35][34] = 164; GBFreq[44][87] = 163; GBFreq[46][66] = 162; GBFreq[42][37] = 161; GBFreq[42][24] = 160; + * GBFreq[54][7] = 159; GBFreq[41][14] = 158; GBFreq[39][83] = 157; GBFreq[16][87] = 156; GBFreq[20][59] = 155; + * GBFreq[42][12] = 154; GBFreq[47][2] = 153; GBFreq[21][32] = 152; GBFreq[53][29] = 151; GBFreq[22][40] = 150; + * GBFreq[24][58] = 149; GBFreq[52][88] = 148; GBFreq[29][30] = 147; GBFreq[15][91] = 146; GBFreq[54][72] = 145; + * GBFreq[51][75] = 144; GBFreq[33][67] = 143; GBFreq[41][50] = 142; GBFreq[27][34] = 141; GBFreq[46][17] = 140; + * GBFreq[31][74] = 139; GBFreq[42][67] = 138; GBFreq[54][87] = 137; GBFreq[27][14] = 136; GBFreq[16][63] = 135; + * GBFreq[16][5] = 134; GBFreq[43][23] = 133; GBFreq[23][13] = 132; GBFreq[31][12] = 131; GBFreq[25][57] = 130; + * GBFreq[38][49] = 129; GBFreq[42][69] = 128; GBFreq[23][80] = 127; GBFreq[29][0] = 126; GBFreq[28][2] = 125; + * GBFreq[28][17] = 124; GBFreq[17][27] = 123; GBFreq[40][16] = 122; GBFreq[45][1] = 121; GBFreq[36][33] = 120; + * GBFreq[35][23] = 119; GBFreq[20][86] = 118; GBFreq[29][53] = 117; GBFreq[23][88] = 116; GBFreq[51][87] = 115; + * GBFreq[54][27] = 114; GBFreq[44][36] = 113; GBFreq[21][45] = 112; GBFreq[53][52] = 111; GBFreq[31][53] = 110; + * GBFreq[38][47] = 109; GBFreq[27][21] = 108; GBFreq[30][42] = 107; GBFreq[29][10] = 106; GBFreq[35][35] = 105; + * GBFreq[24][56] = 104; GBFreq[41][29] = 103; GBFreq[18][68] = 102; GBFreq[29][24] = 101; GBFreq[25][84] = 100; + * GBFreq[35][47] = 99; GBFreq[29][56] = 98; GBFreq[30][44] = 97; GBFreq[53][3] = 96; GBFreq[30][63] = 95; GBFreq[52][52] = + * 94; GBFreq[54][1] = 93; GBFreq[22][48] = 92; GBFreq[54][66] = 91; GBFreq[21][90] = 90; GBFreq[52][47] = 89; + * GBFreq[39][25] = 88; GBFreq[39][39] = 87; GBFreq[44][37] = 86; GBFreq[44][76] = 85; GBFreq[46][75] = 84; GBFreq[18][37] = + * 83; GBFreq[47][42] = 82; GBFreq[19][92] = 81; GBFreq[51][27] = 80; GBFreq[48][83] = 79; GBFreq[23][70] = 78; + * GBFreq[29][9] = 77; GBFreq[33][79] = 76; GBFreq[52][90] = 75; GBFreq[53][6] = 74; GBFreq[24][36] = 73; GBFreq[25][25] = + * 72; GBFreq[44][26] = 71; GBFreq[25][36] = 70; GBFreq[29][87] = 69; GBFreq[48][0] = 68; GBFreq[15][40] = 67; + * GBFreq[17][45] = 66; GBFreq[30][14] = 65; GBFreq[48][38] = 64; GBFreq[23][19] = 63; GBFreq[40][42] = 62; GBFreq[31][63] = + * 61; GBFreq[16][23] = 60; GBFreq[26][21] = 59; GBFreq[32][76] = 58; GBFreq[23][58] = 57; GBFreq[41][37] = 56; + * GBFreq[30][43] = 55; GBFreq[47][38] = 54; GBFreq[21][46] = 53; GBFreq[18][33] = 52; GBFreq[52][37] = 51; GBFreq[36][8] = + * 50; GBFreq[49][24] = 49; GBFreq[15][66] = 48; GBFreq[35][77] = 47; GBFreq[27][58] = 46; GBFreq[35][51] = 45; + * GBFreq[24][69] = 44; GBFreq[20][54] = 43; GBFreq[24][41] = 42; GBFreq[41][0] = 41; GBFreq[33][71] = 40; GBFreq[23][52] = + * 39; GBFreq[29][67] = 38; GBFreq[46][51] = 37; GBFreq[46][90] = 36; GBFreq[49][33] = 35; GBFreq[33][28] = 34; + * GBFreq[37][86] = 33; GBFreq[39][22] = 32; GBFreq[37][37] = 31; GBFreq[29][62] = 30; GBFreq[29][50] = 29; GBFreq[36][89] = + * 28; GBFreq[42][44] = 27; GBFreq[51][82] = 26; GBFreq[28][83] = 25; GBFreq[15][78] = 24; GBFreq[46][62] = 23; + * GBFreq[19][69] = 22; GBFreq[51][23] = 21; GBFreq[37][69] = 20; GBFreq[25][5] = 19; GBFreq[51][85] = 18; GBFreq[48][77] = + * 17; GBFreq[32][46] = 16; GBFreq[53][60] = 15; GBFreq[28][57] = 14; GBFreq[54][82] = 13; GBFreq[54][15] = 12; + * GBFreq[49][54] = 11; GBFreq[53][87] = 10; GBFreq[27][16] = 9; GBFreq[29][34] = 8; GBFreq[20][44] = 7; GBFreq[42][73] = 6; + * GBFreq[47][71] = 5; GBFreq[29][37] = 4; GBFreq[25][50] = 3; GBFreq[18][84] = 2; GBFreq[50][45] = 1; GBFreq[48][46] = 0; + */ + // GBFreq[43][89] = -1; GBFreq[54][68] = -2; + Big5Freq[9][89] = 600; + Big5Freq[11][15] = 599; + Big5Freq[3][66] = 598; + Big5Freq[6][121] = 597; + Big5Freq[3][0] = 596; + Big5Freq[5][82] = 595; + Big5Freq[3][42] = 594; + Big5Freq[5][34] = 593; + Big5Freq[3][8] = 592; + Big5Freq[3][6] = 591; + Big5Freq[3][67] = 590; + Big5Freq[7][139] = 589; + Big5Freq[23][137] = 588; + Big5Freq[12][46] = 587; + Big5Freq[4][8] = 586; + Big5Freq[4][41] = 585; + Big5Freq[18][47] = 584; + Big5Freq[12][114] = 583; + Big5Freq[6][1] = 582; + Big5Freq[22][60] = 581; + Big5Freq[5][46] = 580; + Big5Freq[11][79] = 579; + Big5Freq[3][23] = 578; + Big5Freq[7][114] = 577; + Big5Freq[29][102] = 576; + Big5Freq[19][14] = 575; + Big5Freq[4][133] = 574; + Big5Freq[3][29] = 573; + Big5Freq[4][109] = 572; + Big5Freq[14][127] = 571; + Big5Freq[5][48] = 570; + Big5Freq[13][104] = 569; + Big5Freq[3][132] = 568; + Big5Freq[26][64] = 567; + Big5Freq[7][19] = 566; + Big5Freq[4][12] = 565; + Big5Freq[11][124] = 564; + Big5Freq[7][89] = 563; + Big5Freq[15][124] = 562; + Big5Freq[4][108] = 561; + Big5Freq[19][66] = 560; + Big5Freq[3][21] = 559; + Big5Freq[24][12] = 558; + Big5Freq[28][111] = 557; + Big5Freq[12][107] = 556; + Big5Freq[3][112] = 555; + Big5Freq[8][113] = 554; + Big5Freq[5][40] = 553; + Big5Freq[26][145] = 552; + Big5Freq[3][48] = 551; + Big5Freq[3][70] = 550; + Big5Freq[22][17] = 549; + Big5Freq[16][47] = 548; + Big5Freq[3][53] = 547; + Big5Freq[4][24] = 546; + Big5Freq[32][120] = 545; + Big5Freq[24][49] = 544; + Big5Freq[24][142] = 543; + Big5Freq[18][66] = 542; + Big5Freq[29][150] = 541; + Big5Freq[5][122] = 540; + Big5Freq[5][114] = 539; + Big5Freq[3][44] = 538; + Big5Freq[10][128] = 537; + Big5Freq[15][20] = 536; + Big5Freq[13][33] = 535; + Big5Freq[14][87] = 534; + Big5Freq[3][126] = 533; + Big5Freq[4][53] = 532; + Big5Freq[4][40] = 531; + Big5Freq[9][93] = 530; + Big5Freq[15][137] = 529; + Big5Freq[10][123] = 528; + Big5Freq[4][56] = 527; + Big5Freq[5][71] = 526; + Big5Freq[10][8] = 525; + Big5Freq[5][16] = 524; + Big5Freq[5][146] = 523; + Big5Freq[18][88] = 522; + Big5Freq[24][4] = 521; + Big5Freq[20][47] = 520; + Big5Freq[5][33] = 519; + Big5Freq[9][43] = 518; + Big5Freq[20][12] = 517; + Big5Freq[20][13] = 516; + Big5Freq[5][156] = 515; + Big5Freq[22][140] = 514; + Big5Freq[8][146] = 513; + Big5Freq[21][123] = 512; + Big5Freq[4][90] = 511; + Big5Freq[5][62] = 510; + Big5Freq[17][59] = 509; + Big5Freq[10][37] = 508; + Big5Freq[18][107] = 507; + Big5Freq[14][53] = 506; + Big5Freq[22][51] = 505; + Big5Freq[8][13] = 504; + Big5Freq[5][29] = 503; + Big5Freq[9][7] = 502; + Big5Freq[22][14] = 501; + Big5Freq[8][55] = 500; + Big5Freq[33][9] = 499; + Big5Freq[16][64] = 498; + Big5Freq[7][131] = 497; + Big5Freq[34][4] = 496; + Big5Freq[7][101] = 495; + Big5Freq[11][139] = 494; + Big5Freq[3][135] = 493; + Big5Freq[7][102] = 492; + Big5Freq[17][13] = 491; + Big5Freq[3][20] = 490; + Big5Freq[27][106] = 489; + Big5Freq[5][88] = 488; + Big5Freq[6][33] = 487; + Big5Freq[5][139] = 486; + Big5Freq[6][0] = 485; + Big5Freq[17][58] = 484; + Big5Freq[5][133] = 483; + Big5Freq[9][107] = 482; + Big5Freq[23][39] = 481; + Big5Freq[5][23] = 480; + Big5Freq[3][79] = 479; + Big5Freq[32][97] = 478; + Big5Freq[3][136] = 477; + Big5Freq[4][94] = 476; + Big5Freq[21][61] = 475; + Big5Freq[23][123] = 474; + Big5Freq[26][16] = 473; + Big5Freq[24][137] = 472; + Big5Freq[22][18] = 471; + Big5Freq[5][1] = 470; + Big5Freq[20][119] = 469; + Big5Freq[3][7] = 468; + Big5Freq[10][79] = 467; + Big5Freq[15][105] = 466; + Big5Freq[3][144] = 465; + Big5Freq[12][80] = 464; + Big5Freq[15][73] = 463; + Big5Freq[3][19] = 462; + Big5Freq[8][109] = 461; + Big5Freq[3][15] = 460; + Big5Freq[31][82] = 459; + Big5Freq[3][43] = 458; + Big5Freq[25][119] = 457; + Big5Freq[16][111] = 456; + Big5Freq[7][77] = 455; + Big5Freq[3][95] = 454; + Big5Freq[24][82] = 453; + Big5Freq[7][52] = 452; + Big5Freq[9][151] = 451; + Big5Freq[3][129] = 450; + Big5Freq[5][87] = 449; + Big5Freq[3][55] = 448; + Big5Freq[8][153] = 447; + Big5Freq[4][83] = 446; + Big5Freq[3][114] = 445; + Big5Freq[23][147] = 444; + Big5Freq[15][31] = 443; + Big5Freq[3][54] = 442; + Big5Freq[11][122] = 441; + Big5Freq[4][4] = 440; + Big5Freq[34][149] = 439; + Big5Freq[3][17] = 438; + Big5Freq[21][64] = 437; + Big5Freq[26][144] = 436; + Big5Freq[4][62] = 435; + Big5Freq[8][15] = 434; + Big5Freq[35][80] = 433; + Big5Freq[7][110] = 432; + Big5Freq[23][114] = 431; + Big5Freq[3][108] = 430; + Big5Freq[3][62] = 429; + Big5Freq[21][41] = 428; + Big5Freq[15][99] = 427; + Big5Freq[5][47] = 426; + Big5Freq[4][96] = 425; + Big5Freq[20][122] = 424; + Big5Freq[5][21] = 423; + Big5Freq[4][157] = 422; + Big5Freq[16][14] = 421; + Big5Freq[3][117] = 420; + Big5Freq[7][129] = 419; + Big5Freq[4][27] = 418; + Big5Freq[5][30] = 417; + Big5Freq[22][16] = 416; + Big5Freq[5][64] = 415; + Big5Freq[17][99] = 414; + Big5Freq[17][57] = 413; + Big5Freq[8][105] = 412; + Big5Freq[5][112] = 411; + Big5Freq[20][59] = 410; + Big5Freq[6][129] = 409; + Big5Freq[18][17] = 408; + Big5Freq[3][92] = 407; + Big5Freq[28][118] = 406; + Big5Freq[3][109] = 405; + Big5Freq[31][51] = 404; + Big5Freq[13][116] = 403; + Big5Freq[6][15] = 402; + Big5Freq[36][136] = 401; + Big5Freq[12][74] = 400; + Big5Freq[20][88] = 399; + Big5Freq[36][68] = 398; + Big5Freq[3][147] = 397; + Big5Freq[15][84] = 396; + Big5Freq[16][32] = 395; + Big5Freq[16][58] = 394; + Big5Freq[7][66] = 393; + Big5Freq[23][107] = 392; + Big5Freq[9][6] = 391; + Big5Freq[12][86] = 390; + Big5Freq[23][112] = 389; + Big5Freq[37][23] = 388; + Big5Freq[3][138] = 387; + Big5Freq[20][68] = 386; + Big5Freq[15][116] = 385; + Big5Freq[18][64] = 384; + Big5Freq[12][139] = 383; + Big5Freq[11][155] = 382; + Big5Freq[4][156] = 381; + Big5Freq[12][84] = 380; + Big5Freq[18][49] = 379; + Big5Freq[25][125] = 378; + Big5Freq[25][147] = 377; + Big5Freq[15][110] = 376; + Big5Freq[19][96] = 375; + Big5Freq[30][152] = 374; + Big5Freq[6][31] = 373; + Big5Freq[27][117] = 372; + Big5Freq[3][10] = 371; + Big5Freq[6][131] = 370; + Big5Freq[13][112] = 369; + Big5Freq[36][156] = 368; + Big5Freq[4][60] = 367; + Big5Freq[15][121] = 366; + Big5Freq[4][112] = 365; + Big5Freq[30][142] = 364; + Big5Freq[23][154] = 363; + Big5Freq[27][101] = 362; + Big5Freq[9][140] = 361; + Big5Freq[3][89] = 360; + Big5Freq[18][148] = 359; + Big5Freq[4][69] = 358; + Big5Freq[16][49] = 357; + Big5Freq[6][117] = 356; + Big5Freq[36][55] = 355; + Big5Freq[5][123] = 354; + Big5Freq[4][126] = 353; + Big5Freq[4][119] = 352; + Big5Freq[9][95] = 351; + Big5Freq[5][24] = 350; + Big5Freq[16][133] = 349; + Big5Freq[10][134] = 348; + Big5Freq[26][59] = 347; + Big5Freq[6][41] = 346; + Big5Freq[6][146] = 345; + Big5Freq[19][24] = 344; + Big5Freq[5][113] = 343; + Big5Freq[10][118] = 342; + Big5Freq[34][151] = 341; + Big5Freq[9][72] = 340; + Big5Freq[31][25] = 339; + Big5Freq[18][126] = 338; + Big5Freq[18][28] = 337; + Big5Freq[4][153] = 336; + Big5Freq[3][84] = 335; + Big5Freq[21][18] = 334; + Big5Freq[25][129] = 333; + Big5Freq[6][107] = 332; + Big5Freq[12][25] = 331; + Big5Freq[17][109] = 330; + Big5Freq[7][76] = 329; + Big5Freq[15][15] = 328; + Big5Freq[4][14] = 327; + Big5Freq[23][88] = 326; + Big5Freq[18][2] = 325; + Big5Freq[6][88] = 324; + Big5Freq[16][84] = 323; + Big5Freq[12][48] = 322; + Big5Freq[7][68] = 321; + Big5Freq[5][50] = 320; + Big5Freq[13][54] = 319; + Big5Freq[7][98] = 318; + Big5Freq[11][6] = 317; + Big5Freq[9][80] = 316; + Big5Freq[16][41] = 315; + Big5Freq[7][43] = 314; + Big5Freq[28][117] = 313; + Big5Freq[3][51] = 312; + Big5Freq[7][3] = 311; + Big5Freq[20][81] = 310; + Big5Freq[4][2] = 309; + Big5Freq[11][16] = 308; + Big5Freq[10][4] = 307; + Big5Freq[10][119] = 306; + Big5Freq[6][142] = 305; + Big5Freq[18][51] = 304; + Big5Freq[8][144] = 303; + Big5Freq[10][65] = 302; + Big5Freq[11][64] = 301; + Big5Freq[11][130] = 300; + Big5Freq[9][92] = 299; + Big5Freq[18][29] = 298; + Big5Freq[18][78] = 297; + Big5Freq[18][151] = 296; + Big5Freq[33][127] = 295; + Big5Freq[35][113] = 294; + Big5Freq[10][155] = 293; + Big5Freq[3][76] = 292; + Big5Freq[36][123] = 291; + Big5Freq[13][143] = 290; + Big5Freq[5][135] = 289; + Big5Freq[23][116] = 288; + Big5Freq[6][101] = 287; + Big5Freq[14][74] = 286; + Big5Freq[7][153] = 285; + Big5Freq[3][101] = 284; + Big5Freq[9][74] = 283; + Big5Freq[3][156] = 282; + Big5Freq[4][147] = 281; + Big5Freq[9][12] = 280; + Big5Freq[18][133] = 279; + Big5Freq[4][0] = 278; + Big5Freq[7][155] = 277; + Big5Freq[9][144] = 276; + Big5Freq[23][49] = 275; + Big5Freq[5][89] = 274; + Big5Freq[10][11] = 273; + Big5Freq[3][110] = 272; + Big5Freq[3][40] = 271; + Big5Freq[29][115] = 270; + Big5Freq[9][100] = 269; + Big5Freq[21][67] = 268; + Big5Freq[23][145] = 267; + Big5Freq[10][47] = 266; + Big5Freq[4][31] = 265; + Big5Freq[4][81] = 264; + Big5Freq[22][62] = 263; + Big5Freq[4][28] = 262; + Big5Freq[27][39] = 261; + Big5Freq[27][54] = 260; + Big5Freq[32][46] = 259; + Big5Freq[4][76] = 258; + Big5Freq[26][15] = 257; + Big5Freq[12][154] = 256; + Big5Freq[9][150] = 255; + Big5Freq[15][17] = 254; + Big5Freq[5][129] = 253; + Big5Freq[10][40] = 252; + Big5Freq[13][37] = 251; + Big5Freq[31][104] = 250; + Big5Freq[3][152] = 249; + Big5Freq[5][22] = 248; + Big5Freq[8][48] = 247; + Big5Freq[4][74] = 246; + Big5Freq[6][17] = 245; + Big5Freq[30][82] = 244; + Big5Freq[4][116] = 243; + Big5Freq[16][42] = 242; + Big5Freq[5][55] = 241; + Big5Freq[4][64] = 240; + Big5Freq[14][19] = 239; + Big5Freq[35][82] = 238; + Big5Freq[30][139] = 237; + Big5Freq[26][152] = 236; + Big5Freq[32][32] = 235; + Big5Freq[21][102] = 234; + Big5Freq[10][131] = 233; + Big5Freq[9][128] = 232; + Big5Freq[3][87] = 231; + Big5Freq[4][51] = 230; + Big5Freq[10][15] = 229; + Big5Freq[4][150] = 228; + Big5Freq[7][4] = 227; + Big5Freq[7][51] = 226; + Big5Freq[7][157] = 225; + Big5Freq[4][146] = 224; + Big5Freq[4][91] = 223; + Big5Freq[7][13] = 222; + Big5Freq[17][116] = 221; + Big5Freq[23][21] = 220; + Big5Freq[5][106] = 219; + Big5Freq[14][100] = 218; + Big5Freq[10][152] = 217; + Big5Freq[14][89] = 216; + Big5Freq[6][138] = 215; + Big5Freq[12][157] = 214; + Big5Freq[10][102] = 213; + Big5Freq[19][94] = 212; + Big5Freq[7][74] = 211; + Big5Freq[18][128] = 210; + Big5Freq[27][111] = 209; + Big5Freq[11][57] = 208; + Big5Freq[3][131] = 207; + Big5Freq[30][23] = 206; + Big5Freq[30][126] = 205; + Big5Freq[4][36] = 204; + Big5Freq[26][124] = 203; + Big5Freq[4][19] = 202; + Big5Freq[9][152] = 201; + /* + * Big5Freq[5][0] = 200; Big5Freq[26][57] = 199; Big5Freq[13][155] = 198; Big5Freq[3][38] = 197; Big5Freq[9][155] = 196; + * Big5Freq[28][53] = 195; Big5Freq[15][71] = 194; Big5Freq[21][95] = 193; Big5Freq[15][112] = 192; Big5Freq[14][138] = 191; + * Big5Freq[8][18] = 190; Big5Freq[20][151] = 189; Big5Freq[37][27] = 188; Big5Freq[32][48] = 187; Big5Freq[23][66] = 186; + * Big5Freq[9][2] = 185; Big5Freq[13][133] = 184; Big5Freq[7][127] = 183; Big5Freq[3][11] = 182; Big5Freq[12][118] = 181; + * Big5Freq[13][101] = 180; Big5Freq[30][153] = 179; Big5Freq[4][65] = 178; Big5Freq[5][25] = 177; Big5Freq[5][140] = 176; + * Big5Freq[6][25] = 175; Big5Freq[4][52] = 174; Big5Freq[30][156] = 173; Big5Freq[16][13] = 172; Big5Freq[21][8] = 171; + * Big5Freq[19][74] = 170; Big5Freq[15][145] = 169; Big5Freq[9][15] = 168; Big5Freq[13][82] = 167; Big5Freq[26][86] = 166; + * Big5Freq[18][52] = 165; Big5Freq[6][109] = 164; Big5Freq[10][99] = 163; Big5Freq[18][101] = 162; Big5Freq[25][49] = 161; + * Big5Freq[31][79] = 160; Big5Freq[28][20] = 159; Big5Freq[12][115] = 158; Big5Freq[15][66] = 157; Big5Freq[11][104] = 156; + * Big5Freq[23][106] = 155; Big5Freq[34][157] = 154; Big5Freq[32][94] = 153; Big5Freq[29][88] = 152; Big5Freq[10][46] = 151; + * Big5Freq[13][118] = 150; Big5Freq[20][37] = 149; Big5Freq[12][30] = 148; Big5Freq[21][4] = 147; Big5Freq[16][33] = 146; + * Big5Freq[13][52] = 145; Big5Freq[4][7] = 144; Big5Freq[21][49] = 143; Big5Freq[3][27] = 142; Big5Freq[16][91] = 141; + * Big5Freq[5][155] = 140; Big5Freq[29][130] = 139; Big5Freq[3][125] = 138; Big5Freq[14][26] = 137; Big5Freq[15][39] = 136; + * Big5Freq[24][110] = 135; Big5Freq[7][141] = 134; Big5Freq[21][15] = 133; Big5Freq[32][104] = 132; Big5Freq[8][31] = 131; + * Big5Freq[34][112] = 130; Big5Freq[10][75] = 129; Big5Freq[21][23] = 128; Big5Freq[34][131] = 127; Big5Freq[12][3] = 126; + * Big5Freq[10][62] = 125; Big5Freq[9][120] = 124; Big5Freq[32][149] = 123; Big5Freq[8][44] = 122; Big5Freq[24][2] = 121; + * Big5Freq[6][148] = 120; Big5Freq[15][103] = 119; Big5Freq[36][54] = 118; Big5Freq[36][134] = 117; Big5Freq[11][7] = 116; + * Big5Freq[3][90] = 115; Big5Freq[36][73] = 114; Big5Freq[8][102] = 113; Big5Freq[12][87] = 112; Big5Freq[25][64] = 111; + * Big5Freq[9][1] = 110; Big5Freq[24][121] = 109; Big5Freq[5][75] = 108; Big5Freq[17][83] = 107; Big5Freq[18][57] = 106; + * Big5Freq[8][95] = 105; Big5Freq[14][36] = 104; Big5Freq[28][113] = 103; Big5Freq[12][56] = 102; Big5Freq[14][61] = 101; + * Big5Freq[25][138] = 100; Big5Freq[4][34] = 99; Big5Freq[11][152] = 98; Big5Freq[35][0] = 97; Big5Freq[4][15] = 96; + * Big5Freq[8][82] = 95; Big5Freq[20][73] = 94; Big5Freq[25][52] = 93; Big5Freq[24][6] = 92; Big5Freq[21][78] = 91; + * Big5Freq[17][32] = 90; Big5Freq[17][91] = 89; Big5Freq[5][76] = 88; Big5Freq[15][60] = 87; Big5Freq[15][150] = 86; + * Big5Freq[5][80] = 85; Big5Freq[15][81] = 84; Big5Freq[28][108] = 83; Big5Freq[18][14] = 82; Big5Freq[19][109] = 81; + * Big5Freq[28][133] = 80; Big5Freq[21][97] = 79; Big5Freq[5][105] = 78; Big5Freq[18][114] = 77; Big5Freq[16][95] = 76; + * Big5Freq[5][51] = 75; Big5Freq[3][148] = 74; Big5Freq[22][102] = 73; Big5Freq[4][123] = 72; Big5Freq[8][88] = 71; + * Big5Freq[25][111] = 70; Big5Freq[8][149] = 69; Big5Freq[9][48] = 68; Big5Freq[16][126] = 67; Big5Freq[33][150] = 66; + * Big5Freq[9][54] = 65; Big5Freq[29][104] = 64; Big5Freq[3][3] = 63; Big5Freq[11][49] = 62; Big5Freq[24][109] = 61; + * Big5Freq[28][116] = 60; Big5Freq[34][113] = 59; Big5Freq[5][3] = 58; Big5Freq[21][106] = 57; Big5Freq[4][98] = 56; + * Big5Freq[12][135] = 55; Big5Freq[16][101] = 54; Big5Freq[12][147] = 53; Big5Freq[27][55] = 52; Big5Freq[3][5] = 51; + * Big5Freq[11][101] = 50; Big5Freq[16][157] = 49; Big5Freq[22][114] = 48; Big5Freq[18][46] = 47; Big5Freq[4][29] = 46; + * Big5Freq[8][103] = 45; Big5Freq[16][151] = 44; Big5Freq[8][29] = 43; Big5Freq[15][114] = 42; Big5Freq[22][70] = 41; + * Big5Freq[13][121] = 40; Big5Freq[7][112] = 39; Big5Freq[20][83] = 38; Big5Freq[3][36] = 37; Big5Freq[10][103] = 36; + * Big5Freq[3][96] = 35; Big5Freq[21][79] = 34; Big5Freq[25][120] = 33; Big5Freq[29][121] = 32; Big5Freq[23][71] = 31; + * Big5Freq[21][22] = 30; Big5Freq[18][89] = 29; Big5Freq[25][104] = 28; Big5Freq[10][124] = 27; Big5Freq[26][4] = 26; + * Big5Freq[21][136] = 25; Big5Freq[6][112] = 24; Big5Freq[12][103] = 23; Big5Freq[17][66] = 22; Big5Freq[13][151] = 21; + * Big5Freq[33][152] = 20; Big5Freq[11][148] = 19; Big5Freq[13][57] = 18; Big5Freq[13][41] = 17; Big5Freq[7][60] = 16; + * Big5Freq[21][29] = 15; Big5Freq[9][157] = 14; Big5Freq[24][95] = 13; Big5Freq[15][148] = 12; Big5Freq[15][122] = 11; + * Big5Freq[6][125] = 10; Big5Freq[11][25] = 9; Big5Freq[20][55] = 8; Big5Freq[19][84] = 7; Big5Freq[21][82] = 6; + * Big5Freq[24][3] = 5; Big5Freq[13][70] = 4; Big5Freq[6][21] = 3; Big5Freq[21][86] = 2; Big5Freq[12][23] = 1; + * Big5Freq[3][85] = 0; EUC_TWFreq[45][90] = 600; + */ + Big5PFreq[41][122] = 600; + Big5PFreq[35][0] = 599; + Big5PFreq[43][15] = 598; + Big5PFreq[35][99] = 597; + Big5PFreq[35][6] = 596; + Big5PFreq[35][8] = 595; + Big5PFreq[38][154] = 594; + Big5PFreq[37][34] = 593; + Big5PFreq[37][115] = 592; + Big5PFreq[36][12] = 591; + Big5PFreq[18][77] = 590; + Big5PFreq[35][100] = 589; + Big5PFreq[35][42] = 588; + Big5PFreq[120][75] = 587; + Big5PFreq[35][23] = 586; + Big5PFreq[13][72] = 585; + Big5PFreq[0][67] = 584; + Big5PFreq[39][172] = 583; + Big5PFreq[22][182] = 582; + Big5PFreq[15][186] = 581; + Big5PFreq[15][165] = 580; + Big5PFreq[35][44] = 579; + Big5PFreq[40][13] = 578; + Big5PFreq[38][1] = 577; + Big5PFreq[37][33] = 576; + Big5PFreq[36][24] = 575; + Big5PFreq[56][4] = 574; + Big5PFreq[35][29] = 573; + Big5PFreq[9][96] = 572; + Big5PFreq[37][62] = 571; + Big5PFreq[48][47] = 570; + Big5PFreq[51][14] = 569; + Big5PFreq[39][122] = 568; + Big5PFreq[44][46] = 567; + Big5PFreq[35][21] = 566; + Big5PFreq[36][8] = 565; + Big5PFreq[36][141] = 564; + Big5PFreq[3][81] = 563; + Big5PFreq[37][155] = 562; + Big5PFreq[42][84] = 561; + Big5PFreq[36][40] = 560; + Big5PFreq[35][103] = 559; + Big5PFreq[11][84] = 558; + Big5PFreq[45][33] = 557; + Big5PFreq[121][79] = 556; + Big5PFreq[2][77] = 555; + Big5PFreq[36][41] = 554; + Big5PFreq[37][47] = 553; + Big5PFreq[39][125] = 552; + Big5PFreq[37][26] = 551; + Big5PFreq[35][48] = 550; + Big5PFreq[35][28] = 549; + Big5PFreq[35][159] = 548; + Big5PFreq[37][40] = 547; + Big5PFreq[35][145] = 546; + Big5PFreq[37][147] = 545; + Big5PFreq[46][160] = 544; + Big5PFreq[37][46] = 543; + Big5PFreq[50][99] = 542; + Big5PFreq[52][13] = 541; + Big5PFreq[10][82] = 540; + Big5PFreq[35][169] = 539; + Big5PFreq[35][31] = 538; + Big5PFreq[47][31] = 537; + Big5PFreq[18][79] = 536; + Big5PFreq[16][113] = 535; + Big5PFreq[37][104] = 534; + Big5PFreq[39][134] = 533; + Big5PFreq[36][53] = 532; + Big5PFreq[38][0] = 531; + Big5PFreq[4][86] = 530; + Big5PFreq[54][17] = 529; + Big5PFreq[43][157] = 528; + Big5PFreq[35][165] = 527; + Big5PFreq[69][147] = 526; + Big5PFreq[117][95] = 525; + Big5PFreq[35][162] = 524; + Big5PFreq[35][17] = 523; + Big5PFreq[36][142] = 522; + Big5PFreq[36][4] = 521; + Big5PFreq[37][166] = 520; + Big5PFreq[35][168] = 519; + Big5PFreq[35][19] = 518; + Big5PFreq[37][48] = 517; + Big5PFreq[42][37] = 516; + Big5PFreq[40][146] = 515; + Big5PFreq[36][123] = 514; + Big5PFreq[22][41] = 513; + Big5PFreq[20][119] = 512; + Big5PFreq[2][74] = 511; + Big5PFreq[44][113] = 510; + Big5PFreq[35][125] = 509; + Big5PFreq[37][16] = 508; + Big5PFreq[35][20] = 507; + Big5PFreq[35][55] = 506; + Big5PFreq[37][145] = 505; + Big5PFreq[0][88] = 504; + Big5PFreq[3][94] = 503; + Big5PFreq[6][65] = 502; + Big5PFreq[26][15] = 501; + Big5PFreq[41][126] = 500; + Big5PFreq[36][129] = 499; + Big5PFreq[31][75] = 498; + Big5PFreq[19][61] = 497; + Big5PFreq[35][128] = 496; + Big5PFreq[29][79] = 495; + Big5PFreq[36][62] = 494; + Big5PFreq[37][189] = 493; + Big5PFreq[39][109] = 492; + Big5PFreq[39][135] = 491; + Big5PFreq[72][15] = 490; + Big5PFreq[47][106] = 489; + Big5PFreq[54][14] = 488; + Big5PFreq[24][52] = 487; + Big5PFreq[38][162] = 486; + Big5PFreq[41][43] = 485; + Big5PFreq[37][121] = 484; + Big5PFreq[14][66] = 483; + Big5PFreq[37][30] = 482; + Big5PFreq[35][7] = 481; + Big5PFreq[49][58] = 480; + Big5PFreq[43][188] = 479; + Big5PFreq[24][66] = 478; + Big5PFreq[35][171] = 477; + Big5PFreq[40][186] = 476; + Big5PFreq[39][164] = 475; + Big5PFreq[78][186] = 474; + Big5PFreq[8][72] = 473; + Big5PFreq[36][190] = 472; + Big5PFreq[35][53] = 471; + Big5PFreq[35][54] = 470; + Big5PFreq[22][159] = 469; + Big5PFreq[35][9] = 468; + Big5PFreq[41][140] = 467; + Big5PFreq[37][22] = 466; + Big5PFreq[48][97] = 465; + Big5PFreq[50][97] = 464; + Big5PFreq[36][127] = 463; + Big5PFreq[37][23] = 462; + Big5PFreq[40][55] = 461; + Big5PFreq[35][43] = 460; + Big5PFreq[26][22] = 459; + Big5PFreq[35][15] = 458; + Big5PFreq[72][179] = 457; + Big5PFreq[20][129] = 456; + Big5PFreq[52][101] = 455; + Big5PFreq[35][12] = 454; + Big5PFreq[42][156] = 453; + Big5PFreq[15][157] = 452; + Big5PFreq[50][140] = 451; + Big5PFreq[26][28] = 450; + Big5PFreq[54][51] = 449; + Big5PFreq[35][112] = 448; + Big5PFreq[36][116] = 447; + Big5PFreq[42][11] = 446; + Big5PFreq[37][172] = 445; + Big5PFreq[37][29] = 444; + Big5PFreq[44][107] = 443; + Big5PFreq[50][17] = 442; + Big5PFreq[39][107] = 441; + Big5PFreq[19][109] = 440; + Big5PFreq[36][60] = 439; + Big5PFreq[49][132] = 438; + Big5PFreq[26][16] = 437; + Big5PFreq[43][155] = 436; + Big5PFreq[37][120] = 435; + Big5PFreq[15][159] = 434; + Big5PFreq[43][6] = 433; + Big5PFreq[45][188] = 432; + Big5PFreq[35][38] = 431; + Big5PFreq[39][143] = 430; + Big5PFreq[48][144] = 429; + Big5PFreq[37][168] = 428; + Big5PFreq[37][1] = 427; + Big5PFreq[36][109] = 426; + Big5PFreq[46][53] = 425; + Big5PFreq[38][54] = 424; + Big5PFreq[36][0] = 423; + Big5PFreq[72][33] = 422; + Big5PFreq[42][8] = 421; + Big5PFreq[36][31] = 420; + Big5PFreq[35][150] = 419; + Big5PFreq[118][93] = 418; + Big5PFreq[37][61] = 417; + Big5PFreq[0][85] = 416; + Big5PFreq[36][27] = 415; + Big5PFreq[35][134] = 414; + Big5PFreq[36][145] = 413; + Big5PFreq[6][96] = 412; + Big5PFreq[36][14] = 411; + Big5PFreq[16][36] = 410; + Big5PFreq[15][175] = 409; + Big5PFreq[35][10] = 408; + Big5PFreq[36][189] = 407; + Big5PFreq[35][51] = 406; + Big5PFreq[35][109] = 405; + Big5PFreq[35][147] = 404; + Big5PFreq[35][180] = 403; + Big5PFreq[72][5] = 402; + Big5PFreq[36][107] = 401; + Big5PFreq[49][116] = 400; + Big5PFreq[73][30] = 399; + Big5PFreq[6][90] = 398; + Big5PFreq[2][70] = 397; + Big5PFreq[17][141] = 396; + Big5PFreq[35][62] = 395; + Big5PFreq[16][180] = 394; + Big5PFreq[4][91] = 393; + Big5PFreq[15][171] = 392; + Big5PFreq[35][177] = 391; + Big5PFreq[37][173] = 390; + Big5PFreq[16][121] = 389; + Big5PFreq[35][5] = 388; + Big5PFreq[46][122] = 387; + Big5PFreq[40][138] = 386; + Big5PFreq[50][49] = 385; + Big5PFreq[36][152] = 384; + Big5PFreq[13][43] = 383; + Big5PFreq[9][88] = 382; + Big5PFreq[36][159] = 381; + Big5PFreq[27][62] = 380; + Big5PFreq[40][18] = 379; + Big5PFreq[17][129] = 378; + Big5PFreq[43][97] = 377; + Big5PFreq[13][131] = 376; + Big5PFreq[46][107] = 375; + Big5PFreq[60][64] = 374; + Big5PFreq[36][179] = 373; + Big5PFreq[37][55] = 372; + Big5PFreq[41][173] = 371; + Big5PFreq[44][172] = 370; + Big5PFreq[23][187] = 369; + Big5PFreq[36][149] = 368; + Big5PFreq[17][125] = 367; + Big5PFreq[55][180] = 366; + Big5PFreq[51][129] = 365; + Big5PFreq[36][51] = 364; + Big5PFreq[37][122] = 363; + Big5PFreq[48][32] = 362; + Big5PFreq[51][99] = 361; + Big5PFreq[54][16] = 360; + Big5PFreq[41][183] = 359; + Big5PFreq[37][179] = 358; + Big5PFreq[38][179] = 357; + Big5PFreq[35][143] = 356; + Big5PFreq[37][24] = 355; + Big5PFreq[40][177] = 354; + Big5PFreq[47][117] = 353; + Big5PFreq[39][52] = 352; + Big5PFreq[22][99] = 351; + Big5PFreq[40][142] = 350; + Big5PFreq[36][49] = 349; + Big5PFreq[38][17] = 348; + Big5PFreq[39][188] = 347; + Big5PFreq[36][186] = 346; + Big5PFreq[35][189] = 345; + Big5PFreq[41][7] = 344; + Big5PFreq[18][91] = 343; + Big5PFreq[43][137] = 342; + Big5PFreq[35][142] = 341; + Big5PFreq[35][117] = 340; + Big5PFreq[39][138] = 339; + Big5PFreq[16][59] = 338; + Big5PFreq[39][174] = 337; + Big5PFreq[55][145] = 336; + Big5PFreq[37][21] = 335; + Big5PFreq[36][180] = 334; + Big5PFreq[37][156] = 333; + Big5PFreq[49][13] = 332; + Big5PFreq[41][107] = 331; + Big5PFreq[36][56] = 330; + Big5PFreq[53][8] = 329; + Big5PFreq[22][114] = 328; + Big5PFreq[5][95] = 327; + Big5PFreq[37][0] = 326; + Big5PFreq[26][183] = 325; + Big5PFreq[22][66] = 324; + Big5PFreq[35][58] = 323; + Big5PFreq[48][117] = 322; + Big5PFreq[36][102] = 321; + Big5PFreq[22][122] = 320; + Big5PFreq[35][11] = 319; + Big5PFreq[46][19] = 318; + Big5PFreq[22][49] = 317; + Big5PFreq[48][166] = 316; + Big5PFreq[41][125] = 315; + Big5PFreq[41][1] = 314; + Big5PFreq[35][178] = 313; + Big5PFreq[41][12] = 312; + Big5PFreq[26][167] = 311; + Big5PFreq[42][152] = 310; + Big5PFreq[42][46] = 309; + Big5PFreq[42][151] = 308; + Big5PFreq[20][135] = 307; + Big5PFreq[37][162] = 306; + Big5PFreq[37][50] = 305; + Big5PFreq[22][185] = 304; + Big5PFreq[36][166] = 303; + Big5PFreq[19][40] = 302; + Big5PFreq[22][107] = 301; + Big5PFreq[22][102] = 300; + Big5PFreq[57][162] = 299; + Big5PFreq[22][124] = 298; + Big5PFreq[37][138] = 297; + Big5PFreq[37][25] = 296; + Big5PFreq[0][69] = 295; + Big5PFreq[43][172] = 294; + Big5PFreq[42][167] = 293; + Big5PFreq[35][120] = 292; + Big5PFreq[41][128] = 291; + Big5PFreq[2][88] = 290; + Big5PFreq[20][123] = 289; + Big5PFreq[35][123] = 288; + Big5PFreq[36][28] = 287; + Big5PFreq[42][188] = 286; + Big5PFreq[42][164] = 285; + Big5PFreq[42][4] = 284; + Big5PFreq[43][57] = 283; + Big5PFreq[39][3] = 282; + Big5PFreq[42][3] = 281; + Big5PFreq[57][158] = 280; + Big5PFreq[35][146] = 279; + Big5PFreq[24][54] = 278; + Big5PFreq[13][110] = 277; + Big5PFreq[23][132] = 276; + Big5PFreq[26][102] = 275; + Big5PFreq[55][178] = 274; + Big5PFreq[17][117] = 273; + Big5PFreq[41][161] = 272; + Big5PFreq[38][150] = 271; + Big5PFreq[10][71] = 270; + Big5PFreq[47][60] = 269; + Big5PFreq[16][114] = 268; + Big5PFreq[21][47] = 267; + Big5PFreq[39][101] = 266; + Big5PFreq[18][45] = 265; + Big5PFreq[40][121] = 264; + Big5PFreq[45][41] = 263; + Big5PFreq[22][167] = 262; + Big5PFreq[26][149] = 261; + Big5PFreq[15][189] = 260; + Big5PFreq[41][177] = 259; + Big5PFreq[46][36] = 258; + Big5PFreq[20][40] = 257; + Big5PFreq[41][54] = 256; + Big5PFreq[3][87] = 255; + Big5PFreq[40][16] = 254; + Big5PFreq[42][15] = 253; + Big5PFreq[11][83] = 252; + Big5PFreq[0][94] = 251; + Big5PFreq[122][81] = 250; + Big5PFreq[41][26] = 249; + Big5PFreq[36][34] = 248; + Big5PFreq[44][148] = 247; + Big5PFreq[35][3] = 246; + Big5PFreq[36][114] = 245; + Big5PFreq[42][112] = 244; + Big5PFreq[35][183] = 243; + Big5PFreq[49][73] = 242; + Big5PFreq[39][2] = 241; + Big5PFreq[38][121] = 240; + Big5PFreq[44][114] = 239; + Big5PFreq[49][32] = 238; + Big5PFreq[1][65] = 237; + Big5PFreq[38][25] = 236; + Big5PFreq[39][4] = 235; + Big5PFreq[42][62] = 234; + Big5PFreq[35][40] = 233; + Big5PFreq[24][2] = 232; + Big5PFreq[53][49] = 231; + Big5PFreq[41][133] = 230; + Big5PFreq[43][134] = 229; + Big5PFreq[3][83] = 228; + Big5PFreq[38][158] = 227; + Big5PFreq[24][17] = 226; + Big5PFreq[52][59] = 225; + Big5PFreq[38][41] = 224; + Big5PFreq[37][127] = 223; + Big5PFreq[22][175] = 222; + Big5PFreq[44][30] = 221; + Big5PFreq[47][178] = 220; + Big5PFreq[43][99] = 219; + Big5PFreq[19][4] = 218; + Big5PFreq[37][97] = 217; + Big5PFreq[38][181] = 216; + Big5PFreq[45][103] = 215; + Big5PFreq[1][86] = 214; + Big5PFreq[40][15] = 213; + Big5PFreq[22][136] = 212; + Big5PFreq[75][165] = 211; + Big5PFreq[36][15] = 210; + Big5PFreq[46][80] = 209; + Big5PFreq[59][55] = 208; + Big5PFreq[37][108] = 207; + Big5PFreq[21][109] = 206; + Big5PFreq[24][165] = 205; + Big5PFreq[79][158] = 204; + Big5PFreq[44][139] = 203; + Big5PFreq[36][124] = 202; + Big5PFreq[42][185] = 201; + Big5PFreq[39][186] = 200; + Big5PFreq[22][128] = 199; + Big5PFreq[40][44] = 198; + Big5PFreq[41][105] = 197; + Big5PFreq[1][70] = 196; + Big5PFreq[1][68] = 195; + Big5PFreq[53][22] = 194; + Big5PFreq[36][54] = 193; + Big5PFreq[47][147] = 192; + Big5PFreq[35][36] = 191; + Big5PFreq[35][185] = 190; + Big5PFreq[45][37] = 189; + Big5PFreq[43][163] = 188; + Big5PFreq[56][115] = 187; + Big5PFreq[38][164] = 186; + Big5PFreq[35][141] = 185; + Big5PFreq[42][132] = 184; + Big5PFreq[46][120] = 183; + Big5PFreq[69][142] = 182; + Big5PFreq[38][175] = 181; + Big5PFreq[22][112] = 180; + Big5PFreq[38][142] = 179; + Big5PFreq[40][37] = 178; + Big5PFreq[37][109] = 177; + Big5PFreq[40][144] = 176; + Big5PFreq[44][117] = 175; + Big5PFreq[35][181] = 174; + Big5PFreq[26][105] = 173; + Big5PFreq[16][48] = 172; + Big5PFreq[44][122] = 171; + Big5PFreq[12][86] = 170; + Big5PFreq[84][53] = 169; + Big5PFreq[17][44] = 168; + Big5PFreq[59][54] = 167; + Big5PFreq[36][98] = 166; + Big5PFreq[45][115] = 165; + Big5PFreq[73][9] = 164; + Big5PFreq[44][123] = 163; + Big5PFreq[37][188] = 162; + Big5PFreq[51][117] = 161; + Big5PFreq[15][156] = 160; + Big5PFreq[36][155] = 159; + Big5PFreq[44][25] = 158; + Big5PFreq[38][12] = 157; + Big5PFreq[38][140] = 156; + Big5PFreq[23][4] = 155; + Big5PFreq[45][149] = 154; + Big5PFreq[22][189] = 153; + Big5PFreq[38][147] = 152; + Big5PFreq[27][5] = 151; + Big5PFreq[22][42] = 150; + Big5PFreq[3][68] = 149; + Big5PFreq[39][51] = 148; + Big5PFreq[36][29] = 147; + Big5PFreq[20][108] = 146; + Big5PFreq[50][57] = 145; + Big5PFreq[55][104] = 144; + Big5PFreq[22][46] = 143; + Big5PFreq[18][164] = 142; + Big5PFreq[50][159] = 141; + Big5PFreq[85][131] = 140; + Big5PFreq[26][79] = 139; + Big5PFreq[38][100] = 138; + Big5PFreq[53][112] = 137; + Big5PFreq[20][190] = 136; + Big5PFreq[14][69] = 135; + Big5PFreq[23][11] = 134; + Big5PFreq[40][114] = 133; + Big5PFreq[40][148] = 132; + Big5PFreq[53][130] = 131; + Big5PFreq[36][2] = 130; + Big5PFreq[66][82] = 129; + Big5PFreq[45][166] = 128; + Big5PFreq[4][88] = 127; + Big5PFreq[16][57] = 126; + Big5PFreq[22][116] = 125; + Big5PFreq[36][108] = 124; + Big5PFreq[13][48] = 123; + Big5PFreq[54][12] = 122; + Big5PFreq[40][136] = 121; + Big5PFreq[36][128] = 120; + Big5PFreq[23][6] = 119; + Big5PFreq[38][125] = 118; + Big5PFreq[45][154] = 117; + Big5PFreq[51][127] = 116; + Big5PFreq[44][163] = 115; + Big5PFreq[16][173] = 114; + Big5PFreq[43][49] = 113; + Big5PFreq[20][112] = 112; + Big5PFreq[15][168] = 111; + Big5PFreq[35][129] = 110; + Big5PFreq[20][45] = 109; + Big5PFreq[38][10] = 108; + Big5PFreq[57][171] = 107; + Big5PFreq[44][190] = 106; + Big5PFreq[40][56] = 105; + Big5PFreq[36][156] = 104; + Big5PFreq[3][88] = 103; + Big5PFreq[50][122] = 102; + Big5PFreq[36][7] = 101; + Big5PFreq[39][43] = 100; + Big5PFreq[15][166] = 99; + Big5PFreq[42][136] = 98; + Big5PFreq[22][131] = 97; + Big5PFreq[44][23] = 96; + Big5PFreq[54][147] = 95; + Big5PFreq[41][32] = 94; + Big5PFreq[23][121] = 93; + Big5PFreq[39][108] = 92; + Big5PFreq[2][78] = 91; + Big5PFreq[40][155] = 90; + Big5PFreq[55][51] = 89; + Big5PFreq[19][34] = 88; + Big5PFreq[48][128] = 87; + Big5PFreq[48][159] = 86; + Big5PFreq[20][70] = 85; + Big5PFreq[34][71] = 84; + Big5PFreq[16][31] = 83; + Big5PFreq[42][157] = 82; + Big5PFreq[20][44] = 81; + Big5PFreq[11][92] = 80; + Big5PFreq[44][180] = 79; + Big5PFreq[84][33] = 78; + Big5PFreq[16][116] = 77; + Big5PFreq[61][163] = 76; + Big5PFreq[35][164] = 75; + Big5PFreq[36][42] = 74; + Big5PFreq[13][40] = 73; + Big5PFreq[43][176] = 72; + Big5PFreq[2][66] = 71; + Big5PFreq[20][133] = 70; + Big5PFreq[36][65] = 69; + Big5PFreq[38][33] = 68; + Big5PFreq[12][91] = 67; + Big5PFreq[36][26] = 66; + Big5PFreq[15][174] = 65; + Big5PFreq[77][32] = 64; + Big5PFreq[16][1] = 63; + Big5PFreq[25][86] = 62; + Big5PFreq[17][13] = 61; + Big5PFreq[5][75] = 60; + Big5PFreq[36][52] = 59; + Big5PFreq[51][164] = 58; + Big5PFreq[12][85] = 57; + Big5PFreq[39][168] = 56; + Big5PFreq[43][16] = 55; + Big5PFreq[40][69] = 54; + Big5PFreq[26][108] = 53; + Big5PFreq[51][56] = 52; + Big5PFreq[16][37] = 51; + Big5PFreq[40][29] = 50; + Big5PFreq[46][171] = 49; + Big5PFreq[40][128] = 48; + Big5PFreq[72][114] = 47; + Big5PFreq[21][103] = 46; + Big5PFreq[22][44] = 45; + Big5PFreq[40][115] = 44; + Big5PFreq[43][7] = 43; + Big5PFreq[43][153] = 42; + Big5PFreq[17][20] = 41; + Big5PFreq[16][49] = 40; + Big5PFreq[36][57] = 39; + Big5PFreq[18][38] = 38; + Big5PFreq[45][184] = 37; + Big5PFreq[37][167] = 36; + Big5PFreq[26][106] = 35; + Big5PFreq[61][121] = 34; + Big5PFreq[89][140] = 33; + Big5PFreq[46][61] = 32; + Big5PFreq[39][163] = 31; + Big5PFreq[40][62] = 30; + Big5PFreq[38][165] = 29; + Big5PFreq[47][37] = 28; + Big5PFreq[18][155] = 27; + Big5PFreq[20][33] = 26; + Big5PFreq[29][90] = 25; + Big5PFreq[20][103] = 24; + Big5PFreq[37][51] = 23; + Big5PFreq[57][0] = 22; + Big5PFreq[40][31] = 21; + Big5PFreq[45][32] = 20; + Big5PFreq[59][23] = 19; + Big5PFreq[18][47] = 18; + Big5PFreq[45][134] = 17; + Big5PFreq[37][59] = 16; + Big5PFreq[21][128] = 15; + Big5PFreq[36][106] = 14; + Big5PFreq[31][39] = 13; + Big5PFreq[40][182] = 12; + Big5PFreq[52][155] = 11; + Big5PFreq[42][166] = 10; + Big5PFreq[35][27] = 9; + Big5PFreq[38][3] = 8; + Big5PFreq[13][44] = 7; + Big5PFreq[58][157] = 6; + Big5PFreq[47][51] = 5; + Big5PFreq[41][37] = 4; + Big5PFreq[41][172] = 3; + Big5PFreq[51][165] = 2; + Big5PFreq[15][161] = 1; + Big5PFreq[24][181] = 0; + EUC_TWFreq[48][49] = 599; + EUC_TWFreq[35][65] = 598; + EUC_TWFreq[41][27] = 597; + EUC_TWFreq[35][0] = 596; + EUC_TWFreq[39][19] = 595; + EUC_TWFreq[35][42] = 594; + EUC_TWFreq[38][66] = 593; + EUC_TWFreq[35][8] = 592; + EUC_TWFreq[35][6] = 591; + EUC_TWFreq[35][66] = 590; + EUC_TWFreq[43][14] = 589; + EUC_TWFreq[69][80] = 588; + EUC_TWFreq[50][48] = 587; + EUC_TWFreq[36][71] = 586; + EUC_TWFreq[37][10] = 585; + EUC_TWFreq[60][52] = 584; + EUC_TWFreq[51][21] = 583; + EUC_TWFreq[40][2] = 582; + EUC_TWFreq[67][35] = 581; + EUC_TWFreq[38][78] = 580; + EUC_TWFreq[49][18] = 579; + EUC_TWFreq[35][23] = 578; + EUC_TWFreq[42][83] = 577; + EUC_TWFreq[79][47] = 576; + EUC_TWFreq[61][82] = 575; + EUC_TWFreq[38][7] = 574; + EUC_TWFreq[35][29] = 573; + EUC_TWFreq[37][77] = 572; + EUC_TWFreq[54][67] = 571; + EUC_TWFreq[38][80] = 570; + EUC_TWFreq[52][74] = 569; + EUC_TWFreq[36][37] = 568; + EUC_TWFreq[74][8] = 567; + EUC_TWFreq[41][83] = 566; + EUC_TWFreq[36][75] = 565; + EUC_TWFreq[49][63] = 564; + EUC_TWFreq[42][58] = 563; + EUC_TWFreq[56][33] = 562; + EUC_TWFreq[37][76] = 561; + EUC_TWFreq[62][39] = 560; + EUC_TWFreq[35][21] = 559; + EUC_TWFreq[70][19] = 558; + EUC_TWFreq[77][88] = 557; + EUC_TWFreq[51][14] = 556; + EUC_TWFreq[36][17] = 555; + EUC_TWFreq[44][51] = 554; + EUC_TWFreq[38][72] = 553; + EUC_TWFreq[74][90] = 552; + EUC_TWFreq[35][48] = 551; + EUC_TWFreq[35][69] = 550; + EUC_TWFreq[66][86] = 549; + EUC_TWFreq[57][20] = 548; + EUC_TWFreq[35][53] = 547; + EUC_TWFreq[36][87] = 546; + EUC_TWFreq[84][67] = 545; + EUC_TWFreq[70][56] = 544; + EUC_TWFreq[71][54] = 543; + EUC_TWFreq[60][70] = 542; + EUC_TWFreq[80][1] = 541; + EUC_TWFreq[39][59] = 540; + EUC_TWFreq[39][51] = 539; + EUC_TWFreq[35][44] = 538; + EUC_TWFreq[48][4] = 537; + EUC_TWFreq[55][24] = 536; + EUC_TWFreq[52][4] = 535; + EUC_TWFreq[54][26] = 534; + EUC_TWFreq[36][31] = 533; + EUC_TWFreq[37][22] = 532; + EUC_TWFreq[37][9] = 531; + EUC_TWFreq[46][0] = 530; + EUC_TWFreq[56][46] = 529; + EUC_TWFreq[47][93] = 528; + EUC_TWFreq[37][25] = 527; + EUC_TWFreq[39][8] = 526; + EUC_TWFreq[46][73] = 525; + EUC_TWFreq[38][48] = 524; + EUC_TWFreq[39][83] = 523; + EUC_TWFreq[60][92] = 522; + EUC_TWFreq[70][11] = 521; + EUC_TWFreq[63][84] = 520; + EUC_TWFreq[38][65] = 519; + EUC_TWFreq[45][45] = 518; + EUC_TWFreq[63][49] = 517; + EUC_TWFreq[63][50] = 516; + EUC_TWFreq[39][93] = 515; + EUC_TWFreq[68][20] = 514; + EUC_TWFreq[44][84] = 513; + EUC_TWFreq[66][34] = 512; + EUC_TWFreq[37][58] = 511; + EUC_TWFreq[39][0] = 510; + EUC_TWFreq[59][1] = 509; + EUC_TWFreq[47][8] = 508; + EUC_TWFreq[61][17] = 507; + EUC_TWFreq[53][87] = 506; + EUC_TWFreq[67][26] = 505; + EUC_TWFreq[43][46] = 504; + EUC_TWFreq[38][61] = 503; + EUC_TWFreq[45][9] = 502; + EUC_TWFreq[66][83] = 501; + EUC_TWFreq[43][88] = 500; + EUC_TWFreq[85][20] = 499; + EUC_TWFreq[57][36] = 498; + EUC_TWFreq[43][6] = 497; + EUC_TWFreq[86][77] = 496; + EUC_TWFreq[42][70] = 495; + EUC_TWFreq[49][78] = 494; + EUC_TWFreq[36][40] = 493; + EUC_TWFreq[42][71] = 492; + EUC_TWFreq[58][49] = 491; + EUC_TWFreq[35][20] = 490; + EUC_TWFreq[76][20] = 489; + EUC_TWFreq[39][25] = 488; + EUC_TWFreq[40][34] = 487; + EUC_TWFreq[39][76] = 486; + EUC_TWFreq[40][1] = 485; + EUC_TWFreq[59][0] = 484; + EUC_TWFreq[39][70] = 483; + EUC_TWFreq[46][14] = 482; + EUC_TWFreq[68][77] = 481; + EUC_TWFreq[38][55] = 480; + EUC_TWFreq[35][78] = 479; + EUC_TWFreq[84][44] = 478; + EUC_TWFreq[36][41] = 477; + EUC_TWFreq[37][62] = 476; + EUC_TWFreq[65][67] = 475; + EUC_TWFreq[69][66] = 474; + EUC_TWFreq[73][55] = 473; + EUC_TWFreq[71][49] = 472; + EUC_TWFreq[66][87] = 471; + EUC_TWFreq[38][33] = 470; + EUC_TWFreq[64][61] = 469; + EUC_TWFreq[35][7] = 468; + EUC_TWFreq[47][49] = 467; + EUC_TWFreq[56][14] = 466; + EUC_TWFreq[36][49] = 465; + EUC_TWFreq[50][81] = 464; + EUC_TWFreq[55][76] = 463; + EUC_TWFreq[35][19] = 462; + EUC_TWFreq[44][47] = 461; + EUC_TWFreq[35][15] = 460; + EUC_TWFreq[82][59] = 459; + EUC_TWFreq[35][43] = 458; + EUC_TWFreq[73][0] = 457; + EUC_TWFreq[57][83] = 456; + EUC_TWFreq[42][46] = 455; + EUC_TWFreq[36][0] = 454; + EUC_TWFreq[70][88] = 453; + EUC_TWFreq[42][22] = 452; + EUC_TWFreq[46][58] = 451; + EUC_TWFreq[36][34] = 450; + EUC_TWFreq[39][24] = 449; + EUC_TWFreq[35][55] = 448; + EUC_TWFreq[44][91] = 447; + EUC_TWFreq[37][51] = 446; + EUC_TWFreq[36][19] = 445; + EUC_TWFreq[69][90] = 444; + EUC_TWFreq[55][35] = 443; + EUC_TWFreq[35][54] = 442; + EUC_TWFreq[49][61] = 441; + EUC_TWFreq[36][67] = 440; + EUC_TWFreq[88][34] = 439; + EUC_TWFreq[35][17] = 438; + EUC_TWFreq[65][69] = 437; + EUC_TWFreq[74][89] = 436; + EUC_TWFreq[37][31] = 435; + EUC_TWFreq[43][48] = 434; + EUC_TWFreq[89][27] = 433; + EUC_TWFreq[42][79] = 432; + EUC_TWFreq[69][57] = 431; + EUC_TWFreq[36][13] = 430; + EUC_TWFreq[35][62] = 429; + EUC_TWFreq[65][47] = 428; + EUC_TWFreq[56][8] = 427; + EUC_TWFreq[38][79] = 426; + EUC_TWFreq[37][64] = 425; + EUC_TWFreq[64][64] = 424; + EUC_TWFreq[38][53] = 423; + EUC_TWFreq[38][31] = 422; + EUC_TWFreq[56][81] = 421; + EUC_TWFreq[36][22] = 420; + EUC_TWFreq[43][4] = 419; + EUC_TWFreq[36][90] = 418; + EUC_TWFreq[38][62] = 417; + EUC_TWFreq[66][85] = 416; + EUC_TWFreq[39][1] = 415; + EUC_TWFreq[59][40] = 414; + EUC_TWFreq[58][93] = 413; + EUC_TWFreq[44][43] = 412; + EUC_TWFreq[39][49] = 411; + EUC_TWFreq[64][2] = 410; + EUC_TWFreq[41][35] = 409; + EUC_TWFreq[60][22] = 408; + EUC_TWFreq[35][91] = 407; + EUC_TWFreq[78][1] = 406; + EUC_TWFreq[36][14] = 405; + EUC_TWFreq[82][29] = 404; + EUC_TWFreq[52][86] = 403; + EUC_TWFreq[40][16] = 402; + EUC_TWFreq[91][52] = 401; + EUC_TWFreq[50][75] = 400; + EUC_TWFreq[64][30] = 399; + EUC_TWFreq[90][78] = 398; + EUC_TWFreq[36][52] = 397; + EUC_TWFreq[55][87] = 396; + EUC_TWFreq[57][5] = 395; + EUC_TWFreq[57][31] = 394; + EUC_TWFreq[42][35] = 393; + EUC_TWFreq[69][50] = 392; + EUC_TWFreq[45][8] = 391; + EUC_TWFreq[50][87] = 390; + EUC_TWFreq[69][55] = 389; + EUC_TWFreq[92][3] = 388; + EUC_TWFreq[36][43] = 387; + EUC_TWFreq[64][10] = 386; + EUC_TWFreq[56][25] = 385; + EUC_TWFreq[60][68] = 384; + EUC_TWFreq[51][46] = 383; + EUC_TWFreq[50][0] = 382; + EUC_TWFreq[38][30] = 381; + EUC_TWFreq[50][85] = 380; + EUC_TWFreq[60][54] = 379; + EUC_TWFreq[73][6] = 378; + EUC_TWFreq[73][28] = 377; + EUC_TWFreq[56][19] = 376; + EUC_TWFreq[62][69] = 375; + EUC_TWFreq[81][66] = 374; + EUC_TWFreq[40][32] = 373; + EUC_TWFreq[76][31] = 372; + EUC_TWFreq[35][10] = 371; + EUC_TWFreq[41][37] = 370; + EUC_TWFreq[52][82] = 369; + EUC_TWFreq[91][72] = 368; + EUC_TWFreq[37][29] = 367; + EUC_TWFreq[56][30] = 366; + EUC_TWFreq[37][80] = 365; + EUC_TWFreq[81][56] = 364; + EUC_TWFreq[70][3] = 363; + EUC_TWFreq[76][15] = 362; + EUC_TWFreq[46][47] = 361; + EUC_TWFreq[35][88] = 360; + EUC_TWFreq[61][58] = 359; + EUC_TWFreq[37][37] = 358; + EUC_TWFreq[57][22] = 357; + EUC_TWFreq[41][23] = 356; + EUC_TWFreq[90][66] = 355; + EUC_TWFreq[39][60] = 354; + EUC_TWFreq[38][0] = 353; + EUC_TWFreq[37][87] = 352; + EUC_TWFreq[46][2] = 351; + EUC_TWFreq[38][56] = 350; + EUC_TWFreq[58][11] = 349; + EUC_TWFreq[48][10] = 348; + EUC_TWFreq[74][4] = 347; + EUC_TWFreq[40][42] = 346; + EUC_TWFreq[41][52] = 345; + EUC_TWFreq[61][92] = 344; + EUC_TWFreq[39][50] = 343; + EUC_TWFreq[47][88] = 342; + EUC_TWFreq[88][36] = 341; + EUC_TWFreq[45][73] = 340; + EUC_TWFreq[82][3] = 339; + EUC_TWFreq[61][36] = 338; + EUC_TWFreq[60][33] = 337; + EUC_TWFreq[38][27] = 336; + EUC_TWFreq[35][83] = 335; + EUC_TWFreq[65][24] = 334; + EUC_TWFreq[73][10] = 333; + EUC_TWFreq[41][13] = 332; + EUC_TWFreq[50][27] = 331; + EUC_TWFreq[59][50] = 330; + EUC_TWFreq[42][45] = 329; + EUC_TWFreq[55][19] = 328; + EUC_TWFreq[36][77] = 327; + EUC_TWFreq[69][31] = 326; + EUC_TWFreq[60][7] = 325; + EUC_TWFreq[40][88] = 324; + EUC_TWFreq[57][56] = 323; + EUC_TWFreq[50][50] = 322; + EUC_TWFreq[42][37] = 321; + EUC_TWFreq[38][82] = 320; + EUC_TWFreq[52][25] = 319; + EUC_TWFreq[42][67] = 318; + EUC_TWFreq[48][40] = 317; + EUC_TWFreq[45][81] = 316; + EUC_TWFreq[57][14] = 315; + EUC_TWFreq[42][13] = 314; + EUC_TWFreq[78][0] = 313; + EUC_TWFreq[35][51] = 312; + EUC_TWFreq[41][67] = 311; + EUC_TWFreq[64][23] = 310; + EUC_TWFreq[36][65] = 309; + EUC_TWFreq[48][50] = 308; + EUC_TWFreq[46][69] = 307; + EUC_TWFreq[47][89] = 306; + EUC_TWFreq[41][48] = 305; + EUC_TWFreq[60][56] = 304; + EUC_TWFreq[44][82] = 303; + EUC_TWFreq[47][35] = 302; + EUC_TWFreq[49][3] = 301; + EUC_TWFreq[49][69] = 300; + EUC_TWFreq[45][93] = 299; + EUC_TWFreq[60][34] = 298; + EUC_TWFreq[60][82] = 297; + EUC_TWFreq[61][61] = 296; + EUC_TWFreq[86][42] = 295; + EUC_TWFreq[89][60] = 294; + EUC_TWFreq[48][31] = 293; + EUC_TWFreq[35][75] = 292; + EUC_TWFreq[91][39] = 291; + EUC_TWFreq[53][19] = 290; + EUC_TWFreq[39][72] = 289; + EUC_TWFreq[69][59] = 288; + EUC_TWFreq[41][7] = 287; + EUC_TWFreq[54][13] = 286; + EUC_TWFreq[43][28] = 285; + EUC_TWFreq[36][6] = 284; + EUC_TWFreq[45][75] = 283; + EUC_TWFreq[36][61] = 282; + EUC_TWFreq[38][21] = 281; + EUC_TWFreq[45][14] = 280; + EUC_TWFreq[61][43] = 279; + EUC_TWFreq[36][63] = 278; + EUC_TWFreq[43][30] = 277; + EUC_TWFreq[46][51] = 276; + EUC_TWFreq[68][87] = 275; + EUC_TWFreq[39][26] = 274; + EUC_TWFreq[46][76] = 273; + EUC_TWFreq[36][15] = 272; + EUC_TWFreq[35][40] = 271; + EUC_TWFreq[79][60] = 270; + EUC_TWFreq[46][7] = 269; + EUC_TWFreq[65][72] = 268; + EUC_TWFreq[69][88] = 267; + EUC_TWFreq[47][18] = 266; + EUC_TWFreq[37][0] = 265; + EUC_TWFreq[37][49] = 264; + EUC_TWFreq[67][37] = 263; + EUC_TWFreq[36][91] = 262; + EUC_TWFreq[75][48] = 261; + EUC_TWFreq[75][63] = 260; + EUC_TWFreq[83][87] = 259; + EUC_TWFreq[37][44] = 258; + EUC_TWFreq[73][54] = 257; + EUC_TWFreq[51][61] = 256; + EUC_TWFreq[46][57] = 255; + EUC_TWFreq[55][21] = 254; + EUC_TWFreq[39][66] = 253; + EUC_TWFreq[47][11] = 252; + EUC_TWFreq[52][8] = 251; + EUC_TWFreq[82][81] = 250; + EUC_TWFreq[36][57] = 249; + EUC_TWFreq[38][54] = 248; + EUC_TWFreq[43][81] = 247; + EUC_TWFreq[37][42] = 246; + EUC_TWFreq[40][18] = 245; + EUC_TWFreq[80][90] = 244; + EUC_TWFreq[37][84] = 243; + EUC_TWFreq[57][15] = 242; + EUC_TWFreq[38][87] = 241; + EUC_TWFreq[37][32] = 240; + EUC_TWFreq[53][53] = 239; + EUC_TWFreq[89][29] = 238; + EUC_TWFreq[81][53] = 237; + EUC_TWFreq[75][3] = 236; + EUC_TWFreq[83][73] = 235; + EUC_TWFreq[66][13] = 234; + EUC_TWFreq[48][7] = 233; + EUC_TWFreq[46][35] = 232; + EUC_TWFreq[35][86] = 231; + EUC_TWFreq[37][20] = 230; + EUC_TWFreq[46][80] = 229; + EUC_TWFreq[38][24] = 228; + EUC_TWFreq[41][68] = 227; + EUC_TWFreq[42][21] = 226; + EUC_TWFreq[43][32] = 225; + EUC_TWFreq[38][20] = 224; + EUC_TWFreq[37][59] = 223; + EUC_TWFreq[41][77] = 222; + EUC_TWFreq[59][57] = 221; + EUC_TWFreq[68][59] = 220; + EUC_TWFreq[39][43] = 219; + EUC_TWFreq[54][39] = 218; + EUC_TWFreq[48][28] = 217; + EUC_TWFreq[54][28] = 216; + EUC_TWFreq[41][44] = 215; + EUC_TWFreq[51][64] = 214; + EUC_TWFreq[47][72] = 213; + EUC_TWFreq[62][67] = 212; + EUC_TWFreq[42][43] = 211; + EUC_TWFreq[61][38] = 210; + EUC_TWFreq[76][25] = 209; + EUC_TWFreq[48][91] = 208; + EUC_TWFreq[36][36] = 207; + EUC_TWFreq[80][32] = 206; + EUC_TWFreq[81][40] = 205; + EUC_TWFreq[37][5] = 204; + EUC_TWFreq[74][69] = 203; + EUC_TWFreq[36][82] = 202; + EUC_TWFreq[46][59] = 201; + /* + * EUC_TWFreq[38][32] = 200; EUC_TWFreq[74][2] = 199; EUC_TWFreq[53][31] = 198; EUC_TWFreq[35][38] = 197; EUC_TWFreq[46][62] = + * 196; EUC_TWFreq[77][31] = 195; EUC_TWFreq[55][74] = 194; EUC_TWFreq[66][6] = 193; EUC_TWFreq[56][21] = 192; + * EUC_TWFreq[54][78] = 191; EUC_TWFreq[43][51] = 190; EUC_TWFreq[64][93] = 189; EUC_TWFreq[92][7] = 188; EUC_TWFreq[83][89] = + * 187; EUC_TWFreq[69][9] = 186; EUC_TWFreq[45][4] = 185; EUC_TWFreq[53][9] = 184; EUC_TWFreq[43][2] = 183; + * EUC_TWFreq[35][11] = 182; EUC_TWFreq[51][25] = 181; EUC_TWFreq[52][71] = 180; EUC_TWFreq[81][67] = 179; + * EUC_TWFreq[37][33] = 178; EUC_TWFreq[38][57] = 177; EUC_TWFreq[39][77] = 176; EUC_TWFreq[40][26] = 175; + * EUC_TWFreq[37][21] = 174; EUC_TWFreq[81][70] = 173; EUC_TWFreq[56][80] = 172; EUC_TWFreq[65][14] = 171; + * EUC_TWFreq[62][47] = 170; EUC_TWFreq[56][54] = 169; EUC_TWFreq[45][17] = 168; EUC_TWFreq[52][52] = 167; + * EUC_TWFreq[74][30] = 166; EUC_TWFreq[60][57] = 165; EUC_TWFreq[41][15] = 164; EUC_TWFreq[47][69] = 163; + * EUC_TWFreq[61][11] = 162; EUC_TWFreq[72][25] = 161; EUC_TWFreq[82][56] = 160; EUC_TWFreq[76][92] = 159; + * EUC_TWFreq[51][22] = 158; EUC_TWFreq[55][69] = 157; EUC_TWFreq[49][43] = 156; EUC_TWFreq[69][49] = 155; + * EUC_TWFreq[88][42] = 154; EUC_TWFreq[84][41] = 153; EUC_TWFreq[79][33] = 152; EUC_TWFreq[47][17] = 151; + * EUC_TWFreq[52][88] = 150; EUC_TWFreq[63][74] = 149; EUC_TWFreq[50][32] = 148; EUC_TWFreq[65][10] = 147; EUC_TWFreq[57][6] = + * 146; EUC_TWFreq[52][23] = 145; EUC_TWFreq[36][70] = 144; EUC_TWFreq[65][55] = 143; EUC_TWFreq[35][27] = 142; + * EUC_TWFreq[57][63] = 141; EUC_TWFreq[39][92] = 140; EUC_TWFreq[79][75] = 139; EUC_TWFreq[36][30] = 138; + * EUC_TWFreq[53][60] = 137; EUC_TWFreq[55][43] = 136; EUC_TWFreq[71][22] = 135; EUC_TWFreq[43][16] = 134; + * EUC_TWFreq[65][21] = 133; EUC_TWFreq[84][51] = 132; EUC_TWFreq[43][64] = 131; EUC_TWFreq[87][91] = 130; + * EUC_TWFreq[47][45] = 129; EUC_TWFreq[65][29] = 128; EUC_TWFreq[88][16] = 127; EUC_TWFreq[50][5] = 126; EUC_TWFreq[47][33] = + * 125; EUC_TWFreq[46][27] = 124; EUC_TWFreq[85][2] = 123; EUC_TWFreq[43][77] = 122; EUC_TWFreq[70][9] = 121; + * EUC_TWFreq[41][54] = 120; EUC_TWFreq[56][12] = 119; EUC_TWFreq[90][65] = 118; EUC_TWFreq[91][50] = 117; + * EUC_TWFreq[48][41] = 116; EUC_TWFreq[35][89] = 115; EUC_TWFreq[90][83] = 114; EUC_TWFreq[44][40] = 113; + * EUC_TWFreq[50][88] = 112; EUC_TWFreq[72][39] = 111; EUC_TWFreq[45][3] = 110; EUC_TWFreq[71][33] = 109; EUC_TWFreq[39][12] = + * 108; EUC_TWFreq[59][24] = 107; EUC_TWFreq[60][62] = 106; EUC_TWFreq[44][33] = 105; EUC_TWFreq[53][70] = 104; + * EUC_TWFreq[77][90] = 103; EUC_TWFreq[50][58] = 102; EUC_TWFreq[54][1] = 101; EUC_TWFreq[73][19] = 100; EUC_TWFreq[37][3] = + * 99; EUC_TWFreq[49][91] = 98; EUC_TWFreq[88][43] = 97; EUC_TWFreq[36][78] = 96; EUC_TWFreq[44][20] = 95; + * EUC_TWFreq[64][15] = 94; EUC_TWFreq[72][28] = 93; EUC_TWFreq[70][13] = 92; EUC_TWFreq[65][83] = 91; EUC_TWFreq[58][68] = + * 90; EUC_TWFreq[59][32] = 89; EUC_TWFreq[39][13] = 88; EUC_TWFreq[55][64] = 87; EUC_TWFreq[56][59] = 86; + * EUC_TWFreq[39][17] = 85; EUC_TWFreq[55][84] = 84; EUC_TWFreq[77][85] = 83; EUC_TWFreq[60][19] = 82; EUC_TWFreq[62][82] = + * 81; EUC_TWFreq[78][16] = 80; EUC_TWFreq[66][8] = 79; EUC_TWFreq[39][42] = 78; EUC_TWFreq[61][24] = 77; EUC_TWFreq[57][67] = + * 76; EUC_TWFreq[38][83] = 75; EUC_TWFreq[36][53] = 74; EUC_TWFreq[67][76] = 73; EUC_TWFreq[37][91] = 72; + * EUC_TWFreq[44][26] = 71; EUC_TWFreq[72][86] = 70; EUC_TWFreq[44][87] = 69; EUC_TWFreq[45][50] = 68; EUC_TWFreq[58][4] = + * 67; EUC_TWFreq[86][65] = 66; EUC_TWFreq[45][56] = 65; EUC_TWFreq[79][49] = 64; EUC_TWFreq[35][3] = 63; EUC_TWFreq[48][83] = + * 62; EUC_TWFreq[71][21] = 61; EUC_TWFreq[77][93] = 60; EUC_TWFreq[87][92] = 59; EUC_TWFreq[38][35] = 58; + * EUC_TWFreq[66][17] = 57; EUC_TWFreq[37][66] = 56; EUC_TWFreq[51][42] = 55; EUC_TWFreq[57][73] = 54; EUC_TWFreq[51][54] = + * 53; EUC_TWFreq[75][64] = 52; EUC_TWFreq[35][5] = 51; EUC_TWFreq[49][40] = 50; EUC_TWFreq[58][35] = 49; EUC_TWFreq[67][88] = + * 48; EUC_TWFreq[60][51] = 47; EUC_TWFreq[36][92] = 46; EUC_TWFreq[44][41] = 45; EUC_TWFreq[58][29] = 44; + * EUC_TWFreq[43][62] = 43; EUC_TWFreq[56][23] = 42; EUC_TWFreq[67][44] = 41; EUC_TWFreq[52][91] = 40; EUC_TWFreq[42][81] = + * 39; EUC_TWFreq[64][25] = 38; EUC_TWFreq[35][36] = 37; EUC_TWFreq[47][73] = 36; EUC_TWFreq[36][1] = 35; EUC_TWFreq[65][84] = + * 34; EUC_TWFreq[73][1] = 33; EUC_TWFreq[79][66] = 32; EUC_TWFreq[69][14] = 31; EUC_TWFreq[65][28] = 30; EUC_TWFreq[60][93] = + * 29; EUC_TWFreq[72][79] = 28; EUC_TWFreq[48][0] = 27; EUC_TWFreq[73][43] = 26; EUC_TWFreq[66][47] = 25; EUC_TWFreq[41][18] = + * 24; EUC_TWFreq[51][10] = 23; EUC_TWFreq[59][7] = 22; EUC_TWFreq[53][27] = 21; EUC_TWFreq[86][67] = 20; EUC_TWFreq[49][87] = + * 19; EUC_TWFreq[52][28] = 18; EUC_TWFreq[52][12] = 17; EUC_TWFreq[42][30] = 16; EUC_TWFreq[65][35] = 15; + * EUC_TWFreq[46][64] = 14; EUC_TWFreq[71][7] = 13; EUC_TWFreq[56][57] = 12; EUC_TWFreq[56][31] = 11; EUC_TWFreq[41][31] = + * 10; EUC_TWFreq[48][59] = 9; EUC_TWFreq[63][92] = 8; EUC_TWFreq[62][57] = 7; EUC_TWFreq[65][87] = 6; EUC_TWFreq[70][10] = + * 5; EUC_TWFreq[52][40] = 4; EUC_TWFreq[40][22] = 3; EUC_TWFreq[65][91] = 2; EUC_TWFreq[50][25] = 1; EUC_TWFreq[35][84] = + * 0; + */ + GBKFreq[52][132] = 600; + GBKFreq[73][135] = 599; + GBKFreq[49][123] = 598; + GBKFreq[77][146] = 597; + GBKFreq[81][123] = 596; + GBKFreq[82][144] = 595; + GBKFreq[51][179] = 594; + GBKFreq[83][154] = 593; + GBKFreq[71][139] = 592; + GBKFreq[64][139] = 591; + GBKFreq[85][144] = 590; + GBKFreq[52][125] = 589; + GBKFreq[88][25] = 588; + GBKFreq[81][106] = 587; + GBKFreq[81][148] = 586; + GBKFreq[62][137] = 585; + GBKFreq[94][0] = 584; + GBKFreq[1][64] = 583; + GBKFreq[67][163] = 582; + GBKFreq[20][190] = 581; + GBKFreq[57][131] = 580; + GBKFreq[29][169] = 579; + GBKFreq[72][143] = 578; + GBKFreq[0][173] = 577; + GBKFreq[11][23] = 576; + GBKFreq[61][141] = 575; + GBKFreq[60][123] = 574; + GBKFreq[81][114] = 573; + GBKFreq[82][131] = 572; + GBKFreq[67][156] = 571; + GBKFreq[71][167] = 570; + GBKFreq[20][50] = 569; + GBKFreq[77][132] = 568; + GBKFreq[84][38] = 567; + GBKFreq[26][29] = 566; + GBKFreq[74][187] = 565; + GBKFreq[62][116] = 564; + GBKFreq[67][135] = 563; + GBKFreq[5][86] = 562; + GBKFreq[72][186] = 561; + GBKFreq[75][161] = 560; + GBKFreq[78][130] = 559; + GBKFreq[94][30] = 558; + GBKFreq[84][72] = 557; + GBKFreq[1][67] = 556; + GBKFreq[75][172] = 555; + GBKFreq[74][185] = 554; + GBKFreq[53][160] = 553; + GBKFreq[123][14] = 552; + GBKFreq[79][97] = 551; + GBKFreq[85][110] = 550; + GBKFreq[78][171] = 549; + GBKFreq[52][131] = 548; + GBKFreq[56][100] = 547; + GBKFreq[50][182] = 546; + GBKFreq[94][64] = 545; + GBKFreq[106][74] = 544; + GBKFreq[11][102] = 543; + GBKFreq[53][124] = 542; + GBKFreq[24][3] = 541; + GBKFreq[86][148] = 540; + GBKFreq[53][184] = 539; + GBKFreq[86][147] = 538; + GBKFreq[96][161] = 537; + GBKFreq[82][77] = 536; + GBKFreq[59][146] = 535; + GBKFreq[84][126] = 534; + GBKFreq[79][132] = 533; + GBKFreq[85][123] = 532; + GBKFreq[71][101] = 531; + GBKFreq[85][106] = 530; + GBKFreq[6][184] = 529; + GBKFreq[57][156] = 528; + GBKFreq[75][104] = 527; + GBKFreq[50][137] = 526; + GBKFreq[79][133] = 525; + GBKFreq[76][108] = 524; + GBKFreq[57][142] = 523; + GBKFreq[84][130] = 522; + GBKFreq[52][128] = 521; + GBKFreq[47][44] = 520; + GBKFreq[52][152] = 519; + GBKFreq[54][104] = 518; + GBKFreq[30][47] = 517; + GBKFreq[71][123] = 516; + GBKFreq[52][107] = 515; + GBKFreq[45][84] = 514; + GBKFreq[107][118] = 513; + GBKFreq[5][161] = 512; + GBKFreq[48][126] = 511; + GBKFreq[67][170] = 510; + GBKFreq[43][6] = 509; + GBKFreq[70][112] = 508; + GBKFreq[86][174] = 507; + GBKFreq[84][166] = 506; + GBKFreq[79][130] = 505; + GBKFreq[57][141] = 504; + GBKFreq[81][178] = 503; + GBKFreq[56][187] = 502; + GBKFreq[81][162] = 501; + GBKFreq[53][104] = 500; + GBKFreq[123][35] = 499; + GBKFreq[70][169] = 498; + GBKFreq[69][164] = 497; + GBKFreq[109][61] = 496; + GBKFreq[73][130] = 495; + GBKFreq[62][134] = 494; + GBKFreq[54][125] = 493; + GBKFreq[79][105] = 492; + GBKFreq[70][165] = 491; + GBKFreq[71][189] = 490; + GBKFreq[23][147] = 489; + GBKFreq[51][139] = 488; + GBKFreq[47][137] = 487; + GBKFreq[77][123] = 486; + GBKFreq[86][183] = 485; + GBKFreq[63][173] = 484; + GBKFreq[79][144] = 483; + GBKFreq[84][159] = 482; + GBKFreq[60][91] = 481; + GBKFreq[66][187] = 480; + GBKFreq[73][114] = 479; + GBKFreq[85][56] = 478; + GBKFreq[71][149] = 477; + GBKFreq[84][189] = 476; + GBKFreq[104][31] = 475; + GBKFreq[83][82] = 474; + GBKFreq[68][35] = 473; + GBKFreq[11][77] = 472; + GBKFreq[15][155] = 471; + GBKFreq[83][153] = 470; + GBKFreq[71][1] = 469; + GBKFreq[53][190] = 468; + GBKFreq[50][135] = 467; + GBKFreq[3][147] = 466; + GBKFreq[48][136] = 465; + GBKFreq[66][166] = 464; + GBKFreq[55][159] = 463; + GBKFreq[82][150] = 462; + GBKFreq[58][178] = 461; + GBKFreq[64][102] = 460; + GBKFreq[16][106] = 459; + GBKFreq[68][110] = 458; + GBKFreq[54][14] = 457; + GBKFreq[60][140] = 456; + GBKFreq[91][71] = 455; + GBKFreq[54][150] = 454; + GBKFreq[78][177] = 453; + GBKFreq[78][117] = 452; + GBKFreq[104][12] = 451; + GBKFreq[73][150] = 450; + GBKFreq[51][142] = 449; + GBKFreq[81][145] = 448; + GBKFreq[66][183] = 447; + GBKFreq[51][178] = 446; + GBKFreq[75][107] = 445; + GBKFreq[65][119] = 444; + GBKFreq[69][176] = 443; + GBKFreq[59][122] = 442; + GBKFreq[78][160] = 441; + GBKFreq[85][183] = 440; + GBKFreq[105][16] = 439; + GBKFreq[73][110] = 438; + GBKFreq[104][39] = 437; + GBKFreq[119][16] = 436; + GBKFreq[76][162] = 435; + GBKFreq[67][152] = 434; + GBKFreq[82][24] = 433; + GBKFreq[73][121] = 432; + GBKFreq[83][83] = 431; + GBKFreq[82][145] = 430; + GBKFreq[49][133] = 429; + GBKFreq[94][13] = 428; + GBKFreq[58][139] = 427; + GBKFreq[74][189] = 426; + GBKFreq[66][177] = 425; + GBKFreq[85][184] = 424; + GBKFreq[55][183] = 423; + GBKFreq[71][107] = 422; + GBKFreq[11][98] = 421; + GBKFreq[72][153] = 420; + GBKFreq[2][137] = 419; + GBKFreq[59][147] = 418; + GBKFreq[58][152] = 417; + GBKFreq[55][144] = 416; + GBKFreq[73][125] = 415; + GBKFreq[52][154] = 414; + GBKFreq[70][178] = 413; + GBKFreq[79][148] = 412; + GBKFreq[63][143] = 411; + GBKFreq[50][140] = 410; + GBKFreq[47][145] = 409; + GBKFreq[48][123] = 408; + GBKFreq[56][107] = 407; + GBKFreq[84][83] = 406; + GBKFreq[59][112] = 405; + GBKFreq[124][72] = 404; + GBKFreq[79][99] = 403; + GBKFreq[3][37] = 402; + GBKFreq[114][55] = 401; + GBKFreq[85][152] = 400; + GBKFreq[60][47] = 399; + GBKFreq[65][96] = 398; + GBKFreq[74][110] = 397; + GBKFreq[86][182] = 396; + GBKFreq[50][99] = 395; + GBKFreq[67][186] = 394; + GBKFreq[81][74] = 393; + GBKFreq[80][37] = 392; + GBKFreq[21][60] = 391; + GBKFreq[110][12] = 390; + GBKFreq[60][162] = 389; + GBKFreq[29][115] = 388; + GBKFreq[83][130] = 387; + GBKFreq[52][136] = 386; + GBKFreq[63][114] = 385; + GBKFreq[49][127] = 384; + GBKFreq[83][109] = 383; + GBKFreq[66][128] = 382; + GBKFreq[78][136] = 381; + GBKFreq[81][180] = 380; + GBKFreq[76][104] = 379; + GBKFreq[56][156] = 378; + GBKFreq[61][23] = 377; + GBKFreq[4][30] = 376; + GBKFreq[69][154] = 375; + GBKFreq[100][37] = 374; + GBKFreq[54][177] = 373; + GBKFreq[23][119] = 372; + GBKFreq[71][171] = 371; + GBKFreq[84][146] = 370; + GBKFreq[20][184] = 369; + GBKFreq[86][76] = 368; + GBKFreq[74][132] = 367; + GBKFreq[47][97] = 366; + GBKFreq[82][137] = 365; + GBKFreq[94][56] = 364; + GBKFreq[92][30] = 363; + GBKFreq[19][117] = 362; + GBKFreq[48][173] = 361; + GBKFreq[2][136] = 360; + GBKFreq[7][182] = 359; + GBKFreq[74][188] = 358; + GBKFreq[14][132] = 357; + GBKFreq[62][172] = 356; + GBKFreq[25][39] = 355; + GBKFreq[85][129] = 354; + GBKFreq[64][98] = 353; + GBKFreq[67][127] = 352; + GBKFreq[72][167] = 351; + GBKFreq[57][143] = 350; + GBKFreq[76][187] = 349; + GBKFreq[83][181] = 348; + GBKFreq[84][10] = 347; + GBKFreq[55][166] = 346; + GBKFreq[55][188] = 345; + GBKFreq[13][151] = 344; + GBKFreq[62][124] = 343; + GBKFreq[53][136] = 342; + GBKFreq[106][57] = 341; + GBKFreq[47][166] = 340; + GBKFreq[109][30] = 339; + GBKFreq[78][114] = 338; + GBKFreq[83][19] = 337; + GBKFreq[56][162] = 336; + GBKFreq[60][177] = 335; + GBKFreq[88][9] = 334; + GBKFreq[74][163] = 333; + GBKFreq[52][156] = 332; + GBKFreq[71][180] = 331; + GBKFreq[60][57] = 330; + GBKFreq[72][173] = 329; + GBKFreq[82][91] = 328; + GBKFreq[51][186] = 327; + GBKFreq[75][86] = 326; + GBKFreq[75][78] = 325; + GBKFreq[76][170] = 324; + GBKFreq[60][147] = 323; + GBKFreq[82][75] = 322; + GBKFreq[80][148] = 321; + GBKFreq[86][150] = 320; + GBKFreq[13][95] = 319; + GBKFreq[0][11] = 318; + GBKFreq[84][190] = 317; + GBKFreq[76][166] = 316; + GBKFreq[14][72] = 315; + GBKFreq[67][144] = 314; + GBKFreq[84][44] = 313; + GBKFreq[72][125] = 312; + GBKFreq[66][127] = 311; + GBKFreq[60][25] = 310; + GBKFreq[70][146] = 309; + GBKFreq[79][135] = 308; + GBKFreq[54][135] = 307; + GBKFreq[60][104] = 306; + GBKFreq[55][132] = 305; + GBKFreq[94][2] = 304; + GBKFreq[54][133] = 303; + GBKFreq[56][190] = 302; + GBKFreq[58][174] = 301; + GBKFreq[80][144] = 300; + GBKFreq[85][113] = 299; + /* + * GBKFreq[83][15] = 298; GBKFreq[105][80] = 297; GBKFreq[7][179] = 296; GBKFreq[93][4] = 295; GBKFreq[123][40] = 294; + * GBKFreq[85][120] = 293; GBKFreq[77][165] = 292; GBKFreq[86][67] = 291; GBKFreq[25][162] = 290; GBKFreq[77][183] = 289; + * GBKFreq[83][71] = 288; GBKFreq[78][99] = 287; GBKFreq[72][177] = 286; GBKFreq[71][97] = 285; GBKFreq[58][111] = 284; + * GBKFreq[77][175] = 283; GBKFreq[76][181] = 282; GBKFreq[71][142] = 281; GBKFreq[64][150] = 280; GBKFreq[5][142] = 279; + * GBKFreq[73][128] = 278; GBKFreq[73][156] = 277; GBKFreq[60][188] = 276; GBKFreq[64][56] = 275; GBKFreq[74][128] = 274; + * GBKFreq[48][163] = 273; GBKFreq[54][116] = 272; GBKFreq[73][127] = 271; GBKFreq[16][176] = 270; GBKFreq[62][149] = 269; + * GBKFreq[105][96] = 268; GBKFreq[55][186] = 267; GBKFreq[4][51] = 266; GBKFreq[48][113] = 265; GBKFreq[48][152] = 264; + * GBKFreq[23][9] = 263; GBKFreq[56][102] = 262; GBKFreq[11][81] = 261; GBKFreq[82][112] = 260; GBKFreq[65][85] = 259; + * GBKFreq[69][125] = 258; GBKFreq[68][31] = 257; GBKFreq[5][20] = 256; GBKFreq[60][176] = 255; GBKFreq[82][81] = 254; + * GBKFreq[72][107] = 253; GBKFreq[3][52] = 252; GBKFreq[71][157] = 251; GBKFreq[24][46] = 250; GBKFreq[69][108] = 249; + * GBKFreq[78][178] = 248; GBKFreq[9][69] = 247; GBKFreq[73][144] = 246; GBKFreq[63][187] = 245; GBKFreq[68][36] = 244; + * GBKFreq[47][151] = 243; GBKFreq[14][74] = 242; GBKFreq[47][114] = 241; GBKFreq[80][171] = 240; GBKFreq[75][152] = 239; + * GBKFreq[86][40] = 238; GBKFreq[93][43] = 237; GBKFreq[2][50] = 236; GBKFreq[62][66] = 235; GBKFreq[1][183] = 234; + * GBKFreq[74][124] = 233; GBKFreq[58][104] = 232; GBKFreq[83][106] = 231; GBKFreq[60][144] = 230; GBKFreq[48][99] = 229; + * GBKFreq[54][157] = 228; GBKFreq[70][179] = 227; GBKFreq[61][127] = 226; GBKFreq[57][135] = 225; GBKFreq[59][190] = 224; + * GBKFreq[77][116] = 223; GBKFreq[26][17] = 222; GBKFreq[60][13] = 221; GBKFreq[71][38] = 220; GBKFreq[85][177] = 219; + * GBKFreq[59][73] = 218; GBKFreq[50][150] = 217; GBKFreq[79][102] = 216; GBKFreq[76][118] = 215; GBKFreq[67][132] = 214; + * GBKFreq[73][146] = 213; GBKFreq[83][184] = 212; GBKFreq[86][159] = 211; GBKFreq[95][120] = 210; GBKFreq[23][139] = 209; + * GBKFreq[64][183] = 208; GBKFreq[85][103] = 207; GBKFreq[41][90] = 206; GBKFreq[87][72] = 205; GBKFreq[62][104] = 204; + * GBKFreq[79][168] = 203; GBKFreq[79][150] = 202; GBKFreq[104][20] = 201; GBKFreq[56][114] = 200; GBKFreq[84][26] = 199; + * GBKFreq[57][99] = 198; GBKFreq[62][154] = 197; GBKFreq[47][98] = 196; GBKFreq[61][64] = 195; GBKFreq[112][18] = 194; + * GBKFreq[123][19] = 193; GBKFreq[4][98] = 192; GBKFreq[47][163] = 191; GBKFreq[66][188] = 190; GBKFreq[81][85] = 189; + * GBKFreq[82][30] = 188; GBKFreq[65][83] = 187; GBKFreq[67][24] = 186; GBKFreq[68][179] = 185; GBKFreq[55][177] = 184; + * GBKFreq[2][122] = 183; GBKFreq[47][139] = 182; GBKFreq[79][158] = 181; GBKFreq[64][143] = 180; GBKFreq[100][24] = 179; + * GBKFreq[73][103] = 178; GBKFreq[50][148] = 177; GBKFreq[86][97] = 176; GBKFreq[59][116] = 175; GBKFreq[64][173] = 174; + * GBKFreq[99][91] = 173; GBKFreq[11][99] = 172; GBKFreq[78][179] = 171; GBKFreq[18][17] = 170; GBKFreq[58][185] = 169; + * GBKFreq[47][165] = 168; GBKFreq[67][131] = 167; GBKFreq[94][40] = 166; GBKFreq[74][153] = 165; GBKFreq[79][142] = 164; + * GBKFreq[57][98] = 163; GBKFreq[1][164] = 162; GBKFreq[55][168] = 161; GBKFreq[13][141] = 160; GBKFreq[51][31] = 159; + * GBKFreq[57][178] = 158; GBKFreq[50][189] = 157; GBKFreq[60][167] = 156; GBKFreq[80][34] = 155; GBKFreq[109][80] = 154; + * GBKFreq[85][54] = 153; GBKFreq[69][183] = 152; GBKFreq[67][143] = 151; GBKFreq[47][120] = 150; GBKFreq[45][75] = 149; + * GBKFreq[82][98] = 148; GBKFreq[83][22] = 147; GBKFreq[13][103] = 146; GBKFreq[49][174] = 145; GBKFreq[57][181] = 144; + * GBKFreq[64][127] = 143; GBKFreq[61][131] = 142; GBKFreq[52][180] = 141; GBKFreq[74][134] = 140; GBKFreq[84][187] = 139; + * GBKFreq[81][189] = 138; GBKFreq[47][160] = 137; GBKFreq[66][148] = 136; GBKFreq[7][4] = 135; GBKFreq[85][134] = 134; + * GBKFreq[88][13] = 133; GBKFreq[88][80] = 132; GBKFreq[69][166] = 131; GBKFreq[86][18] = 130; GBKFreq[79][141] = 129; + * GBKFreq[50][108] = 128; GBKFreq[94][69] = 127; GBKFreq[81][110] = 126; GBKFreq[69][119] = 125; GBKFreq[72][161] = 124; + * GBKFreq[106][45] = 123; GBKFreq[73][124] = 122; GBKFreq[94][28] = 121; GBKFreq[63][174] = 120; GBKFreq[3][149] = 119; + * GBKFreq[24][160] = 118; GBKFreq[113][94] = 117; GBKFreq[56][138] = 116; GBKFreq[64][185] = 115; GBKFreq[86][56] = 114; + * GBKFreq[56][150] = 113; GBKFreq[110][55] = 112; GBKFreq[28][13] = 111; GBKFreq[54][190] = 110; GBKFreq[8][180] = 109; + * GBKFreq[73][149] = 108; GBKFreq[80][155] = 107; GBKFreq[83][172] = 106; GBKFreq[67][174] = 105; GBKFreq[64][180] = 104; + * GBKFreq[84][46] = 103; GBKFreq[91][74] = 102; GBKFreq[69][134] = 101; GBKFreq[61][107] = 100; GBKFreq[47][171] = 99; + * GBKFreq[59][51] = 98; GBKFreq[109][74] = 97; GBKFreq[64][174] = 96; GBKFreq[52][151] = 95; GBKFreq[51][176] = 94; + * GBKFreq[80][157] = 93; GBKFreq[94][31] = 92; GBKFreq[79][155] = 91; GBKFreq[72][174] = 90; GBKFreq[69][113] = 89; + * GBKFreq[83][167] = 88; GBKFreq[83][122] = 87; GBKFreq[8][178] = 86; GBKFreq[70][186] = 85; GBKFreq[59][153] = 84; + * GBKFreq[84][68] = 83; GBKFreq[79][39] = 82; GBKFreq[47][180] = 81; GBKFreq[88][53] = 80; GBKFreq[57][154] = 79; + * GBKFreq[47][153] = 78; GBKFreq[3][153] = 77; GBKFreq[76][134] = 76; GBKFreq[51][166] = 75; GBKFreq[58][176] = 74; + * GBKFreq[27][138] = 73; GBKFreq[73][126] = 72; GBKFreq[76][185] = 71; GBKFreq[52][186] = 70; GBKFreq[81][151] = 69; + * GBKFreq[26][50] = 68; GBKFreq[76][173] = 67; GBKFreq[106][56] = 66; GBKFreq[85][142] = 65; GBKFreq[11][103] = 64; + * GBKFreq[69][159] = 63; GBKFreq[53][142] = 62; GBKFreq[7][6] = 61; GBKFreq[84][59] = 60; GBKFreq[86][3] = 59; + * GBKFreq[64][144] = 58; GBKFreq[1][187] = 57; GBKFreq[82][128] = 56; GBKFreq[3][66] = 55; GBKFreq[68][133] = 54; + * GBKFreq[55][167] = 53; GBKFreq[52][130] = 52; GBKFreq[61][133] = 51; GBKFreq[72][181] = 50; GBKFreq[25][98] = 49; + * GBKFreq[84][149] = 48; GBKFreq[91][91] = 47; GBKFreq[47][188] = 46; GBKFreq[68][130] = 45; GBKFreq[22][44] = 44; + * GBKFreq[81][121] = 43; GBKFreq[72][140] = 42; GBKFreq[55][133] = 41; GBKFreq[55][185] = 40; GBKFreq[56][105] = 39; + * GBKFreq[60][30] = 38; GBKFreq[70][103] = 37; GBKFreq[62][141] = 36; GBKFreq[70][144] = 35; GBKFreq[59][111] = 34; + * GBKFreq[54][17] = 33; GBKFreq[18][190] = 32; GBKFreq[65][164] = 31; GBKFreq[83][125] = 30; GBKFreq[61][121] = 29; + * GBKFreq[48][13] = 28; GBKFreq[51][189] = 27; GBKFreq[65][68] = 26; GBKFreq[7][0] = 25; GBKFreq[76][188] = 24; + * GBKFreq[85][117] = 23; GBKFreq[45][33] = 22; GBKFreq[78][187] = 21; GBKFreq[106][48] = 20; GBKFreq[59][52] = 19; + * GBKFreq[86][185] = 18; GBKFreq[84][121] = 17; GBKFreq[82][189] = 16; GBKFreq[68][156] = 15; GBKFreq[55][125] = 14; + * GBKFreq[65][175] = 13; GBKFreq[7][140] = 12; GBKFreq[50][106] = 11; GBKFreq[59][124] = 10; GBKFreq[67][115] = 9; + * GBKFreq[82][114] = 8; GBKFreq[74][121] = 7; GBKFreq[106][69] = 6; GBKFreq[94][27] = 5; GBKFreq[78][98] = 4; + * GBKFreq[85][186] = 3; GBKFreq[108][90] = 2; GBKFreq[62][160] = 1; GBKFreq[60][169] = 0; + */ + KRFreq[31][43] = 600; + KRFreq[19][56] = 599; + KRFreq[38][46] = 598; + KRFreq[3][3] = 597; + KRFreq[29][77] = 596; + KRFreq[19][33] = 595; + KRFreq[30][0] = 594; + KRFreq[29][89] = 593; + KRFreq[31][26] = 592; + KRFreq[31][38] = 591; + KRFreq[32][85] = 590; + KRFreq[15][0] = 589; + KRFreq[16][54] = 588; + KRFreq[15][76] = 587; + KRFreq[31][25] = 586; + KRFreq[23][13] = 585; + KRFreq[28][34] = 584; + KRFreq[18][9] = 583; + KRFreq[29][37] = 582; + KRFreq[22][45] = 581; + KRFreq[19][46] = 580; + KRFreq[16][65] = 579; + KRFreq[23][5] = 578; + KRFreq[26][70] = 577; + KRFreq[31][53] = 576; + KRFreq[27][12] = 575; + KRFreq[30][67] = 574; + KRFreq[31][57] = 573; + KRFreq[20][20] = 572; + KRFreq[30][31] = 571; + KRFreq[20][72] = 570; + KRFreq[15][51] = 569; + KRFreq[3][8] = 568; + KRFreq[32][53] = 567; + KRFreq[27][85] = 566; + KRFreq[25][23] = 565; + KRFreq[15][44] = 564; + KRFreq[32][3] = 563; + KRFreq[31][68] = 562; + KRFreq[30][24] = 561; + KRFreq[29][49] = 560; + KRFreq[27][49] = 559; + KRFreq[23][23] = 558; + KRFreq[31][91] = 557; + KRFreq[31][46] = 556; + KRFreq[19][74] = 555; + KRFreq[27][27] = 554; + KRFreq[3][17] = 553; + KRFreq[20][38] = 552; + KRFreq[21][82] = 551; + KRFreq[28][25] = 550; + KRFreq[32][5] = 549; + KRFreq[31][23] = 548; + KRFreq[25][45] = 547; + KRFreq[32][87] = 546; + KRFreq[18][26] = 545; + KRFreq[24][10] = 544; + KRFreq[26][82] = 543; + KRFreq[15][89] = 542; + KRFreq[28][36] = 541; + KRFreq[28][31] = 540; + KRFreq[16][23] = 539; + KRFreq[16][77] = 538; + KRFreq[19][84] = 537; + KRFreq[23][72] = 536; + KRFreq[38][48] = 535; + KRFreq[23][2] = 534; + KRFreq[30][20] = 533; + KRFreq[38][47] = 532; + KRFreq[39][12] = 531; + KRFreq[23][21] = 530; + KRFreq[18][17] = 529; + KRFreq[30][87] = 528; + KRFreq[29][62] = 527; + KRFreq[29][87] = 526; + KRFreq[34][53] = 525; + KRFreq[32][29] = 524; + KRFreq[35][0] = 523; + KRFreq[24][43] = 522; + KRFreq[36][44] = 521; + KRFreq[20][30] = 520; + KRFreq[39][86] = 519; + KRFreq[22][14] = 518; + KRFreq[29][39] = 517; + KRFreq[28][38] = 516; + KRFreq[23][79] = 515; + KRFreq[24][56] = 514; + KRFreq[29][63] = 513; + KRFreq[31][45] = 512; + KRFreq[23][26] = 511; + KRFreq[15][87] = 510; + KRFreq[30][74] = 509; + KRFreq[24][69] = 508; + KRFreq[20][4] = 507; + KRFreq[27][50] = 506; + KRFreq[30][75] = 505; + KRFreq[24][13] = 504; + KRFreq[30][8] = 503; + KRFreq[31][6] = 502; + KRFreq[25][80] = 501; + KRFreq[36][8] = 500; + KRFreq[15][18] = 499; + KRFreq[39][23] = 498; + KRFreq[16][24] = 497; + KRFreq[31][89] = 496; + KRFreq[15][71] = 495; + KRFreq[15][57] = 494; + KRFreq[30][11] = 493; + KRFreq[15][36] = 492; + KRFreq[16][60] = 491; + KRFreq[24][45] = 490; + KRFreq[37][35] = 489; + KRFreq[24][87] = 488; + KRFreq[20][45] = 487; + KRFreq[31][90] = 486; + KRFreq[32][21] = 485; + KRFreq[19][70] = 484; + KRFreq[24][15] = 483; + KRFreq[26][92] = 482; + KRFreq[37][13] = 481; + KRFreq[39][2] = 480; + KRFreq[23][70] = 479; + KRFreq[27][25] = 478; + KRFreq[15][69] = 477; + KRFreq[19][61] = 476; + KRFreq[31][58] = 475; + KRFreq[24][57] = 474; + KRFreq[36][74] = 473; + KRFreq[21][6] = 472; + KRFreq[30][44] = 471; + KRFreq[15][91] = 470; + KRFreq[27][16] = 469; + KRFreq[29][42] = 468; + KRFreq[33][86] = 467; + KRFreq[29][41] = 466; + KRFreq[20][68] = 465; + KRFreq[25][47] = 464; + KRFreq[22][0] = 463; + KRFreq[18][14] = 462; + KRFreq[31][28] = 461; + KRFreq[15][2] = 460; + KRFreq[23][76] = 459; + KRFreq[38][32] = 458; + KRFreq[29][82] = 457; + KRFreq[21][86] = 456; + KRFreq[24][62] = 455; + KRFreq[31][64] = 454; + KRFreq[38][26] = 453; + KRFreq[32][86] = 452; + KRFreq[22][32] = 451; + KRFreq[19][59] = 450; + KRFreq[34][18] = 449; + KRFreq[18][54] = 448; + KRFreq[38][63] = 447; + KRFreq[36][23] = 446; + KRFreq[35][35] = 445; + KRFreq[32][62] = 444; + KRFreq[28][35] = 443; + KRFreq[27][13] = 442; + KRFreq[31][59] = 441; + KRFreq[29][29] = 440; + KRFreq[15][64] = 439; + KRFreq[26][84] = 438; + KRFreq[21][90] = 437; + KRFreq[20][24] = 436; + KRFreq[16][18] = 435; + KRFreq[22][23] = 434; + KRFreq[31][14] = 433; + KRFreq[15][1] = 432; + KRFreq[18][63] = 431; + KRFreq[19][10] = 430; + KRFreq[25][49] = 429; + KRFreq[36][57] = 428; + KRFreq[20][22] = 427; + KRFreq[15][15] = 426; + KRFreq[31][51] = 425; + KRFreq[24][60] = 424; + KRFreq[31][70] = 423; + KRFreq[15][7] = 422; + KRFreq[28][40] = 421; + KRFreq[18][41] = 420; + KRFreq[15][38] = 419; + KRFreq[32][0] = 418; + KRFreq[19][51] = 417; + KRFreq[34][62] = 416; + KRFreq[16][27] = 415; + KRFreq[20][70] = 414; + KRFreq[22][33] = 413; + KRFreq[26][73] = 412; + KRFreq[20][79] = 411; + KRFreq[23][6] = 410; + KRFreq[24][85] = 409; + KRFreq[38][51] = 408; + KRFreq[29][88] = 407; + KRFreq[38][55] = 406; + KRFreq[32][32] = 405; + KRFreq[27][18] = 404; + KRFreq[23][87] = 403; + KRFreq[35][6] = 402; + KRFreq[34][27] = 401; + KRFreq[39][35] = 400; + KRFreq[30][88] = 399; + KRFreq[32][92] = 398; + KRFreq[32][49] = 397; + KRFreq[24][61] = 396; + KRFreq[18][74] = 395; + KRFreq[23][77] = 394; + KRFreq[23][50] = 393; + KRFreq[23][32] = 392; + KRFreq[23][36] = 391; + KRFreq[38][38] = 390; + KRFreq[29][86] = 389; + KRFreq[36][15] = 388; + KRFreq[31][50] = 387; + KRFreq[15][86] = 386; + KRFreq[39][13] = 385; + KRFreq[34][26] = 384; + KRFreq[19][34] = 383; + KRFreq[16][3] = 382; + KRFreq[26][93] = 381; + KRFreq[19][67] = 380; + KRFreq[24][72] = 379; + KRFreq[29][17] = 378; + KRFreq[23][24] = 377; + KRFreq[25][19] = 376; + KRFreq[18][65] = 375; + KRFreq[30][78] = 374; + KRFreq[27][52] = 373; + KRFreq[22][18] = 372; + KRFreq[16][38] = 371; + KRFreq[21][26] = 370; + KRFreq[34][20] = 369; + KRFreq[15][42] = 368; + KRFreq[16][71] = 367; + KRFreq[17][17] = 366; + KRFreq[24][71] = 365; + KRFreq[18][84] = 364; + KRFreq[15][40] = 363; + KRFreq[31][62] = 362; + KRFreq[15][8] = 361; + KRFreq[16][69] = 360; + KRFreq[29][79] = 359; + KRFreq[38][91] = 358; + KRFreq[31][92] = 357; + KRFreq[20][77] = 356; + KRFreq[3][16] = 355; + KRFreq[27][87] = 354; + KRFreq[16][25] = 353; + KRFreq[36][33] = 352; + KRFreq[37][76] = 351; + KRFreq[30][12] = 350; + KRFreq[26][75] = 349; + KRFreq[25][14] = 348; + KRFreq[32][26] = 347; + KRFreq[23][22] = 346; + KRFreq[20][90] = 345; + KRFreq[19][8] = 344; + KRFreq[38][41] = 343; + KRFreq[34][2] = 342; + KRFreq[39][4] = 341; + KRFreq[27][89] = 340; + KRFreq[28][41] = 339; + KRFreq[28][44] = 338; + KRFreq[24][92] = 337; + KRFreq[34][65] = 336; + KRFreq[39][14] = 335; + KRFreq[21][38] = 334; + KRFreq[19][31] = 333; + KRFreq[37][39] = 332; + KRFreq[33][41] = 331; + KRFreq[38][4] = 330; + KRFreq[23][80] = 329; + KRFreq[25][24] = 328; + KRFreq[37][17] = 327; + KRFreq[22][16] = 326; + KRFreq[22][46] = 325; + KRFreq[33][91] = 324; + KRFreq[24][89] = 323; + KRFreq[30][52] = 322; + KRFreq[29][38] = 321; + KRFreq[38][85] = 320; + KRFreq[15][12] = 319; + KRFreq[27][58] = 318; + KRFreq[29][52] = 317; + KRFreq[37][38] = 316; + KRFreq[34][41] = 315; + KRFreq[31][65] = 314; + KRFreq[29][53] = 313; + KRFreq[22][47] = 312; + KRFreq[22][19] = 311; + KRFreq[26][0] = 310; + KRFreq[37][86] = 309; + KRFreq[35][4] = 308; + KRFreq[36][54] = 307; + KRFreq[20][76] = 306; + KRFreq[30][9] = 305; + KRFreq[30][33] = 304; + KRFreq[23][17] = 303; + KRFreq[23][33] = 302; + KRFreq[38][52] = 301; + KRFreq[15][19] = 300; + KRFreq[28][45] = 299; + KRFreq[29][78] = 298; + KRFreq[23][15] = 297; + KRFreq[33][5] = 296; + KRFreq[17][40] = 295; + KRFreq[30][83] = 294; + KRFreq[18][1] = 293; + KRFreq[30][81] = 292; + KRFreq[19][40] = 291; + KRFreq[24][47] = 290; + KRFreq[17][56] = 289; + KRFreq[39][80] = 288; + KRFreq[30][46] = 287; + KRFreq[16][61] = 286; + KRFreq[26][78] = 285; + KRFreq[26][57] = 284; + KRFreq[20][46] = 283; + KRFreq[25][15] = 282; + KRFreq[25][91] = 281; + KRFreq[21][83] = 280; + KRFreq[30][77] = 279; + KRFreq[35][30] = 278; + KRFreq[30][34] = 277; + KRFreq[20][69] = 276; + KRFreq[35][10] = 275; + KRFreq[29][70] = 274; + KRFreq[22][50] = 273; + KRFreq[18][0] = 272; + KRFreq[22][64] = 271; + KRFreq[38][65] = 270; + KRFreq[22][70] = 269; + KRFreq[24][58] = 268; + KRFreq[19][66] = 267; + KRFreq[30][59] = 266; + KRFreq[37][14] = 265; + KRFreq[16][56] = 264; + KRFreq[29][85] = 263; + KRFreq[31][15] = 262; + KRFreq[36][84] = 261; + KRFreq[39][15] = 260; + KRFreq[39][90] = 259; + KRFreq[18][12] = 258; + KRFreq[21][93] = 257; + KRFreq[24][66] = 256; + KRFreq[27][90] = 255; + KRFreq[25][90] = 254; + KRFreq[22][24] = 253; + KRFreq[36][67] = 252; + KRFreq[33][90] = 251; + KRFreq[15][60] = 250; + KRFreq[23][85] = 249; + KRFreq[34][1] = 248; + KRFreq[39][37] = 247; + KRFreq[21][18] = 246; + KRFreq[34][4] = 245; + KRFreq[28][33] = 244; + KRFreq[15][13] = 243; + KRFreq[32][22] = 242; + KRFreq[30][76] = 241; + KRFreq[20][21] = 240; + KRFreq[38][66] = 239; + KRFreq[32][55] = 238; + KRFreq[32][89] = 237; + KRFreq[25][26] = 236; + KRFreq[16][80] = 235; + KRFreq[15][43] = 234; + KRFreq[38][54] = 233; + KRFreq[39][68] = 232; + KRFreq[22][88] = 231; + KRFreq[21][84] = 230; + KRFreq[21][17] = 229; + KRFreq[20][28] = 228; + KRFreq[32][1] = 227; + KRFreq[33][87] = 226; + KRFreq[38][71] = 225; + KRFreq[37][47] = 224; + KRFreq[18][77] = 223; + KRFreq[37][58] = 222; + KRFreq[34][74] = 221; + KRFreq[32][54] = 220; + KRFreq[27][33] = 219; + KRFreq[32][93] = 218; + KRFreq[23][51] = 217; + KRFreq[20][57] = 216; + KRFreq[22][37] = 215; + KRFreq[39][10] = 214; + KRFreq[39][17] = 213; + KRFreq[33][4] = 212; + KRFreq[32][84] = 211; + KRFreq[34][3] = 210; + KRFreq[28][27] = 209; + KRFreq[15][79] = 208; + KRFreq[34][21] = 207; + KRFreq[34][69] = 206; + KRFreq[21][62] = 205; + KRFreq[36][24] = 204; + KRFreq[16][89] = 203; + KRFreq[18][48] = 202; + KRFreq[38][15] = 201; + KRFreq[36][58] = 200; + KRFreq[21][56] = 199; + KRFreq[34][48] = 198; + KRFreq[21][15] = 197; + KRFreq[39][3] = 196; + KRFreq[16][44] = 195; + KRFreq[18][79] = 194; + KRFreq[25][13] = 193; + KRFreq[29][47] = 192; + KRFreq[38][88] = 191; + KRFreq[20][71] = 190; + KRFreq[16][58] = 189; + KRFreq[35][57] = 188; + KRFreq[29][30] = 187; + KRFreq[29][23] = 186; + KRFreq[34][93] = 185; + KRFreq[30][85] = 184; + KRFreq[15][80] = 183; + KRFreq[32][78] = 182; + KRFreq[37][82] = 181; + KRFreq[22][40] = 180; + KRFreq[21][69] = 179; + KRFreq[26][85] = 178; + KRFreq[31][31] = 177; + KRFreq[28][64] = 176; + KRFreq[38][13] = 175; + KRFreq[25][2] = 174; + KRFreq[22][34] = 173; + KRFreq[28][28] = 172; + KRFreq[24][91] = 171; + KRFreq[33][74] = 170; + KRFreq[29][40] = 169; + KRFreq[15][77] = 168; + KRFreq[32][80] = 167; + KRFreq[30][41] = 166; + KRFreq[23][30] = 165; + KRFreq[24][63] = 164; + KRFreq[30][53] = 163; + KRFreq[39][70] = 162; + KRFreq[23][61] = 161; + KRFreq[37][27] = 160; + KRFreq[16][55] = 159; + KRFreq[22][74] = 158; + KRFreq[26][50] = 157; + KRFreq[16][10] = 156; + KRFreq[34][63] = 155; + KRFreq[35][14] = 154; + KRFreq[17][7] = 153; + KRFreq[15][59] = 152; + KRFreq[27][23] = 151; + KRFreq[18][70] = 150; + KRFreq[32][56] = 149; + KRFreq[37][87] = 148; + KRFreq[17][61] = 147; + KRFreq[18][83] = 146; + KRFreq[23][86] = 145; + KRFreq[17][31] = 144; + KRFreq[23][83] = 143; + KRFreq[35][2] = 142; + KRFreq[18][64] = 141; + KRFreq[27][43] = 140; + KRFreq[32][42] = 139; + KRFreq[25][76] = 138; + KRFreq[19][85] = 137; + KRFreq[37][81] = 136; + KRFreq[38][83] = 135; + KRFreq[35][7] = 134; + KRFreq[16][51] = 133; + KRFreq[27][22] = 132; + KRFreq[16][76] = 131; + KRFreq[22][4] = 130; + KRFreq[38][84] = 129; + KRFreq[17][83] = 128; + KRFreq[24][46] = 127; + KRFreq[33][15] = 126; + KRFreq[20][48] = 125; + KRFreq[17][30] = 124; + KRFreq[30][93] = 123; + KRFreq[28][11] = 122; + KRFreq[28][30] = 121; + KRFreq[15][62] = 120; + KRFreq[17][87] = 119; + KRFreq[32][81] = 118; + KRFreq[23][37] = 117; + KRFreq[30][22] = 116; + KRFreq[32][66] = 115; + KRFreq[33][78] = 114; + KRFreq[21][4] = 113; + KRFreq[31][17] = 112; + KRFreq[39][61] = 111; + KRFreq[18][76] = 110; + KRFreq[15][85] = 109; + KRFreq[31][47] = 108; + KRFreq[19][57] = 107; + KRFreq[23][55] = 106; + KRFreq[27][29] = 105; + KRFreq[29][46] = 104; + KRFreq[33][0] = 103; + KRFreq[16][83] = 102; + KRFreq[39][78] = 101; + KRFreq[32][77] = 100; + KRFreq[36][25] = 99; + KRFreq[34][19] = 98; + KRFreq[38][49] = 97; + KRFreq[19][25] = 96; + KRFreq[23][53] = 95; + KRFreq[28][43] = 94; + KRFreq[31][44] = 93; + KRFreq[36][34] = 92; + KRFreq[16][34] = 91; + KRFreq[35][1] = 90; + KRFreq[19][87] = 89; + KRFreq[18][53] = 88; + KRFreq[29][54] = 87; + KRFreq[22][41] = 86; + KRFreq[38][18] = 85; + KRFreq[22][2] = 84; + KRFreq[20][3] = 83; + KRFreq[39][69] = 82; + KRFreq[30][29] = 81; + KRFreq[28][19] = 80; + KRFreq[29][90] = 79; + KRFreq[17][86] = 78; + KRFreq[15][9] = 77; + KRFreq[39][73] = 76; + KRFreq[15][37] = 75; + KRFreq[35][40] = 74; + KRFreq[33][77] = 73; + KRFreq[27][86] = 72; + KRFreq[36][79] = 71; + KRFreq[23][18] = 70; + KRFreq[34][87] = 69; + KRFreq[39][24] = 68; + KRFreq[26][8] = 67; + KRFreq[33][48] = 66; + KRFreq[39][30] = 65; + KRFreq[33][28] = 64; + KRFreq[16][67] = 63; + KRFreq[31][78] = 62; + KRFreq[32][23] = 61; + KRFreq[24][55] = 60; + KRFreq[30][68] = 59; + KRFreq[18][60] = 58; + KRFreq[15][17] = 57; + KRFreq[23][34] = 56; + KRFreq[20][49] = 55; + KRFreq[15][78] = 54; + KRFreq[24][14] = 53; + KRFreq[19][41] = 52; + KRFreq[31][55] = 51; + KRFreq[21][39] = 50; + KRFreq[35][9] = 49; + KRFreq[30][15] = 48; + KRFreq[20][52] = 47; + KRFreq[35][71] = 46; + KRFreq[20][7] = 45; + KRFreq[29][72] = 44; + KRFreq[37][77] = 43; + KRFreq[22][35] = 42; + KRFreq[20][61] = 41; + KRFreq[31][60] = 40; + KRFreq[20][93] = 39; + KRFreq[27][92] = 38; + KRFreq[28][16] = 37; + KRFreq[36][26] = 36; + KRFreq[18][89] = 35; + KRFreq[21][63] = 34; + KRFreq[22][52] = 33; + KRFreq[24][65] = 32; + KRFreq[31][8] = 31; + KRFreq[31][49] = 30; + KRFreq[33][30] = 29; + KRFreq[37][15] = 28; + KRFreq[18][18] = 27; + KRFreq[25][50] = 26; + KRFreq[29][20] = 25; + KRFreq[35][48] = 24; + KRFreq[38][75] = 23; + KRFreq[26][83] = 22; + KRFreq[21][87] = 21; + KRFreq[27][71] = 20; + KRFreq[32][91] = 19; + KRFreq[25][73] = 18; + KRFreq[16][84] = 17; + KRFreq[25][31] = 16; + KRFreq[17][90] = 15; + KRFreq[18][40] = 14; + KRFreq[17][77] = 13; + KRFreq[17][35] = 12; + KRFreq[23][52] = 11; + KRFreq[23][35] = 10; + KRFreq[16][5] = 9; + KRFreq[23][58] = 8; + KRFreq[19][60] = 7; + KRFreq[30][32] = 6; + KRFreq[38][34] = 5; + KRFreq[23][4] = 4; + KRFreq[23][1] = 3; + KRFreq[27][57] = 2; + KRFreq[39][38] = 1; + KRFreq[32][33] = 0; + JPFreq[3][74] = 600; + JPFreq[3][45] = 599; + JPFreq[3][3] = 598; + JPFreq[3][24] = 597; + JPFreq[3][30] = 596; + JPFreq[3][42] = 595; + JPFreq[3][46] = 594; + JPFreq[3][39] = 593; + JPFreq[3][11] = 592; + JPFreq[3][37] = 591; + JPFreq[3][38] = 590; + JPFreq[3][31] = 589; + JPFreq[3][41] = 588; + JPFreq[3][5] = 587; + JPFreq[3][10] = 586; + JPFreq[3][75] = 585; + JPFreq[3][65] = 584; + JPFreq[3][72] = 583; + JPFreq[37][91] = 582; + JPFreq[0][27] = 581; + JPFreq[3][18] = 580; + JPFreq[3][22] = 579; + JPFreq[3][61] = 578; + JPFreq[3][14] = 577; + JPFreq[24][80] = 576; + JPFreq[4][82] = 575; + JPFreq[17][80] = 574; + JPFreq[30][44] = 573; + JPFreq[3][73] = 572; + JPFreq[3][64] = 571; + JPFreq[38][14] = 570; + JPFreq[33][70] = 569; + JPFreq[3][1] = 568; + JPFreq[3][16] = 567; + JPFreq[3][35] = 566; + JPFreq[3][40] = 565; + JPFreq[4][74] = 564; + JPFreq[4][24] = 563; + JPFreq[42][59] = 562; + JPFreq[3][7] = 561; + JPFreq[3][71] = 560; + JPFreq[3][12] = 559; + JPFreq[15][75] = 558; + JPFreq[3][20] = 557; + JPFreq[4][39] = 556; + JPFreq[34][69] = 555; + JPFreq[3][28] = 554; + JPFreq[35][24] = 553; + JPFreq[3][82] = 552; + JPFreq[28][47] = 551; + JPFreq[3][67] = 550; + JPFreq[37][16] = 549; + JPFreq[26][93] = 548; + JPFreq[4][1] = 547; + JPFreq[26][85] = 546; + JPFreq[31][14] = 545; + JPFreq[4][3] = 544; + JPFreq[4][72] = 543; + JPFreq[24][51] = 542; + JPFreq[27][51] = 541; + JPFreq[27][49] = 540; + JPFreq[22][77] = 539; + JPFreq[27][10] = 538; + JPFreq[29][68] = 537; + JPFreq[20][35] = 536; + JPFreq[41][11] = 535; + JPFreq[24][70] = 534; + JPFreq[36][61] = 533; + JPFreq[31][23] = 532; + JPFreq[43][16] = 531; + JPFreq[23][68] = 530; + JPFreq[32][15] = 529; + JPFreq[3][32] = 528; + JPFreq[19][53] = 527; + JPFreq[40][83] = 526; + JPFreq[4][14] = 525; + JPFreq[36][9] = 524; + JPFreq[4][73] = 523; + JPFreq[23][10] = 522; + JPFreq[3][63] = 521; + JPFreq[39][14] = 520; + JPFreq[3][78] = 519; + JPFreq[33][47] = 518; + JPFreq[21][39] = 517; + JPFreq[34][46] = 516; + JPFreq[36][75] = 515; + JPFreq[41][92] = 514; + JPFreq[37][93] = 513; + JPFreq[4][34] = 512; + JPFreq[15][86] = 511; + JPFreq[46][1] = 510; + JPFreq[37][65] = 509; + JPFreq[3][62] = 508; + JPFreq[32][73] = 507; + JPFreq[21][65] = 506; + JPFreq[29][75] = 505; + JPFreq[26][51] = 504; + JPFreq[3][34] = 503; + JPFreq[4][10] = 502; + JPFreq[30][22] = 501; + JPFreq[35][73] = 500; + JPFreq[17][82] = 499; + JPFreq[45][8] = 498; + JPFreq[27][73] = 497; + JPFreq[18][55] = 496; + JPFreq[25][2] = 495; + JPFreq[3][26] = 494; + JPFreq[45][46] = 493; + JPFreq[4][22] = 492; + JPFreq[4][40] = 491; + JPFreq[18][10] = 490; + JPFreq[32][9] = 489; + JPFreq[26][49] = 488; + JPFreq[3][47] = 487; + JPFreq[24][65] = 486; + JPFreq[4][76] = 485; + JPFreq[43][67] = 484; + JPFreq[3][9] = 483; + JPFreq[41][37] = 482; + JPFreq[33][68] = 481; + JPFreq[43][31] = 480; + JPFreq[19][55] = 479; + JPFreq[4][30] = 478; + JPFreq[27][33] = 477; + JPFreq[16][62] = 476; + JPFreq[36][35] = 475; + JPFreq[37][15] = 474; + JPFreq[27][70] = 473; + JPFreq[22][71] = 472; + JPFreq[33][45] = 471; + JPFreq[31][78] = 470; + JPFreq[43][59] = 469; + JPFreq[32][19] = 468; + JPFreq[17][28] = 467; + JPFreq[40][28] = 466; + JPFreq[20][93] = 465; + JPFreq[18][15] = 464; + JPFreq[4][23] = 463; + JPFreq[3][23] = 462; + JPFreq[26][64] = 461; + JPFreq[44][92] = 460; + JPFreq[17][27] = 459; + JPFreq[3][56] = 458; + JPFreq[25][38] = 457; + JPFreq[23][31] = 456; + JPFreq[35][43] = 455; + JPFreq[4][54] = 454; + JPFreq[35][19] = 453; + JPFreq[22][47] = 452; + JPFreq[42][0] = 451; + JPFreq[23][28] = 450; + JPFreq[46][33] = 449; + JPFreq[36][85] = 448; + JPFreq[31][12] = 447; + JPFreq[3][76] = 446; + JPFreq[4][75] = 445; + JPFreq[36][56] = 444; + JPFreq[4][64] = 443; + JPFreq[25][77] = 442; + JPFreq[15][52] = 441; + JPFreq[33][73] = 440; + JPFreq[3][55] = 439; + JPFreq[43][82] = 438; + JPFreq[27][82] = 437; + JPFreq[20][3] = 436; + JPFreq[40][51] = 435; + JPFreq[3][17] = 434; + JPFreq[27][71] = 433; + JPFreq[4][52] = 432; + JPFreq[44][48] = 431; + JPFreq[27][2] = 430; + JPFreq[17][39] = 429; + JPFreq[31][8] = 428; + JPFreq[44][54] = 427; + JPFreq[43][18] = 426; + JPFreq[43][77] = 425; + JPFreq[4][61] = 424; + JPFreq[19][91] = 423; + JPFreq[31][13] = 422; + JPFreq[44][71] = 421; + JPFreq[20][0] = 420; + JPFreq[23][87] = 419; + JPFreq[21][14] = 418; + JPFreq[29][13] = 417; + JPFreq[3][58] = 416; + JPFreq[26][18] = 415; + JPFreq[4][47] = 414; + JPFreq[4][18] = 413; + JPFreq[3][53] = 412; + JPFreq[26][92] = 411; + JPFreq[21][7] = 410; + JPFreq[4][37] = 409; + JPFreq[4][63] = 408; + JPFreq[36][51] = 407; + JPFreq[4][32] = 406; + JPFreq[28][73] = 405; + JPFreq[4][50] = 404; + JPFreq[41][60] = 403; + JPFreq[23][1] = 402; + JPFreq[36][92] = 401; + JPFreq[15][41] = 400; + JPFreq[21][71] = 399; + JPFreq[41][30] = 398; + JPFreq[32][76] = 397; + JPFreq[17][34] = 396; + JPFreq[26][15] = 395; + JPFreq[26][25] = 394; + JPFreq[31][77] = 393; + JPFreq[31][3] = 392; + JPFreq[46][34] = 391; + JPFreq[27][84] = 390; + JPFreq[23][8] = 389; + JPFreq[16][0] = 388; + JPFreq[28][80] = 387; + JPFreq[26][54] = 386; + JPFreq[33][18] = 385; + JPFreq[31][20] = 384; + JPFreq[31][62] = 383; + JPFreq[30][41] = 382; + JPFreq[33][30] = 381; + JPFreq[45][45] = 380; + JPFreq[37][82] = 379; + JPFreq[15][33] = 378; + JPFreq[20][12] = 377; + JPFreq[18][5] = 376; + JPFreq[28][86] = 375; + JPFreq[30][19] = 374; + JPFreq[42][43] = 373; + JPFreq[36][31] = 372; + JPFreq[17][93] = 371; + JPFreq[4][15] = 370; + JPFreq[21][20] = 369; + JPFreq[23][21] = 368; + JPFreq[28][72] = 367; + JPFreq[4][20] = 366; + JPFreq[26][55] = 365; + JPFreq[21][5] = 364; + JPFreq[19][16] = 363; + JPFreq[23][64] = 362; + JPFreq[40][59] = 361; + JPFreq[37][26] = 360; + JPFreq[26][56] = 359; + JPFreq[4][12] = 358; + JPFreq[33][71] = 357; + JPFreq[32][39] = 356; + JPFreq[38][40] = 355; + JPFreq[22][74] = 354; + JPFreq[3][25] = 353; + JPFreq[15][48] = 352; + JPFreq[41][82] = 351; + JPFreq[41][9] = 350; + JPFreq[25][48] = 349; + JPFreq[31][71] = 348; + JPFreq[43][29] = 347; + JPFreq[26][80] = 346; + JPFreq[4][5] = 345; + JPFreq[18][71] = 344; + JPFreq[29][0] = 343; + JPFreq[43][43] = 342; + JPFreq[23][81] = 341; + JPFreq[4][42] = 340; + JPFreq[44][28] = 339; + JPFreq[23][93] = 338; + JPFreq[17][81] = 337; + JPFreq[25][25] = 336; + JPFreq[41][23] = 335; + JPFreq[34][35] = 334; + JPFreq[4][53] = 333; + JPFreq[28][36] = 332; + JPFreq[4][41] = 331; + JPFreq[25][60] = 330; + JPFreq[23][20] = 329; + JPFreq[3][43] = 328; + JPFreq[24][79] = 327; + JPFreq[29][41] = 326; + JPFreq[30][83] = 325; + JPFreq[3][50] = 324; + JPFreq[22][18] = 323; + JPFreq[18][3] = 322; + JPFreq[39][30] = 321; + JPFreq[4][28] = 320; + JPFreq[21][64] = 319; + JPFreq[4][68] = 318; + JPFreq[17][71] = 317; + JPFreq[27][0] = 316; + JPFreq[39][28] = 315; + JPFreq[30][13] = 314; + JPFreq[36][70] = 313; + JPFreq[20][82] = 312; + JPFreq[33][38] = 311; + JPFreq[44][87] = 310; + JPFreq[34][45] = 309; + JPFreq[4][26] = 308; + JPFreq[24][44] = 307; + JPFreq[38][67] = 306; + JPFreq[38][6] = 305; + JPFreq[30][68] = 304; + JPFreq[15][89] = 303; + JPFreq[24][93] = 302; + JPFreq[40][41] = 301; + JPFreq[38][3] = 300; + JPFreq[28][23] = 299; + JPFreq[26][17] = 298; + JPFreq[4][38] = 297; + JPFreq[22][78] = 296; + JPFreq[15][37] = 295; + JPFreq[25][85] = 294; + JPFreq[4][9] = 293; + JPFreq[4][7] = 292; + JPFreq[27][53] = 291; + JPFreq[39][29] = 290; + JPFreq[41][43] = 289; + JPFreq[25][62] = 288; + JPFreq[4][48] = 287; + JPFreq[28][28] = 286; + JPFreq[21][40] = 285; + JPFreq[36][73] = 284; + JPFreq[26][39] = 283; + JPFreq[22][54] = 282; + JPFreq[33][5] = 281; + JPFreq[19][21] = 280; + JPFreq[46][31] = 279; + JPFreq[20][64] = 278; + JPFreq[26][63] = 277; + JPFreq[22][23] = 276; + JPFreq[25][81] = 275; + JPFreq[4][62] = 274; + JPFreq[37][31] = 273; + JPFreq[40][52] = 272; + JPFreq[29][79] = 271; + JPFreq[41][48] = 270; + JPFreq[31][57] = 269; + JPFreq[32][92] = 268; + JPFreq[36][36] = 267; + JPFreq[27][7] = 266; + JPFreq[35][29] = 265; + JPFreq[37][34] = 264; + JPFreq[34][42] = 263; + JPFreq[27][15] = 262; + JPFreq[33][27] = 261; + JPFreq[31][38] = 260; + JPFreq[19][79] = 259; + JPFreq[4][31] = 258; + JPFreq[4][66] = 257; + JPFreq[17][32] = 256; + JPFreq[26][67] = 255; + JPFreq[16][30] = 254; + JPFreq[26][46] = 253; + JPFreq[24][26] = 252; + JPFreq[35][10] = 251; + JPFreq[18][37] = 250; + JPFreq[3][19] = 249; + JPFreq[33][69] = 248; + JPFreq[31][9] = 247; + JPFreq[45][29] = 246; + JPFreq[3][15] = 245; + JPFreq[18][54] = 244; + JPFreq[3][44] = 243; + JPFreq[31][29] = 242; + JPFreq[18][45] = 241; + JPFreq[38][28] = 240; + JPFreq[24][12] = 239; + JPFreq[35][82] = 238; + JPFreq[17][43] = 237; + JPFreq[28][9] = 236; + JPFreq[23][25] = 235; + JPFreq[44][37] = 234; + JPFreq[23][75] = 233; + JPFreq[23][92] = 232; + JPFreq[0][24] = 231; + JPFreq[19][74] = 230; + JPFreq[45][32] = 229; + JPFreq[16][72] = 228; + JPFreq[16][93] = 227; + JPFreq[45][13] = 226; + JPFreq[24][8] = 225; + JPFreq[25][47] = 224; + JPFreq[28][26] = 223; + JPFreq[43][81] = 222; + JPFreq[32][71] = 221; + JPFreq[18][41] = 220; + JPFreq[26][62] = 219; + JPFreq[41][24] = 218; + JPFreq[40][11] = 217; + JPFreq[43][57] = 216; + JPFreq[34][53] = 215; + JPFreq[20][32] = 214; + JPFreq[34][43] = 213; + JPFreq[41][91] = 212; + JPFreq[29][57] = 211; + JPFreq[15][43] = 210; + JPFreq[22][89] = 209; + JPFreq[33][83] = 208; + JPFreq[43][20] = 207; + JPFreq[25][58] = 206; + JPFreq[30][30] = 205; + JPFreq[4][56] = 204; + JPFreq[17][64] = 203; + JPFreq[23][0] = 202; + JPFreq[44][12] = 201; + JPFreq[25][37] = 200; + JPFreq[35][13] = 199; + JPFreq[20][30] = 198; + JPFreq[21][84] = 197; + JPFreq[29][14] = 196; + JPFreq[30][5] = 195; + JPFreq[37][2] = 194; + JPFreq[4][78] = 193; + JPFreq[29][78] = 192; + JPFreq[29][84] = 191; + JPFreq[32][86] = 190; + JPFreq[20][68] = 189; + JPFreq[30][39] = 188; + JPFreq[15][69] = 187; + JPFreq[4][60] = 186; + JPFreq[20][61] = 185; + JPFreq[41][67] = 184; + JPFreq[16][35] = 183; + JPFreq[36][57] = 182; + JPFreq[39][80] = 181; + JPFreq[4][59] = 180; + JPFreq[4][44] = 179; + JPFreq[40][54] = 178; + JPFreq[30][8] = 177; + JPFreq[44][30] = 176; + JPFreq[31][93] = 175; + JPFreq[31][47] = 174; + JPFreq[16][70] = 173; + JPFreq[21][0] = 172; + JPFreq[17][35] = 171; + JPFreq[21][67] = 170; + JPFreq[44][18] = 169; + JPFreq[36][29] = 168; + JPFreq[18][67] = 167; + JPFreq[24][28] = 166; + JPFreq[36][24] = 165; + JPFreq[23][5] = 164; + JPFreq[31][65] = 163; + JPFreq[26][59] = 162; + JPFreq[28][2] = 161; + JPFreq[39][69] = 160; + JPFreq[42][40] = 159; + JPFreq[37][80] = 158; + JPFreq[15][66] = 157; + JPFreq[34][38] = 156; + JPFreq[28][48] = 155; + JPFreq[37][77] = 154; + JPFreq[29][34] = 153; + JPFreq[33][12] = 152; + JPFreq[4][65] = 151; + JPFreq[30][31] = 150; + JPFreq[27][92] = 149; + JPFreq[4][2] = 148; + JPFreq[4][51] = 147; + JPFreq[23][77] = 146; + JPFreq[4][35] = 145; + JPFreq[3][13] = 144; + JPFreq[26][26] = 143; + JPFreq[44][4] = 142; + JPFreq[39][53] = 141; + JPFreq[20][11] = 140; + JPFreq[40][33] = 139; + JPFreq[45][7] = 138; + JPFreq[4][70] = 137; + JPFreq[3][49] = 136; + JPFreq[20][59] = 135; + JPFreq[21][12] = 134; + JPFreq[33][53] = 133; + JPFreq[20][14] = 132; + JPFreq[37][18] = 131; + JPFreq[18][17] = 130; + JPFreq[36][23] = 129; + JPFreq[18][57] = 128; + JPFreq[26][74] = 127; + JPFreq[35][2] = 126; + JPFreq[38][58] = 125; + JPFreq[34][68] = 124; + JPFreq[29][81] = 123; + JPFreq[20][69] = 122; + JPFreq[39][86] = 121; + JPFreq[4][16] = 120; + JPFreq[16][49] = 119; + JPFreq[15][72] = 118; + JPFreq[26][35] = 117; + JPFreq[32][14] = 116; + JPFreq[40][90] = 115; + JPFreq[33][79] = 114; + JPFreq[35][4] = 113; + JPFreq[23][33] = 112; + JPFreq[19][19] = 111; + JPFreq[31][41] = 110; + JPFreq[44][1] = 109; + JPFreq[22][56] = 108; + JPFreq[31][27] = 107; + JPFreq[32][18] = 106; + JPFreq[27][32] = 105; + JPFreq[37][39] = 104; + JPFreq[42][11] = 103; + JPFreq[29][71] = 102; + JPFreq[32][58] = 101; + JPFreq[46][10] = 100; + JPFreq[17][30] = 99; + JPFreq[38][15] = 98; + JPFreq[29][60] = 97; + JPFreq[4][11] = 96; + JPFreq[38][31] = 95; + JPFreq[40][79] = 94; + JPFreq[28][49] = 93; + JPFreq[28][84] = 92; + JPFreq[26][77] = 91; + JPFreq[22][32] = 90; + JPFreq[33][17] = 89; + JPFreq[23][18] = 88; + JPFreq[32][64] = 87; + JPFreq[4][6] = 86; + JPFreq[33][51] = 85; + JPFreq[44][77] = 84; + JPFreq[29][5] = 83; + JPFreq[46][25] = 82; + JPFreq[19][58] = 81; + JPFreq[4][46] = 80; + JPFreq[15][71] = 79; + JPFreq[18][58] = 78; + JPFreq[26][45] = 77; + JPFreq[45][66] = 76; + JPFreq[34][10] = 75; + JPFreq[19][37] = 74; + JPFreq[33][65] = 73; + JPFreq[44][52] = 72; + JPFreq[16][38] = 71; + JPFreq[36][46] = 70; + JPFreq[20][26] = 69; + JPFreq[30][37] = 68; + JPFreq[4][58] = 67; + JPFreq[43][2] = 66; + JPFreq[30][18] = 65; + JPFreq[19][35] = 64; + JPFreq[15][68] = 63; + JPFreq[3][36] = 62; + JPFreq[35][40] = 61; + JPFreq[36][32] = 60; + JPFreq[37][14] = 59; + JPFreq[17][11] = 58; + JPFreq[19][78] = 57; + JPFreq[37][11] = 56; + JPFreq[28][63] = 55; + JPFreq[29][61] = 54; + JPFreq[33][3] = 53; + JPFreq[41][52] = 52; + JPFreq[33][63] = 51; + JPFreq[22][41] = 50; + JPFreq[4][19] = 49; + JPFreq[32][41] = 48; + JPFreq[24][4] = 47; + JPFreq[31][28] = 46; + JPFreq[43][30] = 45; + JPFreq[17][3] = 44; + JPFreq[43][70] = 43; + JPFreq[34][19] = 42; + JPFreq[20][77] = 41; + JPFreq[18][83] = 40; + JPFreq[17][15] = 39; + JPFreq[23][61] = 38; + JPFreq[40][27] = 37; + JPFreq[16][48] = 36; + JPFreq[39][78] = 35; + JPFreq[41][53] = 34; + JPFreq[40][91] = 33; + JPFreq[40][72] = 32; + JPFreq[18][52] = 31; + JPFreq[35][66] = 30; + JPFreq[39][93] = 29; + JPFreq[19][48] = 28; + JPFreq[26][36] = 27; + JPFreq[27][25] = 26; + JPFreq[42][71] = 25; + JPFreq[42][85] = 24; + JPFreq[26][48] = 23; + JPFreq[28][15] = 22; + JPFreq[3][66] = 21; + JPFreq[25][24] = 20; + JPFreq[27][43] = 19; + JPFreq[27][78] = 18; + JPFreq[45][43] = 17; + JPFreq[27][72] = 16; + JPFreq[40][29] = 15; + JPFreq[41][0] = 14; + JPFreq[19][57] = 13; + JPFreq[15][59] = 12; + JPFreq[29][29] = 11; + JPFreq[4][25] = 10; + JPFreq[21][42] = 9; + JPFreq[23][35] = 8; + JPFreq[33][1] = 7; + JPFreq[4][57] = 6; + JPFreq[17][60] = 5; + JPFreq[25][19] = 4; + JPFreq[22][65] = 3; + JPFreq[42][29] = 2; + JPFreq[27][66] = 1; + JPFreq[26][89] = 0; + } +} + +class Encoding { + // Supported Encoding Types + public static int GB2312 = 0; + + public static int GBK = 1; + + public static int GB18030 = 2; + + public static int HZ = 3; + + public static int BIG5 = 4; + + public static int CNS11643 = 5; + + public static int UTF8 = 6; + + public static int UTF8T = 7; + + public static int UTF8S = 8; + + public static int UNICODE = 9; + + public static int UNICODET = 10; + + public static int UNICODES = 11; + + public static int ISO2022CN = 12; + + public static int ISO2022CN_CNS = 13; + + public static int ISO2022CN_GB = 14; + + public static int EUC_KR = 15; + + public static int CP949 = 16; + + public static int ISO2022KR = 17; + + public static int JOHAB = 18; + + public static int SJIS = 19; + + public static int EUC_JP = 20; + + public static int ISO2022JP = 21; + + public static int ASCII = 22; + + public static int OTHER = 23; + + public static int TOTALTYPES = 24; + + public final static int SIMP = 0; + + public final static int TRAD = 1; + + // Names of the encodings as understood by Java + public static String[] javaname; + + // Names of the encodings for human viewing + public static String[] nicename; + + // Names of charsets as used in charset parameter of HTML Meta tag + public static String[] htmlname; + + // Constructor + public Encoding() { + javaname = new String[TOTALTYPES]; + nicename = new String[TOTALTYPES]; + htmlname = new String[TOTALTYPES]; + // Assign encoding names + javaname[GB2312] = "GB2312"; + javaname[GBK] = "GBK"; + javaname[GB18030] = "GB18030"; + javaname[HZ] = "ASCII"; // What to put here? Sun doesn't support HZ + javaname[ISO2022CN_GB] = "ISO2022CN_GB"; + javaname[BIG5] = "BIG5"; + javaname[CNS11643] = "EUC-TW"; + javaname[ISO2022CN_CNS] = "ISO2022CN_CNS"; + javaname[ISO2022CN] = "ISO2022CN"; + javaname[UTF8] = "UTF-8"; + javaname[UTF8T] = "UTF-8"; + javaname[UTF8S] = "UTF-8"; + javaname[UNICODE] = "Unicode"; + javaname[UNICODET] = "Unicode"; + javaname[UNICODES] = "Unicode"; + javaname[EUC_KR] = "EUC_KR"; + javaname[CP949] = "MS949"; + javaname[ISO2022KR] = "ISO2022KR"; + javaname[JOHAB] = "Johab"; + javaname[SJIS] = "SJIS"; + javaname[EUC_JP] = "EUC_JP"; + javaname[ISO2022JP] = "ISO2022JP"; + javaname[ASCII] = "ASCII"; + javaname[OTHER] = "ISO8859_1"; + // Assign encoding names + htmlname[GB2312] = "GB2312"; + htmlname[GBK] = "GBK"; + htmlname[GB18030] = "GB18030"; + htmlname[HZ] = "HZ-GB-2312"; + htmlname[ISO2022CN_GB] = "ISO-2022-CN-EXT"; + htmlname[BIG5] = "BIG5"; + htmlname[CNS11643] = "EUC-TW"; + htmlname[ISO2022CN_CNS] = "ISO-2022-CN-EXT"; + htmlname[ISO2022CN] = "ISO-2022-CN"; + htmlname[UTF8] = "UTF-8"; + htmlname[UTF8T] = "UTF-8"; + htmlname[UTF8S] = "UTF-8"; + htmlname[UNICODE] = "UTF-16"; + htmlname[UNICODET] = "UTF-16"; + htmlname[UNICODES] = "UTF-16"; + htmlname[EUC_KR] = "EUC-KR"; + htmlname[CP949] = "x-windows-949"; + htmlname[ISO2022KR] = "ISO-2022-KR"; + htmlname[JOHAB] = "x-Johab"; + htmlname[SJIS] = "Shift_JIS"; + htmlname[EUC_JP] = "EUC-JP"; + htmlname[ISO2022JP] = "ISO-2022-JP"; + htmlname[ASCII] = "ASCII"; + htmlname[OTHER] = "ISO8859-1"; + // Assign Human readable names + nicename[GB2312] = "GB-2312"; + nicename[GBK] = "GBK"; + nicename[GB18030] = "GB18030"; + nicename[HZ] = "HZ"; + nicename[ISO2022CN_GB] = "ISO2022CN-GB"; + nicename[BIG5] = "Big5"; + nicename[CNS11643] = "CNS11643"; + nicename[ISO2022CN_CNS] = "ISO2022CN-CNS"; + nicename[ISO2022CN] = "ISO2022 CN"; + nicename[UTF8] = "UTF-8"; + nicename[UTF8T] = "UTF-8 (Trad)"; + nicename[UTF8S] = "UTF-8 (Simp)"; + nicename[UNICODE] = "Unicode"; + nicename[UNICODET] = "Unicode (Trad)"; + nicename[UNICODES] = "Unicode (Simp)"; + nicename[EUC_KR] = "EUC-KR"; + nicename[CP949] = "CP949"; + nicename[ISO2022KR] = "ISO 2022 KR"; + nicename[JOHAB] = "Johab"; + nicename[SJIS] = "Shift-JIS"; + nicename[EUC_JP] = "EUC-JP"; + nicename[ISO2022JP] = "ISO 2022 JP"; + nicename[ASCII] = "ASCII"; + nicename[OTHER] = "OTHER"; + } + +} diff --git a/src/main/java/com/svnlan/home/utils/FileContentTool.java b/src/main/java/com/svnlan/home/utils/FileContentTool.java new file mode 100644 index 0000000..ebbb878 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/FileContentTool.java @@ -0,0 +1,38 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.domain.CommonSource; +import org.springframework.stereotype.Component; +import org.springframework.web.util.HtmlUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/19 13:23 + */ +@Component +public class FileContentTool { + + /** .txt .js .json .css .sql .xml .java .cs(c#), 返回text */ + public void getFileContent(CommonSource cloudFile, Map reMap){ + + // ts,js,json,java,css,html,txt,less,scss,ejs,go,jsx,json5,ls,mysql,nginx,php,py,rb,rst,tsx,xml + if (Arrays.asList("txt","md","json","css","java","cs","xml","sql","js","ts","less","scss","ejs","go","jsx","json5","ls","mysql" + ,"nginx","php","py","rb","rst","tsx","srt","ass","smm").contains(cloudFile.getFileType().toLowerCase())){ + //reMap.put("text", FileUtil.getFileContent(cloudFile.getPath(), StandardCharsets.UTF_8)); + //reMap.put("text", HtmlUtils.htmlEscape(FileUtil.textData(cloudFile.getPath()))); + reMap.put("text", (FileUtil.textData(cloudFile.getPath()))); + }else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(cloudFile.getFileType().toLowerCase())){ + //reMap.put("text", FileUtil.getImageContent(cloudFile.getPath())); + reMap.put("imgData", ""); //FileUtil.getImgStr(cloudFile.getPath()) + }else if (Arrays.asList("doc","docx").contains(cloudFile.getFileType().toLowerCase())){ + // reMap.put("text", FileUtil.getDocxContent(cloudFile.getPath())); + }else if (Arrays.asList("html","htm").contains(cloudFile.getFileType().toLowerCase())){ + reMap.put("text", FileUtil.parseDocumentFromFile(cloudFile.getPath())); + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/FileOptionTool.java b/src/main/java/com/svnlan/home/utils/FileOptionTool.java new file mode 100644 index 0000000..0415be0 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/FileOptionTool.java @@ -0,0 +1,1935 @@ +package com.svnlan.home.utils; + +import com.google.common.base.Joiner; +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.DocumentTypeEnum; +import com.svnlan.enums.EventEnum; +import com.svnlan.enums.LogTypeEnum; +import com.svnlan.enums.MetaEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.*; +import com.svnlan.home.domain.*; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.SourceOpDto; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.home.vo.*; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.tools.SystemLogTool; +import com.svnlan.tools.SystemSortTool; +import com.svnlan.user.dao.GroupSourceDao; +import com.svnlan.user.dao.UserFavDao; +import com.svnlan.user.service.StorageService; +import com.svnlan.utils.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/16 15:14 + */ +@Slf4j +@Component +public class FileOptionTool { + + @Resource + IoSourceMetaDao ioSourceMetaDao; + @Resource + IoSourceDao ioSourceDao; + @Resource + IoFileDao ioFileDao; + @Resource + IoSourceRecycleDao ioSourceRecycleDao; + @Resource + SystemSortTool systemSortTool; + @Resource + SystemLogTool systemLogTool; + @Resource + HomeExplorerDao homeExplorerDao; + @Resource + UserFavDao userFavDao; + @Resource + ShareDao shareDao; + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + AsyncUtil asyncUtil; + @Resource + GroupSourceDao groupSourceDao; + @Resource + AsyncSourceFileOtherUtil asyncSourceFileOtherUtil; + @Resource + StorageService storageService; + @Resource + UserAuthTool userAuthTool; + @Resource + CopyFileSaveUtil copyFileSaveUtil; + + @Value("${ppt.des.key}") + private String pptDesKey; + @Value("${ppt.des.vi}") + private String pptDesIV; + @Value("${ppt.server.url}") + private String pptServerUrl; + @Value("${cdn.domain}") + private String cdnDomain; + + public IOSource addCommonSource(long opUserId, CommonSource commonSource, EventEnum eventEnum) { + return addCommonSource(opUserId, commonSource, eventEnum, null); + } + + // 写入资源的 + public IOSource addCommonSource(long opUserId, CommonSource commonSource, EventEnum eventEnum, + Long fileId) { + + IOFile ioFile = new IOFile(); + ioFile.setFileID(fileId); + ioFile.setHashSimple(""); + ioFile.setName(commonSource.getName()); + ioFile.setSize(commonSource.getSize()); + ioFile.setIoType(0L); + ioFile.setHashMd5(commonSource.getHashMd5()); + ioFile.setPath(commonSource.getPath()); + ioFile.setIsM3u8(ObjectUtils.isEmpty(commonSource.getIsM3u8()) ? 0 : commonSource.getIsM3u8()); + ioFile.setIsH264Preview(ObjectUtils.isEmpty(commonSource.getIsH264Preview()) ? 0 : commonSource.getIsH264Preview()); + ioFile.setIsH264Preview((!ObjectUtils.isEmpty(commonSource.getFileType()) && "mp3".equals(commonSource.getFileType())) ? 1 : ioFile.getIsH264Preview()); + ioFile.setIsPreview(ObjectUtils.isEmpty(commonSource.getIsPreview()) ? 0 : commonSource.getIsPreview()); + ioFile.setAppPreview(ObjectUtils.isEmpty(commonSource.getAppPreview()) ? 0 : commonSource.getAppPreview()); + ioFile.setFileName(commonSource.getPath().substring(commonSource.getPath().lastIndexOf("/") + 1, commonSource.getPath().length())); + ioFile.setThumbSize(ObjectUtils.isEmpty(commonSource.getThumbSize()) ? 0L : commonSource.getThumbSize()); + ioFile.setConvertSize(ObjectUtils.isEmpty(commonSource.getConvertSize()) ? 0L : commonSource.getConvertSize()); + try { + if (Objects.isNull(ioFile.getFileID())) { + ioFileDao.insert(ioFile); + } else { + // 更新 + ioFileDao.updateById(ioFile); + } + } catch (Exception e) { + LogUtil.error(e, " setUserDefaultSource addFile error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + + if (ObjectUtils.isEmpty(ioFile.getFileID()) || ioFile.getFileID() <= 0) { + return null; + } + + commonSource.setFileID(ioFile.getFileID()); + asyncSourceFileOtherUtil.asyncAddFileMeta(commonSource, ioFile); + + LogUtil.info("editIoSourceDetail---------------commonSource=" + JsonUtils.beanToJson(commonSource)); + IOSource source = null; + if (!ObjectUtils.isEmpty(commonSource.getIsEdit()) && "1".equals(commonSource.getIsEdit())) { + this.editIoSourceDetail(commonSource, opUserId); + } else { + source = this.addIoSourceDetail(commonSource, opUserId, ioFile.getFileID(), eventEnum); + } + return source; + } + + // fileSave 保存编辑文档时添加file信息替换老的file信息,老信息插入历史表 + public void editIoSourceDetail(CommonSource commonSource, Long opUserId) { + IOSource source = new IOSource(); + source.setModifyUser(opUserId); + source.setFileID(commonSource.getFileID()); + source.setSize(commonSource.getSize()); + source.setSourceID(commonSource.getSourceID()); + if (!ObjectUtils.isEmpty(commonSource.getThumbSize()) && commonSource.getThumbSize() > 0) { + source.setThumbSize(commonSource.getThumbSize()); + } + if (!ObjectUtils.isEmpty(commonSource.getConvertSize()) && commonSource.getConvertSize() > 0) { + source.setConvertSize(commonSource.getConvertSize()); + } + try { + ioSourceDao.updateSourceAddSizeInfo(source); + } catch (Exception e) { + LogUtil.error(e, " editIoSourceDetail addSource updateSourceAddSizeInfo error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + log.info("fileOptionTool edite source => {}", source); + // 添加文档操作event + this.addSourceEvent(source.getSourceID(), commonSource.getParentID(), opUserId, source.getName(), EventEnum.edit); + } + + public IOSource addIoSourceDetail(CommonSource commonSource, Long opUserId, Long fileID, EventEnum eventEnum) { + + IOSource source = new IOSource(); + source.setName(commonSource.getName()); + source.setParentLevel(commonSource.getParentLevel()); + source.setCreateUser(opUserId); + source.setModifyUser(opUserId); + source.setTargetID(opUserId); + source.setIsFolder(fileID <= 0 ? 1 : 0); + source.setTargetType(commonSource.getTargetType()); + source.setFileType(commonSource.getFileType()); + source.setType(ObjectUtils.isEmpty(commonSource.getFileType()) ? 0 : DocumentTypeEnum.getTypeByExt(commonSource.getFileType())); + source.setFileID(fileID); + source.setParentID(commonSource.getParentID()); + source.setSize(commonSource.getSize()); + source.setThumbSize(ObjectUtils.isEmpty(commonSource.getThumbSize()) ? 0L : commonSource.getThumbSize()); + source.setConvertSize(ObjectUtils.isEmpty(commonSource.getConvertSize()) ? 0L : commonSource.getConvertSize()); + + if (1 == source.getTargetType() && commonSource.getParentID() <= 0) { + LogUtil.error("addIoSourceDetail 不能添加根目录 source=" + JsonUtils.beanToJson(source)); + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + source.setStorageID(storageService.getDefaultStorageDeviceId()); + + source.setNamePinyin(ChinesUtil.getPingYin(source.getName())); + source.setNamePinyinSimple(ChinesUtil.getFirstSpell(source.getName())); + + try { + ioSourceDao.insert(source); + } catch (Exception e) { + LogUtil.error(e, " setUserDefaultSource addSource error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + + if (!ObjectUtils.isEmpty(source.getSourceID()) && source.getSourceID() > 0) { + commonSource.setSourceID(source.getSourceID()); + asyncSourceFileOtherUtil.asyncAddSourceMeta(commonSource); + + if (Arrays.asList(1, 2).contains(source.getTargetType())) { + // 添加文档操作event + log.info("fileOptionTool add source => {}", source); + this.addSourceEvent(source.getSourceID(), commonSource.getParentID(), opUserId, source.getName(), eventEnum); + } + } + return source; + } + + public IOSource updateCommonSource(long opUserId, CommonSource commonSource) { + + IOFile ioFile = new IOFile(); + ioFile.setHashSimple(""); + ioFile.setName(commonSource.getName()); + ioFile.setSize(commonSource.getSize()); + ioFile.setIoType(0L); + ioFile.setHashMd5(commonSource.getHashMd5()); + ioFile.setPath(commonSource.getPath()); + ioFile.setIsM3u8(0); + ioFile.setIsH264Preview(commonSource.getIsH264Preview()); + ioFile.setIsPreview(commonSource.getIsPreview()); + ioFile.setAppPreview(commonSource.getAppPreview()); + ioFile.setThumbSize(ObjectUtils.isEmpty(commonSource.getFileThumbSize()) ? 0L : commonSource.getFileThumbSize()); + ioFile.setConvertSize(ObjectUtils.isEmpty(commonSource.getFileConvertSize()) ? 0L : commonSource.getFileConvertSize()); + + try { + ioFileDao.insert(ioFile); + } catch (Exception e) { + LogUtil.error(e, " updateCommonSource setUserDefaultSource addFile error"); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + + if (ObjectUtils.isEmpty(ioFile.getFileID()) || ioFile.getFileID() <= 0) { + return null; + } + + commonSource.setFileID(ioFile.getFileID()); + + IOFileMeta fileMeta = new IOFileMeta(); + fileMeta.setFileID(ioFile.getFileID()); + fileMeta.setKey("fileInfoMore"); + FileMetaVo fileMetaVo = new FileMetaVo(); + fileMetaVo.setThumb(""); + fileMetaVo.setAppViewUrl(commonSource.getAppPreviewUrl()); + fileMetaVo.setH264Path(commonSource.getH264Path()); + fileMetaVo.setResolution(commonSource.getResolution()); + fileMetaVo.setViewUrl(commonSource.getPreviewUrl()); + fileMetaVo.setLength(commonSource.getSourceLength()); + fileMeta.setValue(!ObjectUtils.isEmpty(fileMetaVo) ? JsonUtils.beanToJson(fileMetaVo) : ""); + try { + ioFileDao.insertMeta(fileMeta); + } catch (Exception e) { + LogUtil.error(e, " updateCommonSource setUserDefaultSource insertMeta error"); + } + + IOSource source = new IOSource(); + source.setModifyUser(opUserId); + source.setFileID(ioFile.getFileID()); + source.setSize(commonSource.getSize()); + if (!ObjectUtils.isEmpty(commonSource.getFileThumbSize()) && commonSource.getFileThumbSize() > 0) { + source.setThumbSize(commonSource.getFileThumbSize()); + } + source.setSourceID(commonSource.getSourceID()); + try { + ioSourceDao.updateSourceAddSizeInfo(source); + } catch (Exception e) { + LogUtil.error(e, " updateCommonSource updateSourceAddSizeInfo addSource error source=" + JsonUtils.beanToJson(source)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + return source; + } + + public CommonSource getSourceInfo(Long sourceID) { + return ioSourceDao.getSourceInfo(sourceID); + } + + /** + * @Description: 文档操作event + * @params: [sourceID 文档id, sourceParent 文档父文件夹id, userID 操作者id, name, eventEnum 事件类型] + * @Return: void + * @Author: sulijuan + * @Date: 2023/2/16 15:20 + * @Modified: + */ + public void addSourceEvent(Long sourceID, Long sourceParent, Long userID, String name, EventEnum eventEnum) { + addSourceEvent(sourceID, sourceParent, userID, name, eventEnum, null); + } + + public void addSourceEvent(Long sourceID, Long sourceParent, Long userID, String name, EventEnum eventEnum, String oldName) { + IoSourceEvent event = new IoSourceEvent(sourceID, sourceParent, userID, eventEnum.getCode(), getSourceEventDesc(eventEnum, name, oldName)); + asyncSourceFileOtherUtil.asyncAddSourceEvent(event); + } + + public void addSourceEventList(List list) { + asyncSourceFileOtherUtil.asyncAddSourceEventList(list); + } + + public static String getSourceEventDesc(EventEnum eventEnum, String name, String oldName) { + Map reMap = new HashMap<>(1); + switch (eventEnum.getValue()) { + case "mkdir": + reMap.put("createType", "mkdir"); + reMap.put("name", name); + break; + case "mkfile": + reMap.put("createType", "mkfile"); + reMap.put("name", name); + break; + case "copy": + reMap.put("createType", "copy"); + reMap.put("name", name); + break; + case "upload": + reMap.put("createType", "upload"); + reMap.put("name", name); + break; + case "uploadNew": + reMap.put("createType", "uploadNew"); + reMap.put("name", name); + break; + case "rename": + reMap.put("from", oldName); + reMap.put("to", name); + break; + case "toRecycle": + reMap.put("content", "toRecycle"); + break; + case "addDesc": + reMap.put("content", name); + break; + case "rollBack": + reMap.put("name", name); + reMap.put("content", oldName); + break; + case "edit": + reMap.put("ua", name); + break; + case "remove": + reMap.put("content", name); + break; + case "restore": + case "shareLinkAdd": + case "shareLinkEdit": + case "shareLinkRemove": + case "shareToAdd": + case "shareEdit": + case "shareToRemove": + reMap.put("content", eventEnum.getValue()); + break; + default: + reMap.put("content", eventEnum.getValue()); + } + return JsonUtils.beanToJson(reMap); + } + + public CommonSource selectByChecksum(String checksum, Long fileSize) { + return ioFileDao.selectByChecksum(checksum, fileSize); + } + public CommonSource selectByChecksum(String checksum, Long fileSize, Long time) { + if (!ObjectUtils.isEmpty(time) && time > 0) { + return ioFileDao.selectByChecksumAndTime(checksum, fileSize, time); + } + return ioFileDao.selectByChecksum(checksum, fileSize); + } + + public CommonSource getFileAttachment(Long sourceID) { + return getFileAttachment(sourceID, 0L); + } + + public CommonSource getFileAttachment(Long sourceID, Long id) { + CommonSource commonSource = null; + if (!ObjectUtils.isEmpty(id) && id > 0) { + commonSource = ioFileDao.getHistoryFileAttachment(id); + } else { + commonSource = ioFileDao.getFileAttachment(sourceID); + } + + if (!ObjectUtils.isEmpty(commonSource) && !ObjectUtils.isEmpty(commonSource.getValue())) { + try { + + FileMetaVo fileMetaVo = JsonUtils.jsonToBean(commonSource.getValue(), FileMetaVo.class); + if (!ObjectUtils.isEmpty(fileMetaVo)) { + commonSource.setThumb(fileMetaVo.getThumb()); + commonSource.setAppPreviewUrl(fileMetaVo.getAppViewUrl()); + commonSource.setH264Path(fileMetaVo.getH264Path()); + commonSource.setResolution(fileMetaVo.getResolution()); + commonSource.setPreviewUrl(fileMetaVo.getViewUrl()); + commonSource.setSourceLength(fileMetaVo.getLength()); + commonSource.setYzEditData(fileMetaVo.getYzEditData()); + commonSource.setYzViewData(fileMetaVo.getYzViewData()); + commonSource.setFrame(ObjectUtils.isEmpty(fileMetaVo.getFrame()) ? fileMetaVo.getFrameRate() : fileMetaVo.getFrame()); + if (!ObjectUtils.isEmpty(commonSource.getFrame()) && commonSource.getFrame().indexOf(".") > 0){ + commonSource.setFrame(commonSource.getFrame().substring(0,commonSource.getFrame().indexOf("."))); + } + } + } catch (Exception e) { + LogUtil.error(e, "getFileAttachment fileMeta 解析错误"); + } + } + return commonSource; + } + + public String getM3u8Param(Long sourceId, String m3u8Key) { + return "?sourceID=" + sourceId + + "&sourceType=" + BusTypeEnum.CLOUD.getBusType() + "&key=" + m3u8Key; + } + + public String getDownloadParam(Long sourceId, String downloadKey, String code) { + return "?busId=" + sourceId + code + "&busType=" + BusTypeEnum.CLOUD.getBusType() + "&key=" + downloadKey; + } + + public String getPptPdfPreview2(String sourceSuffix, Integer isH264Preview, String downloadUrl) { + if (sourceSuffix.equals("ppt") || sourceSuffix.equals("pptx")) { + return null; + } + String pptPreviewUrl = downloadUrl; + pptPreviewUrl += "&getInfo=1"; + if (sourceSuffix.equals("doc") || sourceSuffix.equals("docx")) { + if (isH264Preview != null && isH264Preview == 1) { + pptPreviewUrl += "&forwtop=1"; + } else { + return null; + } + } + return pptPreviewUrl; + } + + // checkOperationPermission + public void getLock(Long sourceID) { + /*boolean getLock = stringRedisTemplate.opsForValue().setIfAbsent(GlobalConfig.CLOUD_OPERATION_LOCK_KEY + sourceID, "1"); + if (!getLock){ + throw new SvnlanRuntimeException(CodeMessageEnum.fileLockError.getCode()); + } + stringRedisTemplate.expire(GlobalConfig.CLOUD_OPERATION_LOCK_KEY + sourceID, 60000, TimeUnit.MILLISECONDS);*/ + } + + public void delLock(Long sourceID) { + // stringRedisTemplate.delete(GlobalConfig.CLOUD_OPERATION_LOCK_KEY + sourceID); + } + + + /** + * @Description: 移动文件 + * @params: [updateFileDTO, paramMap] + * @Return: boolean + * @Modified: + */ + public boolean moveFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (updateFileDTO.getSourceID() == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + if (CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + // 判断层级 0,1,2 0,1,2,5 + if (updateFileDTO.getSourceLevel().indexOf(updateFileDTO.getDataArr().get(0).getParentLevel() + updateFileDTO.getDataArr().get(0).getSourceID() + ",") >= 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.moveSubPathError.getCode()); + } + + // 相同目录剪切 + Long fromSourceId = updateFileDTO.getDataArr().get(0).getParentID(); + if (!ObjectUtils.isEmpty(fromSourceId) && fromSourceId.longValue() == updateFileDTO.getSourceID().longValue()){ + return true; + } + + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "8", cs.getTargetType()); + + updateFileDTO.setSourceLevel(cs.getParentLevel() + cs.getSourceID() + ","); + List sourceNameList = ioSourceDao.getSourceNameList(updateFileDTO.getSourceID()); + + Set parentIDList = new HashSet<>(); + List sourceIDList = new ArrayList<>(); + List sourceLevelList = new ArrayList<>(); + + // 校验用户、群组 容量 + /** 获取企业云盘 */ + + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), updateFileDTO.getSourceID()); + + String desktopSourceIDStr = ioSourceMetaDao.getSourceIDMetaByKey(loginUser.getUserID() + "", "myDesktop"); + long desktopSourceId = 0; + if (!ObjectUtils.isEmpty(desktopSourceIDStr)) { + desktopSourceId = Long.valueOf(desktopSourceIDStr); + } + + for (SourceOpDto dto : updateFileDTO.getDataArr()) { + if (ObjectUtils.isEmpty(dto.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (desktopSourceId == dto.getSourceID().longValue() ){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotSupport.getCode()); + } + sourceIDList.add(dto.getSourceID()); + parentIDList.add(dto.getParentID()); + if ("folder".equals(dto.getType())) { + sourceLevelList.add(dto.getParentLevel() + dto.getSourceID() + ","); + } + } + String oldParentLevel = updateFileDTO.getDataArr().get(0).getParentLevel(); + // Long oldParentId = updateFileDTO.getDataArr().get(0).getParentID(); + + List moveList = ioSourceDao.copySourceList(sourceIDList); + if (CollectionUtils.isEmpty(moveList)) { + throw new SvnlanRuntimeException(CodeMessageEnum.rptSelectTips.getCode()); + } + int fileTargetType = moveList.get(0).getTargetType(); + List moveListByLevel = null; + // 权限校验 + if (fileTargetType == 2){ + int a = 0; + for (IOSource source : moveList) { + userAuthTool.checkGroupDocAuth(loginUser, source.getSourceID(), source.getParentLevel(), "10", fileTargetType, a == 0); + a++; + } + if (!CollectionUtils.isEmpty(sourceLevelList)) { + moveListByLevel = ioSourceDao.copySourceListByLevel(sourceLevelList); + if (!CollectionUtils.isEmpty(moveListByLevel)){ + List otherSourceIds = moveListByLevel.stream().map(IOSource::getSourceID).collect(Collectors.toList()); + userAuthTool.checkGroupDocAuthOther(loginUser, otherSourceIds, "10", fileTargetType); + } + } + } + List parentList = ioSourceDao.copySourceList(new ArrayList<>(parentIDList)); + + long size = 0; + for (IOSource source : moveList) { + size = size + source.getSize(); + source.setParentLevel(updateFileDTO.getSourceLevel()); + source.setParentID(updateFileDTO.getSourceID()); + source.setTargetType(cs.getTargetType()); + if (source.getIsFolder().intValue() == 1) { + source.setName(this.checkRepeatName(source.getName(), source.getName(), sourceNameList, 1)); + } else { + source.setName(this.checkRepeatName(source.getName(), source.getName(), source.getFileType(), sourceNameList, 1)); + } + } + if (!CollectionUtils.isEmpty(sourceLevelList)) { + if (CollectionUtils.isEmpty(moveListByLevel)) { + moveListByLevel = ioSourceDao.copySourceListByLevel(sourceLevelList); + } + if (!CollectionUtils.isEmpty(moveListByLevel)) { + for (IOSource mSource : moveListByLevel) { + mSource.setTargetType(cs.getTargetType()); + mSource.setParentLevel(mSource.getParentLevel().replace(oldParentLevel, updateFileDTO.getSourceLevel())); + } + moveList.addAll(moveListByLevel); + } + } + for (IOSource mSource : moveList) { + if (mSource.getParentID() <= 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + } + this.checkMemory(disk, size); + try { + ioSourceDao.batchUpdateParentAndName(moveList); + } catch (Exception e) { + LogUtil.error(e, "复制出错"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + + // 更新容量 + this.updateMemoryMove(size, updateFileDTO.getDataArr().get(0).getParentLevel(), updateFileDTO.getSourceLevel()); + /* + {"sourceID":"165","sourceParent":"183","pathName":"8888.txt","pathDisplay":"","userID":"1","type":"move", + "desc":{"from":"140","fromName":"885885","fromPath":"","to":183,"toName":"88888888888","toPath":""},"sourceTarget":"165","ip":"101.69.252.186"} + + {"sourceID":"140","sourceParent":"5","pathName":"885885","pathDisplay":"","userID":"1","type":"moveOut", + "desc":{"sourceID":"165","name":"8888.txt"},"sourceTarget":"140","ip":"101.69.252.186"} + */ + + /** 操作日志 */ + Map sourceMap = parentList.stream().collect(Collectors.toMap(IOSource::getSourceID, Function.identity(), (v1, v2) -> v2)); + List> paramList = new ArrayList<>(); + List> outParamList = new ArrayList<>(); + + for (SourceOpDto dto : updateFileDTO.getDataArr()) { + if (!ObjectUtils.isEmpty(sourceMap) && sourceMap.containsKey(dto.getParentID())) { + Map reMap = new HashMap<>(5); + reMap.put("sourceID", dto.getSourceID()); + reMap.put("pathName", dto.getName()); + reMap.put("sourceParent", cs.getSourceID()); + reMap.put("sourceParentName", cs.getSourceName()); + reMap.put("type", "move"); + reMap.put("fromSourceID", dto.getParentID()); + reMap.put("fromName", sourceMap.get(dto.getParentID()).getName()); + paramList.add(reMap); + + Map reOutMap = new HashMap<>(5); + reOutMap.put("sourceID", dto.getParentID()); + reOutMap.put("sourceParent", sourceMap.get(dto.getParentID()).getParentID()); + reOutMap.put("pathName", sourceMap.get(dto.getParentID()).getName()); + reOutMap.put("type", "moveOut"); + reOutMap.put("fromSourceID", dto.getSourceID()); + reOutMap.put("fromName", dto.getName()); + outParamList.add(reOutMap); + + } + } + /** 操作日志 */ + systemLogTool.setSysLog(loginUser, LogTypeEnum.move.getCode(), paramList, systemLogTool.getRequest()); + systemLogTool.setSysLog(loginUser, LogTypeEnum.moveOut.getCode(), outParamList, systemLogTool.getRequest()); + return true; + } + + + /** + * @Description: 重命名文件 + * @params: [updateFileDTO, paramMap] + * @Return: boolean + * @Modified: + */ + public boolean renameFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + List eventList = new ArrayList<>(); + List sourceIDList = new ArrayList<>(); + + String desktopSourceIDStr = ioSourceMetaDao.getSourceIDMetaByKey(loginUser.getUserID() + "", "myDesktop"); + long desktopSourceId = 0; + if (!ObjectUtils.isEmpty(desktopSourceIDStr)) { + desktopSourceId = Long.valueOf(desktopSourceIDStr); + } + for (SourceOpDto data : updateFileDTO.getDataArr()) { + if (ObjectUtils.isEmpty(data.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (desktopSourceId == data.getSourceID().longValue()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotSupport.getCode()); + } + if (StringUtil.isEmpty(data.getName())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + /*if (data.getName().startsWith(".")) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + }*/ + if (data.getName().length() > 200) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + sourceIDList.add(data.getSourceID()); + eventList.add(new IoSourceEvent(data.getSourceID(), data.getParentID(), loginUser.getUserID(), EventEnum.rename.getCode(), getSourceEventDesc(EventEnum.rename, data.getName(), data.getOldName()))); + } + + List copyList = ioSourceDao.copySourceList(sourceIDList); + if (CollectionUtils.isEmpty(copyList) || copyList.size() != sourceIDList.size()) { + throw new SvnlanRuntimeException(CodeMessageEnum.rptSelectTips.getCode()); + } + // 校验权限 + for (IOSource ioSource : copyList){ + userAuthTool.checkGroupDocAuth(loginUser, ioSource.getSourceID(), ioSource.getParentLevel(), "8", ioSource.getTargetType()); + } + Map sourceNameMap = copyList.stream().collect(Collectors.toMap(IOSource::getSourceID, IOSource::getName, (v1, v2) -> v2)); + List list = updateFileDTO.getDataArr(); + List sourceNameList = ioSourceDao.getSourceNameList(copyList.get(0).getParentID()); + if (!CollectionUtils.isEmpty(sourceNameList)) { + sourceNameList = sourceNameList.stream().map(String::toLowerCase).collect(Collectors.toList()); + for (SourceOpDto data : list) { + if (sourceNameList.contains(data.getName().toLowerCase()) + && !data.getName().toLowerCase().equals(sourceNameMap.get(data.getSourceID()).toLowerCase())) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathExists.getCode()); + } + data.setNamePinyin(ChinesUtil.getPingYin(data.getName())); + data.setNamePinyinSimple(ChinesUtil.getFirstSpell(data.getName())); + } + } + + try { + ioSourceDao.batchFileRename(list, loginUser.getUserID()); + } catch (Exception e) { + LogUtil.error(e, " batchFileRename error operationsDTO=" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + // 拼音 + this.setSourcePinYinList(updateFileDTO.getDataArr(), true); + + /** 添加文档操作event */ + if (!CollectionUtils.isEmpty(eventList)) { + this.addSourceEventList(eventList); + } + /** 操作日志 */ + Map reMap = null; + Map sourceMap = copyList.stream().collect(Collectors.toMap(IOSource::getSourceID, Function.identity(), (v1, v2) -> v2)); + List> paramList = new ArrayList<>(); + for (SourceOpDto dto : updateFileDTO.getDataArr()) { + if (!ObjectUtils.isEmpty(sourceMap) && sourceMap.containsKey(dto.getSourceID())) { + reMap = new HashMap<>(5); + reMap.put("sourceID", dto.getSourceID()); + reMap.put("sourceParent", sourceMap.get(dto.getSourceID()).getParentID()); + reMap.put("pathName", dto.getName()); + reMap.put("type", "rename"); + reMap.put("fromName", sourceMap.get(dto.getSourceID()).getName()); + paramList.add(reMap); + } + } + + /** 操作日志 */ + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileRename.getCode(), paramList, systemLogTool.getRequest()); + return true; + } + + public void setSourcePinYinList(List list, boolean isDel) { + // 拼音 + try { + List sourceIDList = new ArrayList<>(); + + List paramList = new ArrayList<>(); + for (SourceOpDto dto : list) { + sourceIDList.add(dto.getSourceID()); + + paramList.add(new IOSourceMeta(dto.getSourceID(), MetaEnum.namePinyin.getValue(), ChinesUtil.getPingYin(dto.getName()))); + paramList.add(new IOSourceMeta(dto.getSourceID(), MetaEnum.namePinyinSimple.getValue(), ChinesUtil.getFirstSpell(dto.getName()))); + } + if (isDel) { + ioSourceMetaDao.delMetaBySourceIDList(sourceIDList, MetaEnum.delKeyList()); + } + + ioSourceMetaDao.batchInsert(paramList); + } catch (Exception e) { + LogUtil.error(e, " setSourcePinYin meta error list=" + JsonUtils.beanToJson(list)); + } + } + + /** + * 容量校验 + */ + public void checkMemory(HomeExplorerVO disk, long size) { + //未分段,或第一个分段时验证 + if (!ObjectUtils.isEmpty(size) && size > 0) { + if (!ObjectUtils.isEmpty(disk) && !ObjectUtils.isEmpty(size) && size > 0 && !ObjectUtils.isEmpty(disk.getTargetType())) { + // 文件大小校验 + if (!ObjectUtils.isEmpty(disk.getIgnoreFileSize()) && disk.getIgnoreFileSize().doubleValue() > 0) { + // 0 为不限制容量 + if (size >= (disk.getIgnoreFileSize() * 1024 * 1024 * 1024)) { + LogUtil.info("文件超过上传大小 ignoreFileSize=" + disk.getIgnoreFileSize()); + throw new SvnlanRuntimeException(CodeMessageEnum.ignoreFileSizeTips.getCode()); + } + } + // 个人空间 + if (disk.getTargetType().intValue() == 1) { + Long userSizeUse = disk.getUserSizeUse() + size; + // 0 为不限制容量 + if (disk.getUserSizeMax().doubleValue() > 0 && userSizeUse >= (disk.getUserSizeMax() * 1024 * 1024 * 1024)) { + throw new SvnlanRuntimeException(CodeMessageEnum.spaceIsFull.getCode()); + } + } else { + // 部门 + Long sizeUse = disk.getSizeUse() + size; + // 0 为不限制容量 + if (disk.getSizeMax().doubleValue() > 0 && sizeUse >= (disk.getSizeMax() * 1024 * 1024 * 1024)) { + throw new SvnlanRuntimeException(CodeMessageEnum.spaceIsFull.getCode()); + } + } + } + } + } + + public void updateMemory(CommonSource commonSource) { + asyncUtil.updateMemory(commonSource.getSize(), commonSource.getGroupID(), commonSource.getUserID(), commonSource.getTargetType(), commonSource.getParentLevel()); + } + + public void updateMemory(long size, long groupID, long userID, Integer targetType, String parentLevel) { + asyncUtil.updateMemory(size, groupID, userID, targetType, parentLevel); + } + + public void updateGroupMemoryCopyBySearch(Map paramMap, String parentLevel) { + asyncUtil.updateGroupMemoryCopyBySearch(paramMap, parentLevel); + } + public void updateGroupMemoryCopy(Map paramMap, Long groupID) { + asyncUtil.updateGroupMemoryCopy(paramMap, groupID); + } + + public void updateMemoryCopy(long size, long groupID, long userID, Integer targetType, List sources) { + if (size > 0 && !ObjectUtils.isEmpty(targetType)) { + Map paramMap = new HashMap<>(2); + paramMap.put("groupID", groupID); + paramMap.put("memory", size); + paramMap.put("userID", userID); + try { + if (targetType.intValue() == 1) { + homeExplorerDao.updateUserMemory(paramMap); + } else { + this.updateGroupMemoryCopy(paramMap, groupID); + } + } catch (Exception e) { + LogUtil.error(e, "更新 企业云盘 sources memory失败"); + } + // source updateSourceMemoryList + if (!CollectionUtils.isEmpty(sources)) { + try { + List sourceList = new ArrayList<>(); + Map sourceSizeMap = new HashMap<>(); + for (IOSource source : sources) { + List sourceIds = Arrays.asList(source.getParentLevel().split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(sourceIds)) { + for (Long id : sourceIds) { + long s = (!ObjectUtils.isEmpty(sourceSizeMap) && sourceSizeMap.containsKey(id)) ? sourceSizeMap.get(id) + source.getSize() : source.getSize(); + sourceSizeMap.put(id, s); + } + } + } + if(!ObjectUtils.isEmpty(sourceSizeMap)){ + IOSource vo = null; + for (Map.Entry entry : sourceSizeMap.entrySet()) { + if (!ObjectUtils.isEmpty(entry.getKey())){ + vo = new IOSource(entry.getKey(), entry.getValue()); + sourceList.add(vo); + } + } + } + if (!CollectionUtils.isEmpty(sourceList)) { + LogUtil.info("updateMemoryCopy batchUpdateSourceMemoryList sourceSizeMap=" + JsonUtils.beanToJson(sourceSizeMap)); + ioSourceDao.batchUpdateSourceMemoryList(sourceList); + } + } catch (Exception e) { + LogUtil.error(e, " updateMemory error "); + } + } + } + } + + public void updateMemoryMove(long size, String fromParentLevel, String toParentLevel) { + if (size > 0) { + // source updateSourceMemoryList + if (!ObjectUtils.isEmpty(fromParentLevel) && !ObjectUtils.isEmpty(toParentLevel)) { + try { + List fromSourceIds = Arrays.asList(fromParentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + List toSourceIds = Arrays.asList(toParentLevel.split(",")).stream().filter(n -> !ObjectUtils.isEmpty(n) && !"0".equals(n)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(toSourceIds)) { + ioSourceDao.updateSourceMemoryList(toSourceIds, size); + } + if (!CollectionUtils.isEmpty(fromSourceIds)) { + ioSourceDao.subtractSourceMemoryList(fromSourceIds, size); + } + } catch (Exception e) { + LogUtil.error(e, " updateMemoryMove error "); + } + } + } + } + + /** + * @Description: 复制文件 + * @params: [updateFileDTO, paramMap] + * @Return: boolean + * @Modified: + */ + public List copyFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (updateFileDTO.getSourceID() == null) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } + if (CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "8", cs.getTargetType()); + List sourceNameList = ioSourceDao.getSourceNameList(updateFileDTO.getSourceID()); + + updateFileDTO.setSourceLevel(cs.getParentLevel() + cs.getSourceID() + ","); + + List sourceIDList = new ArrayList<>(); + Map sourceName = new HashMap<>(); + List sourceLevelList = new ArrayList<>(); + for (SourceOpDto dto : updateFileDTO.getDataArr()) { + sourceIDList.add(dto.getSourceID()); + sourceName.put(dto.getSourceID(), dto.getName()); + if ("folder".equals(dto.getType())) { + sourceLevelList.add(dto.getParentLevel() + dto.getSourceID() + ","); + } + } + List copyList = ioSourceDao.copySourceList(sourceIDList); + if (CollectionUtils.isEmpty(copyList)) { + throw new SvnlanRuntimeException(CodeMessageEnum.rptSelectTips.getCode()); + } + List copyListByLevelCo = null; + int fileTargetType = copyList.get(0).getTargetType(); + // 复制权限校验 + if (fileTargetType == 2) { + int a = 0; + for (IOSource source : copyList) { + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, source.getSourceID(), source.getParentLevel(), "4,10", source.getTargetType() , a == 0); + a ++; + } + if (!CollectionUtils.isEmpty(sourceLevelList)) { + copyListByLevelCo = ioSourceDao.copySourceListByLevel(sourceLevelList); + List otherSourceIds = copyListByLevelCo.stream().map(IOSource::getSourceID).collect(Collectors.toList()); + userAuthTool.checkGroupDocAuthOther(loginUser, otherSourceIds, "4,10", fileTargetType); + } + + } + // 复制权限校验 + List eventList = new ArrayList<>(); + Long size = 0L; + for (IOSource source : copyList) { + source.setOldParentLevel(source.getParentLevel()); + source.setOldSourceLevel(source.getParentLevel() + source.getSourceID() + ","); + source.setOldSourceID(source.getSourceID()); + source.setOldParentID(source.getParentID()); + + + source.setParentLevel(updateFileDTO.getSourceLevel()); + source.setParentID(updateFileDTO.getSourceID()); + source.setTargetID(loginUser.getUserID()); + source.setCreateUser(loginUser.getUserID()); + source.setModifyUser(loginUser.getUserID()); + source.setTargetType(cs.getTargetType()); + if (!ObjectUtils.isEmpty(sourceName) && sourceName.containsKey(source.getSourceID())) { + source.setName(sourceName.get(source.getSourceID())); + if (1 == source.getIsFolder()) { + source.setName(this.checkRepeatName(source.getName(), source.getName(), sourceNameList, 1)); + } else { + source.setName(this.checkRepeatName(source.getName(), source.getName(), source.getFileType(), sourceNameList, 1)); + } + } + + source.setNamePinyin(ChinesUtil.getPingYin(source.getName())); + source.setNamePinyinSimple(ChinesUtil.getFirstSpell(source.getName())); + source.setSourceID(null); + size = size + source.getSize(); + } + + // 校验用户、群组 容量 + /** 获取企业云盘 */ + HomeExplorerVO disk = systemSortTool.getUserSpaceSize(loginUser.getUserID(), updateFileDTO.getSourceID()); + this.checkMemory(disk, size); + + try { + ioSourceDao.batchInsert(copyList); + } catch (Exception e) { + LogUtil.error(e, "复制出错"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + Map parentMap = copyList.stream().collect(Collectors.toMap(IOSource::getOldSourceLevel, Function.identity(), (v1, v2) -> v2)); + for (IOSource source : copyList) { + eventList.add(new IoSourceEvent(source.getSourceID(), source.getParentID(), loginUser.getUserID(), EventEnum.copy.getCode(), getSourceEventDesc(EventEnum.copy, source.getName(), ""))); + } + if (!CollectionUtils.isEmpty(sourceLevelList)) { + if (!CollectionUtils.isEmpty(copyListByLevelCo)){ + size = size + copyListByLevelCo.stream().map(IOSource::getSize).collect(Collectors.toList()).stream().reduce(Long::sum).get(); + } + int s = 0; + // 复制选择文件夹下的所有文件 + copyFileSaveUtil.saveParentLevelSource(updateFileDTO, parentMap, ioSourceDao, loginUser, cs.getTargetType(), copyListByLevelCo,s); + } + /** 添加文档操作event */ + if (!CollectionUtils.isEmpty(eventList)) { + this.addSourceEventList(eventList); + } + + // 更新容量 + updateMemoryCopy(size, disk.getGroupID(), loginUser.getUserID(), disk.getTargetType(), copyList); + + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + for (IOSource dto : copyList) { + reMap = new HashMap<>(5); + reMap.put("sourceID", dto.getSourceID()); + reMap.put("sourceParent", dto.getParentID()); + reMap.put("pathName", dto.getName()); + reMap.put("type", "copy"); + reMap.put("sourceParent", cs.getSourceID()); + reMap.put("sourceParentName", cs.getSourceName()); + paramList.add(reMap); + } + systemLogTool.setSysLog(loginUser, LogTypeEnum.copy.getCode(), paramList, systemLogTool.getRequest()); + return copyList; + } + + + /** + * 添加到收藏夹 + */ + public void favFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (!ObjectUtils.isEmpty(updateFileDTO.getSourceID()) && updateFileDTO.getSourceID() <= 0) { + updateFileDTO.setSourceID(null); + } + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID()) && ObjectUtils.isEmpty(updateFileDTO.getPath())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (ObjectUtils.isEmpty(updateFileDTO.getName())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + Long sourceID = !ObjectUtils.isEmpty(updateFileDTO.getPath()) ? Long.parseLong(updateFileDTO.getPath()) : updateFileDTO.getSourceID(); + CommonSource commonSource = this.getSourceInfo(sourceID); + List nameList = userFavDao.getFavNameList(loginUser.getUserID()); + UserFav userFav = new UserFav(); + userFav.setUserID(loginUser.getUserID()); + userFav.setTagID(0); + if (1 == commonSource.getIsFolder()) { + userFav.setName(this.checkRepeatName(updateFileDTO.getName(), updateFileDTO.getName(), nameList, 1)); + }else { + String suffix = FileUtil.getFileExtension(updateFileDTO.getName()); + userFav.setName(this.checkRepeatName(updateFileDTO.getName(), updateFileDTO.getName(), suffix, nameList, 1)); + } + if (!ObjectUtils.isEmpty(updateFileDTO.getSourceID()) && updateFileDTO.getSourceID() > 0) { + userFav.setPath(updateFileDTO.getSourceID().toString()); + userFav.setType("source"); + } else { + userFav.setPath(updateFileDTO.getPath()); + if (ObjectUtils.isEmpty(updateFileDTO.getType())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + userFav.setType(updateFileDTO.getType()); + } + Integer sort = userFavDao.getFavMaxSort(loginUser.getUserID()); + userFav.setSort(ObjectUtils.isEmpty(sort) ? 1 : sort + 1); + try { + userFavDao.insert(userFav); + } catch (Exception e) { + LogUtil.error(e, "收藏出错"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", updateFileDTO.getSourceID()); + reMap.put("path", userFav.getPath()); + reMap.put("pathName", updateFileDTO.getName()); + reMap.put("type", "favAdd"); + if (!ObjectUtils.isEmpty(updateFileDTO.getType())) { + reMap.put("sourceType", updateFileDTO.getType()); + } + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.favAdd.getCode(), paramList, systemLogTool.getRequest()); + } + + /** + * 取消收藏 + */ + public void delFavFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + List sourceIdList = new ArrayList<>(); + List favIdList = new ArrayList<>(); + for (SourceOpDto data : updateFileDTO.getDataArr()) { + if (!ObjectUtils.isEmpty(data.getId()) && data.getId() > 0) { + sourceIdList.add(data.getId()); + } + if (!ObjectUtils.isEmpty(data.getFavID()) && data.getFavID() > 0) { + favIdList.add(data.getFavID()); + } + } + try { + if (!CollectionUtils.isEmpty(sourceIdList)) { + userFavDao.removeUserFav(loginUser.getUserID(), sourceIdList); + } + if (!CollectionUtils.isEmpty(favIdList)) { + userFavDao.removeUserFavByIdList(loginUser.getUserID(), favIdList); + } + } catch (Exception e) { + LogUtil.error(e, "取消收藏出错"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + for (SourceOpDto data : updateFileDTO.getDataArr()) { + reMap = new HashMap<>(5); + reMap.put("name", data.getName()); + reMap.put("pathName", data.getName()); + paramList.add(reMap); + } + systemLogTool.setSysLog(loginUser, LogTypeEnum.favDel.getCode(), paramList, systemLogTool.getRequest()); + } + + /** + * 添加描述 + */ + public void saveDesc(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + String desc = ObjectUtils.isEmpty(updateFileDTO.getDesc()) ? "" : updateFileDTO.getDesc(); + + + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "8", cs.getTargetType()); + // 修改 + try { + ioSourceDao.updateSourceDesc(updateFileDTO.getSourceID(), desc); + } catch (Exception e) { + LogUtil.error(e, " saveDesc updateSourceDesc error updateFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + return; + } + + public void shareFile(CheckFileDTO updateFileDTO) { + + } + + /** + * @Description: 还原文件 + * @params: [updateFileDTO, paramMap, resultMap] + * @Return: void + * @Modified: + */ + public void recycleFile(CheckFileDTO updateFileDTO, LoginUser loginUser, boolean isAll) { + if (!isAll && CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + List dataArr = null; + if (isAll) { + dataArr = this.getUserRecycleBinList(loginUser); + } else { + dataArr = updateFileDTO.getDataArr(); + } + if (CollectionUtils.isEmpty(dataArr)) { + return; + } + List eventList = new ArrayList<>(); + + List sourceIdList = new ArrayList<>(); + List paList = new ArrayList<>(); + for (SourceOpDto data : dataArr) { + sourceIdList.add(data.getSourceID()); + if ("folder".equals(data.getType())) { + paList.add(data.getParentLevel() + data.getSourceID() + ","); + } + eventList.add(new IoSourceEvent(data.getSourceID(), data.getParentID(), loginUser.getUserID(), EventEnum.restore.getCode(), getSourceEventDesc(EventEnum.restore, data.getName(), null))); + } + List deleteList = ioSourceDao.copySourceList(sourceIdList); + try { + ioSourceDao.restoreDirOrFile(sourceIdList, loginUser.getUserID()); + } catch (Exception e) { + LogUtil.error(e, " restoreDirOrFile error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + // 还原文件夹下的文件夹及文件 + if (!CollectionUtils.isEmpty(paList)) { + try { + ioSourceDao.restoreSourceByParent(paList, loginUser.getUserID()); + } catch (Exception e) { + LogUtil.error(e, " restoreDirOrFile restoreSourceByParent error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + } + /** 还原文件 删除回收站文档表相关信息 targetType 文档所属类型 (0-sys,1-user,2-group) */ + try { + ioSourceRecycleDao.deleteUserRecycle(loginUser.getUserID(), 1, sourceIdList); + } catch (Exception e) { + LogUtil.error(e, " deleteDirOrFile restore error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + + /** 添加文档操作event */ + if (!CollectionUtils.isEmpty(eventList)) { + this.addSourceEventList(eventList); + } + /** 操作日志 */ + Map reMap = null; + Map sourceMap = deleteList.stream().collect(Collectors.toMap(IOSource::getSourceID, Function.identity(), (v1, v2) -> v2)); + List> paramList = new ArrayList<>(); + for (SourceOpDto dto : dataArr) { + if (!ObjectUtils.isEmpty(sourceMap) && sourceMap.containsKey(dto.getSourceID())) { + reMap = new HashMap<>(4); + reMap.put("sourceID", dto.getSourceID()); + reMap.put("sourceParent", sourceMap.get(dto.getSourceID()).getParentID()); + reMap.put("type", "restore"); + reMap.put("pathName", sourceMap.get(dto.getSourceID()).getName()); + paramList.add(reMap); + } + } + systemLogTool.setSysLog(loginUser, LogTypeEnum.restore.getCode(), paramList, systemLogTool.getRequest()); + + } + + private List getUserRecycleBinList(LoginUser loginUser) { + return ioSourceRecycleDao.getUserRecycleBinList(loginUser.getUserID()); + } + + /** + * @Description: 彻底删除 + * @params: [updateFileDTO] + * @Return: void + * @Author: sulijuan + * @Date: 2023/2/18 15:52 + * @Modified: + */ + public void deleteBin(CheckFileDTO updateFileDTO, LoginUser loginUser, boolean isAll) { + if (!isAll && CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + List dataArr = null; + if (isAll) { + dataArr = this.getUserRecycleBinList(loginUser); + } else { + dataArr = updateFileDTO.getDataArr(); + } + if (CollectionUtils.isEmpty(dataArr)) { + return; + } + + List eventList = new ArrayList<>(); + + List sourceIdList = new ArrayList<>(); + List paList = new ArrayList<>(); + for (SourceOpDto data : dataArr) { + sourceIdList.add(data.getSourceID()); + if ("folder".equals(data.getType())) { + paList.add(data.getParentLevel() + data.getSourceID() + ","); + } + eventList.add(new IoSourceEvent(data.getSourceID(), data.getParentID(), loginUser.getUserID(), EventEnum.remove.getCode() + , getSourceEventDesc(EventEnum.remove, data.getName(), null))); + } + + + List copyList = ioSourceDao.getSourceFileInfoList(sourceIdList); + if (CollectionUtils.isEmpty(copyList)) { + throw new SvnlanRuntimeException(CodeMessageEnum.rptSelectTips.getCode()); + } + + Map filePathMap = copyList.stream().filter(n -> !ObjectUtils.isEmpty(n.getPath())).collect(Collectors.toMap(CommonSource::getFileID, CommonSource::getPath, (v1, v2) -> v2)); + + List deleteFileIDList = ioSourceDao.getFileIDBySourceID(sourceIdList); + + List delFileIDs = null; + List deletePath = null; + // 排除fileID被引用被秒传 + if (!CollectionUtils.isEmpty(deleteFileIDList)) { + List fileCountList = ioSourceDao.getFileCountBySourceID(deleteFileIDList); + if (!CollectionUtils.isEmpty(fileCountList)) { + deletePath = new ArrayList<>(); + delFileIDs = new ArrayList<>(); + for (IOSourceVo vo : fileCountList) { + if (vo.getFileCount() == 1) { + delFileIDs.add(vo.getFileID()); + if (filePathMap.containsKey(vo.getFileID())) { + deletePath.add(filePathMap.get(vo.getFileID())); + } + } + } + } + } + + /** 彻底删除*/ + try { + ioSourceDao.removeUserSource(sourceIdList); + } catch (Exception e) { + LogUtil.error(e, " deleteBin removeUserSource error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + // 删除文件夹下的文件夹及文件 + if (!CollectionUtils.isEmpty(paList)) { + try { + ioSourceDao.removeUserSourceByParent(paList); + } catch (Exception e) { + LogUtil.error(e, " deleteBin removeUserSourceByParent error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + } + + + List dList = null; + if (!CollectionUtils.isEmpty(deletePath)) { + dList = ioSourceDao.getFileCountByPath(deletePath); + LogUtil.info(" deleteBin getFileCountByPath error dList=" + JsonUtils.beanToJson(dList)); + } + + // 删除file表信息 + if (!CollectionUtils.isEmpty(delFileIDs) && delFileIDs.size() > 0) { + try { + ioFileDao.removeUserFile(delFileIDs); + ioFileDao.removeUserFileMeta(delFileIDs); + ioFileDao.removeUserFileContents(delFileIDs); + } catch (Exception e) { + LogUtil.error(e, " deleteBin removeUserFile error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + } + + /** 删除回收站文档表相关信息 targetType 文档所属类型 (0-sys,1-user,2-group) */ + try { + ioSourceRecycleDao.deleteUserRecycle(loginUser.getUserID(), 1, sourceIdList); + } catch (Exception e) { + LogUtil.error(e, " deleteBin deleteUserRecycle error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + + // 更新容量 先排序后筛选出是否已经包含的文件 sourceIdList + asyncUtil.asyncDeleteFileUpdateMemory(loginUser, copyList, sourceIdList, dList); + + + /** 添加文档操作event */ + if (!CollectionUtils.isEmpty(eventList)) { + this.addSourceEventList(eventList); + } + /** 操作日志 */ + Map reMap = null; + Map sourceMap = copyList.stream().collect(Collectors.toMap(CommonSource::getSourceID, Function.identity(), (v1, v2) -> v2)); + List> paramList = new ArrayList<>(); + for (SourceOpDto dto : dataArr) { + if (!ObjectUtils.isEmpty(sourceMap) && sourceMap.containsKey(dto.getSourceID())) { + reMap = new HashMap<>(5); + reMap.put("sourceID", dto.getSourceID()); + reMap.put("sourceParent", sourceMap.get(dto.getSourceID()).getParentID()); + reMap.put("pathName", sourceMap.get(dto.getSourceID()).getName()); + reMap.put("type", "remove"); + paramList.add(reMap); + } + } + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileRemove.getCode(), paramList, systemLogTool.getRequest()); + } + + + /** + * @Description: 删除文件 + * @params: [updateFileDTO, paramMap] + * @Return: boolean + * @Modified: + */ + public Integer deleteFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (CollectionUtils.isEmpty(updateFileDTO.getDataArr())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + List eventList = new ArrayList<>(); + + List sourceIdList = new ArrayList<>(); + List paList = new ArrayList<>(); + + String desktopSourceIDStr = ioSourceMetaDao.getSourceIDMetaByKey(loginUser.getUserID() + "", "myDesktop"); + long desktopSourceId = 0; + if (!ObjectUtils.isEmpty(desktopSourceIDStr)) { + desktopSourceId = Long.valueOf(desktopSourceIDStr); + } + for (SourceOpDto data : updateFileDTO.getDataArr()) { + if (ObjectUtils.isEmpty(data.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + if (desktopSourceId == data.getSourceID().longValue()){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotSupport.getCode()); + } + sourceIdList.add(data.getSourceID()); + if ("folder".equals(data.getType())) { + paList.add(data.getParentLevel() + data.getSourceID() + ","); + } + eventList.add(new IoSourceEvent(data.getSourceID(), data.getParentID(), loginUser.getUserID(), EventEnum.recycle.getCode(), getSourceEventDesc(EventEnum.recycle, data.getName(), null))); + } + List deleteList = ioSourceDao.copySourceList(sourceIdList); + if (CollectionUtils.isEmpty(deleteList)) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + for (IOSource ioSource : deleteList){ + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, ioSource.getSourceID(), ioSource.getParentLevel(), "10", ioSource.getTargetType()); + } + // 判断是否是部门 + Long check = groupSourceDao.checkIsGroup(sourceIdList); + if (!ObjectUtils.isEmpty(check) && check > 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.groupDelError.getCode()); + } + + for (IOSource io : deleteList) { + if (io.getTargetType().intValue() == 1 && io.getParentID().longValue() == 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.groupDelError.getCode()); + } else if (io.getTargetType().intValue() == 2 && io.getParentID().longValue() == 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.groupDelError.getCode()); + } + } + int removedFileCount = 0; + try { + removedFileCount = ioSourceDao.deleteDirOrFile(sourceIdList); + } catch (Exception e) { + LogUtil.error(e, " deleteDirOrFile error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + // 删除文件夹下的文件夹及文件 + if (!CollectionUtils.isEmpty(paList)) { + try { + ioSourceDao.deleteSourceByParent(paList); + } catch (Exception e) { + LogUtil.error(e, " deleteDirOrFile deleteSourceByParent error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + } + /** 添加到回收站文档表*/ + + for (IOSource source : deleteList) { + source.setUserID(loginUser.getUserID()); + } + try { + ioSourceRecycleDao.batchInsert(deleteList); + } catch (Exception e) { + LogUtil.error(e, " deleteDirOrFile insert recycle error CheckFileDTO=" + JsonUtils.beanToJson(updateFileDTO)); + } + + /** 添加文档操作event */ + if (!CollectionUtils.isEmpty(eventList)) { + this.addSourceEventList(eventList); + } + /** 操作日志 */ + addOperateLog(deleteList, updateFileDTO, loginUser, LogTypeEnum.fileToRecycle); + + return removedFileCount; + } + + /** + * 添加操作日志 + * + * @param ioSourceList 需要写入日志的数据 + * @param updateFileDTO 更新的数据 + * @param loginUser 当前登录用户 + * @param logTypeEnum 日志类型 + */ + private void addOperateLog(List ioSourceList, CheckFileDTO updateFileDTO, LoginUser loginUser, LogTypeEnum logTypeEnum) { + + Map reMap = null; + Map sourceMap = ioSourceList.stream().collect(Collectors.toMap(IOSource::getSourceID, Function.identity())); + List> paramList = new ArrayList<>(); + for (SourceOpDto dto : updateFileDTO.getDataArr()) { + if (!ObjectUtils.isEmpty(sourceMap) && sourceMap.containsKey(dto.getSourceID())) { + reMap = new HashMap<>(4); + reMap.put("sourceID", dto.getSourceID()); + reMap.put("sourceParent", sourceMap.get(dto.getSourceID()).getParentID()); + reMap.put("type", "recycle"); + reMap.put("pathName", sourceMap.get(dto.getSourceID()).getName()); + paramList.add(reMap); + } + } + systemLogTool.setSysLog(loginUser, logTypeEnum.getCode(), paramList, systemLogTool.getRequest()); + } + + public HomeFileDetailVO getFileDetail(Long fileID) { + if (ObjectUtils.isEmpty(fileID) || fileID <= 0) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + return homeExplorerDao.getFileDetail(fileID); + } + + /** + * @Description: attachment 从key获取token + * @params: [key] + * @Return: java.lang.String + * @Modified: + */ + public String getAttachmentToken(String key) { + String[] tokenArr; + try { + String keyString = AESUtil.decrypt(key, GlobalConfig.ATTACHMENT_AES_KEY, true); + tokenArr = keyString.split(GlobalConfig.ATTACHMENT_KEY_SEPARATOR); + } catch (Exception e) { + LogUtil.error(e, "attachment,验证错误 AES解密失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.errorAdminAuth.getCode()); + } + String token = tokenArr[0]; + Long time = Long.parseLong(tokenArr[1]); + if (time + 86400000 < System.currentTimeMillis()) { + LogUtil.info("attachment链接已超时1天" + time + "," + System.currentTimeMillis()); + } + return token; + } + + public String getAttachmentToken2(String key) { + String[] tokenArr; + try { + String keyString = AESUtil.decrypt(key, GlobalConfig.ATTACHMENT_AES_KEY, true); + tokenArr = keyString.split(GlobalConfig.ATTACHMENT_KEY_SEPARATOR); + } catch (Exception e) { + LogUtil.error(e, "attachment,验证错误 AES解密失败"); + return ""; + } + String token = tokenArr[0]; + Long time = Long.parseLong(tokenArr[1]); + if (time + 86400000 < System.currentTimeMillis()) { + LogUtil.info("attachment链接已超时1天" + time + "," + System.currentTimeMillis()); + } + return token; + } + public String getAttachmentToken3(String key) { + String[] tokenArr; + try { + String keyString = AESUtil.decrypt(key, GlobalConfig.ATTACHMENT_AES_KEY, true); + tokenArr = keyString.split(GlobalConfig.ATTACHMENT_KEY_SEPARATOR); + } catch (Exception e) { + LogUtil.error(e, "getAttachmentToken3,验证错误 AES解密失败"); + return ""; + } + return tokenArr[0]; + } + + public String getPptPreviewUrl(String downloadUrl, String checksum) { + return this.getPptPreviewUrl(downloadUrl, checksum, Boolean.TRUE); + } + + public String getPptPreviewUrl(String downloadUrl, String checksum, Boolean isValidate) { + + try { + HttpServletRequest request = HttpUtil.getRequest(); + String fullUrl = ""; + String serverUrl = HttpUtil.getRequestRootUrl(null); + //若需要验证 + if (isValidate) { + fullUrl = serverUrl + downloadUrl; + fullUrl += "&targetServerNameForOverride=" + HttpUtil.getServerName(request); + } else {//不需要验证 公开的则采用cdn域名 + serverUrl = "https://" + this.cdnDomain; + fullUrl = serverUrl + downloadUrl; + } + String encryptUrl = StringUtil.isEmpty(pptDesKey) ? fullUrl : DESEncrypt.encode(fullUrl, pptDesKey, pptDesIV); + //先从redis取 + String pptServerString = pptServerUrl; + //转码服务器域名 + String[] servers = pptServerString.split(","); + //服务器个数 + int serverCount = servers.length; + + // checksum最后一位 % 服务器数量, 选中某一个服务器 + int idIndex = 0; + if (!ObjectUtils.isEmpty(checksum)) { + char c = checksum.charAt(31); + idIndex = (c % serverCount); + } + String pptUrl = ""; + Boolean isHttps = serverUrl.indexOf("https") == 0; + //若是要通过加密接口校验,则 + if (isValidate) { + pptUrl = servers[idIndex] + "?furl=" + URLEncoder.encode(encryptUrl, "UTF-8") + + (isHttps ? "&ssl=1" : ""); + } else { //不要通过接口加密校验 + pptUrl = servers[idIndex] + (isHttps ? "?ssl=1" : "") + + (isHttps ? "&" : "?") + + "furl=" + URLEncoder.encode(encryptUrl, "UTF-8"); + } + return pptUrl; + } catch (Exception e) { + LogUtil.error(e, "获取ppt预览地址失败"); + return ""; + } + } + + /** + * 置顶 + */ + public void addTop(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID()) || ObjectUtils.isEmpty(updateFileDTO.getParentID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "14", cs.getTargetType()); + + Integer sort = ioSourceDao.getMaxSort(updateFileDTO.getParentID()); + try { + ioSourceDao.updateSort(updateFileDTO.getSourceID(), ObjectUtils.isEmpty(sort) ? 1 : sort + 1); + } catch (Exception e) { + LogUtil.error(e, "置顶失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + } + + /** + * 取消置顶 + */ + public void cancelTop(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "14", cs.getTargetType()); + try { + ioSourceDao.updateSort(updateFileDTO.getSourceID(), 0); + } catch (Exception e) { + LogUtil.error(e, " 取消置顶失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.explorerError.getCode()); + } + } + + /** + * 新建文件 + */ + public void makeFile(CheckFileDTO updateFileDTO, LoginUser loginUser, Map resultMap) { + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID()) || ObjectUtils.isEmpty(updateFileDTO.getName())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + String originalFilename = updateFileDTO.getName(); + /*if (originalFilename.startsWith(".")) { + // 文件名不符合规范, 请修改 + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + }*/ + + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "9", cs.getTargetType()); + + String fileExtension = FileUtil.getFileExtension(originalFilename); + if (ObjectUtils.isEmpty(fileExtension)) { + throw new SvnlanRuntimeException(CodeMessageEnum.paramFormatError.getCode()); + } + List sourceNameList = ioSourceDao.getSourceNameList(updateFileDTO.getSourceID()); + /*if (!CollectionUtils.isEmpty(sourceNameList) && sourceNameList.contains(updateFileDTO.getName())){ + throw new SvnlanRuntimeException(CodeMessageEnum.pathExists.getCode()); + }*/ + originalFilename = this.checkRepeatName(originalFilename, originalFilename, fileExtension, sourceNameList, 1); + CommonSource commonSource = new CommonSource(); + //设置默认值 + this.setDefault(commonSource, loginUser); + String busType = BusTypeEnum.CLOUD.getBusType(); + commonSource.setSourceType(BusTypeEnum.CLOUD.getTypeCode()); + // 添加 + this.saveFileDetail(commonSource, updateFileDTO, busType, fileExtension, originalFilename, resultMap, "makeFile"); + + /** 操作日志 */ + Map reMap = null; + List> paramList = new ArrayList<>(); + reMap = new HashMap<>(4); + reMap.put("sourceID", commonSource.getSourceID()); + reMap.put("sourceParent", commonSource.getParentID()); + reMap.put("type", "mkfile"); + reMap.put("pathName", commonSource.getSourceName()); + paramList.add(reMap); + systemLogTool.setSysLog(loginUser, LogTypeEnum.fileMkFile.getCode(), paramList, systemLogTool.getRequest()); + } + + public void saveFileDetail(CommonSource commonSource, CheckFileDTO updateFileDTO, String busType, String fileExtension + , String originalFilename, Map resultMap, String pre) { + + String defaultPath = storageService.getDefaultStorageDevicePath(); + //最终文件目录路径 + String finalTopPath = defaultPath + PropertiesUtil.getUpConfig(busType + ".savePath"); + //基础路径+日期路径 + String finalFolderPath = finalTopPath + FileUtil.getDatePath(); + LogUtil.info(pre + " doSaveDirect finalFolderPath=" + finalFolderPath); + File folder = new File(finalFolderPath); + //创建目录 + if (!folder.exists()) { + if (!folder.mkdirs()) { + LogUtil.error("创建目录失败,makeFile path:" + finalFolderPath); +// return null; + } + } + //文件后缀 + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = finalFolderPath + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + commonSource.getUserID() + "." + fileExtension; + //最终文件 + File finalFile = new File(finalFilePath); + String serverChecksum; + FileInputStream fis = null; + byte[] size = {0}; + boolean isNew = false; + commonSource.setSize(0L); + if (!ObjectUtils.isEmpty(updateFileDTO.getContent())) { + // 放入addCommonSource方法 + size = updateFileDTO.getContent().getBytes(StandardCharsets.UTF_8); + commonSource.setSize((long) size.length); + } else { + isNew = true; + updateFileDTO.setContent(" "); + } + try { + if ("svg".equals(fileExtension.toLowerCase())) { + FileUtil.writeSvgFile(finalFile, size); + } else if (Arrays.asList("doc", "docx").contains(fileExtension.toLowerCase())) { + FileUtil.writeDocFile(finalFile, updateFileDTO.getContent()); + } else if (Arrays.asList("ppt", "pptx").contains(fileExtension.toLowerCase())) { + FileUtil.writePptFile(finalFile, updateFileDTO.getContent()); + } else if ("html".equals(fileExtension.toLowerCase())) { + FileUtil.writeHTMLFile(finalFile, updateFileDTO.getContent()); + } else if (Arrays.asList("xls", "xlsx").contains(fileExtension.toLowerCase())) { + FileUtil.writeExcelFile(finalFile); + } else if (Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(fileExtension.toLowerCase())) { + //转成保存图片 + FileUtil.byte2image(size, finalFilePath); + } else { + if ("txt".equals(fileExtension.toLowerCase()) && isNew){ + FileUtil.createNewFile(finalFile); + }else { + FileUtil.writeFile(finalFile, size); + } + + + } + /*****************************/ + fis = new FileInputStream(finalFile); + serverChecksum = DigestUtils.md5DigestAsHex(fis); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage(), " 创建文件失败"); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + commonSource.setName(originalFilename); + commonSource.setParentID(updateFileDTO.getSourceID()); + commonSource.setHashMd5(serverChecksum); + commonSource.setPath(finalFilePath); + commonSource.setFileType(fileExtension); + + if (!ObjectUtils.isEmpty(commonSource.getParentID()) && commonSource.getParentID() > 0) { + CommonSource parentSource = this.getSourceInfo(commonSource.getParentID()); + if (ObjectUtils.isEmpty(parentSource)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + commonSource.setParentLevel(parentSource.getParentLevel() + commonSource.getParentID() + ","); + commonSource.setTargetType(parentSource.getTargetType()); + } else { + commonSource.setParentLevel(",0,"); + commonSource.setTargetType(1); + } + try { + this.addCommonSource(commonSource.getUserID(), commonSource, EventEnum.mkfile); + resultMap.put("source", commonSource); + } catch (Exception e) { + LogUtil.error(e, "makeFile source入库失败" + JsonUtils.beanToJson(commonSource)); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + } + + public void setDefault(CommonSource commonSource, LoginUser loginUser) { + commonSource.setUserID(loginUser.getUserID()); + commonSource.setAppPreviewUrl(""); + commonSource.setAppPreview(0); + commonSource.setHashMd5(""); + commonSource.setIsM3u8(0); + commonSource.setIsPreview(0); + commonSource.setSourceLength(0); + commonSource.setName(""); + commonSource.setPath(""); + commonSource.setFileType(""); + commonSource.setPreviewUrl(""); + commonSource.setThumb(""); + if (Objects.isNull(commonSource.getSourceType())) { + commonSource.setSourceType(0); + } + commonSource.setApprovalState("0"); + commonSource.setResolution(""); + } + + /** + * 链接分享 + */ + public List checkUserIsShare(Long userID) { + String key = GlobalConfig.my_share_key + userID; + List shareList = null; + ValueOperations operations = stringRedisTemplate.opsForValue(); + String value = operations.get(key); + if (!ObjectUtils.isEmpty(value) && !"0".equals(value)) { + try { + shareList = Arrays.asList(value.split(",")).stream().map(Long::parseLong).collect(Collectors.toList()); + } catch (Exception e) { + LogUtil.error(e, "checkUserIsShare 缓存解析失败 key=" + key + ",value=" + value); + } + } + if (ObjectUtils.isEmpty(value)) { + shareList = shareDao.checkUserIsShare(userID); + if (ObjectUtils.isEmpty(shareList)) { + shareList = new ArrayList<>(); + shareList.add(0L); + } + String share = shareList.stream().map(String::valueOf).collect(Collectors.joining(",")); + operations.set(key, share, 30, TimeUnit.MINUTES); + } + + return shareList; + } + + /** + * 收藏 + */ + public List checkIsFavByUserId(Long userID) { + + String key = GlobalConfig.my_fav_key + userID; + List favList = null; + ValueOperations operations = stringRedisTemplate.opsForValue(); + String value = operations.get(key); + if (!ObjectUtils.isEmpty(value) && !"0".equals(value)) { + try { + favList = Arrays.asList(value.split(",")).stream().map(String::valueOf).collect(Collectors.toList()); + } catch (Exception e) { + LogUtil.error(e, "checkIsFavByUserId 缓存解析失败 key=" + key + ",value=" + value); + } + } + if (ObjectUtils.isEmpty(value)) { + favList = userFavDao.checkIsFavByUserId(userID); + if (ObjectUtils.isEmpty(favList)) { + favList = new ArrayList<>(); + favList.add("0"); + } + operations.set(key, favList.stream().collect(Collectors.joining(",")), 30, TimeUnit.MINUTES); + } + return favList; + } + + public void updateFileCover(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (ObjectUtils.isEmpty(updateFileDTO.getSourceID())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + CommonSource cs = ioSourceDao.getSourceInfo(updateFileDTO.getSourceID()); + if (ObjectUtils.isEmpty(cs)) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + // 权限校验 + userAuthTool.checkGroupDocAuth(loginUser, cs.getSourceID(), cs.getParentLevel(), "8", cs.getTargetType()); + + + IOFileMeta meta = ioFileDao.getFileValue(updateFileDTO.getSourceID()); + Map map = null; + if (!ObjectUtils.isEmpty(meta) && !ObjectUtils.isEmpty(meta.getValue())) { + map = JsonUtils.jsonToMap(meta.getValue()); + } + if (ObjectUtils.isEmpty(map)) { + map = new HashMap<>(1); + } + map.put("cover", ObjectUtils.isEmpty(updateFileDTO.getCover()) ? "" : updateFileDTO.getCover()); + + try { + if (!ObjectUtils.isEmpty(meta)) { + ioFileDao.updateOneFileUrlValue(meta.getFileID(), JsonUtils.beanToJson(map)); + } else { + IOFileMeta fileMeta = new IOFileMeta(); + fileMeta.setFileID(meta.getFileID()); + fileMeta.setKey("fileInfoMore"); + fileMeta.setValue(JsonUtils.beanToJson(map)); + ioFileDao.insertMeta(fileMeta); + } + } catch (Exception e) { + LogUtil.error(e, " 保存封面失败!"); + throw new SvnlanRuntimeException(CodeMessageEnum.saveError.getCode()); + } + } + + /** + * 标签 + */ + public Map> getSourceTagMap(Long userID, List sourceIDs) { + Map> map = null; + List myTagList = userFavDao.getFileTagBySourceID(userID, sourceIDs); + if (!CollectionUtils.isEmpty(myTagList)) { + map = myTagList.stream().collect(Collectors.toMap(UserFavVo::getPath, UserFavVo::getFavList, (v1, v2) -> v2)); + } + return map; + } + + public String checkRepeatName(String name, String newName, List sourceNameList, int i) { + if (!CollectionUtils.isEmpty(sourceNameList)) { + sourceNameList = sourceNameList.stream().map(String::toLowerCase).collect(Collectors.toList()); + if (sourceNameList.contains(newName.toLowerCase())) { + return checkRepeatName(name, name + "(" + i + ")", sourceNameList, i + 1); + } + } + return newName; + } + + public String checkRepeatName(String name, String newName, String fileType, List sourceNameList, int i) { + log.info("checkRepeatName name => {} newName => {} fileType => {} sourceNameList => {} i => {}", + name, newName, fileType, sourceNameList, i); + if (!CollectionUtils.isEmpty(sourceNameList)) { + sourceNameList = sourceNameList.stream().map(String::toLowerCase).collect(Collectors.toList()); + if (sourceNameList.contains(newName.toLowerCase())) { + return checkRepeatName(name, name.replaceAll("." + fileType, "") + "(" + i + ")." + fileType, fileType, sourceNameList, i + 1); + } + } + return newName; + } + + /** + * @Description: 收藏夹重命名 + * @params: [updateFileDTO, paramMap] + * @Return: boolean + * @Modified: + */ + public boolean favRenameFile(CheckFileDTO updateFileDTO, LoginUser loginUser) { + if (ObjectUtils.isEmpty(updateFileDTO.getId()) || StringUtil.isEmpty(updateFileDTO.getName())) { + throw new SvnlanRuntimeException(CodeMessageEnum.selectFolderFile.getCode()); + } + if (updateFileDTO.getName().length() > 200) { + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorParam.getCode()); + } + List nameList = userFavDao.getFavNameList(loginUser.getUserID()); + if (!CollectionUtils.isEmpty(nameList)) { + nameList = nameList.stream().map(String::toLowerCase).collect(Collectors.toList()); + if (nameList.contains(updateFileDTO.getName().toLowerCase())) { + throw new SvnlanRuntimeException(CodeMessageEnum.pathExists.getCode()); + } + } + + try { + userFavDao.updateFavName(updateFileDTO.getId(), updateFileDTO.getName()); + } catch (Exception e) { + LogUtil.error(e, " batchFileRename error operationsDTO=" + JsonUtils.beanToJson(updateFileDTO)); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } + return true; + } + + public String getPropertiesFilePathAll(String propertiesName) { + String defaultPath = storageService.getDefaultStorageDevicePath(); + String finalTopPath = PropertiesUtil.getUpConfig(propertiesName); + return defaultPath + finalTopPath; + } +} diff --git a/src/main/java/com/svnlan/home/utils/FileUtil.java b/src/main/java/com/svnlan/home/utils/FileUtil.java new file mode 100644 index 0000000..5c8e521 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/FileUtil.java @@ -0,0 +1,1289 @@ +package com.svnlan.home.utils; + +import com.google.common.base.Splitter; +import com.svnlan.common.GlobalConfig; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.domain.CloudFile; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.*; +import org.apache.commons.io.IOUtils; +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFSlide; +import org.apache.poi.xslf.usermodel.XSLFTextBox; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.xwpf.extractor.XWPFWordExtractor; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ObjectUtils; + +import javax.imageio.stream.FileImageOutputStream; +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.sql.Blob; +import java.sql.SQLException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Author: + * @Description: + */ +public class FileUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger("error"); + + //写入文件 + public static boolean putFileContent(String path, String content) { + try (OutputStream out = new FileOutputStream(path)) { + IOUtils.write(content, out, StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error(e.getMessage() + ", 写入文件失败, path: " + path, ", content: " + content); + return false; + } + return true; + } + + //读取文件 + public static String getFileContent(String path) { + try (InputStream in = new FileInputStream(path)) { + return IOUtils.toString(in, StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error("读取文件失败, path: " + path); + } + return ""; + } + + //读取文件 + public static String getFileContent(File File) { + try (InputStream in = new FileInputStream(File)) { + return IOUtils.toString(in, StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error("读取文件失败, getAbsolutePath: " + File.getAbsolutePath()); + } + return ""; + } + + /** + * @Description: 日期路径 + * @params: [] + * @Return: java.lang.String + * @Modified: + */ + public static String getDatePath() { + Calendar calendar = Calendar.getInstance(); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + int day = calendar.get(Calendar.DAY_OF_MONTH); + return year + "_" + month + "/" + day + "/"; + } + + public static final List specificExtList = Arrays.asList("tar.gz"); + + /** + * @Description: 获取文件扩展名 + * @params: [fileName] + * @Return: java.lang.String + * @Modified: + */ + public static String getFileExtension(String fileName) { + if (fileName == null) { + return null; + } + //点号位置 + int indexOfDot = fileName.lastIndexOf("."); + if (indexOfDot == -1) { + return ""; + } + for (String specific : specificExtList) { + if (fileName.endsWith(specific)) { + return specific; + } + } + String fileExt = fileName.substring(indexOfDot); + return StringUtil.ltrim(fileExt, 1).toLowerCase(); + } + + /** + * 磁盘上实际的文件名称 + * + * @param userId 用户id + * @param ext 文件后缀 + */ + public static String getRealFileName(Long userId, String ext) { + return RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + userId + "." + ext; + } + + /** + * @Description: + * @params: [fileName] + * @Return: java.lang.String + * @Modified: + */ + public static String insertBeforeExtension(String fileName, String insert) { + if (fileName == null) { + return null; + } + //点号位置 + Integer indexOfDot = fileName.lastIndexOf("."); + if (indexOfDot == -1) { + return fileName + insert; + } + return fileName.substring(0, indexOfDot) + insert + fileName.substring(indexOfDot, fileName.length()); + } + + public static void responseFile(HttpServletResponse response, String finalFilePath, String fileName, Boolean isSwf) throws Exception { + responseFile(response, finalFilePath, fileName, isSwf, true); + } + + public static void responseFile(HttpServletResponse response, String finalFilePath, String fileName, Boolean isSwf, Boolean isDown) throws Exception { + if (isSwf) { + response.setHeader("Content-Type", "application/x-shockwave-flash"); + response.setHeader("Content-Disposition", "inline; filename=" + fileName); + } else { + response.setHeader("Content-Type", "application/octet-stream"); + response.setHeader("Content-Disposition", "attachment; filename* = UTF-8''" + fileName); + } + // if (isDown) { + response.setHeader("X-Accel-Redirect", finalFilePath); + // } + //response.getWriter().close(); + } + + public static void responseMP4(HttpServletResponse response, String finalFilePath, String fileName) { + + response.setHeader("Content-Type", "video/mp4"); + response.setHeader("Content-Disposition", "inline; filename=" + fileName); + + response.setHeader("X-Accel-Redirect", finalFilePath); + } + + /** + * @Description: 生成下载key + * @params: [] + * @Return: java.lang.String + * @Modified: + */ + public static String getDownloadKey() { + HttpServletRequest request = HttpUtil.getRequest(); + String token = request.getHeader("token"); + String key = AESUtil.encrypt(token + GlobalConfig.ATTACHMENT_KEY_SEPARATOR + System.currentTimeMillis(), + GlobalConfig.ATTACHMENT_AES_KEY, true); + try { + key = URLEncoder.encode(key, "UTF-8"); + } catch (Exception e) { + LogUtil.error(e, "下载key, encode失败"); + } + return key; + } + public static String getVideoImgDownloadKey(String value) { + return getVideoImgDownloadKey(value, "0"); + } + public static String getVideoImgDownloadKey(String value, String sourceKey) { + String key = AESUtil.encrypt(value + GlobalConfig.ATTACHMENT_KEY_SEPARATOR + sourceKey, + GlobalConfig.ATTACHMENT_AES_KEY, true); + try { + key = URLEncoder.encode(key, "UTF-8"); + } catch (Exception e) { + LogUtil.error(e, "下载key, encode失败"); + } + return key; + } + + public static String getDownloadKey(String token) { + if (ObjectUtils.isEmpty(token)) { + token = ""; + } + String key = AESUtil.encrypt(token + GlobalConfig.ATTACHMENT_KEY_SEPARATOR + System.currentTimeMillis(), + GlobalConfig.ATTACHMENT_AES_KEY, true); + try { + key = URLEncoder.encode(key, "UTF-8"); + } catch (Exception e) { + LogUtil.error(e, "下载key, encode失败"); + } + return key; + } + + + public static String encodeDownloadUrl(String sourceName) { + return sourceName.replaceAll("\\[", "%5B") + .replaceAll("]", "%5D") + .replaceAll("%", "%25") + .replaceAll("#", "%23") + .replaceAll(";", "%3B") + .replaceAll("\\?", "") + .replaceAll("/", "") + .replaceAll("\\\\", "") + ; + } + + + public static String getM3u8Key() { + HttpServletRequest request = HttpUtil.getRequest(); + String token = request.getHeader("token"); + String key = AESUtil.encrypt(token + GlobalConfig.M3U8_PLAY_KEY_SEPARATOR + System.currentTimeMillis(), + GlobalConfig.M3U8_PLAY_AES_KEY, true); + try { + key = URLEncoder.encode(key, "UTF-8"); + } catch (Exception e) { + LogUtil.error(e, "m3u8 Key, encode失败"); + } + return key; + } + + /** + * @Description: 转码进度 + * @params: [m3u8Path, videoLength, needProgress] + * @Return: java.lang.Integer + * @Modified: + */ + public static Integer getConvertedLength(String m3u8Path, Integer videoLength, Boolean needProgress) { + if (videoLength.equals(0)) { + return 0; + } + //m3u8内容 + String m3u8String = FileUtil.getFileContent(m3u8Path); + if (StringUtil.isEmpty(m3u8String)) { + return 0; + } + //查找时间xx.xx秒 + Pattern pattern = Pattern.compile("EXTINF:(\\d*?\\.\\d*?),"); + Matcher m = pattern.matcher(m3u8String); + Double seconds = 0D; + while (m.find()) { + seconds += Double.parseDouble(m.group(1)); + } + return Math.min(100, (int) Math.ceil(seconds * 100 / videoLength)); + } + + /** + * @Description: 文件非法字符替换 + * @params: [fileName] + * @Return: java.lang.String + * @Modified: + */ + public static String replaceIllegalSymbol(String fileName) { + return fileName.replaceAll("/", "丿") + .replaceAll("\\\\", "乀") + .replaceAll(":", ":") + .replaceAll("\\?", "?") + .replaceAll("\\|", "丨") + .replaceAll("\\*", "※") + .replaceAll("\"", "”") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll("~", "_") + ; + } + + public static String removeIllegalSymbol(String fileName) { + return fileName.replaceAll("/", "") + .replaceAll("\\\\", "") + .replaceAll(":", "") + .replaceAll("\\?", "") + .replaceAll("\\|", "") + .replaceAll("\\*", "") + .replaceAll("\"", "") + .replaceAll("<", "") + .replaceAll(">", "") + .replaceAll("~", "_") + ; + } + + /** + * @Description: 部分业务返回文件地址 + * @params: [sourcePath, busType, commonSource] + * @Return: void + * @Modified: + */ + public static String returnPath(String sourcePath, String busType, String thumb) { + return returnPath(sourcePath, busType, thumb, true); + } + + public static String returnPath(String sourcePath, String busType, String thumb, boolean needShowPath) { + String path; + BusTypeEnum busTypeEnum = BusTypeEnum.getFromTypeName(busType); + String showPath = needShowPath ? PropertiesUtil.getUpConfig(busTypeEnum.getBusType() + ".showPath") : ""; + String suffix; + switch (busTypeEnum) { + case IMAGE: + case AVATAR: + case HOMEPAGE_IMAGE: + case HOMEPAGE_ATTACHMENT: + case HOMEPAGE_VIDEO: + case BROCHURE_ATTACHMENT: + case DESIGN_THUMB: + case DESIGN_LOGO: + path = sourcePath; + break; + case CLOUD: + path = thumb; + String firstPath = getFirstStorageDevicePath(path); + suffix = FileUtil.getFileExtension(sourcePath); + if (StringUtil.isEmpty(path) && Arrays.asList(GlobalConfig.IMAGE_TYPE_ARR).contains(suffix)) { + path = (showPath + sourcePath) + .replace(firstPath + "/doc/", firstPath + "/common/doc/") + .replace(firstPath + "/attachment/", firstPath + "/common/attachment/") + .replace(firstPath + "/private/", firstPath + "/common/"); + } + break; + default: + path = null; + } + return path; + } + + public static String getFirstStorageDevicePath(String path){ + if (ObjectUtils.isEmpty(path) || path.indexOf("/") < 0){ + return ""; + } + path = path.substring(1, path.length()); + return "/" + path.substring(0, path.indexOf("/")); + + } + + public static String getUseSourceNewPath(CloudFile cloudFile, LoginUser loginUser, String busType) { + String newPath = FileUtil.getDatePath() + System.currentTimeMillis() + + "_" + loginUser.getUserID() + "_" + busType + cloudFile.getFileId() + + "." + cloudFile.getSuffix(); + return newPath; + } + + public static void responseJson(HttpServletResponse response, String finalFilePath, String fileName) { + response.setHeader("Content-Type", "application/json"); + response.setHeader("Content-Disposition", "inline; filename* = UTF-8''" + fileName); + response.setHeader("X-Accel-Redirect", finalFilePath); + } + + public static String[] getFilePathAndName(String path) { + int lastSlash = path.lastIndexOf("/"); + return new String[]{path.substring(0, lastSlash), path.substring(lastSlash + 1, path.length())}; + } + + public static Map extractParams(String url) { + String params = url.substring(url.indexOf("?") + 1, url.length()); + return Splitter.on("&").withKeyValueSeparator("=").split(params); + } + + /** + * @param prefix + * @param is + * @param fileName + * @return void + * @description: 将InputStream写入文件 + */ + public static Boolean generateFile(String prefix, InputStream is, String fileName) { + Boolean success = Boolean.TRUE; + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream(is); + out = new BufferedOutputStream(new FileOutputStream(fileName)); + int len = -1; + byte[] b = new byte[1024]; + while ((len = in.read(b)) != -1) { + out.write(b, 0, len); + } + } catch (Exception e) { + success = Boolean.FALSE; + LogUtil.error(e, prefix + "将InputStream写入文件发生异常"); + } finally { + if (null != in) { + try { + in.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (null != out) { + try { + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return success; + } + + public static File getFile(String url) { + //对本地文件命名 + String fileName = url.substring(url.lastIndexOf(".")); + File file = null; + + URL urlfile; + InputStream inStream = null; + OutputStream os = null; + try { + file = File.createTempFile("net_url", fileName); + //下载 + urlfile = new URL(url); + inStream = urlfile.openStream(); + os = new FileOutputStream(file); + + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (null != os) { + os.close(); + } + if (null != inStream) { + inStream.close(); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + return file; + } + + public static String getImgStr(String imgFile) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + + InputStream in = null; + byte[] data = null; + // 读取图片字节数组 + try { + in = new FileInputStream(imgFile); + data = new byte[in.available()]; + in.read(data); + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return org.apache.commons.codec.binary.Base64.encodeBase64String(data); + } + + + //判断是否UTF-8 + public static void checkUTF8(File file) { + try (BufferedInputStream bin = new BufferedInputStream( + new FileInputStream(file))) { + int p = (bin.read() << 16) + (bin.read() << 8) + bin.read(); + boolean isUTF8 = p == 0xefbbbf; //UTF8 BOM + if (!isUTF8) {//判断UTF8无BOM + try (Reader reader = new FileReader(file)) { + byte[] bytes = IOUtils.toByteArray(reader, "UTF-8"); + int a = ((bytes[0] & 0xff) << 16) + ((bytes[1] & 0xff) << 8) + (bytes[2] & 0xff); + if (a != p) { + // 文件必须是UTF-8编码 + throw new SvnlanRuntimeException(CodeMessageEnum.explorerDataError.getCode()); + } + } + + } + } catch (Exception e) { + LogUtil.error(e, "导入文件文件编码获取失败"); + // , "文件必须是UTF-8编码" + throw new SvnlanRuntimeException(CodeMessageEnum.explorerDataError.getCode()); + } + } + + + /** + * @Description: 文件是否存在 + * @params: [fileName] + * @Return: java.lang.Boolean + * @Modified: + */ + public static Boolean fileExists(String fileName) { + return new File(fileName).exists(); + } + + /** + * @Description: 写文件 + * @params: [file, fileBytes] + * @Return: java.lang.Boolean + * @Modified: + */ + public static Boolean writeFile(File file, byte[] fileBytes) { + try (FileOutputStream fileOutputStream = new FileOutputStream(file); + BufferedOutputStream out = new BufferedOutputStream(fileOutputStream);) { + out.write(fileBytes); + out.flush(); + } catch (IOException e) { + LogUtil.error(e, " util 写入文件失败, " + file.getAbsolutePath()); + return false; + } + return true; + } + public static Boolean createNewFile(File file) { + try { + file.createNewFile(); + } catch (IOException e) { + LogUtil.error(e, " util createNewFile 文件失败, " + file.getAbsolutePath()); + return false; + } + return true; + } + + public static String textData(String filePath) { + File file = new File(filePath); + + if (!file.exists() || file.length() == 0) { + return ""; + } else { + String charset = EncodingDetects.getJavaEncode(filePath); + if ("ASCII".equals(charset)) { + charset = StandardCharsets.US_ASCII.name(); + } + + StringBuilder result = new StringBuilder(); + try { + BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), charset)); + String line; + while ((line = br.readLine()) != null) { + result.append(line).append("\r\n"); + } + br.close(); + return result.toString(); + } catch (IOException e) { + LogUtil.error(e, "textData io error"); + } catch (Exception e) { + LogUtil.error(e, "textData error"); + } + return ""; + } + } + + //读取文件 + public static String getFileContent(String path, Charset encoding) { + BufferedReader br = null; + StringBuilder str = new StringBuilder(); + File f = null; + try { + f = new File(path); + if (!f.exists()) { + return ""; + } + // 在FileInputStream中指定编码格式为"GBK" + br = new BufferedReader(new InputStreamReader(new FileInputStream(f), encoding)); + String t = null; + while ((t = br.readLine()) != null) { + str.append(t + "\n"); + + } + return str.toString(); + } catch (FileNotFoundException e) { + LogUtil.error(e, "读取文件失败 notFound, path: " + path); + } catch (IOException e) { + LogUtil.error(e, "读取文件失败 IOError, path: " + path); + } catch (Exception e) { + LogUtil.error(e, "读取文件失败 error, path: " + path); + } finally { + // 关闭流 + if (br == null) { + try { + br.close(); + } catch (IOException e) { + LogUtil.error(e, "读取文件失败 close , path: " + path); + } catch (Exception e) { + LogUtil.error(e, "读取文件失败 close error, path: " + path); + } + } + } + return ""; + } + + /** + * 十六进制字节转字节数组 + * + * @param s 实例 + * String str2="ffd8ffe000104a46494600010100000100010000f****ee3fdf4ff00d0857927f0cbf43fccd483"; + * byte[] t=fromHexString(str2); + * byte2image(t, "d://1.jpg");//转成保存图片 + */ + public static byte[] fromHexString(String s) { + int length = s.length() / 2; + byte[] bytes = new byte[length]; + for (int i = 0; i < length; i++) { + bytes[i] = (byte) ((Character.digit(s.charAt(i * 2), 16) << 4) | Character + .digit(s.charAt((i * 2) + 1), 16)); + } + return bytes; + } + + /** + * 实现字节数组向十六进制的转换方法一 + * + * @param fieldData + * @return + */ + public static String toHexString(byte[] fieldData) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < fieldData.length; i++) { + int v = (fieldData[i] & 0xFF); + if (v <= 0xF) { + sb.append("0"); + } + sb.append(Integer.toHexString(v)); + } + return sb.toString(); + } + + //byte数组转图片 + public static void byte2image(byte[] data, String path) { + if (data.length < 3 || path.equals("")) return; + try { + FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path)); + imageOutput.write(data, 0, data.length); + imageOutput.close(); + LogUtil.info("Make Picture success,Please find image in " + path); + } catch (Exception ex) { + LogUtil.error("Exception: " + ex); + ex.printStackTrace(); + } + } + + /****** *图片转十六进制* ***********/ + public static String getImageContent(String path) { + try { + //StringBuffer sb = new StringBuffer(); + FileInputStream fis = new FileInputStream(path); + //BufferedInputStream bis = new BufferedInputStream(fis); + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + byte[] buff = new byte[1024]; + int len = 0; + while ((len = fis.read(buff)) != -1) { + bos.write(buff, 0, len); + } + // 得到图片的字节数组 + byte[] result = bos.toByteArray(); + // 字节数组转成十六进制 + + return toHexString(result); + //String str = byte2HexStr(result); + /* + * 将十六进制串保存到txt文件中 + */ + /* PrintWriter pw = new PrintWriter( + new FileWriter("qgc88.txt")); + pw.println(str); + pw.close();*/ + } catch (IOException e) { + LogUtil.error(e, "读取图片失败!"); + } + return ""; + } + + /****** *读取doc内容* ***********/ + public static String getDocxContent(String path) { + try { + FileInputStream fis1 = new FileInputStream(path); + XWPFWordExtractor docx = new XWPFWordExtractor(new XWPFDocument(fis1)); + return docx.getText(); + + } catch (IOException e) { + LogUtil.error(e, "读取docx失败!"); + } + return ""; + } + + + public static Boolean writeDocFile(File file, String content) { + try { + XWPFDocument doc = new XWPFDocument(); + + XWPFParagraph paragraphX = doc.createParagraph(); + XWPFRun runX = paragraphX.createRun(); + runX.setText(content); + + OutputStream os = new FileOutputStream(file); + //把doc输出到输出流 + doc.write(os); + os.close(); + doc.close(); + } catch (IOException e) { + LogUtil.error(e, " writeDocFile 写入文件失败, " + file.getAbsolutePath()); + return false; + } + return true; + } + + + /** + * 先创建一个XSSFWorkbook对象 + * + * @param + * @return + */ + public static boolean writeExcelFile(File file) { + XSSFWorkbook workbook = null; + BufferedOutputStream outputStream = null; + try { + outputStream = new BufferedOutputStream(new FileOutputStream(file)); + workbook = new XSSFWorkbook(); + XSSFSheet xssfSheet = workbook.createSheet("Sheet"); + XSSFRow xssfRow = xssfSheet.createRow(1); // 行 + XSSFCell xssfCell = xssfRow.createCell(1); // 列 + // 4、设置单元格内容 + xssfCell.setCellValue(""); + workbook.write(outputStream); + } catch (Exception e) { + LogUtil.error(e, " writeExcelFile 写入文件失败, " + file.getAbsolutePath()); + return false; + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (workbook != null) { + try { + workbook.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return true; + } + + public static Boolean writePptFile(File file, String content) { + XMLSlideShow ppt = null; + OutputStream os = null; + try { + ppt = new XMLSlideShow(); + XSLFSlide blankSlide = ppt.createSlide(); + // 构建一个文本框 + XSLFTextBox shape = blankSlide.createTextBox(); + // 设置文本 + shape.setText(content); + + os = new FileOutputStream(file); + //输出到输出流 + ppt.write(os); + os.close(); + ppt.close(); + } catch (IOException e) { + LogUtil.error(e, " writePptFile 写入文件失败, " + file.getAbsolutePath()); + return false; + } finally { + if (os != null) { + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (ppt != null) { + try { + ppt.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return true; + } + + public static Boolean writeSvgFile(File file, byte[] fileBytes) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + //输出到输出流 + fos.write(fileBytes); + fos.close(); + } catch (IOException e) { + LogUtil.error(e, " writeSvgFile 写入文件失败, " + file.getAbsolutePath()); + return false; + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return true; + } + + public static Boolean writeHTMLFile(File file, String htmlStr) { + if (ObjectUtils.isEmpty(htmlStr)) { + htmlStr = "" + + "" + + " " + + " " + + " " + + " " + + " " + + " " + + "" + ; + } + BufferedWriter bufferedWriter = null; + try { + bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); + bufferedWriter.write(htmlStr); + bufferedWriter.newLine();//换行 + /* * 刷新该流的缓冲。 + * 关键的一行代码。如果没有加这行代码。数据只是保存在缓冲区中。没有写进文件。 + * 加了这行才能将数据写入目的地。 * */ + bufferedWriter.flush(); + bufferedWriter.close(); + } catch (IOException e) { + LogUtil.error(e, " writeHTMLFile 写入文件失败, " + file.getAbsolutePath()); + return false; + } finally { + if (bufferedWriter != null) { + try { + bufferedWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return true; + } + + /** + * 从文件加载模板 + * + * @return Document + */ + public static String parseDocumentFromFile(String filePath) { + String html = ""; + File input = new File(filePath); + if (input == null) { + return "文档不存在"; + } + Document doc = null; + try { + //从文件加载Document文档 + doc = Jsoup.parse(input, "UTF-8"); + html = doc.outerHtml(); + } catch (IOException e) { + LogUtil.error(e, "parseDocumentFromFile error"); + } + return html; + } + + public static String getJsFileContent(String filename) { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("javascript"); + String ret = ""; + FileReader reader = null; + try { + + reader = new FileReader(filename); // 执行指定脚本 + engine.eval(reader); + if (engine instanceof Invocable) { + Invocable invoke = (Invocable) engine; + ret = (String) invoke.invokeFunction("encrypt", "ABCD"); //方法名和参数 + //System.out.println("s = " + s); + } + } catch (ScriptException e) { + LogUtil.error(e, "getJsFileContent ScriptException error"); + } catch (NoSuchMethodException e) { + LogUtil.error(e, "getJsFileContent NoSuchMethodException error"); + } catch (IOException e) { + LogUtil.error(e, "getJsFileContent IOException error"); + } catch (Exception e) { + LogUtil.error(e, "getJsFileContent Exception error"); + } finally { + if (null != reader) { + try { + reader.close(); + } catch (Exception e) { + LogUtil.error(e, "getJsFileContent reader close error"); + } + } + } + return ret; + } + + public static boolean isMessyCode(String strName) { + //去除字符串中的空格 制表符 换行 回车 + Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*"); + Matcher m = p.matcher(strName); + String after = m.replaceAll("").replaceAll("\\+", "").replaceAll("#", "").replaceAll("&", ""); + //去除字符串中的标点符号 + String temp = after.replaceAll("\\p{P}", ""); + //处理之后转换成字符数组 + char[] ch = temp.trim().toCharArray(); + for (int i = 0; i < ch.length; i++) { + char c = ch[i]; + //判断是否是数字或者英文字符 + if (!judge(c)) { + //判断是否是中日韩文 + if (!isChinese(c)) { + //如果不是数字或者英文字符也不是中日韩文则表示是乱码返回true + return true; + } + } + } + //表示不是乱码 返回false + return false; + } + + /** + * 判断是否是中日韩文字 + */ + private static boolean isChinese(char c) { + Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); + if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS + || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A + || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION + || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION + || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { + return true; + } + return false; + } + + public static boolean judge(char c) { + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) { + return true; + } + return false; + } + + public static String getUtf8String(String str) { + if (str != null && str.length() > 0) { + String needEncodeCode = "ISO-8859-1"; + String neeEncodeCode = "ISO-8859-2"; + String gbkEncodeCode = "GBK"; + try { + if (Charset.forName(needEncodeCode).newEncoder().canEncode(str)) { + str = new String(str.getBytes(needEncodeCode), StandardCharsets.UTF_8); + } + if (Charset.forName(neeEncodeCode).newEncoder().canEncode(str)) { + str = new String(str.getBytes(neeEncodeCode), StandardCharsets.UTF_8); + } + if (Charset.forName(gbkEncodeCode).newEncoder().canEncode(str)) { + str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + return str; + } + + public static byte[] getUTF8BytesFromGBKString(String gbkStr) { + int n = gbkStr.length(); + byte[] utfBytes = new byte[3 * n]; + int k = 0; + for (int i = 0; i < n; i++) { + int m = gbkStr.charAt(i); + if (m < 128 && m >= 0) { + utfBytes[k++] = (byte) m; + continue; + } + utfBytes[k++] = (byte) (0xe0 | (m >> 12)); + utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f)); + utfBytes[k++] = (byte) (0x80 | (m & 0x3f)); + } + if (k < utfBytes.length) { + byte[] tmp = new byte[k]; + System.arraycopy(utfBytes, 0, tmp, 0, k); + return tmp; + } + return utfBytes; + } + + /****** *图片转Blob* ***********/ + public static Object getImageContentBlob(String path) { + try { + // 得到图片的字节数组 + byte[] result = getFileByte(path); + // 字节数组转成十六进制 + + return toBlobString(result); + } catch (Exception e) { + LogUtil.error(e, "读取图片失败!"); + } + return ""; + } + + /****** *图片转Blob* ***********/ + public static byte[] getFileByte(String path) { + try { + FileInputStream fis = new FileInputStream(path); + java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); + byte[] buff = new byte[1024]; + int len = 0; + while ((len = fis.read(buff)) != -1) { + bos.write(buff, 0, len); + } + // 得到图片的字节数组 + byte[] result = bos.toByteArray(); + // 字节数组转成十六进制 + + return result; + } catch (IOException e) { + LogUtil.error(e, "读取图片失败!"); + } + return null; + } + + /** + * 实现字节数组向十六进制的转换方法一 + * + * @param fieldData + * @return + */ + public static Blob toBlobString(byte[] fieldData) { + Blob blob = new Blob() { + @Override + public long length() throws SQLException { + return 0; + } + + @Override + public byte[] getBytes(long pos, int length) throws SQLException { + return new byte[0]; + } + + @Override + public InputStream getBinaryStream() throws SQLException { + return null; + } + + @Override + public long position(byte[] pattern, long start) throws SQLException { + return 0; + } + + @Override + public long position(Blob pattern, long start) throws SQLException { + return 0; + } + + @Override + public int setBytes(long pos, byte[] bytes) throws SQLException { + return 0; + } + + @Override + public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException { + return 0; + } + + @Override + public OutputStream setBinaryStream(long pos) throws SQLException { + return null; + } + + @Override + public void truncate(long len) throws SQLException { + + } + + @Override + public void free() throws SQLException { + + } + + @Override + public InputStream getBinaryStream(long pos, long length) throws SQLException { + return null; + } + }; + try { + blob.setBytes(0, fieldData); + return blob; + } catch (Exception e) { + LogUtil.error(e, "二进制转blob错误"); + } + return null; + } + + /** + * @param prefix + * @param buffer + * @param filePath + * @return void + * @description: 字节数组转存文件 + */ + public static void bytesToFile(String prefix, byte[] buffer, final String filePath) { + File file = new File(filePath); + OutputStream output = null; + BufferedOutputStream bufferedOutput = null; + try { + output = new FileOutputStream(file); + bufferedOutput = new BufferedOutputStream(output); + bufferedOutput.write(buffer); + } catch (FileNotFoundException e) { + LogUtil.error(e, prefix + "文件不存在:" + filePath); + throw new SvnlanRuntimeException(CodeMessageEnum.pathNotExists.getCode()); + } catch (IOException e) { + LogUtil.error(e, prefix + "文件IO异常:" + filePath); + throw new SvnlanRuntimeException(CodeMessageEnum.system_error.getCode()); + } finally { + if (null != bufferedOutput) { + try { + bufferedOutput.close(); + } catch (IOException e) { + LogUtil.error(e, prefix + "出现IO异常:" + filePath); + } + } + if (null != output) { + try { + output.close(); + } catch (IOException e) { + LogUtil.error(e, prefix + "出现IO异常:" + filePath); + } + } + } + } + public static List getM3u8LineList(String path) { + BufferedReader br = null; + List pathList = new ArrayList<>(); + File f = null; + try { + f = new File(path); + if (!f.exists()) { + return pathList; + } + // 在FileInputStream中指定编码格式为"GBK" + br = new BufferedReader(new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8)); + String t = null; + while ((t = br.readLine()) != null) { + if (t.endsWith(".ts")){ + pathList.add(t); + } + } + return pathList; + } catch (FileNotFoundException e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 notFound, path: " + path); + } catch (IOException e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 IOError, path: " + path); + } catch (Exception e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 error, path: " + path); + } finally { + // 关闭流 + if (br == null) { + try { + br.close(); + } catch (IOException e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 close , path: " + path); + } catch (Exception e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 close error, path: " + path); + } + } + } + return pathList; + } + + /** 文本未替换成功时的补救 + * + /tencent_data/private/cloud/2023_6/27/38d3272c136843a897004b84ce956ba51687833456540_1.m3u8 + m3u8_convert_server_url_placeholder/tencent_data/mu/m3u8/2023_6/27/38d3272c136843a897004b84ce956ba51687833456540_1/38d3272c136843a897004b84ce956ba51687833456540_1 + */ + public static String getM3u8LineContent(String path, String key) { + BufferedReader br = null; + + File f = null; + try { + f = new File(path); + if (!f.exists()) { + return ""; + } + StringBuilder result = new StringBuilder(); + // 在FileInputStream中指定编码格式为"GBK" + br = new BufferedReader(new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8)); + String t = null; + int i = 0; + while ((t = br.readLine()) != null) { + if (t.endsWith(".ts")){ + if (t.indexOf(GlobalConfig.m3u8ConvertUrlPlaceholder) >= 0) { + result.append(GlobalConfig.m3u8ConvertUrlPlaceholder + "/api/disk/video/img/"+ ( key + "_"+ i)+".ts?showPreview=1&key=" + + FileUtil.getVideoImgDownloadKey(t.replace(GlobalConfig.m3u8ConvertUrlPlaceholder,""), key)).append("\r\n"); + }else if (t.indexOf("/mu/") < 0){ + String tsMuName = path.substring(path.lastIndexOf("/")+1).replace(".m3u8", ""); + String replaceUrl = path.replace("/private/cloud/", "/mu/m3u8/").replace(".m3u8", "")+ "/" + tsMuName; + result.append(GlobalConfig.m3u8ConvertUrlPlaceholder + "/api/disk/video/img/"+( key + "_"+ i)+".ts?showPreview=1&key=" + + FileUtil.getVideoImgDownloadKey(t.replace(tsMuName, replaceUrl), key)).append("\r\n"); + }else if (t.indexOf(GlobalConfig.oldInnerServer) >= 0){ + result.append(GlobalConfig.oldInnerServer + "/api/disk/video/img/"+( key + "_"+ i)+".ts?showPreview=1&key=" + + FileUtil.getVideoImgDownloadKey(t.replace(GlobalConfig.oldInnerServer,""), key)).append("\r\n"); + } + i ++; + }else { + result.append(t).append("\r\n"); + } + } + br.close(); + return result.toString(); + } catch (FileNotFoundException e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 notFound, path: " + path); + } catch (IOException e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 IOError, path: " + path); + } catch (Exception e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 error, path: " + path); + } finally { + // 关闭流 + if (br == null) { + try { + br.close(); + } catch (IOException e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 close , path: " + path); + } catch (Exception e) { + LogUtil.error(e, "getM3u8LineList 读取文件失败 close error, path: " + path); + } + } + } + return ""; + } + + public static String getShowAvatarUrl(String path, String name){ + if (path.indexOf("http") == 0){ + return path; + } + return getShowImageUrl(path, "avatar_" + name + ".jpg"); + } + public static String getShowImageUrl(String path, String name){ + String viewKey = getVideoImgDownloadKey(path); + return GlobalConfig.show_img_api_key + name + "?showPreview=1&key=" + viewKey; + } + public static String getShowImageUrlDown(String path, String name){ + String viewKey = getVideoImgDownloadKey(path, ""); + return GlobalConfig.show_img_api_key + name + "?showPreview=1&isDown=1&key=" + viewKey; + } + + public static String replaceIllegalSymbolAll(String fileName) { + //替换非法字符 + fileName = replaceIllegalSymbol(fileName); + //url encode + try { + fileName = URLEncoder.encode(fileName, "UTF-8"); + fileName = fileName.replaceAll("\\+", "%20"); + } catch (Exception e) { + LogUtil.error(e, "下载文件,编码失败"); + } + return fileName; + } +} diff --git a/src/main/java/com/svnlan/home/utils/GifDecoder.java b/src/main/java/com/svnlan/home/utils/GifDecoder.java new file mode 100644 index 0000000..c91417b --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/GifDecoder.java @@ -0,0 +1,630 @@ +package com.svnlan.home.utils; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import static java.lang.System.arraycopy; +/** + * @Description: + * @Author: sulijuan + * @Date: 2023/3/7 15:05 + * @Modified: + */ +public final class GifDecoder { + static final class BitReader { + private int nextBitToRead; + private int numberOfBitsToRead; + private int bitMask; // Used to kill unwanted higher bits + private byte[] bytes; // Data array + + // To avoid costly bounds checks, 'in' needs 2 more 0-bytes at the end + private void init(final byte[] bytes) { + this.bytes = bytes; + nextBitToRead = 0; + } + + private int read() { + // Byte indices: (bitPos / 8), (bitPos / 8) + 1, (bitPos / 8) + 2 + int byteIndex = nextBitToRead >>> 3; // Byte = bit / 8 + int bitsToShiftRight = nextBitToRead & 7; // & 7 is the same as MODULO 8 + int byte0, byte1, byte2; + byte0 = bytes[byteIndex++] & 0xFF; // & 0xFF gives us the unsigned values + byte1 = bytes[byteIndex++] & 0xFF; + byte2 = bytes[byteIndex] & 0xFF; + // Glue the bytes together, don't do more shifting than necessary + int buffer = ((byte2 << 8 | byte1) << 8 | byte0) >>> bitsToShiftRight; + nextBitToRead += numberOfBitsToRead; + return buffer & bitMask; // Kill the unwanted higher bits + } + + private void setNumberOfBitsToRead(final int numberOfBitsToRead) { + this.numberOfBitsToRead = numberOfBitsToRead; + bitMask = (1 << numberOfBitsToRead) - 1; + } + } + + static final class CodeTable { + private final int[][] table; // Maps codes to lists of colors + private int initTableSize; // Number of colors +2 for CLEAR + EOI + private int initCodeSize; // Initial code size + private int initCodeLimit; // First code limit + private int codeSize; // Current code size, maximum is 12 bits + private int nextCode; // Next available code for a new entry + private int nextCodeLimit; // Increase codeSize when nextCode == limit + private BitReader bitReader; // Notify when code sizes increases + + public CodeTable() { + table = new int[4096][1]; + } + + private int add(final int[] indices) { + if (nextCode < 4096) { + if (nextCode == nextCodeLimit && codeSize < 12) { + codeSize++; // Max code size is 12 + bitReader.setNumberOfBitsToRead(codeSize); + nextCodeLimit = (1 << codeSize) - 1; // 2^codeSize - 1 + } + table[nextCode++] = indices; + } + return codeSize; + } + + private int clear() { + codeSize = initCodeSize; + bitReader.setNumberOfBitsToRead(codeSize); + nextCodeLimit = initCodeLimit; + nextCode = initTableSize; // Don't recreate table, reset pointer + return codeSize; + } + + private void init(final GifFrame fr, final int[] activeColTbl, final BitReader br) { + this.bitReader = br; + final int numColors = activeColTbl.length; + initCodeSize = fr.firstCodeSize; + initCodeLimit = (1 << initCodeSize) - 1; // 2^initCodeSize - 1 + initTableSize = fr.endOfInfoCode + 1; + nextCode = initTableSize; + for (int c = numColors - 1; c >= 0; c--) { + table[c][0] = activeColTbl[c]; // Translated color + } // A gap may follow with no colors assigned if numCols < CLEAR + table[fr.clearCode] = new int[]{fr.clearCode}; // CLEAR + table[fr.endOfInfoCode] = new int[]{fr.endOfInfoCode}; // EOI + // Locate transparent color in code table and set to 0 + if (fr.transpColFlag && fr.transpColIndex < numColors) { + table[fr.transpColIndex][0] = 0; + } + } + } + + final class GifFrame { + // Graphic control extension (optional) + // Disposal: 0=NO_ACTION, 1=NO_DISPOSAL, 2=RESTORE_BG, 3=RESTORE_PREV + private int disposalMethod; // 0-3 as above, 4-7 undefined + private boolean transpColFlag; // 1 Bit + private int delay; // Unsigned, LSByte first, n * 1/100 * s + private int transpColIndex; // 1 Byte + // Image descriptor + private int x; // Position on the canvas from the left + private int y; // Position on the canvas from the top + private int w; // May be smaller than the base image + private int h; // May be smaller than the base image + private int wh; // width * height + private boolean hasLocColTbl; // Has local color table? 1 Bit + private boolean interlaceFlag; // Is an interlace image? 1 Bit + @SuppressWarnings("unused") + private boolean sortFlag; // True if local colors are sorted, 1 Bit + private int sizeOfLocColTbl; // Size of the local color table, 3 Bits + private int[] localColTbl; // Local color table (optional) + // Image data + private int firstCodeSize; // LZW minimum code size + 1 for CLEAR & EOI + private int clearCode; + private int endOfInfoCode; + private byte[] data; // Holds LZW encoded data + private BufferedImage img; // Full drawn image, not just the frame area + } + + public final class GifImage { + public String header; // Bytes 0-5, GIF87a or GIF89a + private int w; // Unsigned 16 Bit, the least significant byte first + private int h; // Unsigned 16 Bit, the least significant byte first + private int wh; // Image width * image height + public boolean hasGlobColTbl; // 1 Bit + public int colorResolution; // 3 Bits + public boolean sortFlag; // True if global colors are sorted, 1 Bit + public int sizeOfGlobColTbl; // 2^(val(3 Bits) + 1), see spec + public int bgColIndex; // Background color index, 1 Byte + public int pxAspectRatio; // Pixel aspect ratio, 1 Byte + public int[] globalColTbl; // Global color table + private final List frames = new ArrayList(64); + public String appId = ""; // 8 Bytes at in[i+3], usually "NETSCAPE" + public String appAuthCode = ""; // 3 Bytes at in[i+11], usually "2.0" + public int repetitions = 0; // 0: infinite loop, N: number of loops + private BufferedImage img = null; // Currently, drawn frame + private final BitReader bits = new BitReader(); + private final CodeTable codes = new CodeTable(); + private Graphics2D g; + + private int[] decode(final GifFrame fr, final int[] activeColTbl) { + codes.init(fr, activeColTbl, bits); + bits.init(fr.data); // Incoming codes + final int clearCode = fr.clearCode, endCode = fr.endOfInfoCode; + final int[] out = new int[wh]; // Target image pixel array + final int[][] tbl = codes.table; // Code table + int outPos = 0; // Next pixel position in the output image array + codes.clear(); // Init code table + bits.read(); // Skip leading clear code + int code = bits.read(); // Read first code + int[] pixels = tbl[code]; // Output pixel for first code + arraycopy(pixels, 0, out, outPos, pixels.length); + outPos += pixels.length; + try { + while (true) { + final int prevCode = code; + code = bits.read(); // Get next code in stream + if (code == clearCode) { // After a CLEAR table, there is + codes.clear(); // no previous code, we need to read + code = bits.read(); // a new one + pixels = tbl[code]; // Output pixels + arraycopy(pixels, 0, out, outPos, pixels.length); + outPos += pixels.length; + continue; // Back to the loop with a valid previous code + } else if (code == endCode) { + break; + } + final int[] prevVals = tbl[prevCode]; + final int[] prevValsAndK = new int[prevVals.length + 1]; + arraycopy(prevVals, 0, prevValsAndK, 0, prevVals.length); + if (code < codes.nextCode) { // Code table contains code + pixels = tbl[code]; // Output pixels + arraycopy(pixels, 0, out, outPos, pixels.length); + outPos += pixels.length; + prevValsAndK[prevVals.length] = tbl[code][0]; // K + } else { + prevValsAndK[prevVals.length] = prevVals[0]; // K + arraycopy(prevValsAndK, 0, out, outPos, prevValsAndK.length); + outPos += prevValsAndK.length; + } + codes.add(prevValsAndK); // Previous indices + K + } + } catch (final ArrayIndexOutOfBoundsException ignored) { + } + return out; + } + + private int[] deinterlace(final int[] src, final GifFrame fr) { + final int w = fr.w, h = fr.h, wh = fr.wh; + final int[] dest = new int[src.length]; + // Interlaced images are organized in 4 sets of pixel lines + final int set2Y = (h + 7) >>> 3; // Line no. = ceil(h/8.0) + final int set3Y = set2Y + ((h + 3) >>> 3); // ceil(h-4/8.0) + final int set4Y = set3Y + ((h + 1) >>> 2); // ceil(h-2/4.0) + // Sets' start indices in source array + final int set2 = w * set2Y, set3 = w * set3Y, set4 = w * set4Y; + // Line skips in destination array + final int w2 = w << 1, w4 = w2 << 1, w8 = w4 << 1; + // Group 1 contains every 8th line starting from 0 + int from = 0, to = 0; + for (; from < set2; from += w, to += w8) { + arraycopy(src, from, dest, to, w); + } // Group 2 contains every 8th line starting from 4 + for (to = w4; from < set3; from += w, to += w8) { + arraycopy(src, from, dest, to, w); + } // Group 3 contains every 4th line starting from 2 + for (to = w2; from < set4; from += w, to += w4) { + arraycopy(src, from, dest, to, w); + } // Group 4 contains every 2nd line starting from 1 (biggest group) + for (to = w; from < wh; from += w, to += w2) { + arraycopy(src, from, dest, to, w); + } + return dest; // All pixel lines have now been rearranged + } + + private void drawFrame(final GifFrame fr) { + // Determine the color table that will be active for this frame + final int[] activeColTbl = fr.hasLocColTbl ? fr.localColTbl : globalColTbl; + // Get pixels from data stream + int[] pixels = decode(fr, activeColTbl); + if (fr.interlaceFlag) { + pixels = deinterlace(pixels, fr); // Rearrange pixel lines + } + // Create image of type 2=ARGB for frame area + final BufferedImage frame = new BufferedImage(fr.w, fr.h, 2); + arraycopy(pixels, 0, ((DataBufferInt) frame.getRaster().getDataBuffer()).getData(), 0, fr.wh); + // Draw frame area on top of working image + g.drawImage(frame, fr.x, fr.y, null); + + // Visualize frame boundaries during testing + // if (DEBUG_MODE) { + // if (prev != null) { + // g.setColor(Color.RED); // Previous frame color + // g.drawRect(prev.x, prev.y, prev.w - 1, prev.h - 1); + // } + // g.setColor(Color.GREEN); // New frame color + // g.drawRect(fr.x, fr.y, fr.w - 1, fr.h - 1); + // } + + // Keep a copy of the previous frame's pixels in case we need to restore the frame + int[] prevPx = new int[wh]; + arraycopy(((DataBufferInt) img.getRaster().getDataBuffer()).getData(), 0, prevPx, 0, wh); + + // Create another copy for the end user to not expose internal state + fr.img = new BufferedImage(w, h, 2); // 2 = ARGB + arraycopy(prevPx, 0, ((DataBufferInt) fr.img.getRaster().getDataBuffer()).getData(), 0, wh); + + // Handle disposal of current frame + if (fr.disposalMethod == 2) { + // Restore to background color (clear frame area only) + g.clearRect(fr.x, fr.y, fr.w, fr.h); + } else if (fr.disposalMethod == 3) { + // Restore previous frame + arraycopy(prevPx, 0, ((DataBufferInt) img.getRaster().getDataBuffer()).getData(), 0, wh); + } + } + + /** + * Returns the background color of the first frame in this GIF image. If + * the frame has a local color table, the returned color will be from + * that table. If not, the color will be from the global color table. + * Returns 0 if there is neither a local nor a global color table. + * + * @return 32 bit ARGB color in the form 0xAARRGGBB + */ + public final int getBackgroundColor() { + final GifFrame frame = frames.get(0); + if (frame.hasLocColTbl) { + return frame.localColTbl[bgColIndex]; + } else if (hasGlobColTbl) { + return globalColTbl[bgColIndex]; + } + return 0; + } + + /** + * If not 0, the delay specifies how many hundredths (1/100) of a second + * to wait before displaying the frame after the current frame. + * + * @param index Index of the current frame, 0 to N-1 + * @return Delay as number of hundredths (1/100) of a second + */ + public final int getDelay(final int index) { + return frames.get(index).delay; + } + + /** + * @param index Index of the frame to return as image, starting from 0. + * For incremental calls such as [0, 1, 2, ...] the method's + * run time is O(1) as only one frame is drawn per call. For + * random access calls such as [7, 12, ...] the run time is + * O(N+1) with N being the number of previous frames that + * need to be drawn before N+1 can be drawn on top. Once a + * frame has been drawn it is being cached and the run time + * is more or less O(0) to retrieve it from the list. + * @return A BufferedImage for the specified frame. + */ + public BufferedImage getFrame(final int index) { + if (img == null) { // Init + img = new BufferedImage(w, h, 2); // 2 = ARGB + g = img.createGraphics(); + g.setBackground(new Color(0, true)); // Transparent color + } + GifFrame fr = frames.get(index); + if (fr.img == null) { + // Draw all frames until and including the requested frame + for (int i = 0; i <= index; i++) { + fr = frames.get(i); + if (fr.img == null) { + drawFrame(fr); + } + } + } + return fr.img; + } + + /** + * @return The number of frames contained in this GIF image + */ + public final int getFrameCount() { + return frames.size(); + } + + /** + * @return The height of the GIF image + */ + public final int getHeight() { + return h; + } + + /** + * @return The width of the GIF image + */ + public final int getWidth() { + return w; + } + } + + static final boolean DEBUG_MODE = false; + + /** + * @param in Raw image data as a byte[] array + * @return A GifImage object exposing the properties of the GIF image. + * @throws IOException If the image violates the GIF specification or is truncated. + */ + public static GifImage read(final byte[] in) throws IOException { + final GifDecoder decoder = new GifDecoder(); + final GifImage img = decoder.new GifImage(); + GifFrame frame = null; // Currently open frame + int pos = readHeader(in, img); // Read header, get next byte position + pos = readLogicalScreenDescriptor(img, in, pos); + if (img.hasGlobColTbl) { + img.globalColTbl = new int[img.sizeOfGlobColTbl]; + pos = readColTbl(in, img.globalColTbl, pos); + } + while (pos < in.length) { + final int block = in[pos] & 0xFF; + switch (block) { + case 0x21: // Extension introducer + if (pos + 1 >= in.length) { + throw new IOException("Unexpected end of file."); + } + switch (in[pos + 1] & 0xFF) { + case 0xFE: // Comment extension + pos = readTextExtension(in, pos); + break; + case 0xFF: // Application extension + pos = readAppExt(img, in, pos); + break; + case 0x01: // Plain text extension + frame = null; // End of current frame + pos = readTextExtension(in, pos); + break; + case 0xF9: // Graphic control extension + if (frame == null) { + frame = decoder.new GifFrame(); + img.frames.add(frame); + } + pos = readGraphicControlExt(frame, in, pos); + break; + default: + throw new IOException("Unknown extension at " + pos); + } + break; + case 0x2C: // Image descriptor + if (frame == null) { + frame = decoder.new GifFrame(); + img.frames.add(frame); + } + pos = readImgDescr(frame, in, pos); + if (frame.hasLocColTbl) { + frame.localColTbl = new int[frame.sizeOfLocColTbl]; + pos = readColTbl(in, frame.localColTbl, pos); + } + pos = readImgData(frame, in, pos); + frame = null; // End of current frame + break; + case 0x3B: // GIF Trailer + return img; // Found trailer, finished reading. + default: + // Unknown block. The image is corrupted. Strategies: a) Skip + // and wait for a valid block. Experience: It'll get worse. b) + // Throw exception. c) Return gracefully if we are almost done + // processing. The frames we have so far should be error-free. + final double progress = 1.0 * pos / in.length; + if (progress < 0.9) { + throw new IOException("Unknown block at: " + pos); + } + pos = in.length; // Exit loop + } + } + return img; + } + + /** + * @param is Image data as input stream. This method will read from the + * input stream's current position. It will not reset the + * position before reading and won't reset or close the stream + * afterwards. Call these methods before and after calling this + * method as needed. + * @return A GifImage object exposing the properties of the GIF image. + * @throws IOException If an I/O error occurs, the image violates the GIF + * specification or the GIF is truncated. + */ + public static GifImage read(final InputStream is) throws IOException { + final byte[] data = new byte[is.available()]; + is.read(data, 0, data.length); + return read(data); + } + + /** + * @param img GIF image + * @param in Raw data + * @param i Index of the first byte of the application extension + * @return Index of the first byte after this extension + */ + static int readAppExt(final GifImage img, final byte[] in, int i) { + img.appId = new String(in, i + 3, 8); // should be "NETSCAPE" + img.appAuthCode = new String(in, i + 11, 3); // should be "2.0" + i += 14; // Go to sub-block size, it's value should be 3 + final int subBlockSize = in[i] & 0xFF; + // The only app extension widely used is NETSCAPE, it's got 3 data bytes + if (subBlockSize == 3) { + // in[i+1] should have value 01, in[i+5] should be block terminator + img.repetitions = in[i + 2] & 0xFF | in[i + 3] & 0xFF << 8; // Short + return i + 5; + } // Skip unknown application extensions + while ((in[i] & 0xFF) != 0) { // While sub-block size != 0 + i += (in[i] & 0xFF) + 1; // Skip to next sub-block + } + return i + 1; + } + + /** + * @param in Raw data + * @param colors Pre-initialized target array to store ARGB colors + * @param i Index of the color table's first byte + * @return Index of the first byte after the color table + */ + static int readColTbl(final byte[] in, final int[] colors, int i) { + final int numColors = colors.length; + for (int c = 0; c < numColors; c++) { + final int a = 0xFF; // Alpha 255 (opaque) + final int r = in[i++] & 0xFF; // 1st byte is red + final int g = in[i++] & 0xFF; // 2nd byte is green + final int b = in[i++] & 0xFF; // 3rd byte is blue + colors[c] = ((a << 8 | r) << 8 | g) << 8 | b; + } + return i; + } + + /** + * @param fr GIF frame + * @param in Raw data + * @param i Index of the extension introducer + * @return Index of the first byte after this block + */ + static int readGraphicControlExt(final GifFrame fr, final byte[] in, final int i) { + fr.disposalMethod = (in[i + 3] & 0b00011100) >>> 2; // Bits 4-2 + fr.transpColFlag = (in[i + 3] & 1) == 1; // Bit 0 + fr.delay = in[i + 4] & 0xFF | (in[i + 5] & 0xFF) << 8; // 16 bit LSB + fr.transpColIndex = in[i + 6] & 0xFF; // Byte 6 + return i + 8; // Skipped byte 7 (blockTerminator), as it's always 0x00 + } + + /** + * @param in Raw data + * @param img The GifImage object that is currently read + * @return Index of the first byte after this block + * @throws IOException If the GIF header/trailer is missing, incomplete or unknown + */ + static int readHeader(final byte[] in, final GifImage img) throws IOException { + if (in.length < 6) { // Check first 6 bytes + throw new IOException("Image is truncated."); + } + img.header = new String(in, 0, 6); + if (!img.header.equals("GIF87a") && !img.header.equals("GIF89a")) { + throw new IOException("Invalid GIF header."); + } + return 6; + } + + /** + * @param fr The GIF frame to whom this image descriptor belongs + * @param in Raw data + * @param i Index of the first byte of this block, i.e. the minCodeSize + * @return Byte index + */ + static int readImgData(final GifFrame fr, final byte[] in, int i) { + final int fileSize = in.length; + final int minCodeSize = in[i++] & 0xFF; // Read code size, go to block + final int clearCode = 1 << minCodeSize; // CLEAR = 2^minCodeSize + fr.firstCodeSize = minCodeSize + 1; // Add 1 bit for CLEAR and EOI + fr.clearCode = clearCode; + fr.endOfInfoCode = clearCode + 1; + final int imgDataSize = readImgDataSize(in, i); + final byte[] imgData = new byte[imgDataSize + 2]; + int imgDataPos = 0; + int subBlockSize = in[i] & 0xFF; + while (subBlockSize > 0) { // While block has data + try { // Next line may throw exception if sub-block size is fake + final int nextSubBlockSizePos = i + subBlockSize + 1; + final int nextSubBlockSize = in[nextSubBlockSizePos] & 0xFF; + arraycopy(in, i + 1, imgData, imgDataPos, subBlockSize); + imgDataPos += subBlockSize; // Move output data position + i = nextSubBlockSizePos; // Move to next sub-block size + subBlockSize = nextSubBlockSize; + } catch (final Exception e) { + // Sub-block exceeds file end, only use remaining bytes + subBlockSize = fileSize - i - 1; // Remaining bytes + arraycopy(in, i + 1, imgData, imgDataPos, subBlockSize); + imgDataPos += subBlockSize; // Move output data position + i += subBlockSize + 1; // Move to next sub-block size + break; + } + } + fr.data = imgData; // Holds LZW encoded data + i++; // Skip last sub-block size, should be 0 + return i; + } + + static int readImgDataSize(final byte[] in, int i) { + final int fileSize = in.length; + int imgDataPos = 0; + int subBlockSize = in[i] & 0xFF; + while (subBlockSize > 0) { // While block has data + try { // Next line may throw exception if sub-block size is fake + final int nextSubBlockSizePos = i + subBlockSize + 1; + final int nextSubBlockSize = in[nextSubBlockSizePos] & 0xFF; + imgDataPos += subBlockSize; // Move output data position + i = nextSubBlockSizePos; // Move to next sub-block size + subBlockSize = nextSubBlockSize; + } catch (final Exception e) { + // Sub-block exceeds file end, only use remaining bytes + subBlockSize = fileSize - i - 1; // Remaining bytes + imgDataPos += subBlockSize; // Move output data position + break; + } + } + return imgDataPos; + } + + /** + * @param fr The GIF frame to whom this image descriptor belongs + * @param in Raw data + * @param i Index of the image separator, i.e. the first block byte + * @return Index of the first byte after this block + */ + static int readImgDescr(final GifFrame fr, final byte[] in, int i) { + fr.x = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 1-2: left + fr.y = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 3-4: top + fr.w = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 5-6: width + fr.h = in[++i] & 0xFF | (in[++i] & 0xFF) << 8; // Byte 7-8: height + fr.wh = fr.w * fr.h; + final byte b = in[++i]; // Byte 9 is a packed byte + fr.hasLocColTbl = (b & 0b10000000) >>> 7 == 1; // Bit 7 + fr.interlaceFlag = (b & 0b01000000) >>> 6 == 1; // Bit 6 + fr.sortFlag = (b & 0b00100000) >>> 5 == 1; // Bit 5 + final int colTblSizePower = (b & 7) + 1; // Bits 2-0 + fr.sizeOfLocColTbl = 1 << colTblSizePower; // 2^(N+1), As per the spec + return ++i; + } + + /** + * @param img GIF image + * @param i Start index of this block. + * @return Index of the first byte after this block. + */ + static int readLogicalScreenDescriptor(final GifImage img, final byte[] in, final int i) { + img.w = in[i] & 0xFF | (in[i + 1] & 0xFF) << 8; // 16 bit, LSB 1st + img.h = in[i + 2] & 0xFF | (in[i + 3] & 0xFF) << 8; // 16 bit + img.wh = img.w * img.h; + final byte b = in[i + 4]; // Byte 4 is a packed byte + img.hasGlobColTbl = (b & 0b10000000) >>> 7 == 1; // Bit 7 + final int colResPower = ((b & 0b01110000) >>> 4) + 1; // Bits 6-4 + img.colorResolution = 1 << colResPower; // 2^(N+1), As per the spec + img.sortFlag = (b & 0b00001000) >>> 3 == 1; // Bit 3 + final int globColTblSizePower = (b & 7) + 1; // Bits 0-2 + img.sizeOfGlobColTbl = 1 << globColTblSizePower; // 2^(N+1), see spec + img.bgColIndex = in[i + 5] & 0xFF; // 1 Byte + img.pxAspectRatio = in[i + 6] & 0xFF; // 1 Byte + return i + 7; + } + + /** + * @param in Raw data + * @param pos Index of the extension introducer + * @return Index of the first byte after this block + */ + static int readTextExtension(final byte[] in, final int pos) { + int i = pos + 2; // Skip extension introducer and label + int subBlockSize = in[i++] & 0xFF; + while (subBlockSize != 0 && i < in.length) { + i += subBlockSize; + subBlockSize = in[i++] & 0xFF; + } + return i; + } +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/utils/ImageDUtil.java b/src/main/java/com/svnlan/home/utils/ImageDUtil.java new file mode 100644 index 0000000..aac2223 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ImageDUtil.java @@ -0,0 +1,386 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.Result; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import com.svnlan.utils.StringUtil; +import net.coobird.thumbnailator.Thumbnails; +import org.apache.commons.io.IOUtils; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; +import javax.swing.*; +import java.awt.*; +import java.awt.geom.Area; +import java.awt.image.BufferedImage; +import java.awt.image.PixelGrabber; +import java.io.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @description: 图片工具类 + */ +public class ImageDUtil { + + /** + * @description: wmf转png图片(使用libreoffice命令) + * @param prefix + * @param sourceFilePath + * @param targetDir + * @return java.lang.Boolean + */ + public static Boolean wmfToPng(String prefix, String sourceFilePath, String targetDir) { + prefix += String.format("wmf转png(wmfToPng:%s)>>>", RandomUtil.getuuid()); + Boolean success = Boolean.TRUE; + + List convert = new ArrayList<>(); + convert.add("libreoffice"); + convert.add("--headless"); + convert.add("--convert-to"); + convert.add("png"); + convert.add(sourceFilePath); + convert.add("--outdir"); + convert.add(targetDir); + + ProcessBuilder builder = new ProcessBuilder(); + InputStream in = null; + try { + StringBuilder sb = new StringBuilder(); + for (String a : convert){ + sb.append(a); + sb.append(" "); + } + LogUtil.info(prefix + "转换命令: " + sb.toString()); + builder.command(convert); + Process process =builder.start(); + in = process.getErrorStream(); + String errorString = IOUtils.toString(in, "UTF-8"); + in.close(); + if (!StringUtil.isEmpty(errorString)){ + LogUtil.error(prefix + "转换返回错误信息" + errorString); + } + } catch (Exception e) { + LogUtil.error(e, prefix + "转换异常返回信息"); + success = false; + } finally { + if (in != null){ + try { + in.close(); + } catch (Exception e){ + LogUtil.error(prefix + "关闭流失败"); + } + } + } + return success; + } + + /** + * @description: 将PNG图片背景色变成透明 + * @param prefix + * @param imgSrc + * @return java.awt.image.BufferedImage + */ + public static BufferedImage transferAlpha2BufferedImage(String prefix, String imgSrc) { + File file = new File(imgSrc); + InputStream is = null; + BufferedImage bufferedImage = null; + prefix += String.format("将PNG图片背景色变成透明(transferAlpha2BufferedImage:%s)>>>", RandomUtil.getuuid()); + try { + is = new FileInputStream(file); + // 如果是MultipartFile类型,那么自身也有转换成流的方法:is = file.getInputStream(); + BufferedImage bi = ImageIO.read(is); + Image image = (Image) bi; + ImageIcon imageIcon = new ImageIcon(image); + bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), + BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics(); + g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver()); + int alpha = 0; + for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) { + for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) { + int rgb = bufferedImage.getRGB(j2, j1); + + int R = (rgb & 0xff0000) >> 16; + int G = (rgb & 0xff00) >> 8; + int B = (rgb & 0xff); + if (((255 - R) < 30) && ((255 - G) < 30) && ((255 - B) < 30)) { + rgb = ((alpha) << 24) | (rgb & 0x00ffffff); + } + bufferedImage.setRGB(j2, j1, rgb); + } + } + g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver()); + } catch (Exception e) { + LogUtil.error(e,prefix + "发生异常"); + bufferedImage = null; + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + //不用做什么 + } + } + } + return bufferedImage; + } + + /** + * @description: 将Image图像中的透明/不透明部分转换为Shape图形 + * @param img 图片信息 + * @param transparent 是否透明 + * @return java.awt.Shape + */ + public static Shape getImageShape(Image img, boolean transparent) throws InterruptedException { + ArrayList x = new ArrayList(); + ArrayList y = new ArrayList(); + int width = img.getWidth(null); + int height = img.getHeight(null); + + // 首先获取图像所有的像素信息 + PixelGrabber pgr = new PixelGrabber(img, 0, 0, -1, -1, true); + pgr.grabPixels(); + int pixels[] = (int[]) pgr.getPixels(); + + // 循环像素 + for (int i = 0; i < pixels.length; i++) { + // 筛选,将不透明的像素的坐标加入到坐标ArrayList x和y中 + int alpha = (pixels[i] >> 24) & 0xff; + if (alpha == 0) { + continue; + } else { + x.add(i % width > 0 ? i % width - 1 : 0); + y.add(i % width == 0 ? (i == 0 ? 0 : i / width - 1) : i / width); + } + } + + // 建立图像矩阵并初始化(0为透明,1为不透明) + int[][] matrix = new int[height][width]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + matrix[i][j] = 0; + } + } + + // 导入坐标ArrayList中的不透明坐标信息 + for (int c = 0; c < x.size(); c++) { + matrix[y.get(c)][x.get(c)] = 1; + } + + /* + * 逐一水平"扫描"图像矩阵的每一行,将透明(这里也可以取不透明的)的像素生成为Rectangle, + * 再将每一行的Rectangle通过Area类的rec对象进行合并, 最后形成一个完整的Shape图形 + */ + Area rec = new Area(); + int temp = 0; + //生成Shape时是1取透明区域还是取非透明区域的flag + int flag = transparent ? 0 : 1; + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + if (matrix[i][j] == flag) { + if (temp == 0) + temp = j; + else if (j == width) { + if (temp == 0) { + Rectangle rectemp = new Rectangle(j, i, 1, 1); + rec.add(new Area(rectemp)); + } else { + Rectangle rectemp = new Rectangle(temp, i, j - temp, 1); + rec.add(new Area(rectemp)); + temp = 0; + } + } + } else { + if (temp != 0) { + Rectangle rectemp = new Rectangle(temp, i, j - temp, 1); + rec.add(new Area(rectemp)); + temp = 0; + } + } + } + temp = 0; + } + return rec; + } + + /** + * @description: 图片裁切处理 + * @param prefix + * @param bufferedImage + * @param x + * @param y + * @param width + * @param height + * @return java.awt.image.BufferedImage + */ + public static BufferedImage cutImage(String prefix, BufferedImage bufferedImage, int x, + int y, int width, int height) { + Iterator readers = ImageIO.getImageReadersByFormatName("png"); + ImageReader reader = readers.next(); + ImageInputStream imageInputStream = null; + BufferedImage bi = null; + prefix += String.format("裁切图片(cutImage:%s)>>>", RandomUtil.getuuid()); + try { + //将BufferedImage转换为ImageInputStream + imageInputStream = bufferedImageToInputStream(bufferedImage); + reader.setInput(imageInputStream, true); + ImageReadParam param = reader.getDefaultReadParam(); + Rectangle rect = new Rectangle(x, y, width, height); + param.setSourceRegion(rect); + bi = reader.read(0, param); + } catch (Exception e) { + LogUtil.error(e,prefix + "发生异常"); + } finally { + if(null != imageInputStream) { + try { + imageInputStream.close(); + } catch (IOException e) { + //不用做什么 + } + } + } + return bi; + } + + /** + * @description: 将BufferedImage转换为ImageInputStream + * @param image + * @return javax.imageio.stream.ImageInputStream + */ + public static ImageInputStream bufferedImageToInputStream(BufferedImage image) throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageIO.write(image, "png", os); + ImageInputStream input = ImageIO.createImageInputStream(new ByteArrayInputStream(os.toByteArray())); + return input; + } + + /** + * @description: 抽取png图片的非透明内容区域裁切出来 + * @param prefix + * @param imgSrc + * @param imgTarget + * @return com.svnlan.homework.base.Result + */ + public static Result cutPngContent(String prefix, String imgSrc, String imgTarget) { + String code = "200"; + String message = ""; + Boolean success = Boolean.TRUE; + + //检测文件是否生成 + File file = new File(imgSrc); + int retryCount = 10; + int retryIndex = 0; + while (retryIndex < retryCount) { + if (!file.exists()) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + break; + } + retryIndex++; + } + + //将PNG图片背景色变成透明 + BufferedImage bufferedImage = ImageDUtil.transferAlpha2BufferedImage(prefix, imgSrc); + if(null == bufferedImage) { + code = "TransferAlphaFail"; + message = "将PNG图片背景色变成透明失败"; + } + + //得PNG图片非透明的区域 + Shape shape = null; + if("200".equals(code)) { + try { + shape = ImageDUtil.getImageShape(bufferedImage, false); + } catch (Exception e) { + code = "GetImageShapeFail"; + message = "得PNG图片非透明的区域(getImageShape)发生异常"; + LogUtil.error(e, prefix + message); + } + } + + //图片裁切最后写入 + if("200".equals(code)) { + try { + double shapeW = shape.getBounds().getWidth(); + double shapeH = shape.getBounds().getHeight(); + int width = (int) Math.ceil(shapeW); + int height = (int) Math.ceil(shapeH); + int x = (int) Math.ceil(shape.getBounds().getX()); + int y = (int) Math.ceil(shape.getBounds().getY()); + //图片裁切处理 + BufferedImage bi = ImageDUtil.cutImage(prefix, bufferedImage, x, y, width, height); + if(null == bi) { + code = "CutImageFail"; + message = "图片裁切处理发生异常"; + } + + if("200".equals(code)) { + //来源与目标是同一个,则先删除源文件 + if(imgSrc.equals(imgTarget)) { + File sourceFile = new File(imgSrc); + if (sourceFile.exists()) { + sourceFile.delete(); + } + } + + //将BufferedImage写入目标图片 + ImageIO.write(bi, "png", new FileOutputStream(imgTarget)); + } + } catch (Exception e) { + code = "WriteImageFail"; + message = "写入目标文件发生异常"; + LogUtil.error(e, prefix + "写入目标文件发生异常"); + } + } + if(!"200".equals(code)) { + success = Boolean.FALSE; + } + Result result = new Result(code, null); + return result; + } + + /** + * @description: 压缩图片 + * @param prefix + * @param sourcePath + * @param targetPath + * @param accuracy + * @param scale + * @return java.lang.Boolean + */ + public static Boolean compressImage(String prefix, String sourcePath, String targetPath, double accuracy, double scale) { + Boolean success = Boolean.TRUE; + byte[] imageBytes = null; + ByteArrayOutputStream out = null; + try { + out = new ByteArrayOutputStream(); + Thumbnails.of(sourcePath).scale(scale).outputQuality(accuracy).outputFormat("jpg").toOutputStream(out); + imageBytes = out.toByteArray(); + + //字节数组转存文件 + FileUtil.bytesToFile(prefix, imageBytes, targetPath); + } catch (IOException e) { + LogUtil.error(e,prefix + "按质量压缩图片失败,源文件:" + sourcePath + ",目标文件:" + targetPath); + success = Boolean.FALSE; + } finally { + if(null != out) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return success; + } + +} diff --git a/src/main/java/com/svnlan/home/utils/ImageToVideoUtil.java b/src/main/java/com/svnlan/home/utils/ImageToVideoUtil.java new file mode 100644 index 0000000..8aabef5 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ImageToVideoUtil.java @@ -0,0 +1,557 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.enums.EventEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.CommonSource; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.home.dto.VideoCutDto; +import com.svnlan.home.dto.convert.ConvertDTO; +import com.svnlan.home.utils.video.VideoGetUtil; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.HttpUtil; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/7 11:32 + */ + +@Component +public class ImageToVideoUtil { + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + ConvertUtil convertUtil; + @Resource + FileOptionTool fileOptionTool; + @Resource + IoSourceDao ioSourceDao; + + @Async(value = "asyncTaskExecutor") + public void execImageToVideo(String outPath, VideoCommonDto checkFileDTO, String redisKey, String fileType, String serverUrl, LoginUser loginUser, String redisProgressKey) { + + stringRedisTemplate.opsForValue().set(redisProgressKey, "10", 60, TimeUnit.SECONDS); + boolean check = imageToVideo(outPath, checkFileDTO, redisProgressKey); + if (!check){ + stringRedisTemplate.opsForValue().set(redisKey, "2", 1, TimeUnit.HOURS); + stringRedisTemplate.opsForValue().set(redisProgressKey, "100", 60, TimeUnit.SECONDS); + LogUtil.error("图片合成执行失败"); + return; + } + CommonSource parentSource = fileOptionTool.getSourceInfo(checkFileDTO.getSourceIDTo()); + // 查询文件夹下的文件、解析是否要重命名 + List sourceNameList = ioSourceDao.getSourceNameList(checkFileDTO.getSourceIDTo()); + Integer targetType = parentSource.getTargetType(); + String fileName = checkFileDTO.getName(); + CommonSource fileSource = new CommonSource(); + fileSource.setName(fileOptionTool.checkRepeatName(fileName, fileName, fileType, sourceNameList, 1)); + fileSource.setParentID(parentSource.getSourceID()); + fileSource.setParentLevel(parentSource.getParentLevel() + parentSource.getSourceID() + ","); + fileSource.setTargetType(targetType); + fileSource.setFileType(fileType); + fileSource.setPath(outPath); + fileSource.setDomain(serverUrl); + fileSource.setResolution(checkFileDTO.getResolution().replace("x","*")); + + Long size = 0L; + //最终文件 + File finalFile = new File(outPath); + + try { + size = finalFile.length(); + } catch (Exception e) { + LogUtil.error(e.getMessage(), " imagesToVideo 获取文件大小 失败 commonSource=" + JsonUtils.beanToJson(fileSource)); + } + fileSource.setSize(size); + fileSource.setHashMd5(""); + fileSource.setNeedHashMd5(1); + fileOptionTool.addCommonSource(loginUser.getUserID(), fileSource, EventEnum.mkfile); + + stringRedisTemplate.opsForValue().set(redisKey, "1", 1, TimeUnit.HOURS); + stringRedisTemplate.opsForValue().set(redisProgressKey, "100", 60, TimeUnit.SECONDS); + + /** 图片转视频-转码 */ + ConvertDTO convertDTO = new ConvertDTO(); + convertDTO.setBusId(fileSource.getSourceID()); + convertDTO.setBusType("cloud"); + convertDTO.setOtherType("imagesToVideo"); + fileSource.setDomain(serverUrl); + convertDTO.setDomain(serverUrl); + + convertUtil.doConvertMain(convertDTO, fileSource); + + } + public boolean imageToVideoOne(String outPath, VideoCommonDto videoCommonDto, String redisProgressKey, String setdar, int imgW, int imgH) { + // ffmpeg -loop 1 -t 8 -i images/001.jpg -stream_loop -1 -i 002225.mp3 -acodec aac -shortest -c:v libx264 -profile:v main -pix_fmt yuv420p -preset fast -y 98200.mp4 + List command = new ArrayList<>(); + String outPathTemp = outPath + "_temp.mp4"; + VideoCutDto dto = videoCommonDto.getCutList().get(0); + double length = dto.getLength() + dto.getDuration(); + command.add("ffmpeg"); + command.add("-loop"); + command.add("1"); + command.add("-t"); + command.add("" + length); + command.add("-i"); + String videoPathOrg = getOrgPath(dto.getpUrl(), dto.getFileName()); + command.add(videoPathOrg); + + /* + +ffmpeg -loop 1 -t 8 -i img/01.png -stream_loop -1 -i 002225.mp3 -filter_complex + "[0]scale=min(iw*720/ih\,1080):min(720\,ih*1080/iw),pad=1080:720:(1080-iw)/2:(720-ih)/2:#000000,setdar=1920/1080[v]" -map "[v]" -map "1:a" -acodec aac -shortest -c:v libx264 -profile:v main -pix_fmt yuv420p -preset fast -y be4267977fd431785b7ecd1691652970440_30074.mp4 + */ + + command.add("-filter_complex"); + command.add("\"[0]scale=min(iw*"+imgH+"/ih\\,"+imgW+"):min("+imgH+"\\,ih*"+imgW+"/iw),pad="+imgW+":"+imgH+":("+imgW+"-iw)/2:("+imgH+"-ih)/2:"+dto.getBackground()+",setdar="+setdar+"[v]\""); + command.add("-map"); + command.add("\"[v]\""); + //command.add("-map"); + //command.add("\"1:a\""); + command.add("-shortest"); + command.add("-c:v"); + command.add("libx264"); + command.add("-profile:v"); + command.add("main"); + command.add("-pix_fmt"); + command.add("yuv420p"); + command.add("-preset"); + command.add("fast"); + command.add("-y"); + command.add(outPathTemp);//文件输出路径,格式为 11.jpg + + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("covPic cmd:" + sb.toString()); + + String shellPath = outPath+".sh"; + File f = new File(shellPath); + try { + if (f.exists()){ + f.delete(); + } + f.createNewFile(); + }catch (Exception e){ + LogUtil.error(e, "imageToVideoOne创建shell文件失败!"); + return false; + } + + List cmd = cmdHB(outPathTemp, outPath, videoCommonDto, length); + + StringBuilder sb2 = new StringBuilder(); + for (String a : cmd){ + sb2.append(a); + sb2.append(" "); + } + + LogUtil.info("合成音频视频 cmd:" + sb2.toString()); + + + try { + // 创建一个PrintWriter对象,用于写入shell脚本到文件中 + PrintWriter writer = new PrintWriter(new FileWriter(shellPath)); + + // 编写shell脚本 + writer.println("#!/bin/sh"); + writer.println(sb.toString()); + writer.println(sb2.toString()); + + // 关闭PrintWriter对象 + writer.close(); + + // 输出提示信息,表示shell脚本写入成功 + LogUtil.info("imageToVideoOne Shell script written successfully."); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + // 创建一个ProcessBuilder对象,指定shell脚本文件的路径和名称 + ProcessBuilder pb = new ProcessBuilder("/bin/sh", shellPath); + + // 启动进程并执行shell脚本 + Process process = pb.start(); + dealStream(process); + process.waitFor(); + + // 输出提示信息,表示shell脚本执行成功 + LogUtil.info("imageToVideoOne Shell script executed successfully."); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + }finally { + try { + File ff = new File(shellPath); + File ffTmp = new File(outPathTemp); + if (ff.exists()){ + ff.delete(); + } + if (ffTmp.exists()){ + ffTmp.delete(); + } + }catch (Exception e){ + + } + } + + stringRedisTemplate.opsForValue().set(redisProgressKey, "90", 60, TimeUnit.SECONDS); + return true; + } + + public List cmdHB(String outPathTemp, String outPath, VideoCommonDto videoCommonDto, double length) { + List cmd = new ArrayList<>(); +// ffmpeg -i /uploads/private/cloud/2023_8/10/750f98111826435d8199ccd6ccaee27b1691657681851_30074.mp4 +// -stream_loop -1 -i /Cheerfulness.mp3 -t 5 -c:v copy -c:a aac -strict experimental /uploads/private/cloud/2023_8/10/750f98111826435d8199ccd6ccaee27b1691657681851_3007499999.mp4 + cmd.add("ffmpeg"); + cmd.add("-i"); + cmd.add(outPathTemp); + cmd.add("-stream_loop"); + cmd.add("-1"); + cmd.add("-i"); + if (videoCommonDto.getAudio().startsWith("/mp3/")){ + cmd.add(videoCommonDto.getAudio().replaceFirst("/mp3/", "/")); + }else { + cmd.add(getOrgPath(videoCommonDto.getAudio())); + } + cmd.add("-t"); + cmd.add("" + length); + cmd.add("-c:v"); + cmd.add("copy"); + cmd.add("-c:a"); + cmd.add("aac"); + cmd.add("-strict"); + cmd.add("experimental"); + + cmd.add(outPath);//文件输出路径,格式为 11.jpg + + return cmd; + } + + public boolean imageToVideo(String outPath, VideoCommonDto videoCommonDto, String redisProgressKey) { + + int size = videoCommonDto.getCutList().size(); + String outPathTemp = outPath + "_temp.mp4"; + double length = 0; + int imgW = 0; + int imgH = 0; + String resolution = videoCommonDto.getResolution(); + if (ObjectUtils.isEmpty(resolution)){ + VideoCutDto cutDto = videoCommonDto.getCutList().get(0); + String filePath = getOrgPath(cutDto.getpUrl(), cutDto.getFileName()); + File imageFile = new File(filePath); + if (!imageFile.exists()){ + LogUtil.error("ImageToVideo 缩略图处理失败,原图不存在" + filePath); + return false; + } + resolution = ImageUtil.getResolution(filePath); + } + List whList = null; + if (resolution.indexOf("x")>=0){ + whList = Arrays.asList(resolution.split("x")).stream().map(Integer::valueOf).collect(Collectors.toList()); + }else { + whList = Arrays.asList(resolution.split("\\*")).stream().map(Integer::valueOf).collect(Collectors.toList()); + } + imgW = whList.get(0); + imgH = whList.get(1); + if (imgW <= 0){ + imgW = 1280; + } + if (imgH <= 0){ + imgH = 720; + } + if(imgW%2==1){ + imgW = imgW-1; + } + if(imgH%2==1){ + imgH = imgH-1; + } + String setdar = "1/1"; + if (imgH != imgW){ + setdar = imgW+"/"+imgH; + } + + // ffmpeg -f image2 -i %d.jpeg output.mp4 + if (videoCommonDto.getCutList().size() == 1){ + return imageToVideoOne(outPath, videoCommonDto, redisProgressKey, setdar, imgW, imgH ); + } + /* + ffmpeg \ + -loop 1 -t 2 -i 1.jpg \ + -loop 1 -t 2 -i 2.jpg \ + -loop 1 -t 2 -i 3.jpg \ + -loop 1 -t 2 -i 4.jpg \ + -loop 1 -t 2 -i 5.jpg \ + -stream_loop -1 -i 1.mp3 -acodec aac \ + -filter_complex "[0:v]xfade=transition=circlecrop:duration=1:offset=1[v0]; [1:v]xfade=transition=circlecrop:duration=1:offset=1[v1]; [2:v]xfade=transition=circlecrop:duration=1:offset=1[v2]; [3:v]xfade=transition=circlecrop:duration=1:offset=1[v3]; [v0][v1][v2][v3]concat=n=4:v=1:a=0,format=yuv420p[v]" -map "[v]" \ + -map "5:a" \ + -shortest \ + -c:v libx264 \ + -y circlecrop.mp4 + 注释: + -stream_loop + 输入流循环的次数,0 表示无循环,-1 表示无限循环,即音乐循环播放。 + -acodec aac + 设置音频编解码为 acc 模式 + -map “[v]” + 将合成的视频输入流 v 指定为输出文件的源 + -map “5:a” + 将第6个文件作为视频音频文件 + -shortest + 最短的输入流结束时,完成编码。 + -c:v libx264 + 输出视频编码格式 + -pix_fmt yuv420p + 设置像素格式为 yuv420p + xfade transition 转场 duration 特效持续时间 offset =(loop-duration) + + ffmpeg -loop 1 -t 4 -i images/001.jpg -loop 1 -t 4 -i images/002.jpg -loop 1 -t 3 -i images/003.jpg -stream_loop -1 -i 002225.mp3 -acodec aac + -filter_complex "[0]scale=min(iw*720/ih\,400):min(720\,ih*400/iw),pad=400:720:(400-iw)/2:(720-ih)/2:blue[p0];[1]scale=min(iw*720/ih\,400):min(720\,ih*400/iw),pad=400:720:(400-iw)/2:(720-ih)/2:blue[p1];[2]scale=min(iw*720/ih\,400):min(720\,ih*400/iw),pad=400:720:(400-iw)/2:(720-ih)/2:blue[p2];[p0]split[v_sp_0_0][v_sp_0_1];[v_sp_0_0]trim=0:3[v_tr_0_0];[v_sp_0_1]trim=3:4[v_tr_0_1];[v_tr_0_1]setpts=PTS-STARTPTS[v_st_0];[p1]split[v_sp_1_0][v_sp_1_1];[v_sp_1_0]trim=0:3[v_tr_1_0];[v_sp_1_1]trim=3:4[v_tr_1_1];[v_tr_1_1]setpts=PTS-STARTPTS[v_st_1];[v_st_0][v_tr_1_0]xfade=transition=circlecrop:duration=1[v0];[v_st_1][p2]xfade=transition=circlecrop:duration=1[v1];[v_tr_0_0][v0][v1]concat=n=3[v]" -map "[v]" -map "3:a" -t 8 -shortest -c:v libx264 -profile:v main -pix_fmt yuv420p -preset fast -y out.mp4 + */ + String shellPath = outPath+".sh"; + File f = new File(shellPath); + try { + if (f.exists()){ + f.delete(); + } + f.createNewFile(); + }catch (Exception e){ + LogUtil.error(e, "创建shell文件失败!"); + return false; + } + + + + List cutList = videoCommonDto.getCutList(); + List command = new ArrayList<>(); + StringBuilder scaleConmplex = new StringBuilder(); + command.add("ffmpeg"); + int k = 0; + for (VideoCutDto dto : cutList){ + scaleConmplex.append("["+k+"]scale=min(iw*"+imgH+"/ih\\,"+imgW+"):min("+imgH+"\\,ih*"+imgW+"/iw),pad="+imgW+":"+imgH+":("+imgW+"-iw)/2:("+imgH+"-ih)/2:"+dto.getBackground()+",setdar="+setdar+"[p"+k+"];"); + command.add("-loop"); + command.add("1"); + command.add("-t"); + command.add("" + (dto.getLength() + dto.getDuration() )); + if (k == size-1){ + length = length + (dto.getLength()); + }else{ + length = length + (dto.getLength() + dto.getDuration() ); + } + + command.add("-i"); + String videoPathOrg = getOrgPath(dto.getpUrl(), dto.getFileName()); + command.add(videoPathOrg); + k++; + } + /* command.add("-stream_loop"); + command.add("-1"); + command.add("-i"); + if (videoCommonDto.getAudio().startsWith("/mp3/")){ + command.add(videoCommonDto.getAudio().replaceFirst("/mp3/", "/")); + }else { + command.add(getOrgPath(videoCommonDto.getAudio())); + } + command.add("-acodec"); + command.add("aac");*/ + command.add("-filter_complex"); + StringBuilder filterComplex = new StringBuilder(); + StringBuilder vComplex = new StringBuilder(); + StringBuilder xfadeComplex = new StringBuilder(); + int i = 0; + + for (VideoCutDto dto : cutList){ + if (ObjectUtils.isEmpty(dto.getTransition())){ + dto.setTransition("rectcrop"); + } + Double totalLength = (dto.getLength() + dto.getDuration() ); + if (i < size-1){ + if (i==0){ + filterComplex.append(scaleConmplex.toString()); + }else{ + vComplex.append("[v"+(i-1)+"]"); + xfadeComplex.append("[v_st_"+(i-1)+"][v_tr_"+(i)+"_0]xfade=transition="+ dto.getTransition() + ":duration="+dto.getLength()+"[v"+(i-1)+"];"); + } + filterComplex.append("[p"+i+"]split[v_sp_"+i+"_0][v_sp_"+i+"_1];"); + filterComplex.append("[v_sp_"+i+"_0]trim=0:"+dto.getLength()+"[v_tr_"+i+"_0];"); + filterComplex.append("[v_sp_"+i+"_1]trim="+dto.getLength()+":"+totalLength+"[v_tr_"+i+"_1];"); + filterComplex.append("[v_tr_"+i+"_1]setpts=PTS-STARTPTS[v_st_"+i+"];"); + }else { + vComplex.append("[v"+(i-1)+"]"); + xfadeComplex.append("[v_st_"+(i-1)+"][p"+(i)+"]xfade=transition="+ dto.getTransition() + ":duration="+dto.getLength()+"[v"+(i-1)+"];"); + filterComplex.append(xfadeComplex.toString()); + filterComplex.append("[v_tr_0_0]"+vComplex.toString() + "concat=n="+size+"[v]"); + } + i++; + } + command.add("\"" + filterComplex.toString() +"\""); + command.add("-map"); + command.add("\"[v]\""); + /*command.add("-map"); + command.add("\"" + size +":a\"");*/ + command.add("-shortest"); + command.add("-c:v"); + command.add("libx264"); + command.add("-profile:v"); + command.add("main"); + command.add("-pix_fmt"); + command.add("yuv420p"); + command.add("-preset"); + command.add("fast"); + command.add("-y"); + command.add(outPathTemp);//文件输出路径,格式为 11.jpg + + StringBuilder sb = new StringBuilder(); + for (String a : command) { + sb.append(a); + sb.append(" "); + } + LogUtil.info("ImageToVideo cmd:" + sb.toString()); + + List cmd = cmdHB(outPathTemp, outPath, videoCommonDto, length); + + StringBuilder sb2 = new StringBuilder(); + for (String a : cmd){ + sb2.append(a); + sb2.append(" "); + } + + LogUtil.info("合成音频视频 cmd:" + sb2.toString()); + + try { + // 创建一个PrintWriter对象,用于写入shell脚本到文件中 + PrintWriter writer = new PrintWriter(new FileWriter(shellPath)); + + + // 编写shell脚本 + writer.println("#!/bin/sh"); + writer.println(sb.toString()); + writer.println(sb2.toString()); + + // 关闭PrintWriter对象 + writer.close(); + + // 输出提示信息,表示shell脚本写入成功 + LogUtil.info("Shell script written successfully."); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + // 创建一个ProcessBuilder对象,指定shell脚本文件的路径和名称 + ProcessBuilder pb = new ProcessBuilder("/bin/sh", shellPath); + + // 启动进程并执行shell脚本 + Process process = pb.start(); + dealStream(process); + process.waitFor(); + // 输出提示信息,表示shell脚本执行成功 + LogUtil.info("Shell script executed successfully."); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + }finally { + try { + File ff = new File(shellPath); + if (ff.exists()){ + ff.delete(); + } + File ffTmp = new File(outPathTemp); + if (ffTmp.exists()){ + ffTmp.delete(); + } + }catch (Exception e){ + + } + } + + + + stringRedisTemplate.opsForValue().set(redisProgressKey, "90", 5, TimeUnit.MINUTES); + return true; + } + + /** + * 开启线程处理Ffmpeg处理流 + * + * @param process + */ + private static void dealStream(Process process) { + if (process == null) { + return; + } + // 处理InputStream的线程 + new Thread() { + @Override + public void run() { + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line = null; + try { + while ((line = in.readLine()) != null) { + LogUtil.info( "处理InputStream的线程 warn output: " + line); + } + } catch (IOException e) { + LogUtil.error(e, "处理InputStream的线程 error"); + } finally { + try { + in.close(); + } catch (IOException e) { + LogUtil.error(e, "处理InputStream的线程 error"); + } + } + } + }.start(); + // 处理ErrorStream的线程 + new Thread() { + @Override + public void run() { + BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + try { + while ((line = err.readLine()) != null) { + LogUtil.info( "处理ErrorStream的线程 warn output: " + line); + } + } catch (IOException e) { + LogUtil.error(e, "处理ErrorStream的线程 error"); + } finally { + try { + err.close(); + } catch (IOException e) { + LogUtil.error(e, "处理ErrorStream的线程 error"); + } + } + } + }.start(); + } + + public static String getOrgPath(String url){ + if (url.indexOf(GlobalConfig.private_replace_key) < 0){ + return url; + } + return url.replace(GlobalConfig.private_replace_key, "/private/"); + } + public static String getOrgPath(String url, String fileName){ + if (url.indexOf(GlobalConfig.private_replace_key) >= 0){ + return url.replace(GlobalConfig.private_replace_key, "/private/") + fileName; + }else { + return GlobalConfig.default_disk_path_pre + "/private" + url + fileName; + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/ImageUtil.java b/src/main/java/com/svnlan/home/utils/ImageUtil.java new file mode 100644 index 0000000..636ddfc --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ImageUtil.java @@ -0,0 +1,658 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.domain.ScaleInfo; +import com.svnlan.home.enums.BusTypeEnum; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.StringUtil; +import net.coobird.thumbnailator.ThumbnailParameter; +import net.coobird.thumbnailator.Thumbnails; +import org.apache.commons.io.FileUtils; +import org.springframework.data.redis.core.StringRedisTemplate; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.FileImageInputStream; +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.List; + +import static java.awt.Image.SCALE_SMOOTH; + +/** + * @Author: + * @Description: 图片缩略图 + */ +public class ImageUtil { + + //固定大小map + private static final Map thumbSizeMap = new HashMap(){{ + put("fav_icon", new int[][]{{32, 32}}); + put("avatar", new int[][]{{80, 80}}); + put("design_logo", new int[][]{{420, 198}}); + put("common_pic_1", new int[][]{{560, 336}}); + put("common_pic_2", new int[][]{{560, 336}}); + put("common_pic_3", new int[][]{{266, 334}}); + // -1:0.6x, -2:0.4x, -3:0.2x, -4:0.1x + put("ques_image", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}}); +// put("comments_attachment", new int[][]{{768, 1006}}); + put("comments_attachment", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}}); + put("image_repo", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}}); + put("image_repo_cover", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}}); + put("image", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}}); + put("cloud_4", new int[][]{{-2, -2}, {-3, -3}}); + put("cloud", new int[][]{{-6, -6}, {-7, -7}, {-8, -8}}); + put("works_image", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}, {-5, -5}}); + put("doc", new int[][]{{-2, -2}, {-3, -3}}); + put("attachment", new int[][]{{-2, -2}, {-3, -3}}); + put("course_image", new int[][]{{-1, -1}, {-2, -2},{-3, -3}, {-5, -5}}); + put("ware_image", new int[][]{{-1, -1}, {-2, -2}, {-3, -3}, {-5, -5}}); + put("homework_image_answer", new int[][]{{-2, -2}, {-3, -3}}); + put("flow_ticket", new int[][]{{-2, -2}, {-3, -3}}); + put("flow_cert", new int[][]{{-2, -2}, {-3, -3}}); + put("face_image", new int[][]{{80, 80}}); + }}; + //等比map + private static final Map scaleMap = new HashMap(){{ + put(-1, new ScaleInfo(0.8 ,"large")); + put(-2, new ScaleInfo(0.4 ,"medium")); + put(-3, new ScaleInfo(0.2 ,"small")); + put(-4, new ScaleInfo(0.1 ,"tiny")); + put(-5, new ScaleInfo(0.6, "secondary")); + put(-6, new ScaleInfo(200, 200 ,"small")); + put(-7, new ScaleInfo(300, 300 ,"medium")); + put(-8, new ScaleInfo(500, 500 ,"secondary")); + put(0, new ScaleInfo(1.0, "same")); + }}; + private static final Map bigImageScaleMap = new HashMap(){{ + put(-1, new ScaleInfo(0.4 ,"large")); + put(-2, new ScaleInfo(0.2 ,"medium")); + put(-3, new ScaleInfo(0.1 ,"small")); + put(-4, new ScaleInfo(0.05 ,"tiny")); + }}; + + private static final String[] circleCornerTypeArr = new String[]{"course", "ware", "shop", "vip"}; + + //普通流程 + public static List createThumb(String filePath, String busType, String classifyType, int[][] customSizeArr, + String markContent, StringRedisTemplate stringRedisTemplate, boolean needMark) { + return createThumb(filePath, busType, classifyType, customSizeArr, markContent, stringRedisTemplate, null, needMark); + } + //普通流程 + public static List createThumb(String filePath, String busType, String classifyType, int[][] customSizeArr, + String markContent, StringRedisTemplate stringRedisTemplate, Float quality, boolean needMark) { + List list = createThumb(filePath, busType, classifyType, customSizeArr, markContent, stringRedisTemplate, + null, null, true, quality, needMark); + return list; + } + /** needMark 是否需要水印 */ + private static List createThumb(String filePath, String busType, String classifyType, int[][] customSizeArr + , String markContent, StringRedisTemplate stringRedisTemplate + , String sourceDirectoryPath, String targetDirectoryPath, boolean cover, Float quality, boolean needMark) { + List list = new ArrayList<>(); + String typeString = busType + (StringUtil.isEmpty(classifyType) ? "" : "_" + classifyType); + int[][] sizeArr = customSizeArr == null ? thumbSizeMap.get(typeString) : customSizeArr; + + if (sizeArr == null){//默认大小 + sizeArr = new int[][]{{-2, -2}, {-3, -3}, {-4, -4}, {-5, -5}}; + } + String filePathForSave = String.copyValueOf(filePath.toCharArray()); + File imageFile = new File(filePath); + if (!imageFile.exists()){ + LogUtil.error("缩略图处理失败,原图不存在" + filePath); + return null; + } + + //svg处理 + boolean isSvg = filePath.endsWith(".svg"); + boolean isGif = filePath.endsWith(".gif"); + boolean isWebp = filePath.endsWith(".webp"); + + BufferedImage bufferedImage = null; + try { +// Image src = Toolkit.getDefaultToolkit().createImage(filePath); + + if (!isSvg) { + if (isWebp){ + ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next(); + + // Configure the input on the ImageReader + reader.setInput(new FileImageInputStream(imageFile)); + // Decode the image + bufferedImage = reader.read(0); + }else if (!isGif){ + bufferedImage = ImageIO.read(imageFile); //会变红 + }else { + FileInputStream data = new FileInputStream(imageFile); + GifDecoder.GifImage gif = GifDecoder.read(data); + int frameCount = gif.getFrameCount(); + for (int i = 0; i < frameCount; i++) { + bufferedImage = gif.getFrame(i); + if (bufferedImage != null){ + break; + } + } + } + + } else { + bufferedImage = null; + } +// bufferedImage = toBufferedImage(src);//Image to BufferedImage +// +// src.flush();//todo + } catch (Exception e){ + LogUtil.error(e, "图片读取失败" + filePath); + return null; + } + + LogUtil.info("createThumb********* isnull=" + (null == bufferedImage)); + if (null == bufferedImage && !isSvg) { + return null; + } + //云盘 + List cloudList = Arrays.asList(BusTypeEnum.CLOUD.getBusType()); + boolean isCloud = cloudList.contains(busType); + String firstPath = FileUtil.getFirstStorageDevicePath(filePath); + + filePath = filePath.replace(firstPath + "/private/", firstPath + "/common/"); + if (isCloud){ + /*filePath = filePath.replace(firstPath + "/doc/", firstPath + "/common/doc/") + .replace(firstPath + "/attachment/", firstPath + "/common/attachment/");*/ + } + if (sourceDirectoryPath != null && targetDirectoryPath != null){ + filePath = filePath.replace(sourceDirectoryPath, targetDirectoryPath); + } + File pDir = new File(filePath).getParentFile(); + if (!pDir.exists()){ + pDir.mkdirs(); + } + + //点号位置 + int dotPosition = filePath.lastIndexOf("."); + //大小数组循环生成新图片 + for (int[] aSizeArr : sizeArr) { + int newWidth; + int newHeight; + String newPath; + //等比 + if (aSizeArr[0] <= 0){ + if (aSizeArr[0] == -6 || aSizeArr[0] == -7 || aSizeArr[0] == -8 ){ + int imgW = bufferedImage.getWidth(); + int imgH = bufferedImage.getHeight(); + int scaleW = scaleMap.get(aSizeArr[0]).getW(); + int scaleH = scaleMap.get(aSizeArr[0]).getH(); + + if (imgH >= imgW && imgH > scaleH){ + newHeight = scaleH; + double a = (double)scaleH / imgH * imgW; + newWidth = Integer.valueOf(String.valueOf(Math.round(a))); + }else if (imgW >= imgH && imgW > scaleW){ + newWidth = scaleW; + double a = (double)scaleW / imgW * imgH; + newHeight = Integer.valueOf(String.valueOf(Math.round(a))); + }else { + newWidth = bufferedImage.getWidth(); + newHeight = bufferedImage.getHeight(); + } + }else { + newWidth = (int)(bufferedImage.getWidth() * scaleMap.get(aSizeArr[0]).getScale()); + newHeight = (int)(bufferedImage.getHeight() * scaleMap.get(aSizeArr[0]).getScale()); + } + if (aSizeArr[0] == -1 && stringRedisTemplate != null){ + //large的真实size存到redis, 瀑布使用 + stringRedisTemplate.opsForHash().put(GlobalConfig.IMAGE_LARGE_SIZE_KEY, filePath, "" + newWidth + "_" + newHeight); + } + newPath = getNewFilePath(filePath, dotPosition, scaleMap.get(aSizeArr[0]).getTypeString()); + } else {//固定大小 + newWidth = aSizeArr[0]; + newHeight = aSizeArr[1]; + //缩略图大于原图, 不处理 +// if (newWidth > bufferedImage.getWidth() && newHeight > bufferedImage.getHeight()){ +// continue; +// } + newPath = getNewFilePath(filePath, dotPosition, "" + newWidth + "_" + newHeight); + } + //非覆盖模式, 目标文件已存在的不处理 + if (!cover){ + if (new File(newPath).exists()){ + continue; + } + } + LogUtil.info("目标缩略图文件,{"+ newWidth +"," + newHeight +"}" + newPath); + try { + if (isSvg){ + Files.createLink(Paths.get(newPath), Paths.get(filePathForSave)); + } else { + //生成缩略图 + doCreateThumb(newPath, filePathForSave, bufferedImage, newWidth, newHeight, needMark, markContent, quality); + LogUtil.info("目标缩略图文件 压缩成功,{"+ newWidth +"," + newHeight +"}" + newPath); + } + list.add(newPath); + } catch (Exception e) { + LogUtil.error(e, "缩略图生成失败,目标缩略图文件{"+ newWidth +"," + newHeight +"}" + newPath); + } + } + //生成水印 + /*if (customSizeArr == null) { + try { + String markedPath = getNewFilePath(filePath, dotPosition , "marked"); + doCreateThumb(markedPath, filePathForSave, bufferedImage, bufferedImage.getWidth(), bufferedImage.getHeight(), + needMark, markContent, null); + list.add(markedPath); + } catch (Exception e){ + LogUtil.error(e, "水印图生成失败"); + } + }*/ + return list; + } + + public static boolean createPngThumb(String path, int[] sizeArr, String targetPath) throws Exception{ + File imgFile = new File(path); + if (!imgFile.exists()){ + LogUtil.error("原图不存在, " + path); + return false; + } + BufferedImage bufferedImage = ImageIO.read(imgFile); + if (bufferedImage == null){ + return false; + } + if (bufferedImage.getWidth() < sizeArr[0] && bufferedImage.getHeight() < sizeArr[1]){ + FileUtils.copyFile(imgFile, new File(targetPath)); + return false; + } + Image scaleImage = bufferedImage.getScaledInstance(sizeArr[0], sizeArr[1], SCALE_SMOOTH); + BufferedImage newImage = new BufferedImage(sizeArr[0], sizeArr[1], BufferedImage.TYPE_INT_ARGB); + Graphics2D g = newImage.createGraphics(); + g.drawImage(scaleImage, 0, 0, sizeArr[0], sizeArr[1], null); + g.dispose(); + File targetFile = new File(targetPath); + if (!targetFile.getParentFile().exists()){ + targetFile.getParentFile().mkdirs(); + } + return ImageIO.write(newImage, "png", targetFile); + } + + /** + * @Description: 新文件路径 + * @params: [filePath, dotPosition, typeString] + * @Return: java.lang.String + * @Modified: + */ + private static String getNewFilePath(String filePath, int dotPosition, String typeString) { + return filePath.substring(0, dotPosition) + + "!" + typeString + + filePath.substring(dotPosition); + } + + private static BufferedImage toBufferedImage(Image image) throws Exception { + + if (image instanceof BufferedImage) { + return (BufferedImage) image; + } + // This code ensures that all the pixels in the image are loaded + image = new ImageIcon(image).getImage(); + + BufferedImage bimage = null; + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + try { + int transparency = Transparency.OPAQUE; + GraphicsDevice gs = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gs.getDefaultConfiguration(); + bimage = gc.createCompatibleImage(image.getWidth(null), + image.getHeight(null), transparency); + } catch (HeadlessException e) { + // The system does not have a screen + } + if (bimage == null) { + // Create a buffered image using the default color model + int type = BufferedImage.TYPE_INT_RGB; + bimage = new BufferedImage(image.getWidth(null), + image.getHeight(null), type); + } + // Copy image to buffered image + Graphics g = bimage.createGraphics(); + // Paint the image onto the buffered image + g.drawImage(image, 0, 0, null); + g.dispose(); + return bimage; + + } + + /** + * @Description: 创建缩略图 + * @params: [newPath, sourcePath, bufferedImage, width, height, needMark, psName, isImageRepo, quality] + * @Return: void + * @Modified: + */ + public static void doCreateThumb(String newPath, String sourcePath, BufferedImage bufferedImage, int width, int height, + boolean needMark, String psName,Float quality) throws IOException { + //判断宽度是否过小 + if (null != bufferedImage && bufferedImage.getWidth() < 100) { + //硬链拷贝 + Files.createLink(Paths.get(newPath), Paths.get(sourcePath)); + return; + } + + String fileType = null; + boolean isPng = isPng(sourcePath); + boolean isWebp = isWebp(sourcePath); + int imageType = BufferedImage.TYPE_INT_RGB; + if (isPng){ + fileType = "png"; + imageType = BufferedImage.TYPE_INT_ARGB; + }else if (isWebp){ + fileType = "webp"; + imageType = ThumbnailParameter.DEFAULT_IMAGE_TYPE; + }else { + fileType = "jpg"; + } + + //新建一个image, 把来源image画上 + BufferedImage newImage = new BufferedImage(width, height, imageType); + Image scaleImage = bufferedImage.getScaledInstance(width, height, SCALE_SMOOTH); +// Image temp = bufferedImage.getScaledInstance(width, height, SCALE_SMOOTH); + Graphics2D g = newImage.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.drawImage(scaleImage, 0, 0, width, height, null); + if (needMark && !StringUtil.isEmpty(psName) ) {//其他水印 + addMark(g, width, height, psName); + } + g.dispose(); + + //输出图片 + ImageIO.write(newImage, fileType, new File(newPath)); + quality = 0.6f; + //若要对图片进行质量压缩 + if(null != quality) { + try { + // + Thumbnails.of(newPath).scale(1f).outputQuality(quality).toFile(newPath); + } catch (Exception e) { + LogUtil.error(e, "压缩图片失败,路径:" + newPath); + } + } + } + + /** + * @description 判断是否PNG + * @params [picPath] + * @return boolean + */ + private static boolean isPng(String picPath) { + byte[] bytes = new byte[5]; + try (FileInputStream fileInputStream = new FileInputStream(picPath)) { + int read = fileInputStream.read(bytes); + if (read < 4) { + return false; + } + if (bytes[1] == (byte) 'P' && bytes[2] == (byte) 'N' && bytes[3] == (byte) 'G') { + return true; + } + } catch (IOException e) { + } + return false; + } + /** + * @description 判断是否webp + * @params [picPath] + * @return boolean + */ + private static boolean isWebp(String picPath) { + if (picPath.toLowerCase().endsWith(".webp")){ + return true; + } + return false; + } + + /** + * @Description: 创建供分享图使用的缩略图 + * @params: [sourcePath, newPath] + * @Return: void + * @Modified: + */ + public static BufferedImage createThumbForShare(String sourcePath, String newPath){ + + File sourceFile = new File(sourcePath); + File newFile = new File(newPath); + //原图不存在 + if (!sourceFile.exists()){ + return null; + } + try { + //目标已存在, 直接返回 + if (newFile.exists()){ + return ImageIO.read(newFile); + } + BufferedImage bufferedImage = ImageIO.read(sourceFile); + return createThumbForShareByImage(bufferedImage, newFile); + } catch (Exception e){ + LogUtil.error(e, "生成供分享使用的缩略图失败, sourcePath:" + sourcePath + ", newPath:" + newPath); + } + return null; + } + + /** + * @Description: 分享图缩略图 + * @params: [bufferedImage, newFile] + * @Return: java.awt.image.BufferedImage + * @Modified: + */ + private static BufferedImage createThumbForShareByImage(BufferedImage bufferedImage, File newFile) throws Exception { + int width = bufferedImage.getWidth(); + int height = bufferedImage.getHeight(); + double scale; + if (width < 1000){ + return bufferedImage; + } else if (width <= 2000){ + scale = 0.6; + } else if (width <= 3000){ + scale = 0.5; + } else if (width <= 5000){ + scale = 0.4; + } else { + scale = 0.3; + } + if (newFile.exists()){ + return ImageIO.read(newFile); + } + width = (int) (width * scale); + height = (int) (height * scale); + Image scaleImage = bufferedImage.getScaledInstance(width , height, SCALE_SMOOTH); + BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D g = newImage.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.drawImage(scaleImage, 0, 0, width, height, null); + g.dispose(); + ImageIO.write(newImage, "jpg", newFile); + return newImage; + } + + /** + * @Description: 图库水印 + * @params: [g, width, height, psName] + * @Return: void + * @Modified: + */ + private static void addImageRepoMark(Graphics2D g, int width, int height, String psName) { + //字体缩放比例 + float fontScale = 24; + float fontSizePre = height / fontScale; + float fontSize = fontSizePre * 2; + Font font = new Font("黑体", Font.BOLD, 30); + font = font.deriveFont(Font.BOLD, fontSize); + g.setFont(font); + //字实际长度 + int length = getWatermarkLength(psName, g); + boolean overWidth = false; + //字长超过图片宽度 + if (length + fontSize >= width){ + overWidth = true; + //重设字体大小 + fontSize = fontSize / ((1.0f * length + fontSize) / width) * 0.9f; + font = font.deriveFont(Font.BOLD, fontSize); + g.setFont(font); + length = getWatermarkLength(psName, g); + } + int backgroundHeight = (int) (fontSize * 1.5f); + int backgroundWidth = (length + (int)fontSize) > width ? width : (length + (int)fontSize) ; + + BufferedImage markBackground = new BufferedImage(backgroundWidth, backgroundHeight, BufferedImage.TYPE_INT_ARGB); + Graphics2D bg = markBackground.createGraphics(); + //画透明区域 + bg.setColor(new Color(102, 102, 102, 90)); + bg.fillRect(0,0,width,backgroundHeight); + //画字 + bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + bg.setFont(font); + bg.setColor(new Color(255, 255, 255, 150)); + bg.drawString(psName, fontSize / 2 , fontSize); + bg.dispose(); + //水印区域垂直 在图片下半部分的居中位置 + int backgroundY = (int) (height * 0.75 - backgroundHeight / 2); + + g.drawImage(markBackground, width - backgroundWidth, backgroundY, backgroundWidth , backgroundHeight, null); + } + + private static void addMark(Graphics2D g, int width, int height, String content) { + addMark(g, width, height, content, false); + } + + /** + * @Description: 加水印 + * @params: [g, width, height, content, second] + * @Return: void + * @Modified: + */ + private static void addMark(Graphics2D g, int width, int height, String content, boolean second) { + g.setColor(new Color(second ? 0xFFFFFF : 0)); + g.setBackground(Color.GREEN); + if (width <= 100){//小于80的不加水印 + return; + } + int fontSize; + int cLength = content.length(); + double markScale = (double) 250 * 2 / cLength; + + if (width * 2 / cLength > 14){ + fontSize = (int) (width / markScale); +// fontSize = 14; + } else { + fontSize = width * 2 / cLength; + } + Font font = new Font("宋体", Font.PLAIN, fontSize); + g.setFont(font); + int offset; + if (width <= 200) { + offset = second ? 0 : 1; + } else if (width <= 500){ // 201 - 499, 2 - 8 + int b = ((width - 100) / 100 ) * 2; + offset = second ? b - 1 : b; + } else if (width <= 1100){ // 501 - 1100, 12 - 30 + int b = ((width - 100) / 100 ) * 3; + offset = second ? b - 1 : b; + } else { + offset = second ? 29: 30; + } + int x = width - getWatermarkLength(content, g) - offset; + int y = height - offset; + if (y < (double)height / 1.5){ + y = height; + } +// g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, +// 0.5f)); + g.drawString(content, x, y); // 添加水印的文字和设置水印文字出现的内容 + if (!second) { + addMark(g, width, height, content, true); + } + } + + /** + * @Description: 获取字占用长度 + * @params: [content, g] + * @Return: int + * @Modified: + */ + private static int getWatermarkLength(String content, Graphics2D g) { + return g.getFontMetrics(g.getFont()).charsWidth(content.toCharArray(), 0, content.length()); + } + + private static int getCharLen(char c, Graphics2D g) { + return g.getFontMetrics(g.getFont()).charWidth(c); + } + + /** + * @Description: 十六进制获取颜色, 默认黑 + * @params: [color] + * @Return: java.awt.Color + * @Modified: + */ + private static Color getColorByHexString(String color) { + if (StringUtil.isEmpty(color)){ + return Color.BLACK; + } + int colorInt; + try { + colorInt = Integer.valueOf(color, 16); + } catch (Exception e){ + return Color.BLACK; + } + return new Color(colorInt); + } + + + + /** + * 计算旋转参数 + */ + public static Rectangle CalcRotatedSize(Rectangle src, int angel) { + // if angel is greater than 90 degree,we need to do some conversion. + if (angel >= 90) { + if (angel / 90 % 2 == 1) { + int temp = src.height; + src.height = src.width; + src.width = temp; + } + angel = angel % 90; + } + + double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2; + double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r; + double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2; + double angel_data_width = Math.atan((double) src.height / src.width); + double angel_data_height = Math.atan((double) src.width / src.height); + + int len_data_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_data_width)); + int len_data_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_data_height)); + int des_width = src.width + len_data_width * 2; + int des_height = src.height + len_data_height * 2; + return new Rectangle(new Dimension(des_width, des_height)); + } + + + /** + * @Description: 获取图片分辨率 + * @params: [path] + * @Return: java.lang.String + * @Modified: + */ + public static String getResolution(String path) { + BufferedImage bufferedImage; + try { + bufferedImage = ImageIO.read(new File(path)); + } catch (Exception e) { + LogUtil.error( "读取图片失败" + path + ", " + e.getMessage()); + return "0*0"; + } + if (bufferedImage == null){ + return "0*0"; + } + return bufferedImage.getWidth() + "*" + bufferedImage.getHeight(); + } +} diff --git a/src/main/java/com/svnlan/home/utils/KkFileUtils.java b/src/main/java/com/svnlan/home/utils/KkFileUtils.java new file mode 100644 index 0000000..c24ff80 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/KkFileUtils.java @@ -0,0 +1,177 @@ +package com.svnlan.home.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +import org.springframework.web.util.HtmlUtils; + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class KkFileUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(KkFileUtils.class); + + public static final String DEFAULT_FILE_ENCODING = "UTF-8"; + + private static final List illegalFileStrList = new ArrayList<>(); + + static { + illegalFileStrList.add("../"); + illegalFileStrList.add("./"); + illegalFileStrList.add("..\\"); + illegalFileStrList.add(".\\"); + illegalFileStrList.add("\\.."); + illegalFileStrList.add("\\."); + illegalFileStrList.add(".."); + illegalFileStrList.add("..."); + } + + /** + * 检查文件名是否合规 + * @param fileName 文件名 + * @return 合规结果,true:不合规,false:合规 + */ + public static boolean isIllegalFileName(String fileName){ + for (String str: illegalFileStrList){ + if(fileName.contains(str)){ + return true; + } + } + return false; + } + /** + * 检查是否是数字 + * @param str 文件名 + * @return 合规结果,true:不合规,false:合规 + */ + public static boolean isInteger(String str) { + if(StringUtils.hasText(str)){ + boolean strResult = str.matches("-?[0-9]+.?[0-9]*"); + return strResult ; + } + return false; + } + /** + * 判断url是否是http资源 + * + * @param url url + * @return 是否http + */ + public static boolean isHttpUrl(URL url) { + return url.getProtocol().toLowerCase().startsWith("file") || url.getProtocol().toLowerCase().startsWith("http"); + } + + /** + * 判断url是否是ftp资源 + * + * @param url url + * @return 是否ftp + */ + public static boolean isFtpUrl(URL url) { + return "ftp".equalsIgnoreCase(url.getProtocol()); + } + + /** + * 删除单个文件 + * + * @param fileName 要删除的文件的文件名 + * @return 单个文件删除成功返回true,否则返回false + */ + public static boolean deleteFileByName(String fileName) { + File file = new File(fileName); + // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 + if (file.exists() && file.isFile()) { + if (file.delete()) { + LOGGER.info("删除单个文件" + fileName + "成功!"); + return true; + } else { + LOGGER.info("删除单个文件" + fileName + "失败!"); + return false; + } + } else { + LOGGER.info("删除单个文件失败:" + fileName + "不存在!"); + return false; + } + } + + + public static String htmlEscape(String input) { + if(StringUtils.hasText(input)){ + //input = input.replaceAll("\\{", "%7B").replaceAll("}", "%7D").replaceAll("\\\\", "%5C"); + return HtmlUtils.htmlEscape(input, "UTF-8"); + } + return input; + } + + + /** + * 通过文件名获取文件后缀 + * + * @param fileName 文件名称 + * @return 文件后缀 + */ + public static String suffixFromFileName(String fileName) { + return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); + } + + + /** + * 根据文件路径删除文件 + * + * @param filePath 绝对路径 + */ + public static void deleteFileByPath(String filePath) { + File file = new File(filePath); + if (file.exists() && !file.delete()) { + LOGGER.warn("压缩包源文件删除失败:{}!", filePath); + } + } + + /** + * 删除目录及目录下的文件 + * + * @param dir 要删除的目录的文件路径 + * @return 目录删除成功返回true,否则返回false + */ + public static boolean deleteDirectory(String dir) { + // 如果dir不以文件分隔符结尾,自动添加文件分隔符 + if (!dir.endsWith(File.separator)) { + dir = dir + File.separator; + } + File dirFile = new File(dir); + // 如果dir对应的文件不存在,或者不是一个目录,则退出 + if ((!dirFile.exists()) || (!dirFile.isDirectory())) { + LOGGER.info("删除目录失败:" + dir + "不存在!"); + return false; + } + boolean flag = true; + // 删除文件夹中的所有文件包括子目录 + File[] files = dirFile.listFiles(); + for (int i = 0; i < Objects.requireNonNull(files).length; i++) { + // 删除子文件 + if (files[i].isFile()) { + flag = KkFileUtils.deleteFileByName(files[i].getAbsolutePath()); + if (!flag) { + break; + } + } else if (files[i].isDirectory()) { + // 删除子目录 + flag = KkFileUtils.deleteDirectory(files[i].getAbsolutePath()); + if (!flag) { + break; + } + } + } + + if (!dirFile.delete() || !flag) { + LOGGER.info("删除目录失败!"); + return false; + } + return true; + } + +} diff --git a/src/main/java/com/svnlan/home/utils/ObjUtil.java b/src/main/java/com/svnlan/home/utils/ObjUtil.java new file mode 100644 index 0000000..28d25c6 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ObjUtil.java @@ -0,0 +1,147 @@ +package com.svnlan.home.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.svnlan.utils.RandomUtil; +import lombok.SneakyThrows; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description: + * @author: + * @Date: + */ +public class ObjUtil { + + /** + * 获取对象下所有不为空的属性和值 + * + * @param obj + * @return + */ + public static Map checkfield(Object obj) { + Map map = null; + try { + Class objClass = obj.getClass(); + Field[] fields = objClass.getDeclaredFields(); + map = new HashMap<>(); + for (Field field : fields) { + field.setAccessible(true); + Object val = field.get(obj); + if (val != null) { + map.put(field.getName(), val); + } + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return map; + } + + public static void initializefield(Object object) { + try { + Class objectClass = object.getClass(); + Field[] fields = objectClass.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + String type = field.getType().getSimpleName().toString(); + if (field.get(object) == null) { + if (type.equals("String")) { + field.set(object, ""); + } else if (type.equals("Integer")) { + field.set(object, new Integer(0)); + } else if (type.equals("Long")) { + field.set(object, new Long(0)); + } else if (type.equals("Char")) { + field.set(object, ""); + } else if (type.equals("Date")) { + field.set(object, new Date()); + } else if (type.equals("BigDecimal")) { + field.set(object, new BigDecimal(0)); + } else if (type.equals("Double")) { + field.set(object, new Double(0)); + } else if (type.equals("Byte")) { + field.set(object, new Byte("0")); + } else if (type.equals("Float")) { + field.set(object, new Float(0)); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * @param request + * @return + * @description: 得API前缀 + */ + public static String findApiPrefix(HttpServletRequest request) { + return findApiPrefix(request, RandomUtil.getuuid()); + } + + /** + * @param request + * @param taskId + * @description: 得API前缀 + */ + public static String findApiPrefix(HttpServletRequest request, String taskId) { + String prefix = ""; + String requestUri = request.getRequestURI(); + prefix = String.format("@日志@%s(%s) >>> ", requestUri, taskId); + return prefix; + } + + /** + * @param obj + * @description: object转List方法 + */ + public static List objectToList(Object obj, Class clazz) { + List result = new ArrayList(); + // 判断 obj 是否包含 List 类型 + if (obj instanceof List) { + for (Object o : (List) obj) { + // 使用Class.cast做类型转换 + result.add(clazz.cast(o)); + } + return result; + } + return null; + } + + /** + * 将实体类转化为 jsonObject + */ + @SneakyThrows + public static JSONObject toJsonObject(JSONObject jsonObject, Class clazz, Object instance, boolean ignoreNull) { + + Field[] fields = clazz.getDeclaredFields(); + if (Objects.isNull(jsonObject)) { + jsonObject = new JSONObject(); + } + if (ignoreNull) { + for (Field field : fields) { + field.setAccessible(true); + Optional optional = Optional.ofNullable(field.get(instance)); + if (optional.isPresent()) { + jsonObject.fluentPut(field.getName(), optional.get()); + } + } + }else{ + for (Field field : fields) { + field.setAccessible(true); + jsonObject.fluentPut(field.getName(), field.get(instance)); + } + } + return jsonObject; + } + +} diff --git a/src/main/java/com/svnlan/home/utils/ParamUtils.java b/src/main/java/com/svnlan/home/utils/ParamUtils.java new file mode 100644 index 0000000..2acff53 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ParamUtils.java @@ -0,0 +1,79 @@ +package com.svnlan.home.utils; + +import com.svnlan.enums.DocumentTypeEnum; +import com.svnlan.home.dto.HomeExplorerDTO; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/17 13:33 + */ +@Component +public class ParamUtils { + + public void docSearchParam(String fileType, Map hashMap){ + if (fileType.indexOf(DocumentTypeEnum.doc.getExt()) >= 0){ + hashMap.put("documentType", DocumentTypeEnum.doc.getType()); + }else if (fileType.indexOf(DocumentTypeEnum.image.getExt()) >= 0){ + hashMap.put("documentType", DocumentTypeEnum.image.getType()); + }else if (fileType.indexOf(DocumentTypeEnum.music.getExt()) >= 0){ + hashMap.put("documentType", DocumentTypeEnum.music.getType()); + }else if (fileType.indexOf(DocumentTypeEnum.movie.getExt()) >= 0){ + hashMap.put("documentType", DocumentTypeEnum.movie.getType()); + }else if (fileType.indexOf(DocumentTypeEnum.zip.getExt()) >= 0){ + hashMap.put("documentType", DocumentTypeEnum.zip.getType()); + }else if (fileType.indexOf(DocumentTypeEnum.others.getExt()) >= 0){ + hashMap.put("documentType", DocumentTypeEnum.others.getType()); + }else { + hashMap.put("fileTypeList", Arrays.asList(fileType.split(",")).stream().map(String::valueOf).collect(Collectors.toList())); + } + } + + public String getHomeExplorerSecondKey(HomeExplorerDTO homeExplorerDTO){ + if (!ObjectUtils.isEmpty(homeExplorerDTO.getKeyword())){ + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFileType()) && "folder".equals(homeExplorerDTO.getFileType())){ + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFromType()) && homeExplorerDTO.getFromType()) { + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getMinSize()) || !ObjectUtils.isEmpty(homeExplorerDTO.getMaxSize())) { + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getTimeFrom()) || !ObjectUtils.isEmpty(homeExplorerDTO.getTimeTo())) { + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getUserID())) { + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getRepeatName()) || !ObjectUtils.isEmpty(homeExplorerDTO.getRepeatSourceID())) { + return ""; + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getSortField()) || !ObjectUtils.isEmpty(homeExplorerDTO.getSortType())) { + return ""; + } + StringBuilder sb = new StringBuilder(); + if (!ObjectUtils.isEmpty(homeExplorerDTO.getSourceID())) { + sb.append(homeExplorerDTO.getSourceID()); + }else { + sb.append(0); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getFileType())) { + sb.append("_" + homeExplorerDTO.getFileType()); + } + if (!ObjectUtils.isEmpty(homeExplorerDTO.getTagID())) { + sb.append("_" + homeExplorerDTO.getTagID()); + } + sb.append("_" + homeExplorerDTO.getCurrentPage()); + sb.append("_" + homeExplorerDTO.getPageSize()); + return sb.toString(); + } +} diff --git a/src/main/java/com/svnlan/home/utils/PdfDUtil.java b/src/main/java/com/svnlan/home/utils/PdfDUtil.java new file mode 100644 index 0000000..651d89b --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/PdfDUtil.java @@ -0,0 +1,258 @@ +package com.svnlan.home.utils; + +import com.aspose.pdf.Document; +import com.aspose.pdf.ImageType; +import com.aspose.pdf.License; +import com.aspose.pdf.SaveFormat; +import com.aspose.pdf.facades.PdfConverter; +import com.svnlan.common.GlobalConfig; +import com.svnlan.utils.LogUtil; +import org.apache.commons.io.FileUtils; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.rendering.PDFRenderer; +import org.springframework.data.redis.core.StringRedisTemplate; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @description: PDF转换工具类 + */ +public class PdfDUtil { + + /** + * @description: 将PDF转PNG或JPG(有压缩) + * @param prefix + * @param sourcePdfPath 要转的源PDF路径 + * @param targetFilePath 目标的PNG文件前缀路径 + * @param accuracy 压缩质量:0~1 + * @param maxWidth + * @param maxHeight + * @return java.lang.String 最后一张图片地址 + */ + + public static String pdfToPngOrJpg(String prefix, String sourcePdfPath, String targetFilePath, double accuracy, + int maxWidth, int maxHeight) { + return pdfToPngOrJpg(prefix, sourcePdfPath, targetFilePath, accuracy, maxWidth, maxHeight, false, null); + } + public static String pdfToPngOrJpg(String prefix, String sourcePdfPath, String targetFilePath, double accuracy, + int maxWidth, int maxHeight, boolean isReturnList, List pathList) { + String lastImagePath = null; + File file = new File(sourcePdfPath); + + PDDocument doc = null; + try { + doc = PDDocument.load(file); + PDFRenderer renderer = new PDFRenderer(doc); + int pageCount = doc.getNumberOfPages(); + for (int i = 0; i < pageCount; i++) { + PDPage pdPage = doc.getPage(i); + PDRectangle mediaBox = pdPage.getMediaBox(); + Double dpi = mediaBox.getWidth() * 25.4 / 72; + BufferedImage image = renderer.renderImageWithDPI(i, dpi.floatValue()); + String pngImagePath = targetFilePath + (i+1) + ".png"; + lastImagePath = pngImagePath; + + int imageWidth = image.getWidth(); + int imageHeight = image.getHeight(); + + OutputStream out = null; + try { + out = new FileOutputStream(new File(lastImagePath)); + ImageIO.write(image, "png", out); + if (isReturnList && accuracy > 1){ + pathList.add(lastImagePath); + } + } catch (Exception e) { + LogUtil.error(e, prefix); + } finally { + if(null != out) { + out.close(); + } + } + + //若质量小于1,则进行压缩成JPG图片 + if(accuracy < 1 || maxWidth > 0 || maxHeight > 0) { + float widthScale = (float) maxWidth / imageWidth; + float heightScale = (float) maxHeight / imageHeight; + float scale = 1; + if(widthScale < 1 || heightScale < 1) { + if(widthScale < heightScale) { + scale = widthScale; + } else { + scale = heightScale; + } + } + + String targetJpgPath = targetFilePath + (i+1) + ".jpg"; + + //压缩 + Boolean success = ImageDUtil.compressImage(prefix, lastImagePath, targetJpgPath, accuracy, scale); + if(success) { + lastImagePath = targetJpgPath; + if (isReturnList){ + pathList.add(targetJpgPath); + } + //删除源文件 + FileUtils.deleteQuietly(new File(pngImagePath)); + } else { + lastImagePath = null; + } + } + } + } catch (IOException e) { + LogUtil.error(e, prefix + "pdf转png失败,源文件:" + sourcePdfPath + ",目标文件:" + targetFilePath + "。"); + lastImagePath = null; + } finally { + if(null != doc) { + try { + doc.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return lastImagePath; + } + + public static String pdfToPngOrJpg(String prefix, String sourcePdfPath, String targetFilePath, + boolean isReturnList, List pathList, String redisKey, Boolean isProgress, + String suffix, StringRedisTemplate stringRedisTemplate, int progressType) { + String lastImagePath = null; + File file = new File(sourcePdfPath); + PDDocument doc = null; + try { + doc = PDDocument.load(file); + PDFRenderer renderer = new PDFRenderer(doc); + int pageCount = doc.getNumberOfPages(); + for (int i = 0; i < pageCount; i++) { + PDPage pdPage = doc.getPage(i); + PDRectangle mediaBox = pdPage.getMediaBox(); + Double dpi = mediaBox.getWidth() * 25.4 / 72; + BufferedImage image = renderer.renderImageWithDPI(i, dpi.floatValue()); + String pngImagePath = targetFilePath + (i+1) + "." + suffix; + lastImagePath = pngImagePath; + OutputStream out = null; + try { + out = new FileOutputStream(new File(lastImagePath)); + ImageIO.write(image, suffix, out); + if (isReturnList){ + pathList.add(lastImagePath); + } + } catch (Exception e) { + LogUtil.error(e, prefix); + } finally { + if(null != out) { + out.close(); + } + } + if (isProgress){ + String p = PdfDUtil.calculateProgress(i, pageCount, 1); + double r = Double.valueOf(p) / 2; + if (progressType == 2){ + double r1 = r / 2; + stringRedisTemplate.opsForValue().set(redisKey, String.format("%.1f",(50 + r1)), 60, TimeUnit.SECONDS); + }else { + stringRedisTemplate.opsForValue().set(redisKey, p, 60, TimeUnit.SECONDS); + } + } + + } + } catch (IOException e) { + LogUtil.error(e, prefix + "pdf转图片失败,源文件:" + sourcePdfPath + ",目标文件:" + targetFilePath + "。"); + lastImagePath = null; + } finally { + if(null != doc) { + try { + doc.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return lastImagePath; + } + + public static void pdf2Doc(String prefix, String sourcePdfPath, String targetFilePath, boolean isDocX, String redisKey, Boolean isProgress, + StringRedisTemplate stringRedisTemplate){ + File pdfFile = new File(targetFilePath); + try { + long old = System.currentTimeMillis(); + Document document = new Document(sourcePdfPath); + FileOutputStream outputStream = new FileOutputStream(pdfFile); + document.save(outputStream, isDocX ? SaveFormat.DocX : SaveFormat.Doc); + outputStream.close(); + long now = System.currentTimeMillis(); + if (isProgress){ + stringRedisTemplate.opsForValue().set(redisKey, 100+"", 60, TimeUnit.SECONDS); + } + System.out.println("PDF转化WORD共耗时:" + ((now - old) / 1000.0) + "秒"); //转化用时 + } catch (Exception e) { + LogUtil.error(e, prefix + " pdf2Doc 转化失败"); + } + } + + public static String calculateProgress(Integer num, Integer total, int dis){ + NumberFormat numberFormat = NumberFormat.getInstance(); + numberFormat.setMaximumFractionDigits(dis); //保留几位小数填写几 + //注意需要将Integer转换为float进行计算 + String percent = numberFormat.format((float) num / (float) total * 100); + return percent; + } + + public static String pdfToPngOrJpgConverter(String prefix, String sourcePdfPath, String targetFilePath, + boolean isReturnList, List pathList, String redisKey, Boolean isProgress, + String suffix, StringRedisTemplate stringRedisTemplate, int progressType) { + + PdfConverter converter = new PdfConverter(); + converter.bindPdf(sourcePdfPath); + String lastImagePath = null; + try { + converter.doConvert(); + + int pageCount = converter.getPageCount(); + int i=0; + while (converter.hasNextImage()) { + converter.getNextImage(targetFilePath + (i+1) + "." + suffix, "png".equals(suffix) ? ImageType.getPng(): ImageType.getJpeg()); + lastImagePath = targetFilePath + (i+1) + "." + suffix; + LogUtil.info("convertImg i=" + i +" lastImagePath=" + lastImagePath); + if (isReturnList) { + pathList.add(lastImagePath); + } + if (isProgress){ + String p = PdfDUtil.calculateProgress(i, pageCount, 1); + double r = Double.valueOf(p) / 2; + if (progressType == 2){ + double r1 = r / 2; + stringRedisTemplate.opsForValue().set(redisKey, String.format("%.1f",(50 + r1)), 60, TimeUnit.SECONDS); + }else { + stringRedisTemplate.opsForValue().set(redisKey, p, 60, TimeUnit.SECONDS); + } + } + i ++; + } + + }catch (Exception e){ + LogUtil.error(e, prefix + "pdf转图片失败,源文件:" + sourcePdfPath + ",目标文件:" + targetFilePath + "。"); + lastImagePath = null; + }finally { + if(null != converter) { + try { + converter.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + return lastImagePath; + } + +} diff --git a/src/main/java/com/svnlan/home/utils/ShareTool.java b/src/main/java/com/svnlan/home/utils/ShareTool.java new file mode 100644 index 0000000..b4ef2e3 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/ShareTool.java @@ -0,0 +1,72 @@ +package com.svnlan.home.utils; + +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.ShareDao; +import com.svnlan.home.dto.GetAttachmentDTO; +import com.svnlan.home.vo.ShareVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/31 17:12 + */ +@Component +public class ShareTool { + + @Resource + ShareDao shareDao; + + public void checkShareLink(GetAttachmentDTO getAttachmentDTO) { + List list = shareDao.getShareByCode(getAttachmentDTO.getShareCode()); + if (CollectionUtils.isEmpty(list) || list.size() > 1){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareErrorPathTips.getCode()); + } + ShareVo vo = list.get(0); + vo.setPassword(null); + + if (!ObjectUtils.isEmpty(getAttachmentDTO.getD()) && "1".equals(getAttachmentDTO.getD())) { + + boolean checkDown = false; + Map optionsMap = new HashMap<>(1); + if (!ObjectUtils.isEmpty(vo.getOptions())){ + optionsMap = JsonUtils.jsonToBean(vo.getOptions(), Map.class); + } + // notDownload 是否禁用下载 + if (optionsMap.containsKey("down")) { + String downStr = optionsMap.get("down").toString(); + if (!ObjectUtils.isEmpty(downStr)) { + vo.setDown(Integer.parseInt(downStr)); + } + } + if (vo.getDown().intValue() == 1 && optionsMap.containsKey("downNum")){ + String downNumStr = optionsMap.get("downNum").toString(); + if (!ObjectUtils.isEmpty(downNumStr)){ + int downNum = Integer.parseInt(downNumStr); + vo.setDownNum(downNum); + if ("0".equals(downNumStr) || downNum > vo.getNumDownload()){ + checkDown = true; + } + }else { + checkDown = true; + } + } + if (!checkDown){ + throw new SvnlanRuntimeException(CodeMessageEnum.shareDownExceedTips.getCode()); + } + shareDao.updateNumDownload(vo.getShareID(), vo.getNumDownload() + 1); + }else { + shareDao.updateNumView(vo.getShareID(), vo.getNumView() + 1); + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/SourceDownUrlUtils.java b/src/main/java/com/svnlan/home/utils/SourceDownUrlUtils.java new file mode 100644 index 0000000..fb1b35a --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/SourceDownUrlUtils.java @@ -0,0 +1,68 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.utils.zip.ZipUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.StringUtil; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.util.Set; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/15 11:39 + */ +@Component +public class SourceDownUrlUtils { + + @Resource + StringRedisTemplate stringRedisTemplate; + + /** + * @Description: 删除普通下载 + * @params: [] + * @Return: int + * @Modified: + */ + public int deleteCommonDownload() { + Set members = stringRedisTemplate.opsForZSet() + .rangeByScore(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, 0, System.currentTimeMillis()); + if (CollectionUtils.isEmpty(members)){ + LogUtil.info("删除普通下载, 集合空"); + return 0; + } + String pre = "deleteCommonDownload 删除临时文件"; + int count = 0; + for (String path : members){ + try { + count ++; + stringRedisTemplate.opsForZSet().remove(GlobalConfig.COMMON_DOWNLOAD_KEY_SET, path); + if (StringUtil.isEmpty(path.trim())){ + continue; + } + LogUtil.info(pre + " path=" + path); + File file = new File(path); + if (file.exists()){ + if (!file.isDirectory() && path.indexOf("/common/down_temp") == 0){ + LogUtil.info("普通下载删除", path); + file.delete(); + }else { + try { + ZipUtils.deleteFile(file); + }catch (Exception e){ + LogUtil.error(e,pre + "夹失败 "); + } + } + } + } catch (Exception e){ + LogUtil.error(e, pre + " 普通下载出错"); + } + } + return count; + } +} diff --git a/src/main/java/com/svnlan/home/utils/SourceHistoryUtil.java b/src/main/java/com/svnlan/home/utils/SourceHistoryUtil.java new file mode 100644 index 0000000..bf31147 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/SourceHistoryUtil.java @@ -0,0 +1,48 @@ +package com.svnlan.home.utils; + +import com.svnlan.home.dao.IoSourceHistoryDao; +import com.svnlan.home.domain.IoSourceHistory; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/25 13:30 + */ +@Component +public class SourceHistoryUtil { + + @Resource + IoSourceHistoryDao ioSourceHistoryDao; + + public void changeCheckSourceHistory(IoSourceHistory newHistory , IoSourceHistory ioSourceHistory){ + IoSourceHistory org = ioSourceHistoryDao.getHistoryInfoByFileId(ioSourceHistory.getSourceID(), ioSourceHistory.getFileID()); + // 添加历史记录 + try { + if (!ObjectUtils.isEmpty(org)){ + String detail = ObjectUtils.isEmpty(ioSourceHistory.getDetail()) ? "" : ioSourceHistory.getDetail(); + + ioSourceHistoryDao.updateSize(org.getId(), ioSourceHistory.getSize(),detail); + }else { + ioSourceHistoryDao.insert(ioSourceHistory); + } + } catch (Exception e) { + LogUtil.error(e, "添加历史记录失败 ioSourceHistory=" + JsonUtils.beanToJson(ioSourceHistory)); + } + + if (ObjectUtils.isEmpty(newHistory) || ObjectUtils.isEmpty(newHistory.getFileID())){ + return; + } + newHistory.setSize(ObjectUtils.isEmpty(newHistory.getSize()) ? 0L : newHistory.getSize()); + try { + ioSourceHistoryDao.insert(newHistory.initializefield()); + } catch (Exception e) { + LogUtil.error(e, "添加历史记录失败 newHistory=" + JsonUtils.beanToJson(ioSourceHistory)); + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/UserAuthTool.java b/src/main/java/com/svnlan/home/utils/UserAuthTool.java new file mode 100644 index 0000000..6fa6483 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/UserAuthTool.java @@ -0,0 +1,700 @@ +package com.svnlan.home.utils; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.I18nUtils; +import com.svnlan.enums.AuthEnum; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.HomeExplorerDao; +import com.svnlan.home.dao.IoSourceAuthDao; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.enums.CloudOperateEnum; +import com.svnlan.home.vo.HomeExplorerVO; +import com.svnlan.home.vo.IoSourceAuthVo; +import com.svnlan.home.vo.ParentPathDisplayVo; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.user.dao.GroupSourceDao; +import com.svnlan.user.dao.UserDao; +import com.svnlan.user.dao.UserGroupDao; +import com.svnlan.user.domain.GroupSource; +import com.svnlan.user.vo.UserGroupVo; +import com.svnlan.user.vo.UserVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.StringUtil; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/17 10:20 + */ +@Component +public class UserAuthTool { + + @Resource + StringRedisTemplate stringRedisTemplate; + @Resource + UserDao userDao; + @Resource + IoSourceAuthDao ioSourceAuthDao; + @Resource + UserGroupDao userGroupDao; + @Resource + GroupSourceDao groupSourceDao; + @Resource + IoSourceDao ioSourceDao; + @Resource + HomeExplorerDao homeExplorerDao; + + /** 后台权限 */ + public static final String[] manager = {"/api/disk/msgWarning", "/api/disk/setMsgWarning", "/api/disk/pluginList" , "/api/disk/setPlugin"}; + /** 概览 admin.index.dashboard */ + public static final String[] dashboard = {"/api/overview/visitRecord/list", "/api/overview/diskInfo/overview", "/api/overview/fileAndDevice/proportion"}; + /** 基本设置 admin.index.setting */ + public static final String[] setting = {"/api/disk/setSetting"}; + /** 角色权限列表 admin.role.list */ + public static final String[] roleList = {"/api/disk/role/list"}; + /** 角色权限编辑 admin.role.edit */ + public static final String[] roleEdit = {"/api/disk/role/edit","/api/disk/role/sort","/api/disk/role/remove"}; + /** 文档权限列表 admin.auth.list */ + public static final String[] authList = {}; + /** 文档权限编辑 admin.auth.edit */ + public static final String[] authEdit = {"/api/disk/auth/edit","/api/disk/auth/sort","/api/disk/auth/remove"}; + /** 部门与成员列表 admin.member.list */ + public static final String[] userList = {"/api/disk/group/list", "/api/disk/user/list", "/api/disk/group/search"}; + /** 编辑用户 admin.member.userEdit */ + public static final String[] userEdit = {"/api/disk/user/set", "/api/disk/user/edit"}; + /** 部门与成员列表 admin.member.groupEdit */ + public static final String[] groupEdit = {"/api/disk/group/remove", "/api/disk/group/set", "/api/disk/group/edit", "/api/disk/group/sort"}; + /** 存储列表 admin.storage.list */ + public static final String[] storageList = {}; + /** 存储操作 admin.storage.edit */ + public static final String[] storageEdit = {}; + + /** 文件夹 explorer.add */ + public static final String[] addDir = {"/api/disk/createFolder"}; + /** 上传 explorer.upload */ + public static final String[] upload = {"/api/disk/upload","/api/disk/upload/check"}; + /** 解压 explorer.unzip */ + public static final String[] unzip = {"/api/disk/unZip"}; + /** 压缩 explorer.zip */ + public static final String[] zip = {"/api/disk/zip"}; + /** 分享 explorer.share */ + public static final String[] share = {"/api/disk/userShare/save","/api/disk/userShare/cancel"}; + /** 查看资讯 explorer.informationView */ + public static final String[] informationView = {"/api/disk/getInfoList", "/api/disk/getHomepageDetail"}; + public static final String[] informationManage = {"/api/disk/saveInfoType","/api/disk/editInfoType","/api/disk/deleteInfoType" + ,"/api/disk/saveCommonInfo","/api/disk/editCommonInfo", "/api/disk/deleteInfo"}; + /** 编辑保存 explorer.edit*/ + public static final String[] edit = {"/api/disk/fileSave","/api/disk/fav/moveTop","/api/disk/fav/moveBottom","/api/disk/comment/del","/api/disk/comment/save"}; + /** 预览 explorer.view */ + public static final String[] view = {"/api/disk/preview","/api/disk/unzipList","/api/disk/preview/get","/api/disk/comment/list", "api/disk/pathLog","/api/disk/comment/list" + ,"/api/disk/pathLog"}; + /** 文档删除 explorer.remove */ + public static final String[] remove = {"/api/disk/setAuth","/api/disk/history/setVersion","/api/disk/history/delete","/api/disk/history/setDetail"}; + + + public void checkRoleAuthByTypeKey(LoginUser loginUser, String type) { + /** 权限 */ + Map roleMap = null; + if (loginUser.getUserType().intValue() == 1 ){ + return; + } + roleMap = this.getUserRoleMap(loginUser); + if (ObjectUtils.isEmpty(roleMap)) { + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + if (!roleMap.containsKey(type) || !"1".equals(roleMap.get(type).toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + } + + + /** 标签权限跟随 收藏权限 */ + public void checkUserTagPermission(LoginUser loginUser){ + this.checkRoleAuthByTypeKey(loginUser, "user.fav"); + } + + + public void checkUserPermission(LoginUser loginUser, CheckFileDTO updateFileDTO){ + Map roleMap = null; + if (loginUser.getUserType().intValue() == 1 ){ + return; + } + roleMap = this.getUserRoleMap(loginUser); + + if (ObjectUtils.isEmpty(roleMap)) { + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + CloudOperateEnum operateEnum = CloudOperateEnum.getOperateEnum(updateFileDTO.getOperation()); + LogUtil.info("checkUserPermission roleMap=" + JsonUtils.beanToJson(roleMap) + ", operateEnum=" + operateEnum.getOperate()); + try { + switch (operateEnum){ + case RENAME_FILE: + case FILE_DESC: + case ADD_TOP: + case CANCEL_TOP: + case FILE_COVER: + if (!roleMap.containsKey("explorer.edit") || !"1".equals(roleMap.get("explorer.edit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + break; + case COPY_FILE: + case MOVE_FILE: + if (!roleMap.containsKey("explorer.move") || !"1".equals(roleMap.get("explorer.move").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + break; + case DELETE_FILE: + case DELETE_BIN: + case DELETE_BIN_ALL: + if (!roleMap.containsKey("explorer.remove") || !"1".equals(roleMap.get("explorer.remove").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + break; + case SHARE_FILE: + if (!roleMap.containsKey("explorer.share") || !"1".equals(roleMap.get("explorer.share").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + break; + case FAV_FILE: + case FAV_DEL: + if (!roleMap.containsKey("user.fav") || !"1".equals(roleMap.get("user.fav").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + break; + case MAKE_FILE: + if (!roleMap.containsKey("explorer.add") || !"1".equals(roleMap.get("explorer.add").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + break; + case RECYCLE_FILE_ALL: + case RECYCLE_FILE: + break; + default: + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }catch (Exception e){ + LogUtil.error(e, "校验用户权限"); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + + } + + public Map getUserRoleMap(LoginUser loginUser){ + Map roleMap = null; + + Long userID = loginUser.getUserID(); + // 权限 + String userRoleKey = GlobalConfig.userRoleAuth_key; + HashOperations operations = stringRedisTemplate.opsForHash(); + String value = operations.get(userRoleKey, userID + ""); + if (!ObjectUtils.isEmpty(value)) { + try { + roleMap = JsonUtils.jsonToMap(value); + }catch (Exception e){ + LogUtil.error(e, "updateFile 缓存解析失败 key=" + userRoleKey + ",userID=" + userID + ",value=" + value); + } + } + if (ObjectUtils.isEmpty(roleMap)) { + UserVo userVo = userDao.getUserInfo(userID); + roleMap = ObjectUtils.isEmpty(userVo.getAuth()) ? null : AuthEnum.getUserAuthMap(userVo.getAuth()); + } + return roleMap; + } + + public Boolean checkManageAuth(LoginUser loginUser, String uri){ + if (loginUser.getUserType().intValue() == 1){ + return true; + } + Map roleMap = this.getUserRoleMap(loginUser); + + if (!ObjectUtils.isEmpty(roleMap)){ + String v = JsonUtils.beanToJson(roleMap); + if (Arrays.asList(manager).contains(uri)){ + // 管理后台权限 + if (v.indexOf("admin") < 0){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + } + } + LogUtil.info("checkManageAuth uri= " + uri); + if (Arrays.asList(dashboard).contains(uri)){ + if (!roleMap.containsKey("admin.index.dashboard") || !"1".equals(roleMap.get("admin.index.dashboard").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(setting).contains(uri)){ + if (!roleMap.containsKey("admin.index.setting") || !"1".equals(roleMap.get("admin.index.setting").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(roleList).contains(uri)){ + if (!roleMap.containsKey("admin.role.list") || !"1".equals(roleMap.get("admin.role.list").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(roleEdit).contains(uri)){ + if (!roleMap.containsKey("admin.role.edit") || !"1".equals(roleMap.get("admin.role.edit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(authList).contains(uri)){ + if (!roleMap.containsKey("admin.auth.list") || !"1".equals(roleMap.get("admin.auth.list").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(authEdit).contains(uri)){ + if (!roleMap.containsKey("admin.auth.edit") || !"1".equals(roleMap.get("admin.auth.edit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(userList).contains(uri)){ + if (!roleMap.containsKey("admin.member.list") || !"1".equals(roleMap.get("admin.member.list").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(userEdit).contains(uri)){ + if (!roleMap.containsKey("admin.member.userEdit") || !"1".equals(roleMap.get("admin.member.userEdit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(groupEdit).contains(uri)){ + if (!roleMap.containsKey("admin.member.groupEdit") || !"1".equals(roleMap.get("admin.member.groupEdit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(storageList).contains(uri)){ + if (!roleMap.containsKey("admin.storage.list") || !"1".equals(roleMap.get("admin.storage.list").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(storageEdit).contains(uri)){ + if (!roleMap.containsKey("admin.storage.edit") || !"1".equals(roleMap.get("admin.storage.edit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(addDir).contains(uri)){ + if (!roleMap.containsKey("explorer.add") || !"1".equals(roleMap.get("explorer.add").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(upload).contains(uri)){ + if (!roleMap.containsKey("explorer.upload") || !"1".equals(roleMap.get("explorer.upload").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(unzip).contains(uri)){ + if (!roleMap.containsKey("explorer.unzip") || !"1".equals(roleMap.get("explorer.unzip").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(zip).contains(uri)){ + if (!roleMap.containsKey("explorer.zip") || !"1".equals(roleMap.get("explorer.zip").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(share).contains(uri)){ + if (!roleMap.containsKey("explorer.share") || !"1".equals(roleMap.get("explorer.share").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(informationManage).contains(uri)){ + if (!roleMap.containsKey("admin.index.information") || !"1".equals(roleMap.get("admin.index.information").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(informationView).contains(uri)){ + if (!roleMap.containsKey("explorer.informationView") || !"1".equals(roleMap.get("explorer.informationView").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(view).contains(uri)){ + if (!roleMap.containsKey("explorer.view") || !"1".equals(roleMap.get("explorer.view").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(edit).contains(uri)){ + if (!roleMap.containsKey("explorer.edit") || !"1".equals(roleMap.get("explorer.edit").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + }else if (Arrays.asList(remove).contains(uri)){ + if (!roleMap.containsKey("explorer.remove") || !"1".equals(roleMap.get("explorer.remove").toString())){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAction.getCode()); + } + } + + return true; + } + + /** 文档权限 1查看、2搜索、3预览、4下载、5上传、6压缩、7解压、8编辑、9新增、10删除、11分享、12评论、13动态、14管理权限 **/ + public boolean checkGroupDocAuth(LoginUser loginUser, Long sourceId, String parentLevel, String checkAuth, Integer targetType){ + return checkGroupDocAuth(loginUser, sourceId, parentLevel, checkAuth, targetType, true); + } + public boolean checkGroupDocAuth(LoginUser loginUser, Long sourceId, String parentLevel, String checkAuth, Integer targetType, boolean checkParent){ + if (!ObjectUtils.isEmpty(targetType) && targetType.intValue() != 2){ + return true; + } + if (!ObjectUtils.isEmpty(loginUser) && loginUser.getUserType().intValue() == 1){ + return true; + } + Long userId = loginUser.getUserID(); + + List checkAuthList = Arrays.asList(checkAuth.split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Integer::valueOf).collect(Collectors.toList()); + + List sourceIds = new ArrayList<>(); + List parentIds = null; + if (!",0,".equals(parentLevel)){ + parentIds = Arrays.asList(parentLevel.split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Long::parseLong).collect(Collectors.toList()); + sourceIds.addAll(parentIds); + } + if (!sourceIds.contains(sourceId)) { + sourceIds.add(sourceId); + } + // 用户所在部门 + List myGroupList = this.getUserGroupAuth(userId); + // 文件及上级文件夹单独设置的权限 + List allReList = ioSourceAuthDao.getSourceAuthBySourceIDList(sourceIds, userId); + if (!CollectionUtils.isEmpty(allReList)){ + for (int i = sourceIds.size(); i-- > 0; ) { + Long sID = sourceIds.get(i); + List userList = allReList.stream().filter(n-> n.getSourceID().equals(sID) && n.getTargetType().intValue() == 1 && n.getTargetID() > 0).collect(Collectors.toList()); + List groupList = allReList.stream().filter(n-> n.getSourceID().equals(sID) && n.getTargetType().intValue() == 2).collect(Collectors.toList()); + List otherUserList = allReList.stream().filter(n-> n.getSourceID().equals(sID) && n.getTargetType().intValue() == 1 && n.getTargetID().longValue() == 0).collect(Collectors.toList()); + // 用户权限 + if (!CollectionUtils.isEmpty(userList)){ + userList.forEach(n->{ + if (n.getTargetID().longValue() == userId) { + if (ObjectUtils.isEmpty(n.getAuth())) { + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:1:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s", userId, sourceId, parentLevel, checkAuth, targetType, parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList) { + if (authList.contains(a)) { + c = true; + } + } + if (!c) { + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:2:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s", userId, sourceId, parentLevel, checkAuth, targetType, parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + } + }); + return true; + } + if (!CollectionUtils.isEmpty(groupList)){ + boolean check = false; + if (!CollectionUtils.isEmpty(myGroupList)){ + // 指定部门 + for(IoSourceAuthVo n : groupList){ + for (UserGroupVo vo : myGroupList){ + if (n.getTargetID().longValue() == vo.getGroupID()){ + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (!c){ + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:3:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s",userId,sourceId,parentLevel,checkAuth,targetType, parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + check = true; + } + } + } + if (check){ + return true; + } + } + } + // 其他人权限 + if (!CollectionUtils.isEmpty(otherUserList)){ + for(IoSourceAuthVo n : otherUserList){ + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (!c){ + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:5:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s",userId,sourceId,parentLevel,checkAuth,targetType,parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + } + } + // 指定部门的上一级部门 + if (!CollectionUtils.isEmpty(groupList)){ + + boolean check = false; + boolean checkIn = false; + // 指定部门的上级部门 + for(IoSourceAuthVo n : groupList){ + for (UserGroupVo vo : myGroupList){ + List parentIDLists = Arrays.asList(vo.getParentLevel().split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(parentIDLists) ){ + if (parentIDLists.contains(n.getTargetID())){ + checkIn = true; + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (c){ + check = true; + } + } + } + } + } + if (check){ + return true; + } + // 设置了但是没有权限 + if (checkIn){ + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:4:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s",userId,sourceId,parentLevel,checkAuth,targetType,parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + } + } + } + // 单独设置权限 end + List searchSourceIds = new ArrayList(); + if (checkParent){ + searchSourceIds = sourceIds; + }else { + searchSourceIds.add(sourceId); + } + // 文件夹权限及上级文件夹权限 + List allReturnList = groupSourceDao.getGroupSourceList(new ArrayList<>(searchSourceIds)); + if ((checkParent && CollectionUtils.isEmpty(allReturnList)) || CollectionUtils.isEmpty(myGroupList)){ + // 没有部门则没有权限 + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:6:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s",userId,sourceId,parentLevel,checkAuth,targetType,parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + Map AuthGroupMap = myGroupList.stream().collect(Collectors.toMap(UserGroupVo::getGroupID, Function.identity(), (v1, v2) -> v2)); + Map sourceGroupMap = allReturnList.stream().collect(Collectors.toMap(GroupSource::getSourceID, GroupSource::getGroupID, (v1, v2) -> v2)); + for (int i = searchSourceIds.size(); i-- > 0; ) { + Long sID = searchSourceIds.get(i); + if (sourceGroupMap.containsKey(sID)){ + long groupId = sourceGroupMap.get(sID); + if (AuthGroupMap.containsKey(groupId)){ + UserGroupVo userGroupVo = AuthGroupMap.get(groupId); + List authList = Arrays.asList(userGroupVo.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (!c){ + String parentPathDis = getSourceParentPath(sourceId, parentLevel); + LogUtil.error(String.format("权限不足:7:userId=%s,sourceId=%s,parentLevel=%s,checkAuth=%s,targetType=%s,parentPathDis=%s",userId,sourceId,parentLevel,checkAuth,targetType,parentPathDis)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + }else { + return true; + } + } + } + } + + // 文件夹权限及上级文件夹权限 end + return true; + } + /** 用于校验 checkGroupDocAuth 后再校验 */ + public boolean checkGroupDocAuthOther(LoginUser loginUser, List sourceIds, String checkAuth, Integer targetType){ + if (!ObjectUtils.isEmpty(targetType) && targetType.intValue() != 2){ + return true; + } + if (CollectionUtils.isEmpty(sourceIds)){ + return true; + } + if (!ObjectUtils.isEmpty(loginUser) && loginUser.getUserType().intValue() == 1){ + return true; + } + Long userId = loginUser.getUserID(); + List checkAuthList = Arrays.asList(checkAuth.split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Integer::valueOf).collect(Collectors.toList()); + + Map checkResultMap = new HashMap<>(); + // 用户所在部门 + List myGroupList = this.getUserGroupAuth(userId); + // 文件及上级文件夹单独设置的权限 + List allReList = ioSourceAuthDao.getSourceAuthBySourceIDList(sourceIds, userId); + if (!CollectionUtils.isEmpty(allReList)){ + for (int i = sourceIds.size(); i-- > 0; ) { + Long sID = sourceIds.get(i); + List userList = allReList.stream().filter(n-> n.getSourceID().equals(sID) && n.getTargetType().intValue() == 1 && n.getTargetID() > 0).collect(Collectors.toList()); + List groupList = allReList.stream().filter(n-> n.getSourceID().equals(sID) && n.getTargetType().intValue() == 2).collect(Collectors.toList()); + List otherUserList = allReList.stream().filter(n-> n.getSourceID().equals(sID) && n.getTargetType().intValue() == 1 && n.getTargetID().longValue() == 0).collect(Collectors.toList()); + // 用户权限 + if (!CollectionUtils.isEmpty(userList)){ + userList.forEach(n->{ + if (n.getTargetID().longValue() == userId) { + if (ObjectUtils.isEmpty(n.getAuth())) { + String parentPathDis = getSourceParentPath(n.getSourceID(), null); + LogUtil.error(String.format("权限不足Other:1:userId=%s,sourceId=%s,parentPathDis=%s,checkAuth=%s", userId, n.getSourceID(), parentPathDis, checkAuth)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList) { + if (authList.contains(a)) { + c = true; + } + } + if (!c) { + String parentPathDis = getSourceParentPath(n.getSourceID(), null); + LogUtil.error(String.format("权限不足Other:2:userId=%s,sourceId=%s,parentPathDis=%s,checkAuth=%s", userId, n.getSourceID(), parentPathDis, checkAuth)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + checkResultMap.put(n.getSourceID(), true); + } + }); + + } + if (!CollectionUtils.isEmpty(groupList)){ + boolean check = false; + + if (!CollectionUtils.isEmpty(myGroupList)){ + // 指定部门 + for(IoSourceAuthVo n : groupList){ + if (checkResultMap.containsKey(n.getSourceID())){ + continue; + } + for (UserGroupVo vo : myGroupList){ + if (n.getTargetID().longValue() == vo.getGroupID()){ + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (!c){ + String parentPathDis = getSourceParentPath(n.getSourceID(), null); + LogUtil.error(String.format("权限不足Other:3:userId=%s,sourceId=%s,parentPathDis=%s,checkAuth=%s",userId,n.getSourceID(), parentPathDis,checkAuth)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + check = true; + } + } + checkResultMap.put(n.getSourceID(),true); + } + boolean checkIn = false; + // 指定部门的上级部门 + for(IoSourceAuthVo n : groupList){ + if (checkResultMap.containsKey(n.getSourceID())){ + continue; + } + for (UserGroupVo vo : myGroupList){ + List parentIDLists = Arrays.asList(vo.getParentLevel().split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Long::parseLong).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(parentIDLists) ){ + if (parentIDLists.contains(n.getTargetID())){ + checkIn = true; + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (c){ + check = true; + } + } + } + } + // 设置了但是没有权限 + if (checkIn && !check){ + String parentPathDis = getSourceParentPath(n.getSourceID(), null); + LogUtil.error(String.format("权限不足Other:4:userId=%s,sourceId=%s,parentPathDis=%s,checkAuth=%s",userId,n.getSourceID(), parentPathDis,checkAuth)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + checkResultMap.put(n.getSourceID(),true); + } + } + } + // 其他人权限 + if (!CollectionUtils.isEmpty(otherUserList)){ + for(IoSourceAuthVo n : otherUserList){ + if (checkResultMap.containsKey(n.getSourceID())){ + continue; + } + List authList = Arrays.asList(n.getAuth().split(",")).stream().map(Integer::valueOf).collect(Collectors.toList()); + boolean c = false; + for (int a : checkAuthList){ + if (authList.contains(a)){ + c = true; + } + } + if (!c){ + String parentPathDis = getSourceParentPath(n.getSourceID(), null); + LogUtil.error(String.format("权限不足Other:5:userId=%s,sourceId=%s,parentPathDis=%s,checkAuth=%s",userId,n.getSourceID(), parentPathDis,checkAuth)); + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{parentPathDis}); + } + } + } + } + } + return true; + } + + public List getUserGroupAuth(Long userID){ + // 用户群组权限 + List userGroupList = null; + String key = GlobalConfig.REDIS_KEY_USER_GROUP_AUTH; + + HashOperations operations = stringRedisTemplate.opsForHash(); + String value = operations.get(key, userID+""); + if (!ObjectUtils.isEmpty(value)) { + try { + userGroupList = JsonUtils.stringToList(value, UserGroupVo.class); + // JSON.parseArray(JSON.toJSONString(value), UserGroupVo.class); + }catch (Exception e){ + LogUtil.error(e, "getUserGroupAuth 缓存解析失败 key=" + key + ",value=" + value); + } + } + if (ObjectUtils.isEmpty(userGroupList)) { + userGroupList = userGroupDao.getUserGroupInfoList(Arrays.asList(userID)); + operations.put(key, userID+"", JsonUtils.beanToJson(userGroupList)); + operations.getOperations().expire(key, 30, TimeUnit.MINUTES); + } + LogUtil.info("getUserGroupAuth******************** userGroupList=" + JsonUtils.beanToJson(userGroupList)); + return userGroupList; + } + + /** 文件路径、文件夹路径、路径全称path */ + private String getSourceParentPath(Long sourceId, String parentLevel){ + + List parentIDLists = null; + if (!ObjectUtils.isEmpty(parentLevel)){ + parentIDLists = Arrays.asList(parentLevel.split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Long::parseLong).collect(Collectors.toList()); + }else { + HomeExplorerVO parentInfo = homeExplorerDao.getOneSourceInfo(sourceId); + parentIDLists = Arrays.asList(parentInfo.getParentLevel().split(",")).stream().filter(n1 -> !ObjectUtils.isEmpty(n1) && !"0".equals(n1)).map(Long::parseLong).collect(Collectors.toList()); + } + if (CollectionUtils.isEmpty(parentIDLists)){ + parentIDLists = new ArrayList<>(); + } + parentIDLists.add(sourceId); + Map map = new HashMap<>(parentIDLists.size()); + List list = ioSourceDao.getParentPathDisplayByIds(parentIDLists); + if (!CollectionUtils.isEmpty(list)) { + map = list.stream().collect(Collectors.toMap(ParentPathDisplayVo::getSourceID, ParentPathDisplayVo::getName, (v1, v2) -> v2)); + } + List nameList = new ArrayList<>(); + for (Long id : parentIDLists) { + if (map.containsKey(id)) { + nameList.add(map.get(id)); + } + } + return CollectionUtils.isEmpty(nameList) ? "" : StringUtil.joinString(nameList, "/"); + + } +} diff --git a/src/main/java/com/svnlan/home/utils/office/LibreOfficeDUtil.java b/src/main/java/com/svnlan/home/utils/office/LibreOfficeDUtil.java new file mode 100644 index 0000000..ecc598a --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/office/LibreOfficeDUtil.java @@ -0,0 +1,134 @@ +package com.svnlan.home.utils.office; + +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import com.svnlan.utils.StringUtil; +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * @description: libreoffice操作工具类 + */ +public class LibreOfficeDUtil { + + /** + * @description: libreOffice转换命令执行 + * @param prefix + * @param libreOfficeVersion + * @param targetType + * @param sourceFilePath + * @param targetDir + * @return java.lang.Boolean + */ + public static Boolean libreOfficeCommand(String prefix, String libreOfficeVersion, String targetType, String sourceFilePath, String targetDir) { + prefix += String.format("libreOfficeCommand(%s)>>>", RandomUtil.getuuid()); + Boolean success = Boolean.TRUE; + + List convert = new ArrayList<>(); + convert.add(libreOfficeVersion); + convert.add("--headless"); + convert.add("--convert-to"); + convert.add(targetType); + convert.add(sourceFilePath); + convert.add("--outdir"); + convert.add(targetDir); + + ProcessBuilder builder = new ProcessBuilder(); + InputStream in = null; + int runningStatus = 0; + try { + StringBuilder sb = new StringBuilder(); + for (String a : convert){ + sb.append(a); + sb.append(" "); + } + LogUtil.info(prefix + "转换命令: " + sb.toString()); + builder.command(convert); + Process process = builder.start(); + in = process.getErrorStream(); + String errorString = IOUtils.toString(in, "UTF-8"); + if (!StringUtil.isEmpty(errorString)){ + LogUtil.error(prefix + "转换返回的错误信息" + errorString); + } + try { + runningStatus = process.waitFor(); + } catch (InterruptedException e) { + success = false; + LogUtil.error(e, prefix + String.format("转换process.waitFor()中断异常")); + } + } catch (Exception e) { + LogUtil.error(e, prefix + "转换异常的返回信息"); + success = false; + } finally { + if (in != null){ + try { + in.close(); + } catch (Exception e){ + LogUtil.error(prefix + "关闭流失败"); + } + } + } + if(0 != runningStatus) { + success = false; + LogUtil.error(prefix + String.format("转换异常,错误码:%d", runningStatus)); + } + return success; + } + + /** + * @description: 调用shell脚本执行转换为docx文件 + * @param prefix + * @param shellFileDirectory + * @param shellFileName + * @param sourceFilePath + * @param targetDir + * @return java.lang.Boolean + */ + public static Boolean libreOfficeToDocxByShell(String prefix, String shellFileDirectory, String shellFileName, + String sourceFilePath, String targetDir) { + prefix += String.format("libreOfficeToDocxByShell(%s)>>>", RandomUtil.getuuid()); + Boolean success = Boolean.TRUE; + + ProcessBuilder builder = new ProcessBuilder(); + InputStream in = null; + int runningStatus = 0; + try { + LogUtil.info(prefix + "转换命令: " + shellFileDirectory + " " + "./" + shellFileName + " " + sourceFilePath + " " + targetDir); + builder.command("./" + shellFileName, sourceFilePath, targetDir); + builder.directory(new File(shellFileDirectory)); + Process process = builder.start(); + in = process.getErrorStream(); + String errorString = IOUtils.toString(in, "UTF-8"); + if (!StringUtil.isEmpty(errorString)){ + LogUtil.error(prefix + "转换返回的错误信息" + errorString); + } + try { + runningStatus = process.waitFor(); + } catch (InterruptedException e) { + success = false; + LogUtil.error(e, prefix + String.format("转换process.waitFor()中断异常")); + } + } catch (Exception e) { + LogUtil.error(e, prefix + "转换异常的返回信息"); + success = false; + } finally { + if (in != null){ + try { + in.close(); + } catch (Exception e){ + LogUtil.error(prefix + "关闭流失败"); + } + } + } + if(0 != runningStatus) { + success = false; + LogUtil.error(prefix + String.format("转换异常,错误码:%d", runningStatus)); + } + return success; + } + +} \ No newline at end of file diff --git a/src/main/java/com/svnlan/home/utils/video/VideoGetUtil.java b/src/main/java/com/svnlan/home/utils/video/VideoGetUtil.java new file mode 100644 index 0000000..cf4783a --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/video/VideoGetUtil.java @@ -0,0 +1,1015 @@ +package com.svnlan.home.utils.video; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.MarkUrlDto; +import com.svnlan.home.dto.VideoCommonDto; +import com.svnlan.home.dto.VideoCutDto; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.utils.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.io.*; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.concurrent.Future; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/17 13:14 + */ +@Component +public class VideoGetUtil { + + private static final Logger log = LoggerFactory.getLogger("error"); + + /** + * 开启线程处理Ffmpeg处理流 + * + * @param process + */ + private static void dealStream(Process process) { + if (process == null) { + return; + } + // 处理InputStream的线程 + new Thread() { + @Override + public void run() { + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line = null; + try { + while ((line = in.readLine()) != null) { + LogUtil.info( "处理InputStream的线程 warn output: " + line); + } + } catch (IOException e) { + LogUtil.error(e, "处理InputStream的线程 error"); + } finally { + try { + in.close(); + } catch (IOException e) { + LogUtil.error(e, "处理InputStream的线程 error"); + } + } + } + }.start(); + // 处理ErrorStream的线程 + new Thread() { + @Override + public void run() { + BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line = null; + try { + while ((line = err.readLine()) != null) { + LogUtil.info( "处理ErrorStream的线程 warn output: " + line); + } + } catch (IOException e) { + LogUtil.error(e, "处理ErrorStream的线程 error"); + } finally { + try { + err.close(); + } catch (IOException e) { + LogUtil.error(e, "处理ErrorStream的线程 error"); + } + } + } + }.start(); + } + /** + * 截取一帧作为图片 + * + * @param path + * ffmpeg -i /Users/jinx/Downloads/test.mp4 -y -f image2 -ss + * 00:00:01 -vframes 1 /Users/jinx/Downloads/test.jpeg + * @return + */ + public static boolean covPic( String path, String time, String outName, String size) { + + int[] heightAndWidth; + String resolution = ""; + try { + heightAndWidth = VideoUtil.getHeightAndWidthAndduration(path); + } catch (Exception e){ + LogUtil.error("获取视频宽高失败, path: " + path + ", e: " + e.getMessage()); + heightAndWidth = new int[]{0, 0, 0}; + } + int duration = 3; + try { + if (heightAndWidth[2] != 0 && heightAndWidth[2] < 3) { + duration = 1; + } + }catch (Exception e){ + LogUtil.error("获取视频宽高失败2, path: " + path + ", e: " + e.getMessage()); + } + + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(path);//文件输入源 + command.add("-y"); + command.add("-f"); + command.add("image2"); + command.add("-ss"); + command.add(time);//截取的时间点格式为 00:00:01 + command.add("-t"); // 添加参数"-t",该参数指定持续时间 + command.add("0.001"); // 添加持续时间为1毫秒 + command.add("-vframes"); + command.add("1"); + command.add("-s"); + if (heightAndWidth[0] != 0 && heightAndWidth[1] != 0) { + command.add("" + heightAndWidth[1] + "*" + heightAndWidth[0]); + } else { + command.add("1280*720"); //截取的图片大小,格式为:1920x1080 + } + command.add(outName);//文件输出路径,格式为 11.jpg + + + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("covPic cmd:" + sb.toString()); + + return execCommand(command); + } + + /** + * 视频截图 + * @param tempVideoPath 视频路径 + * @param beginN 第几帧开始 + * @param beginN 第几帧结束 + * @param tempImgPath 从视频中截取多张图片 + * @param frameInterval 间隔多少帧取图片 + * 多个-vf 会覆盖前面的 + */ + public static boolean covPicBatch( String tempVideoPath, String tempImgPath, Integer beginN, Integer endN, Integer frameInterval) { + + LogUtil.info("covPicBatch beginN=" + beginN + ",endN=" + endN); + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(tempVideoPath);//文件输入源 + command.add("-vf"); + command.add("select='between\\(n\\,"+(beginN)+"\\,"+ (endN) +"\\)*not\\(mod\\(n\\,"+ frameInterval +"\\)\\)',scale=-1:64"); + command.add("-vsync"); + command.add("2"); + command.add("-f"); + command.add("image2"); + command.add(tempImgPath);//文件输出路径,格式为 11.jpg + + /* + ffmpeg -i /uploads/private/cloud/2023_5/25/3925493832a24b67a16cb94ffb139dd21684998268922_1.mp4 -q 20 -vf select='between\(n\,0\,3288\)*not\(mod\(n\,24\)\)',scale=-1:32 -vsync 0 /uploads/common/down_temp/private/cloud/2023_5/25/3925493832a24b67a16cb94ffb139dd21684998268922_1/25d23d8b950b4df1b2532967fb4e3384/2_137_2/3925493832a24b67a16cb94ffb139dd21684998268922_1_mp4_cut_%02d.jpg + + */ + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("covPicBatch cmd:" + sb.toString()); + return execCommand(command); + } + + /** + * 视频截图 + * @param tempVideoPath 视频路径 + * @param beginN 开始时间 + * @param tempImgPath 从视频中截取图片 + */ + public static boolean covPicBatch(String tempVideoPath, String tempImgPath, String beginN) { + return covPicBatch(tempVideoPath, tempImgPath, beginN, true); + } + public static boolean covPicBatch(String tempVideoPath, String tempImgPath, String beginN, boolean isSetResolution) { + LogUtil.info("covPicBatch begin进入流程 : beginN"+ beginN + ",time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-ss"); + command.add(beginN); + command.add("-i"); + command.add(tempVideoPath);//文件输入源 + // 是否设置分辨率 + if (isSetResolution) { + command.add("-vf"); + command.add("scale=-1:100"); + } + command.add("-f"); + command.add("image2"); + command.add(tempImgPath);//文件输出路径,格式为 11.jpg + /* + ffmpeg -ss 00:02:06 -i test1.flv -f image2 -y test1.jpg + */ + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("covPicBatch cmd:" + sb.toString()); + LogUtil.info("covPicBatch end : time=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS) ); + return execCommand(command); + } + + /** + * @Description: + * @params: [tempVideoPath, tempImgPath, beginN, endN, frameInterval] + * @Modified: + */ + public static boolean covPicBatch(String tempVideoPath, String tempImgPath, String beginN, String endN, String frameInterval) { + /** ffmpeg -ss 5 -i test.mp4 -t 20 t.mp4 + * 截取视频的 5-25秒 + -ss 开始时间 + -t截取时间 + -r每秒取多少帧 + */ + LogUtil.info("covPicBatch begin beginN=" + beginN + ",endN=" + endN); + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-ss"); + command.add(beginN); + command.add("-i"); + command.add(tempVideoPath);//文件输入源 + command.add("-t"); + command.add(endN); + command.add("-r"); + command.add(frameInterval); + command.add("-vf"); + command.add("scale=-1:64"); + command.add("-f"); + command.add("image2"); + command.add(tempImgPath);//文件输出路径,格式为 11.jpg + /* + ffmpeg -i input.mp4 -ss 00:00:20 -t 10 -r 1 -q:v 2 -f image2 pic-%03d.jpeg + + */ + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("covPicBatch end beginN=" + beginN + ",endN=" + endN + " cmd:" + sb.toString()); + return execCommand(command); + } + + /** + * 视频截图 + * @param tempVideoPath 原视频路径 + * @param timeVoList 截取时间段列表 + * @param tempOutPath 从视频中截取多张图片 + */ + public static List covCutBatch( String tempVideoPath, String tempOutPath, List timeVoList, VideoCommonDto videoCommonDto, ThreadPoolTaskExecutor executor) { + + LogUtil.info("covCutBatch tempVideoPath=" + tempVideoPath + ",tempOutPath=" + tempOutPath + ",timeVo=" + JsonUtils.beanToJson(timeVoList)); + + List cutList = new ArrayList<>(); + + + int i = 1; + boolean check = true; + + String tempOrgPath = ""; + // 校验是否需要设置 + boolean settingCheck = checkIsSettingVideo(videoCommonDto) ; + Boolean settingResult = false; + if (settingCheck){ + // 原文件 + videoCommonDto.setVideoPathOrg(tempVideoPath); + + tempOrgPath = tempOutPath.replace("_%02d." , "_temp."); + videoCommonDto.setFinalFilePath(tempOrgPath); + // 先设置再切 + settingResult = configVideoMerge(videoCommonDto); + } + //使用Future方式执行多任务 + //生成一个集合 + List futures = new ArrayList<>(); + for (VideoCutDto cutDto : timeVoList){ + String tempOut = String.format(tempOutPath, i); + cutDto.setPath(tempOut); + + Future future = executor.submit(() -> { + LogUtil.info("covCutBatch slipt future tempOut=" + tempOut + ", beginTime=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS)); + List command = new ArrayList<>(); + /* ffmpeg -ss 2:05 -i input.mp4 -t 20 -c:v copy -c:a copy output.mp4 + 这里把-ss 2:05 放在前面,与原来的区别是,这样会先跳转到第2:05开始解码,而原来的会从开始开始解码,会将2:05前的结果丢掉 + -t 持续时间 + -c:v 和 -c:a 分别指视频编码格式和音频编码格式 + -c:v copy 和 -c:v copy 指的是视频的编码格式不变,直接复制,从而加快速度 */ + command.add("ffmpeg"); + command.add("-ss"); + command.add(cutDto.getBeginTime() + ""); + command.add("-i"); + command.add(tempVideoPath);//文件输入源 + command.add("-t"); + command.add((cutDto.getDuration()) + ""); + command.add("-c:v"); + command.add("copy"); + command.add("-c:a"); + command.add("copy"); + command.add(tempOut);//文件输出路径 + + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("covPicBatch cmd:" + sb.toString()); + try { + Process videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + cutList.add(tempOut); + } catch (Exception e) { + LogUtil.error(e, "covPicBatch error"); + } + LogUtil.info("covCutBatch slipt future tempOut=" + tempOut + ", endTime=" + DateDUtil.getYearMonthDayHMS(new Date(), DateDUtil.YYYY_MM_DD_HH_MM_SS)); + }); + futures.add(future); + i ++; + } + + if (!CollectionUtils.isEmpty(futures)){ + try { + //查询任务执行的结果 + for (Future future : futures) { + while (true) {//CPU高速轮询:每个future都并发轮循,判断完成状态然后获取结果,这一行,是本实现方案的精髓所在。即有10个future在高速轮询,完成一个future的获取结果,就关闭一个轮询 + if (future.isDone() && !future.isCancelled()) {//获取future成功完成状态,如果想要限制每个任务的超时时间,取消本行的状态判断+future.get(1000*1, TimeUnit.MILLISECONDS)+catch超时异常使用即可。 + + LogUtil.info("covCutBatch 任务i=" + future.get() + "获取完成!" + new Date()); + break;//当前future获取结果完毕,跳出while + } else { + Thread.sleep(1);//每次轮询休息1毫秒(CPU纳秒级),避免CPU高速轮循耗空CPU + } + } + } + }catch (Exception e){ + LogUtil.error(e, "covCutBatch error "); + } + } + + if (settingResult && !ObjectUtils.isEmpty(tempOrgPath)){ + try { + File dampFile = new File(tempOrgPath); + if (dampFile.exists()){ + dampFile.delete(); + } + }catch (Exception e){ + LogUtil.error(e, "covCutBatch configVideoMerge delete error tempOrgPath=" + tempOrgPath); + } + } + + if (!check){ + return new ArrayList<>(); + } + return cutList; + } + + /** + * @Description: 异步合并剪切的视频 + * @params: cutList 剪切的视频路径列表 + * @params: finishPath 合并完成的最终视频 + * @params: suffix 文件后缀 + * @params: tempPath temp路径 + */ + public static Boolean cutVideoMerge(List cutList, String finishPath, String suffix, String tempPath,List tsList) { + /* + ffmpeg -i 1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 1.ts +ffmpeg -i 2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 2.ts +ffmpeg -i "concat:1.ts|2.ts" -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4 + + */ + Long time = System.currentTimeMillis(); + + Process videoProcess = null; + List command = null; + StringBuilder sb = null; + StringBuilder sbtxt = new StringBuilder(); + String tempTxt = cutList.get(0).replace("." + suffix, time + "_fileList.txt"); + tsList.add(tempTxt); + + int i = 1; + boolean check = true; + LogUtil.info("cutVideoMerge finishPath=" + finishPath + + ",suffx=" + suffix + + ",tempPath=" + tempPath + + ", cutList=" + JsonUtils.beanToJson(cutList)); + for (String path : cutList){ + command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(path); + command.add("-vcodec"); + command.add("copy"); + command.add("-acodec"); // + command.add("copy"); + command.add("-vbsf"); + command.add("h264_mp4toannexb"); + String tsPath = path.replace("." + suffix, time+ "_" + i + ".ts"); + command.add(tsPath);//文件输入源 + if (i == 1) { + sbtxt.append("file '" + tsPath +"'"); + }else { + sbtxt.append("\nfile '" + tsPath +"'"); + } + // ffmpeg -i 01.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 01.ts + tsList.add(path.replace("." + suffix, ".ts")); + sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("cutVideoMerge sbtxt=" + sbtxt.toString()); + LogUtil.info("cutVideoMerge cmd:" + sb.toString()); + try { + videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + } catch (Exception e) { + check = false; + LogUtil.error(e, "cutVideoMerge error"); + break; + } + i ++; + } + if (!check){ + return false; + } + File finishTxtFile = new File(tempTxt); + byte[] size = sbtxt.toString().getBytes(StandardCharsets.UTF_8); + FileInputStream fis = null; + try { + FileUtil.writeFile(finishTxtFile, size); + fis = new FileInputStream(finishTxtFile); + fis.close(); + } catch (IOException e) { + LogUtil.error(e.getMessage(), " cutVideoMerge 创建文件失败 tempTxt=" + tempTxt); + return false; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + LogUtil.error(e); + } + } + } + + // ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav + command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-f"); + command.add("concat"); + command.add("-safe"); + command.add("0"); + command.add("-i"); + command.add(tempTxt); + command.add("-c"); + command.add("copy"); + command.add(finishPath);//文件输入源 + sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("cutVideoMerge cmd:" + sb.toString()); + try { + videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + } catch (Exception e) { + check = false; + LogUtil.error(e, "cutVideoConcate error"); + } + + return check; + } + + /** + * @Description: 转码视频 + * @params: path 原视频路径 + * @params: finishPath 合并完成的最终视频 + * @params: resolution 分辨率 + * @params: frameRate 帧率 + */ + public static Boolean convertVideoMerge(String path, String finishPath, String resolution, Integer frameRate) { + + boolean check = true; + Process videoProcess = null; + List command = null; + StringBuilder sb = null; + LogUtil.info("convertVideoMerge finishPath=" + finishPath + + ", path=" + path); + /* 【参数说明】 -s 1920x1080:调整分辨率 -r 24:调整帧率 */ + // ffmpeg -i input.mp4  -s 1920x1080 -r 24  output.mp4 -vcodec h264 -b:v 0 + + + int[] heightAndWidth; + try { + heightAndWidth = VideoUtil.getHeightAndWidthAndduration(path); + } catch (Exception e){ + LogUtil.error("获取视频宽高失败, path: " + path + ", e: " + e.getMessage()); + heightAndWidth = new int[]{0, 0, 0}; + } + int duration = 3; + try { + if (heightAndWidth[2] != 0 && heightAndWidth[2] < 3) { + duration = 1; + } + }catch (Exception e){ + LogUtil.error("获取视频宽高失败2, path: " + path + ", e: " + e.getMessage()); + } + LogUtil.info("convertVideoMerge ----------------------duration=" + duration + ", heightAndWidth=" + JsonUtils.beanToJson(heightAndWidth)); + + int width = heightAndWidth[1]; + int height = heightAndWidth[0]; + + int w = 0; + int h = 0; + //视频宽:resolution + if (resolution.indexOf("*") >= 0){ + List whList = Arrays.asList(resolution.split("\\*")).stream().map(Integer::valueOf).collect(Collectors.toList()); + w = whList.get(0); + h = whList.get(1); + }else if (resolution.indexOf("x") >= 0){ + List whList = Arrays.asList(resolution.split("x")).stream().map(Integer::valueOf).collect(Collectors.toList()); + w = whList.get(0); + h = whList.get(1); + } + BigDecimal widthRatio = new BigDecimal(width).divide(new BigDecimal(h),1,BigDecimal.ROUND_UP); + BigDecimal heightReal = new BigDecimal(height).divide(widthRatio,BigDecimal.ROUND_UP); + //BigDecimal value = new BigDecimal(w).subtract(heightReal).divide(new BigDecimal(2),BigDecimal.ROUND_UP); + + + + command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(path); + command.add("-vf"); + command.add("scale=" + h +":"+heightReal.intValue()); + // command.add("scale=" + h +":"+heightReal.intValue()+",pad=" + h+":" + w +":0:"+value.intValue()+":black"); + command.add("-r"); + command.add(frameRate + ""); + command.add("-vcodec"); + command.add("h264"); + command.add("-b:v"); + command.add("0"); + + command.add(finishPath);//文件输出源 + + sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("convertVideoMerge cmd:" + sb.toString()); + try { + videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + } catch (Exception e) { + check = false; + LogUtil.error(e, "convertVideoMerge error"); + } + return check; + } + + /** + * @Description: 设置视频 + * @params: path 原视频路径 + * @params: finishPath 合并完成的最终视频 + * @params: resolution 分辨率 + * @params: frameRate 帧率 + */ + public static Boolean configVideoMerge(VideoCommonDto checkFileDTO) { + + + String path = checkFileDTO.getVideoPathOrg(); + String finishPath = checkFileDTO.getFinalFilePath(); + String dampingTempPath = path.substring(path.lastIndexOf("/") + 1).replace(".","_")+ "_transforms.trf" ; + //String dampingTempPath = path.substring(0, finishPath.lastIndexOf("/")+1 ) + dampingTempName; + + String coverUrl = ""; + if (!ObjectUtils.isEmpty(checkFileDTO.getCoverImg()) && !ObjectUtils.isEmpty(checkFileDTO.getCoverName())){ + if (checkFileDTO.getCoverImg().indexOf(GlobalConfig.private_replace_key) >= 0){ + coverUrl = checkFileDTO.getCoverImg().replace(GlobalConfig.private_replace_key, "/private/") + checkFileDTO.getCoverName(); + }else { + coverUrl = GlobalConfig.default_disk_path_pre + "/private" + checkFileDTO.getCoverImg() + checkFileDTO.getCoverName(); + } + File coverFile = new File(coverUrl); + if (!coverFile.exists()){ + coverUrl = null; + } + } + // 防抖、减震 + if (!ObjectUtils.isEmpty(checkFileDTO.getDampingShakiness())){ + exeDamping(path, dampingTempPath, checkFileDTO.getDampingShakiness(), checkFileDTO.getDampingAccuracy()); + } + boolean check = true; + Process videoProcess = null; + List command = null; + StringBuilder sb = null; + boolean c = false; + StringBuilder settingB = new StringBuilder(); + LogUtil.info("configVideoMerge finishPath=" + finishPath + + ", path=" + path); + /* 【参数说明】 -s 1920x1080:调整分辨率 -r 24:调整帧率 */ + // ffmpeg -i input.mp4  -s 1920x1080 -r 24  output.mp4 + command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(path); + + if (!ObjectUtils.isEmpty(coverUrl)){ + command.add("-i"); + command.add(coverUrl); + } + + // 帧率 + if (!ObjectUtils.isEmpty(checkFileDTO.getFrameRate())) { + command.add("-r"); + command.add(checkFileDTO.getFrameRate() + ""); + } + // 音量 + if (!ObjectUtils.isEmpty(checkFileDTO.getVolume()) || !ObjectUtils.isEmpty(checkFileDTO.getShifting())){ + command.add("-af"); + StringBuilder sbShifting = new StringBuilder(); + boolean a = false; + if (!ObjectUtils.isEmpty(checkFileDTO.getVolume()) ) { + sbShifting.append("volume=" + checkFileDTO.getVolume()); + a = true; + } + if (!ObjectUtils.isEmpty(checkFileDTO.getShifting()) && !ObjectUtils.isEmpty(checkFileDTO.getVolumeShifting()) + && StringUtil.isNumericDecimal(checkFileDTO.getVolumeShifting())){ + + double p = Double.valueOf(checkFileDTO.getVolumeShifting()); + if (p > 2){ + sbShifting.append((a ? "," : "")); + int n = 0; + while (p > 0){ + if (n > 0){ + sbShifting.append(","); + } + if (p > 2){ + sbShifting.append("atempo=2.0" ); + }else { + sbShifting.append("atempo=" + p ); + } + p = p - 2; + n ++; + } + }else { + sbShifting.append((a ? "," : "")+"atempo=" + (0.5 + p * 0.5)); + } + } + command.add(sbShifting.toString()); + } + + + if (!CollectionUtils.isEmpty(checkFileDTO.getMarkUrlList())){ + /* +ffmpeg -i /uploads/private/cloud/2023_6/14/479dbf93ebe44f61b624aa55fcf5e8021686724044186_30074.mp4 -i /uploads/private/cloud/2023_6/15/9f68848570c6494bb13adf8a90d8cff61686806004019_30074.png -i /uploads/private/cloud/2023_6/15/9f68848570c6494bb13adf8a90d8cff61686806004019_30074.png -i /uploads/private/cloud/2023_6/15/9f68848570c6494bb13adf8a90d8cff61686806004019_30074.png -filter_complex [1:v]scale=15:15,format=yuva444p,colorchannelmixer=aa=0.1[v1],[0:v][v1]overlay=30:10[vp],[2:v]scale=20:20,format=yuva444p,colorchannelmixer=aa=0.5[s],[vp][s]overlay=5:5[vo],[3:v]scale=16:10,format=yuva444p,colorchannelmixer=aa=0.9[s2],[vo][s2]overlay=10:30 -vcodec h264 -b:v 0 /uploads/private/cloud/2023_6/15/d1276bfc6b704328a3642bc14f7fcaff1686813747745_1.mp4 + */ + for (MarkUrlDto markUrl : checkFileDTO.getMarkUrlList()){ + command.add("-i"); + if (markUrl.getUrl().indexOf(GlobalConfig.private_replace_key) >= 0){ + command.add( markUrl.getUrl().replace(GlobalConfig.private_replace_key, "/private/") + markUrl.getName()); + }else { + command.add( GlobalConfig.default_disk_path_pre + "/private" + markUrl.getUrl() + markUrl.getName()); + } + + } + command.add("-max_muxing_queue_size"); + command.add("1024"); + command.add("-filter_complex"); + StringBuilder sbui = new StringBuilder(); + int i = 0; + for (MarkUrlDto markUrl : checkFileDTO.getMarkUrlList()){ + /* + [1:v]scale=15:15,format=yuva444p,colorchannelmixer=aa=0.1[v1],[0:v][v1]overlay=30:10[vp] + ,[2:v]scale=20:20,format=yuva444p,colorchannelmixer=aa=0.5[s],[vp][s]overlay=5:5[vo] + ,[3:v]scale=16:10,format=yuva444p,colorchannelmixer=aa=0.9[s2],[vo][s2]overlay=10:30 + */ + if (i > 0){ + sbui.append(","); + } + sbui.append("[" + (i+1)+":v]scale="+markUrl.getScale()); + if (!ObjectUtils.isEmpty(markUrl.getFormat())){ + sbui.append(",format="+markUrl.getFormat()); + } + if (!ObjectUtils.isEmpty(markUrl.getColorchannelmixer())){ + sbui.append(",colorchannelmixer="+markUrl.getColorchannelmixer()); + } + sbui.append("[img" + (i+1) +"]"); + + sbui.append(","); + if (i > 0){ + sbui.append("[" + (i-1) +":oe]"); + }else { + sbui.append("[" + (i) +":v]"); + } + sbui.append("[img" + (i+1) +"]"); + sbui.append("overlay="+markUrl.getPosition()); + if ((i+1) < checkFileDTO.getMarkUrlList().size()){ + sbui.append("[" + (i) +":oe]"); + } + + + i++; + } + + command.add(sbui.toString()); + } + + // 防抖、减震 + if (!ObjectUtils.isEmpty(checkFileDTO.getDampingShakiness())){ + // ffmpeg -i 三山五园绿道.MOV -vf vidstabdetect=stepsize=32:shakiness=10:accuracy=10:result=transform_vectors.trf -f null - + // ffmpeg -i 三山五园绿道.MOV -y -vf vidstabtransform=input=transform_vectors.trf:zoom=0:smoothing=10 三山五园绿道稳定版.MOV + // zoom 设置缩放百分比。 正值将导致放大效果,缩小效果中的负值。 默认值为0(无缩放) + // smoothing 设置用于低通滤波相机移动的帧数(value*2 + 1)。 默认值为10。 + command.add("-y"); + settingB.append((c ? "," : "") + "vidstabtransform=input=" + dampingTempPath +":zoom=0:smoothing=10"); + c = true; + } + + + // 裁剪 + if (!ObjectUtils.isEmpty(checkFileDTO.getCrop())) { + settingB.append((c ? "," : "") + "crop=" + checkFileDTO.getCrop()); + c = true; + } + // 变速 + if (!ObjectUtils.isEmpty(checkFileDTO.getShifting())){ + settingB.append((c ? "," : "") + "setpts=" + checkFileDTO.getShifting() +"*PTS"); + c = true; + } + // 分辨率 + if (!ObjectUtils.isEmpty(checkFileDTO.getResolution())) { + + + int[] heightAndWidth; + try { + heightAndWidth = VideoUtil.getHeightAndWidthAndduration(path); + } catch (Exception e){ + LogUtil.error("获取视频宽高失败, path: " + path + ", e: " + e.getMessage()); + heightAndWidth = new int[]{0, 0, 0}; + } + int duration = 3; + try { + if (heightAndWidth[2] != 0 && heightAndWidth[2] < 3) { + duration = 1; + } + }catch (Exception e){ + LogUtil.error("获取视频宽高失败2, path: " + path + ", e: " + e.getMessage()); + } + LogUtil.info("convertVideoMerge ----------------------duration=" + duration + ", heightAndWidth=" + heightAndWidth); + + int width = heightAndWidth[1]; + int height = heightAndWidth[0]; + + int w = 0; + int h = 0; + String resolution = checkFileDTO.getResolution(); + //视频宽:resolution + if (resolution.indexOf("*") >= 0){ + List whList = Arrays.asList(resolution.split("\\*")).stream().map(Integer::valueOf).collect(Collectors.toList()); + w = whList.get(0); + h = whList.get(1); + }else if (resolution.indexOf("x") >= 0){ + List whList = Arrays.asList(resolution.split("x")).stream().map(Integer::valueOf).collect(Collectors.toList()); + w = whList.get(0); + h = whList.get(1); + } + BigDecimal widthRatio = new BigDecimal(width).divide(new BigDecimal(h),1,BigDecimal.ROUND_UP); + BigDecimal heightReal = new BigDecimal(height).divide(widthRatio,BigDecimal.ROUND_UP); + //BigDecimal value = new BigDecimal(w).subtract(heightReal).divide(new BigDecimal(2),BigDecimal.ROUND_UP); + + //settingB.append((c ? "," : "") + "scale=" + w + ":" + h +",pad=" + w+":" + h +":0:"+value.intValue()+":black"); + settingB.append((c ? "," : "") + "scale=" + w + ":" + h ); + c = true; + } + // 水印 + if (!CollectionUtils.isEmpty(checkFileDTO.getMarkTextList())){ + for (String markTest : checkFileDTO.getMarkTextList()){ + settingB.append((c ? "," : "") + "drawtext=" + markTest); + c = true; + } + } + + // 字幕 + if (!ObjectUtils.isEmpty(checkFileDTO.getCaptions()) && !ObjectUtils.isEmpty(checkFileDTO.getCaptionsUrl())){ + if (checkFileDTO.getCaptions().lastIndexOf(".srt") >= 0){ + settingB.append((c ? "," : "") + "subtitles=" + checkFileDTO.getCaptionsUrl().replace(GlobalConfig.private_replace_key, "/private/") + checkFileDTO.getCaptions()); + c = true; + + }else if (checkFileDTO.getCaptions().lastIndexOf(".ass") >= 0){ + settingB.append((c ? "," : "") + "ass=" + checkFileDTO.getCaptionsUrl().replace(GlobalConfig.private_replace_key, "/private/") + checkFileDTO.getCaptions()); + c = true; + } + } + // 旋转 1 左转 2 右转 + if (!ObjectUtils.isEmpty(checkFileDTO.getRotateType()) && !ObjectUtils.isEmpty(checkFileDTO.getRotate())){ + if (checkFileDTO.getRotate().intValue() == 90){ + settingB.append((c ? "," : "") + "transpose=" + ("2".equals(checkFileDTO.getRotateType()) ? "1" : "2" )); + c = true; + }else if (checkFileDTO.getRotate().intValue() == 180){ + settingB.append((c ? "," : "") + "transpose=" + ("2".equals(checkFileDTO.getRotateType()) ? "1" : "2" )+ ",transpose=" + ("2".equals(checkFileDTO.getRotateType()) ? "1" : "2" )); + c = true; + }else { + command.add("-metadata:s:v:0"); + command.add("transpose=" + ("2".equals(checkFileDTO.getRotateType()) ? checkFileDTO.getRotate() : (360 - checkFileDTO.getRotate()) )); + } + } + // 翻转 1 水平 2 垂直 + if (!ObjectUtils.isEmpty(checkFileDTO.getOverturnType())){ + if ("1".equals(checkFileDTO.getOverturnType())){ + settingB.append((c ? "," : "") + "hflip"); + c = true; + }else { + settingB.append((c ? "," : "") + "vflip"); + c = true; + } + } + + // 多个-vf逗号隔开 + if (c){ + command.add("-vf"); + command.add(settingB.toString()); + } + command.add("-vcodec"); + command.add("h264"); + command.add("-b:v"); + command.add("0"); + if (!ObjectUtils.isEmpty(coverUrl)) { + // 设置封面 + command.add("-map 1 -map 0 -c copy -disposition:0 attached_pic"); + } + + + command.add(finishPath);//文件输出源 + + sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("configVideoMerge cmd:" + sb.toString()); + try { + videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + } catch (Exception e) { + check = false; + LogUtil.error(e, "configVideoMerge error"); + } + /*try { + File dampFile = new File(dampingTempPath); + if (dampFile.exists()){ + dampFile.delete(); + } + }catch (Exception e){ + LogUtil.error(e, "configVideoMerge delete error dampingTempPath=" + dampingTempPath); + }*/ + return check; + } + + public static Boolean checkIsSettingVideo(VideoCommonDto checkFileDTO) { + + boolean check = false; + + if (ObjectUtils.isEmpty(checkFileDTO)){ + return check; + } + // 分辨率 + if (!ObjectUtils.isEmpty(checkFileDTO.getResolution())) { + check = true; + }else + // 帧率 + if (!ObjectUtils.isEmpty(checkFileDTO.getFrameRate())) { + check = true; + }else + // 音量 + if (!ObjectUtils.isEmpty(checkFileDTO.getVolume())){ + check = true; + }else + // 水印 + if (!CollectionUtils.isEmpty(checkFileDTO.getMarkTextList())){ + check = true; + }else + if (!CollectionUtils.isEmpty(checkFileDTO.getMarkUrlList())){ + check = true; + }else + // 字幕 + if (!ObjectUtils.isEmpty(checkFileDTO.getCaptions())){ + check = true; + }else + // 变速 + if (!ObjectUtils.isEmpty(checkFileDTO.getShifting())){ + check = true; + }else + // 防抖、减震 + if (!ObjectUtils.isEmpty(checkFileDTO.getDampingShakiness())){ + check = true; + }else + // 旋转 1 左转 2 右转 + if (!ObjectUtils.isEmpty(checkFileDTO.getRotateType()) && !ObjectUtils.isEmpty(checkFileDTO.getRotate())){ + check = true; + }else + // 翻转 1 水平 2 垂直 + if (!ObjectUtils.isEmpty(checkFileDTO.getOverturnType())){ + check = true; + } + return check; + } + + /* 防抖、减震 + shakiness 设置视频的抖动程度以及相机的速度。它接受1-10范围内的整数,值1表示少量抖动,值10表示强烈颤抖。默认值为5。 + accuracy 设置检测过程的准确性。它必须是1-15范围内的值。值1表示精度低,值15表示高精度。默认值为15。 + */ + public static Boolean exeDamping(String path, String dampingTempPath, String shakiness, String accuracy) { + + + boolean check = true; + Process videoProcess = null; + StringBuilder sb = null; + LogUtil.info("configVideoMerge exeDamping dampingTempPath=" + dampingTempPath + + ", path=" + path); + /* ffmpeg -i 三山五园绿道.MOV -vf */ + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(path);// + command.add("-vf"); + command.add("vidstabdetect=shakiness=" + shakiness + ":accuracy=" + accuracy +":result=" + dampingTempPath ); + command.add("-f"); + command.add("null"); + command.add("-"); + + + sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("configVideoMerge exeDamping cmd:" + sb.toString()); + try { + videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + } catch (Exception e) { + check = false; + LogUtil.error(e, "configVideoMerge exeDamping error"); + } + return check; + } + + // 执行命令 + public static Boolean execCommand(List command){ + try { + Process videoProcess = new ProcessBuilder(command).start(); + dealStream(videoProcess); + videoProcess.waitFor(); + return true; + } catch (Exception e) { + LogUtil.error(e, "execCommand error"); + } + return false; + } + + + /** + * 视频复制音频 + * @param tempVideoPath 视频路径 + */ + public static boolean copyAudioBatch(String tempVideoPath, String tempImgPath) { + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add(tempVideoPath);//文件输入源 + command.add("-vn"); + command.add("-c:a"); + command.add("copy"); + command.add(tempImgPath);//文件输出路径,格式为 11.jpg + /* + // ffmpeg -i input.mp4 -vn -c:a copy output.aac + */ + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("copyAudioBatch cmd:" + sb.toString()); + return execCommand(command); + } + +} diff --git a/src/main/java/com/svnlan/home/utils/zip/FileType.java b/src/main/java/com/svnlan/home/utils/zip/FileType.java new file mode 100644 index 0000000..15e8480 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/FileType.java @@ -0,0 +1,139 @@ +package com.svnlan.home.utils.zip; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by + * Content :文件类型,文本,office,压缩包等等 + */ +public enum FileType { + + PICTURE("pictureFilePreviewImpl"), + COMPRESS("compressFilePreviewImpl"), + OFFICE("officeFilePreviewImpl"), + SIMTEXT("simTextFilePreviewImpl"), + PDF("pdfFilePreviewImpl"), + CODE("codeFilePreviewImpl"), + OTHER("otherFilePreviewImpl"), + MEDIA("mediaFilePreviewImpl"), + MARKDOWN("markdownFilePreviewImpl"), + XML("xmlFilePreviewImpl"), + FLV("flvFilePreviewImpl"), + CAD("cadFilePreviewImpl"), + TIFF("tiffFilePreviewImpl"), + OFD("ofdFilePreviewImpl"), + EML("emlFilePreviewImpl"), + Online3D("online3DFilePreviewImpl"), + XMIND("xmindFilePreviewImpl"), + SVG("svgFilePreviewImpl"), + Epub("epubFilePreviewImpl"), + FOLDER("folder"); + + private static final String[] OFFICE_TYPES = {"docx", "wps", "doc", "docm", "xls", "xlsx", "csv" ,"xlsm", "ppt", "pptx", "vsd", "rtf", "odt", "wmf", "emf", "dps", "et", "ods", "ots", "tsv", "odp", "otp", "sxi", "ott", "vsdx", "fodt", "fods", "xltx","tga","psd"}; + private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "jfif", "webp"}; + private static final String[] ARCHIVE_TYPES = {"rar", "zip", "jar", "7-zip", "tar", "gzip", "7z"}; + private static final String[] Online3D_TYPES = {"obj", "3ds", "stl", "ply", "off", "3dm", "fbx", "dae", "wrl", "3mf", "ifc","glb","o3dv","gltf","stp","bim","fcstd","step","iges","brep"}; + private static final String[] EML_TYPES = {"eml"}; + private static final String[] XMIND_TYPES = {"xmind"}; + private static final String[] Epub_TYPES = {"epub"}; + private static final String[] TIFF_TYPES = {"tif", "tiff"}; + private static final String[] OFD_TYPES = {"ofd"}; + private static final String[] SVG_TYPES = {"svg"}; + private static final String[] CAD_TYPES = {"dwg", "dxf"}; + private static final String[] SSIM_TEXT_TYPES = {"txt","html","htm","asp","jsp","xml","json","properties","md","gitignore","log","java","py","c","cpp","sql","sh","bat","m","bas","prg","cmd","smm"}; + private static final String[] CODES = {"java", "c", "php", "go", "python", "py", "js", "html", "ftl", "css", "lua", "sh", "rb", "yaml", "yml", "json", "h", "cpp", "cs", "aspx", "jsp","smm"}; + private static final String[] MEDIA_TYPES = {"mp3","wav","mp4","flv"}; + public static final String[] MEDIA_TYPES_CONVERT = {"avi","mov","wmv","mkv","3gp","rm"}; + private static final Map FILE_TYPE_MAPPER = new HashMap<>(); + + static { + for (String office : OFFICE_TYPES) { + FILE_TYPE_MAPPER.put(office, FileType.OFFICE); + } + for (String picture : PICTURE_TYPES) { + FILE_TYPE_MAPPER.put(picture, FileType.PICTURE); + } + for (String archive : ARCHIVE_TYPES) { + FILE_TYPE_MAPPER.put(archive, FileType.COMPRESS); + } + for (String text : SSIM_TEXT_TYPES) { + FILE_TYPE_MAPPER.put(text, FileType.SIMTEXT); + } + for (String media : MEDIA_TYPES) { + FILE_TYPE_MAPPER.put(media, FileType.MEDIA); + } + for (String media : MEDIA_TYPES_CONVERT) { + FILE_TYPE_MAPPER.put(media, FileType.MEDIA); + } + for (String tif : TIFF_TYPES) { + FILE_TYPE_MAPPER.put(tif, FileType.TIFF); + } + for (String code : CODES) { + FILE_TYPE_MAPPER.put(code, FileType.CODE); + } + for (String ofd : OFD_TYPES) { + FILE_TYPE_MAPPER.put(ofd, FileType.OFD); + } + for (String cad : CAD_TYPES) { + FILE_TYPE_MAPPER.put(cad, FileType.CAD); + } + for (String svg : SVG_TYPES) { + FILE_TYPE_MAPPER.put(svg, FileType.SVG); + } + for (String epub : Epub_TYPES) { + FILE_TYPE_MAPPER.put(epub, FileType.Epub); + } + for (String eml : EML_TYPES) { + FILE_TYPE_MAPPER.put(eml, FileType.EML); + } + for (String xmind : XMIND_TYPES) { + FILE_TYPE_MAPPER.put(xmind, FileType.XMIND); + } + for (String online3D : Online3D_TYPES) { + FILE_TYPE_MAPPER.put(online3D, FileType.Online3D); + } + FILE_TYPE_MAPPER.put("md", FileType.MARKDOWN); + FILE_TYPE_MAPPER.put("xml", FileType.XML); + FILE_TYPE_MAPPER.put("pdf", FileType.PDF); + FILE_TYPE_MAPPER.put("flv", FileType.FLV); + } + + private static FileType to(String fileType) { + return FILE_TYPE_MAPPER.getOrDefault(fileType, OTHER); + } + + /** + * 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型) + * + * @param url url + * @return 文件类型 + */ + public static FileType typeFromUrl(String url) { + String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length()); + String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); + return typeFromFileName(fileName); + } + + public static FileType typeFromFileName(String fileName) { + String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); + String lowerCaseFileType = fileType.toLowerCase(); + return FileType.to(lowerCaseFileType); + } + + public static String suffixFromFileName(String fileName) { + String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); + return fileType.toLowerCase(); + } + + private final String instanceName; + + FileType(String instanceName) { + this.instanceName = instanceName; + } + + public String getInstanceName() { + return instanceName; + } + +} diff --git a/src/main/java/com/svnlan/home/utils/zip/TarUtils.java b/src/main/java/com/svnlan/home/utils/zip/TarUtils.java new file mode 100644 index 0000000..f170b15 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/TarUtils.java @@ -0,0 +1,144 @@ +package com.svnlan.home.utils.zip; + +import com.svnlan.home.utils.FileUtil; +import com.svnlan.utils.LogUtil; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/4 13:44 + */ +public class TarUtils { + + /**缓冲字节*/ + public static final int BUFFER = 1024; + + + /** 压缩目录 KeepDirStructure 一级目录是否保留 nextKeepDirStructure 下级目录是否保留 */ + public static void toZip(String srcDir, String finalFilePath, boolean KeepDirStructure) throws RuntimeException { + toZip(srcDir, finalFilePath, KeepDirStructure, KeepDirStructure); + } + public static void toZip(String srcDir, String finalFilePath, boolean KeepDirStructure, boolean nextKeepDirStructure) throws RuntimeException { + FileOutputStream out = null; + long start = System.currentTimeMillis(); + TarArchiveOutputStream zos = null; + try { + out = new FileOutputStream(finalFilePath); + zos = new TarArchiveOutputStream(out); + File sourceFile = new File(srcDir); + compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure, nextKeepDirStructure); + long end = System.currentTimeMillis(); + LogUtil.info("压缩完成,耗时:" + (end - start) + " ms"); + } catch (Exception e) { + LogUtil.error(e,"tar compress error"); + throw new RuntimeException("tar error from ", e); + } finally { + if (zos != null) { + try { + zos.close(); + } catch (IOException e) { + LogUtil.error(e,"zos error"); + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + LogUtil.error(e,"zos out error"); + } + } + } + } + + private static boolean isMessyCode( String str ) + { + for( int i = 0; i < str.length(); i++ ) + { + char c = str.charAt( i ) ; + // 当从Unicode编码向某个字符集转换时,如果在该字符集中没有对应的编码,则得到0x3f(即问号字符?) + // 从其他字符集向Unicode编码转换时,如果这个二进制数在该字符集中没有标识任何的字符,则得到的结果是0xfffd + if( (int)c == 0xfffd ) + { + // 存在乱码 + return true ; + } + } + return false ; + } + + /** 递归压缩 KeepDirStructure 一级目录是否保留 nextKeepDirStructure 下级目录是否保留*/ + public static void compress(File sourceFile, TarArchiveOutputStream zos, String name, boolean KeepDirStructure)throws Exception{ + compress(sourceFile, zos, name, KeepDirStructure, KeepDirStructure); + } + public static void compress(File sourceFile, TarArchiveOutputStream taos, String name, boolean KeepDirStructure, boolean nextKeepDirStructure) + throws Exception { + byte[] buf = new byte[BUFFER]; + if (sourceFile.isFile()) { + TarArchiveEntry tae = new TarArchiveEntry(sourceFile); + //不加tae.setName,压缩文件里是全路径(filePath有几层,压缩包里有几层) + String n = FileUtil.getUtf8String(name); + LogUtil.info("tar getUtf8String name=" + name + ",n="+ n); + if (isMessyCode(n)){ + n = new String(name.getBytes(StandardCharsets.ISO_8859_1), "GBK"); + LogUtil.info("tar isMessyCode name=" + name + ",n="+ n); + } + tae.setName(n); + + // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字 + taos.putArchiveEntry(tae); + + // copy文件到zip输出流中 + int len; + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile)); + while ((len = bis.read(buf, 0 , 1024)) != -1) { + taos.write(buf, 0, len); + } + // Complete the entry + bis.close(); + taos.closeArchiveEntry(); + } else { + File[] listFiles = sourceFile.listFiles(); + if (listFiles == null || listFiles.length == 0) { + // 需要保留原来的文件结构时,需要对空文件夹进行处理 + if (KeepDirStructure) { + // 空文件夹的处理 + taos.putArchiveEntry(new TarArchiveEntry(name + "/")); + // 没有文件,不需要文件的copy + taos.closeArchiveEntry(); + } + } else { + for (File file : listFiles) { + // 判断是否需要保留原来的文件结构 + if (KeepDirStructure) { + // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠, + // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了 + compress(file, taos, name + "/" + file.getName(), KeepDirStructure); + } else { + compress(file, taos, file.getName(), nextKeepDirStructure); + } + } + } + } + } + + + + public static void main(String[] args) { + String finalFolderPath = "E:\\zip测试打包\\999\\gz2\\"; + String targetDir = "E:\\zip测试打包\\999\\"; + + String fileName = System.currentTimeMillis() + + "_1" + ".tar"; + String finalFilePath = targetDir + fileName; + try { + toZip(finalFolderPath, finalFilePath, true); + } catch (Exception e){ + + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnBz2Utils.java b/src/main/java/com/svnlan/home/utils/zip/UnBz2Utils.java new file mode 100644 index 0000000..dced879 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnBz2Utils.java @@ -0,0 +1,168 @@ +package com.svnlan.home.utils.zip; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; +import org.apache.tools.tar.TarEntry; +import org.apache.tools.tar.TarInputStream; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import java.io.*; +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/4/4 15:29 + */ +public class UnBz2Utils { + + private static final int BUFFER = 1024; + + /** + * 解压入口方法 + * + * @param zipPath zip文件物理地址 + * @param unzipPath 解压后存放路径 + * @throws Exception + */ + public static void decompress(String zipPath, String unzipPath, List fileList, Long userID) throws Exception { + //解压缩执行方法 + decompressFile(new File(zipPath), new File(unzipPath), fileList, userID); + } + + /** + * 解压缩执行方法 + * + * @param srcFile 压缩文件File实体 + * @param destFile 解压路径File实体 + * @throws Exception + */ + public static void decompressFile(File srcFile, File destFile, List fileList, Long userID) throws Exception { + + //创建压缩输入流 + TarInputStream zis = new TarInputStream(new FileInputStream(srcFile)); + try { + //解压zip + decompressZis(destFile, zis, fileList, userID); + }catch (Exception e){ + LogUtil.error(e, "decompressFile 解压error"); + }finally { + //zis1.close(); + //关闭流 + zis.close(); + } + } + /** + * 生成文件 + * + * @param destFile 目标文件 + * @param zis FileInputStream + * @throws Exception + */ + private static void decompressFile(File destFile, TarInputStream zis) throws Exception { + + OutputStream bos = new FileOutputStream(destFile); + + BZip2CompressorInputStream bis = new BZip2CompressorInputStream(zis); + //创建输出流 + // BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); + //转成byte数组 + int count; + byte[] data = new byte[BUFFER]; + //读取并写入文件 + while ((count = bis.read(data, 0, BUFFER)) != -1) { + bos.write(data, 0, count); + } + //关闭数据流 + bos.close(); + } + /** + * 文件 解压缩执行方法 + * + * @param destFile 目标文件 + * @param zis FileInputStream + * @throws Exception + */ + private static void decompressZis(File destFile, TarInputStream zis, List fileList, Long userID) throws Exception { + TarEntry entry; + + Map reMap = new HashMap<>(1); + + int i = 1; + while (!ObjectUtils.isEmpty(entry = zis.getNextEntry())) { + //获取当前的ZIP条目路径 + String dir = destFile.getPath() + File.separator + entry.getName(); + //判断是否是文件夹 + if (entry.isDirectory()) { + //如果是,创建文件夹 + // dirFile.mkdirs(); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(entry.getName()) ) { + fileList.add(new ChangeSourceVo(entry.getName().endsWith("/") ? entry.getName().substring(0,entry.getName().length() -1) : entry.getName(), + 1, dir)); + } + reMap.put(entry.getName(), 1); + reMap.put(dir, 1); + } else { + + String suffix = FileUtil.getFileExtension(entry.getName()); + String filePath = entry.getName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + + + //递归检查文件路径,路径上没有文件夹则创建,保证整条路径在本地存在 + fileProberParent(filePath.replace(fileName, ""), destFile.getPath() + File.separator, suffix, fileList, reMap); + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = destFile.getPath() + File.separator + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + userID + "." + suffix; + + + //如果不是文件夹,数据流输出,生成文件 + decompressFile(new File(finalFilePath), zis); + + String serverChecksum = DigestUtils.md5DigestAsHex(zis); + + fileList.add(new ChangeSourceVo(fileName, 0, suffix, finalFilePath , filePath + , entry.getSize(), serverChecksum)); + // Integer isFolder, String fileType, String path, String filePath, Long size, String hashMd5 + + } + i ++; + //关闭当前的ZIP条目并定位流 + zis.close(); + } + } + + + private static void fileProberParent(String parentPath, String destPath, String suffix, List fileList, Map reMap) { + if (!ObjectUtils.isEmpty(reMap) && reMap.containsKey(parentPath)){ + return; + } + List parentList = Arrays.asList(parentPath.split("/")).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList());; + + if (!CollectionUtils.isEmpty(parentList)){ + StringBuilder sb = new StringBuilder(); + for (String parent : parentList){ + if (parent.endsWith(suffix)){ + continue; + } + sb.append(parent + "/"); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(sb.toString())) { + fileList.add(new ChangeSourceVo(parent, 1, destPath + sb.toString())); + } + reMap.put(sb.toString(), 1); + } + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnGzUtils.java b/src/main/java/com/svnlan/home/utils/zip/UnGzUtils.java new file mode 100644 index 0000000..fb6a93f --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnGzUtils.java @@ -0,0 +1,9 @@ +package com.svnlan.home.utils.zip; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/6 10:59 + */ +public class UnGzUtils { +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnGzipUtils.java b/src/main/java/com/svnlan/home/utils/zip/UnGzipUtils.java new file mode 100644 index 0000000..8c74942 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnGzipUtils.java @@ -0,0 +1,9 @@ +package com.svnlan.home.utils.zip; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/6 10:58 + */ +public class UnGzipUtils { +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnRarUtils.java b/src/main/java/com/svnlan/home/utils/zip/UnRarUtils.java new file mode 100644 index 0000000..97a401b --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnRarUtils.java @@ -0,0 +1,185 @@ +package com.svnlan.home.utils.zip; + +import com.github.junrar.Archive; +import com.github.junrar.rarfile.FileHeader; +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import java.io.*; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/6 10:58 + */ +public class UnRarUtils { + + private static final int BUFFER = 1024; + + /** + * 解压入口方法 + * + * @param zipPath zip文件物理地址 + * @param unzipPath 解压后存放路径 + * @throws Exception + */ + public static void decompress(String zipPath, String unzipPath, List fileList, Long userID) throws Exception { + //解压缩执行方法 + decompressFile(new File(zipPath), new File(unzipPath), fileList, userID); + } + + /** + * 解压缩执行方法 + * + * @param srcFile 压缩文件File实体 + * @param destFile 解压路径File实体 + * @throws Exception + */ + public static void decompressFile(File srcFile, File destFile, List fileList, Long userID) throws Exception { + + //创建压缩输入流 + + Archive zis = null; + try { + zis = new Archive (new FileInputStream(srcFile)); + //解压zip + decompressZis(destFile, zis, fileList, userID); + }catch (Exception e){ + LogUtil.error(e, "decompressFile 解压error"); + }finally { + //关闭流 + try { + if(zis != null){ + zis.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + /** + * 文件 解压缩执行方法 + * + * @param destFile 目标文件 + * @param zis TarArchiveInputStream + * @throws Exception + */ + private static void decompressZis(File destFile, Archive zis, List fileList, Long userID) throws Exception { + FileHeader entry; + Map reMap = new HashMap<>(1); + OutputStream outputStream = null; + FileInputStream inputStream = null; + try { + int i = 1; + while (!ObjectUtils.isEmpty(entry = zis.nextFileHeader())) { + //获取当前的ZIP条目路径 + String dir = destFile.getPath() + File.separator + entry.getFileNameW(); + //判断是否是文件夹 + if (entry.isDirectory()) { + //如果是,创建文件夹 + // dirFile.mkdirs(); + + if (ObjectUtils.isEmpty(reMap) || (!reMap.containsKey(entry.getFileNameW()) && !reMap.containsKey(entry.getFileNameW() + "/") )) { + fileList.add(new ChangeSourceVo(entry.getFileNameW().endsWith("/") ? entry.getFileNameW().substring(0,entry.getFileNameW().length() -1) : entry.getFileNameW(), + 1, dir)); + } + reMap.put(entry.getFileNameW(), 1); + reMap.put(dir, 1); + } else { + + String suffix = FileUtil.getFileExtension(entry.getFileNameW()); + String filePath = entry.getFileNameW().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + + + //递归检查文件路径,路径上没有文件夹则创建,保证整条路径在本地存在 + fileProberParent(filePath.replace(fileName, ""), destFile.getPath() + File.separator, suffix, fileList, reMap); + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = destFile.getPath() + File.separator + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + userID + "." + suffix; + + + File f = new File(finalFilePath); + //如果不是文件夹,数据流输出,生成文件 + outputStream = new FileOutputStream(f); + inputStream = new FileInputStream(f); + zis.extractFile(entry, outputStream); + + + String serverChecksum = DigestUtils.md5DigestAsHex(inputStream); + + fileList.add(new ChangeSourceVo(fileName, 0, suffix, finalFilePath , filePath + , entry.getDataSize(), serverChecksum)); + + } + i ++; + } + }catch (Exception e){ + LogUtil.error(e, "decompressFile 解压error"); + }finally { + //关闭流 + try { + if(outputStream != null){ + outputStream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + try { + if(inputStream != null){ + inputStream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + private static void fileProberParent(String parentPath, String destPath, String suffix, List fileList, Map reMap) { + if (!ObjectUtils.isEmpty(reMap) && reMap.containsKey(parentPath)){ + return; + } + List parentList = Arrays.asList(parentPath.split("/")).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(parentList)){ + StringBuilder sb = new StringBuilder(); + for (String parent : parentList){ + if (parent.endsWith(suffix)){ + continue; + } + sb.append(parent + "/"); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(sb.toString())) { + fileList.add(new ChangeSourceVo(parent, 1, destPath + sb.toString())); + } + reMap.put(sb.toString(), 1); + } + } + } + + /*public static void main(String[] args) { + String unzipPath = "E:\\zip测试打包\\解压rar\\"; + String zipPath = "E:\\zip测试打包\\主观题答案.rar"; + List list = new ArrayList(); + + try { + decompress(zipPath, unzipPath,list , 1L); + LogUtil.info("list=" + JsonUtils.beanToJson(list)); + } catch (Exception e){ + + LogUtil.error(e, "error"); + + } + }*/ +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnSevenZUtils.java b/src/main/java/com/svnlan/home/utils/zip/UnSevenZUtils.java new file mode 100644 index 0000000..bbf1821 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnSevenZUtils.java @@ -0,0 +1,177 @@ +package com.svnlan.home.utils.zip; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry; +import org.apache.commons.compress.archivers.sevenz.SevenZFile; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/6 10:58 + */ +public class UnSevenZUtils { + + private static final int BUFFER = 1024; + + /** + * 解压入口方法 + * + * @param zipPath zip文件物理地址 + * @param unzipPath 解压后存放路径 + * @throws Exception + */ + public static void decompress(String zipPath, String unzipPath, List fileList, Long userID) throws Exception { + //解压缩执行方法 + decompressFile(new File(zipPath), new File(unzipPath), fileList, userID); + } + + /** + * 解压缩执行方法 + * + * @param srcFile 压缩文件File实体 + * @param destFile 解压路径File实体 + * @throws Exception + */ + public static void decompressFile(File srcFile, File destFile, List fileList, Long userID) throws Exception { + + //创建压缩输入流 + + SevenZFile zis = null; + try { + zis = new SevenZFile (srcFile); + //解压zip + decompressZis(destFile, zis, fileList, userID); + }catch (Exception e){ + LogUtil.error(e, "decompressFile 解压error"); + }finally { + //zis1.close(); + //关闭流 + zis.close(); + } + } + /** + * 生成文件 + * + * @param destFile 目标文件 + * @param zis TarArchiveInputStream + * @throws Exception + */ + private static void decompressFile(File destFile, SevenZFile zis) throws Exception { + //创建输出流 + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); + //转成byte数组 + int count; + byte[] data = new byte[BUFFER]; + //读取并写入文件 + while ((count = zis.read(data, 0, BUFFER)) != -1) { + bos.write(data, 0, count); + } + //关闭数据流 + bos.close(); + } + /** + * 文件 解压缩执行方法 + * + * @param destFile 目标文件 + * @param zis TarArchiveInputStream + * @throws Exception + */ + private static void decompressZis(File destFile, SevenZFile zis, List fileList, Long userID) throws Exception { + SevenZArchiveEntry entry; + Map reMap = new HashMap<>(1); + + int i = 1; + while (!ObjectUtils.isEmpty(entry = zis.getNextEntry())) { + //获取当前的ZIP条目路径 + String dir = destFile.getPath() + File.separator + entry.getName(); + //判断是否是文件夹 + if (entry.isDirectory()) { + //如果是,创建文件夹 + // dirFile.mkdirs(); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(entry.getName()) ) { + fileList.add(new ChangeSourceVo(entry.getName().endsWith("/") ? entry.getName().substring(0,entry.getName().length() -1) : entry.getName(), + 1, dir)); + } + reMap.put(entry.getName(), 1); + reMap.put(dir, 1); + } else { + + String suffix = FileUtil.getFileExtension(entry.getName()); + String filePath = entry.getName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + + + //递归检查文件路径,路径上没有文件夹则创建,保证整条路径在本地存在 + fileProberParent(filePath.replace(fileName, ""), destFile.getPath() + File.separator, suffix, fileList, reMap); + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = destFile.getPath() + File.separator + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + userID + "." + suffix; + + + File f = new File(finalFilePath); + //如果不是文件夹,数据流输出,生成文件 + decompressFile(f, zis); + + String serverChecksum = DigestUtils.md5DigestAsHex(new FileInputStream(f)); + + fileList.add(new ChangeSourceVo(fileName, 0, suffix, finalFilePath , filePath + , entry.getSize(), serverChecksum)); + // Integer isFolder, String fileType, String path, String filePath, Long size, String hashMd5 + + } + i ++; + } + } + + + private static void fileProberParent(String parentPath, String destPath, String suffix, List fileList, Map reMap) { + if (!ObjectUtils.isEmpty(reMap) && reMap.containsKey(parentPath)){ + return; + } + List parentList = Arrays.asList(parentPath.split("/")).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(parentList)){ + StringBuilder sb = new StringBuilder(); + for (String parent : parentList){ + if (parent.endsWith(suffix)){ + continue; + } + sb.append(parent + "/"); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(sb.toString())) { + fileList.add(new ChangeSourceVo(parent, 1, destPath + sb.toString())); + } + reMap.put(sb.toString(), 1); + } + } + } + + public static void main(String[] args) { + String unzipPath = "E:\\zip测试打包\\解压7z\\"; + String zipPath = "E:\\zip测试打包\\42_243_144.7z"; + List list = new ArrayList(); + + try { + decompress(zipPath, unzipPath,list , 1L); + LogUtil.info("list=" + JsonUtils.beanToJson(list)); + } catch (Exception e){ + + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnTarUtils.java b/src/main/java/com/svnlan/home/utils/zip/UnTarUtils.java new file mode 100644 index 0000000..7050476 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnTarUtils.java @@ -0,0 +1,175 @@ +package com.svnlan.home.utils.zip; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.*; +import java.util.stream.Collectors; +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/4 14:18 + */ +public class UnTarUtils { + + private static final int BUFFER = 1024; + + /** + * 解压入口方法 + * + * @param zipPath zip文件物理地址 + * @param unzipPath 解压后存放路径 + * @throws Exception + */ + public static void decompress(String zipPath, String unzipPath, List fileList, Long userID) throws Exception { + //解压缩执行方法 + decompressFile(new File(zipPath), new File(unzipPath), fileList, userID); + } + + /** + * 解压缩执行方法 + * + * @param srcFile 压缩文件File实体 + * @param destFile 解压路径File实体 + * @throws Exception + */ + public static void decompressFile(File srcFile, File destFile, List fileList, Long userID) throws Exception { + + //创建压缩输入流 + + TarArchiveInputStream zis = null; + try { + zis = new TarArchiveInputStream(new FileInputStream(srcFile)); + //解压zip + decompressZis(destFile, zis, fileList, userID); + }catch (Exception e){ + LogUtil.error(e, "decompressFile 解压error"); + }finally { + //zis1.close(); + //关闭流 + zis.close(); + } + } + /** + * 生成文件 + * + * @param destFile 目标文件 + * @param zis TarArchiveInputStream + * @throws Exception + */ + private static void decompressFile(File destFile, TarArchiveInputStream zis) throws Exception { + //创建输出流 + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); + //转成byte数组 + int count; + byte[] data = new byte[BUFFER]; + //读取并写入文件 + while ((count = zis.read(data, 0, BUFFER)) != -1) { + bos.write(data, 0, count); + } + //关闭数据流 + bos.close(); + } + /** + * 文件 解压缩执行方法 + * + * @param destFile 目标文件 + * @param zis TarArchiveInputStream + * @throws Exception + */ + private static void decompressZis(File destFile, TarArchiveInputStream zis, List fileList, Long userID) throws Exception { + ArchiveEntry entry; + + Map reMap = new HashMap<>(1); + + int i = 1; + while (!ObjectUtils.isEmpty(entry = zis.getNextEntry())) { + //获取当前的ZIP条目路径 + String dir = destFile.getPath() + File.separator + entry.getName(); + //判断是否是文件夹 + if (entry.isDirectory()) { + //如果是,创建文件夹 + // dirFile.mkdirs(); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(entry.getName()) ) { + fileList.add(new ChangeSourceVo(entry.getName().endsWith("/") ? entry.getName().substring(0,entry.getName().length() -1) : entry.getName(), + 1, dir)); + } + reMap.put(entry.getName(), 1); + reMap.put(dir, 1); + } else { + + String suffix = FileUtil.getFileExtension(entry.getName()); + String filePath = entry.getName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + + + //递归检查文件路径,路径上没有文件夹则创建,保证整条路径在本地存在 + fileProberParent(filePath.replace(fileName, ""), destFile.getPath() + File.separator, suffix, fileList, reMap); + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = destFile.getPath() + File.separator + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + userID + "." + suffix; + + + //如果不是文件夹,数据流输出,生成文件 + decompressFile(new File(finalFilePath), zis); + + String serverChecksum = DigestUtils.md5DigestAsHex(zis); + + fileList.add(new ChangeSourceVo(fileName, 0, suffix, finalFilePath , filePath + , entry.getSize(), serverChecksum)); + // Integer isFolder, String fileType, String path, String filePath, Long size, String hashMd5 + + } + i ++; + } + } + + + private static void fileProberParent(String parentPath, String destPath, String suffix, List fileList, Map reMap) { + if (!ObjectUtils.isEmpty(reMap) && reMap.containsKey(parentPath)){ + return; + } + List parentList = Arrays.asList(parentPath.split("/")).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(parentList)){ + StringBuilder sb = new StringBuilder(); + for (String parent : parentList){ + if (parent.endsWith(suffix)){ + continue; + } + sb.append(parent + "/"); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(sb.toString())) { + fileList.add(new ChangeSourceVo(parent, 1, destPath + sb.toString())); + } + reMap.put(sb.toString(), 1); + } + } + } + + /*public static void main(String[] args) { + String unzipPath = "E:\\zip测试打包\\999\\解压tar\\"; + String zipPath = "E:\\zip测试打包\\999\\5d1a615c9b9a4635b3c6286fa2b64b791680600305329_1.tar"; + List list = new ArrayList<>(); + + try { + decompress(zipPath, unzipPath,list , 1L); + LogUtil.info("list=" + JsonUtils.beanToJson(list)); + } catch (Exception e){ + + } + }*/ +} diff --git a/src/main/java/com/svnlan/home/utils/zip/UnZipUtils.java b/src/main/java/com/svnlan/home/utils/zip/UnZipUtils.java new file mode 100644 index 0000000..c29b27a --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/UnZipUtils.java @@ -0,0 +1,229 @@ +package com.svnlan.home.utils.zip; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.RandomUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.ObjectUtils; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.CRC32; +import java.util.zip.CheckedInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * zip压缩工具类 + * @className: UnZipUtils + * @author: + * @date: + */ +@Component +public class UnZipUtils { + + private static final int BUFFER = 1024; + private static final String CODING_UTF8 = "UTF-8"; + private static final String CODING_GBK = "GBK"; + + /** + * 解压入口方法 + * + * @param zipPath zip文件物理地址 + * @param unzipPath 解压后存放路径 + * @throws Exception + */ + public static void decompress(String zipPath, String unzipPath, List fileList, Long userID) throws Exception { + //解压缩执行方法 + decompressFile(new File(zipPath), new File(unzipPath), fileList, userID); + } + + /** + * 解压缩执行方法 + * + * @param srcFile 压缩文件File实体 + * @param destFile 解压路径File实体 + * @throws Exception + */ + public static void decompressFile(File srcFile, File destFile, List fileList, Long userID) throws Exception { + //创建数据输入流 + CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32()); + + //创建压缩输入流 + ZipInputStream zis = new ZipInputStream(cis, Charset.forName(CODING_GBK)); + //ZipInputStream zis = new ZipInputStream(cis, Charset.forName(CODING_UTF8)); + //异常捕获的方式判断编码格式 + + /* try { + //判断代码,如果此代码未抛出异常,则表示编码为UTF-8 + zis1.getNextEntry().getName(); + } catch (Exception e) { + //如果乱码会抛异常,抛异常重新创建输入流,重新设置编码格式 + cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32()); + zis = new ZipInputStream(cis, Charset.forName(CODING_GBK)); + }*/ + try { + //解压zip + decompressZis(destFile, zis, fileList, userID); + }catch (Exception e){ + LogUtil.error(e, "decompressFile 解压error"); + }finally { + //关闭流 + if (zis != null) { + try { + zis.close(); + } catch (IOException e) { + LogUtil.error(e,"zos error"); + } + } + if (cis != null) { + try { + cis.close(); + } catch (IOException e) { + LogUtil.error(e,"cis error"); + } + } + } + } + + /** + * 文件 解压缩执行方法 + * + * @param destFile 目标文件 + * @param zis ZipInputStream + * @throws Exception + */ + private static void decompressZis(File destFile, ZipInputStream zis, List fileList, Long userID) throws Exception { + ZipEntry entry; + + Map reMap = new HashMap<>(1); + + int i = 1; + while (!ObjectUtils.isEmpty(entry = zis.getNextEntry())) { + //获取当前的ZIP条目路径 + String dir = destFile.getPath() + File.separator + entry.getName(); + //判断是否是文件夹 + if (entry.isDirectory()) { + //如果是,创建文件夹 + // dirFile.mkdirs(); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(entry.getName()) ) { + fileList.add(new ChangeSourceVo(entry.getName().endsWith("/") ? entry.getName().substring(0,entry.getName().length() -1) : entry.getName(), + 1, dir)); + } + reMap.put(entry.getName(), 1); + reMap.put(dir, 1); + } else { + + String suffix = FileUtil.getFileExtension(entry.getName()); + String filePath = entry.getName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); + + + //递归检查文件路径,路径上没有文件夹则创建,保证整条路径在本地存在 + fileProberParent(filePath.replace(fileName, ""), destFile.getPath() + File.separator, suffix, fileList, reMap); + + //最终文件路径 最终文件目录路径+毫秒+.后缀 + String finalFilePath = destFile.getPath() + File.separator + + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + userID + "." + suffix; + + + //如果不是文件夹,数据流输出,生成文件 + decompressFile(new File(finalFilePath), zis); + + String serverChecksum = DigestUtils.md5DigestAsHex(zis); + + fileList.add(new ChangeSourceVo(fileName, 0, suffix, finalFilePath , filePath + , entry.getSize(), serverChecksum)); + // Integer isFolder, String fileType, String path, String filePath, Long size, String hashMd5 + + } + i ++; + //关闭当前的ZIP条目并定位流 + zis.closeEntry(); + } + } + + /** + * 文件探针,当父目录不存在时,创建目录 + * + * @param dirFile ZIP条目路径 + */ + private static void fileProber(File dirFile) { + //获取此路径的父目录 + File parentFile = dirFile.getParentFile(); + //判断是否存在 + if (!parentFile.exists()) { + // 递归寻找上级目录 + fileProber(parentFile); + //直至存在,递归执行创建文件夹 + parentFile.mkdir(); + + } + + } + + private static void fileProberParent(String parentPath, String destPath, String suffix, List fileList, Map reMap) { + if (!ObjectUtils.isEmpty(reMap) && reMap.containsKey(parentPath)){ + return; + } + List parentList = Arrays.asList(parentPath.split("/")).stream().filter(n -> !ObjectUtils.isEmpty(n)).map(String::valueOf).collect(Collectors.toList());; + + if (!CollectionUtils.isEmpty(parentList)){ + StringBuilder sb = new StringBuilder(); + for (String parent : parentList){ + if (parent.endsWith(suffix)){ + continue; + } + sb.append(parent + "/"); + if (ObjectUtils.isEmpty(reMap) || !reMap.containsKey(sb.toString())) { + fileList.add(new ChangeSourceVo(parent, 1, destPath + sb.toString())); + } + reMap.put(sb.toString(), 1); + } + } + } + + /** + * 生成文件 + * + * @param destFile 目标文件 + * @param zis ZipInputStream + * @throws Exception + */ + private static void decompressFile(File destFile, ZipInputStream zis) throws Exception { + //创建输出流 + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile)); + //转成byte数组 + int count; + byte[] data = new byte[BUFFER]; + //读取并写入文件 + while ((count = zis.read(data, 0, BUFFER)) != -1) { + bos.write(data, 0, count); + } + //关闭数据流 + bos.close(); + } + + /*public static void main(String[] args){ + + try { + + List fileList = new ArrayList<>(); + decompress("E:\\zip测试打包\\999__.zip", "/uploads/private/cloud/2023_4/1/2806/", fileList, 1L); + fileList = fileList.stream().sorted(Comparator.comparing(ChangeSourceVo::getPathLength)).collect(Collectors.toList()); + System.out.println(JsonUtils.beanToJson(fileList)); + } catch (Exception e) { + LogUtil.error(e); + e.printStackTrace(); + } + }*/ + +} diff --git a/src/main/java/com/svnlan/home/utils/zip/ZipUtilApache.java b/src/main/java/com/svnlan/home/utils/zip/ZipUtilApache.java new file mode 100644 index 0000000..d835aa9 --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/ZipUtilApache.java @@ -0,0 +1,97 @@ +package com.svnlan.home.utils.zip; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.utils.LogUtil; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/28 13:45 + */ +public class ZipUtilApache { + + private static final int buffer = 2048; + /** + * 解压Zip文件 + * + * @param zipPath 文件目录 + */ + public static void unZip(String zipPath, String unzipPath, List fileList, Long userID) { + int count = -1; + String savepath = ""; + File file = null; + InputStream is = null; + FileOutputStream fos = null; + BufferedOutputStream bos = null; + savepath = new File(zipPath).getParent() + File.separator; //保存解压文件目录 + new File(savepath).mkdir(); //创建保存目录 + ZipFile zipFile = null; + try { + zipFile = new ZipFile(zipPath, "gbk"); //解决中文乱码问题 + Enumeration entries = zipFile.getEntries(); + while (entries.hasMoreElements()) { + byte buf[] = new byte[buffer]; + ZipEntry entry = (ZipEntry) entries.nextElement(); + String filename = entry.getName(); + boolean ismkdir = false; + if (filename.lastIndexOf("/") != -1) { //检查此文件是否带有文件夹 + ismkdir = true; + } + filename = savepath + filename; + if (entry.isDirectory()) { //如果是文件夹先创建 + file = new File(filename); + file.mkdirs(); + continue; + } + file = new File(filename); + if (!file.exists()) { //如果是目录先创建 + if (ismkdir) { + new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs(); //目录先创建 + } + } + file.createNewFile(); //创建文件 + is = zipFile.getInputStream(entry); + fos = new FileOutputStream(file); + bos = new BufferedOutputStream(fos, buffer); + while ((count = is.read(buf)) > -1) { + bos.write(buf, 0, count); + } + bos.flush(); + bos.close(); + fos.close(); + is.close(); + } + zipFile.close(); + } catch (IOException e) { + LogUtil.error(e, "ZipUtilApache-unZip-Exception error"); + } finally { + try { + if (bos != null) { + bos.close(); + } + if (fos != null) { + fos.close(); + } + if (is != null) { + is.close(); + } + if (zipFile != null) { + zipFile.close(); + } + } catch (Exception e) { + LogUtil.error(e, "ZipUtilApache-unZip-Exception error"); + } + } + } +} diff --git a/src/main/java/com/svnlan/home/utils/zip/ZipUtils.java b/src/main/java/com/svnlan/home/utils/zip/ZipUtils.java new file mode 100644 index 0000000..9d17b5f --- /dev/null +++ b/src/main/java/com/svnlan/home/utils/zip/ZipUtils.java @@ -0,0 +1,508 @@ +package com.svnlan.home.utils.zip; + +import com.svnlan.common.GlobalConfig; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.vo.IOSourceVo; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.LogUtil; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.model.enums.CompressionLevel; +import net.lingala.zip4j.progress.ProgressMonitor; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.io.IOUtils; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/14 16:58 + */ +public class ZipUtils { + + private static final int BUFFER_SIZE = 2 * 1024; + /** + * @return suffix 目录名称 pathName 目录根路径 + * @Description 创建一个临时目录 + **/ + public static java.nio.file.Path createDirectory(String suffix, String pathName) { + java.nio.file.Path path1 = Paths.get(pathName + "/" + suffix); + //判断目录是否存在 + boolean pathExists = Files.exists(path1, new LinkOption[]{LinkOption.NOFOLLOW_LINKS}); + if (pathExists) { + return path1; + } + try { + path1 = Files.createDirectories(path1); + } catch (IOException e) { + e.printStackTrace(); + } + return path1; + } + + /** + * @return OriginalPathName 源文件 path 目标文件地址 pathName 根目录 + * @Description 复制文件 + **/ + public static void copyFile(String OriginalPathName, java.nio.file.Path path, String pathName) { + copyFile(pathName + "/" + OriginalPathName, path); + } + /** + * @return OriginalPath 源文件地址 path 目标文件地址 + * @Description 复制文件 + **/ + public static void copyFile(String OriginalPath, java.nio.file.Path path) { + java.nio.file.Path originalPath = Paths.get(OriginalPath); + + try { + Files.copy(originalPath, path, + StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + e.printStackTrace(); + } + } + /** + * @return attachments 这个参数主要是从数据库中获取文件的信息,这里可以根据自己的需求更改 + * @Description 向文件夹中添加文件 + **/ + public static void addFile(List attachments, String finalFolderPath) { + //遍历所有的文件 + for (IOSourceVo attachment : attachments) { + if (0 == attachment.getIsFolder()){ + java.nio.file.Path dirPath = createDirectory(attachment.getPathDisplay() + attachment.getName(), finalFolderPath); + File file = new File(attachment.getPath()); + attachment.setSize(file.length()); + copyFile(attachment.getPath(), dirPath); + }else { + createDirectory(attachment.getPathDisplay() + attachment.getName() + "/", finalFolderPath); + } + } + } + /** 只创建目录 文件则用复制形式*/ + public static void addFileNew(List attachments, String finalFolderPath) { + //遍历所有的文件 + for (IOSourceVo attachment : attachments) { + if (1 == attachment.getIsFolder()){ + createDirectory(attachment.getPathDisplay() + attachment.getName() + "/", finalFolderPath); + } + } + } + + /** 压缩目录 KeepDirStructure 一级目录是否保留 nextKeepDirStructure 下级目录是否保留 */ + public static void toZip(String srcDir, String finalFilePath, boolean KeepDirStructure, StringRedisTemplate stringRedisTemplate, String taskID, long totalLength) throws RuntimeException { + toZip(srcDir, finalFilePath, KeepDirStructure, KeepDirStructure, stringRedisTemplate, taskID, totalLength); + } + public static void toZip(String srcDir, String finalFilePath, boolean KeepDirStructure, boolean nextKeepDirStructure, StringRedisTemplate stringRedisTemplate + , String taskID, long totalLength) throws RuntimeException { + long start = System.currentTimeMillis(); + ZipOutputStream zos = null; + FileOutputStream out = null; + try { + out = new FileOutputStream(finalFilePath); + zos = new ZipOutputStream(out); + File sourceFile = new File(srcDir); + + long nread = 0L; + + compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure, nextKeepDirStructure, stringRedisTemplate, taskID, totalLength, nread); + long end = System.currentTimeMillis(); + LogUtil.info("压缩完成,耗时:" + (end - start) + " ms"); + } catch (Exception e) { + throw new RuntimeException("zip error from ZipUtils", e); + } finally { + if (zos != null) { + try { + zos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + /** 递归压缩 KeepDirStructure 一级目录是否保留 nextKeepDirStructure 下级目录是否保留*/ + public static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure + , StringRedisTemplate stringRedisTemplate, String taskID, long length, long nread)throws Exception{ + compress(sourceFile, zos, name, KeepDirStructure, KeepDirStructure, stringRedisTemplate, taskID, length, nread); + } + public static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure, boolean nextKeepDirStructure + , StringRedisTemplate stringRedisTemplate, String taskID, long length, long nread) + throws Exception { + byte[] buf = new byte[BUFFER_SIZE]; + if (sourceFile.isFile()) { + // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字 + zos.putNextEntry(new ZipEntry(name)); + // copy文件到zip输出流中 + int len; + FileInputStream in = new FileInputStream(sourceFile); + while ((len = in.read(buf)) != -1) { + zos.write(buf, 0, len); + nread += len; + updateProgress(nread, length, stringRedisTemplate, taskID); + } + // Complete the entry + zos.closeEntry(); + in.close(); + } else { + File[] listFiles = sourceFile.listFiles(); + if (listFiles == null || listFiles.length == 0) { + // 需要保留原来的文件结构时,需要对空文件夹进行处理 + if (KeepDirStructure) { + // 空文件夹的处理 + zos.putNextEntry(new ZipEntry(name + "/")); + // 没有文件,不需要文件的copy + zos.closeEntry(); + } + } else { + for (File file : listFiles) { + // 判断是否需要保留原来的文件结构 + if (KeepDirStructure) { + // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠, + // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了 + compress(file, zos, name + "/" + file.getName(), KeepDirStructure, stringRedisTemplate, taskID, length, nread); + } else { + compress(file, zos, file.getName(), nextKeepDirStructure, stringRedisTemplate, taskID, length, nread); + } + } + } + } + } + + /** + * 下载文件流 + * @param response + * @param fileName + * @param inputData + * @throws IOException + */ + public static void downloadFile(HttpServletResponse response, String fileName, InputStream inputData) throws IOException { + + BufferedInputStream bins = new BufferedInputStream(inputData);//放到缓冲流里面 + OutputStream outs = response.getOutputStream();//获取文件输出IO流 + BufferedOutputStream bouts = new BufferedOutputStream(outs); + response.setContentType("application/x-download"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + //开始向网络传输文件流 + while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) { + bouts.write(buffer, 0, bytesRead); + } + bouts.flush();//这里一定要调用flush()方法 + inputData.close(); + bins.close(); + outs.close(); + bouts.close(); + + } + /** 删除临时的.zip文件*/ + public static void deleteFile(File file) { + if (file.isDirectory()) { + File[] subFiles = file.listFiles(); + if (subFiles != null) { + for (File subFile : subFiles) { + deleteFile(subFile); + } + } + if (file.exists()) + file.delete(); // 删除文件夹 + } else { + if (file.exists()) + file.delete(); + } + } + /** + * @return + * @Description 删除目录及文件 + **/ + public static void deleteDirAndFiles(File file) { + File[] files = file.listFiles(); + if (files != null && files.length > 0) { + for (File f : files) { + deleteDirAndFiles(f); + } + } + file.delete(); + System.out.println("删除成功" + file.getName()); + } + + + /** + * 文件压缩功能 * @param sourcesFiles 源资源,即需要被压缩的文件 * @param zos 压缩包 * @param fileName 压缩包内的文件名称 + */ + public static void compressFile(File sourcesFiles, ZipOutputStream zos, String fileName) throws IOException { + //1.如果源资源是目录,先判断是否空文件夹 + if (sourcesFiles.isDirectory()) { + File[] files = sourcesFiles.listFiles(); + //1-1.先判断是否空文件夹 + if (files.length == 0) { + //1-2.空文件夹,则在压缩包中把目录加上 + zos.putNextEntry(new ZipEntry(fileName + File.separator)); + } else { + //1-3.如果不是空文件夹,则递归列出里面的文件以及文件夹 + for (File file : files) { + //文件名称以目录保持好 + compressFile(file, zos, fileName + File.separator + file.getName()); + } + } + } else { + //将文件放到压缩文件中,同时保留文件名称 + zos.putNextEntry(new ZipEntry(fileName)); + //IO的固化操作,先读取文件再写入文件压缩输出流中,过程不解释 + FileInputStream inputStream = new FileInputStream(sourcesFiles); + int len; + byte[] bytes = new byte[2048]; + while ((len = inputStream.read(bytes)) != -1) { + zos.write(bytes, 0, len); + } + zos.flush(); + //刷新流 + zos.closeEntry(); + inputStream.close(); + } + } + + /** + * @Description: 解压zip + * @params: zipFile 读取文件路径 descDir 输出目标路径 + */ + public String unzip(File zipFile,String descDir) { + String outPath = null; + File pathFile = new File(descDir);//创建目标路径 + if (!pathFile.exists()) {//判断是否存在文件夹 + pathFile.mkdirs();//创建文件夹 + } + + try { + ZipFile zip = new ZipFile(zipFile);//可以使用文件流获取文件路径进行创建流 + for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) { + //遍历所有文件 + ZipEntry entry = (ZipEntry) entries.nextElement(); + String zipEntryName = entry.getName(); + InputStream in = zip.getInputStream(entry); + outPath = (descDir + zipEntryName).replaceAll("\\\\", "/"); + + //判断路径是否存在,不存在则创建文件路径 + File file = new File(outPath.substring(0, outPath.lastIndexOf('/'))); + if (!file.exists()) { + file.mkdirs(); + } + //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压 + if (new File(outPath).isDirectory()) { + continue; + } + //输出文件路径信息 + OutputStream out = new FileOutputStream(outPath); + byte[] buf1 = new byte[1024]; + int len; + while ((len = in.read(buf1)) > 0) { + out.write(buf1, 0, len); + } + in.close();//关闭 + out.flush();//缓冲 + out.close();//关闭输出流 + } + }catch (Exception e){ + + } + + System.out.println("******************解压完毕********************"); + return outPath;//返回路径地址 + } + + public static void updateProgress(long nread, long length, StringRedisTemplate stringRedisTemplate, String taskID){ + if (!ObjectUtils.isEmpty(stringRedisTemplate) && nread > 0 && length > 0) { + int progress = Math.min(100, (int) Math.ceil(nread * 100 / length)); + stringRedisTemplate.opsForValue().set(GlobalConfig.progress_key_zip_file + taskID, String.valueOf(progress), 60, TimeUnit.SECONDS); + LogUtil.info("updateProgress=" + nread + "/" + length + ",progress=" + progress); + }else { + int progress = 0; + if (nread > 0 && length > 0){ + progress = Math.min(100, (int) Math.ceil(nread * 100 / length)); + } + LogUtil.info("updateProgress=" + nread + "/" + length + ",progress=" + progress); + } + } + + public static void main(String[] args) { + /*String finalFolderPath = "E:\\zip测试打包\\999\\gz2\\"; + String targetDir = "E:\\zip测试打包\\999\\"; + + String fileName = RandomUtil.getuuid() + System.currentTimeMillis() + + "_1" + ".zip"; + String finalFilePath = targetDir + fileName; + try { + toZip(finalFolderPath, finalFilePath, true, null, "111", 1011); + } catch (Exception e){ + + }*/ + File zipFile = new File("E:\\zip测试打包\\999__.zip"); + org.apache.commons.compress.archivers.zip.ZipFile zip = null; + try { + + zip = new org.apache.commons.compress.archivers.zip.ZipFile(zipFile); + java.util.Enumeration entries = zip.getEntries(); + + while (entries.hasMoreElements()) { + ZipArchiveEntry entry = entries.nextElement(); + System.out.println(entry.getName() + " : " + entry.getSize() + " bytes"); + if (!entry.isDirectory()) { + InputStream is = zip.getInputStream(entry); + StringWriter writer = new StringWriter(); + IOUtils.copy(is, writer, "UTF-8"); + String content = writer.toString(); + System.out.println(content); + } + } + + zip.close(); + } catch (Exception e){ + LogUtil.error(e); + } + + } + + private static ZipParameters setZipParameters(Integer level){ + ZipParameters parameters = new ZipParameters(); + parameters.setCompressionLevel(CompressionLevel.NORMAL); + if (!ObjectUtils.isEmpty(level)) { + if (0 == level) { + parameters.setCompressionLevel(CompressionLevel.NO_COMPRESSION); + }else if (1 == level){ + parameters.setCompressionLevel(CompressionLevel.FASTEST); + }else if (2 == level){ + parameters.setCompressionLevel(CompressionLevel.FASTER); + }else if (3 == level){ + parameters.setCompressionLevel(CompressionLevel.FAST); + }else if (4 == level){ + parameters.setCompressionLevel(CompressionLevel.MEDIUM_FAST); + }else if (6 == level){ + parameters.setCompressionLevel(CompressionLevel.HIGHER); + }else if (7 == level){ + parameters.setCompressionLevel(CompressionLevel.MAXIMUM); + }else if (8 == level){ + parameters.setCompressionLevel(CompressionLevel.PRE_ULTRA); + }else if (9 == level){ + parameters.setCompressionLevel(CompressionLevel.ULTRA); + } + } + return parameters; + } + + public static void toZipNew(String srcDir, String finalFilePath, StringRedisTemplate stringRedisTemplate, CheckFileDTO checkFileDTO + , long totalLength, List attachments, Map mainAttsMap) throws RuntimeException { + long nread = 0L; + String taskID = checkFileDTO.getTaskID(); + Integer level = checkFileDTO.getLevel(); + try { + ZipParameters parameters = setZipParameters(level); + net.lingala.zip4j.ZipFile zipFile = new net.lingala.zip4j.ZipFile(finalFilePath); + + for (IOSourceVo vo : attachments){ + if (mainAttsMap.containsKey(vo.getSourceID())){ + if (1 == vo.getIsFolder()) { + zipFile.addFolder(new File(srcDir + vo.getName())); + }else { + nread = nread + vo.getSize(); + zipFile.addFile(new File(vo.getPath()), parameters); + zipFile.renameFile(vo.getPath().substring(vo.getPath().lastIndexOf("/") + 1), vo.getPathDisplay() + vo.getName()); + updateProgress(nread, totalLength, stringRedisTemplate, taskID); + } + }else { + if (0 == vo.getIsFolder()) { + + nread = nread + vo.getSize(); + zipFile.addFile(new File(vo.getPath()), parameters); + zipFile.renameFile(vo.getPath().substring(vo.getPath().lastIndexOf("/") + 1), vo.getPathDisplay() + vo.getName()); + } + } + } + }catch (Exception e){ + LogUtil.error(e, ""); + } + } + + public static void toZipNewList(String srcDir, String finalFilePath, StringRedisTemplate stringRedisTemplate, CheckFileDTO checkFileDTO + , boolean isProgress, List attachments, Map mainAttsMap) throws RuntimeException { + String taskID = checkFileDTO.getTaskID(); + Integer level = checkFileDTO.getLevel(); + try { + ZipParameters parameters = setZipParameters(level); + net.lingala.zip4j.ZipFile zipFile = new net.lingala.zip4j.ZipFile(finalFilePath); + + Map fileNamesMap = new HashMap<>(); + LogUtil.info("zipProgressMonitor_getPercentDone=" + 0); + ArrayList filesToAdd = new ArrayList(); + for (IOSourceVo vo : attachments){ + if (mainAttsMap.containsKey(vo.getSourceID())){ + if (1 == vo.getIsFolder()) { + zipFile.addFolder(new File(srcDir + vo.getName())); + }else { + filesToAdd.add(new File(vo.getPath())); + fileNamesMap.put(vo.getPath().substring(vo.getPath().lastIndexOf("/") + 1), vo.getPathDisplay() + vo.getName()); + } + }else { + if (0 == vo.getIsFolder()) { + filesToAdd.add(new File(vo.getPath())); + fileNamesMap.put(vo.getPath().substring(vo.getPath().lastIndexOf("/") + 1), vo.getPathDisplay() + vo.getName()); + } + } + } + + if (!CollectionUtils.isEmpty(filesToAdd)){ + LogUtil.info("zipProgressMonitor_getPercentDone filesToAdd=" + JsonUtils.beanToJson(filesToAdd) + ", fileNamesMap=" + JsonUtils.beanToJson(fileNamesMap)); + zipFile.setRunInThread(true); + zipFile.addFiles(filesToAdd, parameters); + + ProgressMonitor zipProgressMonitor = zipFile.getProgressMonitor(); + while (!zipProgressMonitor.getState().equals(ProgressMonitor.State.READY)) { + if (isProgress) { + double p = zipProgressMonitor.getPercentDone(); + if (p >= 1){ + p = p - 1; + } + stringRedisTemplate.opsForValue().set(GlobalConfig.progress_key_zip_file + taskID, String.valueOf(p), 60, TimeUnit.SECONDS); + try { + LogUtil.info("zipProgressMonitor_getPercentDone=" + p); + Thread.sleep(100); + }catch (Exception e){ + LogUtil.error(e, "zipProgressMonitor_getPercentDone error"); + break; + } + } + } + if (zipProgressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) { + new net.lingala.zip4j.ZipFile(finalFilePath).renameFiles(fileNamesMap); + LogUtil.info("zipProgressMonitor_getPercentDone Successfully added folder to zip"); + } else if (zipProgressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) { + LogUtil.info("zipProgressMonitor_getPercentDone Error occurred. Error message: " + zipProgressMonitor.getException().getMessage()); + } else if (zipProgressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) { + LogUtil.info("zipProgressMonitor_getPercentDone Task cancelled"); + } + } + }catch (Exception e){ + LogUtil.error(e, ""); + } + + } +} diff --git a/src/main/java/com/svnlan/home/vo/ChangeSourceVo.java b/src/main/java/com/svnlan/home/vo/ChangeSourceVo.java new file mode 100644 index 0000000..27822b0 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/ChangeSourceVo.java @@ -0,0 +1,45 @@ +package com.svnlan.home.vo; + +import lombok.Data; +import org.springframework.util.ObjectUtils; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/27 16:10 + */ +@Data +public class ChangeSourceVo { + + private String name; + private String fileType; + private String path; + private String filePath; + private Integer isFolder; + private Integer pathLength = 0; + private Long size; + private String hashMd5 ; + public ChangeSourceVo(){} + public ChangeSourceVo(String name, Integer isFolder, String filePath){ + if (name.lastIndexOf("/") >= 0) { + this.name = name.substring(name.lastIndexOf("/") + 1, name.length()); + }else { + this.name = name; + } + this.isFolder = isFolder; + this.fileType = ""; + this.path = ""; + this.filePath = filePath; + this.pathLength = ObjectUtils.isEmpty(filePath) ? 0 : filePath.length(); + } + public ChangeSourceVo(String name, Integer isFolder, String fileType, String path, String filePath, Long size, String hashMd5){ + this.isFolder = isFolder; + this.fileType = fileType; + this.path = path; + this.filePath = filePath; + this.size = size; + this.hashMd5 = hashMd5; + this.pathLength = ObjectUtils.isEmpty(filePath) ? 0 : filePath.length(); + this.name = name; + } +} diff --git a/src/main/java/com/svnlan/home/vo/CommentVo.java b/src/main/java/com/svnlan/home/vo/CommentVo.java new file mode 100644 index 0000000..e2c1993 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/CommentVo.java @@ -0,0 +1,38 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/8/1 14:19 + */ +@Data +public class CommentVo { + /**评论id */ + private Long commentID; + /** 该评论上级ID */ + private Long pid; + /** 评论用户id */ + private Long userID; + /** 评论对象类型1分享2文件3文章4...... */ + private Integer targetType; + /** 评论对象id */ + private Long targetID; + /** 评论内容 */ + private String content; + private String targetContent; + /** 点赞统计 */ + private Integer praiseCount; + /** 评论统计 */ + private Integer commentCount; + /** 状态 1正常 2异常 3其他 */ + private Integer status; + private Long modifyTime; + private Long createTime; + private String name; + private String nickname; + private String targetUserName; + private String targetNickname; + private String avatar; +} diff --git a/src/main/java/com/svnlan/home/vo/CommonLabelVo.java b/src/main/java/com/svnlan/home/vo/CommonLabelVo.java new file mode 100644 index 0000000..890a997 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/CommonLabelVo.java @@ -0,0 +1,28 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/14 17:51 + */ +@Data +public class CommonLabelVo { + + private Long labelId; + private Long tagID; + private Long userID; + private String labelName; + private String tagName; + private String labelEnName; + private String enNameSimple; + private Integer status; + private Long createTime; + private Long modifyTime; + private String style; + private Integer sort; + private Integer selected; + private Integer tagType; + private String labelColor; +} diff --git a/src/main/java/com/svnlan/home/vo/CommonSourceVO.java b/src/main/java/com/svnlan/home/vo/CommonSourceVO.java new file mode 100644 index 0000000..dc357b8 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/CommonSourceVO.java @@ -0,0 +1,385 @@ +package com.svnlan.home.vo; + +import java.util.Date; + +/** + * @Author: + * @Description: + */ +public class CommonSourceVO { + private Long fileID; + private Long sourceID; + + private String hashMd5; + + private String path; + + private String name; + + private String fileType; + + private Long size; + + private String sourceServer; + + private Integer isPreview; + + private Integer isM3u8; + + private String previewUrl; + + private Integer appPreview; + + private String appPreviewUrl; + + private String thumb; + + private Integer sourceLength; + + private Integer platformId; + + private Long userID; + + private Date gmtCreate; + + private Date gmtModified; + + private Integer state; + + private Integer schoolId; + + private String msg; + + private Integer sourceType; + + private Long gmtCreateTimeStamp; + + private Integer isSwf; + + private String swfPreviewUrl; + + private Boolean isStatic; + + private Boolean isVideoCover; + + private String downloadUrl; + + private String resolution; + + private String busType; + + private Long courseWareId; + //视频转h264的路径 + private String h264Path; + //视频转h264是否成功, 0未成功,1成功,2失败 + private Integer isH264Preview; + private Integer isCommon; + private Long subCommonSourceId; + private String remark; + private String previewPath; + + public String getPreviewPath() { + return previewPath; + } + + public void setPreviewPath(String previewPath) { + this.previewPath = previewPath; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public Long getSourceID() { + return sourceID; + } + + public void setSourceID(Long sourceID) { + this.sourceID = sourceID; + } + + public Integer getIsCommon() { + return isCommon; + } + + public void setIsCommon(Integer isCommon) { + this.isCommon = isCommon; + } + + public Long getSubCommonSourceId() { + return subCommonSourceId; + } + + public void setSubCommonSourceId(Long subCommonSourceId) { + this.subCommonSourceId = subCommonSourceId; + } + + public String getH264Path() { + return h264Path; + } + + public void setH264Path(String h264Path) { + this.h264Path = h264Path; + } + + public Integer getIsH264Preview() { + return isH264Preview; + } + + public void setIsH264Preview(Integer isH264Preview) { + this.isH264Preview = isH264Preview; + } + + public Long getGmtCreateTimeStamp() { + return gmtCreateTimeStamp; + } + + public void setGmtCreateTimeStamp(Long gmtCreateTimeStamp) { + this.gmtCreateTimeStamp = gmtCreateTimeStamp; + } + + public Long getFileID() { + return fileID; + } + + public void setFileID(Long fileID) { + this.fileID = fileID; + } + + public String getHashMd5() { + return hashMd5; + } + + public void setHashMd5(String hashMd5) { + this.hashMd5 = hashMd5; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public String getSourceServer() { + return sourceServer; + } + + public void setSourceServer(String sourceServer) { + this.sourceServer = sourceServer; + } + + public Integer getIsPreview() { + return isPreview; + } + + public void setIsPreview(Integer isPreview) { + this.isPreview = isPreview; + } + + public Integer getIsM3u8() { + return isM3u8; + } + + public void setIsM3u8(Integer isM3u8) { + this.isM3u8 = isM3u8; + } + + public String getPreviewUrl() { + return previewUrl; + } + + public void setPreviewUrl(String previewUrl) { + this.previewUrl = previewUrl; + } + + public Integer getAppPreview() { + return appPreview; + } + + public void setAppPreview(Integer appPreview) { + this.appPreview = appPreview; + } + + public String getAppPreviewUrl() { + return appPreviewUrl; + } + + public void setAppPreviewUrl(String appPreviewUrl) { + this.appPreviewUrl = appPreviewUrl; + } + + public String getThumb() { + return thumb; + } + + public void setThumb(String thumb) { + this.thumb = thumb; + } + + public Integer getSourceLength() { + return sourceLength; + } + + public void setSourceLength(Integer sourceLength) { + this.sourceLength = sourceLength; + } + + public Integer getPlatformId() { + return platformId; + } + + public void setPlatformId(Integer platformId) { + this.platformId = platformId; + } + + public Long getUserID() { + return userID; + } + + public void setUserID(Long userID) { + this.userID = userID; + } + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + this.gmtCreateTimeStamp = gmtCreate.getTime(); + } + + public Date getGmtModified() { + return gmtModified; + } + + public void setGmtModified(Date gmtModified) { + this.gmtModified = gmtModified; + } + + public Integer getState() { + return state; + } + + public void setState(Integer state) { + this.state = state; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public Integer getSchoolId() { + return schoolId; + } + + public void setSchoolId(Integer schoolId) { + this.schoolId = schoolId; + } + + public Integer getSourceType() { + return sourceType; + } + + public void setSourceType(Integer sourceType) { + this.sourceType = sourceType; + } + + public Integer getIsSwf() { + return isSwf; + } + + public void setIsSwf(Integer isSwf) { + this.isSwf = isSwf; + } + + public String getSwfPreviewUrl() { + return swfPreviewUrl; + } + + public void setSwfPreviewUrl(String swfPreviewUrl) { + this.swfPreviewUrl = swfPreviewUrl; + } + + public Boolean getStatic() { + return isStatic; + } + + public void setStatic(Boolean aStatic) { + isStatic = aStatic; + } + + public Boolean getVideoCover() { + return isVideoCover; + } + + public void setVideoCover(Boolean videoCover) { + isVideoCover = videoCover; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getResolution() { + return resolution; + } + + public void setResolution(String resolution) { + this.resolution = resolution; + } + + public String getBusType() { + return busType; + } + + public void setBusType(String busType) { + this.busType = busType; + } + + public Long getCourseWareId() { + return courseWareId; + } + + public void setCourseWareId(Long courseWareId) { + this.courseWareId = courseWareId; + } +} diff --git a/src/main/java/com/svnlan/home/vo/FileMetaVo.java b/src/main/java/com/svnlan/home/vo/FileMetaVo.java new file mode 100644 index 0000000..39383ee --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/FileMetaVo.java @@ -0,0 +1,43 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/17 13:24 + */ +@Data +public class FileMetaVo { + + /** 文档封面logo,主要用于视频格式,此为原始地址,小图在文件名后加_50_50类格式 */ + private String thumb; + /** 图片,视频分辨率, width*height */ + private String resolution; + /** previewUrl 预览地址,可为视频的m3u8地址或图片的存储地址或者文档类型的flash地址*/ + private String viewUrl; + /**视频转h264的路径 */ + private String h264Path; + /** APP文档预览路径*/ + private String appViewUrl; + /** 获取视频长度*/ + private Integer length; + + /** 视频编码名称 */ + private String codecName; + /** 平均帧率*/ + private String avgFrameRate; + /** 实时帧率*/ + private String frameRate; + /** 音频包的采样率 */ + private String sampleRate; + /** 音频声道 */ + private String channels; + /** 音频编码名称 */ + private String audioCodecName; + /** 封面,可上传*/ + private String cover; + private String yzViewData; + private String yzEditData; + private String frame; +} diff --git a/src/main/java/com/svnlan/home/vo/HomeExplorerFileVO.java b/src/main/java/com/svnlan/home/vo/HomeExplorerFileVO.java new file mode 100644 index 0000000..ac00019 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/HomeExplorerFileVO.java @@ -0,0 +1,8 @@ +package com.svnlan.home.vo; + +/** + * @author KingMgg + * @data 2023/2/6 18:01 + */ +public class HomeExplorerFileVO extends HomeExplorerVO{ +} diff --git a/src/main/java/com/svnlan/home/vo/HomeExplorerFolderVO.java b/src/main/java/com/svnlan/home/vo/HomeExplorerFolderVO.java new file mode 100644 index 0000000..b7663d1 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/HomeExplorerFolderVO.java @@ -0,0 +1,8 @@ +package com.svnlan.home.vo; + +/** + * @author KingMgg + * @data 2023/2/6 18:01 + */ +public class HomeExplorerFolderVO extends HomeExplorerVO{ +} diff --git a/src/main/java/com/svnlan/home/vo/HomeExplorerResult.java b/src/main/java/com/svnlan/home/vo/HomeExplorerResult.java new file mode 100644 index 0000000..f53778c --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/HomeExplorerResult.java @@ -0,0 +1,26 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author KingMgg + * @data 2023/2/6 18:02 + */ + +@Data +public class HomeExplorerResult { + List fileList; + List folderList; + Map current; + Long total; + String listType; + String listIconSize; + /** 文件夹 排序字段*/ + private String listSortField; + /** 文件夹 排序升序降序*/ + private String listSortOrder; + +} diff --git a/src/main/java/com/svnlan/home/vo/HomeExplorerShareDetailVO.java b/src/main/java/com/svnlan/home/vo/HomeExplorerShareDetailVO.java new file mode 100644 index 0000000..78ade28 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/HomeExplorerShareDetailVO.java @@ -0,0 +1,22 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @author KingMgg + * @data 2023/2/8 13:53 + */ +@Data +public class HomeExplorerShareDetailVO { + /** + * 自增id + */ + Long sourceID; + Integer isFolder; + String name; + String fileType; + Long createTime; + Long parentID; + String parentLevel; + +} diff --git a/src/main/java/com/svnlan/home/vo/HomeExplorerVO.java b/src/main/java/com/svnlan/home/vo/HomeExplorerVO.java new file mode 100644 index 0000000..d0ef7d6 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/HomeExplorerVO.java @@ -0,0 +1,218 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +import java.util.List; + + +/** + * @author KingMgg + * @data 2023/2/6 13:31 + */ +@Data +public class HomeExplorerVO { + + private Double ignoreFileSize; + private Long sizeUse; + private Double userSizeMax; + private Long userSizeUse; + private Long groupID; + private Long userID; + private Long sort; + private Double sizeMax; + private String groupName; + private String sourceType; + private String path; + private String hashMd5; + /** + * 来源id + */ + private Long sourceID; + private String keyword; + /** + * 拥有者对象id + */ + private Long targetID; + /** + * 创建者id + */ + private Long createUser; + /** + * 父级资源id,为0则为部门或用户根文件夹,添加用户部门时自动新建 + */ + private Long parentID; + /** + * 最后修改者 + */ + private Long modifyUser; + /** + * 对应存储资源id,文件夹则该处为0 + */ + private Long fileID; + /** + * 占用空间大小 + */ + private Long size; + /** + * 创建时间 + */ + private Long createTime; + private Long fileCreateTime; + /** + * 最后修改时间 + */ + private Long modifyTime; + /** + * 最后访问时间 + */ + private Long viewTime; + /** + * id的hash + */ + private String sourceHash; + /** + * 文件名 + */ + private String name=""; + /** + * 文件扩展名,文件夹则为空 + */ + private String fileType; + /** + * 父路径id; 例如: ,2,5,10, + */ + private String parentLevel; + /** + * 文档所属类型 (0-sys,1-user,2-group) + */ + private Integer targetType; + /** + * 是否为文件夹(0否,1是) + */ + private Integer isFolder; + /** + * 是否删除(0-正常 1-已删除) + */ + private Integer isDelete; + + private Boolean canDownload; + private String ext; + private String extType; + private Boolean isTruePath; + private Boolean isParent; + private String type; + private String pathDesc; + private String pathDisplay; + private String open; + private String icon; + private Integer hasFolder; + private Integer hasFile; + private Integer fileCount; + private Boolean isChildren; + + private HomeExplorerResult children; + + private CommonLabelVo tagInfo; + private String key; + private String value; + private String listViewKey; + private String listViewValue; + private Long id; + + private String resolution; + private Integer length; + private String thumb; + private Integer authID; + private String auth; + + private String createUserJson; + private String modifyUserJson; + private Integer isFav; + private String tags; + private String downloadUrl; + private Integer isShare; + + + private Long labelId; + private String labelName; + private Integer status; + private String style; + private Integer selected; + + /** 视频编码名称 */ + private String codecName; + /** 平均帧率*/ + private String avgFrameRate; + /** 实时帧率*/ + private String frameRate; + /** 音频包的采样率 */ + private String sampleRate; + /** 音频声道 */ + private String channels; + /** 音频编码名称 */ + private String audioCodecName; + /** 描述 */ + private String description; + private String title; + private String sourcePath; + private Long timeTo; + private Integer numView; + private Integer numDownload; + private String cover; + private String authName; + private List tagList; + private String parentName; + private String favPath; + private String favType; + private Long favID; + private String favName; + private String oexeContent; + private HomeExplorerVO sourceInfo; + private Long oexeSourceID; + private Long oexeFileID; + private Integer oexeIsFolder; + private String oexeFileType; + private String yzViewData; + private String yzEditData; + private String pptPreviewUrl; + private String detail; + private String avatar; + private String nickname; + private String shareHash; + /**视频转h264的路径 */ + private String h264Path; + /** 是否禁用 1 允许下载 0 禁用*/ + private Integer down; + private Integer downNum; + /** 是否禁用浏览 1 允许流量 0 禁用*/ + private Integer preview; + + private String roleList; + private String label; + private Integer isGroup; + private Long shareID; + private Integer isExistFile; + private Integer isM3u8; + private Integer canShare; + private String viewUrl; + private Integer isH264Preview; + private String fileName; + private String pUrl; + + public String getpUrl() { + return pUrl; + } + + public void setpUrl(String pUrl) { + this.pUrl = pUrl; + } + + /* + key: fileIconSize +value: 108 +listViewKey: listType +listViewValue: icon:108 +listViewPath: {source:1}/ + */ + +} diff --git a/src/main/java/com/svnlan/home/vo/HomeFileDetailVO.java b/src/main/java/com/svnlan/home/vo/HomeFileDetailVO.java new file mode 100644 index 0000000..2bf8429 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/HomeFileDetailVO.java @@ -0,0 +1,53 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @author KingMgg + * @data 2023/2/7 10:30 + */ +@Data +public class HomeFileDetailVO { + Long sourceID; + Long fileID; + /** + * 文件名 + */ + String name; + /** + * 文件大小 + */ + Long size; + /** + * io的id + */ + Integer ioType; + /** + * 文件路径 + */ + + String path; + /** + * 文件简易hash(不全覆盖);hashSimple + */ + String hashSimple; + /** + * 文件hash, md5 + */ + + String hashMd5; + /** + * 引用次数;0则定期删除 + */ + + Long linkCount; + /** + * 修改时间 + */ + + Long createTime; + /** + * 最后修改时间 + */ + Long modifyTime; +} diff --git a/src/main/java/com/svnlan/home/vo/IOSourceVo.java b/src/main/java/com/svnlan/home/vo/IOSourceVo.java new file mode 100644 index 0000000..12d44cc --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/IOSourceVo.java @@ -0,0 +1,88 @@ +package com.svnlan.home.vo; + +import com.svnlan.home.domain.IOSource; +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/20 12:45 + */ +@Data +public class IOSourceVo { + private Integer fileCount; + private Long id; + private Long sourceID; + /** id的hash*/ + private String sourceHash; + /** 文档所属类型 (0-sys,1-user,2-group)*/ + private Integer targetType; + /** 拥有者对象id*/ + private Long targetID; + /** 创建者id */ + private Long createUser; + /** 最后修改者 */ + private Long modifyUser; + /** 是否为文件夹(0否,1是) */ + private Integer isFolder; + /** 文件名 */ + private String name; + /** 文件扩展名,文件夹则为空 */ + private String fileType; + /** 父级资源id,为0则为部门或用户根文件夹,添加用户部门时自动新建 */ + private Long parentID; + /** 父路径id; 例如: ,2,5,10, */ + private String parentLevel; + /** 对应存储资源id,文件夹则该处为0 */ + private Long fileID; + /** 是否删除(0-正常 1-已删除) */ + private Integer isDelete; + /** 占用空间大小 */ + private Long size; + /** */ + private Long createTime; + /** */ + private Long modifyTime; + /** 最后访问时间 */ + private Long viewTime; + private Long userID; + private Long oldSourceID; + private String path; + private String fileName; + /** 路径 */ + private String pathDisplay; + private Long convertSize; + private Long thumbSize; + /** + * 存储id 对应的 system_options 表主键 + */ + private Integer storageID; + + public IOSourceVo(){} + public IOSourceVo(String name, Integer isFolder){ + this.name = name; + this.isFolder = isFolder; + } + + public IOSourceVo copyFromIoSource(IOSource ioSource) { + this.sourceID = ioSource.getSourceID(); + this.sourceHash = ioSource.getSourceHash(); + this.targetType = ioSource.getTargetType(); + this.targetID = ioSource.getTargetID(); + this.createUser = ioSource.getCreateUser(); + this.modifyUser = ioSource.getModifyUser(); + this.isFolder = ioSource.getIsFolder(); + this.name = ioSource.getName(); + this.fileType = ioSource.getFileType(); + this.parentID = ioSource.getParentID(); + this.parentLevel = ioSource.getParentLevel(); + this.fileID = ioSource.getFileID(); + this.isDelete = ioSource.getIsDelete(); + this.size = ioSource.getSize(); + this.createTime = ioSource.getCreateTime(); + this.modifyTime = ioSource.getModifyTime(); + this.viewTime = ioSource.getViewTime(); + this.storageID = ioSource.getStorageID(); + return this; + } +} diff --git a/src/main/java/com/svnlan/home/vo/IoSourceAuthVo.java b/src/main/java/com/svnlan/home/vo/IoSourceAuthVo.java new file mode 100644 index 0000000..afe58fd --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/IoSourceAuthVo.java @@ -0,0 +1,36 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/12 14:16 + */ +@Data +public class IoSourceAuthVo { + + private Long id; + private Long sourceID; + private Integer targetType; + private Long targetID; + private Integer authID; + private Integer authDefine; + private Long createTime; + private Long modifyTime; + private String nickname; + private Long parentID; + private String parentLevel; + private String parentGroupName; + private String authName; + private String label; + private String auth; + + public IoSourceAuthVo(){} + public IoSourceAuthVo(Integer authID, String authName, String label, String auth){ + this.authID = authID; + this.authName = authName; + this.label = label; + this.auth = auth; + } +} diff --git a/src/main/java/com/svnlan/home/vo/IoSourceEventVo.java b/src/main/java/com/svnlan/home/vo/IoSourceEventVo.java new file mode 100644 index 0000000..e2dad08 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/IoSourceEventVo.java @@ -0,0 +1,32 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/22 15:44 + */ +@Data +public class IoSourceEventVo { + + private Long id; + private Long sourceID; + private Long sourceParent; + private Long userID; + private String type; + private String desc; + private Long createTime; + + private String name; + private String avatar; + private String nickname; + private Integer sex; + private Integer status; + private String parentName; + private Integer isFolder; + private Long ppID; + private Integer parentTargetType; + private Integer isChildren; + +} diff --git a/src/main/java/com/svnlan/home/vo/IoSourceHistoryVo.java b/src/main/java/com/svnlan/home/vo/IoSourceHistoryVo.java new file mode 100644 index 0000000..cd3d798 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/IoSourceHistoryVo.java @@ -0,0 +1,25 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/24 17:10 + */ +@Data +public class IoSourceHistoryVo { + private Long id; + private Long sourceID; + private Long userID; + private Long fileID; + private Long size; + private Long createTime; + private Long modifyTime; + private String detail; + private String name; + private String avatar; + private String nickname; + private String sex; + private String status; +} diff --git a/src/main/java/com/svnlan/home/vo/LogDescVo.java b/src/main/java/com/svnlan/home/vo/LogDescVo.java new file mode 100644 index 0000000..0469f5c --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/LogDescVo.java @@ -0,0 +1,34 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/29 13:57 + */ +@Data +public class LogDescVo { + + private Long sourceID; + /** 父ID */ + private Long sourceParent; + /** 文件名 */ + private String pathName; + private String pathDisplay; + private Long userID; + private String type; + /** 目标ID */ + private Long sourceTarget; + private String country; + private String nickName; + private String ip; + private String browser; + private String name; + private String ua; + private String network; + private String sourceParentName; + private String fromName; + private Long fromSourceID; + +} diff --git a/src/main/java/com/svnlan/home/vo/ParentPathDisplayVo.java b/src/main/java/com/svnlan/home/vo/ParentPathDisplayVo.java new file mode 100644 index 0000000..9abc702 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/ParentPathDisplayVo.java @@ -0,0 +1,18 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/5/22 15:19 + */ +@Data +public class ParentPathDisplayVo { + private String parentLevel; + private String parentIDStr; + private String parentLevelName; + private Integer targetType; + private Long sourceID; + private String name; +} diff --git a/src/main/java/com/svnlan/home/vo/ShareAuthDto.java b/src/main/java/com/svnlan/home/vo/ShareAuthDto.java new file mode 100644 index 0000000..38796f2 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/ShareAuthDto.java @@ -0,0 +1,15 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/8 13:08 + */ +@Data +public class ShareAuthDto { + private Integer authID; + private Long targetID; + private Integer targetType; +} diff --git a/src/main/java/com/svnlan/home/vo/ShareToVo.java b/src/main/java/com/svnlan/home/vo/ShareToVo.java new file mode 100644 index 0000000..3a3c4c6 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/ShareToVo.java @@ -0,0 +1,20 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/8 13:11 + */ +@Data +public class ShareToVo { + private Long id; + private Long shareID; + private Integer targetType; + private Long targetID; + private Integer authID; + private Integer authDefine; + private Long createTime; + private Long modifyTime; +} diff --git a/src/main/java/com/svnlan/home/vo/ShareVo.java b/src/main/java/com/svnlan/home/vo/ShareVo.java new file mode 100644 index 0000000..c259247 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/ShareVo.java @@ -0,0 +1,67 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/3 13:40 + */ +@Data +public class ShareVo extends HomeExplorerResult{ + + private Long shareID; + /** 分享标题 */ + private String title; + /** shareid */ + private String shareHash; + /** 分享用户id */ + private Long userID; + /** 用户数据id */ + private Long sourceID; + /** 分享文档路径 */ + private String sourcePath; + /** 分享别名,替代shareHash */ + private String url; + /** 是否外链分享;默认为0 */ + private Integer isLink; + /** 是否为内部分享;默认为0 */ + private Integer isShareTo; + /** 访问密码,为空则无密码 */ + private String password; + /** 到期时间,0-永久生效*/ + private Long timeTo; + /** 预览次数 */ + private Integer numView; + /** 下载次数*/ + private Integer numDownload; + /** json 配置信息;是否可以下载,是否可以上传等*/ + private String options; + /** 创建时间 */ + private Long createTime; + /** 最后修改时间 */ + private Long modifyTime; + + private Boolean success; + private Integer needPwd; + private String message; + private String code; + /** login 是否需要登录 1 是 0 否 */ + private Integer login; + /** 下载次数下载 */ + private Integer downNum; + /** 是否禁用 1 允许下载 0 禁用*/ + private Integer down; + /** 是否禁用浏览 1 允许流量 0 禁用*/ + private Integer preview; + private Long shareToTimeout; + private List authTo; + private HomeExplorerVO shareFile; + private String avatar; + private String nickname; + private String userName; + + private Integer status; +} diff --git a/src/main/java/com/svnlan/home/vo/SystemSortVo.java b/src/main/java/com/svnlan/home/vo/SystemSortVo.java new file mode 100644 index 0000000..033c90d --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/SystemSortVo.java @@ -0,0 +1,49 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/2/15 14:48 + */ +@Data +public class SystemSortVo { + + /** 文件夹 icon 显示大小*/ + private String fileIconSize; + /** 文件夹 排序字段*/ + private String listSortField; + /** 文件夹 排序升序降序*/ + private String listSortOrder; + /** 显示方式 0 适用于所有文件夹 1 适用于单个文件夹 */ + private String listSortKeep; + private String listType; + + private String sourceID; + + public SystemSortVo(){} + public SystemSortVo(String sourceID,String listType,String fileIconSize){ + this.sourceID = sourceID; + this.listType = listType; + this.fileIconSize = fileIconSize; + } + public SystemSortVo(String sourceID,String listSortField,String listSortOrder, boolean sort){ + this.sourceID = sourceID; + this.listSortField = listSortField; + this.listSortOrder = listSortOrder; + } + + List listSortList; + List listTypeList; + + // 'listSortField','listSortOrder','fileIconSize','listSortKeep','listSort','listType' + // ('listSortField','listSortOrder','fileIconSize','listSortKeep','listSort','listType') +/* +SELECT * +FROM `user_option` +where userID = 1 and `key` in ('listSortField','listSortOrder','fileIconSize','listSortKeep','listSort','listType') + */ +} diff --git a/src/main/java/com/svnlan/home/vo/UserFavVo.java b/src/main/java/com/svnlan/home/vo/UserFavVo.java new file mode 100644 index 0000000..d4046a9 --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/UserFavVo.java @@ -0,0 +1,29 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/3/2 14:03 + */ +@Data +public class UserFavVo { + + private Long id; + /** */ + private Long userID; + /** 标签id,收藏则为0 */ + private Integer tagID; + /** 收藏名称 */ + private String name; + /** 收藏路径,tag时则为sourceID */ + private String path; + private String files; + private String tags; + private String style; + private String tagName; + private List favList; +} diff --git a/src/main/java/com/svnlan/home/vo/YzEditParamsDto.java b/src/main/java/com/svnlan/home/vo/YzEditParamsDto.java new file mode 100644 index 0000000..12bde6b --- /dev/null +++ b/src/main/java/com/svnlan/home/vo/YzEditParamsDto.java @@ -0,0 +1,39 @@ +package com.svnlan.home.vo; + +import lombok.Data; + +/** + * @Author: sulijuan + * @Description: + * @Date: 2023/4/3 11:35 + */ +@Data +public class YzEditParamsDto { + + private String userId; + private String fileId; + private String fileName; + private String filePath; + /** 回调地址。 + 如果为null,不会进行任何操作; + 如果不为null,WebOffice会在关闭该文档后向此地址发送HTTP请求以进行通知, + 请求带有3个参数:userId(String或List,所有打开过此文档的用户的id)、fileId和filePath。 + (默认为null) + */ + private String callbackUrl; + + public YzEditParamsDto(){} + public YzEditParamsDto(String userId, String fileId, String fileName, String filePath){ + this.userId = userId; + this.fileId = fileId; + this.fileName = fileName; + this.filePath = filePath; + } + public YzEditParamsDto(String userId, String fileId, String fileName, String filePath,String callbackUrl){ + this.userId = userId; + this.fileId = fileId; + this.fileName = fileName; + this.filePath = filePath; + this.callbackUrl = callbackUrl; + } +} diff --git a/src/main/java/com/svnlan/interceptor/CorsConfig.java b/src/main/java/com/svnlan/interceptor/CorsConfig.java new file mode 100644 index 0000000..ede42d6 --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/CorsConfig.java @@ -0,0 +1,22 @@ +package com.svnlan.interceptor; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @Author: @Description:Cors跨域访问配置 + */ +@Configuration +public class CorsConfig implements WebMvcConfigurer { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry + .addMapping("/**") + .allowedOrigins("*") + .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") + // 预响应的高速缓存持续时间的最大时间(以秒为单位) + .allowCredentials(false) + .maxAge(3600); + } +} diff --git a/src/main/java/com/svnlan/interceptor/HandlerExceptionAdvice.java b/src/main/java/com/svnlan/interceptor/HandlerExceptionAdvice.java new file mode 100644 index 0000000..5df1c6e --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/HandlerExceptionAdvice.java @@ -0,0 +1,81 @@ +package com.svnlan.interceptor; + +import com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException; +import com.svnlan.common.Result; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.utils.LogUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Profile; +import org.springframework.jdbc.BadSqlGrammarException; +import org.springframework.validation.ObjectError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.List; + +/** + * 异常处理 + * + * @author lingxu 2023/03/21 10:31 + */ +@Slf4j +@Profile({"pro", "pre", "test"}) +@RestControllerAdvice(basePackages = { + "com.svnlan.home.controller", + "com.svnlan.user.controller", + "com.svnlan.jwt.controller", + "com.svnlan.manager.controller", + "com.svnlan.webdav"}) +public class HandlerExceptionAdvice { + + /** + * 处理业务 数据上的一些错误 + */ + @ExceptionHandler(IllegalArgumentException.class) + public Result handlerIllegalArgumentException(IllegalArgumentException ex) { + LogUtil.error(ex, "错误类型 => {}", ex.toString()); + return Result.returnError(ex.getMessage()); + } + + /** + * 参数未校验通过的 + */ + @ExceptionHandler(value = {MethodArgumentNotValidException.class, MissingServletRequestParameterException.class}) + public Result MethodArgumentNotValidExceptionHandler(Exception ex) { + StringBuilder detailMessage = new StringBuilder(); + if (ex instanceof MethodArgumentNotValidException) { + MethodArgumentNotValidException ex1 = (MethodArgumentNotValidException) ex; + List list = ex1.getBindingResult().getAllErrors(); + list.forEach(a -> detailMessage.append(a.getDefaultMessage()).append(" ")); + return Result.returnError(detailMessage.toString()); + } else { + MissingServletRequestParameterException ex1 = (MissingServletRequestParameterException) ex; + detailMessage.append(ex1.getMessage()); + } + LogUtil.error(ex, "错误类型 => {}", ex.toString()); + ex.printStackTrace(); + return Result.returnError(CodeMessageEnum.shareErrorParam); + } + + @ExceptionHandler({BadSqlGrammarException.class, MySQLSyntaxErrorException.class}) + public Result handlerSQLException(Exception ex) { + LogUtil.error(ex, "错误类型 => {}", ex.toString()); + return Result.returnError("系统错误,请联系管理员"); + } + + @ExceptionHandler(SvnlanRuntimeException.class) + public Result HandlerException(SvnlanRuntimeException ex) { + LogUtil.error(ex, "错误类型 => {}", ex.toString()); + return new Result(false, ex.getErrorCode(), null); + } + + @ExceptionHandler(Exception.class) + public Result handlerException(Exception ex) { + LogUtil.error(ex, "错误类型 => {}", ex.toString()); + return Result.returnError("系统内部错误,请联系管理员"); + } + +} diff --git a/src/main/java/com/svnlan/interceptor/MyLocaleResolver.java b/src/main/java/com/svnlan/interceptor/MyLocaleResolver.java new file mode 100644 index 0000000..0869473 --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/MyLocaleResolver.java @@ -0,0 +1,39 @@ +package com.svnlan.interceptor; + +import com.svnlan.jwt.constant.SystemConstant; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.LocaleResolver; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Locale; + +/** + * @Author: + * @Description: + */ +@Component +public class MyLocaleResolver implements LocaleResolver { + + @Override + public Locale resolveLocale(HttpServletRequest httpServletRequest) { + Locale locale = Locale.getDefault(); + // 获取请求中的语言参数 + String language = httpServletRequest.getHeader(SystemConstant.LANG); + // 验证参数的有效性 + if(StringUtils.hasLength(language)){ + //zh_CN + String[] split = language.split("_"); + //国家,地区 + locale = new Locale(split[0], split[1]); + } + + return locale; + } + + @Override + public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { + + } +} diff --git a/src/main/java/com/svnlan/interceptor/MyMvcConfig.java b/src/main/java/com/svnlan/interceptor/MyMvcConfig.java new file mode 100644 index 0000000..2831aac --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/MyMvcConfig.java @@ -0,0 +1,20 @@ +package com.svnlan.interceptor; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @Author: + * @Description: + */ +@Configuration +public class MyMvcConfig implements WebMvcConfigurer { + + @Bean + public LocaleResolver localeResolver(){ + return new MyLocaleResolver(); + } + +} diff --git a/src/main/java/com/svnlan/interceptor/ParentInterceptor.java b/src/main/java/com/svnlan/interceptor/ParentInterceptor.java new file mode 100644 index 0000000..c37e3d3 --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/ParentInterceptor.java @@ -0,0 +1,115 @@ +package com.svnlan.interceptor; + +import com.svnlan.common.CheckResult; +import com.svnlan.common.Result; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.home.utils.UserAuthTool; +import com.svnlan.jwt.constant.SystemConstant; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.utils.JsonUtils; +import com.svnlan.utils.JwtUtils; +import com.svnlan.utils.LogUtil; +import com.svnlan.utils.LoginUserUtil; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @Author: + * @Description: + */ +@Configuration +public class ParentInterceptor implements HandlerInterceptor { + + @Resource + LoginUserUtil loginUserUtil; + @Resource + UserAuthTool userAuthTool; + + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + if (!(handler instanceof HandlerMethod)) { + return true; + } + + String token = request.getHeader(SystemConstant.JWT_TOKEN); + LogUtil.info("ParentInterceptor getRequestURI=" + request.getRequestURI() + " token=" + token); + if (StringUtils.isEmpty(token)) { + print(response, CodeMessageEnum.loginFirst.getCode()); + return false; + } else { + // 验证JWT的签名,返回CheckResult对象 + CheckResult checkResult = JwtUtils.validateJWT(token, false); + if (checkResult.isSuccess()) { + return true; + } + switch (checkResult.getErrCode()) { + // 签名验证不通过 + case SystemConstant.JWT_ERRCODE_FAIL: + LogUtil.info("ParentInterceptor 签名验证不通过 token=" + token); + print(response, CodeMessageEnum.bindSignError.getCode()); + break; + // 签名过期,返回过期提示码 + case SystemConstant.JWT_ERRCODE_EXPIRE: + /* 签名过期 */ + LogUtil.info("ParentInterceptor 签名过期 token=" + token); + print(response, CodeMessageEnum.bindSignError.getCode()); + break; + default: + break; + } + return false; + } + + } + private void print(HttpServletResponse response, String code){ + print(response, code, null); + } + private void print(HttpServletResponse response,String code, Object data) { + try { + response.setStatus(HttpStatus.OK.value()); + response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + response.setHeader("Cache-Control", "no-cache, must-revalidate"); + PrintWriter writer = response.getWriter(); + Result result = new Result(code.equals(CodeMessageEnum.success.getCode()), code, data); + writer.write(JsonUtils.beanToJson(result)); + writer.flush(); + writer.close(); + } catch (IOException e) { + LogUtil.error(e, "拦截器print"); + } + } + + public void postHandle( + HttpServletRequest request, + HttpServletResponse response, + Object handler, + ModelAndView modelAndView) { + if (response.getStatus() == 500) { + LogUtil.error("拦截器出错,"+ request.getRequestURI()); + } else if (response.getStatus() == 404) { + LogUtil.error("拦截器出错,"+ request.getRequestURI()); + } + } + + /** + * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, + * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。 + */ + public void afterCompletion( + HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + } +} diff --git a/src/main/java/com/svnlan/interceptor/RequestWebFilter.java b/src/main/java/com/svnlan/interceptor/RequestWebFilter.java new file mode 100644 index 0000000..0575db5 --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/RequestWebFilter.java @@ -0,0 +1,70 @@ +package com.svnlan.interceptor; + +import com.svnlan.webdav.FileProperties; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Resource; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 请求过滤 获取到用户Id + * + * @author lingxu 2023/04/15 10:27 + */ +@Slf4j +//@WebFilter +public class RequestWebFilter implements Filter { + + @Resource + private FileProperties fileProperties; + + public static final Pattern compile = Pattern.compile("^/webdav/(?\\d+)/.*"); + + public static final ThreadLocal userThreadLocal = new ThreadLocal<>(); + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + String uri = slash(req.getRequestURI(), SlashEnum.ADD); + + log.info("uri =>{}", uri); + if (uri.startsWith(fileProperties.webdavPrefixPath())) { + // 表示是 webdav 请求 + Matcher matcher = compile.matcher(uri); + if (matcher.find()) { + try { + String userId = matcher.group("userId"); +// log.info("userId => {}", userId); + userThreadLocal.set(Long.parseLong(userId)); + uri = slash(uri.replaceFirst("/" + userId, ""), SlashEnum.REMOVE); + log.info("replace uri => {}", uri); + req.getRequestDispatcher(uri).forward(request, response); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("用户id必须为数字类型"); + } finally { + userThreadLocal.remove(); + } + } else { + throw new IllegalArgumentException("必须要有userId"); + } + } else + chain.doFilter(request, response); + } + + enum SlashEnum { + ADD, REMOVE + } + + public String slash(String uri, SlashEnum type) { + if (type == SlashEnum.ADD && !uri.endsWith("/")) { + return uri + "/"; + } else if (type == SlashEnum.REMOVE && uri.endsWith("/")) { + return uri.substring(0, uri.length() - 1); + } + return uri; + } +} diff --git a/src/main/java/com/svnlan/interceptor/SqlCostInterceptor.java b/src/main/java/com/svnlan/interceptor/SqlCostInterceptor.java new file mode 100644 index 0000000..f86b83d --- /dev/null +++ b/src/main/java/com/svnlan/interceptor/SqlCostInterceptor.java @@ -0,0 +1,243 @@ +package com.svnlan.interceptor; + +import java.lang.reflect.Field; +import java.sql.Statement; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.ParameterMapping; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Plugin; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.defaults.DefaultSqlSession.StrictMap; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +/** + * Sql执行时间记录拦截器 + */ +@Slf4j +@Profile("pro") +@Component +@Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}), + @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}), + @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})}) +public class SqlCostInterceptor implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + Object target = invocation.getTarget(); + + long startTime = System.currentTimeMillis(); + StatementHandler statementHandler = (StatementHandler) target; + try { + return invocation.proceed(); + } finally { + long endTime = System.currentTimeMillis(); + long sqlCost = endTime - startTime; + + BoundSql boundSql = statementHandler.getBoundSql(); + String sql = boundSql.getSql(); + Object parameterObject = boundSql.getParameterObject(); + List parameterMappingList = boundSql.getParameterMappings(); + + // 格式化Sql语句,去除换行符,替换参数 + sql = formatSql(sql, parameterObject, parameterMappingList); + + System.out.println("SQL:[" + sql + "]执行耗时[" + sqlCost + "ms]"); + } + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties) { + + } + + @SuppressWarnings("unchecked") + private String formatSql(String sql, Object parameterObject, List parameterMappingList) { + // 输入sql字符串空判断 + if (sql == null || sql.length() == 0) { + return ""; + } + + // 美化sql + sql = beautifySql(sql); + + // 不传参数的场景,直接把Sql美化一下返回出去 + if (parameterObject == null || parameterMappingList == null || parameterMappingList.size() == 0) { + return sql; + } + + // 定义一个没有替换过占位符的sql,用于出异常时返回 + String sqlWithoutReplacePlaceholder = sql; + + try { + if (parameterMappingList != null) { + Class parameterObjectClass = parameterObject.getClass(); + + // 如果参数是StrictMap且Value类型为Collection,获取key="list"的属性,这里主要是为了处理循环时传入List这种参数的占位符替换 + // 例如select * from xxx where id in ... + if (isStrictMap(parameterObjectClass)) { + StrictMap> strictMap = (StrictMap>) parameterObject; + + if (isList(strictMap.get("list").getClass())) { + sql = handleListParameter(sql, strictMap.get("list")); + } + } else if (isMap(parameterObjectClass)) { + // 如果参数是Map则直接强转,通过map.get(key)方法获取真正的属性值 + // 这里主要是为了处理 + +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ Uploaded 0 % + + +
+
+ +
+
+
+
+ Files upload + +
+
+ +
+
+ + + +
+
+
+
+
+
+
Drag files here
+
+
+ + + + + + + + + + + + + +
+ Display NameTypeSizeModified
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/handler/attributesErrorPage.html b/src/main/resources/handler/attributesErrorPage.html new file mode 100644 index 0000000..2e33150 --- /dev/null +++ b/src/main/resources/handler/attributesErrorPage.html @@ -0,0 +1,25 @@ + + IT Hit WebDAV Server Engine + + + + +

Your file system doesn't support User Defined Attributes or they are not enabled

+

Information below will help you to find whether your file system supports User Defined Attributes:

+
    +
  • In Linux, the ext2, ext3, ext4, JFS, Squashfs, Yaffs2, ReiserFS, XFS, Btrfs, OrangeFS, Lustre, OCFS2 1.6 and F2FS + support User Defined Attributes. +

    Enabling extended attributes on Linux

    +

    Go to /etc/fstab and add "user_xattr" to the options section of the line regarding the file-system you'd like to enable extended attributes on. Such a line might look like:

    +

    /dev/sda1 / ext4 errors=remount-ro,user_xattr 0 1

    +
  • +
  • In Windows only NTFS supports User Defined Attributes
  • +
  • In FreeBSD only UFS2 supports User Defined Attributes
  • +
  • In Mac OS HFS+ supports User Defined Attributes
  • +
  • Solaris version 9 and later allows files to have "extended attributes"
  • +
+ + \ No newline at end of file diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..1df0f58 --- /dev/null +++ b/src/main/resources/i18n/messages.properties @@ -0,0 +1,5 @@ +login.tip = "¼" +login.username = "û" +login.password = "" +login.btn = "ύ" +login.remeber = "ס" \ No newline at end of file diff --git a/src/main/resources/i18n/messages_de_DE.properties b/src/main/resources/i18n/messages_de_DE.properties new file mode 100644 index 0000000..47e573b --- /dev/null +++ b/src/main/resources/i18n/messages_de_DE.properties @@ -0,0 +1,2565 @@ +admin.serverInfo=Serverinformationen +admin.today=Heute +admin.yesterday=Gestern +admin.weekDay=Fast 7 Tage +admin.monthDay=Fast 30 Tage +admin.ing=In Bearbeitung +admin.paused=Ausgesetzt +admin.serverDownload=Remote-Download +admin.memberManage=Benutzerverwaltung +admin.fileManage=Dateiverwaltung +admin.pwdEdit=Passwort ändern +admin.fileEdit=Bearbeiten Sie die gespeicherte Datei +admin.list=Listenansicht +admin.configError=Konfigurationsspeicherung fehlgeschlagen, Administrator hat diese Berechtigung deaktiviert! +admin.userManage=Persönliches Zentrum +admin.manage=Hintergrundverwaltung +admin.pluginManage=Plug-in-Verwaltung +admin.emailDear=Hallo %s, +admin.emailCodeText=Sie bestätigen gerade Ihre E-Mail-Adresse. Der Bestätigungscode für diese Anfrage lautet wie folgt. Um die Sicherheit Ihres Kontos zu gewährleisten, schließen Sie die Bestätigung bitte rechtzeitig ab. +admin.emailVerifyInTime=Um die Sicherheit Ihres Kontos zu gewährleisten, müssen Sie die Überprüfung rechtzeitig abschließen. +admin.dear=Respekt +admin.dearUser=Sehr geehrter Benutzer, +admin.emailResetLink=Sie setzen das Anmeldekennwort für %s per E-Mail zurück. Klicken Sie zum Zurücksetzen auf den folgenden Link. Wenn der Link nicht springt, kopieren Sie ihn in die Adressleiste Ihres Browsers, um darauf zuzugreifen: +admin.emailExpireTime=Der Link läuft nach 20 Minuten ab. +admin.jobName=Berufsbezeichnung +admin.jobDesc=Stellenbeschreibung +admin.jobNameInput=Bitte geben Sie einen Jobnamen ein +admin.jobEdit=Post Editor +admin.menu.home=Zuhause +admin.menu.dashboard=Übersicht +admin.menu.dashboardTitle=Statistikübersicht +admin.menu.notice=Benachrichtigungsverwaltung +admin.menu.groupMember=Abteilung und Mitgliederverwaltung +admin.menu.member=Abteilungen und Benutzer +admin.menu.role=Rollenverwaltung +admin.menu.job=Auftragsverwaltung +admin.menu.auth=Verwaltung von Dokumentenrechten +admin.menu.storage=Speicher / Datei +admin.menu.storageDriver=Speicherverwaltung +admin.menu.plugin=Plugin Center +admin.menu.tools=Sicherheitskontrolle +admin.menu.server=Serververwaltung +admin.menu.backup=Backup-Management +admin.menu.share=Sharing Management +admin.menu.loginLog=Login log +admin.menu.log=Betriebsprotokoll +admin.menu.task=Geplante Aufgaben +admin.autoTask.restart=Starten Sie geplante Aufgaben neu +admin.autoTask.restartEnd=Die geplante Aufgabe wurde neu gestartet +admin.index.userSpace=Benutzerraum +admin.index.groupSpace=Abteilungsraum +admin.index.folderCount=Anzahl der Ordner: +admin.index.fileCount=Anzahl der Dateien: +admin.index.loginToday=Melden Sie sich noch heute an +admin.index.useTotal=Gesamtverbrauch: +admin.index.userLogin=Benutzeranmeldung +admin.index.spaceUsed=Nehmen Sie Platz ein +admin.index.useSpace=Nutze den Raum +admin.index.usedSpace=Benutzter Raum +admin.index.freeSpace=verbleibender Platz +admin.index.sizeLimit=Begrenzte Größe +admin.index.vipCount=Registrierte Benutzer +admin.index.loginCurrent=Zurzeit online +admin.index.fileDel=Löschen von Dateien +admin.index.fileEdit=Dateibearbeitung +admin.index.fileUpload=Datei-Upload +admin.index.fileDown=Dokument herunterladen +admin.index.spaceUse=Praktische Anwendung +admin.index.spaceSave=Platz sparen +admin.index.spaceUser=Benutzer verwenden +admin.index.spaceGroup=Abteilung verwenden +admin.index.lastLogin=Letzte Anmeldezeit +admin.index.totalUsers=Benutzer insgesamt +admin.index.loginUsers=Login Benutzer +admin.index.spaceActUsed=Tatsächlicher Beruf +admin.index.source=Anmeldequelle +admin.index.address=Anmeldeadresse +admin.index.userInfo=Benutzerinformation +admin.index.userValid=Gültiges Konto +admin.index.userInvalid=Ungültiger Account +admin.index.fileInfo=Dateiinformationen +admin.index.fileCnt=Anzahl der Dateien +admin.index.fileAdd=Heute hinzugefügt +admin.index.accInfo=Zugangsinformation +admin.index.accCnt=Anfragen +admin.index.accUser=Zugriff auf Benutzer +admin.index.serverInfo=Systemnachricht +admin.index.serverDisk=Systemfestplatte +admin.index.serverStore=Netzwerkspeicher +admin.index.serverName=Servername +admin.index.normal=normal +admin.index.scoreDesc=Die folgenden Faktoren wirken sich auf die Systembewertung aus, die optimiert werden kann, um sicherzustellen, dass das System ordnungsgemäß funktioniert:
1. Der verbleibende Speicherplatz der Systemfestplatte und des Netzwerkfestplattenspeichers;
2. Daten-Caching-Methode (Redis wird empfohlen);
3.php Plattformversion (empfohlenes 64-Bit PHP7 +). +admin.index.fileRatio=Dateiverwendungsgrad +admin.setting.system=Systemeinstellungen +admin.setting.account=Kontoeinstellungen +admin.setting.theme=Theme-Einstellungen +admin.setting.wall=Hintergrundeinstellungen +admin.setting.stats=Nutzungsstatistiken +admin.setting.safeMgt=Sicherheitsmanagement +admin.setting.base=Grundeinstellungen +admin.setting.others=Andere Einstellungen +admin.setting.sync=Synchronisieren Sie die Einstellungen +admin.setting.plugin=Plug-in-Einstellungen +admin.setting.auth=Berechtigungseinstellung +admin.setting.safe=Sicherheitseinstellungen +admin.setting.loginLog=Login Log +admin.setting.loginDevice=Anmeldegerät +admin.setting.deviceType=Ausstattungsart +admin.setting.lastLoginTime=Letzte Anmeldezeit +admin.setting.email=E-Mail-Einstellungen +admin.setting.user=Registrierung und Login +admin.setting.pwdOld=Ursprüngliches Passwort +admin.setting.pwdNew=Ändern Sie zu +admin.setting.wallDiy=Benutzerdefiniertes Hintergrundbild: +admin.setting.fav=Favoritenverwaltung +admin.setting.help=Benutze die Hilfe +admin.setting.about=Über Werke +admin.setting.homePage=Kodcloud nach Hause +admin.setting.subMenu=Untermenü +admin.setting.menuName=Menüname +admin.setting.menuUrl=URL-Adresse +admin.setting.menuUrlDesc=URL-Adresse oder JS-Code +admin.setting.safeAccount=Konto- und Anmeldesicherheit +admin.setting.safeData=Datensicherheit / Übertragungssicherheit +admin.setting.passwordErrorLock=Fehlersperre für Passworteingabe +admin.setting.passwordErrorLockDesc= +admin.setting.passwordRule=Einstellung der Benutzerkennwortstärke +admin.setting.passwordRuleDesc=Nachdem die Kennwortstärke angegeben wurde, kann das schwache Kennwort effektiv beseitigt werden +admin.setting.passwordRuleNone=Unbegrenzt +admin.setting.passwordRuleStrong=Mittlere Intensität +admin.setting.passwordRuleStrongMore=Hohe Festigkeit +admin.setting.passwordRuleNoneDesc=Unbegrenzte Passwortstärke +admin.setting.passwordRuleStrongDesc=Die Länge ist größer als 6 und muss sowohl Englisch als auch Zahlen enthalten. +admin.setting.passwordRuleStrongMoreDesc=Länge ist größer als 6; muss Zahlen enthalten, Englisch in Großbuchstaben, Englisch in Kleinbuchstaben; +admin.setting.passwordRuleTips=Ihr aktuelles Passwort ist nicht stark genug, es wird empfohlen, das Passwort sofort zu ändern! +admin.loginCheck.menu=Login-Kontrolle +admin.loginCheck.ipCheck=IP-Einschränkungen +admin.loginCheck.ipCheckNone=nicht limitiert +admin.loginCheck.ipCheckAllow=IP-Whitelist +admin.loginCheck.ipCheckDisable=IP Blacklist +admin.loginCheck.loginIpAllowDesc=Nach dem Öffnen können sich nur Benutzer mit der angegebenen IP anmelden. Seien Sie bitte vorsichtig +admin.loginCheck.ipAllow=Zulässige IP +admin.loginCheck.ipAllowDesc=Füllen Sie die Regeln wie folgt aus (in jeder Zeile ist die lokale IP des Servers standardmäßig zulässig, und der Systemadministrator lässt die LAN-IP zu.) +admin.loginCheck.ipDisable=Blacklist IP-Regeln +admin.loginCheck.ipDisableDesc= +admin.loginCheck.ipDescTitle=Füllen Sie die Regeln wie folgt aus (eine Zeile pro Eintrag) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=Priorität +admin.loginCheck.name=Regelname +admin.loginCheck.user=Designierter Benutzer +admin.loginCheck.device=Ausgewiesene Ausrüstung +admin.loginCheck.deviceWeb=Netz +admin.loginCheck.devicePc=PC-Seite +admin.loginCheck.deviceAndroid=Android +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc= +admin.setting.checkCode=Anmeldebestätigungscode ist aktiviert +admin.setting.checkCodeDesc=Nach dem Login müssen Sie den Bestätigungscode eingeben. +admin.setting.csrfProtect=Aktivieren Sie den CSRF-Schutz +admin.setting.csrfProtectDesc=Kann bei Aktivierung csrf-Angriffe effektiv verhindern +admin.setting.setRootPath=Root-Zugriff +admin.setting.setRootPathDesc= +admin.setting.encode=Dateispeicherverschlüsselung +admin.setting.encodeAll=Alle verschlüsseln +admin.setting.encodeName=Behalten Sie die Erweiterung +admin.setting.encodeNone=Keine Verschlüsselung +admin.setting.encodeAllDesc=Vollständige Verschlüsselung: [Standardempfehlung]: Selbst wenn Sie über Serverberechtigungen verfügen, können Sie den wahren Inhalt der Datei nicht kennen. Sie kann effektiv vor Ransomware und anderen Schäden schützen. +admin.setting.encodeNameDesc=Erweiterung beibehalten : Dateinamenverschlüsselung, Erweiterung beibehalten +admin.setting.encodeNullDesc=Keine Verschlüsselung: Der Dateiname wird nicht verschlüsselt und der ursprüngliche Dateiname wird beibehalten. (Um die Sicherheit zu gewährleisten, wird der Upload-Ordner als verschlüsselte Struktur bezeichnet.) +admin.setting.encodeTips1=Nur die Dateien nach der Einstellungsänderung sind betroffen, die zuvor vorhandenen Dateien sind nicht betroffen. +admin.setting.encodeTips2=Um Fehler zu vermeiden, löschen oder benennen Sie keine Dateien in Daten / Dateien um. +admin.setting.encodeTips3=Zur Unterstützung von Parallelität, zweiter Übertragung, Clustering, Verteilung, automatischer Erweiterung und anderen Funktionen in großem Maßstab wird die Ordnerhierarchie in der Datenbank aufgezeichnet und die Ordnerstruktur kann durch Kopieren und Einfügen importiert und wiederhergestellt werden +admin.setting.thirdLogin=Drittanbieter-Login +admin.setting.thirdLoginDesc=Registrierung, Bindung und Anmeldung über Konten von Drittanbietern zulassen +admin.setting.registOpen=Benutzerregistrierung öffnen +admin.setting.registOpenDesc=Um Datenkonflikte zu vermeiden, können die Datensynchronisierung und die Benutzerregistrierung von Drittanbietern nicht gleichzeitig aktiviert werden +admin.setting.registCheck=Überprüfung der Registrierung öffnen +admin.setting.registCheckDesc=Nach dem Öffnen muss der Administrator die Einstellungen in [Benutzer und Abteilungen] überprüfen und aktivieren, damit registrierte Benutzer sie normal verwenden können +admin.setting.clearUserRecycle=Leeren Sie alle Benutzerpapierkörbe +admin.setting.clearCache=Cache leeren +admin.setting.icp=Urheber- oder Eintragsnummer +admin.setting.icpDesc=Wenn Sie einen Link erstellen müssen, können Sie selbst einen Tag hinzufügen +admin.setting.globalCss=Benutzerdefinierte globale CSS +admin.setting.globalCssDesc=Auf allen Seiten wird ein benutzerdefiniertes CSS eingefügt +admin.setting.globalHtml=Statistischer Code HTML +admin.setting.globalHtmlDesc=Auf allen Seiten wird dieser HTML-Code eingefügt, und Drittanbieter-Statistik-Code kann platziert werden +admin.setting.dateFormat=Datumsformat +admin.setting.dateFormatDesc=Jahr-Monat-Tag-Zeitformatanzeige, Dateiänderungszeit usw. +admin.setting.menu=Menüverwaltung +admin.setting.systemName=Firmenproduktname +admin.setting.systemNameDesc=Für den Titel des Produktlogos +admin.setting.systemDesc=Produkt-Untertitel +admin.setting.pathHidden=Verzeichnisausschluss +admin.setting.pathHiddenDesc=Verzeichnisse und Dateien werden nicht standardmäßig durch Kommas getrennt angezeigt +admin.setting.defaultFolder=Neue Benutzer erstellen standardmäßig Verzeichnisse +admin.setting.defaultFolderDesc=Durch Kommas getrennt +admin.setting.defaultApp=Neue Benutzer erstellen standardmäßig Apps +admin.setting.defaultAppDesc=Application Center-Anwendungen, mehrere durch Kommas getrennte +admin.setting.autoLogin=Automatisches Login +admin.setting.autoLoginDesc=Der Standardanmeldebenutzer ist der guest/guest Gastbenutzer. Stellen Sie sicher, dass dieser Benutzer nach dem Öffnen vorhanden ist +admin.setting.firstIn=Nach dem Login standardmäßig eingeben +admin.setting.registReviewOpen=Offenes Registrierungsaudit: +admin.setting.registRoleEmpty=Die Berechtigungsrolle darf nicht leer sein +admin.setting.registNotSync=Um Datenkonflikte zu vermeiden, können die Datensynchronisierung und die Benutzerregistrierung von Drittanbietern nicht gleichzeitig aktiviert werden +admin.setting.registNeedRewiew=Nachdem es geöffnet wurde, muss der Administrator es überprüfen und in den Benutzern und Abteilungen aktivieren, bevor registrierte Benutzer es normal verwenden können. +admin.setting.roleRight=Rollenberechtigungen +admin.setting.emailHost=Postfachserver +admin.setting.emailHostInput=Bitte geben Sie die Adresse des Mailservers ein +admin.setting.emailHostTips=Bitte geben Sie die Adresse des Mailservers ein +admin.setting.emailHostDesc=Postfachserver, z. B.: smtp.163.com, der Port kann angepasst werden (Standard ist 465) +admin.setting.emailSend=Postausgang +admin.setting.emailSendInput=Bitte geben Sie die E-Mail-Adresse ein +admin.setting.emailSendTips=Bitte geben Sie die E-Mail-Adresse ein +admin.setting.emailSendDesc=System-E-Mail-Adresse, POP3 / SMTP-Dienst muss aktiviert sein +admin.setting.emailPwd=Autorisierungspasswort +admin.setting.emailPwdTips=Bitte geben Sie das Passwort für die E-Mail-Autorisierung ein +admin.setting.secureType=Verschlüsselung +admin.setting.emailSendTest=Erkennung senden +admin.setting.ensureEmailOk=Bitte stellen Sie sicher, dass die Mail normal versendet werden kann +admin.setting.emailTo=Posteingang +admin.setting.emailGoToTips=Bitte gehen Sie zum Briefkasten +admin.setting.emailCheckTips=Ansehen +admin.setting.emailInputError=Falsche E-Mail-Einstellungen +admin.setting.emailPwdError=Das Kennwort für die E-Mail-Einstellung ist falsch +admin.setting.emailDesc=Richten Sie einen Mail-Server für die Benutzerregistrierung und das Senden von E-Mails zur Kennwortwiederherstellung ein +admin.setting.sendEmail=Mail senden +admin.setting.sendEmailDesc=Systemstandard: Aufruf zum Senden des Cloud-Mail-Servers; Benutzerdefiniert: Konfigurieren des Mail-Servers +admin.setting.systemBackup=Systemsicherung +admin.setting.enableFunction=Funktionen und Schalter +admin.setting.treeOpen=Funktionsschalter des Baumverzeichnisses +admin.setting.treeOpenDesc=Dateiverwaltung, Baumverzeichnis entsprechende Funktion global aktiviert und deaktiviert +admin.setting.groupListChild=Teilsektoren auflisten +admin.setting.groupListChildDesc=Unabhängig davon, ob im Abteilungsordner Unterabteilungen angezeigt werden, werden Berechtigungen nach oben vererbt +admin.setting.groupRootListChild=Enterprise Web Disk listet Teilsektoren auf +admin.setting.groupRootListChildDesc=Ob im Netzwerkordner des Unternehmens Unterabteilungen angezeigt werden und Berechtigungen nach oben vererbt werden +admin.setting.shareToMeAllowTree=Mit mir zusammenarbeiten-show nach Organisationsstruktur +admin.setting.shareToMeAllowTreeTips=Nach dem Öffnen wird die inhaltliche Unterstützung für die Zusammenarbeit mit mir nach der Organisationsstruktur der Abteilung geordnet, die für Situationen mit komplexeren Organisationsstrukturen geeignet ist +admin.setting.groupTagAllow=Öffentliches Label der Abteilung +admin.setting.groupTagAllowTips= +admin.setting.shareToMeList=Gekacheltes Display +admin.setting.shareToMeGroup=Nach Organisationsstruktur anzeigen +admin.setting.shareToMeUser=Von Teilen anzeigen +admin.setting.sysSrvState=Server Status +admin.setting.sysSrvInfo=Serverinformation +admin.setting.sysPhpInfo=PHP-Informationen +admin.setting.database=Datenbank +admin.setting.cache=Zwischenspeicher +admin.setting.sysMyInfo=meine Information +admin.setting.srvStateCpu=CPU auslastung +admin.setting.srvStateMem=Speichernutzung +admin.setting.srvStateSrv=Speicherplatz des Serversystems +admin.setting.srvStateDef=Der Standardspeicherplatz der Netzwerkfestplatte +admin.setting.srvInfoName=Servername +admin.setting.srvInfoIp=Server IP +admin.setting.srvInfoTime=Serverzeit +admin.setting.srvInfoUpTime=Kontinuierliche Laufzeit +admin.setting.srvInfoWeb=Serversoftware +admin.setting.srvInfoPhpV=PHP-Version +admin.setting.srvInfoSys=Serversystem +admin.setting.srvInfoPath=Site-Pfad +admin.setting.srvPhpDtl=PHP Details +admin.setting.memLimit=Speicherlimit +admin.setting.postLimit=POST-Einreichungslimit +admin.setting.uploadLimit=Einschränkungen beim Hochladen von Dateien +admin.setting.execTime=Maximale Ausführungszeit +admin.setting.inputTime=Maximale Anforderungszeit +admin.setting.disFunction=Funktion deaktivieren +admin.setting.phpExtSugst=Empfohlene PHP-Erweiterungen +admin.setting.phpExtLoad=Geladene Erweiterung +admin.setting.myClientIp=Meine IP +admin.setting.myClientUa=Mein Browser UA +admin.setting.myClientLng=Meine Browsersprache +admin.setting.disFuncDesc=Für vom System benötigte Funktionen wird empfohlen, diese zu aktivieren +admin.setting.srvMemFree=Verbleibende Erinnerung +admin.setting.srvMemUse=Verwenden Sie Speicher +admin.setting.srvCpuUse=Derzeit besetzt +admin.setting.srvCpuFree=Ungebraucht +admin.setting.noLimit=Unbegrenzt +admin.setting.disFunNo=Nein +admin.setting.systemCache=Systemcache +admin.setting.systemDb=Systemdatenbank +admin.setting.sysCacheTab=Cache-Schalter +admin.setting.sysDbTab=Datenbankwechsel +admin.setting.sysRecTab=Datenbankwiederherstellung +admin.setting.cacheDesc=Cache-Beschreibung +admin.setting.fileCacheDesc= +admin.setting.redisDesc= +admin.setting.memcachedDesc=Memcached: Ein leistungsstarkes Cache-System für verteilte Speicherobjekte, das für hohe gleichzeitige Lesevorgänge geeignet ist. +admin.setting.saveAfterTest=Nachdem der Test bestanden wurde, kann er gespeichert werden +admin.setting.checkPassed=Bestanden +admin.setting.ifSaveCache=Nach dem Umschalten werden alle zwischengespeicherten Daten gelöscht!
Sind Sie sicher, dass Sie ausführen möchten? +admin.setting.ifSaveDb=Der Datenbankswitch importiert die aktuellen Daten des Systems in die neue Datenbank und setzt diese als Standard. Sind Sie sicher, dass Sie es ausführen möchten? +admin.setting.dbCurrent=Aktuelle Konfiguration +admin.setting.dbType=Datenbanktyp +admin.setting.dbName=Namensdatenbank +admin.setting.dbInfo=Datenbankinformationen +admin.setting.dbSwitch=Einschalten +admin.setting.dbSwitchDesc=Nach dem Öffnen können Sie den Datenbanktyp nach Bedarf ändern. Gehen Sie vorsichtig vor. +admin.setting.dbTable=Datenblatt +admin.setting.dbCnt=gesamt +admin.setting.dbNeedNew=Die Datenbank ist bereits vorhanden, bitte erneut angeben +admin.setting.dbInsertError=Tabellendaten konnten nicht geschrieben werden +admin.setting.dbNeedOthers=Bitte wählen Sie einen anderen Datenbanktyp +admin.setting.dbNeedChange=Bitte ändern Sie die Konfigurationsparameter +admin.setting.dbCreateError=Die Erstellung der Datenbankdatei ist fehlgeschlagen. Überprüfen Sie die Lese- und Schreibberechtigungen für das Verzeichnis +admin.setting.dbTaskProcess=Ausführungsfortschritt +admin.setting.dbTasking=Hinrichtung +admin.setting.dbTaskDesc=Schließen Sie das Fenster nicht und führen Sie keine anderen Operationen im System durch, um die Erzeugung von Diskrepanzdaten zu vermeiden. +admin.setting.recTaskDesc=Schließen Sie das Fenster nicht. Nachdem die Anfrage unterbrochen wurde, wird der Hintergrund weiter ausgeführt, bis die Aufgabe beendet ist. +admin.setting.dbCreate=Neue Datenbank +admin.setting.dbSelect=Datenbank lesen +admin.setting.dbInsert=Schreiben Sie in die Datenbank +admin.setting.dbSetSave=Konfigurationsinformationen speichern +admin.setting.recDesc=Gebrauchsanweisung +admin.setting.recDescInfo11=Durch diesen Vorgang werden die Systemdaten zurückgesetzt, bei Nicht-Bedienung und Wartung oder entsprechendem technischen Personal sollte es nicht funktionieren! +admin.setting.recDescInfo21=Durch Schreiben der Sicherungsdatenbank in die neue Datenbank und Festlegen als Systemstandard wird die Datenwiederherstellung erreicht. +admin.setting.recDescInfo22= +admin.setting.recDescInfo23= +admin.setting.recDescInfo31= +admin.setting.recDescInfo32= +admin.setting.recDescInfo33=Berechtigungen einstellen: +admin.setting.recDescInfo34=Berechtigungen widerrufen: +admin.setting.recOpen=Wiederherstellung aktivieren +admin.setting.recOpenDesc=Nach dem Einschalten können Sie die gesicherte Datenbank nach Bedarf auswählen, um sie wiederherzustellen. Bitte gehen Sie mit Vorsicht vor. +admin.setting.recTypeDesc=Abhängig von der Art des derzeit verwendeten Systems +admin.setting.recPath=Datenbanksicherungsverzeichnis +admin.setting.recPathErr=Ungültiges Datenbanksicherungsverzeichnis +admin.setting.ifSaveRec=Bei der Datenbankwiederherstellung werden die Sicherungsdaten in die neue Datenbank importiert und als Standard festgelegt.
Möchten Sie es wirklich ausführen? +admin.setting.recDiyPathErr=Wenn Sie die Selbstsicherung zur Wiederherstellung verwenden, wählen Sie bitte die zu sichernde Datenbankdatei aus +admin.setting.recDiyFileNull=Die Datenbankdatei ist leer +admin.setting.recDiyPhpErr=Damit die SQLite selbst gesichert werden soll, wählen Sie bitte die als php . formatierte Datenbankdatei aus +admin.setting.recDiySqlErr=Damit das MySQL selbst gesichert werden soll, wählen Sie bitte die als sql . formatierte Datenbankdatei aus +admin.setting.recSysPathErr=Wenn Sie die Backup-Verwaltung für die Wiederherstellung verwenden, wählen Sie bitte das Backup-Datenbankverzeichnis aus +admin.setting.recSysTbErr=Das Datenbanksicherungsverzeichnis ist ungültig oder die Datenbankstrukturdatei fehlt +admin.setting.recDbFileErr=Die ausgewählte Bibliotheksdatei stimmt nicht mit dem System überein oder eine gültige Datentabelle fehlt +admin.setting.dbFileDown=Bibliotheksdatei lesen +admin.setting.dbFileDownErr=Bibliotheksdatei konnte nicht gelesen werden +admin.notice.waiting=Warten auf Push +admin.notice.done=Geschoben +admin.notice.time=Zeit drücken +admin.notice.target=Objekt schieben +admin.notice.level=Prompt Level +admin.notice.level0=Schwacher Hinweis +admin.notice.level1=Starke Aufforderung +admin.notice.levelDesc=Schwache Erinnerung: In der Benachrichtigungsleiste in der unteren linken Ecke wird ein roter Punkt angezeigt. Starke Erinnerung: Eine Benachrichtigung wird direkt nach der Anmeldung des Benutzers angezeigt. +admin.notice.targetAuth=Wählen Sie, ob Sie an alle Benutzer oder an bestimmte Benutzer, Benutzergruppen und Berechtigungsgruppen senden möchten +admin.notice.title=Nachrichtentitel +admin.notice.content=Nachrichteninhalt +admin.notice.timeType=Push-Methode +admin.notice.timeNow=Sofort drücken +admin.notice.timePlan=Geplanter Push +admin.notice.listTitle=Benachrichtigung über Stationsnachrichten +admin.notice.clearAll=Leere alles +admin.notice.noMsg=Keine Neuigkeiten +admin.notice.ifClearAll=Möchten Sie wirklich alle Nachrichten löschen? +admin.group.role=Rollenidentität +admin.group.name=Abteilungsname +admin.group.parent=Übergeordnete Abteilung +admin.group.authShow=Der für die Mitglieder der Abteilung sichtbare Umfang der Organisationsstruktur +admin.group.authShowAll=Alle Abteilungen +admin.group.authShowHide=Nur diese Abteilung und Unterabteilung +admin.group.authShowSelect=Vorgesehene Abteilung +admin.group.authShowAllTips=Wenn Mitglieder dieser Abteilung zum Teilen zusammenarbeiten, können sie alle anderen Abteilungen (und Benutzer) auswählen. +admin.group.authShowHideTips=Wenn Mitglieder dieser Abteilung zusammenarbeiten und Inhalte teilen, werden nur die aktuelle Abteilung und Unterabteilung (und Benutzer) unterstützt +admin.group.authShowSelectTips= +admin.group.addSub=Teilsektor hinzufügen +admin.group.remove=Abteilung löschen +admin.group.switch=Migrationsabteilung +admin.group.swtichDesc=Migrieren Sie Benutzer und Dateien unter der ausgewählten Abteilung (und ihren Unterabteilungen) in die Zielabteilung. +admin.group.switchSameError=Die Zielabteilung darf nicht mit der ausgewählten Abteilung identisch sein +admin.group.switching=Migrieren, bitte warten... +admin.group.groupSwitching=Die ausgewählte Abteilung wird migriert +admin.group.parentNullError=Die übergeordnete Abteilung darf nicht leer sein +admin.group.selected=Ausgewählte Abteilung +admin.group.setSizeBatch=Stellen Sie die Speicherplatzgröße in Stapeln ein +admin.group.multiSelect=Für die Chargeneinstellung können mehrere Abteilungen ausgewählt werden +admin.group.ifDisAll=Alle Unterabteilungen werden deaktiviert. Möchten Sie sie wirklich ausführen? +admin.member.manage=Benutzer und Abteilungen +admin.member.add=Neuer Benutzer +admin.member.role=Berechtigungsrolle +admin.member.group=Abteilung +admin.member.groupAdd=Abteilung hinzufügen +admin.member.groupEdit=Redaktion +admin.member.remove=Benutzer löschen +admin.member.import=Fügen Sie in der Masse hinzu +admin.member.enable=Aktivieren +admin.member.batchSet=Massenoperationen +admin.member.groupRemove=Aus der Abteilung entfernen +admin.member.groupInsert=Zur Abteilung hinzufügen +admin.member.groupSwitch=Zur Abteilung migrieren +admin.member.groupTarget=Ziel Abteilung +admin.member.groupReset=Abteilung zurücksetzen +admin.member.groupSwtichDesc=Migrieren Sie ausgewählte Benutzer aus der aktuellen Abteilung in die Zielabteilung +admin.member.roleSet=Berechtigungsrolleneinstellungen +admin.member.sizeSet=Raumgrößeneinstellung +admin.member.name=Login-Konto +admin.member.nickName=Benutzername +admin.member.userInfo=Benutzerinfo +admin.member.userImport=Benutzer in großen Mengen importieren +admin.member.uploadFirst=Bitte laden Sie zuerst die Datei hoch +admin.member.downTpl=Vorlage herunterladen +admin.member.downTplDesc=Bitte füllen Sie das Vorlagenformat aus und laden Sie es hoch. +admin.member.uploadInvalid=Die hochgeladene Datei enthält keine gültigen Daten. Bitte überprüfen Sie sie und laden Sie sie erneut hoch +admin.member.uploadDataInvalid=Upload-Daten sind ungültig oder abgelaufen. Bitte laden Sie sie erneut hoch +admin.member.importSuccess=Import abgeschlossen +admin.member.importFail=Import fehlgeschlagen +admin.member.importFailDesc=Erfolg: {0}; Fehler: {1} +admin.member.importName=Anmeldekonto (erforderlich, einmalig) +admin.member.importNickName=Spitzname (einzigartig) +admin.member.importPwd=Passwort erforderlich) +admin.member.importSex=Geschlecht (männlich-1, weiblich-0) +admin.member.importPhone=Mobilnummer (einmalig) +admin.member.importEmail=E-Mail (nur) +admin.member.groupRemoveTips=Benutzer dieser Benutzergruppe können sich nach dem Löschen nicht anmelden
(Müssen Sie die Benutzergruppe zurücksetzen) Sind Sie sicher, dass Sie fortfahren möchten? +admin.member.memberRemoveTips=Nach dem Löschen wird das Benutzerverzeichnis in den Papierkorb des Systems verschoben,
Sind Sie sicher, dass Sie fortfahren möchten? +admin.member.selectUserTips=Bitte wählen Sie das zu betreibende Konto aus +admin.member.ifRemoveGroup=Möchten Sie die ausgewählten Benutzer wirklich aus dieser Gruppe entfernen? +admin.member.importDesc=Ein Benutzer pro Zeile,
Automatisch ignorieren, wenn es bereits vorhanden ist +admin.member.roleAdminTips=Hinweis: Der Systemadministrator wird nicht durch Berechtigungen gesteuert +admin.member.space=Legen Sie die Größe des Benutzerraums fest +admin.member.spaceTips=0 ist nicht eingeschränkt +admin.member.spaceTipsDefault=(GB) 0 ist nicht begrenzt +admin.member.spaceTipsFull=Nicht eingeschränkt +admin.member.spaceSize=Raumgröße +admin.member.spaceSizeUse=Raumnutzung +admin.member.memberAdd=Benutzer hinzufügen +admin.member.allAdd=Benutzer oder Abteilung hinzufügen +admin.member.nullNotUpdate=Leer lassen +admin.member.search=Benutzer suchen (Konto / Spitzname / E-Mail / Telefon) +admin.member.searchUser=Benutzer suchen (unterstützt Pinyin und Fuzzy Matching) +admin.member.searchGroup=Suchabteilung (unterstützt Pinyin und Fuzzy Matching) +admin.member.searchAll=Suche nach Benutzern oder Abteilungen (unterstützt Pinyin und Fuzzy Matching) +admin.member.editNoAuth=Entschuldigung, Sie haben diese Erlaubnis nicht,
Nur Systemadministratoren können Systemadministratoren hinzufügen und ändern +admin.member.disabledUsers=Konto deaktiviert +admin.member.disabledTips=Wechseln Sie die Abteilung zum Deaktivieren +admin.member.userGroup=Benutzerabteilung +admin.member.userRole=Benutzer-Rolle +admin.member.userSelected=Ausgewählte Benutzer +admin.member.authCopy=Abteilungsberechtigungen kopieren +admin.member.authPaste=Abteilungserlaubnis einfügen +admin.member.ifAuthPaste=Möchten Sie die kopierten Abteilungsberechtigungen wirklich auf den aktuellen Benutzer festlegen? +ERROR_USER_NOT_EXISTS=Benutzer existiert nicht +ERROR_USER_PASSWORD_ERROR=Falsches Passwort +ERROR_USER_EXIST_NAME=Benutzername existiert bereits +ERROR_USER_EXIST_PHONE=Telefonnummer existiert bereits +ERROR_USER_EXIST_EMAIL=Das Postfach ist bereits vorhanden +ERROR_USER_EXIST_NICKNAME=Nutzername vergeben +ERROR_USER_LOGIN_LOCK=Entschuldigung, es gibt zu viele Passwortversuche und das aktuelle Konto ist gesperrt. Bitte versuchen Sie es in 1 Minute erneut! +ERROR_IP_NOT_ALLOW=Ihre aktuelle IP oder Ihr Zugangsgerät darf sich nicht anmelden, bitte wenden Sie sich an den Administrator! +user.passwordCheckError=Das Passwortformat entspricht nicht den Regeln für die Passwortstärke! +admin.role.administrator=Systemadministrator +admin.role.group=Abteilungsadministrator +admin.role.default=allgemeiner Benutzer +admin.role.ignoreExt=Erweiterungsbeschränkungen +admin.role.ignoreExtDesc=Dateitypen, die nicht hochgeladen werden dürfen, unterliegen keinen Einschränkungen für das Leeren +admin.role.ignoreFileSize=Dateigrößenbeschränkung hochladen +admin.role.ignoreFileSizeDesc=Maximaler Upload einzelner Dateien, 0 ist unbegrenzt +admin.role.ignoreExtTips=Leider unterstützen die aktuellen Systemeinstellungen diese Art des Hochladens von Dateien nicht. Bitte wenden Sie sich an den Administrator, um weitere Informationen zu erhalten. +admin.role.ignoreFileSizeTips=Wenn die Datei die Größenbeschränkung überschreitet, wenden Sie sich bitte an den Administrator, um weitere Informationen zu erhalten. +admin.role.desc=Rollenbeschreibung +admin.role.adminDesc=Superadministrator, hat Serververwaltungsrechte; alle Datei- und Ordnereinstellungen sind für diesen Benutzer ungültig! +admin.role.read=Lesen +admin.role.readList=Dateiliste +admin.role.readInfo=Datei- (Ordner-) Attributansicht, Ordnersuche +admin.role.readCopy=Datei kopieren +admin.role.readPreview=Dateivorschau (Bilder, Dokumente, Audio und Video usw.) +admin.role.readDownload=Datei (Ordner) herunterladen +admin.role.write=Schreiben +admin.role.writeAdd=Erstellen Sie Dateien (Ordner), komprimieren und dekomprimieren Sie Dateien +admin.role.writeChange=Umbenennen, Verzeichnisstruktur anpassen +admin.role.writeUpload=Datei (Ordner) hochladen, Remote-Download +admin.role.writeRemove=Datei (Ordner) löschen, ausschneiden +admin.role.adminSetDesc=Der Systemadministrator hat alle Berechtigungen, die er nicht einstellen muss! +admin.role.displayDesc=Gibt an, ob beim Festlegen von Benutzerrollen angezeigt werden soll +admin.role.defaultRoleDesc=Tipp: Das System verfügt standardmäßig über integrierte Rollen und unterstützt das Ändern von Berechtigungen nicht. Sie können neue Rollen erstellen +admin.role.actionSetTitle=Dokumentation und Konfiguration +admin.role.userSetTitle=Benutzerkonfigurationsdaten +admin.role.adminSetTitle=Hintergrundfunktionen +admin.role.fileAdd=Neue Datei (Ordner) +admin.role.fileRemove=Dokument löschen +admin.role.fileMove=Verschieben (Kopieren / Ausschneiden / Einfügen / Ziehen) +admin.role.userConfig=Konfigurationsänderung (Avatar einstellen / Passwort ändern, etc.) +admin.role.userEdit=Benutzer bearbeiten (hinzufügen / ändern / löschen) +admin.role.userFav=Favoritenbedienung +admin.role.itemEdit=Hinzufügen / Ändern / Löschen +admin.role.groupEdit=Abteilung bearbeiten (hinzufügen / ändern / löschen) +admin.role.delErrTips=Das Zeichen wird verwendet und kann nicht gelöscht werden! +admin.authFrom.setUser=Geben Sie Ihre eigenen Berechtigungen an +admin.authFrom.setGroup=Abteilungsautorität angeben +admin.authFrom.setAll=Andere Benutzerberechtigungen +admin.authFrom.groupAt=Abteilungsbehörde +admin.authFrom.groupParent=Oberbehörde +admin.authFrom.pathOnly=Nur Zugriff, die untere Ebene hat Inhalt und Berechtigung +admin.authFrom.groupRoot=Stammverzeichnis der Abteilung +admin.auth.owner=Besitzer +admin.auth.editor=Herausgeber +admin.auth.editUploader=Bearbeiten / Uploader +admin.auth.viewer=Viewer +admin.auth.previewer=Vorschau +admin.auth.uploader=Uploader +admin.auth.invisible=Unsichtbar +admin.auth.user=Benutzerdaten +admin.auth.pathDelete=Datei löschen +admin.auth.pathInfo=Dateiattribute +admin.auth.pathMove=Verschieben (Kopieren / Ausschneiden / Einfügen / Ziehen) +admin.auth.canUpload=Upload herunterladen +admin.auth.config=Konfigurationsdaten +admin.auth.fav=Favoritenbedienung (Hinzufügen / Bearbeiten / Löschen) +admin.auth.extWarning=Das Hochladen solcher Dateien ist nicht gestattet.
Umbenennen (umbenannt in die angegebene Erweiterung),
Bearbeiten, speichern, herunterladen, dekomprimieren +admin.auth.error=Berechtigungsrollenfehler (keine Berechtigungseinstellungen) +admin.auth.errorAdmin=Unzureichende Autorität +admin.auth.targetError=Berechtigungsobjekttyp ist falsch, muss Benutzer oder Abteilung sein +admin.auth.errorAuthToGroup=Nicht-Root-Abteilung, unterstützt keine Delegierung an Abteilungen +admin.auth.errorAuthToUsers=Nicht-Root-Sektor unterstützt keine Delegation an Mitglieder außerhalb des Sektors +admin.auth.displayDesc=Gibt an, ob beim Festlegen von Abteilungsbenutzerberechtigungen angezeigt werden soll +admin.auth.defaultAuthDesc=Tipp: Das System verfügt standardmäßig über eine integrierte Berechtigungsgruppe und unterstützt das Ändern von Berechtigungen nicht. Sie können neue Berechtigungsgruppen erstellen +admin.auth.show=Dateiliste +admin.auth.showAction=Dateilistenansicht +admin.auth.view=Dateivorschau +admin.auth.viewAction=Datei öffnen Vorschau +admin.auth.download=Herunterladen / kopieren +admin.auth.downloadAction=Download / Kopie / Dateivorschau drucken +admin.auth.uploadAction=Datei (Ordner) Upload / Remote-Download +admin.auth.edit=Neu bearbeiten +admin.auth.editAction=Neue Datei (Ordner) / Umbenennen / In Ordner einfügen / Datei bearbeiten / Notizen setzen / Erstellen Kopieren / Entpacken, Komprimieren +admin.auth.removeAction=Ausschneiden / Kopieren / Verschieben +admin.auth.shareAction=Weitergabe der externen Kette / Weitergabe der Zusammenarbeit an andere +admin.auth.comment=Dokumentkommentare +admin.auth.commentAction=Dokumentkommentare anzeigen, eigene Kommentare hinzufügen / löschen (Bearbeitungsberechtigung erforderlich) +admin.auth.event=Dokumentendynamik +admin.auth.eventAction=Dynamische Anzeige von Dokumenten, dynamische Abonnements +admin.auth.root=Administratorrechte +admin.auth.rootAction=Festlegen der Mitgliedsberechtigungen / Kommentarmanagement / Versionsverwaltung des Verlaufs +admin.auth.delErrTips=Diese Berechtigung wird verwendet und kann nicht gelöscht werden! +admin.plugin.center=Plugin Center +admin.plugin.installed=Installiert +admin.plugin.type=Kategorie +admin.plugin.typeFile=Dateierweiterung +admin.plugin.typeSafe=Sicherheits-Tools +admin.plugin.typeTools=Dienstprogramm +admin.plugin.typeMedia=Multimedia +admin.plugin.typeCompany=Unternehmensanwendung +admin.plugin.typeOem=Exklusive Anpassung +admin.plugin.needNetwork=Extranet +admin.plugin.install=Installieren Sie das Plugin +admin.plugin.enable=Plugin aktivieren +admin.plugin.remove=Plugin deinstallieren +admin.plugin.config=Plugin konfigurieren +admin.plugin.statusEnabled=Aktiviert +admin.plugin.statusDisabled=Nicht aktiviert +admin.plugin.statusNotInstall=Nicht installiert +admin.plugin.installing=Wird installiert ... +admin.plugin.hasUpdate=Update +admin.plugin.updateStart=Plugin aktualisieren +admin.plugin.needConfig=Erfordert zur Aktivierung die Erstkonfiguration +admin.plugin.notNull=Pflichtfelder dürfen nicht leer sein! +admin.plugin.auther=Autor +admin.plugin.downloadNumber=Installiert +admin.plugin.back=Zurück zu +admin.plugin.detail=Beschreibung +admin.plugin.resetConfig=Standardeinstellungen wiederherstellen +admin.plugin.installSelf=Manuelle Installation +admin.plugin.updateSelf=Manuelles Update +admin.plugin.updateAll=Aktualisiere alle +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=Netzwerkfehler. Überprüfen Sie, ob der Server auf das Internet zugreifen kann. +admin.plugin.auth=Nutzungsrechte +admin.plugin.authDesc=Stellen Sie alle Benutzer zur Verfügung, oder geben Sie die zu verwendenden Benutzer, Benutzergruppen und Berechtigungsgruppen an +admin.plugin.authOpen=Freier Zugang +admin.plugin.authOpenDesc=Kann ohne Anmeldung zugegriffen werden, kann für externe Schnittstellenaufrufe verwendet werden +admin.plugin.authAll=Jeder +admin.plugin.authUser=Angegebener Benutzer +admin.plugin.authGroup=Designierte Abteilung +admin.plugin.authRole=Geben Sie die Berechtigungsgruppe an +admin.plugin.openWith=Offener Stil +admin.plugin.openWithDilog=Interner Dialog +admin.plugin.openWithWindow=Neue Seite öffnet sich +admin.plugin.fileSort=Priorität der Nebenstellenzuordnung +admin.plugin.fileSortDesc=Je größer die Erweiterung, desto höher die Priorität +admin.plugin.fileExt=Unterstützte Dateiformate +admin.plugin.fileExtDesc=Assoziiere Erweiterung zum Plugin +admin.plugin.tabServer=Serverkonfiguration +admin.plugin.defaultAceEditor=Ass-Editor +admin.plugin.defaultHtmlView=Web-Vorschau +admin.plugin.defaultZipView=Online-Dekomprimierung +admin.plugin.authViewList=Liste der Plugins +admin.plugin.authStatus=Öffnen, schließen +admin.plugin.authInstall=Installieren / deinstallieren +admin.plugin.disabled=Das Plugin existiert nicht oder wurde nicht gestartet +admin.plugin.menuAdd=Ob zum Hauptmenü hinzugefügt werden soll +admin.plugin.menuAddDesc=Als eigenständige Anwendung verwenden +admin.plugin.menuSubMenuDesc=Im Menü [Mehr] verkleinern +admin.storage.type=Speichertyp +admin.storage.local=Lokal +admin.storage.localStore=Lokale Speicherung +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=Sieben Kuhwolken +admin.storage.s3=Amazon S3 +admin.storage.ftp=FTP +admin.storage.oos=Tianyi Cloud OOS +admin.storage.moss=Hongshan MOSS +admin.storage.eos=XSKY EOS +admin.storage.nos=Ehemalige Cloud-NOS +admin.storage.minio=MinIO +admin.storage.uss=Nehmen Sie eine andere Cloud USS +admin.storage.eds=Sangfor EDS +admin.storage.driver=Lokale Festplatte +admin.storage.useage=Raumnutzung +admin.storage.default=Als Standard festlegen +admin.storage.current=Aktueller Standard +admin.storage.edit=Konfigurationsspeicher +admin.storage.setConfig=Konfiguration ändern +admin.storage.moveData=Daten migrieren +admin.storage.delStore=Speicher aushängen +admin.storage.ifMove=Dieser Speicher enthält {0} Netzwerkdatenträgerdateien und wird zum aktuellen Standardspeicher migriert. Möchten Sie fortfahren? +admin.storage.ifDel=Möchten Sie den aktuellen Shop wirklich unmounten? +admin.storage.ifDelWithFile=Dieser Speicher enthält {0} Netzwerkdatenträgerdateien, die beim Löschen in den aktuellen Standardspeicher migriert werden. Möchten Sie fortfahren? +admin.storage.sysFile=Netzwerklaufwerkdateien: Dateien im persönlichen Bereich und in Abteilungen +admin.storage.delErrTips=Erfolg:%s; Fehler:%s, versuchen Sie es erneut oder migrieren Sie manuell +admin.storage.delLocTips=Bitte bewahren Sie mindestens ein Geschäft vor Ort auf +admin.storage.delStoreTips=Dieser Speicher enthält Sicherungsdaten, bitte bearbeiten Sie diese, bevor Sie fortfahren! +admin.storage.nameDesc=Speichername zur Unterscheidung verschiedener Speicher +admin.storage.path=Speicherverzeichnis +admin.storage.pathLocDesc=Stellen Sie sicher, dass das ausgefüllte Verzeichnis über Lese- und Schreibrechte verfügt +admin.storage.pathDesc=Dateispeicherverzeichnis +admin.storage.defaultDesc=Das Standardelement ist der einzige gültige Systemspeicher. Wenn Sie ihn aktivieren, werden andere Standardspeichermethoden automatisch abgebrochen. Gehen Sie vorsichtig vor. +admin.storage.forceEdit=Obligatorische Änderung +admin.storage.editTips=Nach dem Öffnen können Sie die verbotenen Änderungsfelder bearbeiten. Die Datei vor dem Speicher ist möglicherweise nicht zugänglich. Bitte seien Sie vorsichtig. +admin.storage.folderTips=Der aktuelle Speicherort für Systemdateien ist mit Vorsicht zu genießen +admin.storage.sizeTips=Die Speicherplatzgröße muss größer als 0 sein +admin.storage.sizeDesc=(GB), bitte entsprechend dem tatsächlich freien Speicherplatz des gewählten Speicherverzeichnisses ausfüllen +admin.storage.region=Lagerbereich +admin.storage.domain=Space-Domain-Name +admin.storage.bucket=Name des Eimers +admin.storage.bucketDesc=Der Name des Eimers wurde beim Erstellen des Speicherplatzes eingegeben +admin.storage.userName=Kontoname +admin.storage.userPwd=Kontokennwort +admin.storage.server=Serveradresse +admin.storage.serverDesc=ftp (s): // ip, Standard ist ftp ohne Protokoll +admin.storage.refer=Hinweis: +admin.storage.endpoint=Endpunkt +admin.storage.ossDomain=Domänenname im OSS-Bereich gebunden +admin.storage.ossKeyDesc=Zugriffsschlüssel-ID des Alibaba Cloud-Kontos, bitte erstellen oder in [Systemsteuerung - Zugriffsschlüsselverwaltung] anzeigen +admin.storage.ossSecretDesc=Greifen Sie auf das Schlüsselgeheimnis des Alibaba Cloud-Kontos zu +admin.storage.ossEndpoint=Endpunkt, wenn Sie einen Intranetknoten verwenden, müssen Sie die Serverübertragung aktivieren +admin.storage.cosKeyDesc=Zugriffsschlüssel-ID des Tencent Cloud-Kontos, bitte erstellen oder in [Systemsteuerung-Zugriffsverwaltung-API-Schlüsselverwaltung] anzeigen +admin.storage.cosSecretDesc=Greifen Sie auf das Schlüsselgeheimnis des Tencent Cloud-Kontos zu +admin.storage.qiniuDomain=Domainname von Qiniu Space gebunden +admin.storage.qiniuKeyDesc=Access Key für Qiniu-Konto, bitte erstellen oder in [Systemsteuerung-Personal Center-Key Management] anzeigen +admin.storage.qiniuSecretDesc=Der geheime Schlüssel für das Qiniu-Konto entspricht der oben beschriebenen Methode +admin.storage.qnz0=Ostchina - Zhejiang +admin.storage.qnz02=Ostchina - Zhejiang 2 +admin.storage.qnz1=Nordchina - Hebei +admin.storage.qnz2=Südchina - Guangdong +admin.storage.qnna0=Nordamerika - Los Angeles +admin.storage.qnas0=Asien-Pazifik - Singapur +admin.storage.qnas02=Asien-Pazifik - Seoul +admin.storage.awsDomain=Domainname im AWS-Space gebunden +admin.storage.awsKeyDesc=Zugriffsschlüssel-ID des AWS-Kontos, bitte erstellen Sie sie in [Systemsteuerung - Ihre Sicherheitsanmeldeinformationen]. +admin.storage.awsSecretDesc=Greifen Sie auf Key Secret für AWS-Konto zu +admin.storage.oosDomain=Tianyi Cloud Space gebundener Domainname +admin.storage.oosKeyDesc=Zugriffsschlüssel-ID des Tianyi Cloud-Kontos, bitte erstellen Sie sie in [Systemsteuerung - Ihre Sicherheitsanmeldeinformationen] +admin.storage.oosSecretDesc=Das Zugriffsschlüsselgeheimnis des Tianyi-Cloud-Kontos ist dasselbe wie oben +admin.storage.ftpDisabled=FTP ist nicht verfügbar, bitte aktivieren Sie die Erweiterung php_ftp +admin.storage.ifDefaultTips=Durch diesen Vorgang werden andere Standardspeichermethoden abgebrochen. Sind Sie sicher? +admin.storage.spaceUsed=Praktische Anwendung +admin.storage.spaceLave=Restbetrag +admin.storage.delError=Die Datei ist bereits in diesem Speicher vorhanden und kann nicht gelöscht werden +admin.storage.corsError=Wenn die Konfiguration korrekt ist, klicken Sie auf [Hilfe verwenden], um die domänenübergreifenden Bucket-Einstellungen zu überprüfen. +admin.storage.saveError=Überprüfen Sie nicht, ob eine Verbindung zum angegebenen Speicher hergestellt werden kann. Überprüfen Sie, ob die Konfigurationsinformationen korrekt sind. +admin.storage.ftpCharset=FTP-Server-Codierung +admin.storage.ftpCharsetDesc=Wenn der FTP-Server Windows ist, kann er je nach Situation auf GBK eingestellt werden. +admin.storage.ftpPasvOn=Anmachen +admin.storage.ftpPasvOff=Schließung +admin.storage.ftpPasv=Passivmodus +admin.storage.ftpPasvDesc=Datenübertragungsmodus +admin.storage.uploadSrv=Serverübertragung (Upload) +admin.storage.fileoutSrv=Serverübertragung (Download) +admin.storage.uploadSrvDesc=Nach dem Einschalten wird die Datei über den Server in den Objektspeicher hochgeladen, andernfalls wird sie direkt über den Client hochgeladen. +admin.storage.fileoutSrvDesc=Nach dem Einschalten wird die Speicherdatei über den Server zum Herunterladen abgerufen, andernfalls wird die Datei zum direkten Herunterladen von Links abgerufen. +admin.storage.closeDefError=Verbieten Sie das Deaktivieren des Standardspeichers +admin.storage.ussBucket=Dienstname +admin.storage.ussBucketDesc=Name des Cloud-Speicherdienstes +admin.storage.ussUser=Name des Bedieners +admin.storage.ussUserDesc=Name des Bedieners +admin.storage.ussUserPwd=Bedienerkennwort +admin.storage.ussDomain=Machen Sie eine weitere Aufnahme des Domainnamens, der an den Cloud-Bereich gebunden ist +admin.storage.ussToken=Anti-Blutegel-Token +admin.storage.ussTokenDesc=Geheimschlüssel für die Diebstahlsicherungskette (nicht erforderlich) +admin.storage.configError=Der Konfigurationsparameter ist anormal! +admin.storage.sizePercent=Systemdateiverhältnis: +admin.storage.fileCount=Anzahl Dateien: +admin.storage.error=Speicherausnahme +admin.task.name=Aufgabenname +admin.task.edit=Aufgabenbearbeitung +admin.task.type=Aufgabentyp +admin.task.method=Eingebaute Methoden +admin.task.methodName=Methodenname +admin.task.methodDesc=Es besteht aus Systemmodul-Controller-Methodenname, sorgfältig ausfüllen. +admin.task.url=URL anfordern +admin.task.urlDesc=Benutzerdefinierte URL-Adresse, geplante Aufgaben zur regelmäßigen Ausführung von Anforderungen. +admin.task.cycle=Ausführungszyklus +admin.task.desc=Missionsdetails +admin.task.nMinutes=N Minuten +admin.task.default=Systemvorgabe +admin.task.timeInterval=Intervallzeit +admin.task.timeStart=Startzeit +admin.task.timeStartRun=Ausführungszeit starten +admin.task.timeLastRun=Letzte Ausführungszeit +admin.task.timeLastLogin=Anmeldezeit +admin.task.isOpen=Gibt an, ob aktiviert werden soll +admin.task.open=Öffnen +admin.task.content=Implementierungsinhalt +admin.task.param=Ausführungsparameter +admin.task.ifRun=Möchten Sie diese Aufgabe wirklich ausführen? +admin.task.backup=Datensicherung +admin.task.backupDesc=Beginnen Sie jeden Tag um 02:00 Uhr mit der Sicherung der Systemdaten. +admin.install.install=Systeminstallation +admin.install.databaseSet=Datenbankkonfiguration +admin.install.dataUpdate=Datenmigration +admin.install.installSuccess=Erfolgreich installiert +admin.install.dbWasSet=Sie haben die Datenbank konfiguriert. Wenn Sie zurücksetzen müssen, können Sie die Konfiguration in der Datei config / setting_user.php ändern und neu installieren! +admin.install.errorRequest=System installiert ist, sind keine weiteren Anfragen erlaubt +admin.install.databaseError=Datenbankverbindungsfehler, bitte überprüfen Sie die Konfiguration +admin.install.cacheError=%s Verbindung fehlgeschlagen, überprüfen Sie bitte die Konfiguration +admin.install.cacheConnectError=%s kann keine Verbindung zum Server herstellen. Überprüfen Sie die Konfiguration +admin.install.dbSetError=Fehler beim Schreiben der Datenbankkonfigurationsinformationen +admin.install.dbCreateTips=Die Datenbank existiert nicht und die automatische Erstellung schlägt fehl. Bitte erstellen Sie sie manuell +admin.install.ifDelDb=Die Daten sind bereits in der angegebenen Datenbank vorhanden. Klicken Sie auf [OK], um sie zu löschen. Möchten Sie fortfahren? +admin.install.dbCreateError=Ausnahme bei der Erstellung von Datentabellen +admin.install.dbFileError=Die Datenbankdatei existiert nicht +admin.install.dbTypeError=Der ausgewählte Datenbanktyp (%s) ist nicht verfügbar. Installieren Sie den entsprechenden Dienst und die entsprechende Erweiterung oder wählen Sie einen anderen Typ +admin.install.createSuccess=Erfolgreich erstellt +admin.install.defSetError=Systemstandardkonfiguration konnte nicht hinzugefügt werden +admin.install.defStoreError=Das Hinzufügen des Standardspeichers ist fehlgeschlagen +admin.install.defPathError=Hinzufügen des Systemverzeichnisses fehlgeschlagen +admin.install.defAdminError=Das Administratorkonto konnte nicht hinzugefügt werden +admin.install.defRoleError=Hinzufügen der Standardrolle fehlgeschlagen +admin.install.defGroupError=Hinzufügen der Systemabteilung fehlgeschlagen +admin.install.dataPathNotExists=Datenverzeichnis existiert nicht +admin.install.defaultUpdate=Aktualisierung der Systemkonfigurationsinformationen +admin.install.pluginUpdated=Plugin Update abgeschlossen +admin.install.defCacheError=Anfängliche Verzeichnis-Cache-Datenausnahme +admin.install.serverDir=Serverspaltenverzeichnis +admin.install.dirRight=Verzeichnisberechtigungen +admin.install.suggestOpen=Empfohlen zu öffnen +admin.install.suggestClose=Empfohlen zu schließen +admin.install.phpVersionTips=PHP5.3 und höher +admin.install.phpBitTips=64-Bit empfohlen +admin.install.phpBitDesc=32-Bit unterstützt das Hoch- und Herunterladen von Dateien über 2G nicht +admin.install.pathNeedWirte=Das Programmverzeichnis und alle Unterverzeichnisse müssen lesbar und beschreibbar sein +admin.install.mustOpen=Muss sich öffnen +admin.install.setPathWrt=Bitte legen Sie Lese- und Schreibberechtigungen für das Projektverzeichnis fest +admin.install.ensureNoError=Stellen Sie sicher, dass Folgendes korrekt ist: +admin.install.setAdminName=Bitte richten Sie ein Administratorkonto ein +admin.install.setAdminPwd=Bitte legen Sie ein Administratorkennwort fest +admin.install.database=Datenbank +admin.install.dbType=Datenbanktyp +admin.install.dbName=Datenbankname +admin.install.userName=Benutzername +admin.install.dbPort=Portnummer +admin.install.dbPortDesc=Der Standardport ist 3306, wenn Sie ihn anpassen müssen, können Sie ihn anhängen, z. B.: 127.0.0.1:3307 +admin.install.dbEngine=Speicher-Engine +admin.install.sqliteDesc=PHP verfügt über eine integrierte Green-Lightweight-Datenbank (geeignet für Tests oder kleine Anwendungen). +admin.install.mysqlDesc=Unterstützt die Clusterbereitstellung und die Trennung von Master- und Slave-Datenbanken. +admin.install.pdoDesc=Ein sichererer allgemeiner Datenbanktreiber erfordert, dass PHP die PDO-Erweiterung installiert hat. +admin.install.cacheType=System-Cache-Typ +admin.install.cacheTypeDesc=Wird zum Zwischenspeichern allgemeiner Daten und Sitzungssitzungen verwendet, um den Systemzugriff zu beschleunigen +admin.install.fileCache=Datei-Cache +admin.install.groupFile=Abteilungsdokument +admin.install.userFile=Benutzerdokumentation +admin.install.role=Rolle +admin.install.fileAuth=Dokumentberechtigungen +admin.install.userList=Benutzerliste +admin.install.setInfo=Informationen zur Systemkonfiguration +admin.install.favShare=Benutzerfavoriten und Freigaben +admin.install.waitUpdate=Warten auf Update +admin.install.updateSuccess=Update erfolgreich +admin.install.fileCount=Anzahl der Dateien +admin.install.settingDesc=Fehlerelemente können manuell in der Hintergrundverwaltung konfiguriert werden +admin.install.reInstallTips=Das Ergebnis ist nicht normal. Bitte neu installieren +admin.log.accountEdit=Ändern Sie die Kontoinformationen +admin.log.thirdBind=Binden Sie ein Konto eines Drittanbieters +admin.log.delBind=Binden Sie sich los +admin.log.viewFile=Vorschaudatei +admin.log.delFile=Datei löschen +admin.log.editFile=Datei bearbeiten +admin.log.downFile=Datei herunterladen +admin.log.downFolder=Download Ordner +admin.log.moveFile=Datei bewegen +admin.log.addUser=Benutzer hinzufügen +admin.log.editUser=Benutzer bearbeiten +admin.log.addUserTo=Fügen Sie der Abteilung Benutzer hinzu +admin.log.removeUserFrom=Benutzer aus Abteilung entfernt +admin.log.switchUserGroup=Benutzer in Abteilungen migrieren +admin.log.stausUser=Benutzer aktivieren / deaktivieren +admin.log.addRole=Neue Rolle +admin.log.editRole=Rolle bearbeiten +admin.log.delRole=Rolle löschen +admin.log.addAuth=Berechtigungen hinzufügen +admin.log.editAuth=Berechtigungen bearbeiten +admin.log.delAuth=Löschberechtigung +admin.log.editShare=Freigabe bearbeiten +admin.log.delLinkTo=Brechen Sie die Freigabe externer Links ab +admin.log.delShareTo=Brechen Sie die gemeinsame Nutzung ab +admin.log.recycleTo=Zum Papierkorb gehen +admin.log.newName=Neuer Name +admin.log.oldName=Originalname +admin.log.newPath=Neuer Katalog +admin.log.oldPath=Originalkatalog +admin.log.typeFile=Dateivorgänge +admin.log.typeUser=Benutzer Konfiguration +admin.log.queryByIp=Klicken Sie auf die Schaltfläche, um die Protokolldatensätze des Tages basierend auf der IP abzufragen. +admin.backup.setting=Backup-Einstellungen +admin.backup.edit=Backup-Bearbeitung +admin.backup.ing=Sichern +admin.backup.success=Sicherung erfolgreich +admin.backup.fail=Sicherung fehlgeschlagen +admin.backup.complete=Sicherung komplett +admin.backup.db=Datenbank +admin.backup.dbFile=Datenbankdatei +admin.backup.fileError=Sicherung einiger Dateien fehlgeschlagen +admin.backup.checkLog=Bitte prüfen Sie das Backup-Log: data/temp/log/backup/date of the day__log.php +admin.backup.pathNoWrite=Temporäres Verzeichnis hat keine Schreibberechtigung +admin.backup.errorMsg=Ein Teil der Dateisicherung ist fehlgeschlagen. Sie können manuell gemäß dem Protokoll kopieren oder löschen und erneut sichern. +admin.backup.logFile=Logdatei +admin.backup.manual=Manuelle Sicherung +admin.backup.continue=Sichern Sie weiter +admin.backup.start=Sicherung starten +admin.backup.open=Backup aktivieren +admin.backup.notOpen=Backup ist nicht aktiviert +admin.backup.location=Sicherungsspeicherort +admin.backup.content=Inhalt sichern +admin.backup.dbOnly=Datenbank +admin.backup.time=Sicherungszeit +admin.backup.notStart=hat nicht begonnen +admin.backup.notEnabled=Nicht aktiviert +admin.backup.killed=Über +admin.backup.ifKill=Möchten Sie diese Sicherung wirklich beenden? +admin.backup.kill=Ende +admin.backup.error=Abbrechen +admin.backup.timeBeen=Zeitaufwendig +admin.backup.timeTotal=Gesamtzeit +admin.backup.backed=Gesichert +admin.backup.storage=Bitte erstellen Sie einen dedizierten Speicher für die Sicherung. +admin.backup.ifSave=Die Sicherung dauert lange. Möchten Sie wirklich eine Sicherung durchführen? +admin.backup.ifContinue=Möchten Sie die Sicherung wirklich fortsetzen? +admin.backup.saveTips=Backup-Aufgabe wurde übermittelt, bitte haben Sie etwas Geduld +admin.backup.fileSize=Dokumentgröße +admin.backup.dbSize=Datenbankgröße +admin.backup.dbCnt=gesamt +admin.backup.notFinished=Nicht vollständig +admin.backup.timeTaken=Zeitaufwendig +admin.backup.node=Knoten +admin.backup.notYet=Nein +admin.backup.storeNotExist=Der Backup-Speicher existiert nicht, bitte zurücksetzen +admin.backup.timeNote=Hinweis: Das System bewahrt nur die Datenbanksicherungen der letzten 7 Tage und des 1. jedes Monats auf. Sicherungszeit: +admin.backup.recover=Bitte wenden Sie sich zur Datenwiederherstellung an den Dienstanbieter. +admin.backup.optionTime=Die Sicherung dauert lange. Bitte versuchen Sie, sie außerhalb der Arbeitszeit auszuwählen +admin.backup.optionLocation=Wenn Sie Dateien sichern müssen, erstellen Sie bitte einen neuen Speicher für die Sicherung +admin.backup.optionTips1=Die Sicherung ist in zwei Teile unterteilt: Datenbanksicherung und Dateisicherung. +admin.backup.optionTips2=Datenbanksicherung: Generieren Sie SQL-Dateien aus Datenbankinhalten und sichern Sie sie im Zielspeicher-Datenbankverzeichnis. +admin.backup.optionTips3=Dateisicherung: Sichern Sie die Systemspeicherdateien schrittweise gemäß dem ursprünglichen Speicherpfad auf dem Zielspeicher. +admin.backup.optionTips4=Das System bewahrt nur die Datenbanksicherungen der letzten 7 Tage und des 1. eines jeden Monats auf. +admin.backup.needStorage=Der Sicherungsspeicher darf nicht leer sein +admin.backup.needNoDefault=Wählen Sie nicht den Standardspeicher als Speicherort für die Dateisicherung +admin.backup.contentDesc=Die lizenzierte Version unterstützt die gleichzeitige Sicherung von Datenbanken und Dateien +admin.backup.action=Betriebsführung +admin.backup.recovery=die Ermäßigung +admin.backup.sysRecovery=Systemwiederherstellung +admin.backup.bakErr2Rec=Dieses Backup ist unvollständig und kann nicht wiederhergestellt werden +admin.recycle.menu=System-Papierkorb +admin.share.name=Teilename +admin.share.type=Freigabetyp +admin.share.expiryTime=Ablauf +admin.share.expired=abgelaufen +admin.share.link=Externer Link +admin.share.linkView=Klicken Sie hier, um die Freigabe anzuzeigen +admin.share.ifDel=Möchten Sie diese Freigabe wirklich abbrechen? +admin.share.disFile=Diese Datei wurde von Benutzern gemeldet und für die Freigabe gesperrt +admin.share.disFolder=Dieses Verzeichnis enthält unzulässige Dateien, deren Freigabe verboten ist +admin.share.shareTab=Sharing Management +admin.share.reportTab=Berichtsverwaltung freigeben +admin.share.rptType1=Piraterie +admin.share.rptType2=Obszöner Porno +admin.share.rptType3=Blutige Gewalt +admin.share.rptType4=Politik ist schädlich +admin.share.rptType5=andere Gründe +admin.share.doRptClose=Schließen Sie den Bericht nach der Verarbeitung des freigegebenen Inhalts oder schließen Sie ihn direkt +admin.share.doRptDisable=Nach dem Sperren / Zulassen der Freigabe sind alle der Datei entsprechenden Ressourcen betroffen. Möchten Sie diesen Vorgang wirklich ausführen? +admin.share.rptUser=Hinweisgeber +admin.share.rptTitle=Freigabe von Berichten +admin.share.rptDesc=Grund für die Meldung +admin.share.rptTime=Zeit melden +admin.share.rptResult=Prozessergebnis +admin.share.rptDone=Verarbeitet +admin.share.rptNoDone=Unbehandelt +admin.share.rptClose=Bericht schließen +admin.share.rptShareDel=Unshare +admin.share.rptShareAllow=Teilen erlauben +admin.share.rptShareDisable=Kein Teilen +admin.share.rptDoDisable=Teilen verbieten/erlauben +admin.share.rptSelectTips=Bitte wählen Sie den zu bedienenden Artikel! +admin.setting.transfer=Upload / Download +admin.setting.transferChunkSize=Shard-Größe hochladen +admin.setting.transferChunkSizeDesc= +admin.setting.transferChunkSizeDescError1=Die Größe des Upload-Shards darf die Einstellung in der php.ini nicht überschreiten +admin.setting.transferChunkSizeDescError2= +admin.setting.transferThreads=Gleichzeitiges Hochladen von Threads +admin.setting.transferThreadsDesc=Empfohlen = 10; gleichzeitiges Hochladen von Dateien oder Shards +admin.setting.transferIgnore=Ignorier Datei hochladen +admin.setting.transferIgnoreDesc= +admin.setting.transferChunkRetry=Automatische erneute Übertragung, wenn der Upload fehlschlägt +admin.setting.transferChunkRetryDesc= +admin.setting.transferOsChunkSize=Größe des Objektspeichersplitters +admin.setting.transferOsChunkSizeDesc= +admin.setting.transferHttpSendFile=Laden Sie die Webserverbeschleunigung herunter +admin.setting.transferHttpSendFileDesc= +admin.setting.downloadZipClient=Komprimierter Front-End-Download +admin.setting.downloadZipClientDesc=Muss in der Lage sein, auf das externe Netzwerk zu verlinken, oder die Website ist https +admin.setting.downloadZipLimit=Größenbeschränkung für komprimierte Downloads +admin.setting.downloadZipLimitDesc=0 bedeutet keine Begrenzung; um einen übermäßigen Verbrauch der Serverleistung zu vermeiden, wird der Paketdownload eingeschränkt, wenn der Ordner zu groß ist, und es wird darauf hingewiesen, dass die Datei direkt über den PC-Client heruntergeladen werden kann +admin.setting.downloadZipLimitTips=Der komprimierte Inhalt überschreitet die Systemgrenze, bitte wenden Sie sich an den Administrator Sie können den Ordner ohne Komprimierung direkt über den PC-Client herunterladen. +admin.setting.dragDownload=Zum Herunterladen per Drag-and-Drop auf den Desktop ziehen +admin.setting.dragDownloadDesc=Wird nur vom PC-seitigen Chrome-Kernel-Browser unterstützt (Chrome Edge 360 Fast usw.) +admin.setting.dragDownloadZip=Komprimieren per Drag-and-Drop-Download mit Mehrfachauswahl +admin.setting.dragDownloadZipDesc=Unterstützung für Mehrfachauswahl oder Ziehen-und-Ablegen-Download von Ordnern, muss vor dem Herunterladen auf dem Server gepackt und komprimiert werden +admin.setting.dragDownloadLimit=Größenbeschränkung für Drag-and-Drop-Inhalte +admin.setting.dragDownloadLimitDesc=0 bedeutet keine Begrenzung; die Größe der gezogenen Inhalte unterliegt dieser Begrenzung. Da es derzeit keinen Fortschrittsbalken für das Ziehen und Herunterladen von Chrome gibt, kann es nicht abgebrochen werden. Es wird empfohlen, die Größe auf 20 MB zu begrenzen. +admin.setting.dragDownloadUrlTips=Die URL ist zu lang, bitte reduzieren Sie die Auswahl und versuchen Sie es erneut! +admin.setting.dragDownloadOpenTips=Bitte wenden Sie sich an den Administrator, um es in den Hintergrundeinstellungen zu aktivieren! +admin.setting.dragDownloadNotOpen=Drag-and-Compress-Download ist nicht aktiviert +admin.setting.dragDownloadSizeTips=Die Größe des gezogenen Inhalts überschreitet das Limit +admin.setting.showFileSafe=Dateizugriffssicherheit +admin.setting.showFileLink=Anzeige externer Dateilinks +admin.setting.showFileLinkDesc=Nach dem Schließen zeigen die Dateieigenschaften keine externen Links mehr an +admin.setting.showFileMd5=Datei md5 anzeigen +admin.setting.showFileMd5Desc=Nach dem Schließen zeigen die Dateieigenschaften die Datei md5 nicht mehr an +admin.setting.shareLinkAllow=Freigabe externer Links aktivieren +admin.setting.shareLinkAllowDesc=Nach dem Schließen wird die externe Kettenfreigabe nicht mehr unterstützt, und die freigegebenen Inhalte sind nicht betroffen +admin.setting.shareLinkAllowTips=Das aktuelle System hat das Teilen externer Links deaktiviert, bitte wenden Sie sich an den Administrator! +admin.setting.shareLinkPasswordAllowEmpty=Die externe Kettenfreigabe lässt zu, dass das Passwort leer ist +admin.setting.shareLinkPasswordAllowEmptyDesc=Nach dem Schließen muss ein Passwort für die externe Linkfreigabe gesetzt werden, die geteilten Inhalte bleiben davon unberührt +admin.setting.shareLinkAllowGuest=Das Teilen externer Links ermöglicht nicht angemeldeten Besuchern den Zugriff +admin.setting.shareLinkAllowGuestDesc=Nach dem Schließen müssen Sie sich beim Aufrufen externer Links anmelden, die geteilten Inhalte bleiben davon unberührt +admin.setting.shareLinkZip=Download des Pakets für die Freigabe externer Links +admin.setting.shareLinkZipDesc=Nach dem Öffnen unterstützt der externe Chain-Sharing-Ordner das Herunterladen von Paketen und Komprimierungen. Wenn die Parallelität groß ist, wird die Serverleistung beeinträchtigt. +admin.setting.shareLinkZipTips=Die Freigabe externer Links deaktiviert gepackte Downloads. Bitte wenden Sie sich zur Konfiguration an den Administrator. +admin.setting.transferDownSpeed=Geschwindigkeitsbegrenzung herunterladen +admin.setting.transferDownSpeedDesc=Beschränken Sie die Download-Geschwindigkeit und die Geschwindigkeit großer gleichzeitiger Websites +admin.setting.transferDownSpeedNum=Geschwindigkeitsbegrenzung herunterladen +admin.setting.transferDownSpeedNumDesc=Begrenzen Sie die Download-Geschwindigkeit, und Sie können die Geschwindigkeit der Website bei großer Parallelität gleichmäßig begrenzen.
Hinweis: Die Servergeschwindigkeit ist hier begrenzt.Die spezifische Downloadgeschwindigkeit wird auch von der Serverbandbreite und dem Benutzernetzwerk beeinflusst. +explorer.uploadSizeError= +common.----=---- +common.width=Breit +common.height=Hoch +common.test=Test +common.absolutePath=Absolute Adresse +common.qrcode=URL QR-Code +common.wechat=WeChat +common.group=Abteilung +common.user=Benutzer +common.online=Online +common.use=Zu verwenden +common.total=Gesamt +common.year=Jahr +common.month=Monat +common.week=Woche +common.daytime=Tag +common.mon=am Montag +common.tue=am Dienstag +common.wed=Am Mittwoch +common.thu=Donnerstag +common.fri=Freitag +common.sat=am Samstag +common.sun=Sonntag +common.second=Zweitens +common.minute=Minuten +common.hour=Stunden +common.day=Tag +common.every=jeder +common.everyMonth=pro Monat +common.everyWeek=wöchentlich +common.everyDay=jeden Tag +common.language=Sprache +common.all=Alle +common.item=Gegenstand +common.items=Artikelinhalt +common.itemsEmpyt=Kein Inhalt +common.detail=Einzelheiten +common.me=Ich +common.others=Andere +common.guest=Besucher +common.more=Mehr +common.learnMore=Erfahren Sie mehr +common.yes=Ja +common.no=Nein +common.omit=Auslassen +common.unknow=Unbekannt +common.title=Titel +common.time=Zeit +common.scan=Durchsuche +common.report=Bericht +common.name=Name +common.nickName=Spitzname +common.tools=Werkzeuge +common.tag=Tags +common.position=Lage +common.mount=Netzwerk-Mount +common.type=Typ +common.auth=Behörde +common.status=Status +common.run=Rennen +common.file=Datei +common.folder=Ordner +common.fileType=Dateityp +common.fileSize=Dateigröße +common.attributeInfo=Attributinformationen +common.actionType=Vorgangstyp +common.isDisplay=Ob zu zeigen +common.hide=Verstecken +common.isHide=Versteckt +common.cancelHide=Ausblenden +common.default=Standard +common.display=Show +common.moveDown=Gehe nach unten +common.moveUp=Bewegen Sie sich nach oben +common.drag=Ziehen +common.dragSort=Ziehen Sie, um die Reihenfolge anzupassen +common.warning=Warnung +common.tips=Hinweis +common.desc=Anweisung +common.tipsDesc=Sofortige Beschreibung +common.tipsOthers=Andere Anweisungen +common.view=Aussicht +common.log=Log +common.task=Aufgabe +common.important=Wichtig +common.icon=Icon +common.menu=Menü +common.system=System +common.basic=Universal +common.systemSet=Systemkonfiguration +common.systemDefault=Systemvorgabe +common.diy=Brauch +common.input=Bitte eintreten +common.select=Bitte auswählen +common.add=Hinzufügen +common.edit=Bearbeiten +common.action=Bedienung +common.upload=Hochladen +common.uploadTo=etwas hochladen auf +common.download=Herunterladen +common.export=Exportieren +common.cover=Cover +common.retry=Wiederholen +common.zip=Komprimiert +common.unzip=Entpacken +common.preview=Vorschau +common.share=Teilen +common.search=Suche +common.query=Anfragen +common.delete=Löschen +common.deleteForce=Vollständig entfernen +common.deleteEnd=gelöscht +common.refresh=Aktualisieren +common.open=Öffnen +common.close=Schliessen +common.from=Quelle +common.greater=Größer als +common.less=Kleiner als +common.print=Drucken +common.selectInvert=Rückwahl +common.selectAll=Alles auswählen / Auswahl umkehren +common.selectAllItem=Alles auswählen +common.selectNum=Ausgewählt +common.selectNull=Gar keine +common.sizeMore=obenstehendes +common.showMore=Entfalten +common.showLess=Zusammenbruch +common.sizeSmall=klein +common.sizeMiddle=im +common.sizeBig=Groß +common.rename=Umbenennen +common.method=Funktion +common.extend=Erweiterung +common.fav=Liebling +common.reset=Zurücksetzen +common.testing=Testen +common.install=Installation +common.update=Update +common.version=Version +common.sysVersion=Plattformversion +common.login=Anmelden +common.regist=Melden Sie sich an +common.password=Passwort +common.operateTime=Betriebszeit +common.createTime=Erstellungszeit +common.modifyTime=Änderungszeit +common.activeTime=Archivierungszeit +common.startTime=Anfangszeit +common.endTime=Endzeit +common.finishTime=Endzeit +common.disable=Deaktivieren +common.goOn=Weiter +common.ok=OK +common.startRun=Start +common.confirmTips=Bitte noch einmal bestätigen +common.confirmAsk=Möchten Sie diesen Vorgang wirklich ausführen? +common.submit=Senden +common.skip=Überspringen +common.nextStep=Nächster Schritt +common.start=Starten Sie +common.stop=Pause +common.set=Einrichten +common.cancel=Abbrechen +common.save=Speichern +common.empty=Kein Inhalt! +common.isOpen=Eingeschaltet +common.isClose=geschlossen +common.apply=Bewerbung +common.saveAll=Alles speichern +common.notSave=Nicht speichern +common.appAdd=Hinzufügen +common.backAdd=Zurück zum Hinzufügen +common.saveEdit=Änderungen speichern +common.saveSubmit=Commit speichern +common.saveAndAdd=Speichern und fortfahren +common.sex=Sex +common.male=Männlich +common.female=Weiblich +common.address=Adresse +common.email=E-Mail +common.phone=Mobiltelefon +common.sms=SMS +common.phoneNumber=Telefonnummer +common.server=Server +common.handheld=Mobilgerät +common.success=Erfolg +common.fail=Misserfolg +common.error=Falsch +common.result=Ergebnis +common.expired=Abgelaufen +common.valid=Wirksam +common.inAll=gesamt +common.allAndNull=Wählen Sie Alle / Abbrechen +common.moveTop=oben +common.moveBottom=Am Ende einstellen +common.moveTopCancle=Unpink +common.ECN=Ostchina +common.NCN=Nordchina +common.SCN=Südchina +common.USA=Nordamerika +common.SEA=Südostasien +common.noLimit=nicht limitiert +common.notExists=Existiert nicht +common.cannotWrite=Nur lesen, nicht schreiben +common.readOnly=Schreibgeschützt +common.cannotRead=Unlesbar +common.ifDel=Möchten Sie wirklich löschen? +common.pageNotExists=Die Seite existiert nicht! +common.pathNotExists=Das Dokument existiert nicht! +common.fileShare=Dokumentfreigabe +common.logining=Anmelden ... +common.loginTokenError=Login ist abgelaufen, bitte erneut anmelden! +common.loginSuccess=Login erfolgreich! +common.loginError=Anmeldung fehlgeschlagen +common.connectSuccess=Erfolgreich verbunden! +common.bindSuccess=Binden Sie erfolgreich! +common.bindError=Bindung fehlgeschlagen +common.clear=Leer +common.congrats=Glückwunsch, +common.sorry=Entschuldigung +common.invalid=Ungültig +common.unavailable=nicht verfügbar +common.format=Format +common.noPermission=Zugang verweigert +common.allPermission=Alle Berechtigungen +common.invalidParam=Ungültiger Parameter +common.invalidFormat=Ungültiges Format +common.invalidRequest=Unzulässiger Anfragetyp +common.illegalRequest=Illegaler Antrag +common.expiredRequest=Anfrage ist abgelaufen +common.errorExpiredRequest=Ungültige Anfrage oder abgelaufen +common.migrating=Migration +common.migrated=Migration abgeschlossen +common.maintenanceTips=Während der Systemwartung besuchen Sie bitte später ... +common.done=abgeschlossen +common.disabled=deaktiviert +common.sizeTotal=Gesamtgröße +common.sqlStatement=[SQL-Anweisung]: +common.env.check=Umwelttests +common.env.errorLib=PHP-Bibliothek fehlt +common.env.errorIgnore=Ignorieren und eingeben +common.env.errorVersion=Die PHP-Version darf nicht niedriger als 5.0 sein +common.env.errorPath=Nicht beschreibbar +common.env.errorListDir= +common.env.errorGd=Die PHP GD-Bibliothek muss aktiviert sein, da sonst die Verwendung von Bestätigungscodes und Miniaturansichten nicht normal ist. +common.env.invalidExt=Die Erweiterung %s ist nicht verfügbar. Überprüfen Sie, ob sie installiert ist +common.env.installWithBtTips= +common.env.phpCacheOpenTips= +common.env.dataPathNotExists=Das Datenverzeichnis existiert nicht!
(Überprüfen Sie DATA_PATH); +common.env.pathPermissionError= +common.version.free=Kostenlos +common.version.nameQ=Enterprise Edition +common.version.vipFree=Kostenlose Ausgabe +common.version.useFree=Verwenden Sie weiterhin die kostenlose Version +common.version.notSupport=Ihre Version unterstützt diesen Vorgang nicht. Bitte besuchen Sie die offizielle Website, um die erweiterte Version zu erwerben! +common.version.notSupportNumber=Dieser Vorgang wird aufgrund der begrenzten Anzahl nicht unterstützt. Bitte besuchen Sie die offizielle Website, um die erweiterte Version zu erwerben! +common.version.toVip=Upgrade auf Commercial +common.version.license=Kaufberechtigung +common.version.authCode=Aktivierungscode für die Autorisierung +common.version.authActive=Aktivierungsberechtigung +common.version.authorization=Registrierungsberechtigung +common.version.authorizeSuccess=Herzlichen Glückwunsch, die Autorisierung für das Online-Upgrade war erfolgreich! +common.version.networkError=Die Anforderung an den Server ist fehlgeschlagen. Überprüfen Sie, ob der Server auf das Netzwerk zugreifen kann.
Hinweis: Der Server kann kein Proxy für den Internetzugang sein +common.version.authActiveOnline=Online aktivieren +common.version.authActiveOffline=Offline aktivieren +common.version.offlineTips=Der Server kann nicht auf das Internet zugreifen? +common.version.menuTitle=Einstellungen für Unternehmensinformationen +common.version.timeout=abgelaufen +common.version.timeToService=Service-Ablaufzeit +common.version.timeTo=Ablaufzeit der Autorisierung +common.version.licenseAll=Unbefristete Genehmigung +common.version.kodVersion=Programmversion +common.version.userLimitTitle=Benutzernummer +common.version.userUse=Gebraucht +common.version.userAllow=Anzahl der unterstützten Benutzer +common.version.userTo=Autorisiertes Objekt +common.version.userTitle=Autorisierungsinformationen +common.version.basicInfo=Grundinformation +common.version.appInfo=Produktinformation +common.version.tipsWarning=Achtung, bitte ändern Sie das Urheberrecht nicht ohne Erlaubnis, ggf. wenden Sie sich zum Kauf an! +common.version.tipsCopyLink=Erfolgreich kopieren! Einfügen und in txt-Datei speichern,
Öffnen Sie diesen Link auf einem Computer mit einem Netzwerk über ein USB-Flash-Laufwerk usw. +common.version.tipsHistory=Die kostenlose Version unterstützt nur 5 Verlaufsversionen; kaufen Sie eine unbegrenzte Anzahl lizenzierter Versionen! +common.version.codeLink=Link zur Anforderung des Autorisierungscodes +common.version.codeLinkHelp= +common.copyright.logoTitle=Corporate Identity Logo gesetzt +common.copyright.licenseInfo=Autorisierungsinformationen +common.copyright.licenseReset=Neu autorisieren +common.copyright.licenseResetTips=Reaktivieren Sie für weitere Informationen! +common.copyright.formLogo=Anmeldeseite Logo-Typ +common.copyright.formLogoTypeWord=Textlogo +common.copyright.formLogoTypeImage=Bildlogo +common.copyright.formLogoDesc=Das Textlogo verwendet den Firmennamen und das Bildlogo verwendet den folgenden Bildsatz. +common.copyright.formLogoImage=Logoseite der Anmeldeseite +common.copyright.formLogoImageDesc=Anmeldeseite und Management-Hintergrundlogo, empfohlene Größe 250x100, durchscheinendes PNG-Format +common.copyright.formLogoMain=Hauptschnittstellenmenü-Logo +common.copyright.formLogoMainDesc=Dateiverwaltung Logo in der oberen linken Ecke, empfohlene Größe 200 x 200, weißes durchscheinendes PNG-Format +common.copyright.formPowerByInfo=Einstellungen für Copyright-Informationen des Unternehmens +common.copyright.formPowerBy=Firmenname des unteren Urheberrechts +common.copyright.formHomePage=Unterer Copyright-Link-Sprung +common.copyright.formConcat=Popup-Kontakt +common.copyright.formDesc=Detaillierte Beschreibung der Produkt-Popup-Ebene +common.copyright.formDescTips=Nachdem die Änderung gespeichert wurde, wird die Aktualisierungsseite wirksam +common.copyright.formMetaKeywords=Site-Keywords (von Suchmaschinen verwendet) +common.copyright.formMetaName=Site-Name (von Suchmaschinen verwendet) +common.copyright.downloadApp=App herunterladen +common.copyright.downloadLink= +common.copyright.about=Über +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=Automatische Identifikation +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=Arabisch +common.charset.ISO_8859_6=Arabisch +common.charset.ISO_8859_10=Nordische Sprache +common.charset.CP1257=Sprachen rund um die Ostsee +common.charset.ISO_8859_13=Sprachen rund um die Ostsee +common.charset.ISO_8859_4=Sprachen rund um die Ostsee +common.charset.BIG5_HKSCS=Traditionelles Hong Kong +common.charset.BIG5=Traditionelles Taiwan +common.charset.Georgian_Academy=Georgisch +common.charset.PT154=Kasachisch +common.charset.CP949=Koreanisch +common.charset.EUC_KR=Koreanisch +common.charset.GB18030=Vereinfachtes Chinesisch +common.charset.GBK=Vereinfachtes Chinesisch +common.charset.ISO_8859_14=Keltisch +common.charset.CP1133=Lao +common.charset.ISO_8859_16=Rumänisch +common.charset.ISO_8859_3=Südeuropäische Sprachen +common.charset.EUC_JP=Japanisch +common.charset.ISO_2022_JP=Japanisch +common.charset.SHIFT_JIS=Japanisch +common.charset.KOI8_T=Tadschikisch +common.charset.ISO_8859_11=Thai +common.charset.TIS_620=Thai +common.charset.CP1254=Türkisch +common.charset.CP1251=Kyrillisch +common.charset.ISO_8859_5=Kyrillisch +common.charset.KOI8_R=Kyrillisch +common.charset.KOI8_U=Kyrillisch +common.charset.CP1252=Westeuropäische Sprachen +common.charset.ISO_8859_1=Westeuropäische Sprachen +common.charset.ISO_8859_15=Westeuropäische Sprachen +common.charset.Macintosh=Westeuropäische Sprachen +common.charset.CP1255=Hebräisch +common.charset.ISO_8859_8=Hebräisch +common.charset.CP1253=Griechisch +common.charset.ISO_8859_7=Griechisch +common.charset.ARMSCII_8=Armenisch +common.charset.CP1258=Vietnamesisch +common.charset.VISCII=Vietnamesisch +common.charset.CP1250=Mitteleuropäische Sprachen +common.charset.ISO_8859_2=Mitteleuropäische Sprachen +common.charset.defaultSet=Dateicodierung +common.charset.convertSave=Umgerechnet in +common.date.near=Gerade jetzt +common.date.miniteBefore=Vor Minuten +common.date.today=Heute +common.date.yestoday=Gestern +common.date.before=Vor +common.faceDefault=Standard-Emoticon +common.loadMore=Mehr laden +common.numberLimit=Die Menge überschreitet die Höchstgrenze! +common.lengthLimit=Die Länge überschreitet die Höchstgrenze! +common.task.name=Taskmanager +common.task.title=Missionsname +common.task.user=Ausführender Benutzer +common.task.porcess=Zeitplan +common.task.start=Aufgabe starten +common.task.useTime=Verstrichene Zeit +common.task.running=Ausführen +common.task.stoping=Pause +common.task.killing=Ende +common.task.stop=Angehaltene Aufgabe +common.task.kill=Task beenden +common.task.removeTips=Sind Sie sicher, diesen Vorgang zu beenden? +common.task.killAll=Beende alles +common.task.killAllTips=Sind Sie sicher, alle Aufgaben zu beenden? +common.task.timeStart=Anfangen bei +common.task.timeNeed=Verbleibend über +common.task.timeUse=Läuft bereits +ERROR_DB_PWD=Datenbankzugriff verweigert: Benutzername oder Passwort falsch. +ERROR_DB_TIMEOUT=Zeitüberschreitung bei der Datenbankverbindung, bitte überprüfen Sie, ob die Adresse korrekt ist. +ERROR_DB_CONN_RFS=Datenbankverbindung abgelehnt: Falsche Konfigurationsinformationen oder Dienst nicht gestartet. +ERROR_DB_ADR=Datenbankverbindungsfehler, bitte überprüfen Sie, ob die Adresse korrekt ist. +ERROR_DB_NOT_SUPPORT=Nicht unterstützter Datenbanktyp, bitte überprüfen Sie, ob der entsprechende Dienst oder die Konfigurationsdatei normal ist. +ERROR_DB_XS_DENNIED=Datenbankzugriff verweigert: unzureichende Berechtigungen. +ERROR_DB_NOT_EXIST=Die Datenbank existiert nicht oder es wurde ein falscher Name angegeben. +explorer.pathNotSupport=Dieser Verzeichnistyp unterstützt diese Operation nicht! +explorer.pathIsRoot=Sie haben das Stammverzeichnis erreicht! +explorer.pathNull=Der Ordner ist leer +explorer.zipFileLarge=Die Datei ist zu groß, bitte entpacken Sie sie vor der Vorschau! +explorer.charNoSupport=Nicht unterstützte Sonderzeichen: +explorer.moveError=Verschieben fehlgeschlagen +explorer.lockError=Ein Fehler ist aufgetreten, Zeitüberschreitung für gleichzeitige Sperre +explorer.lockErrorDesc=Bitte reduzieren Sie die Anforderungshäufigkeit oder optimieren Sie die Server-Parallelität-bezogene Konfiguration oder verbessern Sie die Server-Hardware-Konfiguration; +explorer.moveSubPathError=Es ist ein Fehler aufgetreten, das übergeordnete Verzeichnis kann nicht in das untergeordnete Verzeichnis verschoben werden! +explorer.spaceIsFull=Nicht genug Platz übrig, bitte wenden Sie sich an den Administrator! +explorer.sessionSaveError=Fehler beim Schreiben der Sitzung! Überprüfen Sie, ob die Festplatte voll ist, oder wenden Sie sich an Ihren Diensteanbieter. +explorer.networkError=Netzwerkverbindungsfehler (net :: ERR_CONNECTION_RESET), Verbindung wurde zurückgesetzt.
Bitte wenden Sie sich an das Host-Unternehmen oder den Netzwerkadministrator, um die Firewall-Konfiguration zu überprüfen! +explorer.folderManage=Verwaltungsverzeichnis +explorer.clickEdit=Klicken Sie zum Bearbeiten +explorer.shortLink=Verknüpfung +explorer.upper=Obere Schicht +explorer.historyNext=Voraus +explorer.historyBack=Zurück +explorer.loading=In Betrieb ... +explorer.getting=Bekommen ... +explorer.sending=Daten werden gesendet ... +explorer.pullTips=Ziehen Sie nach unten, um die Seite zu aktualisieren +explorer.pullDropTips=Kostenlos, um die Seite zu aktualisieren +explorer.getSuccess=Erfolg haben! +explorer.saveSuccess=Erfolgreich gespeichert! +explorer.saveError=Speichern fehlgeschlagen! +explorer.success=Operation erfolgreich +explorer.error=Operation fehlgeschlagen +explorer.dataError=Die Daten sind abnormal! +explorer.pathError=Dokumentpfadfehler +explorer.repeatError=Operation fehlgeschlagen, der Name existiert bereits! +explorer.systemError=Systemfehler +explorer.mistake=Irgendwas ist schief gelaufen! +explorer.recycleClear=Papierkorb leeren +explorer.recycleClearForce=Es befindet sich zu viel Inhalt im Papierkorb. Bitte leeren Sie zuerst den Papierkorb! +explorer.recycleRestore=Papierkorb wiederherstellen +explorer.recycleRestoreItem=Wiederherstellen +explorer.recycleRestoreAll=Stellen Sie alle wieder her +explorer.recycleClearInfo=Möchten Sie den Papierkorb wirklich vollständig leeren? +explorer.zipDownloadReady=Nach der Komprimierung automatisch herunterladen, bitte warten ... +explorer.removeItem=Artikelinhalt +explorer.uploading=Hochladen +explorer.uploadTipsMore=Zu viele Dateien sollten nach der Komprimierung hochgeladen und anschließend online dekomprimiert werden! +explorer.uploadingMove=Zusammenführen und Übertragen ... +explorer.viewNewPage=Neue Seitenvorschau +explorer.unknowFileTitle=Tipps zum Öffnen von Dateien! +explorer.unknowFileTips=Ohne eine App, die diese Datei unterstützt, können Sie: +explorer.unknowAppTips=Ohne die App: +explorer.unknowFileTry=Versuchen Sie es +explorer.unknowFileDown=Laden Sie die Datei herunter +explorer.authFileDown=Datei herunterladen +explorer.authShare=Teilen +explorer.usersShare=Des Teilens +explorer.clipboard=Zwischenablage anzeigen +explorer.clipboardClear=Leere Zwischenablage +explorer.fullScreen=Vollbild +explorer.folderItem=Artikel +explorer.folderItemSelect=Ausgewählt +explorer.dbLoadAll=Doppelklicken, um alle zu laden ... +explorer.ziping=Komprimieren ... +explorer.unziping=Dekomprimieren ... +explorer.zipingTips=Komprimierungsvorgang, bitte warten ... +explorer.unzipingTips=Entpacken, bitte warten ... +explorer.unzipRarTips=Der Inhalt der Datei ist beschädigt oder das Parsen der Datei wird nicht unterstützt. Es wird empfohlen, das ZIP-Format zu verwenden. +explorer.parsing=Abrufen ... +explorer.moving=Umzugsbetrieb ... +explorer.copyMove=Kopieren verschieben +explorer.removeTitle=Bestätigung löschen +explorer.removeInfo=Möchten Sie die Auswahl wirklich löschen? +explorer.removeTitleForce=Für immer löschen +explorer.removeInfoForce=Möchten Sie dieses Dokument wirklich dauerhaft löschen? +explorer.pathInRecycle=Der Ordner befindet sich im Papierkorb, bitte wiederherstellen und erneut versuchen! +explorer.pathInRecycleFile=Die Datei befindet sich im Papierkorb, bitte wiederherstellen und erneut versuchen! +explorer.downOffline=Offline herunterladen +explorer.savePath=Pfad speichern +explorer.uploadSelectMuti=Wählen Sie mehrere Dateien zum Hochladen aus +explorer.goTo=Springe zu +explorer.selectFile=Datei auswählen +explorer.selectFolder=Ordner auswählen +explorer.selectImage=Bitte wählen Sie ein Bild aus ... +explorer.selectValidFolder=Bitte wählen Sie einen Ordner aus, der gültig sein soll! +explorer.selectFolderFile=Datei oder Ordner auswählen +explorer.selectMulti=Mehrfachauswahl +explorer.notNull=Pflichtfelder dürfen nicht leer sein! +explorer.picCannotNull=Bildadresse darf nicht leer sein! +explorer.renameSuccess=Erfolgreich umbenannt! +explorer.inputSearchWords=Bitte geben Sie den Suchbegriff ein +explorer.search.optionContent=Dokumentinhalt +explorer.search.searchContentTips=Inhalt der Schlüsselwortsuchdatei, Unterstützungstextdatei +explorer.search.optionMutil=Massensuche +explorer.search.optionMutilDesc=Ein Suchbegriff pro Zeile, die Suchergebnisse werden nach dem Suchbegriff sortiert +explorer.removeSuccess=Erfolgreich gelöscht! +explorer.removeFail=Löschen fehlgeschlagen! +explorer.clipboardNull=Zwischenablage ist leer! +explorer.createSuccess=Neuer Erfolg! +explorer.createError=Neue Erstellung fehlgeschlagen, bitte Verzeichnisberechtigungen prüfen! +explorer.copySuccess=[Kopieren] - Zwischenablage erfolgreich überschreiben! +explorer.cuteSuccess=[Cut] -Überschreibe die Zwischenablage erfolgreich! +explorer.clipboardState=Zwischenablagestatus: +explorer.copyOK=Erfolgreich kopiert! +explorer.copyNotExists=Quelle existiert nicht +explorer.currentHasParent=Der Zielordner ist ein Unterordner des Quellordners! +explorer.pastSuccess=Einfügevorgang abgeschlossen +explorer.cutePastSuccess=Schneidvorgang abgeschlossen +explorer.zipSuccess=Komprimierung abgeschlossen +explorer.notZip=Keine komprimierte Datei +explorer.zipNull=Keine Dateien oder Verzeichnisse ausgewählt +explorer.unzipSuccess=Entpacken Sie vollständig +explorer.pathIsCurrent=Der geöffnete Pfad ist der gleiche wie der aktuelle Pfad! +explorer.pathExists=Der Name existiert bereits! +explorer.serverDownDesc=Aufgaben zur Download-Liste hinzugefügt +explorer.parentPermission=Übergeordnete Verzeichnisberechtigungen +explorer.confirm=Bist du dir sicher? +explorer.ifSaveFileTips=Gibt es nicht gespeicherte Dateien, möchten Sie das Fenster wirklich schließen? +explorer.ifSaveFile=Die Datei wurde noch nicht gespeichert. Wird sie gespeichert? +explorer.ifStopUploadTips=Eine Datei wird hochgeladen. Schließen Sie das Fenster wirklich? +explorer.noPermissionRead=Sie haben keine Leseberechtigung! +explorer.noPermissionDownload=Sie haben keine Berechtigung zum Herunterladen! +explorer.noPermissionWrite=Das Verzeichnis hat keine Schreibrechte +explorer.noPermissionAction=Sie haben diese Berechtigung nicht, wenden Sie sich bitte an den Administrator! +explorer.noPermissionWriteAll=Die Datei oder das Verzeichnis hat keine Schreibberechtigung +explorer.noPermissionWriteFile=Die Datei hat keine Schreibberechtigung +explorer.noPermissionReadAll=Die Datei oder das Verzeichnis verfügt nicht über Leseberechtigungen +explorer.noPermission=Der Administrator hat diese Berechtigung deaktiviert! +explorer.noPermissionExt=Ein Administrator hat diese Art von Dateiberechtigungen deaktiviert +explorer.noPermissionGroup=Sie sind nicht in dieser Benutzergruppe! +explorer.pathNoWrite=Das Verzeichnis ist nicht beschreibbar. Stellen Sie das Verzeichnis und alle Unterverzeichnisse auf Lesen und Schreiben ein und versuchen Sie es erneut. +explorer.onlyReadDesc=Dieses Verzeichnis verfügt nicht über Schreibberechtigungen. Sie können Berechtigungen für dieses Verzeichnis auf dem Server festlegen +explorer.settingSuccess=Die Änderung wurde wirksam! +explorer.noRepeat=Duplikate sind nicht erlaubt +explorer.dataNotFull=Datenübermittlung ist unvollständig! +explorer.tooManyToView=Enthält zu viel Inhalt (%s Elemente). Bitte öffnen Sie ihn lokal, um ihn anzuzeigen. +explorer.jumpAfterWhile=Automatisch nach%ss springen, Spring jetzt +explorer.retryTips=Bitte überprüfen Sie und versuchen Sie es erneut +explorer.selectObject=Objekte auswählen +explorer.parentGroup=Übergeordnete Abteilung +explorer.actionAuth=Betriebsautorität +explorer.notSelectDesc=Keine Daten, bitte auswählen! +explorer.groupAuthCopy=Kopieren Sie die Kombination +explorer.groupAuthCopyDesc=Kopieren Sie die Berechtigungskombination +explorer.groupAuthPasteDesc=Fügen Sie die kopierte Berechtigungskombination ein +explorer.groupAuthSave=Zum Favoriten speichern +explorer.groupAuthRecent=Kürzlich verwendet +explorer.selectDesc=Inhalt auswählen +explorer.cannotLoad=Ergebnisse können nicht geladen werden. +explorer.loadMore=Weitere Ergebnisse laden ... +explorer.noSearchData=Keine Ergebnisse gefunden +explorer.delAllItem=Löschen Sie alle Elemente +explorer.pleaseDel=Bitte löschen +explorer.pleaseInput=Bitte geben Sie mindestens +explorer.canChoose=Nur höchstens auswählen +explorer.theChars=Zeichen +explorer.theItems=Artikel +explorer.noData=Keine Daten +explorer.ifPathAuthClear=Alle Einstellungen für Subdatei- und Ordnerberechtigungen werden gelöscht. Möchten Sie wirklich fortfahren? +explorer.fileDescAdd=Dokumentbeschreibung hinzufügen +explorer.fileDesc=Dokumentbeschreibung +explorer.fileLog=Dokumentprotokoll +explorer.ifResetOpen=Möchten Sie wirklich alle benutzerdefinierten Öffnungsmethoden zurücksetzen? +explorer.ResetOpen=Setzen Sie alle benutzerdefinierten offenen Methoden zurück +explorer.openWith=Öffnen als ... +explorer.openWithAce=Der Editor wird geöffnet +explorer.openWithLocal=Lokal öffnen +explorer.openWithLocalEdit=Lokale Bearbeitung +explorer.editorSaveTips=Die Datei wurde nicht erstellt, bitte speichern Sie zuerst die neue Datei +explorer.editor.fileTooBig=Die Datei ist zu groß und darf nicht größer als 20 MB sein +explorer.errorFunctionTips=Dieser Dateityp unterstützt keine Funktionslisten! +explorer.errorFormatTips=Der aktuelle Dateityp stimmt nicht mit der Standardformatierungsmethode überein.
Bitte manuell auswählen +explorer.cuteToThe=Verschieben nach: +explorer.copyToThe=Kopieren nach: +explorer.addToFav=Zu den Favoriten hinzufügen +explorer.addFav=Favoriten hinzufügen +explorer.delFav=Sammlung abbrechen +explorer.addFavSuccess=Favorit erfolgreich hinzufügen +explorer.pathHasFaved=Der Weg wurde favorisiert +explorer.delFavSuccess=Sammlung erfolgreich abbrechen +explorer.fileLock=Sperre bearbeiten +explorer.fileLockNow=Verriegelung +explorer.fileLockCancle=Freischalten +explorer.fileLockTitle=gesperrt +explorer.fileLockTips=Gesperrt (andere können die Datei nicht bearbeiten) +explorer.fileLockUser=Schließfach +explorer.fileLockError=Die aktuelle Datei ist gesperrt. Wenden Sie sich an das Schließfach, um sie zu entsperren, und versuchen Sie es erneut. +explorer.downloaded=Download abgeschlossen +explorer.openAutoTips=Wird automatisch geöffnet +explorer.historyAutoTips=Historische Versionen automatisch generieren +explorer.saved=Erfolgreich gespeichert +explorer.opened=Erfolgreich öffnen! +explorer.openFail=Öffnen fehlgeschlagen! +explorer.openingWithLoc=Datei ist lokal geöffnet ... +explorer.openOnlyView=Der schreibgeschützte Modus ist aktiviert +explorer.saving=Datei speichern ... +explorer.notSupport=Ein Fehler ist aufgetreten, das Inhaltsformat wird nicht unterstützt! +explorer.unzipErrorTips=Irgendwas ist schief gelaufen! Nicht erkanntes komprimiertes Dateiformat;
Bitte überprüfen Sie, ob die Datei komprimiert oder beschädigt ist. +explorer.wordLoading=Laden ... +explorer.noFunction=Auf keinen Fall! +explorer.paramFormatError=Parameterformat ist falsch! +explorer.descTooLong=Beschreibung ist zu lang +explorer.noMoreThan=Nicht mehr als +explorer.desktopDelError=Entschuldigung, der Desktop-Ordner unterstützt das Löschen nicht! +explorer.copy=Kopieren +explorer.past=Einfügen +explorer.clone=Erstellen Sie eine Kopie +explorer.cute=Schneiden +explorer.cuteTo=Verschieben nach ... +explorer.copyTo=Kopieren nach ... +explorer.info=Attribut +explorer.searchInPath=Suche im Ordner +explorer.addToPlay=Zur Wiedergabeliste hinzufügen +explorer.manageFav=Favoriten verwalten +explorer.refreshTree=Baumverzeichnis aktualisieren +explorer.zip=Erstellen Sie ein komprimiertes Paket +explorer.unzip=Entpacken, um ... +explorer.unzipFolder=In Ordner extrahieren +explorer.unzipThis=Zum aktuellen entpacken +explorer.unzipTo=Entpacken, um ... +explorer.openProject=Editor Projekt öffnen +explorer.createLink=Erstellen Sie eine Verknüpfung +explorer.createLinkHome=An Desktop-Verknüpfung senden +explorer.setBackground=Als Desktop-Hintergrund festlegen +explorer.favRemove=Diese Sammlung abbrechen +explorer.openPath=Gehe in das Verzeichnis +explorer.openPathFinished=Bereits in das Verzeichnis eingegeben +explorer.openIE=Browser öffnet sich +explorer.newFile=Neue Datei +explorer.newFolder=Neuer Ordner +explorer.fileSaveTo=Datei gespeichert in +explorer.openFather=Anzeige des oberen Ordners +explorer.uploadFile=Datei hochladen +explorer.uploadFolder=Ordner hochladen +explorer.appOpenDefault=Standardmäßig geöffnet +explorer.appOpenAways=Öffnen Sie diese Datei immer mit dem Programm Ihrer Wahl +explorer.appSelectDesc=Wählen Sie das Programm, mit dem Sie diese Datei öffnen möchten +explorer.appSelectMenu=Als Standard-Öffnungsmodus festlegen +explorer.appSelectMenuCancel=Als Standard öffnen mit aufheben +explorer.appSelectWarning=Bitte wählen Sie eine Anwendung! +explorer.appTypeSupport=Support-Anwendungen +explorer.appTypeAll=Alle Anwendungen +explorer.appSearch=Nach verwandten App-Installationen suchen +explorer.recent.createTime=Erstellt am +explorer.recent.modifyTime=Geändert am +explorer.recent.viewTime=Öffnen um +explorer.urlLink=Externe Linkadresse +explorer.downloading=Herunterladen ... +explorer.downReady=Demnächst +explorer.downError=Download fehlgeschlagen! +explorer.max=Maximieren +explorer.min=Minimieren +explorer.minAll=Alles minimieren +explorer.displayAll=Zeige alle Fenster +explorer.closeAll=Alles schließen +explorer.authDtl=Klicken Sie hier, um Ihre Berechtigungen im Verzeichnis anzuzeigen +explorer.authDialog=Interne Mitglieder, Berechtigungstabelle für die Dokumentzusammenarbeit +explorer.authNote= +explorer.auth.toOuter=Externe Autorisierung (andere Abteilungen oder Benutzer) +explorer.auth.share=Sharer +explorer.auth.owner=Besitzer +explorer.auth.disableDeep=Kein Berechtigungszugriff nur +explorer.auth.disableDeepDesc=Das Faktorverzeichnis verfügt über Lese- und Schreibberechtigungen für Dokumente und den festgelegten Zugriffspfad. +explorer.auth.tips=Kann die oben genannten Benutzer kontaktieren, um Berechtigungen für Sie festzulegen +explorer.notSystemPath=Kein Systemdateipfad +explorer.toolbar.rootPath=Persönlicher Raum +explorer.toolbar.fav=Favoriten +explorer.toolbar.desktop=Desktop +explorer.toolbar.client=Klient +explorer.toolbar.myComputer=Mein Computer +explorer.toolbar.recycle=Papierkorb +explorer.toolbar.myDocument=Mein Dokument +explorer.toolbar.myPicture=Mein Foto +explorer.toolbar.myMusic=Meine Musik +explorer.toolbar.myMovie=Mein Video +explorer.toolbar.myDownload=Mein Download +explorer.toolbar.uiDesktop=Desktop +explorer.toolbar.uiExplorer=Dateiverwaltung +explorer.toolbar.uiEditor=Herausgeber +explorer.toolbar.uiProjectHome=Projekt-Startseite +explorer.toolbar.uiLogout=Ausfahrt +explorer.toolbar.uiGroup=Organisationsstruktur +explorer.toolbar.myGroup=Meine Abteilung +explorer.toolbar.publicPath=Öffentliches Verzeichnis +explorer.toolbar.recentDoc=Neueste Dokumente +explorer.toolbar.myShare=Mein Anteil +explorer.toolbar.shareToMe=Arbeiten Sie mit mir zusammen +explorer.toolbar.shareTo=Meine Zusammenarbeit +explorer.toolbar.shareLink=Externe Linkfreigabe +explorer.toolbar.photo=Fotoalbum +explorer.photo.desc=Klassifizierung von Benutzeralben +explorer.photo.group=Albumgruppierung +explorer.photo.setting=Albumeinstellungen +explorer.photo.pathRoot=Album-Scan-Verzeichnis +explorer.photo.pathRootSelect=Wählen Sie einen Ordner als Stammverzeichnis für das Scannen von Albumbildern aus +explorer.photo.fileType=Dateityp angeben +explorer.photo.fileSize=Dateigrößenfilter +explorer.photo.fileSizeDesc=Filtern Sie nur Dateien, die größer als diese Einstellung sind, wenn sie 0 ist, gibt es keine Begrenzung +explorer.toolbar.folder=Katalogalbum +explorer.toolbar.folderSelect=Wählen Sie einen Ordner aus, der im Albummodus angezeigt werden soll +explorer.pathDesc.fav=Nachdem die Datei der Sammlung hinzugefügt wurde, kann sie schnell und direkt aufgerufen werden +explorer.pathDesc.home=Persönlicher Raum ist Ihr privater Stauraum, Nur für Sie sichtbar, nicht für andere Benutzer +explorer.pathDesc.groupRoot=Dies ist der öffentliche Raum des Unternehmens/der Einheit, Alle Mitglieder sind standardmäßig sichtbar +explorer.pathDesc.myGroup= +explorer.pathDesc.group=Abteilungsnetzwerk-Festplatte, nur für Mitglieder der Abteilung sichtbar, Die Betriebsberechtigung wird vom Abteilungsadministrator zugewiesen und festgelegt. +explorer.pathDesc.recentDoc=Kürzlich erstellte, hochgeladene, geänderte und geöffnete Dateien +explorer.pathDesc.shareTo=Hier können Sie Ihre von anderen initiierten [internen Zusammenarbeits]-Projekte anzeigen und verwalten +explorer.pathDesc.shareLink=Hier können Sie die von Ihnen initiierte externe Kettenfreigabe anzeigen und verwalten +explorer.pathDesc.recycle=Verwalten Sie Ihre gelöschten Dateien (Ordner) hier +explorer.pathDesc.fileType=Dateien nach Typ kategorisieren, nur Dateien im persönlichen Bereich +explorer.pathDesc.tag=Fügen Sie Tags zu Dateien (Ordnern) hinzu, um eine effiziente Klassifizierung und schnelle Abfrage zu erreichen +explorer.pathDesc.tagItem=Versuchen Sie, der Datei/dem Ordner ein Label hinzuzufügen! +explorer.pathDesc.mount=Hier können Sie mehrere Back-End-Speicher sowie die auf dem Server gemounteten Festplatten verwalten +explorer.pathDesc.shareToMe=Gekachelte Anzeige – alle Inhalte, mit denen ich zusammengearbeitet habe +explorer.pathDesc.shareToMeUser=Nach Teilen anzeigen – der Inhalt, mit dem ich zusammengearbeitet habe, wird vom Initiator kategorisiert +explorer.pathDesc.shareToMeUserItem=Von diesem Benutzer initiierte Zusammenarbeit +explorer.pathDesc.shareToMeGroup=Die Inhalte, mit denen ich zusammenarbeite, werden nach der Abteilung kategorisiert, in der sich der Ordner befindet +explorer.pathDesc.shareToMeGroupGroup=Kollaboratives Teilen von der Netzwerkfestplatte der Abteilung +explorer.pathDesc.search= +explorer.pathDesc.searchMore=Weitere Suchbedingungen festlegen +explorer.pathDesc.shareFrom=Quellpfad +explorer.pathGroup.shareGroup=Abteilungsraum +explorer.pathGroup.shareGroupDesc=Zugriff, wenn Inhalte in der untergeordneten Abteilung vorhanden sind +explorer.pathGroup.shareUser=Teilen des persönlichen Bereichs von Abteilungsmitgliedern +explorer.pathGroup.shareUserDesc=Quelle: Freigabe des persönlichen Bereichs des Benutzers, Freigabe von Dokumenten durch externe Abteilungen, die vom Benutzer initiiert wurde. +explorer.pathGroup.shareContent=Die Zusammenarbeit und der Austausch im Weltraum der Abteilung +explorer.pathGroup.group=Unterabteilung +explorer.pathGroup.groupContent=Abteilungsdokument +explorer.pathGroup.shareUserOuter=Externe Zusammenarbeit teilen +explorer.pathGroup.shareUserOuterDesc=Kollaboratives Teilen von externen Benutzern, die nicht ihrer eigenen Organisationsstruktur unterliegen +explorer.pathGroup.shareSelf=persönlicher Raum +explorer.toolbar.fileSizeTitle=Symbolgröße +explorer.toolbar.fileSizeSuper=Super klein +explorer.toolbar.fileSizeSmall=Kleines Icon +explorer.toolbar.fileSizeDefault=Mittleres Symbol +explorer.toolbar.fileSizeBig=Großes Symbol +explorer.toolbar.fileSizeBigSuper=Übergroße Symbol +explorer.toolbar.PagePC=PC-Version +explorer.toolbar.pagePhone=Mobile Version +explorer.file.name=Name +explorer.file.type=Typ +explorer.file.contain=Enthält +explorer.file.address=Lage +explorer.file.detil=Beschreibung +explorer.file.linkCount=Zitate +explorer.file.size=Größe +explorer.file.count=Menge +explorer.file.byte=Byte +explorer.file.path=Pfad +explorer.file.action=Bedienung +explorer.file.creator=Schöpfer +explorer.file.editor=Geändert von +explorer.file.location=Lage +explorer.file.timeInfo=Zeitinformation +explorer.file.createTime=Erstellungszeit +explorer.file.modifyTime=Änderungszeit +explorer.file.lastTime=Letzter Besuch +explorer.file.sortType=Sortieren nach +explorer.file.sortDisable=Der Inhalt unterstützt die angegebene Sortierung nicht! +explorer.file.timeType=J / M / T H: i: s +explorer.file.timeTypeInfo=J / M / T H: i: s +explorer.file.listType=Ansehen +explorer.file.listIcon=Icon Anordnung +explorer.file.listList=Liste sortieren +explorer.file.listListSplit=Spaltenmodus +explorer.file.listTypeGroup=Anzeigemodus und Sortiermethode +explorer.file.listTypeKeep=Anzeigemodus +explorer.file.listTypeKeepDesc=Wählen Sie einen Ansichtsmodus für jeden Ordner oder verwenden Sie denselben Ansichtsmodus für alle Ordner +explorer.file.listSortKeep=Sortieren nach +explorer.file.listSortKeepDesc=Konfigurieren Sie die Spaltensortierreihenfolge für jeden Ordner oder verwenden Sie dieselbe Reihenfolge für alle Ordner +explorer.file.listViewKeep=Funktioniert mit einem einzigen Ordner +explorer.file.listViewAll=gilt für alle Ordner +explorer.file.listViewReset=zurücksetzen +explorer.file.sortUp=Zunehmend +explorer.file.sortDown=Dekrement +explorer.file.orderType=Sortieren nach +explorer.file.orderDesc=Absteigend +explorer.file.orderAsc=Aufsteigende Reihenfolge +explorer.file.imageSize=Bildgröße +explorer.file.sharer=Geteilt von +explorer.file.shareTime=Zeit teilen +explorer.file.viewCnt=Besuche +explorer.file.downCnt=Downloads +explorer.file.readWriteLock=Dieser Vorgang wird vorübergehend nicht unterstützt. Es werden andere Lese- und Schreibaufgaben verarbeitet. Bitte versuchen Sie es später erneut. +explorer.app.app=Leichte Anwendung +explorer.app.createLink=Neue URL +explorer.app.create=Erstellen Sie eine Lichtanwendung +explorer.app.edit=Leichte App bearbeiten +explorer.app.open=Licht App öffnen +explorer.app.groupGame=Spiel +explorer.app.groupTools=Werkzeuge +explorer.app.groupReader=Lesen +explorer.app.groupMovie=Film +explorer.app.groupMusic=Musik +explorer.app.groupLife=Leben +explorer.app.desc=Anwendungsbeschreibung +explorer.app.icon=Anwendungssymbol +explorer.app.iconShow=URL-Adresse oder das Verzeichnis +explorer.app.group=Anwendungsgruppierung +explorer.app.type=Typ +explorer.app.typeUrl=Link +explorer.app.typeCode=js extension +explorer.app.display=Aussehen +explorer.app.displayBorder=Randlos (ausgewählt ist randlos) +explorer.app.displaySize=Größe ändern (zum Anpassen auswählen) +explorer.app.size=Größe +explorer.app.url=Linkadresse +explorer.app.code=js code +explorer.app.appType=Anwendungsart +explorer.app.website=URL +explorer.app.shortLink=Dateiverknüpfung +explorer.app.imgIcon=Bildsymbol +explorer.app.imgIconUrl=Wählen Sie das Bild aus oder fügen Sie die Webbild-URL ein. +explorer.app.path=Pfad +explorer.app.pathDesc=Unterstützt keine manuelle Änderung. Sie können mit der rechten Maustaste auf die Datei klicken, um eine Verknüpfung zu erstellen +explorer.app.link=URL-Link +explorer.app.linkDesc=Bitte geben Sie den http / https-Link ein +explorer.app.linkDragTips=Sie können den URL-Link in den Dateibereich ziehen, um automatisch einen URL-Link zu erstellen! +explorer.app.openType=Offener Weg +explorer.app.openWindow=Neues Fenster +explorer.app.openDialog=Dialogbox +explorer.app.openCurrent=aktuelle Seite +explorer.app.openInline=Seite einbetten +explorer.app.dialogSize=Dialoggröße +explorer.app.with=Breite +explorer.app.height=Höhe +explorer.app.moreSet=Weitere Einstellungen +explorer.app.canDiyWith=Breiteneinstellung zulassen +explorer.app.miniBlock=Minimalistische Titelleiste +explorer.app.runCode=Führen Sie js Code aus +explorer.app.name=Anwendungsname +explorer.app.nameDesc=Bitte geben Sie einen Anwendungsnamen ein. +explorer.app.descDesc=Bitte geben Sie eine Anwendungsbeschreibung ein +explorer.embed.title=Eingebettete Datei +explorer.embed.desc=Betten Sie die Datei in eine Webseite oder ein Blog ein +explorer.embed.url=URL einbetten +explorer.embed.code=Code einbetten +explorer.upload.ready=Warten auf Upload +explorer.upload.success=Erfolgreich hochgeladen +explorer.upload.secPassSuccess=Erfolg in Sekunden +explorer.upload.pathCurrent=Wechseln Sie in das aktuelle Verzeichnis +explorer.upload.select=Datei auswählen +explorer.upload.maxSize=Maximal zulässig +explorer.upload.sizeInfo= +explorer.upload.error=Upload fehlgeschlagen +explorer.upload.mergeError=Zusammenführen von Dateien fehlgeschlagen +explorer.upload.errorHttp=Netzwerk- oder Firewallfehler +explorer.upload.muti=Hochladen mehrerer Dateien +explorer.upload.drag=Upload per Drag & Drop +explorer.upload.dragFolder=Zum Hochladen in den Ordner ziehen und dort ablegen +explorer.upload.dragTips=Zum Hochladen freigeben! +explorer.upload.pathNotAllow=Dateiname ist nicht erlaubt +explorer.upload.errorNull=Keine Dokumente! +explorer.upload.errorBig=Dateigröße überschreitet Serverlimit +explorer.upload.errorMove=Dateien konnten nicht verschoben werden! +explorer.upload.errorExists=Die Datei existiert bereits +explorer.upload.local=Lokal hochladen +explorer.upload.tips=Verwenden Sie den Fragment-Upload, der nicht länger durch die php.ini eingeschränkt ist. Es wird empfohlen, den Chrome-Experience-Ordner per Drag & Upload hochzuladen +explorer.upload.exist=Dateiverarbeitung mit gleichem Namen +explorer.upload.clearAll=Alles löschen +explorer.upload.clear=Entleerung abgeschlossen +explorer.upload.addMore=Fügen Sie in der Masse hinzu +explorer.upload.errorEmpty=Darf nicht leer sein! +explorer.upload.errorExt=Die Dateierweiterungen stimmen nicht überein! +explorer.upload.fileSizeDisable=Es werden zu viele Dateien gleichzeitig hochgeladen / übertragen. Bitte wenden Sie sich an den Administrator, um sie anzupassen. +explorer.upload.moreDesc=(Empfohlen nicht mehr als 2000), derzeit insgesamt: +explorer.upload.scan=Scannen +explorer.upload.merge=Zusammenführung wird überprüft +explorer.upload.needTime=Verbleibende ca. +explorer.upload.checkError=Upload-Bestätigung fehlgeschlagen. Bitte versuchen Sie es erneut +explorer.upload.saveError=Dateiinformationen konnten nicht gespeichert werden +explorer.upload.downloadDesc=Unterstützt nur http / https-Netzwerkverbindungen +explorer.table.first=Zuhause +explorer.table.last=Letzte Seite +explorer.table.prev=Zurück +explorer.table.next=Nächste Seite +explorer.table.one=Insgesamt 1 Seiten +explorer.table.page=Seite +explorer.table.itemPage=/Seite +explorer.table.searchTotal=Gefunden +explorer.table.items=Aufzeichnungen +explorer.table.list=Datenliste +explorer.search.ing=Suche läuft ... +explorer.search.result=Suchergebnis +explorer.search.resultTooMore=Zu viele Suchergebnisse, schlagen Sie ein anderes Verzeichnis oder Wort vor +explorer.search.resultNull=Keine Suchergebnisse! +explorer.search.caseSensitive=Groß- und Kleinschreibung beachten +explorer.search.content=Suchen Sie nach Dateiinhalten +explorer.search.extDesc=Geben Sie die zu filternden Erweiterungen ein, getrennt durch Leerzeichen. +explorer.search.byItems=Bedingte Filterung +explorer.search.extNull=Unbegrenzter Typ +explorer.search.extFile=Beliebige Datei +explorer.search.extDiy=anpassen +explorer.search.inputDesc=Bitte geben Sie Stichwörter ein oder filtern Sie! +explorer.search.path=Durchsuche das Verzeichnis: +explorer.search.rootPath=Suchen Sie im Stammverzeichnis: +explorer.search.range=Suchbereich +explorer.search.allFolder=Alle Ordner +explorer.search.currentFolder=Aktueller Ordner +explorer.search.ext=Dateityp +explorer.search.timeRange=Zeitbereich +explorer.search.timeAll=Unbegrenzte Zeit +explorer.search.lastDay=Fast 1 Tag +explorer.search.lastWeek=Letzte 7 Tage +explorer.search.lastMonth=Letzte 30 Tage +explorer.search.lastYear=Letztes Jahr +explorer.search.sizeAll=Unbegrenzte Größe +explorer.search.inputNullDesc=Wenn nicht gefüllt, bedeutet dies, dass ein bestimmter Wert überschritten oder unterschritten wird. Dies kann eine Dezimalzahl sein. +explorer.search.selectUser=Benutzer auswählen ... +explorer.search.byUserDesc=Suche nach Ersteller / Modifikator +explorer.search.total=Gefunden +explorer.search.noResult=Entschuldigung, keine Suchergebnisse, bitte versuchen Sie es erneut +explorer.search.advance=Erweiterte Suche +explorer.search.clear=Inhalt löschen +explorer.history.list=Dateiversionen +explorer.history.lastModify=Zuletzt geändert +explorer.history.modifyUser=Geändert von +explorer.history.noHistory=Keine historische Version! +explorer.history.current=Aktuelle Version +explorer.history.detil=Beschreibung +explorer.history.detilAdd=Impressum hinzufügen +explorer.history.uploadNew=Neue Version hochladen +explorer.history.diff=Vergleich historischer Versionen +explorer.history.setCurrent=Als aktuelle Version festlegen +explorer.history.delCurrent=Löschen Sie diese Version +explorer.history.delAll=Löschen Sie den gesamten Versionsverlauf +explorer.history.ifDelAll=Möchten Sie wirklich den gesamten Verlauf löschen? +explorer.history.ifDelCurrent=Diese Version löschen? +explorer.history.ifRollback=Möchten Sie wirklich zu dieser Version zurückkehren? +explorer.history.changeEvent=Historischer Versionswechsel +explorer.history.before=Vor +explorer.history.after=nach +explorer.recycle.clearUser=Leeren Sie den Papierkorb des Benutzers +explorer.recycle.restoreSelect=Stellen Sie diesen Inhalt wieder her +explorer.recycle.moveTo=Aushändigen +explorer.recycle.config=Papierkorbeinstellungen +explorer.recycle.configTitle=Einstellungen des System-Papierkorbs +explorer.recycle.configOpen=Öffnen Sie den System-Papierkorb +explorer.recycle.configOpenDesc=Schlagen Sie vor, zu öffnen +explorer.recycle.configCloseInfo=Beim Löschen von Inhalten wird dieser nicht in den Papierkorb verschoben, sondern direkt gelöscht. +explorer.recycle.configOpenInfo= +explorer.recycle.configClear=Vollautomatisch löschen +explorer.recycle.restoreConfirm=Sind Sie sicher, das Dokument wiederherzustellen?
Nach dem Wiederherstellen wird das Dokument in das Zielstammverzeichnis verschoben +explorer.recycle.moveConfirm=Übergabe bestätigen +explorer.recycle.moveSelectTarget=Benutzer oder Abteilung auswählen +explorer.recycle.moveDesc= +explorer.recycle.taskTitle=Reinigung des System-Papierkorbs +explorer.recycle.taskDesc=Löschen Sie den Inhalt des Papierkorbs automatisch über die festgelegte Zeit hinaus, um Speicherplatz freizugeben +explorer.share.add=Freigabe hinzufügen +explorer.share.edit=Freigabe bearbeiten +explorer.share.remove=Freigabe abbrechen +explorer.share.path=Pfad teilen +explorer.share.source=Ressourcenteilung +explorer.share.name=Titel teilen +explorer.share.nameDesc=Dateiname standardmäßig freigeben, benutzerdefinierter Name +explorer.share.time=Ablaufzeit +explorer.share.timeLimit=Zeitlich begrenzt +explorer.share.timeLimitDesc=Nach dem Einschalten und Einstellen schlägt die Freigabe nach einiger Zeit automatisch fehl +explorer.share.timeDesc=Wird nicht gesetzt, wenn leer +explorer.share.pwd=Passwort extrahieren +explorer.share.pwdDesc=Es ist kein Passwort festgelegt +explorer.share.randomPwd=Zufällig generiert +explorer.share.randomPwdDesc=Es kann nur durch Extrahieren des Passworts angezeigt werden, das privater und sicherer ist. +explorer.share.cancel=Freigabe abbrechen +explorer.share.create=Erstellen Sie einen öffentlichen Link +explorer.share.url=Gemeinsame Adresse +explorer.share.noDown=Download verboten +explorer.share.codeRead=Code lesen +explorer.share.configSave=Speichern Sie die Konfiguration +explorer.share.errorParam=Parameterfehler! +explorer.share.errorUser=Benutzerinformationen sind falsch! +explorer.share.errorSid=Teilen existiert nicht! +explorer.share.errorTime=Sie sind zu spät, diese Aktie ist abgelaufen! +explorer.share.errorPath=Die freigegebene Datei existiert nicht, sie wurde gelöscht oder verschoben! +explorer.share.errorPwd=Das Passwort ist falsch! +explorer.share.errorShowTips=Dieser Dateityp unterstützt keine Vorschau! +explorer.share.expiredTips=Entschuldigung, diese Aktie ist abgelaufen, bitte kontaktieren Sie den Sharer! +explorer.share.downExceedTips=Entschuldigung, die Downloads für Freigaben haben das vom Sharer festgelegte Limit überschritten +explorer.share.store=In SkyDrive speichern +explorer.share.loginTips=Entschuldigung, diese Freigabe muss eingeloggt sein, um Zugriff zu haben! +explorer.share.noDownTips=Entschuldigung, der Sharer hat das Herunterladen deaktiviert! +explorer.share.noViewTips=Sorry, dieser Sharer hat die Vorschau deaktiviert! +explorer.share.noUploadTips=Entschuldigung, das Hochladen ist durch diesen Sharer deaktiviert! +explorer.share.needPwd=Diese Freigabe erfordert ein Passwort +explorer.share.notExist=Sharing existiert nicht! +explorer.share.viewNum=Durchsuchen: +explorer.share.downNum=Downloads +explorer.share.openPage=Freigegebene Seite öffnen +explorer.share.openLink=Freigabelink öffnen +explorer.share.copyLink=Kopieren Sie die Freigabeinformationen +explorer.share.link=Link teilen: +explorer.share.accessPwd=Zugangspasswort: +explorer.share.copied=Kopiert +explorer.share.actionNotSupport=Teilen Sie Inhalte, dieser Vorgang wird nicht unterstützt +explorer.share.errorPathTips=Der Sharing-Link ist falsch oder der Sharer hat den externen Link abgebrochen +explorer.share.shareTo=Gemeinsames Teilen +explorer.share.shareToTarget=Kooperierendes Mitglied +explorer.share.innerTo=Interne Zusammenarbeit +explorer.share.linkTo=Externe Linkfreigabe +explorer.share.selectTarget=Wählen Sie eine Abteilung oder einen Benutzer für die gemeinsame Nutzung aus +explorer.share.afterShareDesc=Nach der Freigabe für die andere Partei oder die Abteilung, zu der sie gehören, können Benutzer sie in [Für mich freigeben] anzeigen. +explorer.share.openOuterLink=Öffnen Sie die externe Kettenfreigabe +explorer.share.openOuterLinkDesc=Nachdem Sie einen externen Link erstellt haben, können Sie ihn per E-Mail oder QQ an andere senden. +explorer.share.outerLink=Link teilen +explorer.share.advanceSet=Erweiterte Konfiguration +explorer.share.loginLimit=Nur für angemeldete Benutzer verfügbar +explorer.share.loginLimitDesc=Nach dem Öffnen haben nur interne Mitglieder Zugriff. +explorer.share.authLimit=Rechte und Einschränkungen +explorer.share.canUpload=Upload zulassen +explorer.share.notView=Vorschau deaktivieren +explorer.share.notDown=Downloads deaktivieren +explorer.share.downNumLimit=Download-Limit +explorer.share.downNumLimitDesc=Nach dieser Anzahl läuft der Freigabelink automatisch ab. +explorer.share.learnAuth=Grundlegendes zu Berechtigungen für die Dokumentzusammenarbeit +explorer.share.shareToRemove=Sind Sie sicher, diese gemeinsame Freigabe abzubrechen?
Der Zielbenutzer, der mit geteilt hat, kann die kollaborative Freigabe nicht mehr sehen! +explorer.share.shareLinkRemove=Sind Sie sicher, die Freigabe externer Links abzubrechen?
Nach der Stornierung ist der externe Link ungültig! +explorer.share.shareToCopy=Zugriffspfad kopieren +explorer.share.shareToCopyDesc=Der Link kann an die mitarbeitende Person gesendet werden und schnell in die Zusammenarbeit eintreten +explorer.share.specifyAuthTips=Zusätzlich zu den oben genannten Benutzern +explorer.share.specifyAuthDesc=Autorität des designierten Benutzers> Abteilungsautorität des designierten Benutzers> Autorität anderer Personen +explorer.share.selfAuthDesc=Eigene Berechtigungen können nicht geändert werden, andere Manager können sie festlegen +explorer.share.authTypeDesc=Erben Sie standardmäßig die Berechtigungen des übergeordneten Ordners +explorer.share.rootPathAuthDesc=Benutzer- und Abteilungsauswahl für die Unterstützung der Stammabteilung +explorer.share.subPathAuthDesc=Unterabteilung, nur ausgewählte Abteilungsmitglieder +explorer.share.myAuth=Meine Berechtigungen +explorer.share.othersAuth=Andere Berechtigungen +explorer.share.keepAuth=Behalten Sie die ursprünglichen Berechtigungen +explorer.share.specifyAuth=Geben Sie die Berechtigungen an +explorer.share.userAuth=Benutzerrechte +explorer.share.specifyUserAuth=Benutzerberechtigungen angeben +explorer.share.rptTitle=Wenn Sie illegale und schädliche Informationen finden, wählen Sie bitte den folgenden Grund aus, um einen Bericht einzureichen. +explorer.share.illegal=Illegale Informationen +explorer.share.inputRptDesc=Bitte geben Sie den Grund für die Meldung ein +explorer.share.rptSend=Die Einreichung ist erfolgreich, der Administrator wird sich rechtzeitig darum kümmern +explorer.share.rptSended=Der Bericht wurde übermittelt und wartet darauf, dass der Administrator ihn verarbeitet +explorer.auth.mutil=Festlegen von Berechtigungen in Stapeln +explorer.auth.mutilTips=Hinweis : Wenn der ausgewählte Inhalt bereits über die Berechtigung verfügt, wird er überschrieben. +explorer.auth.mutilDesc=Gleichzeitig mit den nachfolgenden Standardberechtigungen +explorer.auth.showMore=Berechtigungsdetails +explorer.auth.tabUser=Abteilungsmitglied +explorer.auth.tabChildren=Berechtigungen für Unterordner +explorer.auth.tabUserTips=Erstberechtigungen von Abteilungsmitgliedern +explorer.auth.tabChildrenTips=Inhalte mit in diesem Ordner festgelegten Berechtigungen +explorer.auth.resetUser=Einstellung dieser Benutzerberechtigung überschreiben +explorer.auth.resetUserBtn=Berechtigungen überschreiben +explorer.auth.resetUserBtnTips=Überschreiben Sie die Berechtigungen des Benutzers und aller Unterordner (Ordner) in diesem Ordner +explorer.auth.resetUserHeader=Der untergeordnete Ordner enthält den Inhalt, der die Berechtigungen des Benutzers angibt, und legt alle Außerkraftsetzungen auf die oben genannten Berechtigungen fest +explorer.auth.resetUserContiner=Enthält den Inhalt der Berechtigung des Benutzers +explorer.auth.resetUserEmpty1=Es gibt keine Inhalte, für die Berechtigungen für diesen Benutzer festgelegt sind, und müssen nicht überschrieben werden +explorer.auth.resetUserEmpty2=Alle untergeordneten Inhalte erben die Ordnerberechtigungen der aktuellen Ebene +explorer.rename.mutil=Batch-Umbenennung +explorer.rename.nameBefore=Ursprünglicher Dateiname +explorer.rename.nameTo=Umbenannt +explorer.rename.start=Jetzt umbenennen +explorer.rename.clearFinished=Entleerung abgeschlossen +explorer.rename.clearAll=Alles löschen +explorer.rename.typeReplaceAll=Ersetzen Sie alle +explorer.rename.typePrepend=Vorher anhängen +explorer.rename.typeAppend=Später anhängen +explorer.rename.typeReplace=Suchen und ersetzen +explorer.rename.typeChangeCase=Fallkonvertierung +explorer.rename.typeRemove=Zeichen löschen +explorer.rename.typeReplaceSet=Geben Sie den Austausch im Stapel an +explorer.rename.typeReplaceSetDesc=Ersetzen Sie sie, wenn sie gleich sind. Jede Zeile ist durch ein Leerzeichen getrennt, und der Dateiname lässt keine Leerzeichen zu. Beispiel: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Zusätzlicher Inhalt +explorer.rename.find=Finden +explorer.rename.replaceTo=Ersetzt durch +explorer.rename.caseUpperFirst=Anfangskapital +explorer.rename.caseUpper=Alle Kappen +explorer.rename.caseLower=Alles in Kleinbuchstaben +explorer.rename.removeStart=Von Grund auf neu entfernen +explorer.rename.removeEnd=Vom Ende entfernen +explorer.rename.chars=Charakter +explorer.editor.beautifyCode=Code-Formatierung +explorer.editor.convertCase=Fallkonvertierung +explorer.editor.convertUpperCase=In Großbuchstaben konvertieren +explorer.editor.convertLowerCase=In Kleinbuchstaben konvertieren +explorer.editor.currentTime=Aktuelle Zeit +explorer.editor.md5=MD5-Verschlüsselung +explorer.editor.qrcode=String QR-Code +explorer.editor.regx=Test des regulären Ausdrucks +explorer.editor.chinese=Vereinfachte Konvertierung +explorer.editor.chineseSimple=In vereinfachtes Chinesisch konvertieren +explorer.editor.chineseTraditional=In traditionelles Chinesisch konvertieren +explorer.editor.base64=Base64-Codec +explorer.editor.base64Encode=Base64-Codierung +explorer.editor.base64Decode=Base64-Dekodierung +explorer.editor.url=URL-Codec +explorer.editor.urlEncode=URL-Codierung +explorer.editor.urlDecode=URL-Decodierung +explorer.editor.unicode=Unicode-Codec +explorer.editor.unicodeEncode=Unicode-Codierung +explorer.editor.unicodeDecode=Unicode-Dekodierung +explorer.editor.toolsSelectTips=Bitte wählen Sie den richtigen zu verarbeitenden Inhalt aus! +explorer.editor.toolsRandString=Generieren Sie eine 32-Bit-Zufallszeichenfolge +explorer.editor.textEncode=Textcodierung / -decodierung +explorer.editor.textParse=Textverarbeitung +explorer.editor.timeShow=Zeitstempel zur Zeit +explorer.editor.timeInt=Zeit zum Zeitstempel +explorer.editor.lineRemoveEmpty=Leerzeilen (einschließlich Leerzeichen) entfernen +explorer.editor.lineUnoin=Entfernen Sie doppelte Zeilen +explorer.editor.lineTrim=Entfernen Sie führende und nachfolgende Leerzeichen +explorer.editor.lineSort=Nach Zeile sortieren (aufsteigende Reihenfolge) +explorer.editor.lineReverse=Vertauschen Sie alle Zeilen nach oben und unten +explorer.editor.lineSum=Summe +explorer.editor.lineAverage=Durchschnittswert +explorer.editor.calc=Freier Rechner +explorer.editor.goToLine=Zur Zeile springen +explorer.editor.keyboardType=Tastaturmodus +explorer.editor.fontFamily=Schriftart +explorer.editor.codeMode=Markieren Sie die Syntax +explorer.editor.closeAll=Alles schließen +explorer.editor.closeLeft=Linke Lasche schließen +explorer.editor.closeRight=Schließen Sie die rechte Registerkarte +explorer.editor.closeOthers=Andere schließen +explorer.editor.wordwrap=Zeilenumbruch +explorer.editor.showGutter=Zeilennummer anzeigen +explorer.editor.charAllDisplay=Zeige unsichtbare Zeichen +explorer.editor.autoComplete=Automatische Abfrage +explorer.editor.autoSave=Autosave +explorer.editor.functionList=Funktionsliste +explorer.editor.codeTheme=Code-Stil +explorer.editor.fontSize=Schriftgröße +explorer.editor.completeCurrent=Strom automatisch vervollständigen +explorer.editor.createProject=Zum Editorprojekt hinzufügen +explorer.editor.markdownContent=Inhaltsverzeichnis +explorer.editor.undo=Widerrufen +explorer.editor.redo=Anti-Widerrufsbelehrung +explorer.editor.shortcut=Verknüpfung +explorer.editor.replace=Ersetzen +explorer.editor.reload=Neu laden +explorer.editor.view=Ansehen +explorer.editor.tools=Werkzeuge +explorer.editor.help=Hilfe +explorer.sync.data=Datensynchronisation +explorer.sync.openLoc=Öffnen Sie das lokale Verzeichnis +explorer.sync.syncing=Synchronisierung +explorer.sync.synced=Synchronisierung abgeschlossen +explorer.sync.syncedError=Fehlerprotokoll +explorer.sync.syncStart=Starten Sie die Synchronisierung +explorer.sync.syncStop=Beenden Sie die Synchronisierung +explorer.sync.notOpenTips=Sie haben die lokale Synchronisierung nicht aktiviert +explorer.sync.setNow=Richten Sie jetzt die Synchronisation ein +explorer.sync.error=Upload fehlgeschlagen +explorer.sync.success=Erfolgreiche Synchronisation +explorer.sync.statusScan=Scannen +explorer.sync.statusNone=Die Synchronisierung ist nicht konfiguriert +explorer.sync.statusScanEnd=Scan abgeschlossen +explorer.sync.statusDoing=Synchronisierung +explorer.sync.statusDone=Synchronisierung abgeschlossen +explorer.sync.statusStop=Pause +explorer.sync.clearCacheSuccess=Cache löschen erfolgreich! +explorer.sync.emptyTask=Keine Synchronisationsaufgabe +explorer.sync.openCloud=Öffnen Sie den Cloud-Speicherort +explorer.sync.openLocal=Lokal öffnen +explorer.sync.statusFiles=Dokumentieren Sie den Fortschritt +explorer.sync.statusLastTime=Fertigstellungszeit +explorer.sync.configName=Synchronisieren Sie die Einstellungen +explorer.sync.configClient=Client-Einstellungen +explorer.sync.configAbout=Über +explorer.sync.configSyncFrom=Lokaler Pfad +explorer.sync.configSyncFromDesc=Wählen Sie einen lokalen Ordner für die Synchronisierung aus +explorer.sync.configSyncTo=Synchronisieren mit +explorer.sync.configSyncToDesc=Mit Serverstandort synchronisieren +explorer.sync.configIgnore=Ignorierte Dateitypen +explorer.sync.configIgnoreDesc=Dateien dieses Typs werden nicht synchronisiert +explorer.sync.autorun=Selbststartend +explorer.sync.configThread=Anzahl gleichzeitiger Threads +explorer.sync.configThreadDesc=Anzahl der gleichzeitig hochgeladenen Dateien +explorer.sync.configDownloadPath=Pfad herunterladen +explorer.sync.configDownloadPathDesc=Standard-Downloadpfad beim Herunterladen von Dateiordnern +explorer.sync.configClearCacheAuto=Cache automatisch leeren +explorer.sync.configClearCacheAutoDesc=Cache-Datei vor N Tagen automatisch löschen +explorer.sync.configClearCache=Cache leeren +explorer.sync.configChangeSite=Beenden Sie die aktuelle Site +explorer.sync.configVersion=Aktuelle Version +explorer.sync.configUpdateDesc=Update Anweisungen +explorer.sync.configUpdateCheck=Aktualisierungen erkennen +explorer.sync.confirmReset=Verzeichnisänderung synchronisieren, Synchronisierungsinformationen werden zurückgesetzt. Sind Sie sicher, dass Sie speichern möchten? +explorer.sync.listClearDone=Entleerung abgeschlossen +explorer.sync.listClearError=Fehlerliste löschen +explorer.sync.listRetryAll=Wiederholen Sie alle +explorer.async.tipsDisablePath=Unterstützt nicht die Auswahl der Synchronisierung des Pfads +explorer.async.tipsIsMoving= +explorer.async.tipsStartUser=Starten Sie die Synchronisation manuell +explorer.download.title=Download-Management +explorer.download.waiting=Warten +explorer.download.stop=Download anhalten +explorer.download.start=Starte Download +explorer.download.remove=Aufgabe entfernen +explorer.download.stopAll=Alles pausieren +explorer.download.startAll=Fahren Sie alle fort +explorer.download.clearAll=Löschen Sie alle Aufgaben +explorer.download.doing=wird bearbeitet +explorer.download.done=Download abgeschlossen +explorer.download.clearAllTips=Sind Sie sicher, alle Download-Aufgaben zu löschen? +explorer.tag.name=Datei-Tag +explorer.tag.edit=Etikettenverwaltung +explorer.tag.add=Etikett erstellen +explorer.tag.remove=Möchten Sie dieses Tag wirklich löschen? +explorer.tag.inputHolder=Bitte geben Sie einen Labelnamen ein +explorer.tag.addTo=Bezeichnung setzen +explorer.tag.default1=Lernen +explorer.tag.default2=Testdaten +explorer.tag.default3=Vertrag +explorer.tag.filter=Nach Label filtern +explorer.groupTag.title=Öffentliches Label +explorer.groupTag.menuTtitle=Öffentliches Label der Abteilung +explorer.groupTag.titleDesc=Öffentliches Label innerhalb der Abteilung +explorer.groupTag.empty= +explorer.tag.pathDesc=Nach persönlichem Label filtern +explorer.groupTag.pathDesc=Nach öffentlichem Label der Abteilung filtern +explorer.groupTag.removeTypeTips=Möchten Sie diese Gruppe wirklich löschen? Alle mit dem Label verknüpften Dokumente werden nach dem Löschen entfernt! +explorer.groupTag.removeTagTips=Möchten Sie das Tag wirklich löschen? Das mit dem Tag verknüpfte Dokument wird nach dem Löschen entfernt! +explorer.groupTag.typeAdd=Kategorie hinzufügen +explorer.groupTag.typeName=Kategoriename +explorer.groupTag.addDesc=Nach dem Hinzufügen von Tags werden Abteilungs-Tags automatisch aktiviert und die maximale Anzahl von Tags beträgt 1000 +explorer.panel.info=Attribute +explorer.panel.version=Ausführung +explorer.panel.chat=diskutieren +explorer.panel.log=dynamisch +explorer.panel.meta=Metadaten +explorer.panel.chatName=Diskussion austauschen +explorer.panel.chat.send=senden +explorer.panel.chat.noAuth=Sie haben keine Berechtigung, dieses Dokument zu kommentieren! +explorer.panel.chat.placeholder=Geben Sie hier [Enter] zum Senden, [Strg + Enter] Zeilenvorschub ein +explorer.panel.chat.placeholderCtrl=Geben Sie hier ein, Strg + Eingabetaste zum Senden, Eingabetaste zum Umschließen +explorer.panel.chat.reply=Antworten +explorer.panel.chat.empty=kein Kommentar +explorer.panel.chat.sendTo=Nach vorne +explorer.panel.metaName=Metadatenerweiterung +explorer.panel.metaDesc=Erweiterte Dokumentfeldeigenschaften +explorer.panel.thumbClear=klares Vorschaubild +explorer.panel.thumbClearDesc=Löschen Sie Datei-Miniaturansichten, Cover-Art zum Regenerieren. +explorer.panel.historyName=historische Version +explorer.panel.historyDesc=Versionshinweise +explorer.panel.infoTips=Wählen Sie die Datei (den Ordner) aus, um detaillierte Eigenschaften anzuzeigen +explorer.panel.info.space=Raumkapazität +explorer.panel.info.groupAt=Standort der Abteilung +explorer.panel.info.tagEmpty=Keine Tags, klicken Sie auf Einstellungen +explorer.panel.logName=Dokumentnachrichten +explorer.panel.logEmpty=Keine Aktivität +explorer.type.doc=Doc +explorer.type.image=Bild +explorer.type.music=Musik- +explorer.type.movie=Video +explorer.type.zip=Archiv +explorer.type.others=andere +explorer.secret.title=Verwaltung der Vertraulichkeit von Dokumenten +explorer.secret.isOpen=Ob zu aktivieren +explorer.secret.isOpenDesc=Aktivieren und deaktivieren Sie die Sicherheitsstufenverwaltung +explorer.secret.setUser=geheimer Verwalter +explorer.secret.setUserDesc=Bestimmen Sie den Benutzer, der die Vertraulichkeitsstufe festlegen kann (muss gleichzeitig Inhaber in der entsprechenden Abteilung sein) +explorer.secret.type=Klassifizierungstyp +explorer.secret.add=Sicherheitsstufe hinzufügen +explorer.secret.edit=Sicherheitsstufe bearbeiten +explorer.secret.name=Klassenname +explorer.secret.style=Stil +explorer.secret.auth=Berechtigung auf geheimer Ebene +explorer.secret.authHas=Vertrauliche Berechtigungen umfassen +explorer.secret.createUser=Setter +explorer.secret.folderAt=vertraulicher Ordner +explorer.secret.tips=Die Berechtigungen werden durch die geheime Ebene gesteuert, und die Berechtigungen der geheimen Ebene sind höher als die Dokumentberechtigungen +explorer.secret.tips1=Nur für die Inhalte unter der Abteilungs-Netzwerkfestplatte kann der oben angegebene Benutzer die Vertraulichkeitsstufe festlegen (und muss gleichzeitig Ordnerbesitzer sein) +explorer.secret.tips2=Alle Inhalte in der unteren Ebene des Ordners mit der Vertraulichkeitsstufe sind festgelegt, und diese Autorität ist die höchste Autorität +explorer.secret.tips3=Nach der Einstellung ist die Berechtigung der Geheimstufe höher als die Dokumentberechtigung (das Dokument wird auch durch die Berechtigung der Geheimstufe gesteuert, der Superadministrator des Systems unterliegt dieser Einschränkung nicht und der Setter der Geheimstufe unterliegt dieser Einschränkung nicht). +explorer.secret.tips4=Berechtigungen auf vertraulicher Ebene: können in „Abteilungs- und Mitgliederverwaltung – Dokumentrechteverwaltung“ hinzugefügt und als ausgeblendet festgelegt werden +user.----=---- +user.displayHideFile=Versteckte Dateien anzeigen +user.displayHideFileDesc=Versteckte Dateien: Dateien, die mit. Beginnen, und versteckte Dateinamen, die im Hintergrund des Systems festgelegt sind. Versteckte Dateien werden nach dem Öffnen angezeigt. +user.soundOpen=Ton einschalten +user.animateOpen=Animation starten +user.recycleOpen=Öffnen Sie den Papierkorb +user.recycleDesc=Nach dem Öffnen wird Löschen in den Papierkorb verschoben. Es wird empfohlen, es zu öffnen +user.animateDesc=Animationen wie das Öffnen von Fenstern können Sie in Betracht ziehen, wenn der Vorgang nicht reibungslos ist +user.soundDesc=Dateien öffnen, Dateien löschen, Papierkorb leeren usw. +user.thumbOpen=Öffnen Sie das Miniaturbild +user.thumbDesc=Besseres Bild-Browsing nach dem Öffnen +user.fileSelect=Dateisymbol öffnen +user.fileSelectDesc=Klicken Sie mit der linken Maustaste auf das Dateisymbol und wählen Sie die Verknüpfung zum Kontextmenü +user.fileShowDesc=Ordnereinführung anzeigen +user.fileShowDescTips=Nur-Symbol-Modus +user.fileOpenClick=Öffnen Sie die Datei (Ordner) wie folgt +user.fileOpenClick.dbclick=Mit Doppelklick öffnen +user.fileOpenClick.click=Durch Anklicken öffnen +user.viewSetting=Optionen anzeigen +user.thirdAccount=Drittanbieter-Konto +user.bindAccount=Konto binden +user.thirdBindFirst=Konto wurde nicht gebunden, bitte nach dem Binden verwenden +user.account=Konto +user.bind=Binden +user.unbind=Lösen +user.binded=Gebunden +user.clickBind=Klicken Sie auf Binden +user.clickToBind=Ungebunden, klicken Sie auf Binden +user.clickEditPwd=Klicken Sie auf Kennwort ändern +user.userAvatar=Profilbild +user.userNickName=Persönlicher Spitzname +user.userAccount=Persönliches Konto +user.uploadAvatar=Avatar hochladen +user.userAvatarCrop=Bitte wählen Sie einen geeigneten Bereich als Avatar +user.userAvatarExt=Unterstützt nur JPG-, JPEG- und PNG-Bildformate +user.resetPwdDesc=Sie haben Ihr Passwort vergessen? +user.inputEmailCode=Bitte geben Sie Ihren E-Mail-Bestätigungscode ein +user.inputSmsCode=Bitte geben Sie den SMS-Bestätigungscode ein +user.emailVerifyDesc=Einige Unternehmen benötigen eine E-Mail-Bestätigung +user.phoneVerifyDesc=In einigen Unternehmen ist eine Handyüberprüfung erforderlich +user.bindOthers=Bereits an ein anderes Konto gebunden +user.notBind=Noch nicht gebunden +user.regist=Benutzerregistrierung +user.notRegist=Nicht registriert +user.registed=Bereits registriert +user.signError=Rückrufsignatur ist falsch +user.repeat=Wiederholen +user.noRepeat=Kann nicht wiederholen +user.newPwd=Neues Passwort +user.unAuthFile=Nicht autorisierter Dateizugriff +user.unbindWarning=Bitte ändern Sie das Passwort, bevor Sie die Bindung aufheben, da sonst das Konto nicht ordnungsgemäß funktioniert +user.isLoginTips=Es wird festgestellt, dass Sie gerade angemeldet sind! +user.isLoginEnter=Jetzt eingeben +user.ifUnbind=Sind Sie sicher, dass Sie die Bindung aufheben möchten? +user.bindFirst=Bitte binden Sie zuerst Ihre E-Mail oder Handynummer ein +user.inputNewPwd=Bitte geben Sie ein neues Passwort ein +user.inputNewValue=Bitte geben Sie den neuen Inhalt ein +user.guestLogin=Touristisches Login +user.name=Login-Konto +user.nickName=Benutzername +user.code=Bestätigungscode +user.codeError=Fehler beim Bestätigungscode +user.imgCode=Captcha +user.rootPwd=Legen Sie das Administratorkennwort fest +user.rootPwdRepeat=Bestätigen Sie das Passwort erneut +user.rootPwdEqual=Die Passwörter stimmen nicht zweimal überein! +user.rootPwdTips=Bitte legen Sie ein Administrator-Passwort fest! +user.pwdError=Benutzername oder Passwort ist falsch! +user.pwdNotNull=Passwort darf nicht leer sein! +user.oldPwdError=Das ursprüngliche Passwort ist falsch! +user.keepPwd=Passwort merken +user.forgetPwd=Passwort vergessen +user.directLogin=Melden Sie sich mit einem Konto an +user.moreLogin=Weitere Möglichkeiten zum Anmelden +user.loginNow=Melden Sie sich jetzt an +user.registNow=Melde dich jetzt an +user.backHome=Zurück nach Hause +user.ifHasAccount=Hast du schon einen Account? +user.userEnabled=Konto ist deaktiviert oder noch nicht aktiviert! Bitte wenden Sie sich an den Administrator +user.roleError=Die Berechtigungsgruppe existiert nicht, bitte wenden Sie sich an den Administrator +user.invalidEmail=Sie haben keine gültige E-Mail-Adresse. Wenden Sie sich zum Ändern an den Administrator +user.codeRefresh=Klicken Sie auf Aktualisieren +user.emailVerify=Mailbox-Authentifizierung +user.sendSuccess=Erfolgreich gesendet +user.sendFail=Senden fehlgeschlagen +user.sendSuccessDesc=Bestätigungscode erfolgreich gesendet, bitte gehen Sie zur Ansicht +user.sendFailDesc=Bestätigungscode konnte nicht gesendet werden. Wenden Sie sich an den Administrator +user.inputVerifyCode=Bitte geben Sie den Bestätigungscode ein +user.getCode=Bestätigungscode abrufen +user.inputPwd=Bitte geben Sie das Passwort ein +user.inputPwdAgain=Bitte geben Sie das Passwort erneut ein +user.inputNickName=Bitte geben Sie einen Spitznamen ein +user.inputEmail=Bitte geben Sie Ihre E-Mail-Adresse ein +user.inputPhone=Bitte geben Sie Ihre Telefonnummer ein +user.inputPhoneEmail=Bitte geben Sie Handy / Email ein +user.invalidPhoneEmail=Ungültiges Telefon / Email +user.findPwd=Passwort abrufen +user.inputNotMatch=Das eingegebene %s stimmt nicht mit der Grenze überein +user.usingDesc=Sie benutzen +user.improveInfo=Bitte vervollständigen Sie die Angaben +user.codeExpired=Der Bestätigungscode ist abgelaufen. Bitte holen Sie ihn erneut +user.codeErrorTooMany=Zu viele Fehler beim Bestätigungscode, bitte neu erwerben +user.codeErrorFreq=Die Sendefrequenz ist zu hoch, bitte versuchen Sie es später noch einmal! +user.codeErrorCnt=Die Anzahl der Sendungen hat das Limit überschritten und wird für %s Stunden gesperrt. +user.registSuccess=Erfolgreich registriert +user.waitCheck=Warten auf Überprüfung durch den Administrator +user.nameHolder=Bitte geben Sie Ihre Telefonnummer / E-Mail-Adresse ein +user.loginNoPermission=Entschuldigung, Sie haben diese Berechtigung nicht, bitte melden Sie sich mit einem Konto mit dieser Berechtigung an! +user.loginFirst=Sie sind nicht angemeldet! Bitte loggen Sie sich zuerst ein +user.bindSignError=Die Signatur ist abnormal. Bitte versuchen Sie es erneut. +user.bindUpdateError=Aktualisierung der Benutzerinformationen fehlgeschlagen. Bitte versuchen Sie es erneut +user.bindTypeError=Ungültiger Bindungstyp +user.bindWxConfigError=Konfigurationsinformationsausnahme abrufen +user.loginTimeout=Die aktuelle Anmeldung ist abgelaufen, bitte melden Sie sich erneut an! +user.theme=Themenstil +user.theme.desc=Automatisches repräsentatives Folgesystem +user.theme.light=Helle Farbe +user.theme.dark=Dunkle Farbe +user.theme.auto=automatisch +user.theme.title=Benutzerdefinierte Designeinstellungen +user.theme.background=Hintergrund +user.theme.image=Bilder +user.theme.colorBlur=Farbverlauf +user.theme.imageBlur=Bildunschärfe Verarbeitung +user.theme.imageUrl=Bildadresse +user.theme.colorStart=Starten Sie die Farbe +user.theme.colorEnd=Endfarbe +user.theme.colorRadius=Steigungswinkel +user.theme.themeImage=Hintergrundbild +user.theme.themeImageDesc=Unterstützung: Bild-URL, CSS-Verlaufsfarbe, Hintergrundbild folgen +user.theme.imageWall=Folgen Sie dem Hintergrundbild +user.wall.random=Zufälliges Hintergrundbild +user.wall.paperDesktop=Desktop-Hintergründe +user.wall.paperDeskMgt=Desktop-Hintergrundverwaltung +user.wall.paperLoginMgt=Login Wallpaper Management +user.wall.paperLoginTips=Wenn mehr als ein Bild vorhanden ist, wird der Hintergrund der Anmeldeschnittstelle zufällig gedreht +log-type-create-mkdir=neuer Ordner +log-type-create-mkfile=Erstellen Sie eine neue Datei +log-type-create-upload=Daten hochladen +log-type-create-copy=Datei einfügen +log-type-edit=Update-Datei +log-type-move=Datei bewegen +log-type-moveOut=Dateien entfernen +log-type-share-shareLinkAdd=Erstellt eine externe Linkfreigabe +log-type-share-shareToAdd=Kollaboratives Teilen aktiviert +log-type-share-shareLinkRemove=Freigabe geschlossener Links +log-type-share-shareToRemove=Deaktivieren Sie die kollaborative Freigabe +log-type-share-shareEdit=Freigabe bearbeiten +log-type-rename=Umbenennen +log-type-recycle-toRecycle=Zum Papierkorb gehen +log-type-recycle-restore=Aus dem Papierkorb wiederherstellen +log-type-remove=löschen +log-type-addDesc=Beschreibung ändern +log-type-addComment=Einen Kommentar posten +log-event-create-mkdir=Erstellt diesen Ordner +log-event-create-mkfile=Erstellt die Datei +log-event-create-upload=Datei hochgeladen +log-event-create-copy=Die Datei wurde durch Einfügen erstellt +log-event-create-mkdir-current=Erstellt hier einen neuen Ordner {0} +log-event-create-mkfile-current=Neue Datei hier erstellt {0} +log-event-create-upload-current=Hier hochgeladen {0} +log-event-create-copy-current=Hier {0} eingefügt +log-event-create-mkdir-item=Erstellt einen neuen Ordner in {0} {1} +log-event-create-mkfile-item=Neue Datei erstellt in {0} {1} +log-event-create-upload-item=Hochgeladen {1} auf {0} +log-event-create-copy-item=Fügen Sie {0} bis {1} ein. +log-event-create-mkdir-more=Hier wurden {0} Ordner erstellt +log-event-create-mkfile-more={0} Hier wurden neue Dateien erstellt +log-event-create-upload-more={0} hier hochgeladene Dateien +log-event-create-copy-more=Hier wurden {0} Dateien eingefügt +log-event-create-mkdir-more-at=Erstellt {1} neue Ordner in {0} +log-event-create-mkfile-more-at=Erstellt {1} neue Dateien in {0} +log-event-create-upload-more-at={1} Dateien hochgeladen auf {0} +log-event-create-copy-more-at=Einfügen von {0} Dokumenten in {1} +log-event-view-item=Gesehen {0} +log-event-edit=die Datei aktualisiert +log-event-edit-item=Bearbeiten aktualisiert {0} +log-event-edit-more=Aktualisierte {0} Dateien bearbeiten +log-event-edit-more-user=Die Datei wurde {0} {1} mal bearbeitet und aktualisiert +log-event-edit-more-at=Bearbeitete und aktualisierte {1} Dateien in {0} +log-event-move=Verschieben Sie das Dokument von {0} nach {1}. +log-event-move-item=Verschiebe {0} von {1} nach [3] +log-event-move-current=Bewegen Sie {0} von {1} hierher +log-event-move-more={0} Dokumente verschoben +log-event-move-more-desc=Verschiebe {0} von {1} nach [3] +log-event-moveOut-more-desc=Entfernt aus {0} {1} +log-event-moveOut=Von hier entfernt {0} +log-event-moveOut-item=Entfernt aus {0} {1} +log-event-moveOut-more={0} Dokumente entfernt +log-event-share-shareLinkAdd=Erstellt einen externen Link, um dieses Dokument freizugeben +log-event-share-shareLinkAdd-item={0} hat einen externen Link zum Teilen erstellt +log-event-share-shareLinkAdd-more=Erstellt {0} Links zum Teilen +log-event-share-shareToAdd=Aktivieren Sie die gemeinsame Freigabe dieses Dokuments +log-event-share-shareToAdd-item={0} hat das kollaborative Teilen aktiviert +log-event-share-shareToAdd-more={0} kollaborative Freigaben erstellt +log-event-share-shareLinkRemove=Die Linkfreigabe des Dokuments wurde geschlossen +log-event-share-shareLinkRemove-item=Link-Sharing von {0} geschlossen +log-event-share-shareLinkRemove-more=Schließen Sie {0} die Freigabe externer Links +log-event-share-shareToRemove=Deaktivieren Sie die gemeinsame Freigabe dieses Dokuments +log-event-share-shareToRemove-item=Deaktivieren Sie die gemeinsame Nutzung von Kollaborationen für {0}. +log-event-share-shareToRemove-more=Schließen Sie {0} kollaboratives Teilen +log-event-share-shareEdit=Die Freigabe dieses Dokuments wurde bearbeitet +log-event-share-shareEdit-item=Der Anteil von {0} wurde bearbeitet +log-event-share-shareEdit-more=Bearbeitete {0} Dokumente zum Teilen +log-event-rename=Dokument umbenannt +log-event-rename-item=Umbenannt {0} +log-event-rename-more={0} Dokumente umbenannt +log-event-recycle-toRecycle=Das Dokument wurde in den Papierkorb verschoben +log-event-recycle-toRecycle-current=Hier {0} in den Papierkorb verschoben +log-event-recycle-toRecycle-item={1} auf {0} in den Papierkorb verschoben +log-event-recycle-toRecycle-more={0} Dokumente in den Papierkorb verschoben +log-event-recycle-toRecycle-more-at={1} Dokumente wurden auf {0} in den Papierkorb verschoben. +log-event-recycle-restore=Stellen Sie das Dokument aus dem Papierkorb wieder her +log-event-recycle-restore-item=Stellen Sie {0} aus dem Papierkorb wieder her +log-event-recycle-restore-more=Stellen Sie {0} Dokumente aus dem Papierkorb wieder her +log-event-remove=Hier {0} gelöscht +log-event-remove-current=Hier {0} gelöscht +log-event-remove-item={1} in {0} gelöscht +log-event-remove-more={0} hier gelöschte Dokumente +log-event-remove-more-at=Gelöschte {1} Dokumente zu {0} +log-event-addDesc=Die Dokumentbeschreibung wurde geändert +log-event-addDesc-item=Geänderte {0} Dokumentbeschreibung +log-event-addDesc-more=Geänderte {0} Dokumentbeschreibungen +log-event-addComment=Dieses Dokument kommentiert +log-event-addComment-item=Kommentiert zu {0} +log-event-addComment-more=Gelistete {1} Kommentare in {0} +log-event-fav-fileAdd=Lesezeichen {0} +log-event-fav-dirAdd=Mit Lesezeichen versehene Ordner {0} +log-event-down-item=Heruntergeladen {1} von {0} +log-event-down-items=Heruntergeladen von {0} +log-event-recycle-del-item=Löschen Sie {0} Dateien aus dem Papierkorb +log-event-recycle-rst-item=Stellen Sie {0} Dateien aus dem Papierkorb wieder her +log-event-del-item={0} Dateien gelöscht +log.file.move=Verschieben / kopieren +log.file.fav=Favoriten Betrieb +log.file.shareLink=Externe Linkfreigabe +log.file.shareTo=Kollaboratives Teilen +log.user.edit=Kontoinformationen ändern +log.group.edit=Abteilungsleitung +log.member.edit=Benutzerverwaltung +log.role.edit=Rollenverwaltung +log.auth.edit=Verwaltung von Dokumentenrechten +meta.user_sourceAlias=Verwandte Dateien (Anhänge) +meta.user_fileEncodeType=Datei Vertraulichkeit +meta.user_fileEncodeType.A=A-Top geheim +meta.user_fileEncodeType.B=B-vertraulich +meta.user_fileEncodeType.C=C-Geheimnis +meta.user_sourceNumber=Datenträgernummer +meta.user_sourceParticipant=Teilnehmer +explorer.fileInfo.createTime=Erstellungsdatum +explorer.fileInfo.modifyTime=Änderungsdatum +explorer.fileInfo.softwareCreate=Produktionssoftware +explorer.fileInfo.software=Codierungssoftware +explorer.fileInfo.playTime=Spielzeit +explorer.fileInfo.imageSize=Größe des Bildes +explorer.fileInfo.imageDpi=Auflösung +explorer.fileInfo.imageBits=Bittiefe +explorer.fileInfo.imageDesc=Anmerkung +explorer.fileInfo.imageAuthor=Schöpfer +explorer.fileInfo.imageColor=Farbraum +explorer.fileInfo.cameraType=Gerätemodell +explorer.fileInfo.cameraApertureFNumber=Blendenzahl +explorer.fileInfo.cameraApertureValue=Blendenwert +explorer.fileInfo.cameraShutterSpeedValue=Verschlusszeit +explorer.fileInfo.cameraExposureTime=Belichtungszeit +explorer.fileInfo.cameraFocalLength=Brennweite +explorer.fileInfo.cameraFocusDistance=Fokusentfernung +explorer.fileInfo.cameraISOSpeedRatings=ISO-Empfindlichkeit +explorer.fileInfo.cameraWhiteBalance=Weißabgleich +explorer.fileInfo.cameraUser=Handbuch +explorer.fileInfo.cameraAuto=automatisch +explorer.fileInfo.cameraExposureMode=Belichtungsmodus +explorer.fileInfo.cameraExposureBiasValue=Belichtungsausgleich +explorer.fileInfo.imageGps=Drehort +explorer.fileInfo.imageCreateTime=Aufnahmedatum +explorer.fileInfo.audioChannel=Audiokanal +explorer.fileInfo.audioChannel1=Mono +explorer.fileInfo.audioChannel2=Stereo +explorer.fileInfo.audioChannels=Mehrkanal +explorer.fileInfo.audioRate=Audio-Abtastrate +explorer.fileInfo.audioBits=Audio-Bittiefe +explorer.fileInfo.audioBitrate=Audio Bitrate +explorer.fileInfo.vedioFormat=Videokodierung +explorer.fileInfo.audioTitle=Titel +explorer.fileInfo.audioAuthor=Autor +explorer.fileInfo.audioAlbum=Album +explorer.fileInfo.audioStyle=Stil +explorer.fileInfo.audioYear=Albumjahr +explorer.fileInfo.vedioSize=Bildschirmgröße +explorer.fileInfo.vedioFrame=Video-Bildrate +explorer.fileInfo.vedioBitrate=Video-Bitrate +explorer.fileInfo.title=Titel +explorer.fileInfo.author=Autor +explorer.fileInfo.pageTotal=Alle Seiten +explorer.fileInfo.pageSize=Seitengröße +explorer.fileInfo.pagePower=Ersteller von Inhalten +explorer.fileInfo.pdfVersion=PDF-Version +explorer.filter.shareCopyLimit=Die Anzahl der auszugebenden Dateien überschreitet das Limit; die maximale Anzahl an Dateien, die Sie ausgeben können, beträgt: +explorer.filter.shareSizeLimit=Die freigegebene Dateigröße überschreitet das Limit; Sie können maximal Folgendes freigeben: +explorer.filter.unzipSizeLimit=Die Größe der entpackten Datei überschreitet das Limit; Sie können maximal Folgendes entpacken: +explorer.filter.zipSizeLimit=Komprimierte Dateigröße überschreitet Limit; Ihre maximal komprimierbaren Dokumente: +explorer.filter.uploadSizeLimit=Die Upload-Größe überschreitet das Limit. Sie können maximal Folgendes hochladen: +explorer.fileEditError=Die aktuelle Datei %s wird derzeit bearbeitet. Bitte versuchen Sie es später erneut +explorer.groupDelError=Entschuldigung, Abteilungsordner unterstützen das Löschen nicht +admin.info.typeDelError=Löschen fehlgeschlagen mit Unterkategorien oder Daten +admin.info.domainIdentifyError=Unbekannte Website +admin.info.articleIdentifyError=Nicht erkannter Artikel +admin.info.domainSupportError=Diese Website unterstützt derzeit keine Sammlung +admin.info.fileTooLarge=Datei zu groß +explorer.toolbar.info=Informationen in Echtzeit +source.shareDisabled=Die aktuelle Ressource darf nicht geteilt werden +admin.exceeds.limit=Überschreitung der Grenzwerte +admin.design.deleted=Aktivierungsstatus kann nicht gelöscht werden +admin.design.url.locked=Die aktuelle URL ist gesperrt und kann nicht temporär verwendet werden +explorer.SING_INVALID=Unterschriftsausnahme +explorer.TEMP_AUTH_INVALID=Temporärer Autorisierungscode ist ungültig (ungültig) +explorer.QR_INVALID=QR-Code ist abgelaufen +explorer.toolbar.toolbox=Werkzeugkasten +explorer.toolbox.desc= +logs-detail-mkdir=Erstellt einen neuen Ordner +logs-detail-mkfile=Eine neue Datei erstellt +logs-detail-editFile=Der Editor hat aktualisiert +logs-detail-upload=Hochgeladene Dateien +logs-detail-uploadNew=Bearbeitet +logs-detail-file.upload=Hochladen +logs-detail-file-copy=Erstellte Datei einfügen +logs-detail-folder-copy=Erstellten Ordner einfügen +logs-detail-paste=Paste +logs-detail-from=von +logs-detail-to=Reichweite +logs-detail-rename=Umbenannt +logs-detail-rename-file=Datei umbenannt +logs-detail-rename-folder=Ordner umbenannt +logs-detail-user=Benutzer: +logs-detail-moveFrom-restore=nehmen +logs-detail-moveTo-restore=Wiederherstellen aus dem Papierkorb +logs-detail-move=nehmen +logs-detail-moveTo=Verschieben nach +logs-detail-moveFrom-toRecycle=nehmen +logs-detail-moveTo-toRecycle=In den Papierkorb verschoben +logs-detail-file-toRecycle=Verschiebt die Datei in den Papierkorb +logs-detail-file-restore=Wiederherstellen dieser Datei aus dem Papierkorb +logs-detail-folder-toRecycle=Diesen Ordner in den Papierkorb verschoben +logs-detail-folder-restore=Diesen Ordner aus dem Papierkorb wiederherstellen +logs-detail-favAdd=Gesammelt +logs-detail-favDel=Sammlung abgebrochen +logs-detail-unstar=Name: +logs-detail-moveOut=Entfernt +logs-detail-remove=Entfernt +logs-detail-file.copy=Einfügen +explorer.noPermissionAuthAll={0} ,Keine Berechtigung für diesen Vorgang \ No newline at end of file diff --git a/src/main/resources/i18n/messages_en_US.properties b/src/main/resources/i18n/messages_en_US.properties new file mode 100644 index 0000000..73595b0 --- /dev/null +++ b/src/main/resources/i18n/messages_en_US.properties @@ -0,0 +1,2566 @@ +admin.serverInfo=Serverinformation +admin.today=Today +admin.yesterday=Yesterday +admin.weekDay=Last7days +admin.monthDay=Last30days +admin.ing=Processing +admin.paused=Paused +admin.serverDownload=Remotedownload +admin.memberManage=Usermanage +admin.fileManage=Filemanage +admin.pwdEdit=ChangePassword +admin.fileEdit=Edit +admin.list=List +admin.configError=Configurationsavefailed,administratorhasdisabledthispermission! +admin.userManage=Personal +admin.manage=Backend +admin.pluginManage=Plugin +admin.emailDear=Hello%s, +admin.emailCodeText=Youareverifyingyouremailaddress.Theverificationcodeforthisrequestisasfollows.Toensurethesecurityofyouraccount,pleasecompletetheverificationintime. +admin.emailVerifyInTime=Inordertoprotectthesecurityofyouraccount,pleasecompleteverificationintime. +admin.dear=Dear +admin.dearUser=Dearuser, +admin.emailResetLink=Youareresettingtheloginpasswordfor%sviaemail,pleaseclickthelinkbelowtoresetit.Ifthelinkcannotjump,copyittoyourbrowseraddressbartoaccessit: +admin.emailExpireTime=Thelinkexpiresafter20minutes. +admin.jobName=Name +admin.jobDesc=Description +admin.jobNameInput=Pleaseenterajobname +admin.jobEdit=Edit +admin.menu.home=Home +admin.menu.dashboard=Overview +admin.menu.dashboardTitle=Overview +admin.menu.notice=Notice +admin.menu.groupMember=Users&Groups +admin.menu.member=Users&Groups +admin.menu.role=Role +admin.menu.job=Job +admin.menu.auth=DocumentPermission +admin.menu.storage=Storage/file +admin.menu.storageDriver=Storage +admin.menu.plugin=PluginCenter +admin.menu.tools=Safetycontrol +admin.menu.server=Server +admin.menu.backup=Backup +admin.menu.share=Share +admin.menu.loginLog=Loginlog +admin.menu.log=Operationlog +admin.menu.task=ScheduledTasks +admin.autoTask.restart=Restartscheduledtasks +admin.autoTask.restartEnd=Thescheduledtaskhasrestarted +admin.index.userSpace=Userspace +admin.index.groupSpace=Groupspace +admin.index.folderCount=Folders: +admin.index.fileCount=Files: +admin.index.loginToday=Logins +admin.index.useTotal=Total: +admin.index.userLogin=Login +admin.index.spaceUsed=Spaceusage +admin.index.useSpace=Spaceusage +admin.index.usedSpace=Used +admin.index.freeSpace=Free +admin.index.sizeLimit=Limitedsize +admin.index.vipCount=Registrations +admin.index.loginCurrent=Online +admin.index.fileDel=Delete +admin.index.fileEdit=Edit +admin.index.fileUpload=Upload +admin.index.fileDown=Download +admin.index.spaceUse=Actual +admin.index.spaceSave=Saved +admin.index.spaceUser=User +admin.index.spaceGroup=Group +admin.index.lastLogin=Lastlogintime +admin.index.totalUsers=Totalusers +admin.index.loginUsers=Logins +admin.index.spaceActUsed=Actualusage +admin.index.source=Loginsource +admin.index.address=Loginaddress +admin.index.userInfo=User +admin.index.userValid=Valid +admin.index.userInvalid=Invalid +admin.index.fileInfo=File +admin.index.fileCnt=Count +admin.index.fileAdd=Today +admin.index.accInfo=Access +admin.index.accCnt=Requests +admin.index.accUser=Users +admin.index.serverInfo=System +admin.index.serverDisk=Disk +admin.index.serverStore=Storage +admin.index.serverName=Name +admin.index.normal=Normal +admin.index.scoreDesc=Thefollowingfactorswillaffectthesystemscore,whichcanbeoptimizedtoensurethesystemrunswell:
1.Theremainingspaceofsystemdiskandnetworkdiskstorage;
2.Datacachingmethod(redisisrecommended);
3.phpplatformversion(recommended64-bitphp7+). +admin.index.fileRatio=Fileusageratio +admin.setting.system=Systemsettings +admin.setting.account=Account +admin.setting.theme=Theme +admin.setting.wall=Wallpaper +admin.setting.stats=Usagestatistics +admin.setting.safeMgt=Safetymanagement +admin.setting.base=Basic +admin.setting.others=Others +admin.setting.sync=Sync +admin.setting.plugin=Plug-in +admin.setting.auth=Permission +admin.setting.safe=Security +admin.setting.loginLog=Loginlog +admin.setting.loginDevice=Logindevice +admin.setting.deviceType=Equipmenttype +admin.setting.lastLoginTime=Lastlogintime +admin.setting.email=Email +admin.setting.user=Registration +admin.setting.pwdOld=Oldpassword +admin.setting.pwdNew=Changeinto +admin.setting.wallDiy=Customwallpaper: +admin.setting.fav=Starred +admin.setting.help=Help +admin.setting.about=About +admin.setting.homePage=KodcloudHomepage +admin.setting.subMenu=Submenu +admin.setting.menuName=Menuname +admin.setting.menuUrl=URL +admin.setting.menuUrlDesc=Urladdressorjscode +admin.setting.safeAccount=Accountandloginsecurity +admin.setting.safeData=Datasecurity/transmissionsecurity +admin.setting.passwordErrorLock=Passworderrorlock +admin.setting.passwordErrorLockDesc=Ifthepasswordisincorrectfor5consecutivetimes,theaccountwillbelockedfor1minuteandnotallowedtologin.Afteropening,itcaneffectivelypreventthepasswordfrombruteforcecracking; +admin.setting.passwordRule=Passwordstrong +admin.setting.passwordRuleDesc=Theweakpasswordcanbeeffectivelyeliminated +admin.setting.passwordRuleNone=Notlimited +admin.setting.passwordRuleStrong=Mediumintensity +admin.setting.passwordRuleStrongMore=Highstrength +admin.setting.passwordRuleNoneDesc=Unlimitedpasswordstrength +admin.setting.passwordRuleStrongDesc=Lengthisgreaterthan6;mustcontainbothEnglishandnumbers; +admin.setting.passwordRuleStrongMoreDesc=Lengthisgreaterthan6;mustcontainnumbers,uppercaseEnglish,lowercaseEnglish; +admin.setting.passwordRuleTips=Yourcurrentpasswordisnotstrongenough,itisrecommendedtochangethepasswordimmediately! +admin.loginCheck.menu=Logincontrol +admin.loginCheck.ipCheck=IPrestrictions +admin.loginCheck.ipCheckNone=Notlimited +admin.loginCheck.ipCheckAllow=IPwhitelist +admin.loginCheck.ipCheckDisable=IPblacklist +admin.loginCheck.loginIpAllowDesc=Afteropening,onlyuserswiththespecifiedipcanlogin,pleasebecareful +admin.loginCheck.ipAllow=AllowedIP +admin.loginCheck.ipAllowDesc=Fillintherulesasfollows(eachline,theserver'slocalIPisallowedbydefault,andthesystemadministratorallowstheLANIP) +admin.loginCheck.ipDisable=BlacklistIPrules +admin.loginCheck.ipDisableDesc=Afteropening,userswhomeettheipconditionswillnotbeabletodoanyoperations,pleaseproceedwithcaution!
Ifeveryoneisspecified,allrequestswillbeblocked! +admin.loginCheck.ipDescTitle=Fillintherulesasfollows(onelineperentry) +admin.loginCheck.ipDesc=
  • FullIP:matchifequal,forexample:192.168.10.10
  • IPprefix:ipstartswiththeprefixandmatches;forexample:192.168
  • IPrange:ipmatcheswithintherange;forexample:192.168.1.1-192.168.200.255
  • +admin.loginCheck.sort=Priority +admin.loginCheck.name=Rulename +admin.loginCheck.user=Designateduser +admin.loginCheck.device=Designatedequipment +admin.loginCheck.deviceWeb=Web +admin.loginCheck.devicePc=PC +admin.loginCheck.deviceAndroid=Android +admin.loginCheck.deviceIOS=IOS +admin.loginCheck.desc=Userloginrestrictioncontrolinstructions(ipanddevicerestrictions):
  • Detectinsequenceaccordingtothepriorityorderoftherule;theuserspecifiedbytheruleincludesthecurrentlylogged-inuser;thentheruleisdeterminedastheresult
  • Itisrecommendedtoputusergroupsanddepartmentalusersontheback,andspecifyusersettingsonthefront;(draganddroptoadjusttheorder)
  • +admin.setting.checkCode=Needverification +admin.setting.checkCodeDesc=Loginrequiresaverificationcodewhenenabled +admin.setting.csrfProtect=Enablecsrfprotection +admin.setting.csrfProtectDesc=Caneffectivelypreventcsrfattackswhenenabled +admin.setting.setRootPath=Rootaccess +admin.setting.setRootPathDesc=Onlythesystemadministratorcanaccessalldirectories
    Ifyouwanttoenableordisableadministratoraccesstootherdirectories,youcanmodifythePHPcross-siteopen_basedirparameter,howtoset +admin.setting.encode=Fileencryption +admin.setting.encodeAll=Encryptall +admin.setting.encodeName=Keeptheextension +admin.setting.encodeNone=Noencryption +admin.setting.encodeAllDesc=Fullencryption:[defaultrecommendation];evenifyouhaveserverpermissions,youcan��tknowthetruecontentofthefile;itcaneffectivelyprotectagainstransomwareandotherdamages; +admin.setting.encodeNameDesc=Retainextension:filenameencryption,retainextension +admin.setting.encodeNullDesc=Noencryption:thefilenameisnotencrypted,andtheoriginalfilenameisretained;(toensuresecurity,theuploadfolderisnamedencryptedstructure); +admin.setting.encodeTips1=Onlythefilesafterthesettingchangeareaffected,thefilesthathaveexistedbeforearenotaffected; +admin.setting.encodeTips2=Toavoiderrors,pleasedonotdeleteorrenamefilesindata/files; +admin.setting.encodeTips3=Tosupportlarge-scaleconcurrency,secondtransmission,clustering,distribution,automaticexpansionandotherfunctions;thefolderhierarchyisrecordedinthedatabase;thefolderstructurecanbeimportedandrestoredbycopyingandpasting +admin.setting.thirdLogin=Thirdpartylogin +admin.setting.thirdLoginDesc=Allowregistration,bindingandloginthroughthird-partyaccounts +admin.setting.registOpen=Enableregistration +admin.setting.registOpenDesc=Toavoidconflicts,third-partysyncandregistrationcannotbeenabledatthesametime +admin.setting.registCheck=Registrationreview +admin.setting.registCheckDesc=Theadministratorneedstoreviewandenableitin[Users&Groups]forregistereduserstousenormally +admin.setting.clearUserRecycle=Emptyalluserrecyclebins +admin.setting.clearCache=Emptythecache +admin.setting.icp=Copyright +admin.setting.icpDesc=Ifyouneedtogeneratealink,youcanaddatagyourself +admin.setting.globalCss=Customglobalcss +admin.setting.globalCssDesc=Allpageswillinsertcustomcss +admin.setting.globalHtml=StatisticalCode +admin.setting.globalHtmlDesc=Allpageswillinsertthishtmlcode,andthird-partystatisticscodecanbeplaced +admin.setting.dateFormat=Dateformat +admin.setting.dateFormatDesc=Year-month-daytimeformatdisplay,filemodificationtime,etc. +admin.setting.menu=Menu +admin.setting.systemName=CompanyName +admin.setting.systemNameDesc=Forproductlogotitle +admin.setting.systemDesc=ProductSubtitle +admin.setting.pathHidden=Directoryexclusion +admin.setting.pathHiddenDesc=Hiddenfiles,separatedbycommas +admin.setting.defaultFolder=Defaultdirectories +admin.setting.defaultFolderDesc=Separatedbycommas +admin.setting.defaultApp=Defaultapps +admin.setting.defaultAppDesc=Applicationcenterapplications,multipleseparatedbycommas +admin.setting.autoLogin=Automaticlogin +admin.setting.autoLoginDesc=Thedefaultloginuseristheguest/guestuser;makesurethisuserexistsafteropening +admin.setting.firstIn=Logintodefault +admin.setting.registReviewOpen=Enabledregistrationaudit: +admin.setting.registRoleEmpty=Rolecannotbeempty +admin.setting.registNotSync=Toavoiddataconflicts,third-partydatasynchronizationanduserregistrationcannotbeenabledatthesametime +admin.setting.registNeedRewiew=Afteritisopened,theadministratorneedstoreviewandenableitintheusersandgroupsforregistereduserstouse +admin.setting.roleRight=Role +admin.setting.emailHost=Mailboxserver +admin.setting.emailHostInput=Pleaseenterthemailserveraddress +admin.setting.emailHostTips=Pleaseenterthemailserveraddress +admin.setting.emailHostDesc=Mailboxserver,suchas:smtp.163.com,theportcanbecustomized(thedefaultis465) +admin.setting.emailSend=Outbox +admin.setting.emailSendInput=Pleaseentertheemailaddress +admin.setting.emailSendTips=Pleaseenterthesendingemailaddress +admin.setting.emailSendDesc=Systememailaddress,POP3/SMTPserviceneedstobeenabled +admin.setting.emailPwd=Authorizationpassword +admin.setting.emailPwdTips=Pleasefillintheemailauthorizationpassword +admin.setting.secureType=Encryption +admin.setting.emailSendTest=Senddetection +admin.setting.ensureEmailOk=Pleasemakesurethemailcanbesentnormally +admin.setting.emailTo=Inbox +admin.setting.emailGoToTips=Pleasegotothemailbox +admin.setting.emailCheckTips=View +admin.setting.emailInputError=Incorrectemailsettings +admin.setting.emailPwdError=E-mailsettingpasswordisincorrect +admin.setting.emailDesc=Mailserverforuserregistration,passwordrecovery. +admin.setting.sendEmail=Sendemail +admin.setting.sendEmailDesc=Systemdefault:calltosendcloudmailservertosend;custom:configuremailserverbyyourself +admin.setting.systemBackup=Systembackup +admin.setting.enableFunction=Functionsandswitches +admin.setting.treeOpen=Treedirectoryfunctionswitch +admin.setting.treeOpenDesc=Filemanagement,treedirectorycorrespondingfunctiongloballyturnedonandoff +admin.setting.groupListChild=Listsub-sectors +admin.setting.groupListChildDesc=Whetherthedepartmentfoldershowssub-departments,permissionsareinheritedupwards +admin.setting.groupRootListChild=Listssub-sectors(Root) +admin.setting.groupRootListChildDesc=Whetherthecorporatenetworkdiskfolderdisplayssub-departmentsandpermissionsareinheritedupwards +admin.setting.shareToMeAllowTree=Collaboratewithme-showbyorganizationstructure +admin.setting.shareToMeAllowTreeTips=Afteropening,thecontentsupportforcollaborationwithmeisclassifiedaccordingtotheorganizationalstructureofthedepartment,whichissuitableforsituationswheretheorganizationalstructureismorecomplex +admin.setting.groupTagAllow=Departmentpubliclabel +admin.setting.groupTagAllowTips=Afterenabling,alldepartmentmemberswillbevisibleaftersettingthepubliclabelforthefilesinthedepartment.Thedepartmentadministratorcanmaintainthelabelcontent. +admin.setting.shareToMeList=Listall +admin.setting.shareToMeGroup=Byorganization +admin.setting.shareToMeUser=Bysharer +admin.setting.sysSrvState=Serverstatus +admin.setting.sysSrvInfo=Serverinformation +admin.setting.sysPhpInfo=PHPinformation +admin.setting.database=Database +admin.setting.cache=Cache +admin.setting.sysMyInfo=Myinformation +admin.setting.srvStateCpu=CPUusage +admin.setting.srvStateMem=Memoryusage +admin.setting.srvStateSrv=Serversystemstoragespace +admin.setting.srvStateDef=Systemdefaultstoragespace +admin.setting.srvInfoName=Servername +admin.setting.srvInfoIp=ServerIP +admin.setting.srvInfoTime=Servertime +admin.setting.srvInfoUpTime=Continuousrunningtime +admin.setting.srvInfoWeb=Serversoftware +admin.setting.srvInfoPhpV=PHPversion +admin.setting.srvInfoSys=Serversystem +admin.setting.srvInfoPath=Sitepath +admin.setting.srvPhpDtl=PHPdetails +admin.setting.memLimit=Memorylimit +admin.setting.postLimit=POSTsubmissionlimit +admin.setting.uploadLimit=Uploadfilerestrictions +admin.setting.execTime=Maximumexecutiontime +admin.setting.inputTime=Maximumrequesttime +admin.setting.disFunction=Disablefunction +admin.setting.phpExtSugst=RecommendedPHPextensions +admin.setting.phpExtLoad=Loadedextension +admin.setting.myClientIp=MyIP +admin.setting.myClientUa=MybrowserUA +admin.setting.myClientLng=Mybrowserlanguage +admin.setting.disFuncDesc=Functionsrequiredbythesystem,itisrecommendedtoenable +admin.setting.srvMemFree=Remainingmemory +admin.setting.srvMemUse=Usememory +admin.setting.srvCpuUse=Currentlyoccupied +admin.setting.srvCpuFree=Unused +admin.setting.noLimit=Unlimited +admin.setting.disFunNo=No +admin.setting.systemCache=Systemcache +admin.setting.systemDb=Systemdatabase +admin.setting.sysCacheTab=Cacheswitch +admin.setting.sysDbTab=Databaseswitch +admin.setting.sysRecTab=Databaserecovery +admin.setting.cacheDesc=Cachedescription +admin.setting.fileCacheDesc=Filecache:Writedatadirectlytothecachefile,suitablefortestingorsmall-scaleuse. +admin.setting.redisDesc=Redis:Ahigh-performancekey-valuenon-relationaldatabase,suitableforhighconcurrentreadandwritesituations.RecommendedUse. +admin.setting.memcachedDesc=Memcached:Ahigh-performancedistributedmemoryobjectcachesystem,suitableforhighconcurrentreads. +admin.setting.saveAfterTest=Afterthetestispassed,itcanbesaved +admin.setting.checkPassed=Passed +admin.setting.ifSaveCache=Afterswitching,allcacheddatawillbecleared!
    Areyousureyouwanttoexecute? +admin.setting.ifSaveDb=Thedatabaseswitchwillimportthecurrentdataofthesystemintothenewdatabaseandsetitasthedefault.Areyousureyouwanttoexecuteit? +admin.setting.dbCurrent=Currentconfiguration +admin.setting.dbType=Databasetype +admin.setting.dbName=Namedatabase +admin.setting.dbInfo=Databaseinformation +admin.setting.dbSwitch=Switchon +admin.setting.dbSwitchDesc=Afteropening,youcanchangethedatabasetypeasneeded,pleaseoperatewithcaution. +admin.setting.dbTable=Datasheet +admin.setting.dbCnt=Total +admin.setting.dbNeedNew=Thedatabasealreadyexists,pleasere-specify +admin.setting.dbInsertError=Failedtowritetabledata +admin.setting.dbNeedOthers=Pleaseselectanotherdatabasetype +admin.setting.dbNeedChange=Pleasemodifytheconfigurationparameters +admin.setting.dbCreateError=Databasefilecreationfailed,pleasecheckthedirectoryreadandwritepermissions +admin.setting.dbTaskProcess=Executionprogress +admin.setting.dbTasking=Beingexecuted +admin.setting.dbTaskDesc=Donotclosethewindoworperformotheroperationsinthesystemtoavoidgeneratingdiscrepancydata. +admin.setting.recTaskDesc=Donotclosethewindow.Aftertherequestisinterrupted,thebackgroundwillcontinuetoexecuteuntilthetaskends. +admin.setting.dbCreate=Newdatabase +admin.setting.dbSelect=Readdatabase +admin.setting.dbInsert=Writetothedatabase +admin.setting.dbSetSave=Saveconfigurationinformation +admin.setting.recDesc=Instructionsforuse +admin.setting.recDescInfo11=Thisoperationwillresetthesystemdata,non-operationandmaintenanceorrelatedtechnicalpersonnelshouldnotoperate! +admin.setting.recDescInfo21=Bywritingthebackupdatabasetothenewdatabaseandsettingitasthesystemdefault,datarecoveryisachieved. +admin.setting.recDescInfo22=Thenewdatabaseconfigurationparameterswillbeappendedtothesystemconfigurationfileconfig/setting_user.php.Ifthesystemisabnormalaftertherecoveryisexecuted,theappendedpartofthefilecanberemovedwithoutaffectingtheprevioussystemdata. +admin.setting.recDescInfo23=Thisfunctiononlysupportsprocessingthebackupdatageneratedbythesystembackupmanagement,andthedatabasebackedupbyyourselfshouldbeprocessedinotherways. +admin.setting.recDescInfo31=Note:WhenthedatabasetypeisMySQL,anewlibrary(originallibraryname_currentdate_rebuild)willbecreatedbasedonthecurrentconfigurationinformation.Non-rootusersmaynothavesufficientpermissions,soyouneedtosetpermissionsfortheuserfirst. +admin.setting.recDescInfo32=Forexample,thecurrentdatabaseconfigurationinformationis:user:kod;password:kod123.UsetherootaccounttologintothedatabaseandexecutethecorrespondingSQLstatementtosetthepermissions(thepermissionscanberevokedafterthetestispassedandtherecoveryissuccessful). +admin.setting.recDescInfo33=Settingpermissions: +admin.setting.recDescInfo34=Revokepermissions: +admin.setting.recOpen=Turnonrecovery +admin.setting.recOpenDesc=Afteritisturnedon,youcanselectthebacked-updatabasetorestoreasneeded.Pleaseoperatewithcaution. +admin.setting.recTypeDesc=Dependsonthetypeofsystemcurrentlyused +admin.setting.recPath=Databasebackupdirectory +admin.setting.recPathErr=Invaliddatabasebackupdirectory +admin.setting.ifSaveRec=Databaserestorationwillimportthebackupdataintothenewdatabaseandsetitasthedefault.
    Areyousureyouwanttoexecuteit? +admin.setting.recDiyPathErr=Whenusingself-backuptorestore,pleaseselectthedatabasefiletobebackedup +admin.setting.recDiyFileNull=Thedatabasefileisempty +admin.setting.recDiyPhpErr=FortheSQLitetobebackedupbyyourself,pleaseselectthedatabasefileformattedasphp +admin.setting.recDiySqlErr=FortheMySQLtobebackedupbyyourself,pleaseselectthedatabasefileformattedassql +admin.setting.recSysPathErr=Whenusingbackupmanagementtorestore,pleaseselectthebackupdatabasedirectory +admin.setting.recSysTbErr=Thedatabasebackupdirectoryisinvalid,orthedatabasestructurefileismissing +admin.setting.recDbFileErr=Theselectedlibraryfiledoesnotmatchthesystem,oravaliddatatableismissing +admin.setting.dbFileDown=Readlibraryfile +admin.setting.dbFileDownErr=Failedtoreadlibraryfile +admin.notice.waiting=Waitingforpush +admin.notice.done=Pushed +admin.notice.time=Pushtime +admin.notice.target=Pushobject +admin.notice.level=Promptlevel +admin.notice.level0=Weakhint +admin.notice.level1=Strongprompt +admin.notice.levelDesc=Weakreminder:areddotisdisplayedinthenotificationbaratthelowerleftcorner;strongreminder:anotificationwillpopupdirectlyaftertheuserlogsin. +admin.notice.targetAuth=Choosetopushtoeveryone,orpushtospecifiedusers,usergroups,andpermissiongroups +admin.notice.title=Messagetitle +admin.notice.content=Messagecontent +admin.notice.timeType=Pushmethod +admin.notice.timeNow=Pushimmediately +admin.notice.timePlan=Scheduledpush +admin.notice.listTitle=Stationnewsnotification +admin.notice.clearAll=Emptyall +admin.notice.noMsg=Nonews +admin.notice.ifClearAll=Areyousureyouwanttoclearallmessages? +admin.group.role=Roleidentity +admin.group.name=Name +admin.group.parent=Parentgroup +admin.group.authShow=Thescopeoftheorganizationstructurevisibletothemembersofthedepartment +admin.group.authShowAll=Alldepartments +admin.group.authShowHide=Onlythisdepartmentandsub-department +admin.group.authShowSelect=Designateddepartment +admin.group.authShowAllTips=Whenmembersofthisdepartmentcollaboratetoshare,theycanselectallotherdepartments(andusers) +admin.group.authShowHideTips=Whenmembersofthisdepartmentcollaborateandshare,onlythecurrentdepartmentandsub-department(andusers)aresupported +admin.group.authShowSelectTips=Whenthemembersofthedepartmentcollaborateandshare,theycanselectthedesignateddepartmentandsub-department(anduser),includingthecurrentdepartmentandsub-department +admin.group.addSub=Addsub-group +admin.group.remove=Deletegroup +admin.group.switch=MigrationDepartment +admin.group.swtichDesc=Migrateusersandfilesundertheselecteddepartment(anditssub-departments)tothetargetdepartment. +admin.group.switchSameError=Targetdepartmentcannotbethesameastheselecteddepartment +admin.group.switching=Migrating,pleasewait... +admin.group.groupSwitching=Theselecteddepartmentismigrating +admin.group.parentNullError=Theparentgroupcannotbeempty +admin.group.selected=Selecteddepartment +admin.group.setSizeBatch=Setspacesizebatches +admin.group.multiSelect=Multipledepartmentscanbeselectedforbatchsetting +admin.group.ifDisAll=Allsub-departmentswillbedisabled.Areyousureyouwanttoexecuteit? +admin.member.manage=Users&Groups +admin.member.add=Newuser +admin.member.role=Role +admin.member.group=Group +admin.member.groupAdd=Addgroup +admin.member.groupEdit=Editgroup +admin.member.remove=Deleteusers +admin.member.import=Addinbulk +admin.member.enable=Enable +admin.member.batchSet=Bulkoperations +admin.member.groupRemove=Removefromgroup +admin.member.groupInsert=Addtogroup +admin.member.groupSwitch=Migratetodepartment +admin.member.groupTarget=Targetdepartment +admin.member.groupReset=Resetgroup +admin.member.groupSwtichDesc=Migrateselectedusersfromthecurrentdepartmenttothetargetdepartment +admin.member.roleSet=Userrolesetting +admin.member.sizeSet=Spacesizesetting +admin.member.name=Name +admin.member.nickName=Nickname +admin.member.userInfo=UserInfo +admin.member.userImport=Importusersinbulk +admin.member.uploadFirst=Pleaseuploadthefilefirst +admin.member.downTpl=Downloadtemplate +admin.member.downTplDesc=,Pleasefillinthetemplateformatandupload. +admin.member.uploadInvalid=Thereisnovaliddataintheuploadedfile,pleasecheckanduploadagain +admin.member.uploadDataInvalid=Uploaddataisinvalidorexpired,pleaseuploadagain +admin.member.importSuccess=Importcomplete +admin.member.importFail=Importfailed +admin.member.importFailDesc=Success:{0};Failure:{1} +admin.member.importName=Loginaccount(required,unique) +admin.member.importNickName=Nickname(unique) +admin.member.importPwd=Password(required) +admin.member.importSex=Gender(Male-1,Female-0) +admin.member.importPhone=Mobilenumber(unique) +admin.member.importEmail=Email(unique) +admin.member.groupRemoveTips=Usersofthisusergroupcannotloginafterdeletion
    (Needtoresettheusergroup),areyousureyouwanttocontinue? +admin.member.memberRemoveTips=Afterdeletion,theuserdirectorywillbemovedtothesystemrecyclebin,
    Areyousureyouwanttocontinue? +admin.member.selectUserTips=Pleaseselecttheaccounttooperate +admin.member.ifRemoveGroup=Areyousureyouwanttoremovetheselectedusersfromthisgroup? +admin.member.importDesc=Oneuserperline,
    Automaticallyignoreifitalreadyexists +admin.member.roleAdminTips=Note:Thesystemadministratorisnotcontrolledbypermissions +admin.member.space=Setuserspacesize +admin.member.spaceTips=0isunlimited +admin.member.spaceTipsDefault=(GB)0isunlimited +admin.member.spaceTipsFull=Unlimited +admin.member.spaceSize=Spacesize +admin.member.spaceSizeUse=Spaceusage +admin.member.memberAdd=Adduser +admin.member.allAdd=Add +admin.member.nullNotUpdate=Ifnotfilledin,itwillnotbemodified +admin.member.search=Searchusers(account/nickname/email/phone) +admin.member.searchUser=Searchusers(supportpinyinandfuzzymatching) +admin.member.searchGroup=Searchgroup(supportpinyinandfuzzymatching) +admin.member.searchAll=Searchforusersorgroups(supportpinyinandfuzzymatching) +admin.member.editNoAuth=Sorry,youdonothavethispermission,
    Onlysystemadministratorscanaddandmodifysystemadministrators +admin.member.disabledUsers=Accountdisabled +admin.member.disabledTips=Switchdepartmentstouncheck +admin.member.userGroup=Userdepartment +admin.member.userRole=Userrole +admin.member.userSelected=Selectedusers +admin.member.authCopy=Copydepartmentpermissions +admin.member.authPaste=Departmentpermissionpaste +admin.member.ifAuthPaste=Areyousureyouwanttosetthecopieddepartmentpermissionstothecurrentuser? +ERROR_USER_NOT_EXISTS=Userdoesnotexist +ERROR_USER_PASSWORD_ERROR=Wrongpassword +ERROR_USER_EXIST_NAME=Usernamealreadyexists +ERROR_USER_EXIST_PHONE=Phonenumberalreadyexists +ERROR_USER_EXIST_EMAIL=Themailboxalreadyexists +ERROR_USER_EXIST_NICKNAME=Nicknamealreadyexists +ERROR_USER_LOGIN_LOCK=Sorry,therearetoomanypasswordattempts,andthecurrentaccountislocked.Pleasetryagainin1minute! +ERROR_IP_NOT_ALLOW=YourcurrentIPoraccessdeviceisnotallowedtologin,pleasecontacttheadministrator! +user.passwordCheckError=Thepasswordformatdoesnotmeetthepasswordstrengthrules! +admin.role.administrator=Administrator +admin.role.group=DepartmentAdministrator +admin.role.default=Ordinaryuser +admin.role.ignoreExt=Extensionrestrictions +admin.role.ignoreExtDesc=Filetypesthatarenotallowedtoupload,therearenorestrictionsonempty +admin.role.ignoreFileSize=Uploadfilesizelimit +admin.role.ignoreFileSizeDesc=Singlefileuploadmaximum,0isunlimited +admin.role.ignoreExtTips=Sorry,thecurrentsystemsettingsdonotsupportthistypeoffileupload;pleasecontacttheadministratorfordetails! +admin.role.ignoreFileSizeTips=Sorry,whenthefileexceedsthesizelimit;pleasecontacttheadministratorfordetails! +admin.role.desc=Roledescription +admin.role.adminDesc=Superadministrator,hasservermanagementrights;allfileandfoldersettingsareinvalidforthisuser! +admin.role.read=Read +admin.role.readList=Documentlist +admin.role.readInfo=File(folder)attributeview,foldersearch +admin.role.readCopy=Filecopy +admin.role.readPreview=Filepreview(pictures,documents,audioandvideo,etc.) +admin.role.readDownload=File(folder)download +admin.role.write=Write +admin.role.writeAdd=Createfiles(folders),compressanddecompressfiles +admin.role.writeChange=Rename,adjustdirectorystructure +admin.role.writeUpload=File(folder)upload,remotedownload +admin.role.writeRemove=File(folder)delete,cut +admin.role.adminSetDesc=Thesystemadministratorhasallpermissions,noneedtoset! +admin.role.displayDesc=Whethertodisplaywhensettinguserroles +admin.role.defaultRoleDesc=Tip:Thesystemhasbuilt-inrolesbydefaultanddoesnotsupportmodifyingpermissions.Youcancreatenewroles +admin.role.actionSetTitle=Documentation +admin.role.userSetTitle=User +admin.role.adminSetTitle=Backstage +admin.role.fileAdd=Newfile(folder) +admin.role.fileRemove=Delete +admin.role.fileMove=Move(copy/cut/paste/dragoperation) +admin.role.userConfig=Configurationmodification(setavatar/changepassword,etc.) +admin.role.userEdit=Edituser(add/modify/delete) +admin.role.userFav=Starredoperation +admin.role.itemEdit=Add/modify/delete +admin.role.groupEdit=Editgroup(add/modify/delete) +admin.role.delErrTips=Thecharacterisbeingusedandcannotbedeleted! +admin.authFrom.setUser=Specifyyourownpermissions +admin.authFrom.setGroup=Specifydepartmentauthority +admin.authFrom.setAll=Otheruserpermissions +admin.authFrom.groupAt=Departmentauthority +admin.authFrom.groupParent=Upperdepartmentauthority +admin.authFrom.pathOnly=Onlyaccess,thelowerlevelhascontentandpermission +admin.authFrom.groupRoot=Departmentrootdirectory +admin.auth.owner=Owner +admin.auth.editor=Editor +admin.auth.editUploader=Edit/uploader +admin.auth.viewer=Viewer +admin.auth.previewer=Previewer +admin.auth.uploader=Uploadedby +admin.auth.invisible=Invisible +admin.auth.user=Userdata +admin.auth.pathDelete=Filedeletion +admin.auth.pathInfo=Fileattribute +admin.auth.pathMove=Move(copy/cut/paste/dragoperation) +admin.auth.canUpload=Upload +admin.auth.config=ConfigurationData +admin.auth.fav=Starredoperation(add/edit/delete) +admin.auth.extWarning=Uploadingofsuchfilesisnotallowed,
    Rename(renamedtothespecifiedextension),
    Editsave,remotedownload,decompress +admin.auth.error=Documentpermissionerror(nopermissionsettings) +admin.auth.errorAdmin=Insufficientpermissions +admin.auth.targetError=Permissionobjecttypeiswrong,mustbeuserorgroup +admin.auth.errorAuthToGroup=Non-rootgroup,doesnotsupportdelegationtogroups +admin.auth.errorAuthToUsers=Non-rootsector,doesnotsupportdelegationtomembersoutsidethesector +admin.auth.displayDesc=Displayornotwhensettinggrouppermissions +admin.auth.defaultAuthDesc=Tip:Thesystembuilt-inpermissiondoesnotsupportmodifying.Youcancreatenew +admin.auth.show=Documentlist +admin.auth.showAction=Filelistview +admin.auth.view=Preview +admin.auth.viewAction=Fileopenpreview +admin.auth.download=Download/Copy +admin.auth.downloadAction=Download/Copy/Preview/Print +admin.auth.uploadAction=Upload/Remotedownload +admin.auth.edit=Edit +admin.auth.editAction=NewFile(Folder)/Rename/Paste/Edit/SetNotes/Copy/Unzip,Compress +admin.auth.removeAction=Cut/copy/move +admin.auth.shareAction=Linksharing/Internalsharing +admin.auth.comment=Comments +admin.auth.commentAction=Viewdocumentcomments;add/deleteyourowncomments(editingpermissionrequired) +admin.auth.event=Dynamics +admin.auth.eventAction=Documentdynamicviewing,subscriptiondynamic +admin.auth.root=Administration +admin.auth.rootAction=Setmemberpermissions/comment/historyversionmanagement +admin.auth.delErrTips=Thispermissionisbeingusedandcannotbedeleted! +admin.plugin.center=PluginCenter +admin.plugin.installed=Installed +admin.plugin.type=Type +admin.plugin.typeFile=File +admin.plugin.typeSafe=Security +admin.plugin.typeTools=Utilities +admin.plugin.typeMedia=Media +admin.plugin.typeCompany=Enterprise +admin.plugin.typeOem=Customization +admin.plugin.needNetwork=Extranet +admin.plugin.install=Install +admin.plugin.enable=Enable +admin.plugin.remove=Uninstall +admin.plugin.config=Configure +admin.plugin.statusEnabled=Activated +admin.plugin.statusDisabled=Notactivated +admin.plugin.statusNotInstall=NotInstalled +admin.plugin.installing=Installing... +admin.plugin.hasUpdate=Update +admin.plugin.updateStart=Update +admin.plugin.needConfig=Requiresinitialconfigurationtoenable +admin.plugin.notNull=Requiredfieldscannotbeempty! +admin.plugin.auther=Author +admin.plugin.downloadNumber=Installs +admin.plugin.back=Return +admin.plugin.detail=Description +admin.plugin.resetConfig=Resettodefault +admin.plugin.installSelf=Manualinstallation +admin.plugin.updateSelf=Manualupdate +admin.plugin.updateAll=Updateall +admin.plugin.installSelfDesc=
    Applicablesituation:
  • 1.Theserverdoesnotsupportconnectingtotheexternalnetwork.
  • 2.Whenthevirtualhosthasdisabledrelatedfunctions(networkrequest,httpsverification).

  • Installation:Afterdownloading,uploadandunziptothepluginsdirectory(youneedtokeepthefolderwiththepluginname,youcan'tmodifythepluginname);theplugincentercanbeenabled
  • Update:Afterdownloading,uploadandunziptothecorrespondingplug-innamefolder;
  • +admin.plugin.installNetworkError=Networkerror.Pleasecheckwhethertheservercanaccesstheexternalnetwork. +admin.plugin.auth=Permission +admin.plugin.authDesc=Makeeveryoneavailable,orspecifyusers,groups,androlestouse +admin.plugin.authOpen=Openaccess +admin.plugin.authOpenDesc=Canbeaccessedwithoutlogin,canbeusedforexternalinterfacecalls +admin.plugin.authAll=Everyone +admin.plugin.authUser=Users +admin.plugin.authGroup=Groups +admin.plugin.authRole=Roles +admin.plugin.openWith=Openstyle +admin.plugin.openWithDilog=Internaldialog +admin.plugin.openWithWindow=Newpage +admin.plugin.fileSort=Priority +admin.plugin.fileSortDesc=Thehigherthevalue,thehigherthepriorityofopening +admin.plugin.fileExt=Formats +admin.plugin.fileExtDesc=Associateextensiontotheplugin +admin.plugin.tabServer=Server +admin.plugin.defaultAceEditor=Aceeditor +admin.plugin.defaultHtmlView=Webpreview +admin.plugin.defaultZipView=Onlinedecompression +admin.plugin.authViewList=Listofplugins +admin.plugin.authStatus=Switch +admin.plugin.authInstall=Install/uninstall +admin.plugin.disabled=Theplugindoesnotexistorhasnotbeenstarted +admin.plugin.menuAdd=Whethertoaddtothemainmenu +admin.plugin.menuAddDesc=Useasastandaloneapplication +admin.plugin.menuSubMenuDesc=Shrinkinthe[More]menu +admin.storage.type=Storagetype +admin.storage.local=Local +admin.storage.localStore=Localstorage +admin.storage.oss=AlibabaOSS +admin.storage.cos=TencentCOS +admin.storage.qiniu=QiniuCloud +admin.storage.s3=AmazonS3 +admin.storage.ftp=FTP +admin.storage.oos=TianyiCloudOOS +admin.storage.moss=HongshanMOSS +admin.storage.eos=XSKYEOS +admin.storage.nos=FormercloudNOS +admin.storage.minio=MinIO +admin.storage.uss=TakeanothercloudUSS +admin.storage.eds=SangforEDS +admin.storage.driver=Disk +admin.storage.useage=Spaceusage +admin.storage.default=Default +admin.storage.current=Currentdefault +admin.storage.edit=Configuration +admin.storage.setConfig=Edit +admin.storage.moveData=Migratedata +admin.storage.delStore=Unmountstorage +admin.storage.ifMove=Thisstoragecontains{0}networkdiskfilesandwillbemigratedtothecurrentdefaultstorage.Doyouwanttocontinue? +admin.storage.ifDel=Areyousureyouwanttounmountthecurrentstore? +admin.storage.ifDelWithFile=Thisstoragecontains{0}networkdiskfiles,whichwillbemigratedtothecurrentdefaultstoragewhendeleted.Doyouwanttocontinue? +admin.storage.sysFile=Networkdiskfiles:filesunderpersonalspaceanddepartments +admin.storage.delErrTips=Success:%s;Failure:%s,pleasetryagainormanuallymigrate +admin.storage.delLocTips=Pleasekeepatleastonelocalstore +admin.storage.delStoreTips=Thisstoragecontainsbackupdata,pleaseprocessitbeforeproceeding! +admin.storage.nameDesc=Storagenametodistinguishdifferentstorage +admin.storage.path=Directory +admin.storage.pathLocDesc=Filestoragedirectory,pleaseensureithaswritepermissions +admin.storage.pathDesc=Filestoragedirectory +admin.storage.defaultDesc=Thedefaultitemistheonlyvalidsystemstorage.Ifyouchoosetoenableit,otherdefaultstoragemethodswillbeautomaticallycancelled.Pleaseoperatewithcaution. +admin.storage.forceEdit=Mandatorymodification +admin.storage.editTips=Afteropening,youcanedittheprohibitedmodificationfields.Thefilebeforethestoragemaynotbeaccessible,pleaseexercisecaution. +admin.storage.folderTips=Thecurrentsystemfilestoragelocation,pleaseoperatewithcaution +admin.storage.sizeTips=Spacesizemustbegreaterthan0 +admin.storage.sizeDesc=(GB),pleasefillinaccordingtotheactualfreespaceoftheselectedstoragedirectory +admin.storage.region=Region +admin.storage.domain=Domainname +admin.storage.bucket=Bucketname +admin.storage.bucketDesc=Bucketnamefilledinwhencreatingspace +admin.storage.userName=AccountName +admin.storage.userPwd=Accountpassword +admin.storage.server=Serveraddress +admin.storage.serverDesc=Ftp(s)://ip,defaultisftpwithoutprotocol +admin.storage.refer=Reference: +admin.storage.endpoint=Endpoint +admin.storage.ossDomain=DomainnameboundinOSSspace +admin.storage.ossKeyDesc=AccessKeyIDofAlibabaCloudaccount,pleasecreateorviewin[ControlPanel-AccessKeyManagement] +admin.storage.ossSecretDesc=AccessKeySecretofAlibabaCloud +admin.storage.ossEndpoint=Endpoint,ifyouuseanintranetnode,youneedtoenableservertransfer +admin.storage.cosKeyDesc=AccessKeyIDofTencentCloudaccount,pleasecreateorviewin[ControlPanel-AccessManagement-APIKeyManagement] +admin.storage.cosSecretDesc=AccessKeySecretofTencentCloudaccount +admin.storage.qiniuDomain=DomainnameboundbyQiniuSpace +admin.storage.qiniuKeyDesc=AccessKeyforQiniuaccount,pleasecreateorviewin[ControlPanel-PersonalCenter-KeyManagement] +admin.storage.qiniuSecretDesc=SecretKeyofQiniu,themethodofobtainingisthesameasabove +admin.storage.qnz0=EastChina-Zhejiang +admin.storage.qnz02=EastChina-Zhejiang2 +admin.storage.qnz1=NorthChina-Hebei +admin.storage.qnz2=SouthChina-Guangdong +admin.storage.qnna0=NorthAmerica-LosAngeles +admin.storage.qnas0=AsiaPacific-Singapore +admin.storage.qnas02=AsiaPacific-Seoul +admin.storage.awsDomain=DomainnameboundinAWSspace +admin.storage.awsKeyDesc=AccessKeyIDofAWS,pleasecreateitin[ControlPanel-YourSecurityCredentials] +admin.storage.awsSecretDesc=AccessKeySecretforAWS +admin.storage.oosDomain=TianyiCloudSpacebounddomainname +admin.storage.oosKeyDesc=AccessKeyIDofTianyiCloud,pleasecreateitin[ControlPanel-YourSecurityCredentials] +admin.storage.oosSecretDesc=TheaccesskeysecretoftheTianyiCloudisthesameasabove +admin.storage.ftpDisabled=FTPisnotavailable,pleaseenablethephp_ftpextension +admin.storage.ifDefaultTips=Thisoperationwillcancelotherdefaultstoragemethods.Areyousure? +admin.storage.spaceUsed=Actualusage +admin.storage.spaceLave=Remainingamount +admin.storage.delError=Thefilealreadyexistsinthisstoreandcannotbedeleted +admin.storage.corsError=Iftheconfigurationiscorrect,pleaseclick[UseHelp]tocheckthebucketcross-domainsettings. +admin.storage.saveError=Unabletoconnecttothespecifiedstorage,pleasecheckwhethertheconfigurationinformationiscorrect. +admin.storage.ftpCharset=FTPserverencoding +admin.storage.ftpCharsetDesc=IftheFTPserveriswindows,itcanbesettoGBKaccordingtothesituation; +admin.storage.ftpPasvOn=Turnon +admin.storage.ftpPasvOff=Closure +admin.storage.ftpPasv=Passivemode +admin.storage.ftpPasvDesc=Datatransfermode +admin.storage.uploadSrv=Servertransfer(upload) +admin.storage.fileoutSrv=Servertransfer(download) +admin.storage.uploadSrvDesc=Afteritisturnedon,thefilewillbeuploadedtotheobjectstoragethroughtheserver;otherwise,itwillbeuploadeddirectlythroughtheclient. +admin.storage.fileoutSrvDesc=Afteritisturnedon,thestoragefilewillbeobtainedthroughtheserverfordownload;otherwise,thefilewillbeobtainedfordirectlinkdownload. +admin.storage.closeDefError=Prohibitturningoffthedefaultstorage +admin.storage.ussBucket=Servicename +admin.storage.ussBucketDesc=Cloudstorageservicename +admin.storage.ussUser=Operatorname +admin.storage.ussUserDesc=Operatorname +admin.storage.ussUserPwd=Operatorpassword +admin.storage.ussDomain=Takeanothershotofthedomainnameboundtothecloudspace +admin.storage.ussToken=Anti-leechToken +admin.storage.ussTokenDesc=Tokenanti-theftchainsecretkey(notrequired) +admin.storage.configError=Theconfigurationparameterisabnormal! +admin.storage.sizePercent=Systemfileratio: +admin.storage.fileCount=Numberoffiles: +admin.storage.error=Storageexception +admin.task.name=Name +admin.task.edit=Edit +admin.task.type=Type +admin.task.method=Method +admin.task.methodName=Methodname +admin.task.methodDesc=Itconsistsofsystemmodule-controller-methodname,fillincarefully. +admin.task.url=URL +admin.task.urlDesc=User-definedURLaddress,scheduledtaskstoexecuterequestsregularly. +admin.task.cycle=Executioncycle +admin.task.desc=Missiondetails +admin.task.nMinutes=Nminutes +admin.task.default=Systemdefault +admin.task.timeInterval=Intervalstime +admin.task.timeStart=Starttime +admin.task.timeStartRun=Startexecutiontime +admin.task.timeLastRun=Lastexecutiontime +admin.task.timeLastLogin=Logintime +admin.task.isOpen=Enable +admin.task.open=Enable +admin.task.content=Content +admin.task.param=Parameter +admin.task.ifRun=Areyousureyouwanttorunthistask? +admin.task.backup=Databackup +admin.task.backupDesc=Startbackingupsystemdataat02:00everyday. +admin.install.install=Systeminstallation +admin.install.databaseSet=Databaseconfiguration +admin.install.dataUpdate=Datamigration +admin.install.installSuccess=Successfulinstallation +admin.install.dbWasSet=Youhaveconfiguredthedatabase.Ifyouneedtoreset,youcanmodifytheconfigurationintheconfig/setting_user.phpfileandreinstallit! +admin.install.errorRequest=Systemisinstalled,nofurtherrequestsareallowed +admin.install.databaseError=Databaseconnectionerror,pleasechecktheconfiguration +admin.install.cacheError=%sconnectionfailed,pleasechecktheconfiguration +admin.install.cacheConnectError=%scannotconnecttotheserver,pleasechecktheconfiguration +admin.install.dbSetError=Databaseconfigurationinformationwritefailed +admin.install.dbCreateTips=Thedatabasedoesnotexistandtheautomaticcreationfails.Pleasecreateitmanually +admin.install.ifDelDb=Thedataalreadyexistsinthespecifieddatabase.Click[OK]todeleteit.Whethertocontinue? +admin.install.dbCreateError=Datatablecreationexception +admin.install.dbFileError=Thedatabasefiledoesnotexist +admin.install.dbTypeError=Theselecteddatabasetype(%s)isnotavailable,pleaseinstallthecorrespondingserviceandextension,orchooseanothertype +admin.install.createSuccess=Createdsuccessfully +admin.install.defSetError=Failedtoadd +admin.install.defStoreError=Defaultstoragefailedtoadd +admin.install.defPathError=Systemdirectoryfailedtoadd +admin.install.defAdminError=Adminaccountfailedtoadd +admin.install.defRoleError=Defaultrolefailedtoadd +admin.install.defGroupError=Systemgroupfailedtoadd +admin.install.dataPathNotExists=Datadirectorydoesnotexist +admin.install.defaultUpdate=Systeminformationupdate +admin.install.pluginUpdated=Pluginupdatecompleted +admin.install.defCacheError=Initialdirectorycachedataexception +admin.install.serverDir=Servercolumndirectory +admin.install.dirRight=Directorypermissions +admin.install.suggestOpen=Recommendedtoopen +admin.install.suggestClose=Recommendedtoclose +admin.install.phpVersionTips=PHP5.3andabove +admin.install.phpBitTips=64-bitrecommended +admin.install.phpBitDesc=32-bitdoesnotsupportuploadanddownloadoffilesover2G +admin.install.pathNeedWirte=Theprogramdirectoryandallsubdirectoriesneedtobereadableandwritable +admin.install.mustOpen=Mustopen +admin.install.setPathWrt=Pleasesetreadandwritepermissionsfortheprojectdirectory +admin.install.ensureNoError=Makesurethefollowingiscorrect: +admin.install.setAdminName=Pleasesetupanadministratoraccount +admin.install.setAdminPwd=Pleasesetanadministratorpassword +admin.install.database=Database +admin.install.dbType=Databasetype +admin.install.dbName=Databasename +admin.install.userName=Username +admin.install.dbPort=PortNumber +admin.install.dbPortDesc=Thedefaultportis3306,ifyouneedtocustomizeit,youcanappendit,suchas:127.0.0.1:3307 +admin.install.dbEngine=Storageengine +admin.install.sqliteDesc=PHPhasabuilt-ingreenlightweightdatabase(suitablefortestingorsmallscaleuse). +admin.install.mysqlDesc=Supportsclusterdeployment,separationofmasterandslavedatabases. +admin.install.pdoDesc=AmoresecuredatabasegeneraldriverrequiresPHPtohavethePDOextensioninstalled. +admin.install.cacheType=Systemcachetype +admin.install.cacheTypeDesc=Usedtocachegeneraldataandsessionsessionstospeedupsystemaccess +admin.install.fileCache=Filecache +admin.install.groupFile=GroupDocument +admin.install.userFile=Userdocumentation +admin.install.role=Roles +admin.install.fileAuth=Documentpermissions +admin.install.userList=Userlist +admin.install.setInfo=System +admin.install.favShare=UserStarredandShares +admin.install.waitUpdate=Waitingforupdate +admin.install.updateSuccess=Updatecompleted +admin.install.fileCount=Files +admin.install.settingDesc=Failureitemscanbemanuallyconfiguredinbackgroundmanagement +admin.install.reInstallTips=Returnresultisabnormal,pleasereinstall +admin.log.accountEdit=Modifyaccountinformation +admin.log.thirdBind=Bindathird-partyaccount +admin.log.delBind=Unbind +admin.log.viewFile=Previewfile +admin.log.delFile=DeleteFiles +admin.log.editFile=Editfile +admin.log.downFile=Downloadfile +admin.log.downFolder=Downloadfolder +admin.log.moveFile=Movefile +admin.log.addUser=Newusers +admin.log.editUser=Edituser +admin.log.addUserTo=Adduserstothegroup +admin.log.removeUserFrom=Userremovedfromgroup +admin.log.switchUserGroup=Migrateuserstodepartments +admin.log.stausUser=Enable/disableusers +admin.log.addRole=Newrole +admin.log.editRole=Editrole +admin.log.delRole=Deleterole +admin.log.addAuth=Addpermissions +admin.log.editAuth=Editpermissions +admin.log.delAuth=Deletepermission +admin.log.editShare=Editsharing +admin.log.delLinkTo=Cancelexternallinksharing +admin.log.delShareTo=Cancelcollaborativesharing +admin.log.recycleTo=Movetorecyclebin +admin.log.newName=Newname +admin.log.oldName=Originalname +admin.log.newPath=Newcatalog +admin.log.oldPath=Originalcatalog +admin.log.typeFile=Fileoperations +admin.log.typeUser=Userconfiguration +admin.log.queryByIp=ClickthebuttontoquerythelogrecordsofthedaybasedontheIP. +admin.backup.setting=Settings +admin.backup.edit=Backupediting +admin.backup.ing=Backingup +admin.backup.success=Backupsucceeded +admin.backup.fail=Backupfailed +admin.backup.complete=Backupcomplete +admin.backup.db=Database +admin.backup.dbFile=Databasefile +admin.backup.fileError=Backupofsomefilesfailed +admin.backup.checkLog=Pleasecheckthebackuplog:data/temp/log/backup/dateoftheday__log.php +admin.backup.pathNoWrite=Temporarydirectorydoesnothavewritepermission +admin.backup.errorMsg=Partofthefilebackupfailed,youcanmanuallycopyaccordingtothelog,ordeleteandbackupagain. +admin.backup.logFile=Logfile +admin.backup.manual=Manual +admin.backup.continue=Continue +admin.backup.start=Startbackup +admin.backup.open=Turnonbackup +admin.backup.notOpen=Backupisnotenabled +admin.backup.location=Backuplocation +admin.backup.content=Backupcontent +admin.backup.dbOnly=Database +admin.backup.time=Backuptime +admin.backup.notStart=Hasnotstarted +admin.backup.notEnabled=NotEnabled +admin.backup.killed=Over +admin.backup.ifKill=Areyousureyouwanttoendthisbackup? +admin.backup.kill=End +admin.backup.error=Abort +admin.backup.timeBeen=Timeconsuming +admin.backup.timeTotal=Totaltime +admin.backup.backed=Backedup +admin.backup.storage=Pleasecreateadedicatedstorageforbackup. +admin.backup.ifSave=Thebackuptakesalongtime.Areyousureyouwanttobackup? +admin.backup.ifContinue=Areyousureyouwanttocontinuethebackup? +admin.backup.saveTips=Backuptaskhasbeensubmitted,pleasebepatient +admin.backup.fileSize=Documentsize +admin.backup.dbSize=Databasesize +admin.backup.dbCnt=Total +admin.backup.notFinished=Notcompleted +admin.backup.timeTaken=Timeconsuming +admin.backup.node=Node +admin.backup.notYet=No +admin.backup.storeNotExist=Thebackupstoragedoesnotexist,pleasereset +admin.backup.timeNote=Note:Thesystemonlykeepsthedatabasebackupsofthelast7daysandthe1stofeachmonth.Backuptime: +admin.backup.recover=Pleasecontacttheserviceproviderfordatarecovery. +admin.backup.optionTime=Thebackuptakesalongtime,pleasetrytochooseitduringnon-workinghours +admin.backup.optionLocation=Ifyouneedtobackupfiles,pleasecreateanewstoragededicatedforbackup +admin.backup.optionTips1=Thebackupisdividedintotwoparts:databasebackupandfilebackup. +admin.backup.optionTips2=Databasebackup:GenerateSQLfilesfromdatabasecontentandbackthemuptothetargetstoragedatabasedirectory. +admin.backup.optionTips3=Filebackup:backupsystemstoragefilestothetargetstorageincrementallyaccordingtotheoriginalstoragepath. +admin.backup.optionTips4=Thesystemonlykeepsthedatabasebackupsofthelast7daysandthe1stofeachmonth. +admin.backup.needStorage=Backupstoragecannotbeempty +admin.backup.needNoDefault=Donotchoosethedefaultstorageasthefilebackuplocation +admin.backup.contentDesc=Thelicensedversionsupportssimultaneousbackupofdatabasesandfiles +admin.backup.action=OperationManagement +admin.backup.recovery=Reduction +admin.backup.sysRecovery=SystemRestore +admin.backup.bakErr2Rec=Thisbackupisincompleteandcannotberestored +admin.recycle.menu=SystemRecycleBin +admin.share.name=Sharename +admin.share.type=Sharingtype +admin.share.expiryTime=Expiration +admin.share.expired=Expired +admin.share.link=Externallink +admin.share.linkView=Clicktoviewshare +admin.share.ifDel=Areyousureyouwanttocancelthissharing? +admin.share.disFile=Thisfilehasbeenreportedbyusersandhasbeenbannedfromsharing +admin.share.disFolder=Thisdirectorycontainsillegalfilesthatareforbiddentobeshared +admin.share.shareTab=Sharing +admin.share.reportTab=Sharingreport +admin.share.rptType1=Piracy +admin.share.rptType2=Obsceneporn +admin.share.rptType3=Bloodyviolence +admin.share.rptType4=Politicsisharmful +admin.share.rptType5=Otherreasons +admin.share.doRptClose=Closethereportafterprocessingthesharedcontent,orcloseitdirectly +admin.share.doRptDisable=Afterprohibiting/allowingsharing,allresourcescorrespondingtothefilewillbeaffected.Areyousureyouwanttoperformthisoperation? +admin.share.rptUser=Whistleblower +admin.share.rptTitle=Reportsharing +admin.share.rptDesc=Reasonforreporting +admin.share.rptTime=Reporttime +admin.share.rptResult=Processresult +admin.share.rptDone=Processed +admin.share.rptNoDone=Untreated +admin.share.rptClose=Closereport +admin.share.rptShareDel=Unshare +admin.share.rptShareAllow=Allowsharing +admin.share.rptShareDisable=Nosharing +admin.share.rptDoDisable=Prohibit/allowsharing +admin.share.rptSelectTips=Pleaseselecttheitemtobeoperated! +admin.setting.transfer=UploadDownload +admin.setting.transferChunkSize=Uploadshardsize +admin.setting.transferChunkSizeDesc=Whenuploadingalargefile,itiscutintopiecesforconcurrentupload,soastoachieveaccelerationandresumeresume.
    5Misrecommended;thisvaluemustbelessthanthefollowingconfiguration;otherwiseitwillcauseuploadexception(uploadfailure,rollback) +admin.setting.transferChunkSizeDescError1=Uploadshardsizecannotexceedthesettinginphp.ini +admin.setting.transferChunkSizeDescError2=Modifyitinphp.iniandtryagain(modifyupload_max_filesize,post_max_size,needtorestart) +admin.setting.transferThreads=Uploadingconcurrentthreads +admin.setting.transferThreadsDesc=Recommended=10;simultaneousuploadsoffilesorshards +admin.setting.transferIgnore=Uploadignorefile +admin.setting.transferIgnoreDesc=Uploadfilenamesthatareautomaticallyignored.Temporaryfilescanbeexcluded,multipleseparatedbycommas,forexample:.DS_store,thumb.db +admin.setting.transferChunkRetry=Retryonerror +admin.setting.transferChunkRetryDesc=Recommendation=5;numberofretransmissionswillbeautomaticallyperformediftheuploadfails,0meansnoautomaticretransmission +admin.setting.transferOsChunkSize=Objectstorageshardsize +admin.setting.transferOsChunkSizeDesc=Objectstorageupload,thefragmentsizerangesfrom5MBto5GB,andthemaximumnumberofrequestsis1000,whichmeansthatthemaximumfileuploadsizeis5TB.
    10~20MBisrecommended.Atthistime,themaximumfilesizesupportedis9.7~19.5GB,anduserscanadjustthesizeoftheuploadedfileaccordingtotheirneeds. +admin.setting.transferHttpSendFile=Downloadwebserveracceleration +admin.setting.transferHttpSendFileDesc=Filedownloadisdirectlytransmittedthroughthewebserver;thedownloadspeedisimproved;itisonlyeffectivewhenthedefaultstorageisconfiguredaslocalstorage. +admin.setting.downloadZipClient=Front-endcompresseddownload +admin.setting.downloadZipClientDesc=Needtobeabletolinktotheexternalnetwork,orthesiteishttps +admin.setting.downloadZipLimit=Compresseddownloadsizelimit +admin.setting.downloadZipLimitDesc=0meansnolimit;inordertoavoidexcessiveserverperformanceconsumption,thepackagedownloadisrestrictedwhenthefolderistoolarge,anditispromptedthatthefilecanbedownloadeddirectlythroughthePCclient +admin.setting.downloadZipLimitTips=Thecompressedcontentexceedsthesystemlimit,pleasecontacttheadministrator!YoucandirectlydownloadthefolderthroughthePCclientwithoutcompression. +admin.setting.dragDownload=Draganddroptodesktoptodownload +admin.setting.dragDownloadDesc=OnlysupportedbythePC-sideChromekernelbrowser(chromeedge360fast,etc.) +admin.setting.dragDownloadZip=Multi-selectdraganddropcompressdownload +admin.setting.dragDownloadZipDesc=Multipleselectionorfolderdraganddropdownloadsupport,mustbepackagedandcompressedontheserverbeforedownloading +admin.setting.dragDownloadLimit=Draganddropcontentsizelimit +admin.setting.dragDownloadLimitDesc=0meansnolimit;thesizeofthedraggedcontentwillbesubjecttothislimit.SincethereisnoprogressbarforChromedragginganddownloadingatpresent,itcannotbecanceled.Itisrecommendedtolimitthesizeto20M. +admin.setting.dragDownloadUrlTips=Theurlistoolong,pleasereducetheselectionandtryagain! +admin.setting.dragDownloadOpenTips=Pleasecontacttheadministratortoenableitinthebackgroundsettings! +admin.setting.dragDownloadNotOpen=Dragandcompressdownloadisnotenabled +admin.setting.dragDownloadSizeTips=Thesizeofthedraggedcontentexceedsthelimit +admin.setting.showFileSafe=Fileaccesssecurity +admin.setting.showFileLink=Fileexternallinkdisplay +admin.setting.showFileLinkDesc=Afterclosing,thefilepropertiesnolongershowexternallinks +admin.setting.showFileMd5=Filemd5display +admin.setting.showFileMd5Desc=Afterclosing,filepropertiesnolongershowfilemd5 +admin.setting.shareLinkAllow=Enablelinksharing +admin.setting.shareLinkAllowDesc=Afterclosing,itwillnolongersupportexternalchainsharing,andthesharedcontentwillnotbeaffected +admin.setting.shareLinkAllowTips=Thecurrentsystemhasdisabledexternallinksharing,pleasecontacttheadministrator! +admin.setting.shareLinkPasswordAllowEmpty=Allowsemptypassword +admin.setting.shareLinkPasswordAllowEmptyDesc=Afterclosing,apasswordmustbesetforexternallinksharing;thesharedcontentwillnotbeaffected +admin.setting.shareLinkAllowGuest=Sharingallowsunloggedvisitors +admin.setting.shareLinkAllowGuestDesc=Afterclosing,youmustloginwhenaccessingexternallinks;thesharedcontentwillnotbeaffected +admin.setting.shareLinkZip=Sharingallowpackagedownload +admin.setting.shareLinkZipDesc=Afteropening,theexternalchainsharingfoldersupportspackagingandcompressiondownloading.Iftheconcurrencyislarge,theserverperformancewillbeconsumed. +admin.setting.shareLinkZipTips=Externallinksharingdisablespackageddownloads,pleasecontacttheadministratorforconfiguration! +admin.setting.transferDownSpeed=Downloadlimit +admin.setting.transferDownSpeedDesc=Limitdownloadspeeds,anduniformlylimitthespeedoflargeconcurrentwebsites +admin.setting.transferDownSpeedNum=Downloadspeed +admin.setting.transferDownSpeedNumDesc=Limitthedownloadspeed,andyoucanuniformlylimitthespeedofthewebsitewithlargeconcurrency.
    Note:Theserverspeedislimitedhere.Thespecificdownloadspeedisalsoaffectedbytheserverbandwidthandusernetwork. +explorer.uploadSizeError=Yourserverdoesnotcurrentlysupportfilesover2G,
    Pleaseupgradeto64-bitphp;64-bitphp7isrecommended
    (Note:64-bitoperatingsystemcanonlyinstall64-bitPHP); +common.----=---- +common.width=Width +common.height=High +common.test=Test +common.absolutePath=Absoluteaddress +common.qrcode=URLQRcode +common.wechat=WeChat +common.group=Group +common.user=User +common.online=Online +common.use=Use +common.total=Total +common.year=Year +common.month=Month +common.week=Week +common.daytime=Day +common.mon=Monday +common.tue=Tuesday +common.wed=Wednesday +common.thu=Thursday +common.fri=Friday +common.sat=Saturday +common.sun=Sunday +common.second=Second +common.minute=Minute +common.hour=Hour +common.day=Day +common.every=Each +common.everyMonth=Permonth +common.everyWeek=Weekly +common.everyDay=Everyday +common.language=Language +common.all=All +common.item=Item +common.items=Itemcontent +common.itemsEmpyt=Nocontent +common.detail=Details +common.me=Me +common.others=Others +common.guest=Visitors +common.more=More +common.learnMore=Learnmore +common.yes=Yes +common.no=No +common.omit=Omitted +common.unknow=Unknown +common.title=Title +common.time=Time +common.scan=Browse +common.report=Report +common.name=Name +common.nickName=Nickname +common.tools=Tools +common.tag=Tags +common.position=Position +common.mount=Network +common.type=Type +common.auth=Permission +common.status=Status +common.run=Run +common.file=File +common.folder=Folder +common.fileType=Filetype +common.fileSize=Filesize +common.attributeInfo=Information +common.actionType=Type +common.isDisplay=Display +common.hide=Hide +common.isHide=Hidden +common.cancelHide=Unhide +common.default=Default +common.display=Display +common.moveDown=Movedown +common.moveUp=Moveup +common.drag=Drag +common.dragSort=Dragtoadjustorder +common.warning=Caveat +common.tips=Tips +common.desc=Instruction +common.tipsDesc=Promptdescription +common.tipsOthers=Otherinstructions +common.view=View +common.log=Log +common.task=Task +common.important=Important +common.icon=Icon +common.menu=Menu +common.system=System +common.basic=Universal +common.systemSet=System +common.systemDefault=Systemdefault +common.diy=Customize +common.input=Pleaseenter +common.select=Pleasechoose +common.add=Add +common.edit=Edit +common.action=Action +common.upload=Upload +common.uploadTo=Uploadto +common.download=Download +common.export=Export +common.cover=Cover +common.retry=Retry +common.zip=Compression +common.unzip=Decompression +common.preview=Preview +common.share=Share +common.search=Search +common.query=Inquire +common.delete=Delete +common.deleteForce=Removecompletely +common.deleteEnd=Deleted +common.refresh=Refresh +common.open=Open +common.close=Close +common.from=Source +common.greater=Morethanthe +common.less=Lessthan +common.print=Print +common.selectInvert=Reverseelection +common.selectAll=SelectAll/Reverse +common.selectAllItem=Selectall +common.selectNum=Chosen +common.selectNull=Unselectall +common.sizeMore=Theabove +common.showMore=Unfold +common.showLess=Collapse +common.sizeSmall=Small +common.sizeMiddle=In +common.sizeBig=Big +common.rename=Rename +common.method=Function +common.extend=Extension +common.fav=Starred +common.reset=Reset +common.testing=Testing +common.install=Installation +common.update=Update +common.version=Version +common.sysVersion=Platformversion +common.login=Login +common.regist=Signup +common.password=Password +common.operateTime=Operation +common.createTime=Creation +common.modifyTime=Modification +common.activeTime=Archivetime +common.startTime=Startingtime +common.endTime=EndTime +common.finishTime=EndTime +common.disable=Disable +common.goOn=Goon +common.ok=OK +common.startRun=Start +common.confirmTips=Pleaseconfirmagain +common.confirmAsk=Areyousureyouwanttoperformthisoperation? +common.submit=Submit +common.skip=Skip +common.nextStep=Nextstep +common.start=Start +common.stop=Pause +common.set=Setup +common.cancel=Cancel +common.save=Save +common.empty=Nocontent! +common.isOpen=Turnedon +common.isClose=Closed +common.apply=Apply +common.saveAll=Saveall +common.notSave=Donotsave +common.appAdd=Add +common.backAdd=Backtoadd +common.saveEdit=Savechanges +common.saveSubmit=Savecommit +common.saveAndAdd=Saveandcontinueadding +common.sex=Gender +common.male=Male +common.female=Female +common.address=Address +common.email=Email +common.phone=Mobilephone +common.sms=SMS +common.phoneNumber=Phonenumber +common.server=Server +common.handheld=Mobiledevices +common.success=Success +common.fail=Fail +common.error=Error +common.result=Result +common.expired=Expired +common.valid=Effective +common.inAll=Total +common.allAndNull=SelectAll/Cancel +common.moveTop=Movetop +common.moveBottom=Setattheend +common.moveTopCancle=Unpink +common.ECN=EastChina +common.NCN=NorthChina +common.SCN=SouthChina +common.USA=NorthAmerica +common.SEA=SoutheastAsia +common.noLimit=Notlimited +common.notExists=Doesnotexist +common.cannotWrite=Readonly,notwrite +common.readOnly=Readonly +common.cannotRead=Unreadable +common.ifDel=Yousureyouwanttodeleteit? +common.pageNotExists=Thepagedoesnotexist! +common.pathNotExists=Thefiledoesnotexist! +common.fileShare=Documentsharing +common.logining=Loggingin... +common.loginTokenError=Loginhasexpired,pleaseloginagain! +common.loginSuccess=Loginsuccessful! +common.loginError=Loginfailed +common.connectSuccess=Connectionsucceeded! +common.bindSuccess=Bindsuccessfully! +common.bindError=Bindfailed +common.clear=Empty +common.congrats=Congratulations, +common.sorry=Sorry, +common.invalid=Invalid +common.unavailable=Unavailable +common.format=Format +common.noPermission=Permissiondenied +common.allPermission=Allpermissions +common.invalidParam=Invalidparameter +common.invalidFormat=Invalidformat +common.invalidRequest=Illegalrequesttype +common.illegalRequest=Illegalrequest +common.expiredRequest=Requesthasexpired +common.errorExpiredRequest=Invalidrequestorhasexpired +common.migrating=Migrating +common.migrated=Migrationcomplete +common.maintenanceTips=Duringsystemmaintenance,pleasevisitlater... +common.done=Completed +common.disabled=Disabled +common.sizeTotal=Totalsize +common.sqlStatement=[SQLstatement]: +common.env.check=Environmentaltest +common.env.errorLib=PHPlibraryismissing +common.env.errorIgnore=Ignoreandenter +common.env.errorVersion=PHPversioncannotbelowerthan5.0 +common.env.errorPath=Notwriteable +common.env.errorListDir=Yourwebserverhasthedirectorylistingfunctionenabled.Pleasedisableitforsecurityreasons!Howdoesitwork? +common.env.errorGd=ThePHPGDlibrarymustbeturnedon,otherwisetheuseofverificationcodesandthumbnailswillbeabnormal. +common.env.invalidExt=%sextensionisunavailable,pleasecheckifitisinstalled +common.env.installWithBtTips=Theserverphpversionrequires5.3andabove.Iamnotfamiliarwiththeone-clicksetupoftherecommendedpagodapanel.
    currentversion +common.env.phpCacheOpenTips=Yourserverhasphpcachingenabled,andfileupdateshavenotyettakeneffect;
    Pleaseturnoffthecache,orrefreshthepageandtryagainin1minute!
    Learnmore +common.env.dataPathNotExists=Thedatadirectorydoesnotexist!
    (CheckDATA_PATH); +common.env.pathPermissionError=[ErrorCode:1002]Directorypermissionerror!Pleasesettheprogramdirectoryandallsubdirectoriestoreadandwrite.
    linuxrunsthefollowingcommand:
    su-c'setenforce0'
    chmod-R777 +common.version.free=Free +common.version.nameQ=EnterpriseEdition +common.version.vipFree=Freeedition +common.version.useFree=Continuetousethefreeversion +common.version.notSupport=Yourversiondoesnotsupportthisoperation,pleasegototheofficialwebsitetopurchasetheadvancedversion! +common.version.notSupportNumber=Thisoperationisnotsupportedduetothelimitednumber,pleasegototheofficialwebsitetopurchasetheadvancedversion! +common.version.toVip=UpgradetoCommercial +common.version.license=Purchaselicense +common.version.authCode=Licensecode +common.version.authActive=Activationauthorization +common.version.authorization=Registrationlicense +common.version.authorizeSuccess=Congratulations,theauthorizationforonlineupgradewassuccessful! +common.version.networkError=Therequesttotheserverfailed.Checkwhethertheservercanaccessthenetwork.
    Note:TheservercannotbeaproxytoaccesstheInternet +common.version.authActiveOnline=Activateonline +common.version.authActiveOffline=Activateoffline +common.version.offlineTips=TheservercannotaccesstheInternet? +common.version.menuTitle=Enterpriseinformation +common.version.timeout=Expired +common.version.timeToService=Servicetimeto +common.version.timeTo=Authorizationtimeto +common.version.licenseAll=Perpetualauthorization +common.version.kodVersion=Version +common.version.userLimitTitle=Usernumber +common.version.userUse=Used +common.version.userAllow=Numberofsupported +common.version.userTo=User +common.version.userTitle=Authorization +common.version.basicInfo=Basicinformation +common.version.appInfo=Productinformation +common.version.tipsWarning=Warning,pleasedonotmodifythecopyrightwithoutpermission;ifnecessary,pleasecontacttopurchase! +common.version.tipsCopyLink=Copysuccessfully!Pasteandsavetotxtfile,
    OpenthislinkonacomputerwithanetworkthroughaUSBflashdrive,etc. +common.version.tipsHistory=Thefreeversiononlysupports5historyversions;buyanunlimitednumberoflicensedversions! +common.version.codeLink=Authorizationcoderequestlink +common.version.codeLinkHelp=1.Copytheabovelinkandvisitothercomputerswithinternetaccess.
    2.Fillinthe"AuthorizationAuthenticationCode"obtainedabove,andthenactivateandauthorize +common.copyright.logoTitle=Corporateidentitylogoset +common.copyright.licenseInfo=Authorizationinformation +common.copyright.licenseReset=Reauthorize +common.copyright.licenseResetTips=Reactivateformoreinformation! +common.copyright.formLogo=Loginpagelogotype +common.copyright.formLogoTypeWord=Textlogo +common.copyright.formLogoTypeImage=Picturelogo +common.copyright.formLogoDesc=Thetextlogousesthecompanyname,andtheimagelogousesthepicturesetasfollows. +common.copyright.formLogoImage=Loginpagelogoimage +common.copyright.formLogoImageDesc=Loginpageandmanagementbackgroundlogo,recommendedsize250x100,translucentpngformat +common.copyright.formLogoMain=Maininterfacemenulogo +common.copyright.formLogoMainDesc=Filemanagementupperleftcornerlogo,recommendedsize200x200,whitetranslucentpngformat +common.copyright.formPowerByInfo=Companycopyrightinformationsettings +common.copyright.formPowerBy=Bottomcopyrightcompanyname +common.copyright.formHomePage=Bottomcopyrightlinkjump +common.copyright.formConcat=Pop-upcontact +common.copyright.formDesc=Productpop-uplayerdetaileddescription +common.copyright.formDescTips=Afterthemodificationissaved,therefreshpagetakeseffect +common.copyright.formMetaKeywords=Sitekeywords(usedbysearchengines) +common.copyright.formMetaName=Sitename(usedbysearchengines) +common.copyright.downloadApp=Appdownload +common.copyright.downloadLink= +common.copyright.about=About +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=AutomaticIdentification +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=Arabic +common.charset.ISO_8859_6=Arabic +common.charset.ISO_8859_10=Nordiclanguage +common.charset.CP1257=LanguagesaroundtheBaltic +common.charset.ISO_8859_13=LanguagesaroundtheBaltic +common.charset.ISO_8859_4=LanguagesaroundtheBaltic +common.charset.BIG5_HKSCS=Traditional-HongKong +common.charset.BIG5=Traditional-Taiwan +common.charset.Georgian_Academy=Georgian +common.charset.PT154=Kazakh +common.charset.CP949=Korean +common.charset.EUC_KR=Korean +common.charset.GB18030=SimplifiedChinese +common.charset.GBK=SimplifiedChinese +common.charset.ISO_8859_14=Celtic +common.charset.CP1133=Lao +common.charset.ISO_8859_16=Romanian +common.charset.ISO_8859_3=SouthernEuropeanlanguages +common.charset.EUC_JP=Japanese +common.charset.ISO_2022_JP=Japanese +common.charset.SHIFT_JIS=Japanese +common.charset.KOI8_T=Tajik +common.charset.ISO_8859_11=Thai +common.charset.TIS_620=Thai +common.charset.CP1254=Turkish +common.charset.CP1251=Cyrillic +common.charset.ISO_8859_5=Cyrillic +common.charset.KOI8_R=Cyrillic +common.charset.KOI8_U=Cyrillic +common.charset.CP1252=WesternEuropeanlanguages +common.charset.ISO_8859_1=WesternEuropeanlanguages +common.charset.ISO_8859_15=WesternEuropeanlanguages +common.charset.Macintosh=WesternEuropeanlanguages +common.charset.CP1255=Hebrew +common.charset.ISO_8859_8=Hebrew +common.charset.CP1253=Greek +common.charset.ISO_8859_7=Greek +common.charset.ARMSCII_8=Armenian +common.charset.CP1258=Vietnamese +common.charset.VISCII=Vietnamese +common.charset.CP1250=CentralEuropeanlanguages +common.charset.ISO_8859_2=CentralEuropeanlanguages +common.charset.defaultSet=Fileencoding +common.charset.convertSave=Convertedto +common.date.near=Justnow +common.date.miniteBefore=Minutesago +common.date.today=Today +common.date.yestoday=Yesterday +common.date.before=Before +common.faceDefault=Defaultemoticon +common.loadMore=Loadmore +common.numberLimit=Thequantityexceedsthemaximumlimit! +common.lengthLimit=Thelengthexceedsthemaximumlimit! +common.task.name=Taskmanager +common.task.title=Missionname +common.task.user=Executiveuser +common.task.porcess=Schedule +common.task.start=Starttask +common.task.useTime=Elapsedtime +common.task.running=Executing +common.task.stoping=Paused +common.task.killing=Ending +common.task.stop=Suspendedtask +common.task.kill=Endtask +common.task.removeTips=Areyousuretoendthisoperation? +common.task.killAll=Endall +common.task.killAllTips=Areyousuretoendalltasks? +common.task.timeStart=Startat +common.task.timeNeed=Remainingabout +common.task.timeUse=Alreadyrunning +ERROR_DB_PWD=Databaseaccessdenied:wrongusernameorpassword. +ERROR_DB_TIMEOUT=Databaseconnectiontimedout,pleasecheckiftheaddressiscorrect. +ERROR_DB_CONN_RFS=Databaseconnectionrefused:Incorrectconfigurationinformation,orservicenotstarted. +ERROR_DB_ADR=Databaseconnectionerror,pleasecheckiftheaddressiscorrect. +ERROR_DB_NOT_SUPPORT=Unsupporteddatabasetype,pleasecheckwhetherthecorrespondingserviceorconfigurationfileisnormal. +ERROR_DB_XS_DENNIED=Databaseaccessdenied:insufficientprivileges. +ERROR_DB_NOT_EXIST=Thedatabasedoesnotexist,orthewrongnamewasspecified. +explorer.----=---- +explorer.pathNotSupport=Thistypeofdirectorydoesnotsupportthisoperation! +explorer.pathIsRoot=Youhavereachedtherootdirectory! +explorer.pathNull=Folderisempty +explorer.zipFileLarge=Thefileistoolarge,pleaseunzipitbeforepreviewingit! +explorer.charNoSupport=Unsupportedspecialcharacters: +explorer.moveError=Movefailed +explorer.lockError=Anerroroccurred,concurrentlocktimedout +explorer.lockErrorDesc=Pleasereducetherequestfrequency,oroptimizetheserverconcurrencyrelatedconfiguration,orimprovetheserverhardwareconfiguration; +explorer.moveSubPathError=Somethingwentwrong,theparentdirectorycannotbemovedtothechilddirectory! +explorer.spaceIsFull=Notenoughspaceleft,pleasecontacttheadministrator! +explorer.sessionSaveError=Sessionwritefailed!Pleasecheckifthediskisfull,orconsultyourserviceprovider. +explorer.networkError=Networkconnectionerror(net::ERR_CONNECTION_RESET),connectionhasbeenreset.
    Pleasecontactthehostcompanyornetworkadministratortocheckthefirewallconfiguration! +explorer.folderManage=Managedirectory +explorer.clickEdit=Clicktoedit +explorer.shortLink=Ashortcut +explorer.upper=Upperlayer +explorer.historyNext=Goahead +explorer.historyBack=Back +explorer.loading=Loading... +explorer.getting=Getting... +explorer.sending=Sendingdata... +explorer.pullTips=Pulldowntorefreshthepage +explorer.pullDropTips=Freetorefreshthepage +explorer.getSuccess=Getsuccess! +explorer.saveSuccess=Savedsuccessfully! +explorer.saveError=Savefailed! +explorer.success=Successfuloperation +explorer.error=Operationfailed +explorer.dataError=Thedataisabnormal! +explorer.pathError=Documentpatherror +explorer.repeatError=Operationfailed,thenamealreadyexists! +explorer.systemError=Systemerror +explorer.mistake=Error! +explorer.recycleClear=EmptyRecycleBin +explorer.recycleClearForce=Thereistoomuchcontentintherecyclebin,pleaseemptytherecyclebinfirst! +explorer.recycleRestore=RestoreRecycleBin +explorer.recycleRestoreItem=Reduction +explorer.recycleRestoreAll=Restoreall +explorer.recycleClearInfo=Areyousureyouwanttoemptytherecyclebincompletely? +explorer.zipDownloadReady=Downloadautomaticallyaftercompression,pleasewait... +explorer.removeItem=Itemcontent +explorer.uploading=Uploading +explorer.uploadTipsMore=Toomanyfiles,itisrecommendedtouploadaftercompression,andthendecompressonline! +explorer.uploadingMove=Mergingandtransferring... +explorer.viewNewPage=Newpagepreview +explorer.unknowFileTitle=Fileopeningtips! +explorer.unknowFileTips=Withoutanappthatsupportsthisfile,youcan: +explorer.unknowAppTips=Withouttheapp: +explorer.unknowFileTry=Try +explorer.unknowFileDown=Downloadthefile +explorer.authFileDown=Documentdowload +explorer.authShare=Shared +explorer.usersShare=Ofsharing +explorer.clipboard=Viewclipboard +explorer.clipboardClear=Emptyclipboard +explorer.fullScreen=Fullscreen +explorer.folderItem=Items +explorer.folderItemSelect=Selected +explorer.dbLoadAll=Double-clicktoloadall... +explorer.ziping=Compressing... +explorer.unziping=Decompressing... +explorer.zipingTips=Compressingoperation,pleasewait... +explorer.unzipingTips=Unzippingoperation,pleasewait... +explorer.unzipRarTips=Thecontentofthefileisdamagedortheparsingofthefileisnotsupported.ItisrecommendedtousetheZIPformat. +explorer.parsing=Retrieving... +explorer.moving=Movingoperation... +explorer.copyMove=Copymove +explorer.removeTitle=Deleteconfirmation +explorer.removeInfo=Areyousureyouwanttodeletetheselection? +explorer.removeTitleForce=Deletepermanently +explorer.removeInfoForce=Areyousureyouwanttopermanentlydeletethisdocument? +explorer.pathInRecycle=Thefolderisintherecyclebin,pleaserestoreandtryagain! +explorer.pathInRecycleFile=Thefileisintherecyclebin,pleaserestoreandtryagain! +explorer.downOffline=Downloadoffline +explorer.savePath=Saveroute +explorer.uploadSelectMuti=Selectmultiplefilestoupload +explorer.goTo=Redirectto +explorer.selectFile=Selectthefile +explorer.selectFolder=Selectfolder +explorer.selectImage=Pleaseselectapicture... +explorer.selectValidFolder=Pleaseselectafoldertobevalid! +explorer.selectFolderFile=Selectfileorfolder +explorer.selectMulti=Multiplechoice +explorer.notNull=Requiredfieldscannotbeempty! +explorer.picCannotNull=Pictureaddresscannotbeempty! +explorer.renameSuccess=Renamedsuccessfully! +explorer.inputSearchWords=Pleaseenterthestringtosearch +explorer.search.optionContent=Documentcontent +explorer.search.searchContentTips=Keywordsearchfilecontent,supporttextfile +explorer.search.optionMutil=Bulksearch +explorer.search.optionMutilDesc=Onesearchtermperline,thesearchresultsaresortedaccordingtothesearchterm +explorer.removeSuccess=Successfullydeleted! +explorer.removeFail=Failedtodelete! +explorer.clipboardNull=Clipboardisempty! +explorer.createSuccess=Newsuccess! +explorer.createError=Newcreationfailed,pleasecheckdirectorypermissions! +explorer.copySuccess=[Copy]-Overwriteclipboardsuccessfully! +explorer.cuteSuccess=[Cut]-Overwriteclipboardsuccessfully! +explorer.clipboardState=Clipboardstatus: +explorer.copyOK=Successfullycopied! +explorer.copyNotExists=Sourcedoesnotexist +explorer.currentHasParent=Thedestinationfolderisasubfolderofthesourcefolder! +explorer.pastSuccess=Pasteoperationcompleted +explorer.cutePastSuccess=Cutoperationcompleted +explorer.zipSuccess=Compressioncompleted +explorer.notZip=Notacompressedfile +explorer.zipNull=Nofilesordirectoriesselected +explorer.unzipSuccess=Unzipcomplete +explorer.pathIsCurrent=Theopenedpathisthesameasthecurrentpath! +explorer.pathExists=Thenamealreadyexists! +explorer.serverDownDesc=Tasksaddedtodownloadlist +explorer.parentPermission=Parentdirectorypermissions +explorer.confirm=Areyousure? +explorer.ifSaveFileTips=Arethereanyunsavedfiles? +explorer.ifSaveFile=Thefilehasnotbeensavedyet.Isitsaved? +explorer.ifStopUploadTips=Afileisbeinguploaded,areyousuretoclosethewindow? +explorer.noPermissionRead=Youdonothavereadpermission! +explorer.noPermissionDownload=Youdonothavepermissiontodownload! +explorer.noPermissionWrite=Thedirectorydoesnothavewritepermissions +explorer.noPermissionAction=Youdonothavethispermission,pleasecontacttheadministrator! +explorer.noPermissionWriteAll=Thefileordirectorydoesnothavewritepermission +explorer.noPermissionWriteFile=Thefiledoesnothavewritepermission +explorer.noPermissionReadAll=Thefileordirectorydoesnothavereadpermissions +explorer.noPermission=Theadministratorhasdisabledthispermission! +explorer.noPermissionExt=Anadministratorhasdisabledthistypeoffilepermissions +explorer.noPermissionGroup=Youarenotinthisusergroup! +explorer.pathNoWrite=Thedirectoryisnotwritable,pleasesetthedirectoryandallsubdirectoriestoreadandwriteandtryagain! +explorer.onlyReadDesc=Thisdirectorydoesnothavewritepermissions,youcansetpermissionsonthisdirectoryontheserver +explorer.settingSuccess=Themodificationhastakeneffect! +explorer.noRepeat=Noduplicatesallowed +explorer.dataNotFull=Datasubmissionisincomplete! +explorer.tooManyToView=Containstoomuchcontent(%sitems),pleaseopenitlocallytoview; +explorer.jumpAfterWhile=Automaticallyjumpafter%ss,Jumpimmediately +explorer.retryTips=Pleasecheckandtryagain +explorer.selectObject=Select +explorer.parentGroup=Parent +explorer.actionAuth=Permission +explorer.notSelectDesc=Nodata,pleasechoose! +explorer.groupAuthCopy=Copy +explorer.groupAuthCopyDesc=Copythepermissioncombination +explorer.groupAuthPasteDesc=Pastethecopiedpermissioncombination +explorer.groupAuthSave=Save +explorer.groupAuthRecent=Recently +explorer.selectDesc=Selectcontent +explorer.cannotLoad=Unabletoloadresults. +explorer.loadMore=Loadmoreresults... +explorer.noSearchData=Noresultsfound +explorer.delAllItem=Deleteallitems +explorer.pleaseDel=Pleasedelete +explorer.pleaseInput=Pleaseenteratleast +explorer.canChoose=Onlyselectatmost +explorer.theChars=Characters +explorer.theItems=Items +explorer.noData=Nodata +explorer.ifPathAuthClear=Allsub-fileandfolderpermissionssettingswillbecleared.Areyousureyouwanttocontinue? +explorer.fileDescAdd=Adddocumentdescription +explorer.fileDesc=Documentdescription +explorer.fileLog=Documentlog +explorer.ifResetOpen=Areyousureyouwanttoresetallcustomopeningmethods? +explorer.ResetOpen=Resetallcustomopenmethods +explorer.openWith=Openwith... +explorer.openWithAce=OpenwithEditor +explorer.openWithLocal=Openlocally +explorer.openWithLocalEdit=Localediting +explorer.editorSaveTips=Thefilehasnotbeencreated,pleasesavethenewfilefirst +explorer.editor.fileTooBig=Thefileistoolargeandcannotbelargerthan20M +explorer.errorFunctionTips=Thistypeoffiledoesnotsupportfunctionlists! +explorer.errorFormatTips=Thecurrentfiletypedoesnotmatchthedefaultformattingmethod.
    Pleaseselectmanually +explorer.cuteToThe=Moveto: +explorer.copyToThe=Copyto: +explorer.addToFav=Star +explorer.addFav=Star +explorer.delFav=Unstar +explorer.addFavSuccess=Starsuccessfully +explorer.pathHasFaved=Thepathhasbeenstar +explorer.delFavSuccess=Unstarsuccessfully +explorer.fileLock=Editlock +explorer.fileLockNow=Lock +explorer.fileLockCancle=Unlock +explorer.fileLockTitle=Locked +explorer.fileLockTips=Locked(otherscannoteditthefile) +explorer.fileLockUser=Locker +explorer.fileLockError=Thecurrentfileislocked,pleasecontactthelockertounlockitandtryagain; +explorer.downloaded=Downloadcompleted +explorer.openAutoTips=Willopenautomatically +explorer.historyAutoTips=Automaticallygeneratehistoricalversions +explorer.saved=Savedsuccessfully +explorer.opened=Opensuccessfully! +explorer.openFail=Openfailed! +explorer.openingWithLoc=Fileisopenlocally... +explorer.openOnlyView=Readonlymodeison +explorer.saving=Filesaving... +explorer.notSupport=Somethingwentwrong,thecontentformatisnotsupported! +explorer.unzipErrorTips=Error!Unrecognizedcompressedfileformat;
    Pleasecheckifthefileiscompressedordamaged. +explorer.wordLoading=Loading... +explorer.noFunction=Noway! +explorer.paramFormatError=Parameterformatiswrong! +explorer.descTooLong=Descriptionistoolong +explorer.noMoreThan=Nomorethan +explorer.desktopDelError=Sorry,thedesktopfolderdoesnotsupportdeletion! +explorer.copy=Copy +explorer.past=Paste +explorer.clone=Createacopy +explorer.cute=Cut +explorer.cuteTo=Moveto... +explorer.copyTo=Copyto... +explorer.info=Attribute +explorer.searchInPath=Search +explorer.addToPlay=Addtoplaylist +explorer.manageFav=ManageStar +explorer.refreshTree=Refresh +explorer.zip=Compress +explorer.unzip=Unzipto... +explorer.unzipFolder=Unziptofolder +explorer.unzipThis=Unziptocurrent +explorer.unzipTo=Unzipto... +explorer.openProject=Editoropenproject +explorer.createLink=CreateShortcut +explorer.createLinkHome=Sendtodesktopshortcut +explorer.setBackground=Setasdesktopwallpaper +explorer.favRemove=Unstar +explorer.openPath=Enterthedirectory +explorer.openPathFinished=Alreadyenteredthedirectory +explorer.openIE=Openwithbrowser +explorer.newFile=Newfile +explorer.newFolder=Newfolder +explorer.fileSaveTo=Filesavedto +explorer.openFather=Position +explorer.uploadFile=Uploadfiles +explorer.uploadFolder=Uploadfolder +explorer.appOpenDefault=Openwithdefault +explorer.appOpenAways=Openthisfilealwayswiththeprogramofyourchoice +explorer.appSelectDesc=Choosetheprogramyouwanttousetoopenthisfile +explorer.appSelectMenu=Setasdefaultopenmode +explorer.appSelectMenuCancel=Unsetasdefaultopenwith +explorer.appSelectWarning=Pleaseselectanapplication! +explorer.appTypeSupport=Supportapplications +explorer.appTypeAll=Allapplications +explorer.appSearch=Searchforrelatedappinstalls +explorer.recent.createTime=Createdat +explorer.recent.modifyTime=Modifiedat +explorer.recent.viewTime=Openedat +explorer.urlLink=URL +explorer.downloading=Downloading... +explorer.downReady=Comingsoon +explorer.downError=Downloadfailed! +explorer.max=Maximize +explorer.min=Minimize +explorer.minAll=Minimizeall +explorer.displayAll=Showallwindows +explorer.closeAll=Closeall +explorer.authDtl=Clicktoviewyourpermissionsinthedirectory +explorer.authDialog=Internalmembers,documentpermissionleveltable +explorer.authNote=Note:Managementfunctionsincludesettingmemberpermissions/commentmanagement,etc.Becareful![SystemAdministrator]Roleisnotrestrictedbyanypermissions +explorer.auth.toOuter=Externalauthorization(otherdepartmentsorusers) +explorer.auth.share=Sharer +explorer.auth.owner=Owner +explorer.auth.disableDeep=Nopermission-accessonly +explorer.auth.disableDeepDesc=Thefactordirectoryhasdocumentreadandwritepermissions,andtheestablishedaccesspath. +explorer.auth.tips=Cancontacttheaboveuserstosetpermissionsforyou +explorer.notSystemPath=Isnotasystemfilepath +explorer.toolbar.rootPath=Personal +explorer.toolbar.fav=Starred +explorer.toolbar.desktop=Desktop +explorer.toolbar.client=Client +explorer.toolbar.myComputer=Mycomputer +explorer.toolbar.recycle=Recyclebin +explorer.toolbar.myDocument=Mydocument +explorer.toolbar.myPicture=MyPhotos +explorer.toolbar.myMusic=Mymusic +explorer.toolbar.myMovie=Myvideo +explorer.toolbar.myDownload=Mydownload +explorer.toolbar.uiDesktop=Desktop +explorer.toolbar.uiExplorer=File +explorer.toolbar.uiEditor=Editor +explorer.toolbar.uiProjectHome=ProjectHome +explorer.toolbar.uiLogout=Logout +explorer.toolbar.uiGroup=Organization +explorer.toolbar.myGroup=Mygroup +explorer.toolbar.publicPath=Publicdirectory +explorer.toolbar.recentDoc=Recent +explorer.toolbar.myShare=Myshare +explorer.toolbar.shareToMe=Collaboratewithme +explorer.toolbar.shareTo=Mycollaboration +explorer.toolbar.shareLink=Linksharing +explorer.toolbar.photo=MyAlbum +explorer.photo.desc=Useralbumclassification +explorer.photo.group=Albumgrouping +explorer.photo.setting=Albumsettings +explorer.photo.pathRoot=AlbumScanDirectory +explorer.photo.pathRootSelect=Selectafolderastherootdirectoryforalbumimagescanning +explorer.photo.fileType=Specifyfiletype +explorer.photo.fileSize=Filesizefilter +explorer.photo.fileSizeDesc=Onlyfilterfileslargerthanthissetting,ifitis0,thereisnolimit +explorer.toolbar.folder=Catalogalbum +explorer.toolbar.folderSelect=Selectafoldertodisplayinalbummode +explorer.pathDesc.fav=Afterthefileisaddedtostarred,itcanbeaccessedquicklyanddirectly +explorer.pathDesc.home=Personalspaceisyourprivatestoragespace,Onlyvisibletoyou,nottootherusers +explorer.pathDesc.groupRoot=Thisisthepublicspaceoftheenterprise/unit,Allmembersarevisiblebydefault +explorer.pathDesc.myGroup=Managethedocumentsofyourdepartmenthere,Departmentdocumentsareonlyvisibleandoperablebymembersofthisdepartment,andnotvisibletootherdepartmentmembers +explorer.pathDesc.group=Departmentalnetworkdisk,visibleonlytomembersofthedepartment,Theoperationauthorityisassignedandsetbythedepartmentadministrator. +explorer.pathDesc.recentDoc=Recentlycreated,uploaded,modified,andopenedfiles +explorer.pathDesc.shareTo=Viewandmanageyour[internalcollaboration]projectsinitiatedbyothershere +explorer.pathDesc.shareLink=Viewandmanagetheexternalchainsharinginitiatedbyyouhere +explorer.pathDesc.recycle=Manageyourdeletedfiles(folders)here +explorer.pathDesc.fileType=Categorizefilesbytype,onlyfilesinpersonalspace +explorer.pathDesc.tag=Addtagstofiles(folders)toachieveefficientclassificationandfastquery +explorer.pathDesc.tagItem=Tryaddingalabeltothefile/folder! +explorer.pathDesc.mount=Hereyoucanmanagemultipleback-endstorage,aswellasthedisksmountedontheserver +explorer.pathDesc.shareToMe=Tileddisplay--allthecontentthatIcollaboratedwith +explorer.pathDesc.shareToMeUser=Showbysharer-thecontentthatIcollaboratedwithiscategorizedbytheinitiator +explorer.pathDesc.shareToMeUserItem=Collaborationinitiatedbythisuser +explorer.pathDesc.shareToMeGroup=ThecontentthatIcollaboratewithiscategorizedbythedepartmentwherethefolderislocated +explorer.pathDesc.shareToMeGroupGroup=Collaborativesharingfromthedepartment��snetworkdisk +explorer.pathDesc.search=Supportsearchingfiles/tags/notes/content;Supportpinyin,fuzzymatchingofthefirstletter +explorer.pathDesc.searchMore=Setmoresearchconditions +explorer.pathDesc.shareFrom=Sourcepath +explorer.pathGroup.shareGroup=Departmentalspace +explorer.pathGroup.shareGroupDesc=Accesswhenthereiscontentinthelower-leveldepartment +explorer.pathGroup.shareUser=Personalspacesharing +explorer.pathGroup.shareUserDesc=Source:Userpersonalspacesharing,externaldepartmentdocumentsharinginitiatedbytheuser. +explorer.pathGroup.shareContent=Thedepartment'sspacecollaborationandsharing +explorer.pathGroup.group=Sub-department +explorer.pathGroup.groupContent=DepartmentalDocument +explorer.pathGroup.shareUserOuter=Externalcollaborationsharing +explorer.pathGroup.shareUserOuterDesc=Collaborativesharingofexternalusersnotundertheirownorganizationalstructure +explorer.pathGroup.shareSelf=Personalspace +explorer.toolbar.fileSizeTitle=Iconsize +explorer.toolbar.fileSizeSuper=Tiny +explorer.toolbar.fileSizeSmall=Smallicon +explorer.toolbar.fileSizeDefault=Mediumicon +explorer.toolbar.fileSizeBig=Bigicon +explorer.toolbar.fileSizeBigSuper=Oversizedicon +explorer.toolbar.PagePC=PCversion +explorer.toolbar.pagePhone=Mobileversion +explorer.file.name=Name +explorer.file.type=Type +explorer.file.contain=Contain +explorer.file.address=Position +explorer.file.detil=Description +explorer.file.linkCount=Citations +explorer.file.size=Size +explorer.file.count=Quantity +explorer.file.byte=Byte +explorer.file.path=Path +explorer.file.action=Action +explorer.file.creator=Creator +explorer.file.editor=Editor +explorer.file.location=Location +explorer.file.timeInfo=Time +explorer.file.createTime=Creation +explorer.file.modifyTime=Modification +explorer.file.lastTime=Lastvisit +explorer.file.sortType=Sortby +explorer.file.sortDisable=Thecontentdoesnotsupportspecifiedsorting! +explorer.file.timeType=Y/m/dH:i:s +explorer.file.timeTypeInfo=Y/m/dH:i:s +explorer.file.listType=View +explorer.file.listIcon=Icon +explorer.file.listList=List +explorer.file.listListSplit=Column +explorer.file.listTypeGroup=Displaymodeandsortingmethod +explorer.file.listTypeKeep=Displaymode +explorer.file.listTypeKeepDesc=Selectviewmodeonaper-folderbasis,orusethesameviewmodeforallfolders. +explorer.file.listSortKeep=Sortby +explorer.file.listSortKeepDesc=Configurecolumnsortingorderonaper-folderbasis,orusethesameorderforallfolders. +explorer.file.listViewKeep=Perfolder +explorer.file.listViewAll=Sameforeachfolder +explorer.file.listViewReset=Resettodefault +explorer.file.sortUp=Increasing +explorer.file.sortDown=Decrement +explorer.file.orderType=Sortby +explorer.file.orderDesc=Descending +explorer.file.orderAsc=Ascendingorder +explorer.file.imageSize=Sizeofthepicture +explorer.file.sharer=Sharer +explorer.file.shareTime=Sharetime +explorer.file.viewCnt=Views +explorer.file.downCnt=Downloads +explorer.file.readWriteLock=Thisoperationistemporarilynotsupported,thereareotherreadandwritetasksbeingprocessed,pleasetryagainlater! +explorer.app.app=LightApp +explorer.app.createLink=NewURL +explorer.app.create=Createalightapplication +explorer.app.edit=Editlightapp +explorer.app.open=Openlightapp +explorer.app.groupGame=Game +explorer.app.groupTools=Tool +explorer.app.groupReader=Read +explorer.app.groupMovie=Movie +explorer.app.groupMusic=Music +explorer.app.groupLife=Life +explorer.app.desc=Applicationdescription +explorer.app.icon=Applicationicon +explorer.app.iconShow=Urladdressorthedirectory +explorer.app.group=Applicationgrouping +explorer.app.type=Type +explorer.app.typeUrl=Link +explorer.app.typeCode=Jsextension +explorer.app.display=Exterior +explorer.app.displayBorder=Borderless(selectedisborderless) +explorer.app.displaySize=Resize(selecttoadjust) +explorer.app.size=Size +explorer.app.url=Linkaddress +explorer.app.code=Jscode +explorer.app.appType=ApplicationType +explorer.app.website=URL +explorer.app.shortLink=Fileshortcut +explorer.app.imgIcon=Pictureicon +explorer.app.imgIconUrl=Selectthepictureorpastethewebpictureurl. +explorer.app.path=Path +explorer.app.pathDesc=Doesnotsupportmanualmodification,youcanright-clickthefiletocreateashortcut +explorer.app.link=Websitelink +explorer.app.linkDesc=Pleaseenterhttp/httpslink +explorer.app.linkDragTips=YoucandragtheurllinkintothefileareatoautomaticallycreateaURLlink! +explorer.app.openType=OpenType +explorer.app.openWindow=Newwindow +explorer.app.openDialog=Dialog +explorer.app.openCurrent=Current +explorer.app.openInline=Embed +explorer.app.dialogSize=Dialogsize +explorer.app.with=Width +explorer.app.height=Height +explorer.app.moreSet=Moresettings +explorer.app.canDiyWith=Allowwidthadjustment +explorer.app.miniBlock=Minimalisttitlebar +explorer.app.runCode=Executejscode +explorer.app.name=Applicationname +explorer.app.nameDesc=Pleaseenteranapplicationname. +explorer.app.descDesc=Pleaseenteranapplicationdescription +explorer.embed.title=Embeddedfile +explorer.embed.desc=Embedthefileinawebpageorblog +explorer.embed.url=EmbedURL +explorer.embed.code=Embedcode +explorer.upload.ready=Waitingforupload +explorer.upload.success=Uploadedsuccessfully +explorer.upload.secPassSuccess=Successinseconds +explorer.upload.pathCurrent=Changetothecurrentdirectory +explorer.upload.select=Selectthefile +explorer.upload.maxSize=Maximumallowable +explorer.upload.sizeInfo=Ifyouwanttoconfigurelarger,pleasemodifythemaximumalloweduploadinphp.ini.Whenselectingafile,thoselargerthanthisconfigurationwillbeautomaticallyfilteredout. +explorer.upload.error=Uploadfailed +explorer.upload.mergeError=Mergefilesfailed +explorer.upload.errorHttp=Networkorfirewallerror +explorer.upload.muti=Multi-fileupload +explorer.upload.drag=Draganddropupload +explorer.upload.dragFolder=Draganddroptofoldertoupload +explorer.upload.dragTips=Releasetoupload! +explorer.upload.pathNotAllow=Filenameisnotallowed +explorer.upload.errorNull=Nodocuments! +explorer.upload.errorBig=Filesizeexceedsserverlimit +explorer.upload.errorMove=Failedtomovefiles! +explorer.upload.errorExists=Thefilealreadyexists +explorer.upload.local=LocalUpload +explorer.upload.tips=Usefragmentupload,nolongerlimitedbyphp.ini;chromeexperiencefolderdraganduploadisrecommended +explorer.upload.exist=Duplicatefiles +explorer.upload.clearAll=Clearall +explorer.upload.clear=Emptyingcompleted +explorer.upload.addMore=Addinbulk +explorer.upload.errorEmpty=Cannotbeempty! +explorer.upload.errorExt=Thefileextensionsdonotmatch! +explorer.upload.fileSizeDisable=Therearetoomanyfilesuploaded/transferredatthesametime,pleasecontacttheadministratortoadjust! +explorer.upload.moreDesc=(Recommendednomorethan2000),currentlytotal: +explorer.upload.scan=Scanning +explorer.upload.merge=Verifyingmerge +explorer.upload.needTime=Remainingapprox. +explorer.upload.checkError=Uploadverificationfailed,pleasetryagain +explorer.upload.saveError=Uploadfileinformationfailedtosave +explorer.upload.downloadDesc=Onlysupportshttp/httpsnetworklinks +explorer.table.first=Home +explorer.table.last=Lastpage +explorer.table.prev=Previous +explorer.table.next=Nextpage +explorer.table.one=Total1pages +explorer.table.page=Page +explorer.table.itemPage=/page +explorer.table.searchTotal=Found +explorer.table.items=Records +explorer.table.list=Datasheets +explorer.search.ing=Searching... +explorer.search.result=Searchresults +explorer.search.resultTooMore=Toomanysearchresults,suggestanotherdirectoryorword +explorer.search.resultNull=Nosearchresults! +explorer.search.caseSensitive=Casesensitive +explorer.search.content=Searchfilecontent +explorer.search.extDesc=Entertheextensionstobefiltered,separatedbyspaces. +explorer.search.byItems=Conditionalfiltering +explorer.search.extNull=Unlimitedtype +explorer.search.extFile=Anyfile +explorer.search.extDiy=Customize +explorer.search.inputDesc=Pleaseenterkeywordsorprovidefilters! +explorer.search.path=Thedirectory: +explorer.search.rootPath=Therootdirectory: +explorer.search.range=Scope +explorer.search.allFolder=Allfolders +explorer.search.currentFolder=Currentfolder +explorer.search.ext=Filetype +explorer.search.timeRange=Timelimit +explorer.search.timeAll=Unlimitedtime +explorer.search.lastDay=Lastday +explorer.search.lastWeek=Last7days +explorer.search.lastMonth=Last30days +explorer.search.lastYear=Lastyear +explorer.search.sizeAll=Unlimitedsize +explorer.search.inputNullDesc=Ifnotfilled,itmeansgreaterorlessthanacertainvalue,whichcanbeadecimal. +explorer.search.selectUser=Selectuser... +explorer.search.byUserDesc=Searchbycreator/modifier +explorer.search.total=Found +explorer.search.noResult=Sorry,therearenosearchresults,pleasetryanothersearchterm! +explorer.search.advance=AdvancedSearch +explorer.search.clear=Clearcontent +explorer.history.list=Filehistory +explorer.history.lastModify=LastModified +explorer.history.modifyUser=Modifiedby +explorer.history.noHistory=Nohistoricalversion! +explorer.history.current=Currentversion +explorer.history.detil=Description +explorer.history.detilAdd=Addimprint +explorer.history.uploadNew=Newversion +explorer.history.diff=Comparisonofversions +explorer.history.setCurrent=This is the version before the rollback +explorer.history.delCurrent=Deletethisversion +explorer.history.delAll=Deleteallversionhistory +explorer.history.ifDelAll=Areyousureyouwanttodeleteallhistory? +explorer.history.ifDelCurrent=Deletethisversion? +explorer.history.ifRollback=Areyousureyouwanttorollbacktothisversion? +explorer.history.changeEvent=Historicalversionswitching +explorer.history.before=Before +explorer.history.after=After +explorer.recycle.clearUser=Clearuser'srecyclebin +explorer.recycle.restoreSelect=Restorethis +explorer.recycle.moveTo=Handover +explorer.recycle.config=Recyclesettings +explorer.recycle.configTitle=Recyclesettings +explorer.recycle.configOpen=Openrecyclebin +explorer.recycle.configOpenDesc=Suggesttoopen +explorer.recycle.configCloseInfo=Whendeletingcontent,itwillnotenterthesystemrecyclebin;itwillbedeleteddirectly. +explorer.recycle.configOpenInfo=
  • Personaldocumentsordepartmentaldocuments,aftercompletelydeletingoremptyingtherecyclebin,enterthesystemrecyclebin
  • Thedeletedcontentisclassifiedintheuserordepartmentfolderaccordingtotheuserordepartmentwherethefileislocated,andtheadministratorcanchoosetorestorethesefiles;
  • Thefilesbeforethetimeofautomaticcompletedeletionwillbeautomaticallyemptiedregularly;
  • Note:Thefilesdeletedherecannotberecovered.
  • +explorer.recycle.configClear=Deletecompletelyautomatically +explorer.recycle.restoreConfirm=Areyousuretorestorethedocument?
    Afterrestoring,thedocumentwillbemovedtothetargetrootdirectory +explorer.recycle.moveConfirm=Confirmhandover +explorer.recycle.moveSelectTarget=Selectuserordepartment +explorer.recycle.moveDesc=
  • Handovertothedesignateduserordepartment;itwillmigratetotherootdirectoryoftheobject
  • Afterthehandover,documentdescriptions,exchangesanddiscussions,historicalversionsandotherinformationwillcontinuetoberetained;sharedcollaborationandpermissioninformationwillberemoved
  • +explorer.recycle.taskTitle=Systemrecyclebincleaning +explorer.recycle.taskDesc=Automaticallydeletetherecyclebincontentexceedingthesettimetofreeupstoragespace +explorer.share.add=Addshare +explorer.share.edit=EditShare +explorer.share.remove=Cancelsharing +explorer.share.path=Sharepath +explorer.share.source=Informationsharing +explorer.share.name=Sharetitle +explorer.share.nameDesc=Sharefilenamebydefault,canbecustomized +explorer.share.time=Expiredate +explorer.share.timeLimit=Limitedtime +explorer.share.timeLimitDesc=Willautomaticallyexpireafterthetimelimit +explorer.share.timeDesc=Notsetifempty +explorer.share.pwd=Password +explorer.share.pwdDesc=Nopasswordisset +explorer.share.randomPwd=Random +explorer.share.randomPwdDesc=Onlyextractpasswordtoview,moreprivacyandsecurity +explorer.share.cancel=Cancelsharing +explorer.share.create=Createpubliclink +explorer.share.url=Sharedaddress +explorer.share.noDown=Downloadprohibited +explorer.share.codeRead=Codereading +explorer.share.configSave=Savetheconfiguration +explorer.share.errorParam=Parametererror! +explorer.share.errorUser=Userinformationiswrong! +explorer.share.errorSid=Sharedoesnotexist! +explorer.share.errorTime=Youarelate,thissharehasexpired! +explorer.share.errorPath=Thesharedfiledoesnotexist,ithasbeendeletedormoved! +explorer.share.errorPwd=Wrongpassword! +explorer.share.errorShowTips=Thistypeoffiledoesnotsupportpreview! +explorer.share.expiredTips=Sorry,thissharehasexpired,pleasecontactthesharer! +explorer.share.downExceedTips=Sorry,thesharedownloadsexceededthelimitsetbythesharer +explorer.share.store=SavetoSkyDrive +explorer.share.loginTips=Sorry,thissharemustbeloggedinusertoaccess! +explorer.share.noDownTips=Sorry,thesharerhasdisableddownloading! +explorer.share.noViewTips=Sorry,thissharerhasdisabledpreview! +explorer.share.noUploadTips=Sorry,uploadisdisabledbythissharer! +explorer.share.needPwd=Thissharerequiresapassword +explorer.share.notExist=Sharingdoesnotexist! +explorer.share.viewNum=Browse: +explorer.share.downNum=Downloadtimes +explorer.share.openPage=Opensharedpage +explorer.share.openLink=Open +explorer.share.copyLink=Copy +explorer.share.link=Sharelink: +explorer.share.accessPwd=Accesspassword: +explorer.share.copied=Copied +explorer.share.actionNotSupport=Sharecontent,thisoperationisnotsupported +explorer.share.errorPathTips=Thesharinglinkiswrongorthesharerhascancelledtheexternallink +explorer.share.shareTo=Collaborativesharing +explorer.share.shareToTarget=Collaboratingmember +explorer.share.innerTo=Collaboration +explorer.share.linkTo=Linksharing +explorer.share.selectTarget=Selectusersorgroups +explorer.share.afterShareDesc=Aftersharing,userscanviewitin[SharetoMe]. +explorer.share.openOuterLink=Enable +explorer.share.openOuterLinkDesc=YoucansendlinktoothersviaemailorQQ. +explorer.share.outerLink=URL +explorer.share.advanceSet=Advanced +explorer.share.loginLimit=Needlogin +explorer.share.loginLimitDesc=Onlyinternalmemberscanaccess. +explorer.share.authLimit=Permission +explorer.share.canUpload=Allowupload +explorer.share.notView=Disablepreview +explorer.share.notDown=Disabledownloads +explorer.share.downNumLimit=Downloadlimit +explorer.share.downNumLimitDesc=Thesharinglinkautomaticallyexpiresafterthisnumberoftimes +explorer.share.learnAuth=Documentpermissions +explorer.share.shareToRemove=Areyousuretocancelthiscollaborativesharing?
    Thetargetuserwhosharedwithcannolongerseethecollaborativeshare! +explorer.share.shareLinkRemove=Areyousuretocanceltheexternallinksharing?
    Aftercancellation,theexternallinkwillbeinvalid! +explorer.share.shareToCopy=Copyaccesspath +explorer.share.shareToCopyDesc=Thelinkcanbesenttothecollaboratingpersonandquicklyenterthecollaboration +explorer.share.specifyAuthTips=Inadditiontotheabovespecifiedusers +explorer.share.specifyAuthDesc=Designateduserauthority>Designateduser'sdepartmentauthority>Otherpersonauthority +explorer.share.selfAuthDesc=Cannotmodifyownpermissions,othermanagerscanset +explorer.share.authTypeDesc=Inheritfromparentbydefault +explorer.share.rootPathAuthDesc=Rootgroupsupportuserandgroupselection +explorer.share.subPathAuthDesc=Sub-group,onlyselectusersofthegroup +explorer.share.myAuth=Permissions +explorer.share.othersAuth=Otherpermissions +explorer.share.keepAuth=Keepdefault +explorer.share.specifyAuth=Specifypermissions +explorer.share.userAuth=Userpermissions +explorer.share.specifyUserAuth=Specifyuserpermissions +explorer.share.rptTitle=Ifyoufindillegalandharmfulinformation,pleaseselectthereasonbelowtosubmitareport. +explorer.share.illegal=Illegalinformation +explorer.share.inputRptDesc=Pleaseenterthereasonforreporting +explorer.share.rptSend=Thesubmissionissuccessful,theadministratorwilldealwithitintime +explorer.share.rptSended=Reporthasbeensubmitted,waitingfortheadministratortoprocess +explorer.auth.mutil=Batchespermissions +explorer.auth.mutilTips=Note:Iftheselectedcontentalreadyhaspermission,itwillbeoverwritten. +explorer.auth.mutilDesc=Asthedefaultpermissions +explorer.auth.showMore=Permissiondetails +explorer.auth.tabUser=Departmentmember +explorer.auth.tabChildren=Subfolderpermissions +explorer.auth.tabUserTips=Initialpermissionsofdepartmentmembers +explorer.auth.tabChildrenTips=Contentswithpermissionssetinthisfolder +explorer.auth.resetUser=Overridesettingthisuserpermission +explorer.auth.resetUserBtn=Overridepermissions +explorer.auth.resetUserBtnTips=Overridetheuserandallsub-folders(folders)permissionsinthisfolder +explorer.auth.resetUserHeader=Thelower-levelfoldercontainsthecontentspecifyingtheuser'spermissions,andsetalloverridestotheabovepermissions +explorer.auth.resetUserContiner=Containsthecontentoftheuser'spermission +explorer.auth.resetUserEmpty1=Thereisnocontentforwhichpermissionsaresetforthisuser,noneedtooverride +explorer.auth.resetUserEmpty2=Allchildcontentinheritsthecurrentlevelfolderpermissions +explorer.rename.mutil=Batchrenaming +explorer.rename.nameBefore=Oldname +explorer.rename.nameTo=Renamed +explorer.rename.start=Renamenow +explorer.rename.clearFinished=Clearcompleted +explorer.rename.clearAll=Clearall +explorer.rename.typeReplaceAll=Replaceall +explorer.rename.typePrepend=Appendbefore +explorer.rename.typeAppend=Appendafter +explorer.rename.typeReplace=Replace +explorer.rename.typeChangeCase=ChangeCase +explorer.rename.typeRemove=RemoveChars +explorer.rename.typeReplaceSet=Specifyreplacementinbatch +explorer.rename.typeReplaceSetDesc=Replaceiftheyareequal;eachlineisseparatedbyaspace,andthefilenamedoesnotallowspaces;forexample: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Content +explorer.rename.find=Find +explorer.rename.replaceTo=Replaced +explorer.rename.caseUpperFirst=TitleCase +explorer.rename.caseUpper=Uppercase +explorer.rename.caseLower=Lowercase +explorer.rename.removeStart=Fromstart +explorer.rename.removeEnd=Fromend +explorer.rename.chars=Char +explorer.editor.beautifyCode=Codeformatting +explorer.editor.convertCase=Caseconversion +explorer.editor.convertUpperCase=Converttouppercase +explorer.editor.convertLowerCase=Converttolowercase +explorer.editor.currentTime=Currenttime +explorer.editor.md5=Md5encryption +explorer.editor.qrcode=StringQRcode +explorer.editor.regx=Regularexpressiontest +explorer.editor.chinese=Simplifiedconversion +explorer.editor.chineseSimple=ConverttoSimplifiedChinese +explorer.editor.chineseTraditional=ConverttoTraditionalChinese +explorer.editor.base64=Base64codec +explorer.editor.base64Encode=Base64encoding +explorer.editor.base64Decode=Base64decoding +explorer.editor.url=URLcodec +explorer.editor.urlEncode=URLencoding +explorer.editor.urlDecode=URLdecoding +explorer.editor.unicode=Unicodecodec +explorer.editor.unicodeEncode=Unicodeencoding +explorer.editor.unicodeDecode=Unicodedecoding +explorer.editor.toolsSelectTips=Pleaseselectthecorrectcontenttobeprocessed! +explorer.editor.toolsRandString=Generate32-bitrandomstring +explorer.editor.textEncode=Textencoding/decoding +explorer.editor.textParse=Textprocessing +explorer.editor.timeShow=Timestamptotime +explorer.editor.timeInt=Timetotimestamp +explorer.editor.lineRemoveEmpty=Removeblanklines(includingspaces) +explorer.editor.lineUnoin=Removeduplicaterows +explorer.editor.lineTrim=Removeleadingandtrailingspaces +explorer.editor.lineSort=Sortbyrow(ascendingorder) +explorer.editor.lineReverse=Swapalllinesupanddown +explorer.editor.lineSum=Sum +explorer.editor.lineAverage=Averagevalue +explorer.editor.calc=FreeCalculator +explorer.editor.goToLine=Jumptoline +explorer.editor.keyboardType=Keyboardmode +explorer.editor.fontFamily=Font +explorer.editor.codeMode=Highlightsyntax +explorer.editor.closeAll=Closeall +explorer.editor.closeLeft=Closelefttab +explorer.editor.closeRight=Closerighttab +explorer.editor.closeOthers=Closeother +explorer.editor.wordwrap=Autowrap +explorer.editor.showGutter=Showlinenumber +explorer.editor.charAllDisplay=Showinvisiblecharacters +explorer.editor.autoComplete=Automaticprompt +explorer.editor.autoSave=Autosave +explorer.editor.functionList=Functionlist +explorer.editor.codeTheme=Codestyle +explorer.editor.fontSize=Fontsize +explorer.editor.completeCurrent=Autocompletecurrent +explorer.editor.createProject=Addtoeditorproject +explorer.editor.markdownContent=Contentdirectory +explorer.editor.undo=Revoke +explorer.editor.redo=Anti-revocation +explorer.editor.shortcut=Hotkey +explorer.editor.replace=Replace +explorer.editor.reload=Reload +explorer.editor.view=View +explorer.editor.tools=Tool +explorer.editor.help=Help +explorer.sync.data=Synchronization +explorer.sync.openLoc=Openlocalfolder +explorer.sync.syncing=Syncing +explorer.sync.synced=Complete +explorer.sync.syncedError=Error +explorer.sync.syncStart=Startsyncing +explorer.sync.syncStop=Stopsyncing +explorer.sync.notOpenTips=Youhavenotturnedonlocalsync +explorer.sync.setNow=Setupsynchronizationnow +explorer.sync.error=Uploadfailed +explorer.sync.success=Successful +explorer.sync.statusScan=Scanning +explorer.sync.statusNone=Syncisnotconfigured +explorer.sync.statusScanEnd=Scancompleted +explorer.sync.statusDoing=Synchronizing +explorer.sync.statusDone=Synccomplete +explorer.sync.statusStop=Pause +explorer.sync.clearCacheSuccess=Clearcachesuccessful! +explorer.sync.emptyTask=Nosynchronizationtasks +explorer.sync.openCloud=Opencloudlocation +explorer.sync.openLocal=Openlocally +explorer.sync.statusFiles=Documentprogress +explorer.sync.statusLastTime=Completetime +explorer.sync.configName=Syncsetting +explorer.sync.configClient=Clientsettings +explorer.sync.configAbout=About +explorer.sync.configSyncFrom=Localpath +explorer.sync.configSyncFromDesc=Selectalocalfoldertosync +explorer.sync.configSyncTo=Syncto +explorer.sync.configSyncToDesc=Synctoserverlocation +explorer.sync.configIgnore=Ignoredfiletypes +explorer.sync.configIgnoreDesc=Filesofthistypearenotsynchronized +explorer.sync.autorun=Self-starting +explorer.sync.configThread=Uploadthreads +explorer.sync.configThreadDesc=Numberoffilesuploaded +explorer.sync.configDownloadPath=Downloadpath +explorer.sync.configDownloadPathDesc=Defaultdownloadpath +explorer.sync.configClearCacheAuto=Clearcache +explorer.sync.configClearCacheAutoDesc=AutomaticallyclearthecachefileNdaysago +explorer.sync.configClearCache=Emptythecache +explorer.sync.configChangeSite=Exitthecurrentsite +explorer.sync.configVersion=Version +explorer.sync.configUpdateDesc=ReleaseNotes +explorer.sync.configUpdateCheck=Updates +explorer.sync.confirmReset=Synchronizedirectorymodification,synchronizationinformationwillbereset.Areyousuretosave? +explorer.sync.listClearDone=Clearcompleted +explorer.sync.listClearError=Clearerrorlist +explorer.sync.listRetryAll=Retryall +explorer.async.tipsDisablePath=Doesnotsupportchoosingtosynchronizethepath +explorer.async.tipsIsMoving=Detectedthatalargeamountofcontentiscurrentlybeingmovedorcopiedtothesynchronizeddirectory;
    Itisrecommendedtorefreshthepageforsynchronizationafterlocalcompletion! +explorer.async.tipsStartUser=Startsynchronizationmanually +explorer.download.title=Downloadmanagement +explorer.download.waiting=Waiting +explorer.download.stop=Pausedownload +explorer.download.start=Startdownload +explorer.download.remove=Removetask +explorer.download.stopAll=Pauseall +explorer.download.startAll=Continueall +explorer.download.clearAll=Clearalltasks +explorer.download.doing=Processing +explorer.download.done=Downloadcompleted +explorer.download.clearAllTips=Areyousuretodeletealldownloadtasks? +explorer.tag.name=Filetag +explorer.tag.edit=Tagedit +explorer.tag.add=Createtag +explorer.tag.remove=Areyousureyouwanttodeletethistag? +explorer.tag.inputHolder=Pleaseenteratagname +explorer.tag.addTo=Settags +explorer.tag.default1=Study +explorer.tag.default2=TestData +explorer.tag.default3=Contract +explorer.tag.filter=Filterbylabel +explorer.groupTag.title=Publiclabel +explorer.groupTag.menuTtitle=Publiclabel +explorer.groupTag.titleDesc=Publiclabelwithinthedepartment +explorer.groupTag.empty=Afterthedepartmentadministratorsetsthepubliclabel,itisautomaticallyenabled.Whenthereisnolabelcontent,thepubliclabelisautomaticallyturnedoff! +explorer.tag.pathDesc=Filterbypersonallabel +explorer.groupTag.pathDesc=Filterbydepartmentpubliclabel +explorer.groupTag.removeTypeTips=Areyousuretodeletethisgroup?Alldocumentsassociatedwiththelabelwillberemovedafterdeletion! +explorer.groupTag.removeTagTips=Areyousureyouwanttodeletethetag?Thedocumentassociatedwiththetagwillberemovedafterdeletion! +explorer.groupTag.typeAdd=Addcategory +explorer.groupTag.typeName=CategoryName +explorer.groupTag.addDesc=Afteraddingtags,departmenttagsareautomaticallyenabled,andthemaximumnumberoftagsis1000 +explorer.panel.info=Info +explorer.panel.version=History +explorer.panel.chat=Chat +explorer.panel.log=Log +explorer.panel.meta=Meta +explorer.panel.chatName=Discussion +explorer.panel.chat.send=Send +explorer.panel.chat.noAuth=Youdonothavepermissiontocommentonthisdocument! +explorer.panel.chat.placeholder=Enterhere,[Enter]tosend,[Ctrl+Enter]linefeed +explorer.panel.chat.placeholderCtrl=Enterhere,Ctrl+Entertosend,Entertowrap +explorer.panel.chat.reply=Reply +explorer.panel.chat.empty=Nocomment +explorer.panel.chat.sendTo=Forward +explorer.panel.metaName=Metadataextension +explorer.panel.metaDesc=Properties +explorer.panel.thumbClear=Clearthumbnail +explorer.panel.thumbClearDesc=Clearfilethumbnails,coverarttoregenerate. +explorer.panel.historyName=Historicversion +explorer.panel.historyDesc=Releasenotes +explorer.panel.infoTips=Selectthefile(folder)toviewdetailedproperties +explorer.panel.info.space=Spacecapacity +explorer.panel.info.groupAt=DepartmentLocation +explorer.panel.info.tagEmpty=Notags,clicksettings +explorer.panel.logName=DocumentNews +explorer.panel.logEmpty=Noactivity +explorer.type.doc=Documents +explorer.type.image=Image +explorer.type.music=Music +explorer.type.movie=Video +explorer.type.zip=Archive +explorer.type.others=Other +explorer.secret.title=Documentconfidentiality +explorer.secret.isOpen=Enabled +explorer.secret.isOpenDesc=Enableanddisablesecuritylevelmanagement +explorer.secret.setUser=Secretmanager +explorer.secret.setUserDesc=Specifytheuserwhocansettheconfidentialitylevel(mustbetheownerinthecorrespondingdepartmentatthesametime) +explorer.secret.type=Classificationtype +explorer.secret.add=Addsecuritylevel +explorer.secret.edit=Editsecuritylevel +explorer.secret.name=Classname +explorer.secret.style=Style +explorer.secret.auth=Secretpermission +explorer.secret.authHas=Permissionsinclude +explorer.secret.createUser=Setter +explorer.secret.folderAt=Confidentialfolder +explorer.secret.tips=Thepermissionsarecontrolledbythesecretlevel,andthesecretlevelpermissionsarehigherthanthedocumentpermissions +explorer.secret.tips1=Onlyforthecontentunderthedepartmentalnetworkdisk,theabove-mentionedspecifiedusercansettheconfidentialitylevel(andmustbethefolderowneratthesametime) +explorer.secret.tips2=Allcontentinthelowerlayerofthefolderwiththeconfidentialitylevelisset,andthisauthorityisthehighestauthority +explorer.secret.tips3=Aftersetting,thesecretlevelpermissionishigherthanthedocumentpermission(thedocumentisalsocontrolledbythesecretlevelpermission,thesystemsuperadministratorisnotsubjecttothisrestriction,andthesecretlevelsetterisnotsubjecttothisrestriction) +explorer.secret.tips4=Confidentiallevelpermissions:canbeaddedin\DepartmentandMemberManagement--DocumentRightsManagement\andsetashidden +user.----=---- +user.displayHideFile=Showhiddenfiles +user.displayHideFileDesc=Hiddenfiles:filesstartingwith.,Andhiddenfilenamessetinthebackend; +user.soundOpen=Operatesound +user.animateOpen=Animation +user.recycleOpen=Recyclebin +user.recycleDesc=Deletewillmovetotherecyclebin +user.animateDesc=Youcanclosingwhentheoperationisnotsmooth +user.soundDesc=Openfiles,deletefiles,emptyrecyclebin,etc. +user.thumbOpen=Picturethumbnail +user.thumbDesc=Betterpicturebrowsingexperienceafteropening +user.fileSelect=Fileicon +user.fileSelectDesc=Checkfileonthefileicon +user.fileShowDesc=Showfolderintroduction +user.fileShowDescTips=Iconmode +user.fileOpenClick=Openthefile(folder)asfollows +user.fileOpenClick.dbclick=Openwithdoubleclick +user.fileOpenClick.click=Openbyclicking +user.viewSetting=Showoptions +user.thirdAccount=Third-partyaccount +user.bindAccount=Bindaccount +user.thirdBindFirst=Accounthasnotbeenbound,pleaseuseafterbinding +user.account=Account +user.bind=Bind +user.unbind=Unbind +user.binded=Bound +user.clickBind=Clicktobind +user.clickToBind=Clicktobind +user.clickEditPwd=Clicktomodifypassword +user.userAvatar=Avatar +user.userNickName=Nickname +user.userAccount=Account +user.uploadAvatar=Upload +user.userAvatarCrop=Pleaseselectasuitableareaastheavatar +user.userAvatarExt=OnlysupportsJPG,JPEG,PNGimageformats +user.resetPwdDesc=Forgotyourpassword?Youcan +user.inputEmailCode=Pleaseenteryouremailverificationcode +user.inputSmsCode=PleaseenterSMSverificationcode +user.emailVerifyDesc=Somebusinessesrequireemailverification +user.phoneVerifyDesc=Somebusinessesrequiremobilephoneverification +user.bindOthers=Alreadyboundtoanotheraccount +user.notBind=Notbound +user.regist=Signup +user.notRegist=Notregistered +user.registed=Alreadyregistered +user.signError=Callbacksignatureiswrong +user.repeat=Repeat +user.noRepeat=Cannotrepeat +user.newPwd=Newpassword +user.unAuthFile=Unauthorizedfileaccess +user.unbindWarning=Pleasechangethepasswordbeforeunbinding,otherwisetheaccountwillnotworkproperly +user.isLoginTips=Itisdetectedthatyouarecurrentlyloggedin! +user.isLoginEnter=Enternow +user.ifUnbind=Areyousureyouwanttounbind? +user.bindFirst=Pleasebindyouremailormobilenumberfirst +user.inputNewPwd=Pleaseenteranewpassword +user.inputNewValue=Pleasefillinthenewcontent +user.guestLogin=Touristlogin +user.name=Username +user.nickName=Nickname +user.code=Verificationcode +user.codeError=Verificationcodeerror +user.imgCode=Captcha +user.rootPwd=Setadministratorpassword +user.rootPwdRepeat=Confirmthepasswordagain +user.rootPwdEqual=Thepasswordsdonotmatchtwice! +user.rootPwdTips=Pleasesetanadministratorpassword! +user.pwdError=Wrongusernameorpassword! +user.pwdNotNull=Passwordcannotbeblank! +user.oldPwdError=Theoriginalpasswordiswrong! +user.keepPwd=Rememberme +user.forgetPwd=Forgotpassword +user.directLogin=LoginDirectly +user.moreLogin=Morewaystologin +user.loginNow=Loginimmediately +user.registNow=Signupnow +user.backHome=BacktoHome +user.ifHasAccount=Alreadyhaveanaccount? +user.userEnabled=Accountisdisabledornotyetenabled!Pleasecontacttheadministrator +user.roleError=Theroledoesnotexist,pleasecontacttheadministrator +user.invalidEmail=Youdonothaveavalidemailaddress,pleasecontacttheadministratortomodify +user.codeRefresh=Clickrefresh +user.emailVerify=Mailboxauthentication +user.sendSuccess=Sentsuccessfully +user.sendFail=Failedtosend +user.sendSuccessDesc=Verificationcodesentsuccessfully,pleasegotoview +user.sendFailDesc=Verificationcodefailedtosend,pleasecontactadministrator +user.inputVerifyCode=Pleaseenterverificationcode +user.getCode=Verificationcode +user.inputPwd=Pleaseenterthepassword +user.inputPwdAgain=Pleaseenterthepasswordagain +user.inputNickName=Pleaseenteranickname +user.inputEmail=Pleaseinputtheemailaddress +user.inputPhone=Pleaseenterphonenumber +user.inputPhoneEmail=Pleaseentermobilephone/Email +user.invalidPhoneEmail=Invalidphone/Email +user.findPwd=Retrievepassword +user.inputNotMatch=Theentered%sdoesnotmatchthebound +user.usingDesc=Youareusing +user.improveInfo=Pleasecompletetheinformation +user.codeExpired=Verificationcodehasexpired,pleasegetitagain +user.codeErrorTooMany=Toomanyverificationcodeerrors,pleasere-acquire +user.codeErrorFreq=Sendingfrequencyistoohigh,pleasetryagainlater! +user.codeErrorCnt=Thenumberofsendinghasexceededthelimitandwillbelockedfor%shours. +user.registSuccess=Registrationsuccess +user.waitCheck=Waitingforadministratorreview +user.nameHolder=Pleaseenteryourphonenumber/Email +user.loginNoPermission=Sorry,youdonothavethispermission,pleaseloginwithanaccountwiththispermission! +user.loginFirst=Youarenotloggedin!Pleaseloginfirst +user.bindSignError=Thesignatureisabnormal,pleasetryagain! +user.bindUpdateError=Userinformationupdatefailed,pleasetryagain +user.bindTypeError=Invalidbindingtype +user.bindWxConfigError=Getconfigurationinformationexception +user.loginTimeout=Thecurrentloginhastimedout,pleaseloginagain! +user.theme=Themestyle +user.theme.desc=Automaticrepresentativefollowsystem +user.theme.light=Lightcolor +user.theme.dark=Darkcolor +user.theme.auto=Automatic +user.theme.title=Customthemesettings +user.theme.background=Background +user.theme.image=Image +user.theme.colorBlur=Gradientcolor +user.theme.imageBlur=Imageblurprocessing +user.theme.imageUrl=Themap'saddress +user.theme.colorStart=Startcolor +user.theme.colorEnd=Endcolor +user.theme.colorRadius=Gradientangle +user.theme.themeImage=Backgroundpicture +user.theme.themeImageDesc=Support:pictureurl,cssgradientcolor,followwallpaper +user.theme.imageWall=Followwallpaper +user.wall.random=Randomwallpaper +user.wall.paperDesktop=DesktopWallpapers +user.wall.paperDeskMgt=Desktopwallpapermanagement +user.wall.paperLoginMgt=Loginwallpapermanagement +user.wall.paperLoginTips=Whenthereismorethanonepicture,thebackgroundofthelogininterfacewillrotaterandomly +log-type-create-mkdir=Newfolder +log-type-create-mkfile=Createanewfile +log-type-create-upload=Uploadfiles +log-type-create-copy=Pastefile +log-type-edit=Updatefile +log-type-move=Movefile +log-type-moveOut=Removefiles +log-type-share-shareLinkAdd=Createdanexternallinkshare +log-type-share-shareToAdd=Collaborativesharingturnedon +log-type-share-shareLinkRemove=Closedlinksharing +log-type-share-shareToRemove=Turnoffcollaborativesharing +log-type-share-shareEdit=Editsharing +log-type-rename=Rename +log-type-recycle-toRecycle=Movetorecyclebin +log-type-recycle-restore=Restorefromrecyclebin +log-type-remove=Delete +log-type-addDesc=Modifydescription +log-type-addComment=Postacomment +log-event-create-mkdir=Createdthisfolder +log-event-create-mkfile=Createdthefile +log-event-create-upload=Uploadedthefile +log-event-create-copy=Thefilewascreatedbypasting +log-event-create-mkdir-current=Createdanewfolderhere{0} +log-event-create-mkfile-current=Newfilecreatedhere{0} +log-event-create-upload-current=Uploadedhere{0} +log-event-create-copy-current=Pasted{0}here +log-event-create-mkdir-item=Createdanewfolderin{0}{1} +log-event-create-mkfile-item=Newfilecreatedin{0}{1} +log-event-create-upload-item=Uploaded{1}on{0} +log-event-create-copy-item=Paste{0}to{1} +log-event-create-mkdir-more=Created{0}foldershere +log-event-create-mkfile-more={0}newfilescreatedhere +log-event-create-upload-more={0}filesuploadedhere +log-event-create-copy-more=Pasted{0}fileshere +log-event-create-mkdir-more-at=Created{1}newfoldersin{0} +log-event-create-mkfile-more-at=Created{1}newfilesin{0} +log-event-create-upload-more-at={1}filesuploadedon{0} +log-event-create-copy-more-at=Pasted{0}documentsto{1} +log-event-view-item=Viewed{0} +log-event-edit=Updatedthefile +log-event-edit-item=Editupdated{0} +log-event-edit-more=Editupdated{0}files +log-event-edit-more-user=Editedandupdatedthefile{0}{1}times +log-event-edit-more-at=Editedandupdated{1}filesin{0} +log-event-move=Movethedocumentfrom{0}to{1} +log-event-move-item=Move{0}from{1}to[3] +log-event-move-current=Move{0}from{1}here +log-event-move-more={0}documentsmoved +log-event-move-more-desc=Move{0}from{1}to[3] +log-event-moveOut-more-desc=Removedfrom{0}{1} +log-event-moveOut=Removedfromhere{0} +log-event-moveOut-item=Removedfrom{0}{1} +log-event-moveOut-more={0}documentsremoved +log-event-share-shareLinkAdd=Createdanexternallinktosharethisdocument +log-event-share-shareLinkAdd-item={0}createdanexternallinktoshare +log-event-share-shareLinkAdd-more=Created{0}linkstoshare +log-event-share-shareToAdd=Turnoncollaborativesharingofthisdocument +log-event-share-shareToAdd-item={0}turnedoncollaborativesharing +log-event-share-shareToAdd-more={0}collaborativesharescreated +log-event-share-shareLinkRemove=Closedthedocument'slinksharing +log-event-share-shareLinkRemove-item=Closed{0}linksharing +log-event-share-shareLinkRemove-more=Close{0}externallinksharing +log-event-share-shareToRemove=Turnoffcollaborativesharingofthisdocument +log-event-share-shareToRemove-item=Turnoffcollaborationsharingfor{0} +log-event-share-shareToRemove-more=Close{0}collaborativesharing +log-event-share-shareEdit=Editedtheshareofthisdocument +log-event-share-shareEdit-item=Edited{0}share +log-event-share-shareEdit-more=Edited{0}documentstoshare +log-event-rename=Renamedthedocument +log-event-rename-item=Renamed{0} +log-event-rename-more={0}documentsrenamed +log-event-recycle-toRecycle=Movedthedocumenttothetrash +log-event-recycle-toRecycle-current=Moved{0}totherecyclebinhere +log-event-recycle-toRecycle-item=Moved{1}totherecyclebinon{0} +log-event-recycle-toRecycle-more=Moved{0}documentstoTrash +log-event-recycle-toRecycle-more-at=Moved{1}documentstotherecyclebinon{0} +log-event-recycle-restore=Restorethedocumentfromtherecyclebin +log-event-recycle-restore-item=Restore{0}fromtherecyclebin +log-event-recycle-restore-more=Restore{0}documentsfromtherecyclebin +log-event-remove=Deleted{0}here +log-event-remove-current=Deleted{0}here +log-event-remove-item=Deleted{1}in{0} +log-event-remove-more={0}documentsdeletedhere +log-event-remove-more-at=Deleted{1}documentson{0} +log-event-addDesc=Modifiedthedocumentdescription +log-event-addDesc-item=Modified{0}documentdescription +log-event-addDesc-more=Modified{0}documentdescriptions +log-event-addComment=Commentedonthisdocument +log-event-addComment-item=Commentedon{0} +log-event-addComment-more=Listed{1}commentsin{0} +log-event-fav-fileAdd=Starred{0} +log-event-fav-dirAdd=Starredfolders{0} +log-event-down-item=Downloaded{1}from{0} +log-event-down-items=Downloadedfrom{0} +log-event-recycle-del-item=Delete{0}filesfromrecyclebin +log-event-recycle-rst-item=Restore{0}filesfromtherecyclebin +log-event-del-item={0}filesdeleted +log.file.move=Move/copy +log.file.fav=Starredoperation +log.file.shareLink=Externallinksharing +log.file.shareTo=Collaborativesharing +log.user.edit=Modifyaccountinformation +log.group.edit=Departmentmanagement +log.member.edit=UserManagement +log.role.edit=Rolemanagement +log.auth.edit=Documentrightsmanagement +meta.user_sourceAlias=Relatedfiles(attachments) +meta.user_fileEncodeType=FileConfidentiality +meta.user_fileEncodeType.A=A-Topsecret +meta.user_fileEncodeType.B=B-confidential +meta.user_fileEncodeType.C=C-Secret +meta.user_sourceNumber=Volumenumber +meta.user_sourceParticipant=Participant +explorer.fileInfo.createTime=Creation +explorer.fileInfo.modifyTime=Modified +explorer.fileInfo.softwareCreate=Software +explorer.fileInfo.software=Software +explorer.fileInfo.playTime=Playtime +explorer.fileInfo.imageSize=Size +explorer.fileInfo.imageDpi=Resolution +explorer.fileInfo.imageBits=Bitdepth +explorer.fileInfo.imageDesc=Annotation +explorer.fileInfo.imageAuthor=Creator +explorer.fileInfo.imageColor=Colorspace +explorer.fileInfo.cameraType=Devicemodel +explorer.fileInfo.cameraApertureFNumber=Aperture +explorer.fileInfo.cameraApertureValue=Aperturevalue +explorer.fileInfo.cameraShutterSpeedValue=Shutterspeed +explorer.fileInfo.cameraExposureTime=Exposuretime +explorer.fileInfo.cameraFocalLength=Focallength +explorer.fileInfo.cameraFocusDistance=Focusdistance +explorer.fileInfo.cameraISOSpeedRatings=ISOsensitivity +explorer.fileInfo.cameraWhiteBalance=Whitebalance +explorer.fileInfo.cameraUser=Manual +explorer.fileInfo.cameraAuto=Automatic +explorer.fileInfo.cameraExposureMode=Exposuremode +explorer.fileInfo.cameraExposureBiasValue=Exposurecompensation +explorer.fileInfo.imageGps=Shootinglocation +explorer.fileInfo.imageCreateTime=Shootingdate +explorer.fileInfo.audioChannel=Audiochannel +explorer.fileInfo.audioChannel1=Mono +explorer.fileInfo.audioChannel2=Stereo +explorer.fileInfo.audioChannels=Multichannel +explorer.fileInfo.audioRate=Audiorate +explorer.fileInfo.audioBits=Audiobitdepth +explorer.fileInfo.audioBitrate=Audiobitrate +explorer.fileInfo.vedioFormat=Encoding +explorer.fileInfo.audioTitle=Title +explorer.fileInfo.audioAuthor=Author +explorer.fileInfo.audioAlbum=Album +explorer.fileInfo.audioStyle=Style +explorer.fileInfo.audioYear=Year +explorer.fileInfo.vedioSize=Screensize +explorer.fileInfo.vedioFrame=Framerate +explorer.fileInfo.vedioBitrate=Bitrate +explorer.fileInfo.title=Title +explorer.fileInfo.author=Author +explorer.fileInfo.pageTotal=Totalpages +explorer.fileInfo.pageSize=Pagesize +explorer.fileInfo.pagePower=Creator +explorer.fileInfo.pdfVersion=PDFversion +explorer.filter.shareCopyLimit=Thenumberoffilestobedumpedexceedsthelimit;themaximumnumberoffilesyoucandumpis: +explorer.filter.shareSizeLimit=Thesharedfilesizeexceedsthelimit;themaximumyoucanshareis: +explorer.filter.unzipSizeLimit=Theunzipfilesizeexceedsthelimit;themaximumyoucanunzipis: +explorer.filter.zipSizeLimit=Compressedfilesizeexceedslimit;yourmaximumcompressibledocuments: +explorer.filter.uploadSizeLimit=Theuploadsizeexceedsthelimit;themaximumyoucanuploadis: +explorer.fileEditError=The current file is being edited by %s, please try again later +explorer.groupDelError=Sorry, the group folder does not support deletion +admin.info.typeDelError=Delete failed with subcategories or data +admin.info.domainIdentifyError=Unrecognized website +admin.info.articleIdentifyError=Unrecognized article +admin.info.domainSupportError=This website currently does not support collection +admin.info.fileTooLarge=File too large +explorer.toolbar.info=information +source.shareDisabled=The current resource is prohibited from sharing +admin.exceeds.limit=EXCEEDS LIMIT +admin.design.deleted=Enabling status cannot be deleted +admin.design.url.locked=Locked and temporarily unavailable for use +explorer.SING_INVALID=Signature exception +explorer.TEMP_AUTH_INVALID=Invalid temporary authorization code +explorer.QR_INVALID=QR code has expired +explorer.toolbar.toolbox=toolbox +explorer.toolbox.desc= +logs-detail-mkdir=Erstellt einen neuen Ordner +logs-detail-mkfile=Eine neue Datei erstellt +logs-detail-editFile=Der Editor hat aktualisiert +logs-detail-upload=Hochgeladene Dateien +logs-detail-uploadNew=Bearbeitet +logs-detail-file.upload=Hochladen +logs-detail-file-copy=Erstellte Datei einfügen +logs-detail-folder-copy=Erstellten Ordner einfügen +logs-detail-paste=Paste +logs-detail-from=von +logs-detail-to=Reichweite +logs-detail-rename=Umbenannt +logs-detail-rename-file=Datei umbenannt +logs-detail-rename-folder=Ordner umbenannt +logs-detail-user=Benutzer: +logs-detail-moveFrom-restore=nehmen +logs-detail-moveTo-restore=Wiederherstellen aus dem Papierkorb +logs-detail-move=nehmen +logs-detail-moveTo=Verschieben nach +logs-detail-moveFrom-toRecycle=nehmen +logs-detail-moveTo-toRecycle=In den Papierkorb verschoben +logs-detail-file-toRecycle=Verschiebt die Datei in den Papierkorb +logs-detail-file-restore=Wiederherstellen dieser Datei aus dem Papierkorb +logs-detail-folder-toRecycle=Diesen Ordner in den Papierkorb verschoben +logs-detail-folder-restore=Diesen Ordner aus dem Papierkorb wiederherstellen +logs-detail-favAdd=Gesammelt +logs-detail-favDel=Sammlung abgebrochen +logs-detail-unstar=Name: +logs-detail-moveOut=Entfernt +logs-detail-remove=Entfernt +logs-detail-file.copy=Einfügen +explorer.noPermissionAuthAll={0} ,No permission for this operation diff --git a/src/main/resources/i18n/messages_es_ES.properties b/src/main/resources/i18n/messages_es_ES.properties new file mode 100644 index 0000000..9c36b24 --- /dev/null +++ b/src/main/resources/i18n/messages_es_ES.properties @@ -0,0 +1,2563 @@ +admin.serverInfo=Información del servidor +admin.today=Hoy +admin.yesterday=Ayer +admin.weekDay=Casi 7 días +admin.monthDay=Casi 30 días +admin.ing=En progreso +admin.paused=Suspendido +admin.serverDownload=Descarga remota +admin.memberManage=Gestión de usuarios +admin.fileManage=Gestión de archivos +admin.pwdEdit=Cambiar contraseña +admin.fileEdit=Editar guardar archivo +admin.list=Vista de lista +admin.configError=Error al guardar la configuración, el administrador ha deshabilitado este permiso. +admin.userManage=Centro personal +admin.manage=Gestión de antecedentes +admin.pluginManage=Gestión de complementos +admin.emailDear=Hola %s, +admin.emailCodeText=Está verificando su dirección de correo electrónico. El código de verificación para esta solicitud es el siguiente. Para garantizar la seguridad de su cuenta, complete la verificación a tiempo. +admin.emailVerifyInTime=Para proteger la seguridad de su cuenta, complete la verificación a tiempo. +admin.dear=Respeto +admin.dearUser=Estimado usuario +admin.emailResetLink=Está restableciendo la contraseña de inicio de sesión para %s por correo electrónico, haga clic en el enlace a continuación para restablecerla. Si el enlace no salta, cópielo en la barra de direcciones de su navegador para acceder a él: +admin.emailExpireTime=El enlace caduca después de 20 minutos. +admin.jobName=Título del trabajo +admin.jobDesc=Descripción del puesto +admin.jobNameInput=Por favor ingrese un nombre de trabajo +admin.jobEdit=Editor de publicaciones +admin.menu.home=Inicio +admin.menu.dashboard=Resumen +admin.menu.dashboardTitle=Resumen de estadísticas +admin.menu.notice=Gestión de notificaciones +admin.menu.groupMember=Departamento y gestión de miembros +admin.menu.member=Departamentos y usuarios +admin.menu.role=Gestión de roles +admin.menu.job=Gestión laboral +admin.menu.auth=Gestión de derechos de documentos +admin.menu.storage=Almacenamiento / archivo +admin.menu.storageDriver=Gestión de almacenamiento +admin.menu.plugin=Centro de complementos +admin.menu.tools=Control de seguridad +admin.menu.server=Gestión del servidor +admin.menu.backup=Gestión de copia de seguridad +admin.menu.share=Gestión de compartir +admin.menu.loginLog=Registro de inicio de sesión +admin.menu.log=Registro de operaciones +admin.menu.task=Tareas programadas +admin.autoTask.restart=Reiniciar las tareas programadas +admin.autoTask.restartEnd=La tarea programada se ha reiniciado +admin.index.userSpace=Espacio de usuario +admin.index.groupSpace=Espacio del departamento +admin.index.folderCount=Cantidad de carpetas: +admin.index.fileCount=Numero de archivos: +admin.index.loginToday=Inicie sesión hoy +admin.index.useTotal=Uso total: +admin.index.userLogin=Inicio de sesión de usuario +admin.index.spaceUsed=Ocupar espacio +admin.index.useSpace=Usa el espacio +admin.index.usedSpace=Espacio utilizado +admin.index.freeSpace=espacio restante +admin.index.sizeLimit=Tamaño limitado +admin.index.vipCount=Usuarios registrados +admin.index.loginCurrent=Actualmente en línea +admin.index.fileDel=Eliminación de archivos +admin.index.fileEdit=Edición de archivos +admin.index.fileUpload=Subir archivo +admin.index.fileDown=Descargar documento +admin.index.spaceUse=Uso práctico +admin.index.spaceSave=Ahorrar espacio +admin.index.spaceUser=Uso del usuario +admin.index.spaceGroup=Uso del departamento +admin.index.lastLogin=Última hora de inicio de sesión +admin.index.totalUsers=Usuarios totales +admin.index.loginUsers=Usuario de inicio de sesión +admin.index.spaceActUsed=Ocupación real +admin.index.source=Fuente de inicio de sesión +admin.index.address=Dirección de acceso +admin.index.userInfo=Información de usuario +admin.index.userValid=Cuenta valida +admin.index.userInvalid=Cuenta no válida +admin.index.fileInfo=Informacion del archivo +admin.index.fileCnt=Número de archivos +admin.index.fileAdd=Agregado hoy +admin.index.accInfo=Informacion de acceso +admin.index.accCnt=Peticiones +admin.index.accUser=Usuario de acceso +admin.index.serverInfo=Mensaje del sistema +admin.index.serverDisk=Disco del sistema +admin.index.serverStore=Almacenamiento en red +admin.index.serverName=nombre del servidor +admin.index.normal=normal +admin.index.scoreDesc=Los siguientes factores afectarán la puntuación del sistema, que se puede optimizar para garantizar que el sistema funcione bien:
    1. El espacio restante del disco del sistema y el almacenamiento en disco de la red;
    2. Método de almacenamiento en caché de datos (se recomienda redis);
    Versión de la plataforma 3.php (se recomienda php7 + de 64 bits). +admin.index.fileRatio=Ratio de uso de archivo +admin.setting.system=Configuraciones del sistema +admin.setting.account=Configuraciones de cuenta +admin.setting.theme=Configuraciones de tema +admin.setting.wall=Configuraciones de papel tapiz +admin.setting.stats=Estadísticas de uso +admin.setting.safeMgt=Administración de Seguridad +admin.setting.base=Ajustes básicos +admin.setting.others=Otras configuraciones +admin.setting.sync=Configuraciones de sincronización +admin.setting.plugin=Configuraciones de complementos +admin.setting.auth=Configuración de permisos +admin.setting.safe=Configuraciones de seguridad +admin.setting.loginLog=Registro de inicio de sesión +admin.setting.loginDevice=Dispositivo de inicio de sesión +admin.setting.deviceType=Tipo de equipo +admin.setting.lastLoginTime=Última hora de inicio de sesión +admin.setting.email=Configuraciones de correo electrónico +admin.setting.user=Registro e inicio de sesión +admin.setting.pwdOld=Contraseña original +admin.setting.pwdNew=Modificar a +admin.setting.wallDiy=Fondo de pantalla personalizado: +admin.setting.fav=Gestión de favoritos +admin.setting.help=Usa la ayuda +admin.setting.about=Sobre trabajos +admin.setting.homePage=casa de kodcloud +admin.setting.subMenu=Submenú +admin.setting.menuName=Nombre del menú +admin.setting.menuUrl=Dirección URL +admin.setting.menuUrlDesc=dirección url o código js +admin.setting.safeAccount=Seguridad de cuenta e inicio de sesión +admin.setting.safeData=Seguridad de datos / seguridad de transmisión +admin.setting.passwordErrorLock=Bloqueo de error de entrada de contraseña +admin.setting.passwordErrorLockDesc=Si la contraseña es incorrecta durante 5 veces consecutivas, la cuenta se bloqueará durante 1 minuto y no se le permitirá iniciar sesión. Después de abrirla, puede evitar que la contraseña se rompa por fuerza bruta; +admin.setting.passwordRule=Configuración de seguridad de contraseña de usuario +admin.setting.passwordRuleDesc=Después de que se especifica la seguridad de la contraseña, la contraseña débil se puede eliminar efectivamente +admin.setting.passwordRuleNone=Ilimitado +admin.setting.passwordRuleStrong=Intensidad media +admin.setting.passwordRuleStrongMore=Alta resistencia +admin.setting.passwordRuleNoneDesc=Contraseña ilimitada +admin.setting.passwordRuleStrongDesc=La longitud es mayor que 6; debe contener tanto inglés como números; +admin.setting.passwordRuleStrongMoreDesc=La longitud es mayor que 6; debe contener números, inglés en mayúscula, inglés en minúscula; +admin.setting.passwordRuleTips=Su contraseña actual no es lo suficientemente segura, ¡se recomienda cambiar la contraseña de inmediato! +admin.loginCheck.menu=Control de inicio de sesión +admin.loginCheck.ipCheck=Restricciones de IP +admin.loginCheck.ipCheckNone=no limitado +admin.loginCheck.ipCheckAllow=Lista blanca de IP +admin.loginCheck.ipCheckDisable=Lista negra de IP +admin.loginCheck.loginIpAllowDesc=Después de abrir, solo los usuarios con la IP especificada pueden iniciar sesión, tenga cuidado +admin.loginCheck.ipAllow=IP permitida +admin.loginCheck.ipAllowDesc=Complete las reglas de la siguiente manera (en cada línea, la IP local del servidor está permitida de forma predeterminada y el administrador del sistema permite la IP de LAN) +admin.loginCheck.ipDisable=Reglas de IP de lista negra +admin.loginCheck.ipDisableDesc= +admin.loginCheck.ipDescTitle=Complete las reglas de la siguiente manera (una línea por entrada) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=prioridad +admin.loginCheck.name=Nombre de la regla +admin.loginCheck.user=Usuario designado +admin.loginCheck.device=Equipo designado +admin.loginCheck.deviceWeb=Web +admin.loginCheck.devicePc=Lado de la PC +admin.loginCheck.deviceAndroid=Androide +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc=
    Instrucciones de control de restricciones de inicio de sesión de usuario (restricciones de dispositivos e IP):
  • Detectar en secuencia de acuerdo con el orden de prioridad de la regla; el usuario especificado por la regla incluye el usuario actualmente conectado; luego, la regla se determina como resultado
  • Se recomienda colocar los grupos de usuarios y los usuarios departamentales en la parte posterior, y especificar la configuración del usuario en el frente; (arrastre y suelte para ajustar el orden)
  • +admin.setting.checkCode=El código de verificación de inicio de sesión está activado +admin.setting.checkCodeDesc=Después de iniciar sesión, debe ingresar el código de verificación. +admin.setting.csrfProtect=Habilitar protección csrf +admin.setting.csrfProtectDesc=Puede prevenir efectivamente los ataques csrf cuando está habilitado +admin.setting.setRootPath=Acceso a la raíz +admin.setting.setRootPathDesc=Solo el administrador del sistema puede acceder a todos los directorios, y los usuarios de otros grupos de permisos solo pueden ver sus propios directorios de usuarios.
    Si desea habilitar o deshabilitar el acceso del administrador a otros directorios, puede modificar el parámetro open_basedir cross-site de PHP, cómo configurar +admin.setting.encode=Cifrado de almacenamiento de archivos +admin.setting.encodeAll=Cifrar todo +admin.setting.encodeName=Mantener la extensión +admin.setting.encodeNone=Sin cifrado +admin.setting.encodeAllDesc=Cifrado completo: [recomendación predeterminada]; incluso si tiene permisos de servidor, no puede conocer el verdadero contenido del archivo; puede proteger eficazmente contra ransomware y otros daños; +admin.setting.encodeNameDesc=Conservar extensión: cifrado de nombre de archivo, conservar extensión +admin.setting.encodeNullDesc=Sin cifrado: el nombre del archivo no está cifrado y el nombre del archivo original se conserva (para garantizar la seguridad, la carpeta de carga se denomina estructura cifrada); +admin.setting.encodeTips1=Solo los archivos después del cambio de configuración se ven afectados, los archivos que existieron antes no se ven afectados; +admin.setting.encodeTips2=Para evitar errores, no elimine ni cambie el nombre de los archivos en datos / archivos; +admin.setting.encodeTips3=Para admitir concurrencia a gran escala, segunda transmisión, agrupación, distribución, expansión automática y otras funciones; la jerarquía de carpetas se registra en la base de datos; la estructura de carpetas se puede importar y restaurar copiando y pegando +admin.setting.thirdLogin=Inicio de sesión de terceros +admin.setting.thirdLoginDesc=Permitir el registro, enlace e inicio de sesión a través de cuentas de terceros +admin.setting.registOpen=Registro de usuario abierto +admin.setting.registOpenDesc=Para evitar conflictos de datos, la sincronización de datos de terceros y el registro de usuarios no se pueden habilitar al mismo tiempo +admin.setting.registCheck=Revisión de registro abierto +admin.setting.registCheckDesc=Después de abrir, el administrador debe revisarlo y habilitarlo en [Usuarios y departamentos] para que los usuarios registrados lo usen normalmente +admin.setting.clearUserRecycle=Vaciar todas las papeleras de reciclaje del usuario +admin.setting.clearCache=Borrar caché +admin.setting.icp=Copyright o número de registro +admin.setting.icpDesc=Si necesita generar un enlace, puede agregar una etiqueta usted mismo +admin.setting.globalCss=CSS global personalizado +admin.setting.globalCssDesc=Todas las páginas insertarán CSS personalizado +admin.setting.globalHtml=Código Estadístico HTML +admin.setting.globalHtmlDesc=Todas las páginas insertarán este código html, y se puede colocar el código de estadísticas de terceros +admin.setting.dateFormat=formato de fecha +admin.setting.dateFormatDesc=Visualización del formato de hora año-mes-día, hora de modificación del archivo, etc. +admin.setting.menu=Gestión de menú +admin.setting.systemName=Nombre del producto de la compañía +admin.setting.systemNameDesc=Para el título del logotipo del producto +admin.setting.systemDesc=Subtítulo del producto +admin.setting.pathHidden=Exclusión de directorio +admin.setting.pathHiddenDesc=Directorios y archivos que no se muestran por defecto, separados por comas +admin.setting.defaultFolder=Los nuevos usuarios crean directorios por defecto +admin.setting.defaultFolderDesc=Separado por comas +admin.setting.defaultApp=Los nuevos usuarios crean aplicaciones por defecto +admin.setting.defaultAppDesc=Aplicaciones del centro de aplicaciones, múltiples separadas por comas +admin.setting.autoLogin=Inicio de sesión automático +admin.setting.autoLoginDesc=El usuario de inicio de sesión predeterminado es el usuario de guest / guest ; asegúrese de que este usuario existe después de abrir +admin.setting.firstIn=Ingrese por defecto después de iniciar sesión +admin.setting.registReviewOpen=Auditoría de registro abierto: +admin.setting.registRoleEmpty=El rol de permiso no puede estar vacío +admin.setting.registNotSync=Para evitar conflictos de datos, la sincronización de datos de terceros y el registro de usuarios no se pueden habilitar al mismo tiempo +admin.setting.registNeedRewiew=Una vez abierto, el administrador debe revisarlo y habilitarlo en los usuarios y departamentos antes de que los usuarios registrados puedan usarlo normalmente. +admin.setting.roleRight=Permisos de rol +admin.setting.emailHost=Servidor de buzones +admin.setting.emailHostInput=Por favor ingrese la dirección del servidor de correo +admin.setting.emailHostTips=Por favor complete la dirección del servidor de correo +admin.setting.emailHostDesc=Servidor de buzón, como: smtp.163.com, el puerto se puede personalizar (el valor predeterminado es 465) +admin.setting.emailSend=Bandeja de salida +admin.setting.emailSendInput=Por favor ingrese la dirección de correo electrónico +admin.setting.emailSendTips=Por favor complete la dirección de correo electrónico de envío +admin.setting.emailSendDesc=Dirección de correo electrónico del sistema, el servicio POP3 / SMTP debe estar habilitado +admin.setting.emailPwd=Contraseña de autorización +admin.setting.emailPwdTips=Por favor complete la contraseña de autorización de correo electrónico +admin.setting.secureType=Cifrado +admin.setting.emailSendTest=Enviar detección +admin.setting.ensureEmailOk=Asegúrese de que el correo se pueda enviar normalmente +admin.setting.emailTo=Bandeja de entrada +admin.setting.emailGoToTips=Por favor vaya al buzón +admin.setting.emailCheckTips=Ver +admin.setting.emailInputError=Configuraciones de correo electrónico incorrectas +admin.setting.emailPwdError=La contraseña de configuración del correo electrónico es incorrecta +admin.setting.emailDesc=Configure un servidor de correo para el registro de usuarios, envío de correo electrónico de recuperación de contraseña +admin.setting.sendEmail=Enviar correo +admin.setting.sendEmailDesc=Valor predeterminado del sistema: llame para enviar el servidor de correo en la nube para enviar; personalizado: configure el servidor de correo usted mismo +admin.setting.systemBackup=Sistema de copia de seguridad +admin.setting.enableFunction=Funciones e interruptores +admin.setting.treeOpen=Cambio de función del directorio de árbol +admin.setting.treeOpenDesc=Gestión de archivos, función correspondiente del directorio de árbol activada y desactivada global +admin.setting.groupListChild=Lista de subsectores +admin.setting.groupListChildDesc=Si la carpeta del departamento muestra subdepartamentos, los permisos se heredan hacia arriba +admin.setting.groupRootListChild=El disco web de la empresa enumera subsectores +admin.setting.groupRootListChildDesc=Si la carpeta del disco de la red corporativa muestra subdepartamentos y los permisos se heredan hacia arriba +admin.setting.shareToMeAllowTree=Colaborar conmigo, mostrar por estructura organizativa +admin.setting.shareToMeAllowTreeTips=Después de la apertura, el soporte de contenido para la colaboración conmigo se clasifica de acuerdo con la estructura organizativa del departamento, lo que es adecuado para situaciones en las que la estructura organizativa es más compleja. +admin.setting.groupTagAllow=Etiqueta pública del departamento +admin.setting.groupTagAllowTips=Después de habilitar, todos los miembros del departamento serán visibles después de configurar la etiqueta pública para los archivos en el departamento. El administrador del departamento puede mantener el contenido de la etiqueta. +admin.setting.shareToMeList=Pantalla en mosaico +admin.setting.shareToMeGroup=Mostrar por estructura organizativa +admin.setting.shareToMeUser=Mostrar por participante +admin.setting.sysSrvState=El estado del servidor +admin.setting.sysSrvInfo=información del servidor +admin.setting.sysPhpInfo=Información PHP +admin.setting.database=base de datos +admin.setting.cache=Cache +admin.setting.sysMyInfo=mi informacion +admin.setting.srvStateCpu=uso de CPU +admin.setting.srvStateMem=Uso de memoria +admin.setting.srvStateSrv=Espacio de almacenamiento del sistema del servidor +admin.setting.srvStateDef=El espacio de almacenamiento predeterminado del disco de red +admin.setting.srvInfoName=nombre del servidor +admin.setting.srvInfoIp=Servidor IP +admin.setting.srvInfoTime=Tiempo de Servidor +admin.setting.srvInfoUpTime=Tiempo de funcionamiento continuo +admin.setting.srvInfoWeb=Software de servidor +admin.setting.srvInfoPhpV=Versión PHP +admin.setting.srvInfoSys=Sistema servidor +admin.setting.srvInfoPath=Ruta del sitio +admin.setting.srvPhpDtl=Detalles de PHP +admin.setting.memLimit=Limite de memoria +admin.setting.postLimit=Límite de envío POST +admin.setting.uploadLimit=Subir restricciones de archivos +admin.setting.execTime=Tiempo máximo de ejecución +admin.setting.inputTime=Tiempo máximo de solicitud +admin.setting.disFunction=Deshabilitar función +admin.setting.phpExtSugst=Extensiones PHP recomendadas +admin.setting.phpExtLoad=Extensión cargada +admin.setting.myClientIp=Mi IP +admin.setting.myClientUa=Mi navegador UA +admin.setting.myClientLng=El idioma de mi navegador +admin.setting.disFuncDesc=Funciones requeridas por el sistema, se recomienda habilitar +admin.setting.srvMemFree=Memoria restante +admin.setting.srvMemUse=Usar memoria +admin.setting.srvCpuUse=Actualmente ocupado +admin.setting.srvCpuFree=No usado +admin.setting.noLimit=Ilimitado +admin.setting.disFunNo=No +admin.setting.systemCache=Caché del sistema +admin.setting.systemDb=Base de datos del sistema +admin.setting.sysCacheTab=Interruptor de caché +admin.setting.sysDbTab=Cambio de base de datos +admin.setting.sysRecTab=Recuperación de la base de datos +admin.setting.cacheDesc=Descripción de la caché +admin.setting.fileCacheDesc=Caché de archivo: escriba datos directamente en el archivo de caché, adecuado para pruebas o uso a pequeña escala. +admin.setting.redisDesc=Redis: una base de datos no relacional de valor clave de alto rendimiento, adecuada para situaciones de lectura y escritura de alta concurrencia. Recomendado para su uso. +admin.setting.memcachedDesc=Memcached: un sistema de caché de objetos de memoria distribuida de alto rendimiento, adecuado para lecturas concurrentes altas. +admin.setting.saveAfterTest=Después de pasar la prueba, se puede guardar +admin.setting.checkPassed=Aprobado +admin.setting.ifSaveCache=Después de cambiar, se borrarán todos los datos en caché.
    ¿Estás seguro de que quieres ejecutar? +admin.setting.ifSaveDb=El conmutador de la base de datos importará los datos actuales del sistema a la nueva base de datos y la establecerá como predeterminada. ¿Estás seguro de que quieres ejecutarlo? +admin.setting.dbCurrent=Configuración actual +admin.setting.dbType=Tipo de base de datos +admin.setting.dbName=Base de datos de nombres +admin.setting.dbInfo=Información de la base de datos +admin.setting.dbSwitch=Encender +admin.setting.dbSwitchDesc=Después de abrir, puede cambiar el tipo de base de datos según sea necesario; opere con precaución. +admin.setting.dbTable=ficha de datos +admin.setting.dbCnt=total +admin.setting.dbNeedNew=La base de datos ya existe, vuelva a especificar +admin.setting.dbInsertError=No se pudieron escribir los datos de la tabla +admin.setting.dbNeedOthers=Seleccione otro tipo de base de datos +admin.setting.dbNeedChange=Modifique los parámetros de configuración +admin.setting.dbCreateError=Falló la creación del archivo de base de datos, verifique los permisos de lectura y escritura del directorio +admin.setting.dbTaskProcess=Progreso de ejecución +admin.setting.dbTasking=Ser ejecutado +admin.setting.dbTaskDesc=No cierre la ventana ni realice otras operaciones en el sistema para evitar generar datos discrepantes. +admin.setting.recTaskDesc=No cierre la ventana. Después de que se interrumpa la solicitud, el fondo continuará ejecutándose hasta que finalice la tarea. +admin.setting.dbCreate=Nueva base de datos +admin.setting.dbSelect=Leer base de datos +admin.setting.dbInsert=Escribir en la base de datos +admin.setting.dbSetSave=Guardar información de configuración +admin.setting.recDesc=Instrucciones de uso +admin.setting.recDescInfo11=Esta operación restablecerá los datos del sistema, la no operación y el mantenimiento o el personal técnico relacionado no debe operar. +admin.setting.recDescInfo21=Al escribir la base de datos de respaldo en la nueva base de datos y establecerla como predeterminada del sistema, se logra la recuperación de datos. +admin.setting.recDescInfo22=Los nuevos parámetros de configuración de la base de datos se agregarán al archivo de configuración del sistema config / setting_user.php. Si el sistema es anormal después de que se ejecuta la recuperación, la parte adjunta del archivo se puede eliminar sin afectar los datos del sistema anterior. +admin.setting.recDescInfo23=Esta función solo admite el procesamiento de los datos de respaldo generados por la administración de respaldo del sistema, y la base de datos respaldada por usted debe procesarse de otras formas. +admin.setting.recDescInfo31=Nota: Cuando el tipo de base de datos es MySQL, se creará una nueva biblioteca (biblioteca original name_current date_rebuild) basada en la información de configuración actual. Es posible que los usuarios no root no tengan los permisos suficientes, por lo que primero debe configurar los permisos para el usuario. +admin.setting.recDescInfo32=Por ejemplo, la información de configuración de la base de datos actual es: usuario: kod; contraseña: kod123. Utilice la cuenta raíz para iniciar sesión en la base de datos y ejecutar la instrucción SQL correspondiente para establecer los permisos (los permisos se pueden revocar después de que se pasa la prueba y la recuperación es exitosa). +admin.setting.recDescInfo33=Configuración de permisos: +admin.setting.recDescInfo34=Revocar permisos: +admin.setting.recOpen=Encienda la recuperación +admin.setting.recOpenDesc=Una vez encendido, puede seleccionar la base de datos respaldada para restaurar según sea necesario. Por favor, opere con precaución. +admin.setting.recTypeDesc=Depende del tipo de sistema utilizado actualmente +admin.setting.recPath=Directorio de respaldo de la base de datos +admin.setting.recPathErr=Directorio de respaldo de base de datos no válido +admin.setting.ifSaveRec=La restauración de la base de datos importará los datos de la copia de seguridad a la nueva base de datos y la establecerá como predeterminada.
    ¿Estás seguro de que quieres ejecutarlo? +admin.setting.recDiyPathErr=Cuando utilice la auto-copia de seguridad para restaurar, seleccione el archivo de base de datos para realizar la copia de seguridad +admin.setting.recDiyFileNull=El archivo de la base de datos está vacío +admin.setting.recDiyPhpErr=Para que usted mismo haga una copia de seguridad de SQLite, seleccione el archivo de base de datos formateado como php +admin.setting.recDiySqlErr=Para que usted mismo haga una copia de seguridad de MySQL, seleccione el archivo de base de datos formateado como sql +admin.setting.recSysPathErr=Cuando utilice la gestión de copias de seguridad para restaurar, seleccione el directorio de la base de datos de copias de seguridad +admin.setting.recSysTbErr=El directorio de respaldo de la base de datos no es válido o falta el archivo de estructura de la base de datos +admin.setting.recDbFileErr=El archivo de biblioteca seleccionado no coincide con el sistema o falta una tabla de datos válida +admin.setting.dbFileDown=Leer archivo de biblioteca +admin.setting.dbFileDownErr=No se pudo leer el archivo de la biblioteca +admin.notice.waiting=Esperando el empujón +admin.notice.done=Empujado +admin.notice.time=Tiempo de empuje +admin.notice.target=Objeto de empuje +admin.notice.level=Nivel de aviso +admin.notice.level0=Insinuación débil +admin.notice.level1=Aviso fuerte +admin.notice.levelDesc=Recordatorio débil: se muestra un punto rojo en la barra de notificaciones en la esquina inferior izquierda; recordatorio fuerte: aparecerá una notificación directamente después de que el usuario inicie sesión. +admin.notice.targetAuth=Elija enviar a todos o enviar a usuarios, grupos de usuarios y grupos de permisos específicos +admin.notice.title=Título del mensaje +admin.notice.content=Contenido del mensaje +admin.notice.timeType=Método de empuje +admin.notice.timeNow=Empuje inmediatamente +admin.notice.timePlan=Empuje programado +admin.notice.listTitle=Notificación de noticias de la estación +admin.notice.clearAll=Vaciar todo +admin.notice.noMsg=No hay noticias +admin.notice.ifClearAll=¿Está seguro de que desea borrar todos los mensajes? +admin.group.role=Identidad de rol +admin.group.name=Nombre del departamento +admin.group.parent=Departamento superior +admin.group.authShow=El alcance de la estructura organizativa visible para los miembros del departamento. +admin.group.authShowAll=Todos los departamentos +admin.group.authShowHide=Solo este departamento y subdepartamento +admin.group.authShowSelect=Departamento designado +admin.group.authShowAllTips=Cuando los miembros de este departamento colaboran para compartir, pueden seleccionar todos los demás departamentos (y usuarios) +admin.group.authShowHideTips=Cuando los miembros de este departamento colaboran y comparten, solo se admite el departamento y el subdepartamento (y los usuarios) actuales +admin.group.authShowSelectTips=Cuando los miembros del departamento colaboran y comparten, pueden seleccionar el departamento y subdepartamento designados (y el usuario), incluido el departamento y subdepartamento actual +admin.group.addSub=Agregar subsector +admin.group.remove=Eliminar departamento +admin.group.switch=Departamento de Migración +admin.group.swtichDesc=Migre usuarios y archivos del departamento seleccionado (y sus subdepartamentos) al departamento de destino. +admin.group.switchSameError=El departamento de destino no puede ser el mismo que el departamento seleccionado +admin.group.switching=Migrando, por favor espere... +admin.group.groupSwitching=El departamento seleccionado está migrando +admin.group.parentNullError=El departamento superior no puede estar vacío +admin.group.selected=Departamento seleccionado +admin.group.setSizeBatch=Establecer el tamaño del espacio en lotes +admin.group.multiSelect=Se pueden seleccionar varios departamentos para la configuración por lotes +admin.group.ifDisAll=Se inhabilitarán todos los subdepartamentos. ¿Está seguro de que desea ejecutarlo? +admin.member.manage=Usuarios y departamentos +admin.member.add=Nuevo usuario +admin.member.role=Rol de autoridad +admin.member.group=Departamento +admin.member.groupAdd=Agregar departamento +admin.member.groupEdit=Departamento editorial +admin.member.remove=Eliminar usuario +admin.member.import=Agregar a granel +admin.member.enable=Habilitar +admin.member.batchSet=Operaciones masivas +admin.member.groupRemove=Eliminar del departamento +admin.member.groupInsert=Agregar al departamento +admin.member.groupSwitch=Migrar al departamento +admin.member.groupTarget=Departamento objetivo +admin.member.groupReset=Restablecer departamento +admin.member.groupSwtichDesc=Migrar usuarios seleccionados del departamento actual al departamento de destino +admin.member.roleSet=Configuración de roles de permisos +admin.member.sizeSet=Ajuste del tamaño del espacio +admin.member.name=Cuenta de inicio de sesión +admin.member.nickName=Apodo del usuario +admin.member.userInfo=Información del usuario +admin.member.userImport=Importar usuarios a granel +admin.member.uploadFirst=Sube el archivo primero +admin.member.downTpl=Descargar plantilla +admin.member.downTplDesc=, Complete el formato de la plantilla y cárguelo. +admin.member.uploadInvalid=No hay datos válidos en el archivo cargado, verifique y cargue nuevamente +admin.member.uploadDataInvalid=Los datos de carga no son válidos o caducaron, cargue nuevamente +admin.member.importSuccess=Importación completa +admin.member.importFail=Importación fallida +admin.member.importFailDesc=Éxito: {0}; Fracaso: {1} +admin.member.importName=Cuenta de inicio de sesión (obligatorio, único) +admin.member.importNickName=Apodo (único) +admin.member.importPwd=Se requiere contraseña) +admin.member.importSex=Género (Masculino-1, Femenino-0) +admin.member.importPhone=Número de móvil (único) +admin.member.importEmail=Correo electrónico (solo) +admin.member.groupRemoveTips=Los usuarios de este grupo de usuarios no pueden iniciar sesión después de la eliminación
    (Necesita restablecer el grupo de usuarios), ¿está seguro de que desea continuar? +admin.member.memberRemoveTips=Después de la eliminación, el directorio de usuarios se moverá a la papelera de reciclaje del sistema,
    Estás seguro de que quieres continuar? +admin.member.selectUserTips=Seleccione la cuenta para operar +admin.member.ifRemoveGroup=¿Estás seguro de que deseas eliminar a los usuarios seleccionados de este grupo? +admin.member.importDesc=Un usuario por línea,
    Ignorar automáticamente si ya existe +admin.member.roleAdminTips=Nota: el administrador del sistema no está controlado por permisos +admin.member.space=Establecer el tamaño del espacio del usuario +admin.member.spaceTips=0 no está restringido +admin.member.spaceTipsDefault=(GB) 0 no está limitado +admin.member.spaceTipsFull=No restringido +admin.member.spaceSize=Tamaño del espacio +admin.member.spaceSizeUse=Uso del espacio +admin.member.memberAdd=Agregar usuario +admin.member.allAdd=Agregar usuario o departamento +admin.member.nullNotUpdate=Dejar en blanco +admin.member.search=Buscar usuarios (cuenta / apodo / correo electrónico / teléfono) +admin.member.searchUser=Buscar usuarios (admite pinyin y coincidencia difusa) +admin.member.searchGroup=Departamento de búsqueda (admite pinyin y coincidencia difusa) +admin.member.searchAll=Buscar usuarios o departamentos (admite pinyin y coincidencia difusa) +admin.member.editNoAuth=Lo sentimos, no tienes este permiso,
    Solo los administradores del sistema pueden agregar y modificar administradores del sistema +admin.member.disabledUsers=Cuenta deshabilitada +admin.member.disabledTips=Cambiar departamentos para desmarcar +admin.member.userGroup=Departamento de usuario +admin.member.userRole=Rol del usuario +admin.member.userSelected=Usuarios seleccionados +admin.member.authCopy=Copiar permisos de departamento +admin.member.authPaste=Pegar permiso de departamento +admin.member.ifAuthPaste=¿Está seguro de que desea establecer los permisos del departamento copiado para el usuario actual? +ERROR_USER_NOT_EXISTS=El usuario no existe +ERROR_USER_PASSWORD_ERROR=Contraseña incorrecta +ERROR_USER_EXIST_NAME=El nombre de usuario ya existe +ERROR_USER_EXIST_PHONE=El número de teléfono ya existe. +ERROR_USER_EXIST_EMAIL=El buzón ya existe +ERROR_USER_EXIST_NICKNAME=El apodo ya existe +ERROR_USER_LOGIN_LOCK=Lo sentimos, hay demasiados intentos de contraseña y la cuenta actual está bloqueada. ¡Inténtalo de nuevo en 1 minuto! +ERROR_IP_NOT_ALLOW=Su IP actual o dispositivo de acceso no tiene permitido iniciar sesión, por favor contacte al administrador +user.passwordCheckError=¡El formato de contraseña no cumple con las reglas de seguridad de contraseña! +admin.role.administrator=Administrador de sistema +admin.role.group=Administrador de departamento +admin.role.default=usuario general +admin.role.ignoreExt=Restricciones de extensión +admin.role.ignoreExtDesc=Tipos de archivos que no pueden cargarse, no hay restricciones en vacío +admin.role.ignoreFileSize=Subir límite de tamaño de archivo +admin.role.ignoreFileSizeDesc=Carga máxima de archivo único, 0 es ilimitado +admin.role.ignoreExtTips=Lo sentimos, la configuración actual del sistema no admite este tipo de carga de archivos; ¡comuníquese con el administrador para obtener más detalles! +admin.role.ignoreFileSizeTips=Lo sentimos, cuando el archivo excede el límite de tamaño; ¡comuníquese con el administrador para obtener más detalles! +admin.role.desc=Descripción del rol +admin.role.adminDesc=Súper administrador, tiene derechos de administración del servidor; ¡todas las configuraciones de archivos y carpetas no son válidas para este usuario! +admin.role.read=Leer +admin.role.readList=Lista de archivos +admin.role.readInfo=Vista de atributo de archivo (carpeta), búsqueda de carpeta +admin.role.readCopy=Copia de archivo +admin.role.readPreview=Vista previa de archivo (imágenes, documentos, audio y video, etc.) +admin.role.readDownload=Descarga de archivo (carpeta) +admin.role.write=Escribir +admin.role.writeAdd=Crear archivos (carpetas), comprimir y descomprimir archivos +admin.role.writeChange=Cambiar el nombre, ajustar la estructura del directorio +admin.role.writeUpload=Carga de archivo (carpeta), descarga remota +admin.role.writeRemove=Archivo (carpeta) borrar, cortar +admin.role.adminSetDesc=El administrador del sistema tiene todos los permisos, ¡no es necesario configurarlo! +admin.role.displayDesc=Si se debe mostrar al configurar roles de usuario +admin.role.defaultRoleDesc=Consejo: El sistema tiene roles incorporados de manera predeterminada y no admite permisos de modificación. Puedes crear nuevos roles +admin.role.actionSetTitle=Documentación y configuración +admin.role.userSetTitle=Datos de configuración del usuario +admin.role.adminSetTitle=Funciones de fondo +admin.role.fileAdd=Nuevo archivo (carpeta) +admin.role.fileRemove=Borrado de documentos +admin.role.fileMove=Mover (copiar / cortar / pegar / arrastrar) +admin.role.userConfig=Modificación de configuración (establecer avatar / cambiar contraseña, etc.) +admin.role.userEdit=Editar usuario (agregar / modificar / eliminar) +admin.role.userFav=Operación de favoritos +admin.role.itemEdit=Agregar / modificar / eliminar +admin.role.groupEdit=Editar departamento (agregar / modificar / eliminar) +admin.role.delErrTips=¡El personaje se está utilizando y no se puede eliminar! +admin.authFrom.setUser=Especifique sus propios permisos +admin.authFrom.setGroup=Especificar la autoridad del departamento +admin.authFrom.setAll=Otros permisos de usuario +admin.authFrom.groupAt=Autoridad departamental +admin.authFrom.groupParent=Autoridad superior del departamento +admin.authFrom.pathOnly=Solo acceso, el nivel inferior tiene contenido y permiso +admin.authFrom.groupRoot=directorio raíz del departamento +admin.auth.owner=Propietario +admin.auth.editor=Editor +admin.auth.editUploader=Editar / cargador +admin.auth.viewer=Espectador +admin.auth.previewer=Vista previa +admin.auth.uploader=Cargador +admin.auth.invisible=Invisible +admin.auth.user=Datos del usuario +admin.auth.pathDelete=Eliminación de archivos +admin.auth.pathInfo=Atributos de archivo +admin.auth.pathMove=Mover (copiar / cortar / pegar / arrastrar) +admin.auth.canUpload=Subir descargar +admin.auth.config=Datos de configuración +admin.auth.fav=Operación de favoritos (agregar / editar / eliminar) +admin.auth.extWarning=La carga de dichos archivos no está permitida,
    Renombrar (renombrado a la extensión especificada),
    Editar guardar, descargar remotamente, descomprimir +admin.auth.error=Error de rol de permiso (sin configuración de permisos) +admin.auth.errorAdmin=Autoridad insuficiente +admin.auth.targetError=El tipo de objeto de permiso es incorrecto, debe ser usuario o departamento +admin.auth.errorAuthToGroup=Departamento no root, no admite delegación a departamentos +admin.auth.errorAuthToUsers=Sector no root, no admite delegación a miembros fuera del sector +admin.auth.displayDesc=Si se debe mostrar al configurar los permisos de usuario del departamento +admin.auth.defaultAuthDesc=Consejo: El sistema tiene un grupo de permisos incorporado de manera predeterminada y no admite la modificación de permisos. Puedes crear nuevos grupos de permisos +admin.auth.show=Lista de archivos +admin.auth.showAction=Vista de lista de archivos +admin.auth.view=Vista previa de archivo +admin.auth.viewAction=Vista previa de archivo abierto +admin.auth.download=Descargar / copiar +admin.auth.downloadAction=Descargar / copiar / previsualizar archivo imprimir +admin.auth.uploadAction=Carga de archivos (carpeta) / descarga remota +admin.auth.edit=Editar nuevo +admin.auth.editAction=Nuevo archivo (carpeta) / Cambiar nombre / Pegar a carpeta / Editar archivo / Establecer notas / Crear copia / Descomprimir +admin.auth.removeAction=Cortar / copiar / mover +admin.auth.shareAction=Cadena externa compartida / colaboración compartida con otros +admin.auth.comment=Comentarios de documentos +admin.auth.commentAction=Ver comentarios del documento; agregar / eliminar sus propios comentarios (se requiere permiso de edición) +admin.auth.event=Dinámica de documentos +admin.auth.eventAction=Visualización dinámica de documentos, suscripción dinámica +admin.auth.root=Derechos administrativos +admin.auth.rootAction=Establecer permisos de miembros / gestión de comentarios / gestión de versiones de historial +admin.auth.delErrTips=¡Este permiso se está utilizando y no se puede eliminar! +admin.plugin.center=Centro de complementos +admin.plugin.installed=Instalado +admin.plugin.type=Categoría +admin.plugin.typeFile=Mejora de archivo +admin.plugin.typeSafe=Herramientas de seguridad +admin.plugin.typeTools=Utilidad +admin.plugin.typeMedia=Multimedia +admin.plugin.typeCompany=Aplicación empresarial +admin.plugin.typeOem=Personalización exclusiva +admin.plugin.needNetwork=Extranet +admin.plugin.install=Instala el complemento +admin.plugin.enable=Habilitar complemento +admin.plugin.remove=Desinstalar el complemento +admin.plugin.config=Configurar complemento +admin.plugin.statusEnabled=Habilitado +admin.plugin.statusDisabled=No habilitado +admin.plugin.statusNotInstall=No instalado +admin.plugin.installing=Instalando ... +admin.plugin.hasUpdate=Actualización +admin.plugin.updateStart=Complemento de actualización +admin.plugin.needConfig=Requiere configuración inicial para habilitar +admin.plugin.notNull=¡Los campos obligatorios no pueden estar vacíos! +admin.plugin.auther=Autor +admin.plugin.downloadNumber=Instala +admin.plugin.back=Volver +admin.plugin.detail=Descripción +admin.plugin.resetConfig=Restaurar la configuración predeterminada +admin.plugin.installSelf=Instalación manual +admin.plugin.updateSelf=Actualización manual +admin.plugin.updateAll=Actualizar todo +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=Error de red. Compruebe si el servidor puede acceder a Internet. +admin.plugin.auth=Derechos de uso +admin.plugin.authDesc=Haga que todos estén disponibles o especifique usuarios, grupos de usuarios y grupos de permisos +admin.plugin.authOpen=Acceso abierto +admin.plugin.authOpenDesc=Se puede acceder sin inicio de sesión, se puede utilizar para llamadas de interfaz externa +admin.plugin.authAll=Todos +admin.plugin.authUser=Usuario especificado +admin.plugin.authGroup=Departamento designado +admin.plugin.authRole=Especificar grupo de permisos +admin.plugin.openWith=Estilo abierto +admin.plugin.openWithDilog=Diálogo interno +admin.plugin.openWithWindow=Se abre una nueva página. +admin.plugin.fileSort=Prioridad de asociación de extensión +admin.plugin.fileSortDesc=Cuanto mayor es la extensión, mayor es la prioridad +admin.plugin.fileExt=Formatos de archivo compatibles +admin.plugin.fileExtDesc=Extensión asociada al complemento +admin.plugin.tabServer=Configuración del servidor +admin.plugin.defaultAceEditor=Editor de Ace +admin.plugin.defaultHtmlView=Vista previa web +admin.plugin.defaultZipView=Descompresión en línea +admin.plugin.authViewList=Lista de complementos +admin.plugin.authStatus=Abrir cerrar +admin.plugin.authInstall=Instalar / desinstalar +admin.plugin.disabled=El complemento no existe o no se ha iniciado +admin.plugin.menuAdd=Ya sea para agregar al menú principal +admin.plugin.menuAddDesc=Úselo como una aplicación independiente +admin.plugin.menuSubMenuDesc=Reducir en el menú [Más] +admin.storage.type=Tipo de almacenamiento +admin.storage.local=Local +admin.storage.localStore=Almacenamiento local +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=Siete nubes de vaca +admin.storage.s3=Amazon S3 +admin.storage.ftp=FTP +admin.storage.oos=Tianyi Cloud OOS +admin.storage.moss=Hongshan MUSGO +admin.storage.eos=XSKY EOS +admin.storage.nos=Antiguo NOS en la nube +admin.storage.minio=MinIO +admin.storage.uss=Toma otro USS nube +admin.storage.eds=Cantó por EDS +admin.storage.driver=Disco local +admin.storage.useage=Uso del espacio +admin.storage.default=Establecer como predeterminado +admin.storage.current=Valor predeterminado actual +admin.storage.edit=Almacenamiento de configuración +admin.storage.setConfig=Modificar configuración +admin.storage.moveData=Migrar datos +admin.storage.delStore=Desmontar almacenamiento +admin.storage.ifMove=Este almacenamiento contiene {0} archivos de disco de red y se migrarán al almacenamiento predeterminado actual. ¿Desea continuar? +admin.storage.ifDel=¿Está seguro de que desea desmontar la tienda actual? +admin.storage.ifDelWithFile=Este almacenamiento contiene {0} archivos de disco de red, que se migrarán al almacenamiento predeterminado actual cuando se eliminen. ¿Desea continuar? +admin.storage.sysFile=Archivos de disco de red: archivos en el espacio personal y departamentos +admin.storage.delErrTips=Correcto:%s; Fallo:%s, intente nuevamente o migre manualmente +admin.storage.delLocTips=Mantenga al menos una tienda local +admin.storage.delStoreTips=Este almacenamiento contiene datos de copia de seguridad, procéselos antes de continuar. +admin.storage.nameDesc=Nombre de almacenamiento para distinguir el almacenamiento diferente +admin.storage.path=Directorio de almacenamiento +admin.storage.pathLocDesc=Directorio de almacenamiento de archivos, asegúrese de que el directorio lleno tenga permisos de lectura y escritura +admin.storage.pathDesc=Directorio de almacenamiento de archivos +admin.storage.defaultDesc=El elemento predeterminado es el único almacenamiento válido del sistema. Si eliges habilitarlo, otros métodos de almacenamiento predeterminados se cancelarán automáticamente. Por favor, opera con precaución +admin.storage.forceEdit=Modificación obligatoria +admin.storage.editTips=Después de abrir, puede editar los campos de modificación prohibidos. El archivo antes del almacenamiento puede no ser accesible, tenga cuidado. +admin.storage.folderTips=La ubicación actual de almacenamiento de archivos del sistema, opere con precaución +admin.storage.sizeTips=El tamaño del espacio debe ser mayor que 0 +admin.storage.sizeDesc=(GB), complete de acuerdo con el espacio libre real del directorio de almacenamiento seleccionado +admin.storage.region=Área de almacenamiento +admin.storage.domain=Nombre de dominio espacial +admin.storage.bucket=Nombre del cubo +admin.storage.bucketDesc=Nombre del depósito completado al crear espacio +admin.storage.userName=Nombre de cuenta +admin.storage.userPwd=Contraseña de la cuenta +admin.storage.server=Dirección del servidor +admin.storage.serverDesc=ftp (s): // ip, el valor predeterminado es ftp sin protocolo +admin.storage.refer=Referencia: +admin.storage.endpoint=Punto final +admin.storage.ossDomain=Nombre de dominio vinculado en el espacio OSS +admin.storage.ossKeyDesc=ID de clave de acceso de la cuenta de Alibaba Cloud, cree o visualice en [Panel de control-Gestión de claves de acceso] +admin.storage.ossSecretDesc=Acceso clave secreta de la cuenta de Alibaba Cloud +admin.storage.ossEndpoint=Endpoint, si usa un nodo de intranet, debe habilitar la transferencia del servidor +admin.storage.cosKeyDesc=ID de clave de acceso de la cuenta de Tencent Cloud, cree o visualice en [Panel de control-Gestión de acceso-Gestión de clave API] +admin.storage.cosSecretDesc=Acceso clave secreta de la cuenta Tencent Cloud +admin.storage.qiniuDomain=Nombre de dominio limitado por Qiniu Space +admin.storage.qiniuKeyDesc=Clave de acceso para la cuenta Qiniu, cree o visualice en [Panel de control-Centro personal-Gestión de claves] +admin.storage.qiniuSecretDesc=Clave secreta para la cuenta Qiniu, el método de obtención es el mismo que el anterior +admin.storage.qnz0=Este de China - Zhejiang +admin.storage.qnz02=Este de China - Zhejiang 2 +admin.storage.qnz1=Norte de China - Hebei +admin.storage.qnz2=Sur de China - Guangdong +admin.storage.qnna0=América del Norte - Los Ángeles +admin.storage.qnas0=Asia Pacífico - Singapur +admin.storage.qnas02=Asia Pacífico - Seúl +admin.storage.awsDomain=Nombre de dominio vinculado en el espacio de AWS +admin.storage.awsKeyDesc=ID de clave de acceso de la cuenta de AWS, créelo en [Panel de control: sus credenciales de seguridad] +admin.storage.awsSecretDesc=Acceso clave secreta para la cuenta de AWS +admin.storage.oosDomain=Nombre de dominio de Tianyi Cloud Space +admin.storage.oosKeyDesc=ID de clave de acceso de la cuenta de Tianyi Cloud, créelo en [Panel de control: sus credenciales de seguridad] +admin.storage.oosSecretDesc=El secreto de la clave de acceso de la cuenta en la nube Tianyi es el mismo que el anterior +admin.storage.ftpDisabled=FTP no está disponible, habilite la extensión php_ftp +admin.storage.ifDefaultTips=Esta operación cancelará otros métodos de almacenamiento predeterminados. ¿Estás seguro? +admin.storage.spaceUsed=Uso práctico +admin.storage.spaceLave=Cantidad restante +admin.storage.delError=El archivo ya existe en esta tienda y no se puede eliminar. +admin.storage.corsError=Si la configuración es correcta, haga clic en [Usar ayuda] para verificar la configuración de dominio cruzado del depósito. +admin.storage.saveError=No se puede conectar al almacenamiento especificado, verifique si la información de configuración es correcta. +admin.storage.ftpCharset=Codificación del servidor FTP +admin.storage.ftpCharsetDesc=Si el servidor FTP es Windows, se puede configurar en GBK según la situación; +admin.storage.ftpPasvOn=Encender +admin.storage.ftpPasvOff=cierre +admin.storage.ftpPasv=Modo pasivo +admin.storage.ftpPasvDesc=Modo de transferencia de datos +admin.storage.uploadSrv=Transferencia de servidor (carga) +admin.storage.fileoutSrv=Transferencia de servidor (descargar) +admin.storage.uploadSrvDesc=Una vez activado, el archivo se cargará en el almacenamiento de objetos a través del servidor; de lo contrario, se cargará directamente a través del cliente. +admin.storage.fileoutSrvDesc=Una vez encendido, el archivo de almacenamiento se obtendrá a través del servidor para su descarga; de lo contrario, el archivo se obtendrá para su descarga directa. +admin.storage.closeDefError=Prohibir apagar el almacenamiento predeterminado +admin.storage.ussBucket=Nombre del Servicio +admin.storage.ussBucketDesc=Nombre del servicio de almacenamiento en la nube +admin.storage.ussUser=Nombre del operador +admin.storage.ussUserDesc=Nombre del operador +admin.storage.ussUserPwd=Contraseña de operador +admin.storage.ussDomain=Tome otra foto del nombre de dominio vinculado al espacio de la nube +admin.storage.ussToken=Ficha anti-sanguijuelas +admin.storage.ussTokenDesc=Token clave secreta de cadena antirrobo (no requerida) +admin.storage.configError=¡El parámetro de configuración es anormal! +admin.storage.sizePercent=Relación de archivos del sistema: +admin.storage.fileCount=Número de archivos: +admin.storage.error=excepción de almacenamiento +admin.task.name=Nombre de la tarea +admin.task.edit=Edición de tareas +admin.task.type=Tipo de tarea +admin.task.method=Métodos incorporados +admin.task.methodName=Nombre del método +admin.task.methodDesc=Consiste en el nombre del método del módulo del controlador del sistema, complete cuidadosamente. +admin.task.url=URL de solicitud +admin.task.urlDesc=Dirección URL definida por el usuario, tareas programadas para ejecutar solicitudes regularmente. +admin.task.cycle=Ciclo de ejecución +admin.task.desc=detalles de la misión +admin.task.nMinutes=N minutos +admin.task.default=Sistema predeterminado +admin.task.timeInterval=Tiempo de intervalo +admin.task.timeStart=Hora de inicio +admin.task.timeStartRun=Iniciar tiempo de ejecución +admin.task.timeLastRun=Último tiempo de ejecución +admin.task.timeLastLogin=Tiempo de inicio de sesión +admin.task.isOpen=Ya sea para habilitar +admin.task.open=Abierto +admin.task.content=Contenido de implementación +admin.task.param=Parámetro de ejecución +admin.task.ifRun=¿Seguro que quieres ejecutar esta tarea? +admin.task.backup=copias de seguridad +admin.task.backupDesc=Comience a hacer copias de seguridad de los datos del sistema a las 02:00 todos los días. +admin.install.install=Instalación del sistema +admin.install.databaseSet=Configuración de la base de datos +admin.install.dataUpdate=Migración de datos +admin.install.installSuccess=Instalado exitosamente +admin.install.dbWasSet=Ha configurado la base de datos. Si necesita restablecer, puede modificar la configuración en el archivo config / setting_user.php y reinstalarla. +admin.install.errorRequest=El sistema está instalado, no se permiten más solicitudes +admin.install.databaseError=Error de conexión a la base de datos, verifique la configuración +admin.install.cacheError=%s falló la conexión, verifique la configuración +admin.install.cacheConnectError=%s no puede conectarse al servidor, verifique la configuración +admin.install.dbSetError=Error de escritura de información de configuración de la base de datos +admin.install.dbCreateTips=La base de datos no existe y la creación automática falla. Créala manualmente +admin.install.ifDelDb=Los datos ya existen en la base de datos especificada. Haga clic en [Aceptar] para eliminarlos. Quieres continuar +admin.install.dbCreateError=Excepción de creación de tabla de datos +admin.install.dbFileError=El archivo de la base de datos no existe. +admin.install.dbTypeError=El tipo de base de datos seleccionado (%s) no está disponible, instale el servicio y la extensión correspondientes, o elija otro tipo +admin.install.createSuccess=Creado con éxito +admin.install.defSetError=La configuración predeterminada del sistema no se pudo agregar +admin.install.defStoreError=Error al agregar almacenamiento predeterminado +admin.install.defPathError=La adición del directorio del sistema falló +admin.install.defAdminError=La cuenta de administrador no pudo agregar +admin.install.defRoleError=La adición de roles predeterminada falló +admin.install.defGroupError=La adición del departamento del sistema falló +admin.install.dataPathNotExists=el directorio de datos no existe +admin.install.defaultUpdate=Actualización de la información de configuración del sistema +admin.install.pluginUpdated=Actualización del complemento completada +admin.install.defCacheError=Excepción de datos de caché de directorio inicial +admin.install.serverDir=Directorio de columnas del servidor +admin.install.dirRight=Permisos de directorio +admin.install.suggestOpen=Recomendado para abrir +admin.install.suggestClose=Recomendado para cerrar +admin.install.phpVersionTips=PHP5.3 y superior +admin.install.phpBitTips=64 bits recomendado +admin.install.phpBitDesc=32 bits no admite la carga y descarga de archivos de más de 2G +admin.install.pathNeedWirte=El directorio del programa y todos los subdirectorios deben ser legibles y escribibles +admin.install.mustOpen=Debe abrir +admin.install.setPathWrt=Establezca permisos de lectura y escritura para el directorio del proyecto. +admin.install.ensureNoError=Asegúrese de que lo siguiente sea correcto: +admin.install.setAdminName=Configura una cuenta de administrador +admin.install.setAdminPwd=Establezca una contraseña de administrador +admin.install.database=Base de datos +admin.install.dbType=Tipo de base de datos +admin.install.dbName=Nombre de la base de datos +admin.install.userName=Nombre de usuario +admin.install.dbPort=Número de puerto +admin.install.dbPortDesc=El puerto predeterminado es 3306, si necesita personalizarlo, puede agregarlo, como: 127.0.0.1:3307 +admin.install.dbEngine=Motor de almacenamiento +admin.install.sqliteDesc=PHP tiene una base de datos verde liviana incorporada (adecuada para pruebas o uso a pequeña escala). +admin.install.mysqlDesc=Admite la implementación de clústeres, la separación de bases de datos maestras y esclavas. +admin.install.pdoDesc=Un controlador general de base de datos más seguro requiere que PHP tenga instalada la extensión PDO. +admin.install.cacheType=Tipo de caché del sistema +admin.install.cacheTypeDesc=Se usa para almacenar en caché los datos generales y las sesiones para acelerar el acceso al sistema +admin.install.fileCache=Caché de archivos +admin.install.groupFile=Documento del departamento +admin.install.userFile=Documentación del usuario +admin.install.role=Papel +admin.install.fileAuth=Permisos de documentos +admin.install.userList=Lista de usuarios +admin.install.setInfo=Información de configuración del sistema +admin.install.favShare=Favoritos y acciones del usuario +admin.install.waitUpdate=Esperando actualización +admin.install.updateSuccess=Actualización exitosa +admin.install.fileCount=Numero de archivos +admin.install.settingDesc=Los elementos de falla se pueden configurar manualmente en la administración en segundo plano +admin.install.reInstallTips=El resultado de la devolución es anormal, reinstale +admin.log.accountEdit=Modificar información de la cuenta +admin.log.thirdBind=Vincula una cuenta de terceros +admin.log.delBind=Desenlazar +admin.log.viewFile=archivo de vista previa +admin.log.delFile=Eliminar archivo +admin.log.editFile=Editar archivo +admin.log.downFile=Descargar archivo +admin.log.downFolder=Carpeta de descargas +admin.log.moveFile=Mover archivo +admin.log.addUser=Agregar usuario +admin.log.editUser=Editar usuario +admin.log.addUserTo=Agregar usuarios al departamento +admin.log.removeUserFrom=Usuario eliminado del departamento +admin.log.switchUserGroup=Migrar usuarios a departamentos +admin.log.stausUser=Habilitar / deshabilitar usuarios +admin.log.addRole=Nuevo rol +admin.log.editRole=Editar rol +admin.log.delRole=Eliminar rol +admin.log.addAuth=Agregar permisos +admin.log.editAuth=Editar permisos +admin.log.delAuth=Eliminar permiso +admin.log.editShare=Editar compartir +admin.log.delLinkTo=Cancelar el intercambio de enlaces externos +admin.log.delShareTo=Cancelar el intercambio colaborativo +admin.log.recycleTo=Mover a la papelera de reciclaje +admin.log.newName=Nuevo nombre +admin.log.oldName=Nombre original +admin.log.newPath=Nuevo catalogo +admin.log.oldPath=Catalogo original +admin.log.typeFile=Operaciones de archivo +admin.log.typeUser=Configuración de usuario +admin.log.queryByIp=Haga clic en el botón para consultar los registros del día en función de la IP. +admin.backup.setting=Configuración de copia de seguridad +admin.backup.edit=Edición de respaldo +admin.backup.ing=Copia de seguridad +admin.backup.success=Copia de seguridad realizada correctamente +admin.backup.fail=Copia de seguridad fallida +admin.backup.complete=Copia de seguridad completa +admin.backup.db=base de datos +admin.backup.dbFile=archivo de base de datos +admin.backup.fileError=Ha fallado la copia de seguridad de algunos archivos +admin.backup.checkLog=Verifique el registro de respaldo: data/temp/log/backup/date of the day__log.php +admin.backup.pathNoWrite=El directorio temporal no tiene permiso de escritura +admin.backup.errorMsg=Parte de la copia de seguridad del archivo falló, puede copiar manualmente de acuerdo con el registro, o eliminar y volver a realizar una copia de seguridad. +admin.backup.logFile=Archivo de registro +admin.backup.manual=Copia de seguridad manual +admin.backup.continue=Continuar copia de seguridad +admin.backup.start=Comenzar respaldo +admin.backup.open=Activar copia de seguridad +admin.backup.notOpen=La copia de seguridad no está habilitada +admin.backup.location=Ubicación de respaldo +admin.backup.content=Contenido de respaldo +admin.backup.dbOnly=base de datos +admin.backup.time=Tiempo de respaldo +admin.backup.notStart=no ha comenzado +admin.backup.notEnabled=No disponible +admin.backup.killed=encima +admin.backup.ifKill=¿Seguro que quieres finalizar esta copia de seguridad? +admin.backup.kill=Final +admin.backup.error=Abortar +admin.backup.timeBeen=Pérdida de tiempo +admin.backup.timeTotal=Tiempo Total +admin.backup.backed=Respaldado +admin.backup.storage=Cree un almacenamiento dedicado para la copia de seguridad. +admin.backup.ifSave=La copia de seguridad lleva mucho tiempo. ¿Está seguro de que desea hacer una copia de seguridad? +admin.backup.ifContinue=¿Seguro que quieres continuar con la copia de seguridad? +admin.backup.saveTips=La tarea de respaldo ha sido enviada, por favor sea paciente +admin.backup.fileSize=Tamaño del documento +admin.backup.dbSize=Tamaño de la base de datos +admin.backup.dbCnt=total +admin.backup.notFinished=Sin completar +admin.backup.timeTaken=pérdida de tiempo +admin.backup.node=nodo +admin.backup.notYet=No +admin.backup.storeNotExist=El almacenamiento de respaldo no existe, reinicie +admin.backup.timeNote=Nota: El sistema solo mantiene las copias de seguridad de la base de datos de los últimos 7 días y el 1 de cada mes. Tiempo de respaldo: +admin.backup.recover=Comuníquese con el proveedor de servicios para la recuperación de datos. +admin.backup.optionTime=La copia de seguridad lleva mucho tiempo, intente elegirla durante las horas no laborables +admin.backup.optionLocation=Si necesita hacer una copia de seguridad de los archivos, cree un nuevo almacenamiento dedicado para la copia de seguridad +admin.backup.optionTips1=La copia de seguridad se divide en dos partes: copia de seguridad de la base de datos y copia de seguridad de archivos. +admin.backup.optionTips2=Copia de seguridad de la base de datos: genere archivos SQL a partir del contenido de la base de datos y realice una copia de seguridad de ellos en el directorio de la base de datos de almacenamiento de destino. +admin.backup.optionTips3=Copia de seguridad de archivos: copia de seguridad de los archivos de almacenamiento del sistema en el almacenamiento de destino de forma incremental de acuerdo con la ruta de almacenamiento original. +admin.backup.optionTips4=El sistema solo mantiene las copias de seguridad de la base de datos de los últimos 7 días y el 1 de cada mes. +admin.backup.needStorage=El almacenamiento de respaldo no puede estar vacío +admin.backup.needNoDefault=No elija el almacenamiento predeterminado como la ubicación de la copia de seguridad del archivo +admin.backup.contentDesc=La versión con licencia admite copias de seguridad simultáneas de bases de datos y archivos. +admin.backup.action=Gestión de operaciones +admin.backup.recovery=reducción +admin.backup.sysRecovery=restauración del sistema +admin.backup.bakErr2Rec=Esta copia de seguridad está incompleta y no se puede restaurar +admin.recycle.menu=Papelera de reciclaje del sistema +admin.share.name=Compartir nombre +admin.share.type=Tipo de intercambio +admin.share.expiryTime=Vencimiento +admin.share.expired=Caducado +admin.share.link=Enlace externo +admin.share.linkView=Haga clic para ver compartir +admin.share.ifDel=¿Estás seguro de que deseas cancelar este intercambio? +admin.share.disFile=Este archivo ha sido informado por los usuarios y no se puede compartir. +admin.share.disFolder=Este directorio contiene archivos ilegales que no se pueden compartir. +admin.share.shareTab=Gestión de compartir +admin.share.reportTab=Compartir la gestión de informes +admin.share.rptType1=Piratería +admin.share.rptType2=Porno obsceno +admin.share.rptType3=Violencia sangrienta +admin.share.rptType4=La política es dañina +admin.share.rptType5=otras razones +admin.share.doRptClose=Cierre el informe después de procesar el contenido compartido o ciérrelo directamente +admin.share.doRptDisable=Después de prohibir / permitir compartir, todos los recursos correspondientes al archivo se verán afectados. ¿Está seguro de que desea realizar esta operación? +admin.share.rptUser=Denunciante +admin.share.rptTitle=Compartir informes +admin.share.rptDesc=Razón de la denuncia +admin.share.rptTime=Hora del informe +admin.share.rptResult=resultado del proceso +admin.share.rptDone=Procesada +admin.share.rptNoDone=Sin tratar +admin.share.rptClose=Cerrar informe +admin.share.rptShareDel=Dejar de compartir +admin.share.rptShareAllow=Permite compartir +admin.share.rptShareDisable=No compartir +admin.share.rptDoDisable=Prohibir / permitir compartir +admin.share.rptSelectTips=Por favor, seleccione el artículo que se va a utilizar. +admin.setting.transfer=Subir / descargar +admin.setting.transferChunkSize=Subir tamaño de fragmento +admin.setting.transferChunkSizeDesc=Al cargar un archivo grande, se corta en pedazos para la carga simultánea, a fin de lograr la aceleración y reanudar la reanudación.
    Se recomienda 5M; este valor debe ser menor que la siguiente configuración; de lo contrario, causará una excepción de carga (falla de carga, reversión) +admin.setting.transferChunkSizeDescError1=El tamaño del fragmento de carga no puede exceder la configuración en php.ini +admin.setting.transferChunkSizeDescError2=Modifíquelo en php.ini e intente nuevamente (modifique upload_max_filesize, post_max_size, necesita reiniciar) +admin.setting.transferThreads=Subir hilos concurrentes +admin.setting.transferThreadsDesc=Recomendado = 10; cargas simultáneas de archivos o fragmentos +admin.setting.transferIgnore=Subir ignorar archivo +admin.setting.transferIgnoreDesc=Cargue los nombres de archivo que se ignoran automáticamente. Los archivos temporales se pueden excluir, separados por comas, por ejemplo: .DS_store, thumb.db +admin.setting.transferChunkRetry=Retransmisión automática cuando falla la carga +admin.setting.transferChunkRetryDesc=Recomendación = 5; el número de retransmisiones se realizará automáticamente si la carga falla, 0 significa que no hay retransmisión automática +admin.setting.transferOsChunkSize=Tamaño del fragmento de almacenamiento de objetos +admin.setting.transferOsChunkSizeDesc=Carga de almacenamiento de objetos, el tamaño del fragmento varía de 5 MB a 5 GB y el número máximo de solicitudes es 1000, lo que significa que el tamaño máximo de carga de archivos es 5 TB.
    Se recomiendan 10 ~ 20 MB. En este momento, el tamaño máximo de archivo admitido es de 9,7 ~ 19,5 GB, y los usuarios pueden ajustar el tamaño del archivo cargado según sus necesidades. +admin.setting.transferHttpSendFile=Descargar la aceleración del servidor web +admin.setting.transferHttpSendFileDesc=La descarga de archivos se transmite directamente a través del servidor web; la velocidad de descarga mejora; solo es efectiva cuando el almacenamiento predeterminado está configurado como almacenamiento local. +admin.setting.downloadZipClient=Descarga comprimida front-end +admin.setting.downloadZipClientDesc=Necesita poder conectarse a la red externa, o el sitio es https +admin.setting.downloadZipLimit=Límite de tamaño de descarga comprimida +admin.setting.downloadZipLimitDesc=0 significa sin límite; para evitar un consumo excesivo de rendimiento del servidor, la descarga del paquete se restringe cuando la carpeta es demasiado grande y se solicita que el archivo se pueda descargar directamente a través del cliente de PC +admin.setting.downloadZipLimitTips=El contenido comprimido excede el límite del sistema, ¡póngase en contacto con el administrador! Puede descargar directamente la carpeta a través del cliente de PC sin compresión. +admin.setting.dragDownload=Arrastre y suelte en el escritorio para descargar +admin.setting.dragDownloadDesc=Solo es compatible con el navegador Chrome kernel del lado de la PC (chrome edge 360 fast, etc.) +admin.setting.dragDownloadZip=Descarga de compresión de arrastrar y soltar de selección múltiple +admin.setting.dragDownloadZipDesc=Soporte de descarga de selección múltiple o arrastrar y soltar carpetas, debe empaquetarse y comprimirse en el servidor antes de descargar +admin.setting.dragDownloadLimit=Límite de tamaño de contenido de arrastrar y soltar +admin.setting.dragDownloadLimitDesc=0 significa que no hay límite; el tamaño del contenido arrastrado estará sujeto a este límite. Dado que no hay una barra de progreso para arrastrar y descargar Chrome en este momento, no se puede cancelar. Se recomienda limitar el tamaño a 20M. +admin.setting.dragDownloadUrlTips=La URL es demasiado larga, reduce la selección e inténtalo de nuevo. +admin.setting.dragDownloadOpenTips=¡Póngase en contacto con el administrador para habilitarlo en la configuración de fondo! +admin.setting.dragDownloadNotOpen=La descarga de arrastrar y comprimir no está habilitada +admin.setting.dragDownloadSizeTips=El tamaño del contenido arrastrado supera el límite +admin.setting.showFileSafe=Seguridad de acceso a archivos +admin.setting.showFileLink=Visualización de enlace externo de archivo +admin.setting.showFileLinkDesc=Después de cerrar, las propiedades del archivo ya no muestran enlaces externos +admin.setting.showFileMd5=pantalla de archivo md5 +admin.setting.showFileMd5Desc=Después de cerrar, las propiedades del archivo ya no muestran el archivo md5 +admin.setting.shareLinkAllow=Habilitar el uso compartido de enlaces externos +admin.setting.shareLinkAllowDesc=Después del cierre, ya no admitirá el uso compartido de cadenas externas y el contenido compartido no se verá afectado. +admin.setting.shareLinkAllowTips=El sistema actual ha deshabilitado el uso compartido de enlaces externos, ¡póngase en contacto con el administrador! +admin.setting.shareLinkPasswordAllowEmpty=El uso compartido de cadenas externas permite que la contraseña esté vacía +admin.setting.shareLinkPasswordAllowEmptyDesc=Después de cerrar, se debe establecer una contraseña para compartir mediante enlace externo; el contenido compartido no se verá afectado +admin.setting.shareLinkAllowGuest=El uso compartido de enlaces externos permite que los visitantes no registrados accedan +admin.setting.shareLinkAllowGuestDesc=Después de cerrar, debe iniciar sesión al acceder a enlaces externos; el contenido compartido no se verá afectado +admin.setting.shareLinkZip=Descarga del paquete para compartir enlaces externos +admin.setting.shareLinkZipDesc=Después de abrirse, la carpeta de intercambio de cadena externa admite la descarga de paquetes y compresión. Si la simultaneidad es grande, se consumirá el rendimiento del servidor. +admin.setting.shareLinkZipTips=El uso compartido de enlaces externos deshabilita las descargas empaquetadas, comuníquese con el administrador para configurarlo. +admin.setting.transferDownSpeed=Descargar límite de velocidad +admin.setting.transferDownSpeedDesc=Limite las velocidades de descarga y limite de manera uniforme la velocidad de los grandes sitios web concurrentes +admin.setting.transferDownSpeedNum=Descargar límite de velocidad +admin.setting.transferDownSpeedNumDesc=Limite la velocidad de descarga, y puede limitar uniformemente la velocidad del sitio web con gran concurrencia.
    Nota: La velocidad del servidor está limitada aquí. La velocidad de descarga específica también se ve afectada por el ancho de banda del servidor y la red del usuario. +explorer.uploadSizeError=Su servidor actualmente no admite archivos de más de 2G,
    Actualice a php de 64 bits; se recomienda php7 de 64 bits
    (Nota: el sistema operativo de 64 bits solo puede instalar PHP de 64 bits); +common.width=Amplia +common.height=Alta +common.test=Prueba +common.absolutePath=Dirección absoluta +common.qrcode=Código QR URL +common.wechat=WeChat +common.group=Departamento +common.user=Usuario +common.online=En línea +common.use=Para utilizar +common.total=Total +common.year=Año +common.month=Mes +common.week=Semana +common.daytime=Día +common.mon=el lunes +common.tue=el martes +common.wed=el miércoles +common.thu=jueves +common.fri=viernes +common.sat=en sábado +common.sun=domingo +common.second=Segundo +common.minute=Minuto +common.hour=Horas +common.day=Día +common.every=cada +common.everyMonth=por mes +common.everyWeek=semanal +common.everyDay=todos los días +common.language=Idioma +common.all=Todos +common.item=Artículo +common.items=Contenido del artículo +common.itemsEmpyt=Sin contenido +common.detail=Detalles +common.me=Yo +common.others=Otros +common.guest=Visitantes +common.more=Más +common.learnMore=Aprende más +common.yes=Si +common.no=No +common.omit=Omitir +common.unknow=Desconocido +common.title=título +common.time=hora +common.scan=Vistazo +common.report=Reporte +common.name=Nombre +common.nickName=Apodo +common.tools=Herramientas +common.tag=Etiquetas +common.position=Ubicación +common.mount=Montaje en red +common.type=Tipo +common.auth=Autoridad +common.status=Estado +common.run=Correr +common.file=Archivo +common.folder=Carpeta +common.fileType=Tipo de archivo +common.fileSize=Tamaño del archivo +common.attributeInfo=Información de atributo +common.actionType=Tipo de operación +common.isDisplay=Ya sea para mostrar +common.hide=Ocultar +common.isHide=Oculto +common.cancelHide=Mostrar +common.default=defecto +common.display=Mostrar +common.moveDown=Mover hacia abajo +common.moveUp=Mover hacia arriba +common.drag=Arrastrar +common.dragSort=Arrastra para ajustar el orden +common.warning=Advertencia +common.tips=Pista +common.desc=instrucción +common.tipsDesc=Descripción rápida +common.tipsOthers=Otras instrucciones +common.view=Ver +common.log=Iniciar sesión +common.task=tarea +common.important=Importante +common.icon=Icono +common.menu=Menu +common.system=sistema +common.basic=Universal +common.systemSet=Configuración del sistema +common.systemDefault=Sistema predeterminado +common.diy=Personalizado +common.input=Por favor ingrese +common.select=Por favor seleccione +common.add=Agregar +common.edit=Editar +common.action=Operación +common.upload=Subir +common.uploadTo=subir a +common.download=Descargar +common.export=Exportar +common.cover=Cubierta +common.retry=Reintentar +common.zip=Comprimido +common.unzip=Descomprimir +common.preview=Vista previa +common.share=Compartir +common.search=Buscar +common.query=Preguntar +common.delete=Eliminar +common.deleteForce=Eliminar por completo +common.deleteEnd=eliminado +common.refresh=Actualizar +common.open=Abierto +common.close=Cerrar +common.from=fuente +common.greater=Mayor que +common.less=Menos de +common.print=Imprimir +common.selectInvert=Elección inversa +common.selectAll=Seleccionar todo / Selección inversa +common.selectAllItem=Seleccionar todo +common.selectNum=Seleccionado +common.selectNull=Ninguno en absoluto +common.sizeMore=lo anterior +common.showMore=Desplegar +common.showLess=Colapso +common.sizeSmall=pequeño +common.sizeMiddle=en +common.sizeBig=Grande +common.rename=Renombrar +common.method=Función +common.extend=Extensión +common.fav=Favorito +common.reset=Restablecer +common.testing=Prueba +common.install=Instalar +common.update=Actualización +common.version=Versión +common.sysVersion=Versión de la plataforma +common.login=Iniciar sesión +common.regist=Registrarse +common.password=Contraseña +common.operateTime=Tiempo de funcionamiento +common.createTime=Tiempo de creación +common.modifyTime=Tiempo de modificación +common.activeTime=Tiempo de archivo +common.startTime=Tiempo de empezar +common.endTime=Hora de finalización +common.finishTime=Hora de finalización +common.disable=Deshabilitar +common.goOn=Continuar +common.ok=Determinar +common.startRun=Comienzo +common.confirmTips=Por favor confirme de nuevo +common.confirmAsk=¿Está seguro de que desea realizar esta operación? +common.submit=Enviar +common.skip=Saltar +common.nextStep=Paso siguiente +common.start=Inicio +common.stop=pausa +common.set=Ambientación +common.cancel=Cancelar +common.save=Guardar +common.empty=Sin contenido! +common.isOpen=Encendido +common.isClose=cerrado +common.apply=Solicitud +common.saveAll=Guardar todo +common.notSave=No guardar +common.appAdd=Agregar +common.backAdd=Volver a agregar +common.saveEdit=Guardar cambios +common.saveSubmit=Guardar confirmación +common.saveAndAdd=Guardar y continuar agregando +common.sex=Sexo +common.male=Hombre +common.female=Hembra +common.address=Dirección +common.email=Correo electrónico +common.phone=Teléfono móvil +common.sms=Sms +common.phoneNumber=Número de teléfono +common.server=Servidor +common.handheld=Dispositivo móvil +common.success=El éxito +common.fail=Fracaso +common.error=Mal +common.result=resultado +common.expired=Caducado +common.valid=Eficaz +common.inAll=total +common.allAndNull=Seleccionar todo / Cancelar +common.moveTop=Parte superior +common.moveBottom=Establecer al final +common.moveTopCancle=Unpink +common.ECN=China oriental +common.NCN=Norte de China +common.SCN=Sur de china +common.USA=Norteamérica +common.SEA=Asia sudoriental +common.noLimit=no limitado +common.notExists=No existe +common.cannotWrite=Solo lectura, no escribir +common.readOnly=Solo lectura +common.cannotRead=Ilegible +common.ifDel=¿Estás seguro de que quieres eliminar? +common.pageNotExists=¡La página no existe! +common.pathNotExists=¡El documento no existe! +common.fileShare=Compartir documentos +common.logining=Iniciando sesión ... +common.loginTokenError=El inicio de sesión ha caducado, ¡vuelva a iniciar sesión! +common.loginSuccess=¡Inicio de sesión exitoso! +common.loginError=Error de inicio de sesión +common.connectSuccess=Conectado con éxito! +common.bindSuccess=¡Ate con éxito! +common.bindError=Enlace fallido +common.clear=Vacío +common.congrats=Felicidades +common.sorry=Lo siento +common.invalid=Inválido +common.unavailable=indisponible +common.format=Formato +common.noPermission=Permiso denegado +common.allPermission=Todos los permisos +common.invalidParam=Parámetro inválido +common.invalidFormat=Formato inválido +common.invalidRequest=Tipo de solicitud ilegal +common.illegalRequest=Solicitud ilegal +common.expiredRequest=La solicitud ha expirado +common.errorExpiredRequest=Solicitud inválida o ha expirado +common.migrating=Migrando +common.migrated=Migración completada +common.maintenanceTips=Durante el mantenimiento del sistema, visite más tarde ... +common.done=terminado +common.disabled=discapacitado +common.sizeTotal=Tamaño total +common.sqlStatement=[Instrucción SQL]: +common.env.check=Pruebas ambientales +common.env.errorLib=Falta la biblioteca PHP +common.env.errorIgnore=Ignorar y entrar +common.env.errorVersion=La versión de PHP no puede ser inferior a 5.0 +common.env.errorPath=No escribible +common.env.errorListDir=Su servidor web tiene habilitada la función de listado de directorios. ¡Deshabilítela por razones de seguridad! Como funciona +common.env.errorGd=La biblioteca PHP GD debe estar activada, de lo contrario, el uso de códigos de verificación y miniaturas será anormal. +common.env.invalidExt=La extensión %s no está disponible, verifique si está instalada +common.env.installWithBtTips=La versión del servidor php requiere 5.3 y superior. No estoy familiarizado con la configuración de un clic del panel de pagoda recomendado.
    Versión actual +common.env.phpCacheOpenTips=Su servidor tiene habilitado el almacenamiento en caché de php y las actualizaciones de archivos aún no han entrado en vigencia;
    ¡Apague el caché o actualice la página e intente nuevamente en 1 minuto!
    Aprende más +common.env.dataPathNotExists=¡El directorio de datos no existe!
    (Verifique DATA_PATH); +common.env.pathPermissionError=[Código de error: 1002] ¡Error de permiso de directorio! Configure el directorio del programa y todos los subdirectorios para leer y escribir.
    Linux ejecuta el siguiente comando:
     su -c 'setenforce 0' 
    chmod -R 777 +common.version.free=Sin cargo +common.version.nameQ=Edición Enterprise +common.version.vipFree=Edición gratuita +common.version.useFree=Continúa usando la versión gratuita +common.version.notSupport=Su versión no es compatible con esta operación, vaya al sitio web oficial para comprar la versión avanzada. +common.version.notSupportNumber=Esta operación no es compatible debido al número limitado, ¡vaya al sitio web oficial para comprar la versión avanzada! +common.version.toVip=Actualizar a comercial +common.version.license=Autorizacion de compra +common.version.authCode=Código de activación de autorización +common.version.authActive=Autorización de activación +common.version.authorization=Autorización de registro +common.version.authorizeSuccess=¡Felicitaciones, la autorización para la actualización en línea fue exitosa! +common.version.networkError=La solicitud al servidor falló. Compruebe si el servidor puede acceder a la red.
    Nota: el servidor no puede ser un proxy para acceder a Internet +common.version.authActiveOnline=Activar en línea +common.version.authActiveOffline=Activar sin conexión +common.version.offlineTips=¿El servidor no puede acceder a Internet? +common.version.menuTitle=Configuración de información empresarial +common.version.timeout=Caducado +common.version.timeToService=Hora de vencimiento del servicio +common.version.timeTo=Hora de vencimiento de la autorización +common.version.licenseAll=Autorización perpetua +common.version.kodVersion=Versión del programa +common.version.userLimitTitle=Número de usuario +common.version.userUse=Usado +common.version.userAllow=Número de usuarios admitidos +common.version.userTo=Objeto autorizado +common.version.userTitle=Información de autorización +common.version.basicInfo=información básica +common.version.appInfo=Información del Producto +common.version.tipsWarning=Advertencia, no modifique los derechos de autor sin permiso; si es necesario, póngase en contacto para comprar. +common.version.tipsCopyLink=Copie con éxito! Pegue y guarde en el archivo txt,
    Abra este enlace en una computadora con una red a través de una unidad flash USB, etc. +common.version.tipsHistory=La versión gratuita solo admite 5 versiones de historial; ¡compre un número ilimitado de versiones con licencia! +common.version.codeLink=Enlace de solicitud de código de autorización +common.version.codeLinkHelp=1. Copie el enlace de arriba y visite otras computadoras con acceso a internet.
    2. Complete el "Código de autenticación de autorización" obtenido anteriormente, y luego active y autorice +common.copyright.logoTitle=Conjunto de logotipos de identidad corporativa +common.copyright.licenseInfo=Información de autorización +common.copyright.licenseReset=Reautorizar +common.copyright.licenseResetTips=¡Reactivar para más información! +common.copyright.formLogo=Tipo de logotipo de la página de inicio de sesión +common.copyright.formLogoTypeWord=Logotipo de texto +common.copyright.formLogoTypeImage=Logotipo de la imagen +common.copyright.formLogoDesc=El logotipo de texto usa el nombre de la compañía y el logotipo de la imagen usa el conjunto de imágenes de la siguiente manera. +common.copyright.formLogoImage=Imagen del logotipo de la página de inicio de sesión +common.copyright.formLogoImageDesc=Página de inicio de sesión y logotipo de fondo de administración, tamaño recomendado 250x100, formato png semitransparente +common.copyright.formLogoMain=Logotipo del menú de la interfaz principal +common.copyright.formLogoMainDesc=Logotipo de gestión de archivos en la esquina superior izquierda, tamaño recomendado 200x200, formato png translúcido blanco +common.copyright.formPowerByInfo=Configuración de información de copyright de la empresa +common.copyright.formPowerBy=Nombre de la empresa de derechos de autor inferior +common.copyright.formHomePage=Salto de enlace de copyright inferior +common.copyright.formConcat=Contacto emergente +common.copyright.formDesc=Descripción detallada de la capa emergente del producto +common.copyright.formDescTips=Después de guardar la modificación, la página de actualización entra en vigencia +common.copyright.formMetaKeywords=Palabras clave del sitio (utilizadas por los motores de búsqueda) +common.copyright.formMetaName=Nombre del sitio (utilizado por los motores de búsqueda) +common.copyright.downloadApp=Descarga de la aplicación +common.copyright.downloadLink= +common.copyright.about=en +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=Identificación automática +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=Árabe +common.charset.ISO_8859_6=Árabe +common.charset.ISO_8859_10=Lengua nórdica +common.charset.CP1257=Idiomas alrededor del Báltico +common.charset.ISO_8859_13=Idiomas alrededor del Báltico +common.charset.ISO_8859_4=Idiomas alrededor del Báltico +common.charset.BIG5_HKSCS=Tradicional-Hong Kong +common.charset.BIG5=Taiwán tradicional +common.charset.Georgian_Academy=Georgiano +common.charset.PT154=Kazajo +common.charset.CP949=Coreano +common.charset.EUC_KR=Coreano +common.charset.GB18030=Chino simplificado +common.charset.GBK=Chino simplificado +common.charset.ISO_8859_14=Celta +common.charset.CP1133=Laos +common.charset.ISO_8859_16=Rumano +common.charset.ISO_8859_3=Lenguas del sur de Europa +common.charset.EUC_JP=Japonés +common.charset.ISO_2022_JP=Japonés +common.charset.SHIFT_JIS=Japonés +common.charset.KOI8_T=Tayiko +common.charset.ISO_8859_11=Tailandés +common.charset.TIS_620=Tailandés +common.charset.CP1254=Turco +common.charset.CP1251=Cirílico +common.charset.ISO_8859_5=Cirílico +common.charset.KOI8_R=Cirílico +common.charset.KOI8_U=Cirílico +common.charset.CP1252=Idiomas de Europa occidental +common.charset.ISO_8859_1=Idiomas de Europa occidental +common.charset.ISO_8859_15=Idiomas de Europa occidental +common.charset.Macintosh=Idiomas de Europa occidental +common.charset.CP1255=Hebreo +common.charset.ISO_8859_8=Hebreo +common.charset.CP1253=Griego +common.charset.ISO_8859_7=Griego +common.charset.ARMSCII_8=Armenio +common.charset.CP1258=Vietnamita +common.charset.VISCII=Vietnamita +common.charset.CP1250=Lenguas centroeuropeas +common.charset.ISO_8859_2=Lenguas centroeuropeas +common.charset.defaultSet=Codificación de archivo +common.charset.convertSave=Convertido a +common.date.near=Justo ahora +common.date.miniteBefore=Hace minutos +common.date.today=Hoy +common.date.yestoday=Ayer +common.date.before=antes de +common.faceDefault=Emoticon predeterminado +common.loadMore=carga más +common.numberLimit=¡La cantidad supera el límite máximo! +common.lengthLimit=¡La longitud supera el límite máximo! +common.task.name=Administrador de tareas +common.task.title=nombre de la misión +common.task.user=Usuario ejecutivo +common.task.porcess=calendario +common.task.start=Iniciar tarea +common.task.useTime=Tiempo transcurrido +common.task.running=Ejecutando +common.task.stoping=Pausado +common.task.killing=Finalizando +common.task.stop=Tarea suspendida +common.task.kill=Tarea final +common.task.removeTips=¿Estás seguro de terminar esta operación? +common.task.killAll=Acabar todo +common.task.killAllTips=¿Estás seguro de terminar todas las tareas? +common.task.timeStart=Empieza en +common.task.timeNeed=Restante sobre +common.task.timeUse=Ya corriendo +ERROR_DB_PWD=Acceso a la base de datos denegado: nombre de usuario o contraseña incorrectos. +ERROR_DB_TIMEOUT=Se agotó el tiempo de conexión de la base de datos, verifique si la dirección es correcta. +ERROR_DB_CONN_RFS=Conexión de base de datos rechazada: información de configuración incorrecta o servicio no iniciado. +ERROR_DB_ADR=Error de conexión a la base de datos, compruebe si la dirección es correcta. +ERROR_DB_NOT_SUPPORT=Tipo de base de datos no compatible, verifique si el servicio correspondiente o el archivo de configuración son normales. +ERROR_DB_XS_DENNIED=Acceso a la base de datos denegado: privilegios insuficientes. +ERROR_DB_NOT_EXIST=La base de datos no existe o se especificó un nombre incorrecto. +explorer.pathNotSupport=¡Este tipo de directorio no es compatible con esta operación! +explorer.pathIsRoot=¡Has llegado al directorio raíz! +explorer.pathNull=La carpeta está vacía +explorer.zipFileLarge=El archivo es demasiado grande, descomprímalo antes de previsualizarlo. +explorer.charNoSupport=Caracteres especiales no compatibles: +explorer.moveError=Movimiento fallido +explorer.lockError=Ocurrió un error, se agotó el tiempo de bloqueo simultáneo +explorer.lockErrorDesc=Reduzca la frecuencia de las solicitudes, optimice la configuración relacionada con la simultaneidad del servidor o mejore la configuración del hardware del servidor; +explorer.moveSubPathError=Algo salió mal, el directorio principal no se puede mover al directorio secundario. +explorer.spaceIsFull=No queda suficiente espacio, ¡comuníquese con el administrador! +explorer.sessionSaveError=Error de escritura de sesión. Compruebe si el disco está lleno o consulte a su proveedor de servicios. +explorer.networkError=Error de conexión de red (net :: ERR_CONNECTION_RESET), la conexión se ha restablecido.
    ¡Póngase en contacto con la empresa anfitriona o el administrador de red para verificar la configuración del firewall! +explorer.folderManage=Directorio de gestión +explorer.clickEdit=Haga clic para editar +explorer.shortLink=Atajo +explorer.upper=Capa superior +explorer.historyNext=Por adelantado +explorer.historyBack=Volver +explorer.loading=En funcionamiento ... +explorer.getting=Obteniendo ... +explorer.sending=Enviando datos ... +explorer.pullTips=Tire hacia abajo para actualizar la página +explorer.pullDropTips=Gratis para actualizar la página +explorer.getSuccess=¡Consigue el éxito! +explorer.saveSuccess=¡Guardado con éxito! +explorer.saveError=¡Error al guardar! +explorer.success=Operación exitosa +explorer.error=Operación fallida +explorer.dataError=¡Los datos son anormales! +explorer.pathError=Error de ruta del documento +explorer.repeatError=Operación fallida, ¡el nombre ya existe! +explorer.systemError=Error del sistema +explorer.mistake=Algo salió mal! +explorer.recycleClear=Papelera de reciclaje vacía +explorer.recycleClearForce=Hay demasiado contenido en la papelera de reciclaje, primero vacíe la papelera de reciclaje. +explorer.recycleRestore=Restaurar papelera de reciclaje +explorer.recycleRestoreItem=Restaurar +explorer.recycleRestoreAll=Restaurar todo +explorer.recycleClearInfo=¿Seguro que quieres vaciar la papelera de reciclaje por completo? +explorer.zipDownloadReady=Descargue automáticamente después de la compresión, espere ... +explorer.removeItem=Contenido del artículo +explorer.uploading=Cargando +explorer.uploadTipsMore=Demasiados archivos, se recomienda cargarlos después de la compresión y luego descomprimirlos en línea. +explorer.uploadingMove=Fusionar y transferir ... +explorer.viewNewPage=Vista previa de nueva página +explorer.unknowFileTitle=¡Consejos para abrir archivos! +explorer.unknowFileTips=Sin una aplicación que admita este archivo, puede: +explorer.unknowAppTips=Sin la aplicación: +explorer.unknowFileTry=Prueba +explorer.unknowFileDown=Descargar el archivo +explorer.authFileDown=Descarga de archivos +explorer.authShare=Compartir +explorer.usersShare=De compartir +explorer.clipboard=Ver portapapeles +explorer.clipboardClear=Portapapeles vacio +explorer.fullScreen=Pantalla completa +explorer.folderItem=Artículos +explorer.folderItemSelect=Seleccionado +explorer.dbLoadAll=Haga doble clic para cargar todo ... +explorer.ziping=Comprimiendo ... +explorer.unziping=Descomprimiendo ... +explorer.zipingTips=Operación de compresión, por favor espere ... +explorer.unzipingTips=Operación de descompresión, por favor espere ... +explorer.unzipRarTips=El contenido del archivo está dañado o el análisis del archivo no es compatible. Se recomienda utilizar el formato ZIP. +explorer.parsing=Recuperando ... +explorer.moving=Operación de mudanza ... +explorer.copyMove=Copiar movimiento +explorer.removeTitle=Eliminar confirmación +explorer.removeInfo=¿Estás seguro de que deseas eliminar la selección? +explorer.removeTitleForce=Eliminar para siempre +explorer.removeInfoForce=¿Seguro que quieres eliminar este documento de forma permanente? +explorer.pathInRecycle=La carpeta está en la papelera de reciclaje, restaure y vuelva a intentarlo. +explorer.pathInRecycleFile=El archivo está en la papelera de reciclaje, restaure y vuelva a intentarlo. +explorer.downOffline=Descargar sin conexión +explorer.savePath=Guardar ruta +explorer.uploadSelectMuti=Seleccione varios archivos para cargar +explorer.goTo=Saltar a +explorer.selectFile=Seleccionar archivo +explorer.selectFolder=Seleccionar carpeta +explorer.selectImage=Por favor seleccione una imagen ... +explorer.selectValidFolder=¡Seleccione una carpeta para ser válida! +explorer.selectFolderFile=Seleccionar archivo o carpeta +explorer.selectMulti=Opción múltiple +explorer.notNull=¡Los campos obligatorios no pueden estar vacíos! +explorer.picCannotNull=¡La dirección de la imagen no puede estar vacía! +explorer.renameSuccess=Renombrado con éxito! +explorer.inputSearchWords=Por favor, introduzca la cadena para buscar +explorer.search.optionContent=contenido del documento +explorer.search.searchContentTips=Contenido del archivo de búsqueda de palabras clave, archivo de texto de soporte +explorer.search.optionMutil=Búsqueda masiva +explorer.search.optionMutilDesc=Un término de búsqueda por línea, los resultados de la búsqueda se ordenan según el término de búsqueda +explorer.removeSuccess=Borrado con éxito! +explorer.removeFail=Eliminar falló! +explorer.clipboardNull=¡El portapapeles está vacío! +explorer.createSuccess=Nuevo éxito! +explorer.createError=Nueva creación fallida, por favor revise los permisos del directorio! +explorer.copySuccess=[Copiar] -Sobreescribir el portapapeles con éxito! +explorer.cuteSuccess=[Corte] -Sobreescribir el portapapeles con éxito! +explorer.clipboardState=Estado del portapapeles: +explorer.copyOK=Copiado con éxito +explorer.copyNotExists=La fuente no existe +explorer.currentHasParent=¡La carpeta de destino es una subcarpeta de la carpeta de origen! +explorer.pastSuccess=Operación de pegado completada +explorer.cutePastSuccess=Operación de corte completada +explorer.zipSuccess=Compresión completada +explorer.notZip=No es un archivo comprimido +explorer.zipNull=No hay archivos o directorios seleccionados +explorer.unzipSuccess=Descomprimir completado +explorer.pathIsCurrent=¡La ruta abierta es la misma que la ruta actual! +explorer.pathExists=¡El nombre ya existe! +explorer.serverDownDesc=Tareas agregadas a la lista de descargas +explorer.parentPermission=Permisos del directorio principal +explorer.confirm=Estas seguro +explorer.ifSaveFileTips=¿Hay archivos no guardados? +explorer.ifSaveFile=El archivo aún no se ha guardado. ¿Está guardado? +explorer.ifStopUploadTips=Se está cargando un archivo, ¿está seguro de cerrar la ventana? +explorer.noPermissionRead=¡No tienes permiso de lectura! +explorer.noPermissionDownload=¡No tienes permiso para descargar! +explorer.noPermissionWrite=El directorio no tiene permisos de escritura. +explorer.noPermissionAction=No tiene este permiso, ¡póngase en contacto con el administrador! +explorer.noPermissionWriteAll=El archivo o directorio no tiene permiso de escritura +explorer.noPermissionWriteFile=El archivo no tiene permiso de escritura +explorer.noPermissionReadAll=El archivo o directorio no tiene permisos de lectura +explorer.noPermission=¡El administrador ha deshabilitado este permiso! +explorer.noPermissionExt=Un administrador ha deshabilitado este tipo de permisos de archivo +explorer.noPermissionGroup=¡No estás en este grupo de usuarios! +explorer.pathNoWrite=El directorio no se puede escribir, configure el directorio y todos los subdirectorios para leer y escribir e intente nuevamente. +explorer.onlyReadDesc=Este directorio no tiene permisos de escritura, puede establecer permisos en este directorio en el servidor +explorer.settingSuccess=¡La modificación ha entrado en vigor! +explorer.noRepeat=No se permiten duplicados. +explorer.dataNotFull=¡El envío de datos está incompleto! +explorer.tooManyToView=Contiene demasiado contenido (%s elementos), ábralo localmente para verlo; +explorer.jumpAfterWhile=Salta automáticamente después de%ss, Salta inmediatamente +explorer.retryTips=Por favor verifique e intente nuevamente +explorer.selectObject=Seleccionar objetos +explorer.parentGroup=Departamento superior +explorer.actionAuth=Autoridad de operación +explorer.notSelectDesc=Sin datos, por favor elija! +explorer.groupAuthCopy=Copia la combinación +explorer.groupAuthCopyDesc=Copiar la combinación de permisos +explorer.groupAuthPasteDesc=Pegue la combinación de permisos copiada +explorer.groupAuthSave=Guardar en favorito +explorer.groupAuthRecent=Recientemente usado +explorer.selectDesc=Seleccionar contenido +explorer.cannotLoad=No se pueden cargar los resultados. +explorer.loadMore=Cargar más resultados ... +explorer.noSearchData=No se encontraron resultados. +explorer.delAllItem=Eliminar todos los elementos +explorer.pleaseDel=Por favor eliminar +explorer.pleaseInput=Por favor ingrese al menos +explorer.canChoose=Solo seleccione como máximo +explorer.theChars=Personajes +explorer.theItems=Artículos +explorer.noData=Sin datos +explorer.ifPathAuthClear=Se borrarán todas las configuraciones de permisos de subarchivos y carpetas. ¿Está seguro de que desea continuar? +explorer.fileDescAdd=Agregar descripción del documento +explorer.fileDesc=Descripción del documento +explorer.fileLog=Registro de documentos +explorer.ifResetOpen=¿Estás seguro de que deseas restablecer todos los métodos de apertura personalizados? +explorer.ResetOpen=Restablecer todos los métodos abiertos personalizados +explorer.openWith=Abierto como ... +explorer.openWithAce=Editor abierto +explorer.openWithLocal=Abierto localmente +explorer.openWithLocalEdit=Edición local +explorer.editorSaveTips=El archivo no se ha creado, primero guarde el nuevo archivo +explorer.editor.fileTooBig=El archivo es demasiado grande y no puede ser mayor de 20M +explorer.errorFunctionTips=¡Este tipo de archivo no admite listas de funciones! +explorer.errorFormatTips=El tipo de archivo actual no coincide con el método de formato predeterminado.
    Por favor seleccione manualmente +explorer.cuteToThe=Mover a: +explorer.copyToThe=Copiar a: +explorer.addToFav=Agregar a los favoritos +explorer.addFav=Añadir favoritos +explorer.delFav=Cancelar colección +explorer.addFavSuccess=Añadir favorito con éxito +explorer.pathHasFaved=El camino ha sido favorecido +explorer.delFavSuccess=Cancelar la recolección exitosamente +explorer.fileLock=Editar bloqueo +explorer.fileLockNow=cierre +explorer.fileLockCancle=desbloquear +explorer.fileLockTitle=bloqueado +explorer.fileLockTips=Bloqueado (otros no pueden editar el archivo) +explorer.fileLockUser=Armario +explorer.fileLockError=El archivo actual está bloqueado, comuníquese con el casillero para desbloquearlo e intente nuevamente; +explorer.downloaded=Descarga completada +explorer.openAutoTips=Se abrirá automáticamente +explorer.historyAutoTips=Generar automáticamente versiones históricas +explorer.saved=Guardado exitosamente +explorer.opened=¡Abre con éxito! +explorer.openFail=¡Abierto fallido! +explorer.openingWithLoc=El archivo está abierto localmente ... +explorer.openOnlyView=El modo de solo lectura está activado +explorer.saving=Archivo guardado ... +explorer.notSupport=Algo salió mal, el formato de contenido no es compatible. +explorer.unzipErrorTips=Algo salió mal! Formato de archivo comprimido no reconocido;
    Compruebe si el archivo está comprimido o dañado. +explorer.wordLoading=Cargando ... +explorer.noFunction=De ninguna manera! +explorer.paramFormatError=¡El formato del parámetro está mal! +explorer.descTooLong=La descripción es demasiado larga. +explorer.noMoreThan=No más que +explorer.desktopDelError=Lo sentimos, la carpeta de escritorio no admite la eliminación. +explorer.copy=Copia +explorer.past=Pegar +explorer.clone=Crear una copia +explorer.cute=Cortar +explorer.cuteTo=Mover a ... +explorer.copyTo=Copiar a ... +explorer.info=Atributo +explorer.searchInPath=Buscar en carpeta +explorer.addToPlay=Agregar a la lista de reproducción +explorer.manageFav=Administrar favoritos +explorer.refreshTree=Actualizar directorio de árbol +explorer.zip=Crea un paquete comprimido +explorer.unzip=Descomprimir para ... +explorer.unzipFolder=Extraer a carpeta +explorer.unzipThis=Descomprimir a actual +explorer.unzipTo=Descomprimir para ... +explorer.openProject=Proyecto abierto editor +explorer.createLink=Crear acceso directo +explorer.createLinkHome=Enviar a acceso directo de escritorio +explorer.setBackground=Establecer como fondo de escritorio +explorer.favRemove=Cancelar esta colección +explorer.openPath=Ir al directorio +explorer.openPathFinished=Ya ingresaste al directorio +explorer.openIE=Se abre el navegador +explorer.newFile=Archivo nuevo +explorer.newFolder=Nueva carpeta +explorer.fileSaveTo=Archivo guardado en +explorer.openFather=Visualización de carpeta superior +explorer.uploadFile=Subir archivo +explorer.uploadFolder=Subir carpeta +explorer.appOpenDefault=Establecer para abrir por defecto +explorer.appOpenAways=Abra este archivo siempre con el programa que elija +explorer.appSelectDesc=Elija el programa que desea usar para abrir este archivo +explorer.appSelectMenu=Establecer como modo de apertura predeterminado +explorer.appSelectMenuCancel=Desestablecer como predeterminado abrir con +explorer.appSelectWarning=Por favor seleccione una aplicación! +explorer.appTypeSupport=Aplicaciones de apoyo +explorer.appTypeAll=Todas las aplicaciones +explorer.appSearch=Buscar instalaciones de aplicaciones relacionadas +explorer.recent.createTime=Creado en +explorer.recent.modifyTime=Modificado en +explorer.recent.viewTime=Abierto a las +explorer.urlLink=Dirección de enlace externo +explorer.downloading=Descargando ... +explorer.downReady=Próximamente +explorer.downError=¡Descarga fallida! +explorer.max=Maximiza +explorer.min=Minimizar +explorer.minAll=Minimiza todo +explorer.displayAll=Mostrar todas las ventanas +explorer.closeAll=Cerrar todo +explorer.authDtl=Haga clic para ver sus permisos en el directorio +explorer.authDialog=Miembros internos, tabla de permisos de nivel de colaboración de documentos +explorer.authNote=Nota: Las funciones de administración incluyen la configuración de permisos de miembros / administración de comentarios, etc. ¡Tenga cuidado! [Administrador del sistema] El rol no está restringido por ningún permiso +explorer.auth.toOuter=Autorización externa (otros departamentos o usuarios) +explorer.auth.share=Sharer +explorer.auth.owner=Propietario +explorer.auth.disableDeep=Sin permiso de acceso únicamente +explorer.auth.disableDeepDesc=El directorio de factores tiene permisos de lectura y escritura de documentos y la ruta de acceso establecida. +explorer.auth.tips=Puede contactar a los usuarios anteriores para establecer permisos para usted +explorer.notSystemPath=No es una ruta de archivo del sistema +explorer.toolbar.rootPath=Espacio personal +explorer.toolbar.fav=Favoritos +explorer.toolbar.desktop=Escritorio +explorer.toolbar.client=Cliente +explorer.toolbar.myComputer=Mi computadora +explorer.toolbar.recycle=Papelera de reciclaje +explorer.toolbar.myDocument=Mi documento +explorer.toolbar.myPicture=Mi foto +explorer.toolbar.myMusic=Mi musica +explorer.toolbar.myMovie=Mi video +explorer.toolbar.myDownload=Mi descarga +explorer.toolbar.uiDesktop=Escritorio +explorer.toolbar.uiExplorer=Gestión de archivos +explorer.toolbar.uiEditor=Editor +explorer.toolbar.uiProjectHome=Proyecto Inicio +explorer.toolbar.uiLogout=Salir +explorer.toolbar.uiGroup=Estructura organizacional +explorer.toolbar.myGroup=Mi departamento +explorer.toolbar.publicPath=Directorio público +explorer.toolbar.recentDoc=Documentos recientes +explorer.toolbar.myShare=Mi parte +explorer.toolbar.shareToMe=Colabora conmigo +explorer.toolbar.shareTo=Mi colaboracion +explorer.toolbar.shareLink=Compartir enlaces externos +explorer.toolbar.photo=album de fotos +explorer.photo.desc=Clasificación de álbumes de usuario +explorer.photo.group=Agrupación de álbumes +explorer.photo.setting=Configuración del álbum +explorer.photo.pathRoot=Directorio de escaneo de álbumes +explorer.photo.pathRootSelect=Seleccione una carpeta como directorio raíz para escanear imágenes de álbumes +explorer.photo.fileType=Especificar tipo de archivo +explorer.photo.fileSize=filtro de tamaño de archivo +explorer.photo.fileSizeDesc=Solo filtre archivos más grandes que esta configuración, si es 0, no hay límite +explorer.toolbar.folder=álbum de catálogo +explorer.toolbar.folderSelect=Seleccionar una carpeta para mostrar en modo álbum +explorer.pathDesc.fav=Una vez que el archivo se agrega a la colección, se puede acceder a él de manera rápida y directa +explorer.pathDesc.home=El espacio personal es su espacio de almacenamiento privado, Solo visible para ti, no para otros usuarios +explorer.pathDesc.groupRoot=Este es el espacio público de la empresa / unidad, Todos los miembros son visibles por defecto +explorer.pathDesc.myGroup=Gestiona aquí los documentos de tu departamento, Los documentos del departamento solo son visibles y operables por miembros de este departamento, y no son visibles para otros miembros del departamento. +explorer.pathDesc.group=Disco de red departamental, visible solo para miembros del departamento, La autoridad de operación es asignada y establecida por el administrador del departamento. +explorer.pathDesc.recentDoc=Archivos creados, cargados, modificados y abiertos recientemente +explorer.pathDesc.shareTo=Vea y administre sus proyectos de [colaboración interna] iniciados por otros aquí +explorer.pathDesc.shareLink=Vea y administre el uso compartido en cadena externo iniciado por usted aquí +explorer.pathDesc.recycle=Administre sus archivos (carpetas) eliminados aquí +explorer.pathDesc.fileType=Categorizar archivos por tipo, solo archivos en el espacio personal +explorer.pathDesc.tag=Agregue etiquetas a los archivos (carpetas) para lograr una clasificación eficiente y una consulta rápida +explorer.pathDesc.tagItem=¡Intente agregar una etiqueta al archivo / carpeta! +explorer.pathDesc.mount=Aquí puede administrar el almacenamiento de back-end múltiple, así como los discos montados en el servidor +explorer.pathDesc.shareToMe=Pantalla en mosaico: todo el contenido con el que colaboré +explorer.pathDesc.shareToMeUser=Mostrar por participante: el contenido con el que colaboré está categorizado por el iniciador +explorer.pathDesc.shareToMeUserItem=Colaboración iniciada por este usuario +explorer.pathDesc.shareToMeGroup=El contenido con el que colaboro está categorizado por el departamento donde se encuentra la carpeta +explorer.pathDesc.shareToMeGroupGroup=Uso compartido colaborativo desde el disco de red del departamento +explorer.pathDesc.search=Admite la búsqueda de archivos / etiquetas / notas / contenido; Admite pinyin, coincidencia difusa de la primera letra +explorer.pathDesc.searchMore=Establecer más condiciones de búsqueda +explorer.pathDesc.shareFrom=Ruta de origen +explorer.pathGroup.shareGroup=Espacio departamental +explorer.pathGroup.shareGroupDesc=Acceso cuando hay contenido en el departamento de nivel inferior +explorer.pathGroup.shareUser=Compartir el espacio personal de los miembros del departamento +explorer.pathGroup.shareUserDesc=Fuente: uso compartido del espacio personal del usuario, intercambio de documentos del departamento externo iniciado por el usuario. +explorer.pathGroup.shareContent=La colaboración y el intercambio de espacios del departamento +explorer.pathGroup.group=sub-Departamento +explorer.pathGroup.groupContent=Documento departamental +explorer.pathGroup.shareUserOuter=Compartir colaboración externa +explorer.pathGroup.shareUserOuterDesc=Uso compartido colaborativo de usuarios externos que no están bajo su propia estructura organizativa +explorer.pathGroup.shareSelf=espacio personal +explorer.toolbar.fileSizeTitle=Tamaño del icono +explorer.toolbar.fileSizeSuper=Super pequeño +explorer.toolbar.fileSizeSmall=Pequeño icono +explorer.toolbar.fileSizeDefault=Ícono mediano +explorer.toolbar.fileSizeBig=Icono grande +explorer.toolbar.fileSizeBigSuper=Icono de gran tamaño +explorer.toolbar.PagePC=Versión para PC +explorer.toolbar.pagePhone=Versión móvil +explorer.file.name=Nombre +explorer.file.type=Tipo +explorer.file.contain=Contiene +explorer.file.address=Ubicación +explorer.file.detil=Descripción +explorer.file.linkCount=Citas +explorer.file.size=Tamaño +explorer.file.count=Cantidad +explorer.file.byte=Byte +explorer.file.path=Camino +explorer.file.action=Operación +explorer.file.creator=Creador +explorer.file.editor=Modificado por +explorer.file.location=Ubicación +explorer.file.timeInfo=Información del tiempo +explorer.file.createTime=Tiempo de creación +explorer.file.modifyTime=Tiempo de modificación +explorer.file.lastTime=Ultima visita +explorer.file.sortType=Ordenar por +explorer.file.sortDisable=¡El contenido no admite la clasificación especificada! +explorer.file.timeType=Y / m / d H: i: s +explorer.file.timeTypeInfo=Y / m / d H: i: s +explorer.file.listType=Ver +explorer.file.listIcon=Arreglo de iconos +explorer.file.listList=Ordenar por lista +explorer.file.listListSplit=Modo de columna +explorer.file.listTypeGroup=Modo de visualización y método de clasificación +explorer.file.listTypeKeep=modo de visualización +explorer.file.listTypeKeepDesc=Elija un modo de visualización para cada carpeta o utilice el mismo modo de visualización para todas las carpetas +explorer.file.listSortKeep=Ordenar por +explorer.file.listSortKeepDesc=Configure el orden de clasificación de las columnas para cada carpeta o use el mismo orden para todas las carpetas +explorer.file.listViewKeep=Funciona con una sola carpeta. +explorer.file.listViewAll=se aplica a todas las carpetas +explorer.file.listViewReset=restablecen a los predeterminados +explorer.file.sortUp=En aumento +explorer.file.sortDown=Decremento +explorer.file.orderType=Ordenar por +explorer.file.orderDesc=Descendente +explorer.file.orderAsc=Orden ascendente +explorer.file.imageSize=Tamaño de la imagen +explorer.file.sharer=Sharer +explorer.file.shareTime=Tiempo compartido +explorer.file.viewCnt=Visitas +explorer.file.downCnt=Descargas +explorer.file.readWriteLock=Esta operación no es compatible temporalmente, se están procesando otras tareas de lectura y escritura, ¡inténtelo de nuevo más tarde! +explorer.app.app=Aplicación ligera +explorer.app.createLink=Nueva URL +explorer.app.create=Crea una aplicación ligera +explorer.app.edit=Editar aplicación ligera +explorer.app.open=Aplicación de luz abierta +explorer.app.groupGame=El juego +explorer.app.groupTools=Herramientas +explorer.app.groupReader=Leer +explorer.app.groupMovie=Pelicula +explorer.app.groupMusic=Musica +explorer.app.groupLife=La vida +explorer.app.desc=Descripción de la aplicación +explorer.app.icon=Icono de la aplicación +explorer.app.iconShow=dirección url o el directorio +explorer.app.group=Agrupación de aplicaciones +explorer.app.type=Tipo +explorer.app.typeUrl=Enlace +explorer.app.typeCode=extensión js +explorer.app.display=Apariencia +explorer.app.displayBorder=Sin bordes (seleccionado no tiene bordes) +explorer.app.displaySize=Cambiar tamaño (seleccionar para ajustar) +explorer.app.size=Tamaño +explorer.app.url=Dirección de enlace +explorer.app.code=código js +explorer.app.appType=Tipo de aplicación +explorer.app.website=URL +explorer.app.shortLink=Atajo de archivo +explorer.app.imgIcon=Icono de imagen +explorer.app.imgIconUrl=Seleccione la imagen o pegue la URL de la imagen web. +explorer.app.path=Camino +explorer.app.pathDesc=No admite modificaciones manuales, puede hacer clic con el botón derecho en el archivo para crear un acceso directo +explorer.app.link=Enlace URL +explorer.app.linkDesc=Por favor ingrese el enlace http / https +explorer.app.linkDragTips=¡Puede arrastrar el enlace URL al área del archivo para crear automáticamente un enlace URL! +explorer.app.openType=Camino abierto +explorer.app.openWindow=Nueva ventana +explorer.app.openDialog=Caja de diálogo +explorer.app.openCurrent=página actual +explorer.app.openInline=Insertar página +explorer.app.dialogSize=Tamaño del cuadro de diálogo +explorer.app.with=Ancho +explorer.app.height=Altura +explorer.app.moreSet=Más configuraciones +explorer.app.canDiyWith=Permitir ajuste de ancho +explorer.app.miniBlock=Barra de título minimalista +explorer.app.runCode=Ejecutar código js +explorer.app.name=Nombre de la aplicación +explorer.app.nameDesc=Por favor, introduzca el nombre de la aplicación. +explorer.app.descDesc=Por favor, introduzca una descripción de la aplicación +explorer.embed.title=Archivo incrustado +explorer.embed.desc=Insertar el archivo en una página web o blog +explorer.embed.url=Insertar URL +explorer.embed.code=Código de inserción +explorer.upload.ready=Esperando carga +explorer.upload.success=Subido correctamente +explorer.upload.secPassSuccess=Éxito en segundos +explorer.upload.pathCurrent=Cambiar al directorio actual +explorer.upload.select=Seleccionar archivo +explorer.upload.maxSize=Máximo permitido +explorer.upload.sizeInfo=Si desea configurar más grande, modifique la carga máxima permitida en php.ini. Al seleccionar un archivo, los más grandes que esta configuración se filtrarán automáticamente. +explorer.upload.error=Carga fallida +explorer.upload.mergeError=Fusionar archivos fallidos +explorer.upload.errorHttp=Error de red o firewall +explorer.upload.muti=Carga de múltiples archivos +explorer.upload.drag=Arrastra y suelta la carga +explorer.upload.dragFolder=Arrastre y suelte en la carpeta para cargar +explorer.upload.dragTips=¡Suelta para subir! +explorer.upload.pathNotAllow=El nombre del archivo no está permitido +explorer.upload.errorNull=No hay documentos! +explorer.upload.errorBig=El tamaño del archivo excede el límite del servidor +explorer.upload.errorMove=¡Error al mover archivos! +explorer.upload.errorExists=El archivo ya existe +explorer.upload.local=Subir localmente +explorer.upload.tips=Use la carga de fragmentos, que ya no está limitada por php.ini; se recomienda arrastrar y cargar la carpeta de experiencia de Chrome +explorer.upload.exist=Procesamiento de archivos con el mismo nombre +explorer.upload.clearAll=Borrar todo +explorer.upload.clear=Vaciado completado +explorer.upload.addMore=Agregar a granel +explorer.upload.errorEmpty=¡No puede estar vacío! +explorer.upload.errorExt=¡Las extensiones de archivo no coinciden! +explorer.upload.fileSizeDisable=Hay demasiados archivos cargados / transferidos al mismo tiempo, comuníquese con el administrador para ajustar. +explorer.upload.moreDesc=(Recomendado no más de 2000) +explorer.upload.scan=Escaneo +explorer.upload.merge=Verificar fusión +explorer.upload.needTime=Restante aprox. +explorer.upload.checkError=Error de verificación de carga, por favor intente nuevamente +explorer.upload.saveError=No se pudo guardar la información del archivo de carga +explorer.upload.downloadDesc=Solo admite enlaces de red http / https +explorer.table.first=Inicio +explorer.table.last=Ultima pagina +explorer.table.prev=Anterior +explorer.table.next=Página siguiente +explorer.table.one=Total 1 páginas +explorer.table.page=Pagina +explorer.table.itemPage=/página +explorer.table.searchTotal=Encontrado +explorer.table.items=Registros +explorer.table.list=Lista de datos +explorer.search.ing=Buscando ... +explorer.search.result=Resultado de busqueda +explorer.search.resultTooMore=Demasiados resultados de búsqueda, sugiera otro directorio o palabra +explorer.search.resultNull=No hay resultados de búsqueda! +explorer.search.caseSensitive=Mayúsculas y minúsculas +explorer.search.content=Buscar contenido del archivo +explorer.search.extDesc=Ingrese las extensiones a filtrar, separadas por espacios. +explorer.search.byItems=Filtrado condicional +explorer.search.extNull=Tipo ilimitado +explorer.search.extFile=Cualquier archivo +explorer.search.extDiy=personalizar +explorer.search.inputDesc=¡Ingrese palabras clave o proporcione filtros! +explorer.search.path=Buscar en el directorio: +explorer.search.rootPath=Buscar en el directorio raíz: +explorer.search.range=Rango de búsqueda +explorer.search.allFolder=Todas las carpetas +explorer.search.currentFolder=Carpeta actual +explorer.search.ext=Tipo de archivo +explorer.search.timeRange=Rango de tiempo +explorer.search.timeAll=Tiempo ilimitado +explorer.search.lastDay=Casi 1 día +explorer.search.lastWeek=Últimos 7 días +explorer.search.lastMonth=Últimos 30 días +explorer.search.lastYear=El año pasado +explorer.search.sizeAll=Tamaño ilimitado +explorer.search.inputNullDesc=Si no se llena, significa mayor o menor que cierto valor, que puede ser un decimal. +explorer.search.selectUser=Seleccionar usuario ... +explorer.search.byUserDesc=Buscar por creador / modificador +explorer.search.total=Encontrado +explorer.search.noResult=Lo sentimos, no hay resultados de búsqueda, intente con otro término de búsqueda. +explorer.search.advance=Búsqueda avanzada +explorer.search.clear=Contenido claro +explorer.history.list=Historial de archivos +explorer.history.lastModify=Última modificación +explorer.history.modifyUser=Modificado por +explorer.history.noHistory=No hay versión histórica! +explorer.history.current=Versión actual +explorer.history.detil=Descripción +explorer.history.detilAdd=Añadir impresión +explorer.history.uploadNew=Subir nueva versión +explorer.history.diff=Comparación de versiones históricas +explorer.history.setCurrent=Establecer como versión actual +explorer.history.delCurrent=Eliminar esta versión +explorer.history.delAll=Eliminar todo el historial de versiones +explorer.history.ifDelAll=¿Seguro que quieres eliminar todo el historial? +explorer.history.ifDelCurrent=¿Eliminar esta versión? +explorer.history.ifRollback=¿Seguro que quieres volver a esta versión? +explorer.history.changeEvent=Cambio de versión histórica +explorer.history.before=Antes +explorer.history.after=después +explorer.recycle.clearUser=Vacíe la papelera de reciclaje del usuario +explorer.recycle.restoreSelect=Restaurar este contenido +explorer.recycle.moveTo=Entregar +explorer.recycle.config=Reciclar la configuración de la papelera +explorer.recycle.configTitle=Configuración de la papelera de reciclaje del sistema +explorer.recycle.configOpen=Abra la papelera de reciclaje del sistema +explorer.recycle.configOpenDesc=Sugerir para abrir +explorer.recycle.configCloseInfo=Al eliminar contenido, no ingresará a la papelera de reciclaje del sistema; se eliminará directamente. +explorer.recycle.configOpenInfo=
  • Documentos personales o documentos departamentales, luego de eliminar o vaciar completamente la papelera de reciclaje, ingresan a la papelera de reciclaje del sistema
  • El contenido eliminado se clasifica en la carpeta de usuario o departamento según el usuario o departamento donde se encuentra el archivo, y el administrador puede optar por restaurar estos archivos;
  • Los archivos anteriores al momento de la eliminación completa automática se vaciarán automáticamente con regularidad;
  • Nota: Los archivos eliminados aquí no se pueden recuperar.
  • +explorer.recycle.configClear=Eliminar de forma completamente automática +explorer.recycle.restoreConfirm=¿Estás seguro de restaurar el documento?
    Después de la restauración, el documento se moverá al directorio raíz de destino. +explorer.recycle.moveConfirm=Confirmar traspaso +explorer.recycle.moveSelectTarget=Seleccionar usuario o departamento +explorer.recycle.moveDesc=
  • Entregar al usuario o departamento designado; el directorio raíz del objeto será migrado
  • Después de la transferencia, se seguirán conservando las descripciones de los documentos, los intercambios y las discusiones, las versiones históricas y otra información; se eliminará la colaboración compartida y la información sobre permisos.
  • +explorer.recycle.taskTitle=Limpieza de la papelera de reciclaje del sistema +explorer.recycle.taskDesc=Elimine automáticamente el contenido de la papelera de reciclaje que exceda el tiempo establecido para liberar espacio de almacenamiento +explorer.share.add=Añadir compartir +explorer.share.edit=Editar Compartir +explorer.share.remove=Cancelar compartir +explorer.share.path=Compartir ruta +explorer.share.source=Intercambio de recursos +explorer.share.name=Compartir título +explorer.share.nameDesc=Compartir nombre de archivo por defecto, se puede personalizar +explorer.share.time=Tiempo de expiración +explorer.share.timeLimit=Tiempo limitado +explorer.share.timeLimitDesc=Después de encender y configurar, el uso compartido se deshabilitará automáticamente después de que el tiempo exceda +explorer.share.timeDesc=No establecido si está vacío +explorer.share.pwd=Extraer contraseña +explorer.share.pwdDesc=No hay contraseña establecida +explorer.share.randomPwd=Generado aleatoriamente +explorer.share.randomPwdDesc=Solo se puede ver extrayendo la contraseña, que es más privada y segura. +explorer.share.cancel=Cancelar compartir +explorer.share.create=Crear enlace público +explorer.share.url=Dirección compartida +explorer.share.noDown=Descarga prohibida +explorer.share.codeRead=Lectura de código +explorer.share.configSave=Guardar la configuración +explorer.share.errorParam=Error de parámetro +explorer.share.errorUser=La información del usuario está mal! +explorer.share.errorSid=Compartir no existe! +explorer.share.errorTime=¡Llegas tarde, esta acción ha expirado! +explorer.share.errorPath=El archivo compartido no existe, se ha eliminado o movido. +explorer.share.errorPwd=¡La contraseña es incorrecta! +explorer.share.errorShowTips=¡Este tipo de archivo no es compatible con la vista previa! +explorer.share.expiredTips=Lo sentimos, este recurso ha caducado, ¡comuníquese con el usuario! +explorer.share.downExceedTips=Lo sentimos, las descargas compartidas excedieron el límite establecido por el compartidor +explorer.share.store=Guardar en SkyDrive +explorer.share.loginTips=Lo sentimos, este recurso compartido debe estar registrado como usuario para acceder. +explorer.share.noDownTips=Lo sentimos, el usuario ha inhabilitado la descarga. +explorer.share.noViewTips=Lo sentimos, este usuario ha deshabilitado la vista previa. +explorer.share.noUploadTips=Lo sentimos, la carga está deshabilitada por este usuario. +explorer.share.needPwd=Este recurso compartido requiere una contraseña +explorer.share.notExist=¡Compartir no existe! +explorer.share.viewNum=Navegar: +explorer.share.downNum=Descargas +explorer.share.openPage=Abrir página compartida +explorer.share.openLink=Abrir enlace para compartir +explorer.share.copyLink=Copiar información para compartir +explorer.share.link=Compartir enlace: +explorer.share.accessPwd=Contraseña de acceso: +explorer.share.copied=Copiado +explorer.share.actionNotSupport=Compartir contenido, esta operación no es compatible +explorer.share.errorPathTips=El enlace para compartir es incorrecto o el usuario ha cancelado el enlace para compartir externo +explorer.share.shareTo=Intercambio colaborativo +explorer.share.shareToTarget=Miembro colaborador +explorer.share.innerTo=Colaboración interna +explorer.share.linkTo=Enlace externo compartido +explorer.share.selectTarget=Seleccione un departamento o usuario para compartir en colaboración +explorer.share.afterShareDesc=Después de compartir con la otra parte o el departamento al que pertenecen, los usuarios pueden verlo en [Compartir conmigo]. +explorer.share.openOuterLink=Abrir cadena externa compartida +explorer.share.openOuterLinkDesc=Después de crear un enlace externo, puede enviarlo a otros por correo electrónico o QQ. +explorer.share.outerLink=Compartir enlace +explorer.share.advanceSet=Configuración avanzada +explorer.share.loginLimit=Disponible solo para usuarios registrados +explorer.share.loginLimitDesc=Después de abrir, solo los miembros internos pueden acceder. +explorer.share.authLimit=Derechos y restricciones +explorer.share.canUpload=Permitir subir +explorer.share.notView=Deshabilitar vista previa +explorer.share.notDown=Deshabilitar descargas +explorer.share.downNumLimit=Límite de descarga +explorer.share.downNumLimitDesc=Después de este número de veces, el enlace para compartir caduca automáticamente. +explorer.share.learnAuth=Comprender los permisos de colaboración de documentos +explorer.share.shareToRemove=¿Está seguro de cancelar este uso compartido colaborativo?
    ¡El usuario de destino con quien compartió ya no puede ver el recurso compartido colaborativo! +explorer.share.shareLinkRemove=¿Está seguro de cancelar el uso compartido de enlaces externos?
    Después de la cancelación, el enlace externo no será válido. +explorer.share.shareToCopy=Copiar ruta de acceso +explorer.share.shareToCopyDesc=Puede enviar el enlace a la persona colaboradora e ingresar rápidamente a la colaboración +explorer.share.specifyAuthTips=Además de los usuarios especificados anteriormente +explorer.share.specifyAuthDesc=Autoridad de usuario designada> Autoridad de departamento de usuario designado> Autoridad de otra persona +explorer.share.selfAuthDesc=No se pueden modificar los permisos propios, otros administradores pueden establecer +explorer.share.authTypeDesc=Heredar permisos de la carpeta principal de forma predeterminada +explorer.share.rootPathAuthDesc=El departamento raíz admite la selección de usuarios y departamentos +explorer.share.subPathAuthDesc=Subdepartamento, solo miembros seleccionados del departamento +explorer.share.myAuth=Mis permisos +explorer.share.othersAuth=Otros permisos +explorer.share.keepAuth=Mantener permisos originales +explorer.share.specifyAuth=Especificar permisos +explorer.share.userAuth=Derechos de usuario +explorer.share.specifyUserAuth=Especificar permisos de usuario +explorer.share.rptTitle=Si encuentra información ilegal y dañina, seleccione el motivo a continuación para enviar un informe. +explorer.share.illegal=Información ilegal +explorer.share.inputRptDesc=Ingrese el motivo de la denuncia +explorer.share.rptSend=El envío es exitoso, el administrador lo manejará a tiempo +explorer.share.rptSended=Se ha enviado el informe, esperando que el administrador lo procese +explorer.auth.mutil=Establecer permisos en lotes +explorer.auth.mutilTips=Nota : Si el contenido seleccionado ya tiene permiso, se sobrescribirá. +explorer.auth.mutilDesc=Al mismo tiempo que los permisos predeterminados posteriores +explorer.auth.showMore=Detalles del permiso +explorer.auth.tabUser=miembro del departamento +explorer.auth.tabChildren=permisos de subcarpetas +explorer.auth.tabUserTips=Permisos iniciales de los miembros del departamento +explorer.auth.tabChildrenTips=Contenidos con permisos establecidos en esta carpeta +explorer.auth.resetUser=Anular la configuración de este permiso de usuario +explorer.auth.resetUserBtn=Anular permisos +explorer.auth.resetUserBtnTips=Anular los permisos de usuario y todas las subcarpetas (carpetas) en esta carpeta +explorer.auth.resetUserHeader=La carpeta de nivel inferior contiene el contenido que especifica los permisos del usuario y establece todas las anulaciones a los permisos anteriores. +explorer.auth.resetUserContiner=Contiene el contenido del permiso del usuario. +explorer.auth.resetUserEmpty1=No hay contenido para el que se hayan establecido permisos para este usuario, no es necesario anularlo +explorer.auth.resetUserEmpty2=Todo el contenido secundario hereda los permisos de carpeta de nivel actual +explorer.rename.mutil=Cambio de nombre de lote +explorer.rename.nameBefore=Nombre de archivo original +explorer.rename.nameTo=Renombrado +explorer.rename.start=Renombrar ahora +explorer.rename.clearFinished=Vaciado completado +explorer.rename.clearAll=Borrar todo +explorer.rename.typeReplaceAll=Reemplazar todo +explorer.rename.typePrepend=Añadir antes +explorer.rename.typeAppend=Añadir más tarde +explorer.rename.typeReplace=Encuentra y reemplaza +explorer.rename.typeChangeCase=Conversión de caso +explorer.rename.typeRemove=Eliminar personajes +explorer.rename.typeReplaceSet=Especificar reemplazo en lote +explorer.rename.typeReplaceSetDesc=Reemplazar si son iguales; cada línea está separada por un espacio y el nombre del archivo no permite espacios; por ejemplo: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Contenido adicional +explorer.rename.find=Encontrar +explorer.rename.replaceTo=Reemplazado con +explorer.rename.caseUpperFirst=Capital inicial +explorer.rename.caseUpper=Todas las tapas +explorer.rename.caseLower=Todo en minúsculas +explorer.rename.removeStart=Eliminar desde cero +explorer.rename.removeEnd=Eliminar del final +explorer.rename.chars=Personaje +explorer.editor.beautifyCode=Formato de código +explorer.editor.convertCase=Conversión de caso +explorer.editor.convertUpperCase=Convertir a mayúsculas +explorer.editor.convertLowerCase=Convertir a minúsculas +explorer.editor.currentTime=Hora actual +explorer.editor.md5=cifrado md5 +explorer.editor.qrcode=Código QR de cadena +explorer.editor.regx=Prueba de expresión regular +explorer.editor.chinese=Conversión simplificada +explorer.editor.chineseSimple=Convertir a chino simplificado +explorer.editor.chineseTraditional=Convertir a chino tradicional +explorer.editor.base64=códec base64 +explorer.editor.base64Encode=codificación base64 +explorer.editor.base64Decode=decodificación base64 +explorer.editor.url=Códec URL +explorer.editor.urlEncode=Codificación URL +explorer.editor.urlDecode=Decodificación de URL +explorer.editor.unicode=Códec Unicode +explorer.editor.unicodeEncode=Codificación Unicode +explorer.editor.unicodeDecode=Decodificación Unicode +explorer.editor.toolsSelectTips=Seleccione el contenido correcto para ser procesado. +explorer.editor.toolsRandString=Generar cadena aleatoria de 32 bits +explorer.editor.textEncode=Codificación / decodificación de texto +explorer.editor.textParse=Procesamiento de texto +explorer.editor.timeShow=Marca de tiempo a tiempo +explorer.editor.timeInt=Tiempo hasta la marca de tiempo +explorer.editor.lineRemoveEmpty=Eliminar líneas en blanco (incluidos los espacios) +explorer.editor.lineUnoin=Eliminar filas duplicadas +explorer.editor.lineTrim=Eliminar espacios iniciales y finales +explorer.editor.lineSort=Ordenar por fila (orden ascendente) +explorer.editor.lineReverse=Intercambia todas las líneas hacia arriba y hacia abajo +explorer.editor.lineSum=Suma +explorer.editor.lineAverage=valor promedio +explorer.editor.calc=Calculadora gratis +explorer.editor.goToLine=Saltar a la linea +explorer.editor.keyboardType=Modo de teclado +explorer.editor.fontFamily=Font +explorer.editor.codeMode=Sintaxis resaltada +explorer.editor.closeAll=Cerrar todo +explorer.editor.closeLeft=Cerrar pestaña izquierda +explorer.editor.closeRight=Cerrar pestaña derecha +explorer.editor.closeOthers=Cerrar otro +explorer.editor.wordwrap=Word wrap +explorer.editor.showGutter=Mostrar número de línea +explorer.editor.charAllDisplay=Mostrar personajes invisibles +explorer.editor.autoComplete=Aviso automático +explorer.editor.autoSave=Guardar automáticamente +explorer.editor.functionList=Lista de funciones +explorer.editor.codeTheme=Estilo de código +explorer.editor.fontSize=Tamaño de fuente +explorer.editor.completeCurrent=Corriente autocompletada +explorer.editor.createProject=Agregar al proyecto del editor +explorer.editor.markdownContent=Directorio de contenido +explorer.editor.undo=Revocar +explorer.editor.redo=Anti-revocación +explorer.editor.shortcut=Atajo +explorer.editor.replace=Reemplazar +explorer.editor.reload=Recargar +explorer.editor.view=Ver +explorer.editor.tools=Herramientas +explorer.editor.help=Ayuda +explorer.sync.data=Sincronización de datos +explorer.sync.openLoc=Abrir directorio local +explorer.sync.syncing=Sincronización +explorer.sync.synced=Sincronización completada +explorer.sync.syncedError=Registro de errores +explorer.sync.syncStart=Comienza a sincronizar +explorer.sync.syncStop=Deja de sincronizar +explorer.sync.notOpenTips=No has activado la sincronización local +explorer.sync.setNow=Configurar sincronización ahora +explorer.sync.error=Carga fallida +explorer.sync.success=Sincronización exitosa +explorer.sync.statusScan=Escaneo +explorer.sync.statusNone=La sincronización no está configurada +explorer.sync.statusScanEnd=Escaneo completado +explorer.sync.statusDoing=Sincronización +explorer.sync.statusDone=Sincronización completada +explorer.sync.statusStop=Pausa +explorer.sync.clearCacheSuccess=Borrar caché exitoso! +explorer.sync.emptyTask=Sin tarea de sincronización +explorer.sync.openCloud=Abrir ubicación en la nube +explorer.sync.openLocal=Abierto localmente +explorer.sync.statusFiles=Documentar el progreso +explorer.sync.statusLastTime=Tiempo de finalización +explorer.sync.configName=Configuraciones de sincronización +explorer.sync.configClient=Configuraciones del cliente +explorer.sync.configAbout=Acerca de +explorer.sync.configSyncFrom=Camino local +explorer.sync.configSyncFromDesc=Seleccione una carpeta local para sincronizar +explorer.sync.configSyncTo=Sincronizar con +explorer.sync.configSyncToDesc=Sincronizar con la ubicación del servidor +explorer.sync.configIgnore=Tipos de archivo ignorados +explorer.sync.configIgnoreDesc=Los archivos de este tipo no están sincronizados +explorer.sync.autorun=Auto-arranque +explorer.sync.configThread=Número de hilos concurrentes +explorer.sync.configThreadDesc=Número de archivos cargados al mismo tiempo +explorer.sync.configDownloadPath=Descargar ruta +explorer.sync.configDownloadPathDesc=Ruta de descarga predeterminada al descargar carpetas de archivos +explorer.sync.configClearCacheAuto=Borrar automáticamente el caché +explorer.sync.configClearCacheAutoDesc=Borrar automáticamente el archivo de caché hace N días +explorer.sync.configClearCache=Borrar caché +explorer.sync.configChangeSite=Salir del sitio actual +explorer.sync.configVersion=Versión actual +explorer.sync.configUpdateDesc=Instrucciones de actualización +explorer.sync.configUpdateCheck=Detectando actualizaciones +explorer.sync.confirmReset=Sincronice la modificación del directorio, la información de sincronización se restablecerá. ¿Está seguro de guardar? +explorer.sync.listClearDone=Vaciado completado +explorer.sync.listClearError=Borrar lista de errores +explorer.sync.listRetryAll=Reintentar todo +explorer.async.tipsDisablePath=No admite elegir sincronizar la ruta +explorer.async.tipsIsMoving=Se detectó que una gran cantidad de contenido se está moviendo o copiando actualmente al directorio sincronizado;
    ¡Se recomienda actualizar la página para la sincronización después de la finalización local! +explorer.async.tipsStartUser=Iniciar sincronización manualmente +explorer.download.title=Gestión de descargas +explorer.download.waiting=Esperando +explorer.download.stop=Pausar descarga +explorer.download.start=Comienza a descargar +explorer.download.remove=Quitar tarea +explorer.download.stopAll=Pausar todo +explorer.download.startAll=Continuar todo +explorer.download.clearAll=Borrar todas las tareas +explorer.download.doing=Procesando +explorer.download.done=Descarga completa +explorer.download.clearAllTips=¿Está seguro de eliminar todas las tareas de descarga? +explorer.tag.name=Etiqueta de archivo +explorer.tag.edit=Gestión de etiquetas +explorer.tag.add=Crear etiqueta +explorer.tag.remove=¿Está seguro de que desea eliminar esta etiqueta? +explorer.tag.inputHolder=Por favor, introduzca un nombre de etiqueta +explorer.tag.addTo=Coloca una etiqueta +explorer.tag.default1=Aprender +explorer.tag.default2=Datos de prueba +explorer.tag.default3=contrato +explorer.tag.filter=Filtrar por etiqueta +explorer.groupTag.title=Etiqueta pública +explorer.groupTag.menuTtitle=Etiqueta pública del departamento +explorer.groupTag.titleDesc=Etiqueta pública dentro del departamento +explorer.groupTag.empty=Una vez que el administrador del departamento establece la etiqueta pública, esta se habilita automáticamente. Cuando no hay contenido de etiqueta, ¡la etiqueta pública se apaga automáticamente! +explorer.tag.pathDesc=Filtrar por etiqueta personal +explorer.groupTag.pathDesc=Filtrar por etiqueta pública de departamento +explorer.groupTag.removeTypeTips=¿Está seguro de eliminar este grupo? ¡Todos los documentos asociados con la etiqueta se eliminarán después de la eliminación! +explorer.groupTag.removeTagTips=¿Está seguro de que desea eliminar la etiqueta? ¡El documento asociado con la etiqueta se eliminará después de la eliminación! +explorer.groupTag.typeAdd=añadir categoría +explorer.groupTag.typeName=nombre de la categoría +explorer.groupTag.addDesc=Después de agregar etiquetas, las etiquetas de departamento se habilitan automáticamente y el número máximo de etiquetas es 1000 +explorer.panel.info=Atributos +explorer.panel.version=versión +explorer.panel.chat=discutir +explorer.panel.log=dinámica +explorer.panel.meta=Metadatos +explorer.panel.chatName=Discusión de intercambio +explorer.panel.chat.send=enviar +explorer.panel.chat.noAuth=¡No tiene permiso para comentar este documento! +explorer.panel.chat.placeholder=Ingrese aquí, [Intro] para enviar, [Ctrl + Intro] avance de línea +explorer.panel.chat.placeholderCtrl=Ingrese aquí, Ctrl + Enter para enviar, Enter para envolver +explorer.panel.chat.reply=Respuesta +explorer.panel.chat.empty=sin comentarios +explorer.panel.chat.sendTo=Adelante +explorer.panel.metaName=Extensión de metadatos +explorer.panel.metaDesc=Propiedades de campo de documento extendido +explorer.panel.thumbClear=miniatura clara +explorer.panel.thumbClearDesc=Borrar miniaturas de archivos, carátula para regenerar. +explorer.panel.historyName=versión histórica +explorer.panel.historyDesc=Notas de lanzamiento +explorer.panel.infoTips=Seleccione el archivo (carpeta) para ver propiedades detalladas +explorer.panel.info.space=Capacidad de espacio +explorer.panel.info.groupAt=Ubicación del departamento +explorer.panel.info.tagEmpty=Sin etiquetas, haga clic en configuración +explorer.panel.logName=Noticias de documentos +explorer.panel.logEmpty=Ninguna actividad +explorer.type.doc=Doc +explorer.type.image=imagen +explorer.type.music=música +explorer.type.movie=vídeo +explorer.type.zip=Archivo +explorer.type.others=otro +explorer.secret.title=Gestión de la confidencialidad de los documentos +explorer.secret.isOpen=Ya sea para habilitar +explorer.secret.isOpenDesc=Habilitar y deshabilitar la administración del nivel de seguridad +explorer.secret.setUser=administrador secreto +explorer.secret.setUserDesc=Especifique el usuario que puede establecer el nivel de confidencialidad (debe ser el propietario en el departamento correspondiente al mismo tiempo) +explorer.secret.type=Tipo de clasificación +explorer.secret.add=Agregar nivel de seguridad +explorer.secret.edit=editar nivel de seguridad +explorer.secret.name=Nombre de la clase +explorer.secret.style=estilo +explorer.secret.auth=Permiso de nivel secreto +explorer.secret.authHas=Los permisos confidenciales incluyen +explorer.secret.createUser=setter +explorer.secret.folderAt=carpeta confidencial +explorer.secret.tips=Los permisos están controlados por el nivel secreto, y los permisos del nivel secreto son más altos que los permisos del documento. +explorer.secret.tips1=Solo para el contenido del disco de red departamental, el usuario especificado mencionado anteriormente puede establecer el nivel de confidencialidad (y debe ser el propietario de la carpeta al mismo tiempo) +explorer.secret.tips2=Se establece todo el contenido en la capa inferior de la carpeta con el nivel de confidencialidad, y esta autoridad es la autoridad más alta +explorer.secret.tips3=Después de la configuración, el permiso de nivel secreto es más alto que el permiso del documento (el documento también está controlado por el permiso de nivel secreto, el superadministrador del sistema no está sujeto a esta restricción y el establecedor de nivel secreto no está sujeto a esta restricción) +explorer.secret.tips4=Permisos de nivel confidencial: se pueden agregar en "Administración de departamentos y miembros--Administración de derechos de documentos" y establecerse como ocultos +user.displayHideFile=Mostrar archivos ocultos +user.displayHideFileDesc=Archivos ocultos: archivos que comienzan con., Y nombres de archivos ocultos establecidos en el fondo del sistema; los archivos ocultos se mostrarán después de abrirlos; +user.soundOpen=Enciende el sonido +user.animateOpen=Iniciar animación +user.recycleOpen=Papelera de reciclaje abierta +user.recycleDesc=Después de abrir, eliminar se moverá a la papelera de reciclaje, se recomienda abrir +user.animateDesc=Animaciones como la apertura de ventanas, puede considerar cerrar cuando la operación no es fluida +user.soundDesc=Abrir archivos, eliminar archivos, vaciar papelera de reciclaje, etc. +user.thumbOpen=Abrir miniatura de imagen +user.thumbDesc=Mejor experiencia de exploración de imágenes después de abrir +user.fileSelect=Ícono de archivo abierto +user.fileSelectDesc=Haga clic con el botón izquierdo en el icono del archivo, acceso directo al menú del botón derecho +user.fileShowDesc=Mostrar introducción a la carpeta +user.fileShowDescTips=modo de solo icono +user.fileOpenClick=Abra el archivo (carpeta) de la siguiente manera +user.fileOpenClick.dbclick=Abrir con doble clic +user.fileOpenClick.click=Abrir haciendo clic +user.viewSetting=Mostrar opciones +user.thirdAccount=Cuenta de terceros +user.bindAccount=Vincular cuenta +user.thirdBindFirst=La cuenta no se ha vinculado, úsela después de la vinculación +user.account=Cuenta +user.bind=Atar +user.unbind=Desatar +user.binded=Obligado +user.clickBind=Click Bind +user.clickToBind=Sin consolidar, haga clic en enlace +user.clickEditPwd=Haga clic en Modificar contraseña +user.userAvatar=Foto de perfil +user.userNickName=Apodo personal +user.userAccount=Cuenta personal +user.uploadAvatar=Subir avatar +user.userAvatarCrop=Seleccione un área adecuada como avatar +user.userAvatarExt=Solo admite formatos de imagen JPG, JPEG, PNG +user.resetPwdDesc=¿Olvidó su contraseña? Puede +user.inputEmailCode=Por favor ingrese su código de verificación de correo electrónico +user.inputSmsCode=Por favor ingrese el código de verificación de SMS +user.emailVerifyDesc=Algunas empresas requieren verificación por correo electrónico +user.phoneVerifyDesc=Algunas empresas requieren verificación de teléfono móvil +user.bindOthers=Ya vinculado a otra cuenta +user.notBind=Aún no atado +user.regist=Registro de usuario +user.notRegist=No registrado +user.registed=Ya registrado +user.signError=La firma de devolución de llamada es incorrecta +user.repeat=Repetir +user.noRepeat=No se puede repetir +user.newPwd=Nueva contraseña +user.unAuthFile=Acceso no autorizado a archivos +user.unbindWarning=Cambie la contraseña antes de desvincular, de lo contrario la cuenta no funcionará correctamente. +user.isLoginTips=¡Se ha detectado que está conectado actualmente! +user.isLoginEnter=Entra ahora +user.ifUnbind=¿Estás seguro de que quieres deshacerte? +user.bindFirst=Por favor, primero añada su correo electrónico o número de teléfono móvil +user.inputNewPwd=Por favor ingrese una nueva contraseña +user.inputNewValue=Por favor complete el nuevo contenido +user.guestLogin=Inicio de sesión turístico +user.name=Cuenta de inicio de sesión +user.nickName=Apodo del usuario +user.code=Código de verificación +user.codeError=Error de código de verificación +user.imgCode=Captcha +user.rootPwd=Establecer contraseña de administrador +user.rootPwdRepeat=Confirme la contraseña nuevamente +user.rootPwdEqual=¡Las contraseñas no coinciden dos veces! +user.rootPwdTips=Por favor, configure una contraseña de administrador! +user.pwdError=Nombre de usuario o contraseña incorrectos! +user.pwdNotNull=¡La contraseña no puede estar vacía! +user.oldPwdError=¡La contraseña original es incorrecta! +user.keepPwd=Recordar contraseña +user.forgetPwd=Olvidé mi contraseña +user.directLogin=Ya inicié sesión +user.moreLogin=Más formas de iniciar sesión +user.loginNow=Inicia sesión ahora +user.registNow=Regístrate ahora +user.backHome=De vuelta a casa +user.ifHasAccount=¿Ya tienes una cuenta? +user.userEnabled=¡La cuenta está deshabilitada o aún no está habilitada! Por favor contacte al administrador +user.roleError=El grupo de permisos no existe, comuníquese con el administrador +user.invalidEmail=No tiene una dirección de correo electrónico válida, póngase en contacto con el administrador para modificar +user.codeRefresh=Haga clic en actualizar +user.emailVerify=Autenticación de buzón +user.sendSuccess=Enviado con éxito +user.sendFail=Envío fallido +user.sendSuccessDesc=El código de verificación se envió correctamente, ve a ver +user.sendFailDesc=No se pudo enviar el código de verificación, comuníquese con el administrador +user.inputVerifyCode=Por favor ingrese el código de verificación +user.getCode=Obtén el código de verificación +user.inputPwd=Por favor ingrese la contraseña +user.inputPwdAgain=Por favor ingrese la contraseña nuevamente +user.inputNickName=Por favor ingrese un apodo +user.inputEmail=Por favor ingrese su dirección de correo electrónico +user.inputPhone=Por favor ingrese su número de teléfono +user.inputPhoneEmail=Por favor, introduzca el teléfono móvil / correo electrónico +user.invalidPhoneEmail=Teléfono / Email inválido +user.findPwd=Recuperar contraseña +user.inputNotMatch=El %s ingresado no coincide con el límite +user.usingDesc=Estas usando +user.improveInfo=Por favor complete la información +user.codeExpired=El código de verificación ha expirado, consíguelo nuevamente +user.codeErrorTooMany=Demasiados errores de código de verificación, vuelva a adquirir +user.codeErrorFreq=La frecuencia de envío es demasiado alta. Vuelve a intentarlo más tarde. +user.codeErrorCnt=El número de envíos ha superado el límite y se bloqueará durante %s horas. +user.registSuccess=Registrado exitosamente +user.waitCheck=Esperando la revisión del administrador +user.nameHolder=Ingrese su número de teléfono / correo electrónico +user.loginNoPermission=Lo sentimos, no tiene este permiso, ¡inicie sesión con una cuenta con este permiso! +user.loginFirst=¡No has iniciado sesión! Inicia sesión primero +user.bindSignError=La firma es anormal, por favor intente nuevamente! +user.bindUpdateError=Error en la actualización de la información del usuario, intente nuevamente +user.bindTypeError=Tipo de enlace inválido +user.bindWxConfigError=Obtener la excepción de información de configuración +user.loginTimeout=El inicio de sesión actual ha excedido el tiempo de espera, ¡vuelva a iniciar sesión! +user.theme=Estilo del tema +user.theme.desc=Sistema automático de seguimiento de representantes +user.theme.light=Color claro +user.theme.dark=Color oscuro +user.theme.auto=automático +user.theme.title=Configuraciones de tema personalizadas +user.theme.background=Antecedentes +user.theme.image=Imágenes +user.theme.colorBlur=Color degradado +user.theme.imageBlur=Procesamiento de desenfoque de imagen +user.theme.imageUrl=Dirección de imagen +user.theme.colorStart=Color de inicio +user.theme.colorEnd=Color final +user.theme.colorRadius=Ángulo de gradiente +user.theme.themeImage=Imagen de fondo +user.theme.themeImageDesc=Soporte: URL de imagen, color degradado css, seguir fondo de pantalla +user.theme.imageWall=Seguir el fondo de pantalla +user.wall.random=Fondo de pantalla aleatorio +user.wall.paperDesktop=Fondos de escritorio +user.wall.paperDeskMgt=Gestión de fondos de escritorio +user.wall.paperLoginMgt=Gestión de fondos de pantalla de inicio de sesión +user.wall.paperLoginTips=Cuando hay más de una imagen, el fondo de la interfaz de inicio de sesión rotará aleatoriamente +log-type-create-mkdir=nueva carpeta +log-type-create-mkfile=crear un nuevo archivo +log-type-create-upload=subir archivos +log-type-create-copy=Pegar archivo +log-type-edit=Actualizar archivo +log-type-move=Mover archivo +log-type-moveOut=Eliminar archivos +log-type-share-shareLinkAdd=Creó un enlace externo compartido +log-type-share-shareToAdd=Compartir colaboración activado +log-type-share-shareLinkRemove=Compartir enlaces cerrados +log-type-share-shareToRemove=Desactiva el intercambio colaborativo +log-type-share-shareEdit=Editar compartir +log-type-rename=Rebautizar +log-type-recycle-toRecycle=Mover a la papelera de reciclaje +log-type-recycle-restore=Restaurar desde la papelera de reciclaje +log-type-remove=Eliminar +log-type-addDesc=Modificar descripción +log-type-addComment=Publicar un comentario +log-event-create-mkdir=Creó esta carpeta +log-event-create-mkfile=Creado el archivo +log-event-create-upload=Subido el archivo +log-event-create-copy=El archivo fue creado pegando +log-event-create-mkdir-current=Creé una nueva carpeta aquí {0} +log-event-create-mkfile-current=Nuevo archivo creado aquí {0} +log-event-create-upload-current=Subido aquí {0} +log-event-create-copy-current=Pegado {0} aquí +log-event-create-mkdir-item=Creó una nueva carpeta en {0} {1} +log-event-create-mkfile-item=Nuevo archivo creado en {0} {1} +log-event-create-upload-item=Subido {1} en {0} +log-event-create-copy-item=Pegar {0} a {1} +log-event-create-mkdir-more=Creé {0} carpetas aquí +log-event-create-mkfile-more={0} nuevos archivos creados aquí +log-event-create-upload-more={0} archivos cargados aquí +log-event-create-copy-more=Pegó {0} archivos aquí +log-event-create-mkdir-more-at=Se crearon {1} carpetas nuevas en {0} +log-event-create-mkfile-more-at=Creó {1} archivos nuevos en {0} +log-event-create-upload-more-at={1} archivos cargados en {0} +log-event-create-copy-more-at={0} documentos pegados a {1} +log-event-view-item=Visto {0} +log-event-edit=actualizado el archivo +log-event-edit-item=Editar actualizado {0} +log-event-edit-more=Editar archivos {0} actualizados +log-event-edit-more-user=Editó y actualizó el archivo {0} {1} veces +log-event-edit-more-at=Archivos editados y actualizados {1} en {0} +log-event-move=Mover el documento de {0} a {1} +log-event-move-item=Mover {0} de {1} a [3] +log-event-move-current=Mueve {0} desde {1} aquí +log-event-move-more={0} documentos movidos +log-event-move-more-desc=Mover {0} de {1} a [3] +log-event-moveOut-more-desc=Eliminado de {0} {1} +log-event-moveOut=Eliminado de aquí {0} +log-event-moveOut-item=Eliminado de {0} {1} +log-event-moveOut-more={0} documentos eliminados +log-event-share-shareLinkAdd=Creó un enlace externo para compartir este documento +log-event-share-shareLinkAdd-item={0} creó un enlace externo para compartir +log-event-share-shareLinkAdd-more=Se crearon {0} enlaces para compartir +log-event-share-shareToAdd=Activar el intercambio colaborativo de este documento +log-event-share-shareToAdd-item={0} activó el intercambio colaborativo +log-event-share-shareToAdd-more={0} acciones colaborativas creadas +log-event-share-shareLinkRemove=Cerró el intercambio de enlaces del documento. +log-event-share-shareLinkRemove-item=Cerrado el intercambio de enlaces de {0} +log-event-share-shareLinkRemove-more=Cerrar {0} intercambio de enlaces externos +log-event-share-shareToRemove=Desactiva el intercambio colaborativo de este documento +log-event-share-shareToRemove-item=Desactiva el uso compartido de colaboración para {0} +log-event-share-shareToRemove-more=Cerrar {0} intercambio colaborativo +log-event-share-shareEdit=Editó la parte de este documento +log-event-share-shareEdit-item=Cuota editada de {0} +log-event-share-shareEdit-more=Documentos {0} editados para compartir +log-event-rename=Renombrado el documento +log-event-rename-item=Renombrado {0} +log-event-rename-more={0} documentos renombrados +log-event-recycle-toRecycle=Movió el documento a la papelera. +log-event-recycle-toRecycle-current=Movido {0} a la papelera de reciclaje aquí +log-event-recycle-toRecycle-item=Movido {1} a la papelera de reciclaje en {0} +log-event-recycle-toRecycle-more=Se movieron {0} documentos a la Papelera +log-event-recycle-toRecycle-more-at=Se movieron {1} documentos a la papelera de reciclaje el {0} +log-event-recycle-restore=Restaurar el documento desde la papelera de reciclaje +log-event-recycle-restore-item=Restaurar {0} desde la papelera de reciclaje +log-event-recycle-restore-more=Restaurar {0} documentos de la papelera de reciclaje +log-event-remove=Borrado {0} aquí +log-event-remove-current=Borrado {0} aquí +log-event-remove-item=Eliminado {1} en {0} +log-event-remove-more={0} documentos eliminados aquí +log-event-remove-more-at=Documentos eliminados {1} en {0} +log-event-addDesc=Se modificó la descripción del documento. +log-event-addDesc-item=Descripción del documento modificado {0} +log-event-addDesc-more=Descripciones de documentos modificados {0} +log-event-addComment=Comentó este documento +log-event-addComment-item=Comentó en {0} +log-event-addComment-more=Enumerados {1} comentarios en {0} +log-event-fav-fileAdd=Marcado como favorito {0} +log-event-fav-dirAdd=Carpetas marcadas {0} +log-event-down-item=Descargado {1} de {0} +log-event-down-items=Descargado de {0} +log-event-recycle-del-item=Eliminar {0} archivos de la papelera de reciclaje +log-event-recycle-rst-item=Restaurar {0} archivos de la papelera de reciclaje +log-event-del-item={0} archivos eliminados +log.file.move=Mover / copiar +log.file.fav=Operación de favoritos +log.file.shareLink=Compartir enlaces externos +log.file.shareTo=Intercambio colaborativo +log.user.edit=Modificar la información de la cuenta +log.group.edit=Gestión de departamentos +log.member.edit=Gestión de usuarios +log.role.edit=Gestión de roles +log.auth.edit=Gestión de derechos de documentos +meta.user_sourceAlias=Archivos relacionados (archivos adjuntos) +meta.user_fileEncodeType=Confidencialidad de archivo +meta.user_fileEncodeType.A=A-Top secret +meta.user_fileEncodeType.B=B-confidencial +meta.user_fileEncodeType.C=C-secreto +meta.user_sourceNumber=Numero de volumen +meta.user_sourceParticipant=Partícipe +explorer.fileInfo.createTime=Fecha de creación +explorer.fileInfo.modifyTime=Fecha de modificación +explorer.fileInfo.softwareCreate=Software de producción +explorer.fileInfo.software=Software de codificación +explorer.fileInfo.playTime=Tiempo de juego +explorer.fileInfo.imageSize=tamaño de la imagen +explorer.fileInfo.imageDpi=Resolución +explorer.fileInfo.imageBits=Profundidad de bits +explorer.fileInfo.imageDesc=Anotación +explorer.fileInfo.imageAuthor=creador +explorer.fileInfo.imageColor=Espacio de color +explorer.fileInfo.cameraType=Modelo de dispositivo +explorer.fileInfo.cameraApertureFNumber=Número de apertura +explorer.fileInfo.cameraApertureValue=Valor de apertura +explorer.fileInfo.cameraShutterSpeedValue=Velocidad de obturación +explorer.fileInfo.cameraExposureTime=Tiempo de exposición +explorer.fileInfo.cameraFocalLength=longitud focal +explorer.fileInfo.cameraFocusDistance=Distancia de enfoque +explorer.fileInfo.cameraISOSpeedRatings=Sensibilidad ISO +explorer.fileInfo.cameraWhiteBalance=Balance de blancos +explorer.fileInfo.cameraUser=Manual +explorer.fileInfo.cameraAuto=automático +explorer.fileInfo.cameraExposureMode=Modo de exposición +explorer.fileInfo.cameraExposureBiasValue=Compensación de exposición +explorer.fileInfo.imageGps=Lugar de rodaje +explorer.fileInfo.imageCreateTime=Fecha de rodaje +explorer.fileInfo.audioChannel=Canal de audio +explorer.fileInfo.audioChannel1=Mononucleosis infecciosa +explorer.fileInfo.audioChannel2=estéreo +explorer.fileInfo.audioChannels=Multicanal +explorer.fileInfo.audioRate=Frecuencia de muestreo de audio +explorer.fileInfo.audioBits=Profundidad de bits de audio +explorer.fileInfo.audioBitrate=Tasa de bits de audio +explorer.fileInfo.vedioFormat=Codificación de video +explorer.fileInfo.audioTitle=título +explorer.fileInfo.audioAuthor=Autor +explorer.fileInfo.audioAlbum=Álbum +explorer.fileInfo.audioStyle=estilo +explorer.fileInfo.audioYear=Año del álbum +explorer.fileInfo.vedioSize=Tamaño de pantalla +explorer.fileInfo.vedioFrame=Velocidad de fotogramas de vídeo +explorer.fileInfo.vedioBitrate=Bitrate de vídeo +explorer.fileInfo.title=título +explorer.fileInfo.author=Autor +explorer.fileInfo.pageTotal=paginas totales +explorer.fileInfo.pageSize=Tamaño de página +explorer.fileInfo.pagePower=Creador de contenido +explorer.fileInfo.pdfVersion=Versión PDF +explorer.filter.shareCopyLimit=El número de archivos a volcar supera el límite; el número máximo de archivos que puede volcar es: +explorer.filter.shareSizeLimit=El tamaño del archivo compartido supera el límite; el máximo que puede compartir es: +explorer.filter.unzipSizeLimit=El tamaño del archivo descomprimido excede el límite; el máximo que puede descomprimir es: +explorer.filter.zipSizeLimit=El tamaño del archivo comprimido excede el límite; sus documentos comprimibles máximos: +explorer.filter.uploadSizeLimit=El tamaño de carga supera el límite; el máximo que puede cargar es: +explorer.fileEditError=El archivo actual %s está siendo editado, por favor vuelva a intentarlo más tarde +explorer.groupDelError=Lo siento, la carpeta del Departamento no admite la eliminación. +admin.info.typeDelError=Falló la eliminación, con subclasificaciones o datos +admin.info.domainIdentifyError=Sitio web no reconocido +admin.info.articleIdentifyError=Artículo no reconocido +admin.info.domainSupportError=El sitio web no admite la recolección por el momento. +admin.info.fileTooLarge=El documento es demasiado grande +explorer.toolbar.info=Información +source.shareDisabled=Los recursos actuales están prohibidos de compartir +admin.exceeds.limit=Más allá del límite +admin.design.deleted=El Estado habilitado no se puede eliminar +admin.design.url.locked=La Dirección actual está bloqueada y no se puede usar por el momento +explorer.SING_INVALID=Firma anormal +explorer.TEMP_AUTH_INVALID=El Código de autorización temporal no es válido (caducado) +explorer.QR_INVALID=El Código QR ha fallado +explorer.toolbar.toolbox=Caja de herramientas +explorer.toolbox.desc= +logs-detail-mkdir=Se ha creado una nueva carpeta +logs-detail-mkfile=Nuevos archivos +logs-detail-editFile=Edición actualizada +logs-detail-upload=Se sube el archivo +logs-detail-uploadNew=Editado +logs-detail-file.upload=Subido +logs-detail-file-copy=Pegar crea un archivo +logs-detail-folder-copy=Pegar crea una carpeta +logs-detail-paste=Pegar +logs-detail-from=De +logs-detail-to=A +logs-detail-rename=Renombrado +logs-detail-rename-file=El archivo fue renombrado +logs-detail-rename-folder=La carpeta ha sido renombrada +logs-detail-user=Usuarios: +logs-detail-moveFrom-restore=Será +logs-detail-moveTo-restore=Restaurar de la estación de reciclaje +logs-detail-move=Será +logs-detail-moveTo=Mover a +logs-detail-moveFrom-toRecycle=Será +logs-detail-moveTo-toRecycle=Se trasladó a la estación de reciclaje +logs-detail-file-toRecycle=Traslada el documento a la estación de reciclaje +logs-detail-file-restore=Restaurar el archivo de la estación de reciclaje +logs-detail-folder-toRecycle=Traslada la carpeta a la estación de reciclaje +logs-detail-folder-restore=Restaurar la carpeta de la estación de reciclaje +logs-detail-favAdd=Colección +logs-detail-favDel=Colección cancelada +logs-detail-unstar=Nombre: +logs-detail-moveOut=Retirado +logs-detail-remove=Eliminado +logs-detail-file.copy=Pegado +explorer.noPermissionAuthAll={0} ,No hay permisos para esta operación \ No newline at end of file diff --git a/src/main/resources/i18n/messages_fr_FR.properties b/src/main/resources/i18n/messages_fr_FR.properties new file mode 100644 index 0000000..791b0b1 --- /dev/null +++ b/src/main/resources/i18n/messages_fr_FR.properties @@ -0,0 +1,2563 @@ +admin.serverInfo=Informations sur le serveur +admin.today=Aujourd'hui +admin.yesterday=Hier +admin.weekDay=Presque 7 jours +admin.monthDay=Près de 30 jours +admin.ing=En cours +admin.paused=Suspendu +admin.serverDownload=Téléchargement à distance +admin.memberManage=Gestion des utilisateurs +admin.fileManage=Gestion de fichiers +admin.pwdEdit=Changer le mot de passe +admin.fileEdit=Editer le fichier de sauvegarde +admin.list=Vue liste +admin.configError=L'enregistrement de la configuration a échoué, l'administrateur a désactivé cette autorisation! +admin.userManage=Centre personnel +admin.manage=Gestion de fond +admin.pluginManage=Gestion des plug-ins +admin.emailDear=Bonjour %s, +admin.emailCodeText=Vous êtes en train de vérifier votre adresse e-mail. Le code de vérification pour cette demande est le suivant. Pour assurer la sécurité de votre compte, veuillez effectuer la vérification à temps. +admin.emailVerifyInTime=Afin de protéger la sécurité de votre compte, veuillez compléter la vérification à temps. +admin.dear=Le respect +admin.dearUser=Cher utilisateur, +admin.emailResetLink=Vous réinitialisez le mot de passe de connexion pour %s par e-mail, veuillez cliquer sur le lien ci-dessous pour le réinitialiser. Si le lien ne saute pas, copiez-le dans la barre d'adresse de votre navigateur pour y accéder: +admin.emailExpireTime=Le lien expire après 20 minutes. +admin.jobName=Titre du poste +admin.jobDesc=Description du poste +admin.jobNameInput=S'il vous plaît entrer un nom de travail +admin.jobEdit=Rédacteur en chef +admin.menu.home=Accueil +admin.menu.dashboard=Vue d'ensemble +admin.menu.dashboardTitle=Aperçu des statistiques +admin.menu.notice=Gestion des notifications +admin.menu.groupMember=Direction des départements et des membres +admin.menu.member=Départements et utilisateurs +admin.menu.role=Gestion des rôles +admin.menu.job=Gestion des travaux +admin.menu.auth=Gestion des droits de document +admin.menu.storage=Stockage / fichier +admin.menu.storageDriver=Gestion du stockage +admin.menu.plugin=Centre de plugins +admin.menu.tools=Contrôle de sécurité +admin.menu.server=Gestion du serveur +admin.menu.backup=Gestion des sauvegardes +admin.menu.share=Gestion du partage +admin.menu.loginLog=Journal de connexion +admin.menu.log=Journal d'opération +admin.menu.task=Tâches planifiées +admin.autoTask.restart=Redémarrez les tâches planifiées +admin.autoTask.restartEnd=La tâche planifiée a redémarré +admin.index.userSpace=Espace utilisateur +admin.index.groupSpace=Espace département +admin.index.folderCount=Nombre de dossiers: +admin.index.fileCount=Nombre de fichiers: +admin.index.loginToday=Connectez-vous aujourd'hui +admin.index.useTotal=Utilisation totale: +admin.index.userLogin=Login utilisateur +admin.index.spaceUsed=Prendre de la place +admin.index.useSpace=Utiliser l'espace +admin.index.usedSpace=Espace utilisé +admin.index.freeSpace=espace restant +admin.index.sizeLimit=Taille limitée +admin.index.vipCount=Utilisateurs enregistrés +admin.index.loginCurrent=Actuellement en ligne +admin.index.fileDel=Suppression de fichiers +admin.index.fileEdit=Édition de fichiers +admin.index.fileUpload=Téléchargement de fichiers +admin.index.fileDown=Télécharger le document +admin.index.spaceUse=Utilisation pratique +admin.index.spaceSave=Économiser de l'espace +admin.index.spaceUser=Utilisation par l'utilisateur +admin.index.spaceGroup=Utilisation du département +admin.index.lastLogin=Dernière heure de connexion +admin.index.totalUsers=Nombre d'utilisateurs +admin.index.loginUsers=Login utilisateur +admin.index.spaceActUsed=Occupation réelle +admin.index.source=Source de connexion +admin.index.address=Adresse de connexion +admin.index.userInfo=informations utilisateur +admin.index.userValid=Compte valide +admin.index.userInvalid=Compte invalide +admin.index.fileInfo=Informations sur le fichier +admin.index.fileCnt=Nombre de fichiers +admin.index.fileAdd=Ajouté aujourd'hui +admin.index.accInfo=Accéder aux informations +admin.index.accCnt=Demandes +admin.index.accUser=Accéder à l'utilisateur +admin.index.serverInfo=Message système +admin.index.serverDisk=Disque système +admin.index.serverStore=Stockage réseau +admin.index.serverName=nom du serveur +admin.index.normal=Ordinaire +admin.index.scoreDesc=Les facteurs suivants affecteront le score du système, qui peut être optimisé pour garantir le bon fonctionnement du système:
    1. L'espace restant sur le disque système et le stockage sur disque réseau;
    2. Méthode de mise en cache des données (redis est recommandé);
    Version de la plateforme 3.php (php7 + 64 bits recommandé). +admin.index.fileRatio=Ratio d'utilisation des fichiers +admin.setting.system=Paramètres système +admin.setting.account=Paramètres du compte +admin.setting.theme=Paramètres du thème +admin.setting.wall=Paramètres de fond d'écran +admin.setting.stats=Statistiques d'utilisation +admin.setting.safeMgt=Gestion de la sécurité +admin.setting.base=Paramètres de base +admin.setting.others=Autres réglages +admin.setting.sync=Paramètres de synchronisation +admin.setting.plugin=Paramètres du plug-in +admin.setting.auth=Paramétrage des autorisations +admin.setting.safe=Paramètres de sécurité +admin.setting.loginLog=Journal de connexion +admin.setting.loginDevice=Dispositif de connexion +admin.setting.deviceType=Type d'équipement +admin.setting.lastLoginTime=Heure de la dernière connexion +admin.setting.email=Paramètres de messagerie +admin.setting.user=Inscription et connexion +admin.setting.pwdOld=Mot de passe original +admin.setting.pwdNew=Modifier pour +admin.setting.wallDiy=Papier peint personnalisé: +admin.setting.fav=Gestion des favoris +admin.setting.help=Utilisez l'aide +admin.setting.about=A propos des travaux +admin.setting.homePage=kodcloud maison +admin.setting.subMenu=Sous menu +admin.setting.menuName=Nom du menu +admin.setting.menuUrl=Adresse URL +admin.setting.menuUrlDesc=adresse URL ou code js +admin.setting.safeAccount=Sécurité du compte et de la connexion +admin.setting.safeData=Sécurité des données / sécurité de transmission +admin.setting.passwordErrorLock=Verrouillage d'erreur de saisie de mot de passe +admin.setting.passwordErrorLockDesc=Si le mot de passe est incorrect pendant 5 fois consécutives, le compte sera verrouillé pendant 1 minute et ne sera pas autorisé à se connecter. Après l'ouverture, il peut empêcher efficacement le mot de passe de se fissurer par force brute ; +admin.setting.passwordRule=Réglage de la force du mot de passe utilisateur +admin.setting.passwordRuleDesc=Une fois la force du mot de passe spécifiée, le mot de passe faible peut être efficacement éliminé +admin.setting.passwordRuleNone=Illimité +admin.setting.passwordRuleStrong=Intensité moyenne +admin.setting.passwordRuleStrongMore=Haute résistance +admin.setting.passwordRuleNoneDesc=Mot de passe illimité +admin.setting.passwordRuleStrongDesc=La longueur est supérieure à 6, doit contenir à la fois de l'anglais et des chiffres; +admin.setting.passwordRuleStrongMoreDesc=La longueur est supérieure à 6, doit contenir des chiffres, anglais majuscule, anglais minuscule; +admin.setting.passwordRuleTips=Votre mot de passe actuel n'est pas assez fort, il est recommandé de changer le mot de passe immédiatement! +admin.loginCheck.menu=Contrôle de connexion +admin.loginCheck.ipCheck=Restrictions IP +admin.loginCheck.ipCheckNone=non limité +admin.loginCheck.ipCheckAllow=Liste blanche IP +admin.loginCheck.ipCheckDisable=Liste noire IP +admin.loginCheck.loginIpAllowDesc=Après ouverture, seuls les utilisateurs avec l'IP spécifiée peuvent se connecter, veuillez faire attention +admin.loginCheck.ipAllow=IP autorisée +admin.loginCheck.ipAllowDesc=Remplissez les règles comme suit (chaque ligne, l'adresse IP locale du serveur est autorisée par défaut et l'administrateur système autorise l'adresse IP du réseau local) +admin.loginCheck.ipDisable=Règles IP de la liste noire +admin.loginCheck.ipDisableDesc= +admin.loginCheck.ipDescTitle=Remplissez les règles comme suit (une ligne par entrée) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=priorité +admin.loginCheck.name=Nom de la règle +admin.loginCheck.user=Utilisateur désigné +admin.loginCheck.device=Équipement désigné +admin.loginCheck.deviceWeb=la toile +admin.loginCheck.devicePc=Côté PC +admin.loginCheck.deviceAndroid=Android +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc=
    Instructions de contrôle de restriction de connexion utilisateur (restrictions d'adresse IP et de périphérique) :
  • Détecter dans l'ordre selon l'ordre de priorité de la règle ; l'utilisateur spécifié par la règle inclut l'utilisateur actuellement connecté ; la règle est alors déterminée comme résultat
  • Il est recommandé de mettre les groupes d'utilisateurs et les utilisateurs départementaux au verso, et de spécifier les paramètres utilisateur au recto ; (glisser-déposer pour ajuster l'ordre)
  • +admin.setting.checkCode=Le code de vérification de connexion est activé +admin.setting.checkCodeDesc=Après la connexion, vous devez entrer le code de vérification. +admin.setting.csrfProtect=Activer la protection csrf +admin.setting.csrfProtectDesc=Peut prévenir efficacement les attaques de type CRF lorsqu'il est activé +admin.setting.setRootPath=Accès racine +admin.setting.setRootPathDesc=Seul l'administrateur système peut accéder à tous les répertoires et les utilisateurs appartenant à d'autres groupes d'autorisations ne peuvent voir que leurs propres répertoires d'utilisateurs.
    Si vous voulez activer ou désactiver l’accès administrateur à d’autres répertoires, vous pouvez modifier le paramètre open_basedir PHP intersite, comment définir +admin.setting.encode=Cryptage du stockage de fichiers +admin.setting.encodeAll=Crypter tout +admin.setting.encodeName=Conserver l'extension +admin.setting.encodeNone=Pas de cryptage +admin.setting.encodeAllDesc=Cryptage complet: [recommandation par défaut]; même si vous avez des autorisations de serveur, vous ne pouvez pas connaître le vrai contenu du fichier; il peut efficacement protéger contre les ransomwares et autres dommages; +admin.setting.encodeNameDesc=Conserver l'extension: cryptage du nom de fichier, conserver l'extension +admin.setting.encodeNullDesc=Pas de cryptage: le nom du fichier nest pas crypté et le nom du fichier dorigine est conservé (pour assurer la sécurité, le dossier de téléchargement est nommé structure cryptée); +admin.setting.encodeTips1=Seuls les fichiers après la modification du paramètre sont affectés, les fichiers qui existaient auparavant ne sont pas affectés; +admin.setting.encodeTips2=Pour éviter les erreurs, veuillez ne pas supprimer ou renommer les fichiers dans les données / fichiers; +admin.setting.encodeTips3=Pour prendre en charge la simultanéité à grande échelle, la deuxième transmission, le clustering, la distribution, l'expansion automatique et d'autres fonctions; la hiérarchie des dossiers est enregistrée dans la base de données; la structure des dossiers peut être importée et restaurée par copier-coller +admin.setting.thirdLogin=Login tiers +admin.setting.thirdLoginDesc=Autoriser l'enregistrement, la liaison et la connexion via des comptes tiers +admin.setting.registOpen=Inscription utilisateur ouverte +admin.setting.registOpenDesc=Pour éviter les conflits de données, la synchronisation des données tierces et l'enregistrement des utilisateurs ne peuvent pas être activés simultanément. +admin.setting.registCheck=Examen d'inscription ouvert +admin.setting.registCheckDesc=Après ouverture, l'administrateur doit vérifier et l'activer dans [Utilisateurs et départements] pour que les utilisateurs enregistrés puissent utiliser +admin.setting.clearUserRecycle=Vider toutes les corbeilles de l'utilisateur +admin.setting.clearCache=Effacer le cache +admin.setting.icp=Copyright ou numéro d'enregistrement +admin.setting.icpDesc=Si vous devez générer un lien, vous pouvez ajouter vous-même un tag +admin.setting.globalCss=Css global personnalisé +admin.setting.globalCssDesc=Toutes les pages insèrent un css personnalisé +admin.setting.globalHtml=Code statistique HTML +admin.setting.globalHtmlDesc=Toutes les pages vont insérer ce code html, et le code de statistiques tiers peut être placé +admin.setting.dateFormat=format de date +admin.setting.dateFormatDesc=Affichage du format d'heure année-mois-jour, heure de modification du fichier, etc. +admin.setting.menu=Gestion du menu +admin.setting.systemName=Nom du produit de l'entreprise +admin.setting.systemNameDesc=Pour le titre du logo du produit +admin.setting.systemDesc=Sous-titre du produit +admin.setting.pathHidden=Exclusion de répertoire +admin.setting.pathHiddenDesc=Répertoires et fichiers non affichés par défaut, séparés par des virgules +admin.setting.defaultFolder=Les nouveaux utilisateurs créent des répertoires par défaut +admin.setting.defaultFolderDesc=Séparé par des virgules +admin.setting.defaultApp=Les nouveaux utilisateurs créent des applications par défaut +admin.setting.defaultAppDesc=Applications du centre d'applications, multiples séparées par des virgules +admin.setting.autoLogin=Connexion automatique +admin.setting.autoLoginDesc=L'utilisateur par défaut est l'utilisateur guest/guest , assurez-vous qu'il existe après l'ouverture. +admin.setting.firstIn=Entrer par défaut après la connexion +admin.setting.registReviewOpen=Audit d'enregistrement ouvert: +admin.setting.registRoleEmpty=Le rôle d'autorisation ne peut pas être vide +admin.setting.registNotSync=Pour éviter les conflits de données, la synchronisation des données tierces et l'enregistrement des utilisateurs ne peuvent pas être activés simultanément. +admin.setting.registNeedRewiew=Une fois ouvert, l'administrateur doit l'examiner et l'activer dans les utilisateurs et les services pour que les utilisateurs enregistrés puissent l'utiliser. +admin.setting.roleRight=Autorisations de rôle +admin.setting.emailHost=Serveur de boîtes aux lettres +admin.setting.emailHostInput=Veuillez entrer l'adresse du serveur de messagerie +admin.setting.emailHostTips=Veuillez renseigner l'adresse du serveur de messagerie +admin.setting.emailHostDesc=Serveur de boîte aux lettres, tel que : smtp.163.com, le port peut être personnalisé (la valeur par défaut est 465) +admin.setting.emailSend=Boîte d'envoi +admin.setting.emailSendInput=S'il vous plaît entrer l'adresse email +admin.setting.emailSendTips=S'il vous plaît remplir l'adresse e-mail d'envoi +admin.setting.emailSendDesc=Adresse e-mail du système, le service POP3 / SMTP doit être activé +admin.setting.emailPwd=Mot de passe d'autorisation +admin.setting.emailPwdTips=Veuillez saisir le mot de passe d'autorisation par e-mail +admin.setting.secureType=Chiffrement +admin.setting.emailSendTest=Détection de l'envoi +admin.setting.ensureEmailOk=Assurez-vous que le courrier peut être envoyé normalement +admin.setting.emailTo=Boîte de réception +admin.setting.emailGoToTips=S'il vous plaît aller à la boîte aux lettres +admin.setting.emailCheckTips=Voir +admin.setting.emailInputError=Paramètres de messagerie incorrects +admin.setting.emailPwdError=Le mot de passe de configuration de messagerie est incorrect +admin.setting.emailDesc=Configurer un serveur de messagerie pour l'enregistrement des utilisateurs et l'envoi d'e-mails de récupération du mot de passe +admin.setting.sendEmail=Envoyer un mail +admin.setting.sendEmailDesc=Système par défaut: appel à envoyer un serveur de messagerie en nuage à envoyer; personnalisé: configurer le serveur de messagerie +admin.setting.systemBackup=Système de sauvegarde +admin.setting.enableFunction=Fonctions et commutateurs +admin.setting.treeOpen=Commutateur de fonction de répertoire d'arborescence +admin.setting.treeOpenDesc=Gestion des fichiers, fonction correspondante du répertoire d'arborescence globalement activée et désactivée +admin.setting.groupListChild=Liste des sous-secteurs +admin.setting.groupListChildDesc=Que le dossier du département affiche les sous-départements, les autorisations sont héritées vers le haut +admin.setting.groupRootListChild=Le disque Web d'entreprise répertorie les sous-secteurs +admin.setting.groupRootListChildDesc=Indique si le dossier du disque du réseau d'entreprise affiche les sous-services et les autorisations sont héritées vers le haut +admin.setting.shareToMeAllowTree=Collaborer avec me-show par structure organisationnelle +admin.setting.shareToMeAllowTreeTips=Après ouverture, le support de contenu pour la collaboration avec moi est classé en fonction de la structure organisationnelle du département, ce qui convient aux situations où la structure organisationnelle est plus complexe +admin.setting.groupTagAllow=Label public départemental +admin.setting.groupTagAllowTips=Après l'activation, tous les membres du service seront visibles après avoir défini l'étiquette publique pour les fichiers du service. L'administrateur du service peut conserver le contenu de l'étiquette. +admin.setting.shareToMeList=Affichage en mosaïque +admin.setting.shareToMeGroup=Afficher par structure organisationnelle +admin.setting.shareToMeUser=Afficher par partageur +admin.setting.sysSrvState=État du serveur +admin.setting.sysSrvInfo=informations sur le serveur +admin.setting.sysPhpInfo=Informations PHP +admin.setting.database=base de données +admin.setting.cache=Cache +admin.setting.sysMyInfo=mon information +admin.setting.srvStateCpu=l'utilisation du processeur +admin.setting.srvStateMem=Utilisation de la mémoire +admin.setting.srvStateSrv=Espace de stockage du système serveur +admin.setting.srvStateDef=L'espace de stockage par défaut du disque réseau +admin.setting.srvInfoName=nom du serveur +admin.setting.srvInfoIp=IP du serveur +admin.setting.srvInfoTime=heure du serveur +admin.setting.srvInfoUpTime=Temps de fonctionnement continu +admin.setting.srvInfoWeb=Logiciel serveur +admin.setting.srvInfoPhpV=Version PHP +admin.setting.srvInfoSys=Système serveur +admin.setting.srvInfoPath=Chemin du site +admin.setting.srvPhpDtl=Détails PHP +admin.setting.memLimit=Limite de mémoire +admin.setting.postLimit=Limite de soumission POST +admin.setting.uploadLimit=Importer des restrictions de fichiers +admin.setting.execTime=Temps d'exécution maximum +admin.setting.inputTime=Temps de demande maximum +admin.setting.disFunction=Désactiver la fonction +admin.setting.phpExtSugst=Extensions PHP recommandées +admin.setting.phpExtLoad=Extension chargée +admin.setting.myClientIp=Mon IP +admin.setting.myClientUa=Mon navigateur UA +admin.setting.myClientLng=La langue de mon navigateur +admin.setting.disFuncDesc=Fonctions requises par le système, il est recommandé d'activer +admin.setting.srvMemFree=Mémoire restante +admin.setting.srvMemUse=Utiliser la mémoire +admin.setting.srvCpuUse=Actuellement occupé +admin.setting.srvCpuFree=Inutilisé +admin.setting.noLimit=Illimité +admin.setting.disFunNo=non +admin.setting.systemCache=Cache système +admin.setting.systemDb=Base de données système +admin.setting.sysCacheTab=Commutateur de cache +admin.setting.sysDbTab=Commutateur de base de données +admin.setting.sysRecTab=Récupération de base de données +admin.setting.cacheDesc=Description du cache +admin.setting.fileCacheDesc=Cache de fichiers: écrivez les données directement dans le fichier de cache, adaptées aux tests ou à une utilisation à petite échelle. +admin.setting.redisDesc=Redis: base de données non relationnelle à valeur-clé hautes performances, adaptée aux situations de lecture et d'écriture simultanées élevées. Recommandé pour une utilisation. +admin.setting.memcachedDesc=Memcached: système de cache d'objets de mémoire distribuée hautes performances, adapté aux lectures simultanées élevées. +admin.setting.saveAfterTest=Une fois le test réussi, il peut être enregistré +admin.setting.checkPassed=Passé +admin.setting.ifSaveCache=Après la commutation, toutes les données mises en cache seront effacées!
    Êtes-vous sûr de vouloir exécuter? +admin.setting.ifSaveDb=Le commutateur de base de données importera les données actuelles du système dans la nouvelle base de données et les définira comme valeur par défaut. Êtes-vous sûr de vouloir l'exécuter ? +admin.setting.dbCurrent=Configuration actuelle +admin.setting.dbType=Type de base de données +admin.setting.dbName=Base de données de noms +admin.setting.dbInfo=Informations sur la base de données +admin.setting.dbSwitch=Allumer +admin.setting.dbSwitchDesc=Après ouverture, vous pouvez changer le type de base de données selon vos besoins, veuillez agir avec prudence. +admin.setting.dbTable=Fiche technique +admin.setting.dbCnt=total +admin.setting.dbNeedNew=La base de données existe déjà, veuillez le préciser à nouveau +admin.setting.dbInsertError=Échec de l'écriture des données de la table +admin.setting.dbNeedOthers=Veuillez sélectionner un autre type de base de données +admin.setting.dbNeedChange=Veuillez modifier les paramètres de configuration +admin.setting.dbCreateError=La création du fichier de base de données a échoué, veuillez vérifier les autorisations de lecture et d'écriture du répertoire +admin.setting.dbTaskProcess=Progression de l'exécution +admin.setting.dbTasking=Être exécuté +admin.setting.dbTaskDesc=Ne fermez pas la fenêtre et n'effectuez pas d'autres opérations dans le système pour éviter de générer des données de divergence. +admin.setting.recTaskDesc=Ne fermez pas la fenêtre. Une fois la requête interrompue, l'arrière-plan continuera à s'exécuter jusqu'à la fin de la tâche. +admin.setting.dbCreate=Nouvelle base de données +admin.setting.dbSelect=Lire la base de données +admin.setting.dbInsert=Écrire dans la base de données +admin.setting.dbSetSave=Enregistrer les informations de configuration +admin.setting.recDesc=Mode d'emploi +admin.setting.recDescInfo11=Cette opération réinitialisera les données du système, le non fonctionnement et la maintenance ou le personnel technique associé ne doit pas fonctionner ! +admin.setting.recDescInfo21=En écrivant la base de données de sauvegarde dans la nouvelle base de données et en la définissant comme valeur par défaut du système, la récupération des données est réalisée. +admin.setting.recDescInfo22=Les nouveaux paramètres de configuration de la base de données seront ajoutés au fichier de configuration du système config/setting_user.php. Si le système est anormal après l'exécution de la récupération, la partie ajoutée du fichier peut être supprimée sans affecter les données système précédentes. +admin.setting.recDescInfo23=Cette fonction prend uniquement en charge le traitement des données de sauvegarde générées par la gestion des sauvegardes du système, et la base de données sauvegardée par vous-même doit être traitée d'une autre manière. +admin.setting.recDescInfo31=Remarque : lorsque le type de base de données est MySQL, une nouvelle bibliothèque (nom de la bibliothèque d'origine_date actuelle_rebuild) sera créée en fonction des informations de configuration actuelles. Les utilisateurs non root peuvent ne pas disposer d'autorisations suffisantes, vous devez donc d'abord définir des autorisations pour l'utilisateur. +admin.setting.recDescInfo32=Par exemple, les informations de configuration de la base de données actuelle sont : utilisateur : kod ; mot de passe : kod123. Utilisez le compte root pour vous connecter à la base de données et exécutez l'instruction SQL correspondante pour définir les autorisations (les autorisations peuvent être révoquées une fois le test réussi et la récupération réussie). +admin.setting.recDescInfo33=Paramétrage des autorisations : +admin.setting.recDescInfo34=Révoquer les autorisations : +admin.setting.recOpen=Activer la récupération +admin.setting.recOpenDesc=Une fois activé, vous pouvez sélectionner la base de données sauvegardée à restaurer selon vos besoins. Veuillez opérer avec prudence. +admin.setting.recTypeDesc=Dépend du type de système actuellement utilisé +admin.setting.recPath=Répertoire de sauvegarde de la base de données +admin.setting.recPathErr=Répertoire de sauvegarde de la base de données invalide +admin.setting.ifSaveRec=La restauration de la base de données importera les données de sauvegarde dans la nouvelle base de données et les définira comme valeur par défaut.
    Êtes-vous sûr de vouloir l'exécuter ? +admin.setting.recDiyPathErr=Lorsque vous utilisez l'auto-sauvegarde pour restaurer, veuillez sélectionner le fichier de base de données à sauvegarder +admin.setting.recDiyFileNull=Le fichier de la base de données est vide +admin.setting.recDiyPhpErr=Pour que SQLite soit sauvegardé par vous-même, veuillez sélectionner le fichier de base de données au format php +admin.setting.recDiySqlErr=Pour que MySQL soit sauvegardé par vous-même, veuillez sélectionner le fichier de base de données au format sql +admin.setting.recSysPathErr=Lorsque vous utilisez la gestion des sauvegardes pour restaurer, veuillez sélectionner le répertoire de la base de données de sauvegarde +admin.setting.recSysTbErr=Le répertoire de sauvegarde de la base de données n'est pas valide ou le fichier de structure de la base de données est manquant +admin.setting.recDbFileErr=Le fichier de bibliothèque sélectionné ne correspond pas au système ou une table de données valide est manquante +admin.setting.dbFileDown=Lire le fichier de bibliothèque +admin.setting.dbFileDownErr=Échec de la lecture du fichier de bibliothèque +admin.notice.waiting=En attente de poussée +admin.notice.done=Poussé +admin.notice.time=Temps de poussée +admin.notice.target=Objet push +admin.notice.level=Niveau rapide +admin.notice.level0=Indice faible +admin.notice.level1=Invite forte +admin.notice.levelDesc=Rappel faible: un point rouge s'affiche dans la barre de notification dans le coin inférieur gauche; rappel fort: une notification apparaîtra directement après la connexion de l'utilisateur. +admin.notice.targetAuth=Choisissez de pousser vers tout le monde ou de pousser vers des utilisateurs, groupes d'utilisateurs et groupes d'autorisations spécifiés +admin.notice.title=Titre du message +admin.notice.content=Contenu du message +admin.notice.timeType=Méthode push +admin.notice.timeNow=Poussez immédiatement +admin.notice.timePlan=Push programmé +admin.notice.listTitle=Notification de nouvelles de la station +admin.notice.clearAll=Vider tout +admin.notice.noMsg=Pas de nouvelles +admin.notice.ifClearAll=Voulez-vous vraiment effacer tous les messages? +admin.group.role=Identité de rôle +admin.group.name=Nom du département +admin.group.parent=Département supérieur +admin.group.authShow=La portée de la structure organisationnelle visible par les membres du département +admin.group.authShowAll=Tous les départements +admin.group.authShowHide=Seul ce département et sous-département +admin.group.authShowSelect=Département désigné +admin.group.authShowAllTips=Lorsque les membres de ce service collaborent pour partager, ils peuvent sélectionner tous les autres services (et utilisateurs) +admin.group.authShowHideTips=Lorsque les membres de ce département collaborent et partagent, seuls le département et le sous-département actuels (et les utilisateurs) sont pris en charge +admin.group.authShowSelectTips=Lorsque les membres du département collaborent et partagent, ils peuvent sélectionner le département et le sous-département (et l'utilisateur) désignés, y compris le département et le sous-département actuels +admin.group.addSub=Ajouter un sous-secteur +admin.group.remove=Supprimer le département +admin.group.switch=Département des migrations +admin.group.swtichDesc=Migrez les utilisateurs et les fichiers du service sélectionné (et de ses sous-services) vers le service cible. +admin.group.switchSameError=Le département cible ne peut pas être le même que le département sélectionné +admin.group.switching=Migration, veuillez patienter... +admin.group.groupSwitching=Le service sélectionné est en cours de migration +admin.group.parentNullError=Le département supérieur ne peut pas être vide +admin.group.selected=Département sélectionné +admin.group.setSizeBatch=Définir la taille de l'espace par lots +admin.group.multiSelect=Plusieurs départements peuvent être sélectionnés pour le réglage des lots +admin.group.ifDisAll=Tous les sous-départements seront désactivés. Voulez-vous vraiment l'exécuter ? +admin.member.manage=Utilisateurs et départements +admin.member.add=Nouvel utilisateur +admin.member.role=Rôle d'autorité +admin.member.group=Département +admin.member.groupAdd=Ajouter un département +admin.member.groupEdit=Département éditorial +admin.member.remove=Supprimer l'utilisateur +admin.member.import=Ajouter en vrac +admin.member.enable=Activer +admin.member.batchSet=Opérations en vrac +admin.member.groupRemove=Retirer du service +admin.member.groupInsert=Ajouter au département +admin.member.groupSwitch=Migrer vers le département +admin.member.groupTarget=Département cible +admin.member.groupReset=Réinitialiser le département +admin.member.groupSwtichDesc=Migrer les utilisateurs sélectionnés du service actuel vers le service cible +admin.member.roleSet=Paramètres de rôle d'autorisation +admin.member.sizeSet=Réglage de la taille de l'espace +admin.member.name=Compte de connexion +admin.member.nickName=Pseudo de l'utilisateur +admin.member.userInfo=Informations utilisateur +admin.member.userImport=Importer des utilisateurs en masse +admin.member.uploadFirst=Veuillez d'abord télécharger le fichier +admin.member.downTpl=Téléchargez le modèle +admin.member.downTplDesc=, Veuillez remplir le format du modèle et télécharger. +admin.member.uploadInvalid=Il n'y a pas de données valides dans le fichier téléchargé, veuillez vérifier et télécharger à nouveau +admin.member.uploadDataInvalid=Les données de téléchargement ne sont pas valides ou ont expiré, veuillez télécharger à nouveau +admin.member.importSuccess=Importation terminée +admin.member.importFail=L'importation a échoué +admin.member.importFailDesc=Réussite : {0} ; Échec : {1} +admin.member.importName=Compte de connexion (obligatoire, unique) +admin.member.importNickName=Surnom (unique) +admin.member.importPwd=Mot de passe requis) +admin.member.importSex=Sexe (Homme-1, Femme-0) +admin.member.importPhone=Numéro de portable (unique) +admin.member.importEmail=E-mail (seulement) +admin.member.groupRemoveTips=Les utilisateurs de ce groupe d'utilisateurs ne peuvent pas se connecter après la suppression
    (Vous devez réinitialiser le groupe d'utilisateurs), êtes-vous sûr de vouloir continuer? +admin.member.memberRemoveTips=Après la suppression, le répertoire utilisateur sera déplacé vers la corbeille du système,
    Es-tu sur de vouloir continuer? +admin.member.selectUserTips=Veuillez sélectionner le compte à exploiter +admin.member.ifRemoveGroup=Êtes-vous sûr de vouloir supprimer les utilisateurs sélectionnés de ce groupe? +admin.member.importDesc=Un utilisateur par ligne,
    Ignorer automatiquement s'il existe déjà +admin.member.roleAdminTips=Remarque: l'administrateur système n'est pas contrôlé par les autorisations. +admin.member.space=Définir la taille de l'espace utilisateur +admin.member.spaceTips=0 n'est pas limité +admin.member.spaceTipsDefault=(GB) 0 n'est pas limité +admin.member.spaceTipsFull=Non restreint +admin.member.spaceSize=Taille de l'espace +admin.member.spaceSizeUse=Utilisation de l'espace +admin.member.memberAdd=Ajouter un utilisateur +admin.member.allAdd=Ajouter un utilisateur ou un département +admin.member.nullNotUpdate=Laisser en blanc +admin.member.search=Rechercher des utilisateurs (compte / pseudo / email / téléphone) +admin.member.searchUser=Rechercher des utilisateurs (support pinyin et correspondance floue) +admin.member.searchGroup=Département de recherche (support pinyin et correspondance floue) +admin.member.searchAll=Rechercher des utilisateurs ou des départements (support pinyin et correspondance floue) +admin.member.editNoAuth=Désolé, vous ne disposez pas de cette autorisation,
    Seuls les administrateurs système peuvent ajouter et modifier des administrateurs système +admin.member.disabledUsers=Compte désactivé +admin.member.disabledTips=Basculer les départements à décocher +admin.member.userGroup=Département utilisateur +admin.member.userRole=Rôle d'utilisateur +admin.member.userSelected=Utilisateurs sélectionnés +admin.member.authCopy=Copier les autorisations du service +admin.member.authPaste=Coller l'autorisation du département +admin.member.ifAuthPaste=Êtes-vous sûr de vouloir attribuer les autorisations de service copiées à l'utilisateur actuel ? +ERROR_USER_NOT_EXISTS=L'utilisateur n'existe pas +ERROR_USER_PASSWORD_ERROR=Mot de passe incorrect +ERROR_USER_EXIST_NAME=Le nom d'utilisateur existe déjà +ERROR_USER_EXIST_PHONE=Le numéro de téléphone existe déjà +ERROR_USER_EXIST_EMAIL=La boîte aux lettres existe déjà +ERROR_USER_EXIST_NICKNAME=Pseudo déjà existant +ERROR_USER_LOGIN_LOCK=Désolé, il y a trop de tentatives de mot de passe et le compte actuel est verrouillé. Veuillez réessayer dans 1 minute! +ERROR_IP_NOT_ALLOW=Votre adresse IP ou périphérique d'accès actuel n'est pas autorisé à se connecter, veuillez contacter l'administrateur ! +user.passwordCheckError=Le format du mot de passe ne répond pas aux règles de résistance du mot de passe! +admin.role.administrator=Administrateur du système +admin.role.group=Administrateur de département +admin.role.default=utilisateur général +admin.role.ignoreExt=Restrictions d'extension +admin.role.ignoreExtDesc=Les types de fichiers qui ne sont pas autorisés à télécharger, il n'y a aucune restriction sur vide +admin.role.ignoreFileSize=Taille limite de téléchargement de fichier +admin.role.ignoreFileSizeDesc=Téléchargement de fichier unique maximum, 0 est illimité +admin.role.ignoreExtTips=Désolé, les paramètres système actuels ne prennent pas en charge ce type de téléchargement de fichiers; veuillez contacter l'administrateur pour plus de détails! +admin.role.ignoreFileSizeTips=Désolé, lorsque le fichier dépasse la taille limite; veuillez contacter l'administrateur pour plus de détails! +admin.role.desc=Description du rôle +admin.role.adminDesc=Super administrateur, dispose des droits de gestion du serveur ; tous les paramètres de fichiers et de dossiers ne sont pas valides pour cet utilisateur ! +admin.role.read=Lire +admin.role.readList=Liste de fichiers +admin.role.readInfo=Vue d'attribut de fichier (dossier), recherche de dossier +admin.role.readCopy=Copie du fichier +admin.role.readPreview=Aperçu du fichier (images, documents, audio et vidéo, etc.) +admin.role.readDownload=Téléchargement de fichier (dossier) +admin.role.write=Écrire +admin.role.writeAdd=Créer des fichiers (dossiers), compresser et décompresser des fichiers +admin.role.writeChange=Renommer, ajuster la structure du répertoire +admin.role.writeUpload=Téléchargement de fichier (dossier), téléchargement à distance +admin.role.writeRemove=Fichier (dossier) supprimer, couper +admin.role.adminSetDesc=L'administrateur système a toutes les autorisations, pas besoin de définir! +admin.role.displayDesc=À afficher lors de la définition des rôles d'utilisateur +admin.role.defaultRoleDesc=Conseil: Le système possède des rôles intégrés par défaut et ne prend pas en charge la modification des autorisations. Vous pouvez créer de nouveaux rôles +admin.role.actionSetTitle=Documentation et configuration +admin.role.userSetTitle=Données de configuration de l'utilisateur +admin.role.adminSetTitle=Fonctions de fond +admin.role.fileAdd=Nouveau fichier (dossier) +admin.role.fileRemove=Suppression de document +admin.role.fileMove=Déplacer (copier / couper / coller / glisser) +admin.role.userConfig=Modification de la configuration (définir l'avatar / changer le mot de passe, etc.) +admin.role.userEdit=Modifier l'utilisateur (ajouter / modifier / supprimer) +admin.role.userFav=Opération Favoris +admin.role.itemEdit=Ajouter / modifier / supprimer +admin.role.groupEdit=Modifier le département (ajouter / modifier / supprimer) +admin.role.delErrTips=Le caractère est utilisé et ne peut pas être supprimé! +admin.authFrom.setUser=Spécifiez vos propres autorisations +admin.authFrom.setGroup=Spécifier l'autorité du département +admin.authFrom.setAll=Autres autorisations utilisateur +admin.authFrom.groupAt=Autorité du département +admin.authFrom.groupParent=Autorité départementale supérieure +admin.authFrom.pathOnly=Seul accès, le niveau inférieur a le contenu et l'autorisation +admin.authFrom.groupRoot=répertoire racine du département +admin.auth.owner=Propriétaire +admin.auth.editor=Éditeur +admin.auth.editUploader=Edit / uploader +admin.auth.viewer=Spectateur +admin.auth.previewer=Previewer +admin.auth.uploader=Uploader +admin.auth.invisible=Invisible +admin.auth.user=Données utilisateur +admin.auth.pathDelete=Suppression de fichier +admin.auth.pathInfo=Attributs de fichier +admin.auth.pathMove=Déplacer (copier / couper / coller / glisser) +admin.auth.canUpload=Télécharger le téléchargement +admin.auth.config=Données de configuration +admin.auth.fav=Opération Favoris (ajouter / modifier / supprimer) +admin.auth.extWarning=Le téléchargement de tels fichiers n'est pas autorisé,
    Renommer (renommé à l'extension spécifiée),
    Editer sauvegarder, télécharger à distance, décompresser +admin.auth.error=Erreur de rôle d'autorisation (pas de paramètres d'autorisation) +admin.auth.errorAdmin=Autorité insuffisante +admin.auth.targetError=Le type d'objet d'autorisation est incorrect, il doit s'agir d'un utilisateur ou d'un service. +admin.auth.errorAuthToGroup=Département non root, ne prend pas en charge la délégation aux départements +admin.auth.errorAuthToUsers=Secteur non racine, ne prend pas en charge la délégation à des membres extérieurs au secteur +admin.auth.displayDesc=Affichage ou non lors de la définition des autorisations utilisateur du service +admin.auth.defaultAuthDesc=Conseil: Le système possède un groupe d'autorisations intégré par défaut et ne prend pas en charge la modification des autorisations. Vous pouvez créer de nouveaux groupes de permissions +admin.auth.show=Liste de fichiers +admin.auth.showAction=Vue de la liste de fichiers +admin.auth.view=Aperçu du fichier +admin.auth.viewAction=Aperçu du fichier ouvert +admin.auth.download=Télécharger / copier +admin.auth.downloadAction=Télécharger / copier / imprimer un aperçu du fichier +admin.auth.uploadAction=Téléchargement de fichier (dossier) / téléchargement à distance +admin.auth.edit=Modifier nouveau +admin.auth.editAction=Nouveau fichier (dossier) / Renommer / Coller dans un dossier / Modifier le fichier / Définir les notes / Créer une copie / Décompresser +admin.auth.removeAction=Couper / copier / déplacer +admin.auth.shareAction=Partage de chaîne externe / partage de collaboration avec d'autres +admin.auth.comment=Documentez les commentaires +admin.auth.commentAction=Afficher les commentaires du document; ajouter / supprimer vos propres commentaires (autorisation de modification requise) +admin.auth.event=Document dynamique +admin.auth.eventAction=Visualisation dynamique des documents, dynamique des abonnements +admin.auth.root=Droits administratifs +admin.auth.rootAction=Définir les autorisations des membres / la gestion des commentaires / la gestion des versions de l'historique +admin.auth.delErrTips=Cette autorisation est utilisée et ne peut pas être supprimée! +admin.plugin.center=Centre de plugins +admin.plugin.installed=Installé +admin.plugin.type=Catégorie +admin.plugin.typeFile=Amélioration de fichier +admin.plugin.typeSafe=Outils de sécurité +admin.plugin.typeTools=Utilitaire +admin.plugin.typeMedia=Multimédia +admin.plugin.typeCompany=Application d'entreprise +admin.plugin.typeOem=Personnalisation exclusive +admin.plugin.needNetwork=Extranet +admin.plugin.install=Installer le plugin +admin.plugin.enable=Activer le plugin +admin.plugin.remove=Désinstaller plugin +admin.plugin.config=Configurer le plugin +admin.plugin.statusEnabled=Activé +admin.plugin.statusDisabled=Non activé +admin.plugin.statusNotInstall=Non installé +admin.plugin.installing=Installation en cours ... +admin.plugin.hasUpdate=Mise à jour +admin.plugin.updateStart=Mise à jour du plugin +admin.plugin.needConfig=Nécessite une configuration initiale pour activer +admin.plugin.notNull=Les champs obligatoires ne peuvent pas être vides! +admin.plugin.auther=Auteur +admin.plugin.downloadNumber=Installe +admin.plugin.back=Retour à +admin.plugin.detail=Description +admin.plugin.resetConfig=Restaurer les paramètres par défaut +admin.plugin.installSelf=Installation manuelle +admin.plugin.updateSelf=Mise à jour manuelle +admin.plugin.updateAll=Tout mettre à jour +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=Erreur réseau. Veuillez vérifier si le serveur peut accéder à Internet. +admin.plugin.auth=Droits d'utilisation +admin.plugin.authDesc=Rendre tout le monde disponible ou spécifier des utilisateurs, des groupes d'utilisateurs et des groupes d'autorisations +admin.plugin.authOpen=Accès ouvert +admin.plugin.authOpenDesc=Peut être consulté sans connexion, peut être utilisé pour les appels d'interface externe +admin.plugin.authAll=Tout le monde +admin.plugin.authUser=Utilisateur spécifié +admin.plugin.authGroup=Département désigné +admin.plugin.authRole=Spécifier le groupe de permission +admin.plugin.openWith=Style ouvert +admin.plugin.openWithDilog=Dialogue interne +admin.plugin.openWithWindow=Nouvelle page s'ouvre +admin.plugin.fileSort=Priorité d'association d'extension +admin.plugin.fileSortDesc=Plus l'extension est grande, plus la priorité est élevée +admin.plugin.fileExt=Formats de fichiers pris en charge +admin.plugin.fileExtDesc=Associer l'extension au plugin +admin.plugin.tabServer=Configuration du serveur +admin.plugin.defaultAceEditor=Ace éditeur +admin.plugin.defaultHtmlView=Aperçu Web +admin.plugin.defaultZipView=Décompression en ligne +admin.plugin.authViewList=Liste des plugins +admin.plugin.authStatus=Ouvrir fermer +admin.plugin.authInstall=Installer / désinstaller +admin.plugin.disabled=Le plugin n'existe pas ou n'a pas été démarré +admin.plugin.menuAdd=Que ce soit pour ajouter au menu principal +admin.plugin.menuAddDesc=Utilisation en tant qu'application autonome +admin.plugin.menuSubMenuDesc=Réduire dans le menu [Plus] +admin.storage.type=Type de stockage +admin.storage.local=Local +admin.storage.localStore=Stockage local +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=Sept nuages de vache +admin.storage.s3=Amazon S3 +admin.storage.ftp=FTP +admin.storage.oos=Tianyi Cloud OOS +admin.storage.moss=Hongshan MOSS +admin.storage.eos=XSKY EOS +admin.storage.nos=Ancien NOS cloud +admin.storage.minio=MinIO +admin.storage.uss=Prenez un autre USS cloud +admin.storage.eds=Sang pour EDS +admin.storage.driver=Disque local +admin.storage.useage=Utilisation de l'espace +admin.storage.default=Définir par défaut +admin.storage.current=Valeur par défaut actuelle +admin.storage.edit=Stockage de configuration +admin.storage.setConfig=Modifier la configuration +admin.storage.moveData=Migrer des données +admin.storage.delStore=Démonter le stockage +admin.storage.ifMove=Ce stockage contient {0} fichiers de disque réseau et sera migré vers le stockage par défaut actuel. Voulez-vous continuer ? +admin.storage.ifDel=Voulez-vous vraiment démonter le magasin actuel ? +admin.storage.ifDelWithFile=Ce stockage contient {0} fichiers de disque réseau, qui seront migrés vers le stockage par défaut actuel une fois supprimés. Voulez-vous continuer ? +admin.storage.sysFile=Fichiers disque réseau : fichiers sous espace personnel et départements +admin.storage.delErrTips=Succès:%s; échec:%s, veuillez réessayer ou migrer manuellement +admin.storage.delLocTips=Veuillez conserver au moins un magasin local +admin.storage.delStoreTips=Ce stockage contient des données de sauvegarde, veuillez les traiter avant de continuer ! +admin.storage.nameDesc=Nom de stockage pour distinguer différents stockage +admin.storage.path=Répertoire de stockage +admin.storage.pathLocDesc=Répertoire de stockage de fichiers, veuillez vous assurer que le répertoire rempli dispose des autorisations de lecture et d'écriture. +admin.storage.pathDesc=Répertoire de stockage de fichiers +admin.storage.defaultDesc=L'élément par défaut est le seul stockage système valide. Si vous choisissez de l'activer, les autres méthodes de stockage par défaut seront automatiquement annulées. Veuillez faire preuve de prudence. +admin.storage.forceEdit=Modification obligatoire +admin.storage.editTips=Après ouverture, vous pouvez éditer les champs de modification interdits. Le fichier avant le stockage peut ne pas être accessible, veuillez faire preuve de prudence. +admin.storage.folderTips=L'emplacement de stockage actuel des fichiers système, veuillez faire preuve de prudence +admin.storage.sizeTips=La taille de l'espace doit être supérieure à 0 +admin.storage.sizeDesc=(Go), veuillez remplir en fonction de l'espace libre réel du répertoire de stockage sélectionné +admin.storage.region=Zone de stockage +admin.storage.domain=Nom de domaine spatial +admin.storage.bucket=Nom du seau +admin.storage.bucketDesc=Nom du seau renseigné lors de la création d'espace +admin.storage.userName=Nom du compte +admin.storage.userPwd=Mot de passe du compte +admin.storage.server=Adresse du serveur +admin.storage.serverDesc=ftp (s): // ip, la valeur par défaut est ftp sans protocole +admin.storage.refer=Référence: +admin.storage.endpoint=Endpoint +admin.storage.ossDomain=Nom de domaine lié dans l'espace OSS +admin.storage.ossKeyDesc=ID de clé d'accès du compte Alibaba Cloud, veuillez créer ou afficher dans [Panneau de configuration - Gestion des clés d'accès] +admin.storage.ossSecretDesc=Clé d'accès secrète du compte Alibaba Cloud +admin.storage.ossEndpoint=Endpoint, si vous utilisez un nœud intranet, vous devez activer le transfert de serveur +admin.storage.cosKeyDesc=ID de clé d'accès du compte Tencent Cloud, veuillez créer ou afficher dans [Panneau de configuration-Gestion des accès-Gestion des clés API] +admin.storage.cosSecretDesc=Accéder au secret de clé du compte Tencent Cloud +admin.storage.qiniuDomain=Nom de domaine lié par l'espace Qiniu +admin.storage.qiniuKeyDesc=Clé d'accès pour le compte Qiniu, veuillez créer ou afficher dans [Panneau de configuration-Centre personnel-Gestion des clés] +admin.storage.qiniuSecretDesc=Clé secrète pour le compte Qiniu, la méthode d'obtention est la même que ci-dessus +admin.storage.qnz0=Chine orientale - Zhejiang +admin.storage.qnz02=Est de la Chine - Zhejiang 2 +admin.storage.qnz1=Chine du Nord - Hebei +admin.storage.qnz2=Chine du Sud - Guangdong +admin.storage.qnna0=Amérique du Nord - Los Angeles +admin.storage.qnas0=Asie-Pacifique - Singapour +admin.storage.qnas02=Asie-Pacifique - Séoul +admin.storage.awsDomain=Nom de domaine lié dans l'espace AWS +admin.storage.awsKeyDesc=Clé d’accès ID du compte AWS, veuillez la créer dans [Panneau de configuration-Vos identifiants de sécurité] +admin.storage.awsSecretDesc=Clé d'accès secrète pour le compte AWS +admin.storage.oosDomain=Tianyi Cloud Nom de domaine lié à l'espace +admin.storage.oosKeyDesc=Clé d’accès du compte Tianyi Cloud, veuillez la créer dans [Panneau de configuration-Vos identifiants de sécurité] +admin.storage.oosSecretDesc=Le secret de clé d'accès du compte cloud Tianyi est le même que ci-dessus +admin.storage.ftpDisabled=Le FTP n'est pas disponible, veuillez activer l'extension php_ftp +admin.storage.ifDefaultTips=Cette opération annulera les autres méthodes de stockage par défaut. Êtes-vous sûr? +admin.storage.spaceUsed=Utilisation pratique +admin.storage.spaceLave=Montant restant +admin.storage.delError=Le fichier existe déjà dans ce magasin et ne peut pas être supprimé +admin.storage.corsError=Si la configuration est correcte, cliquez sur [Utiliser l'aide] pour vérifier les paramètres interdomaines du bucket. +admin.storage.saveError=Impossible de se connecter au stockage spécifié, veuillez vérifier si les informations de configuration sont correctes. +admin.storage.ftpCharset=Encodage du serveur FTP +admin.storage.ftpCharsetDesc=Si le serveur FTP est Windows, il peut être défini sur GBK selon la situation; +admin.storage.ftpPasvOn=Allumer +admin.storage.ftpPasvOff=fermeture +admin.storage.ftpPasv=Mode passif +admin.storage.ftpPasvDesc=Mode de transfert de données +admin.storage.uploadSrv=Transfert de serveur (téléchargement) +admin.storage.fileoutSrv=Transfert de serveur (téléchargement) +admin.storage.uploadSrvDesc=Une fois activé, le fichier sera téléchargé sur le stockage d'objets via le serveur; sinon, il sera téléchargé directement via le client. +admin.storage.fileoutSrvDesc=Une fois allumé, le fichier de stockage sera obtenu via le serveur pour téléchargement; sinon, le fichier sera obtenu pour un téléchargement par lien direct. +admin.storage.closeDefError=Interdire la désactivation du stockage par défaut +admin.storage.ussBucket=Nom du service +admin.storage.ussBucketDesc=Nom du service de stockage cloud +admin.storage.ussUser=Nom de l'opérateur +admin.storage.ussUserDesc=Nom de l'opérateur +admin.storage.ussUserPwd=Mot de passe opérateur +admin.storage.ussDomain=Prenez une autre photo du nom de domaine lié à l'espace cloud +admin.storage.ussToken=Jeton anti-sangsue +admin.storage.ussTokenDesc=Clé secrète de la chaîne antivol de jeton (non requise) +admin.storage.configError=Le paramètre de configuration est anormal ! +admin.storage.sizePercent=Rapport de fichier système : +admin.storage.fileCount=Nombre de fichiers : +admin.storage.error=Exception de stockage +admin.task.name=Nom de la tâche +admin.task.edit=Édition de tâches +admin.task.type=Type de tâche +admin.task.method=Méthodes intégrées +admin.task.methodName=Nom de la méthode +admin.task.methodDesc=Il se compose du nom de la méthode du contrôleur du module système, à remplir soigneusement. +admin.task.url=URL de demande +admin.task.urlDesc=Adresse URL définie par l'utilisateur, tâches planifiées pour exécuter régulièrement les demandes. +admin.task.cycle=Cycle d'exécution +admin.task.desc=détails de la mission +admin.task.nMinutes=N minutes +admin.task.default=Système par défaut +admin.task.timeInterval=Temps d'intervalle +admin.task.timeStart=Heure de début +admin.task.timeStartRun=Démarrer le temps d'exécution +admin.task.timeLastRun=Dernière heure d'exécution +admin.task.timeLastLogin=Temps de connexion +admin.task.isOpen=Que ce soit pour activer +admin.task.open=Ouvert +admin.task.content=Contenu de mise en œuvre +admin.task.param=Paramètre d'exécution +admin.task.ifRun=Voulez-vous vraiment exécuter cette tâche? +admin.task.backup=sauvegarde de données +admin.task.backupDesc=Commencez à sauvegarder les données système à 02h00 tous les jours. +admin.install.install=Installation du système +admin.install.databaseSet=Configuration de la base de données +admin.install.dataUpdate=Migration de données +admin.install.installSuccess=Installé avec succès +admin.install.dbWasSet=Vous avez configuré la base de données. Si vous devez réinitialiser, vous pouvez modifier la configuration dans le fichier config / setting_user.php et la réinstaller! +admin.install.errorRequest=Le système est installé, aucune autre demande n'est autorisée +admin.install.databaseError=Erreur de connexion à la base de données, veuillez vérifier la configuration +admin.install.cacheError=La connexion %s a échoué, veuillez vérifier la configuration +admin.install.cacheConnectError=%s ne peut pas se connecter au serveur, veuillez vérifier la configuration +admin.install.dbSetError=L'écriture des informations de configuration de la base de données a échoué +admin.install.dbCreateTips=La base de données n'existe pas et la création automatique échoue. Créez-la manuellement +admin.install.ifDelDb=Les données existent déjà dans la base de données spécifiée. Cliquez sur [OK] pour les supprimer. Voulez-vous continuer? +admin.install.dbCreateError=Exception de création de table de données +admin.install.dbFileError=Le fichier de base de données n'existe pas +admin.install.dbTypeError=Le type de base de données sélectionné (%s) n'est pas disponible, veuillez installer le service et l'extension correspondants, ou choisissez un autre type +admin.install.createSuccess=Créé avec succès +admin.install.defSetError=La configuration système par défaut n'a pas pu être ajoutée +admin.install.defStoreError=L'ajout de stockage par défaut a échoué +admin.install.defPathError=L'ajout du répertoire système a échoué +admin.install.defAdminError=Le compte administrateur n'a pas pu être ajouté +admin.install.defRoleError=L'ajout de rôle par défaut a échoué +admin.install.defGroupError=L'ajout du département système a échoué +admin.install.dataPathNotExists=le répertoire de données n'existe pas +admin.install.defaultUpdate=Mise à jour des informations de configuration du système +admin.install.pluginUpdated=Mise à jour du plugin terminée +admin.install.defCacheError=Exception de données du cache de répertoire initial +admin.install.serverDir=Répertoire de la colonne du serveur +admin.install.dirRight=Autorisations de répertoire +admin.install.suggestOpen=Suggéré d'ouvrir +admin.install.suggestClose=Recommandé de fermer +admin.install.phpVersionTips=PHP 5.3 et supérieur +admin.install.phpBitTips=64 bits recommandé +admin.install.phpBitDesc=32 bits ne prend pas en charge le téléchargement et le téléchargement de fichiers sur 2G +admin.install.pathNeedWirte=Le répertoire du programme et tous les sous-répertoires doivent être lisibles et inscriptibles +admin.install.mustOpen=Doit ouvrir +admin.install.setPathWrt=Veuillez définir les autorisations de lecture et d'écriture pour le répertoire du projet +admin.install.ensureNoError=Assurez-vous que ce qui suit est correct: +admin.install.setAdminName=Veuillez créer un compte administrateur +admin.install.setAdminPwd=Veuillez définir un mot de passe administrateur +admin.install.database=Base de données +admin.install.dbType=Type de base de données +admin.install.dbName=Nom de la base de données +admin.install.userName=Nom d'utilisateur +admin.install.dbPort=Numéro de port +admin.install.dbPortDesc=Le port par défaut est 3306, si vous avez besoin de le personnaliser, vous pouvez l'ajouter, par exemple : 127.0.0.1:3307 +admin.install.dbEngine=Moteur de stockage +admin.install.sqliteDesc=PHP possède une base de données intégrée légère et verte (adaptée aux tests ou à une utilisation à petite échelle). +admin.install.mysqlDesc=Prend en charge le déploiement de clusters, la séparation des bases de données maîtres et esclaves. +admin.install.pdoDesc=Un pilote général de base de données plus sécurisé nécessite que PHP ait l’extension PDO installée. +admin.install.cacheType=Type de cache système +admin.install.cacheTypeDesc=Utilisé pour mettre en cache les données générales et les sessions pour accélérer l'accès au système +admin.install.fileCache=Cache de fichiers +admin.install.groupFile=Document du département +admin.install.userFile=Documentation utilisateur +admin.install.role=Rôle +admin.install.fileAuth=Autorisations de document +admin.install.userList=Liste d'utilisateurs +admin.install.setInfo=Informations de configuration du système +admin.install.favShare=Favoris de l'utilisateur et partages +admin.install.waitUpdate=En attente de mise à jour +admin.install.updateSuccess=Mise à jour réussie +admin.install.fileCount=Nombre de fichiers +admin.install.settingDesc=Les éléments d'échec peuvent être configurés manuellement dans la gestion en arrière-plan +admin.install.reInstallTips=Le résultat est anormal, veuillez réinstaller. +admin.log.accountEdit=Modifier les informations du compte +admin.log.thirdBind=Lier un compte tiers +admin.log.delBind=Se détacher +admin.log.viewFile=fichier de prévisualisation +admin.log.delFile=Supprimer le fichier +admin.log.editFile=Editer le fichier +admin.log.downFile=Télécharger le fichier +admin.log.downFolder=Dossier de téléchargement +admin.log.moveFile=Déplacer le fichier +admin.log.addUser=Ajouter un utilisateur +admin.log.editUser=Modifier l'utilisateur +admin.log.addUserTo=Ajouter des utilisateurs au département +admin.log.removeUserFrom=Utilisateur retiré du département +admin.log.switchUserGroup=Migrer les utilisateurs vers les départements +admin.log.stausUser=Activer / désactiver les utilisateurs +admin.log.addRole=Nouveau rôle +admin.log.editRole=Modifier le rôle +admin.log.delRole=Supprimer le rôle +admin.log.addAuth=Ajouter des autorisations +admin.log.editAuth=Modifier les autorisations +admin.log.delAuth=Supprimer l'autorisation +admin.log.editShare=Modifier le partage +admin.log.delLinkTo=Annuler le partage de liens externes +admin.log.delShareTo=Annuler le partage collaboratif +admin.log.recycleTo=Passer à la corbeille +admin.log.newName=Nouveau nom +admin.log.oldName=Nom d'origine +admin.log.newPath=Nouveau catalogue +admin.log.oldPath=Catalogue original +admin.log.typeFile=Opérations sur les fichiers +admin.log.typeUser=Configuration utilisateur +admin.log.queryByIp=Cliquez sur le bouton pour interroger les enregistrements du journal du jour en fonction de l'adresse IP. +admin.backup.setting=Paramètres de sauvegarde +admin.backup.edit=Edition de sauvegarde +admin.backup.ing=Sauvegarde +admin.backup.success=La sauvegarde a réussi +admin.backup.fail=La sauvegarde a échoué +admin.backup.complete=Sauvegarde terminée +admin.backup.db=base de données +admin.backup.dbFile=fichier de base de données +admin.backup.fileError=La sauvegarde de certains fichiers a échoué +admin.backup.checkLog=Veuillez vérifier le journal de sauvegarde : data/temp/log/backup/date of the day__log.php +admin.backup.pathNoWrite=Le répertoire temporaire n'a pas l'autorisation d'écriture +admin.backup.errorMsg=Une partie de la sauvegarde de fichiers a échoué, vous pouvez copier manuellement en fonction du journal, ou supprimer et sauvegarder à nouveau. +admin.backup.logFile=Fichier journal +admin.backup.manual=Sauvegarde manuelle +admin.backup.continue=Continuer la sauvegarde +admin.backup.start=Démarrer la sauvegarde +admin.backup.open=Activer la sauvegarde +admin.backup.notOpen=La sauvegarde n'est pas activée +admin.backup.location=Emplacement de sauvegarde +admin.backup.content=Contenu de sauvegarde +admin.backup.dbOnly=base de données +admin.backup.time=Temps de sauvegarde +admin.backup.notStart=n'a pas commencé +admin.backup.notEnabled=Pas activé +admin.backup.killed=plus de +admin.backup.ifKill=Voulez-vous vraiment mettre fin à cette sauvegarde? +admin.backup.kill=Fin +admin.backup.error=Avorter +admin.backup.timeBeen=Long +admin.backup.timeTotal=Temps total +admin.backup.backed=Sauvegardé +admin.backup.storage=Veuillez créer un stockage dédié pour la sauvegarde. +admin.backup.ifSave=La sauvegarde prend du temps. Voulez-vous vraiment effectuer une sauvegarde? +admin.backup.ifContinue=Voulez-vous vraiment continuer la sauvegarde? +admin.backup.saveTips=La tâche de sauvegarde a été soumise, veuillez patienter +admin.backup.fileSize=Taille du document +admin.backup.dbSize=Taille de la base de données +admin.backup.dbCnt=total +admin.backup.notFinished=Pas achevé +admin.backup.timeTaken=long +admin.backup.node=nœud +admin.backup.notYet=Non +admin.backup.storeNotExist=Le stockage de sauvegarde n'existe pas, veuillez réinitialiser +admin.backup.timeNote=Remarque : Le système ne conserve que les sauvegardes de la base de données des 7 derniers jours et du 1er de chaque mois. Temps de sauvegarde : +admin.backup.recover=Veuillez contacter le fournisseur de services pour la récupération des données. +admin.backup.optionTime=La sauvegarde prend beaucoup de temps, veuillez essayer de la choisir pendant les heures creuses +admin.backup.optionLocation=Si vous devez sauvegarder des fichiers, veuillez créer un nouveau stockage dédié à la sauvegarde +admin.backup.optionTips1=La sauvegarde est divisée en deux parties: la sauvegarde de la base de données et la sauvegarde des fichiers. +admin.backup.optionTips2=Sauvegarde de la base de données: générez des fichiers SQL à partir du contenu de la base de données et sauvegardez-les dans le répertoire de la base de données de stockage cible. +admin.backup.optionTips3=Sauvegarde de fichiers: sauvegardez les fichiers de stockage système sur le stockage cible de manière incrémentielle en fonction du chemin de stockage d'origine. +admin.backup.optionTips4=Le système ne conserve que les sauvegardes de la base de données des 7 derniers jours et du 1er de chaque mois. +admin.backup.needStorage=Le stockage de sauvegarde ne peut pas être vide +admin.backup.needNoDefault=Ne choisissez pas le stockage par défaut comme emplacement de sauvegarde de fichiers +admin.backup.contentDesc=La version sous licence prend en charge la sauvegarde simultanée des bases de données et des fichiers +admin.backup.action=Gestion d'opération +admin.backup.recovery=réduction +admin.backup.sysRecovery=restauration du système +admin.backup.bakErr2Rec=Cette sauvegarde est incomplète et ne peut pas être restaurée +admin.recycle.menu=Corbeille système +admin.share.name=Partager le nom +admin.share.type=Type de partage +admin.share.expiryTime=Expiration +admin.share.expired=expiré +admin.share.link=Lien externe +admin.share.linkView=Cliquez pour voir le partage +admin.share.ifDel=Voulez-vous vraiment annuler ce partage? +admin.share.disFile=Ce fichier a été signalé par les utilisateurs et a été interdit de partage +admin.share.disFolder=Ce répertoire contient des fichiers illégaux dont le partage est interdit +admin.share.shareTab=Gestion du partage +admin.share.reportTab=Gestion des rapports de partage +admin.share.rptType1=Le piratage +admin.share.rptType2=Porno obscène +admin.share.rptType3=Violence sanglante +admin.share.rptType4=La politique est nuisible +admin.share.rptType5=autres raisons +admin.share.doRptClose=Fermez le rapport après avoir traité le contenu partagé ou fermez-le directement +admin.share.doRptDisable=Après avoir interdit / autorisé le partage, toutes les ressources correspondant au fichier seront affectées. Etes-vous sûr de vouloir effectuer cette opération? +admin.share.rptUser=Lanceur d'alerte +admin.share.rptTitle=Partage de rapport +admin.share.rptDesc=Raison du signalement +admin.share.rptTime=Temps de rapport +admin.share.rptResult=résultat du processus +admin.share.rptDone=Traité +admin.share.rptNoDone=Non traité +admin.share.rptClose=Fermer le rapport +admin.share.rptShareDel=Annuler le partage +admin.share.rptShareAllow=Autoriser le partage +admin.share.rptShareDisable=Pas de partage +admin.share.rptDoDisable=Interdire/autoriser le partage +admin.share.rptSelectTips=Veuillez sélectionner l'élément à utiliser ! +admin.setting.transfer=Téléchargement / téléchargement +admin.setting.transferChunkSize=Importer la taille du fragment +admin.setting.transferChunkSizeDesc=Lors du téléchargement d'un fichier volumineux, il est découpé en morceaux pour un téléchargement simultané, de manière à accélérer et à reprendre la reprise.
    5M est recommandé; cette valeur doit être inférieure à la configuration suivante; sinon, cela entraînera une exception de téléchargement (échec du téléchargement, restauration) +admin.setting.transferChunkSizeDescError1=La taille du fragment de téléchargement ne peut pas dépasser le paramètre dans php.ini +admin.setting.transferChunkSizeDescError2=Modifiez-le dans php.ini et réessayez (modifiez upload_max_filesize, post_max_size, besoin de redémarrer) +admin.setting.transferThreads=Téléchargement de threads simultanés +admin.setting.transferThreadsDesc=Recommandé = 10; téléchargements simultanés de fichiers ou de fragments +admin.setting.transferIgnore=Importer un fichier ignoré +admin.setting.transferIgnoreDesc=Téléchargez les noms de fichiers qui sont automatiquement ignorés.Les fichiers temporaires peuvent être exclus, plusieurs séparés par des virgules, par exemple: .DS_store, thumb.db +admin.setting.transferChunkRetry=Retransmission automatique en cas d'échec du téléchargement +admin.setting.transferChunkRetryDesc=Recommandation = 5; le nombre de retransmissions sera effectué automatiquement si le téléchargement échoue, 0 signifie aucune retransmission automatique +admin.setting.transferOsChunkSize=Taille de la partition de stockage d'objets +admin.setting.transferOsChunkSizeDesc=Téléchargement de stockage d'objets, la taille du fragment varie de 5 Mo à 5 Go et le nombre maximal de demandes est de 1000, ce qui signifie que la taille maximale de téléchargement de fichier est de 5 To.
    Il est recommandé de 10 à 20 Mo. À l'heure actuelle, la taille de fichier maximale prise en charge est de 9,7 à 19,5 Go et les utilisateurs peuvent ajuster la taille du fichier téléchargé en fonction de leurs besoins. +admin.setting.transferHttpSendFile=Télécharger l'accélération du serveur web +admin.setting.transferHttpSendFileDesc=Le téléchargement de fichiers est directement transmis via le serveur Web; la vitesse de téléchargement est améliorée; il n'est efficace que lorsque le stockage par défaut est configuré comme stockage local. +admin.setting.downloadZipClient=Téléchargement compressé frontal +admin.setting.downloadZipClientDesc=Besoin de pouvoir se connecter au réseau externe, ou le site est https +admin.setting.downloadZipLimit=Limite de taille de téléchargement compressé +admin.setting.downloadZipLimitDesc=0 signifie aucune limite ; afin d'éviter une consommation excessive des performances du serveur, le téléchargement du package est restreint lorsque le dossier est trop volumineux, et il est demandé que le fichier puisse être téléchargé directement via le client PC +admin.setting.downloadZipLimitTips=Le contenu compressé dépasse la limite du système, veuillez contacter l'administrateur ! Vous pouvez télécharger directement le dossier via le client PC sans compression. +admin.setting.dragDownload=Glisser-déposer sur le bureau pour télécharger +admin.setting.dragDownloadDesc=Uniquement pris en charge par le navigateur du noyau Chrome côté PC (chrome edge 360 fast, etc.) +admin.setting.dragDownloadZip=Téléchargement de compression multi-sélection par glisser-déposer +admin.setting.dragDownloadZipDesc=Prise en charge du téléchargement par glisser-déposer de sélections multiples ou de dossiers, doit être empaqueté et compressé sur le serveur avant le téléchargement +admin.setting.dragDownloadLimit=Glisser-déposer la limite de taille du contenu +admin.setting.dragDownloadLimitDesc=0 signifie aucune limite ; la taille du contenu déplacé sera soumise à cette limite. Étant donné qu'il n'y a pas de barre de progression pour le déplacement et le téléchargement de Chrome à l'heure actuelle, il ne peut pas être annulé. Il est recommandé de limiter la taille à 20 Mo. +admin.setting.dragDownloadUrlTips=L'URL est trop longue, veuillez réduire la sélection et réessayer ! +admin.setting.dragDownloadOpenTips=Veuillez contacter l'administrateur pour l'activer dans les paramètres d'arrière-plan ! +admin.setting.dragDownloadNotOpen=Le téléchargement par glisser-compresser n'est pas activé +admin.setting.dragDownloadSizeTips=La taille du contenu déplacé dépasse la limite +admin.setting.showFileSafe=Sécurité d'accès aux fichiers +admin.setting.showFileLink=Affichage du lien externe du fichier +admin.setting.showFileLinkDesc=Après la fermeture, les propriétés du fichier n'affichent plus les liens externes +admin.setting.showFileMd5=affichage du fichier md5 +admin.setting.showFileMd5Desc=Après la fermeture, les propriétés du fichier n'affichent plus le fichier md5 +admin.setting.shareLinkAllow=Activer le partage de lien externe +admin.setting.shareLinkAllowDesc=Après la fermeture, il ne prendra plus en charge le partage de chaînes externes et le contenu partagé ne sera pas affecté +admin.setting.shareLinkAllowTips=Le système actuel a désactivé le partage de liens externes, veuillez contacter l'administrateur ! +admin.setting.shareLinkPasswordAllowEmpty=Le partage de chaîne externe permet au mot de passe d'être vide +admin.setting.shareLinkPasswordAllowEmptyDesc=Après la fermeture, un mot de passe doit être défini pour le partage de lien externe ; le contenu partagé ne sera pas affecté +admin.setting.shareLinkAllowGuest=Le partage de liens externes permet aux visiteurs non connectés d'accéder +admin.setting.shareLinkAllowGuestDesc=Après la fermeture, vous devez vous connecter lors de l'accès aux liens externes ; le contenu partagé ne sera pas affecté +admin.setting.shareLinkZip=Téléchargement du package de partage de lien externe +admin.setting.shareLinkZipDesc=Après ouverture, le dossier de partage de chaîne externe prend en charge le téléchargement de package et de compression. Si la concurrence est importante, les performances du serveur seront consommées. +admin.setting.shareLinkZipTips=Le partage de lien externe désactive le téléchargement du pack, veuillez contacter l'administrateur pour la configuration! +admin.setting.transferDownSpeed=Limite de vitesse de téléchargement +admin.setting.transferDownSpeedDesc=Limitez les vitesses de téléchargement et limitez uniformément la vitesse des grands sites Web simultanés +admin.setting.transferDownSpeedNum=Limite de vitesse de téléchargement +admin.setting.transferDownSpeedNumDesc=Limitez la vitesse de téléchargement et vous pouvez limiter uniformément la vitesse du site Web avec une concurrence importante.
    Remarque: ici, la vitesse du serveur est limitée. La vitesse de téléchargement spécifique est également affectée par la bande passante du serveur et le réseau utilisateur. +explorer.uploadSizeError=Votre serveur ne prend actuellement pas en charge les fichiers supérieurs à 2G,
    Veuillez passer à php 64 bits; php7 64 bits est recommandé
    (Remarque: le système d'exploitation 64 bits peut uniquement installer PHP 64 bits); +common.width=Large +common.height=Haute +common.test=Test +common.absolutePath=Adresse absolue +common.qrcode=URL code QR +common.wechat=WeChat +common.group=Département +common.user=Utilisateur +common.online=En ligne +common.use=À utiliser +common.total=Le total +common.year=Année +common.month=Mois +common.week=Semaine +common.daytime=Jour +common.mon=le lundi +common.tue=mardi +common.wed=mercredi +common.thu=Jeudi +common.fri=Vendredi +common.sat=le samedi +common.sun=dimanche +common.second=Deuxième +common.minute=Minute +common.hour=Les heures +common.day=Jour +common.every=chaque +common.everyMonth=par mois +common.everyWeek=hebdomadaire +common.everyDay=tous les jours +common.language=Langue +common.all=Tous +common.item=Item +common.items=Contenu de l'article +common.itemsEmpyt=Pas de contenu +common.detail=Détails +common.me=Je +common.others=Autre +common.guest=Visiteurs +common.more=Plus +common.learnMore=En savoir plus +common.yes=Oui +common.no=Non +common.omit=Omettre +common.unknow=Inconnu +common.title=Titre +common.time=temps +common.scan=Feuilleter +common.report=rapport +common.name=Nom +common.nickName=Surnom +common.tools=Des outils +common.tag=Tags +common.position=Emplacement +common.mount=Montage en réseau +common.type=Type +common.auth=Autorité +common.status=Statut +common.run=Run +common.file=Fichier +common.folder=Dossier +common.fileType=Type de fichier +common.fileSize=Taille du fichier +common.attributeInfo=Informations d'attribut +common.actionType=Type d'opération +common.isDisplay=Si montrer +common.hide=Masquer +common.isHide=Caché +common.cancelHide=Afficher +common.default=défaut +common.display=Montrer +common.moveDown=Descendre +common.moveUp=Monter +common.drag=Glisser +common.dragSort=Faites glisser pour ajuster l'ordre +common.warning=Avertissement +common.tips=Indice +common.desc=instruction +common.tipsDesc=Description rapide +common.tipsOthers=Autres instructions +common.view=Vue +common.log=Journal +common.task=tâche +common.important=Important +common.icon=Icône +common.menu=Le menu +common.system=système +common.basic=Universel +common.systemSet=Configuration du système +common.systemDefault=Système par défaut +common.diy=Personnalisé +common.input=S'il vous plaît entrer +common.select=Veuillez choisir +common.add=Ajouter +common.edit=Éditer +common.action=Opération +common.upload=Upload +common.uploadTo=télécharger sur +common.download=Télécharger +common.export=Exporter +common.cover=Couverture +common.retry=Réessayer +common.zip=Comprimé +common.unzip=Décompressez +common.preview=Aperçu +common.share=Partager +common.search=Recherche +common.query=Renseigner +common.delete=Supprimer +common.deleteForce=Supprimer complètement +common.deleteEnd=supprimé +common.refresh=Rafraîchir +common.open=Ouvert +common.close=Fermer +common.from=la source +common.greater=Plus grand que +common.less=Moins que +common.print=Imprimer +common.selectInvert=Élection inversée +common.selectAll=Sélectionner tout / Sélection inversée +common.selectAllItem=Tout sélectionner +common.selectNum=Sélectionnés +common.selectNull=Aucun du tout +common.sizeMore=ce qui précède +common.showMore=Se dérouler +common.showLess=Effondrer +common.sizeSmall=petit +common.sizeMiddle=dans +common.sizeBig=Gros +common.rename=Renommer +common.method=Fonction +common.extend=Extension +common.fav=Favori +common.reset=Réinitialiser +common.testing=Test +common.install=Installer +common.update=Mise à jour +common.version=Version +common.sysVersion=Version plateforme +common.login=Se connecter +common.regist=S'inscrire +common.password=Mot de passe +common.operateTime=Temps de fonctionnement +common.createTime=Heure de création +common.modifyTime=Temps de modification +common.activeTime=Temps d'archivage +common.startTime=Heure de départ +common.endTime=Heure de fin +common.finishTime=Heure de fin +common.disable=Désactiver +common.goOn=Continuer +common.ok=Ok +common.startRun=Début +common.confirmTips=Veuillez confirmer à nouveau +common.confirmAsk=Etes-vous sûr de vouloir effectuer cette opération? +common.submit=Soumettre +common.skip=Passer +common.nextStep=Prochaine étape +common.start=Début +common.stop=pause +common.set=Mettre en place +common.cancel=Annuler +common.save=Enregistrer +common.empty=Pas de contenu! +common.isOpen=Allumé +common.isClose=fermé +common.apply=Application +common.saveAll=Enregistrer tout +common.notSave=Ne pas enregistrer +common.appAdd=Ajouter +common.backAdd=Retour pour ajouter +common.saveEdit=Enregistrer les modifications +common.saveSubmit=Enregistrer la validation +common.saveAndAdd=Sauvegarder et continuer à ajouter +common.sex=Le sexe +common.male=Masculin +common.female=Femme +common.address=Adresse +common.email=Email +common.phone=Téléphone portable +common.sms=Sms +common.phoneNumber=Numéro de téléphone +common.server=Serveur +common.handheld=Appareil mobile +common.success=Le succès +common.fail=Échec +common.error=Mal +common.result=résultat +common.expired=Expiré +common.valid=Efficace +common.inAll=le total +common.allAndNull=Sélectionner tout / Annuler +common.moveTop=Haut +common.moveBottom=Définir à la fin +common.moveTopCancle=Dissocier +common.ECN=Chine de l'est +common.NCN=Chine du nord +common.SCN=Chine du sud +common.USA=Amérique du nord +common.SEA=Asie du sud est +common.noLimit=non limité +common.notExists=N'existe pas +common.cannotWrite=Lecture seule, pas écriture +common.readOnly=Lecture seulement +common.cannotRead=Illisible +common.ifDel=Êtes-vous sûr de vouloir supprimer? +common.pageNotExists=La page n'existe pas! +common.pathNotExists=Le document n'existe pas! +common.fileShare=Partage de documents +common.logining=Connexion ... +common.loginTokenError=La connexion est expirée, veuillez vous reconnecter! +common.loginSuccess=Connexion réussie! +common.loginError=Échec de la connexion +common.connectSuccess=Connecté avec succès! +common.bindSuccess=Lier avec succès! +common.bindError=La liaison a échoué +common.clear=Vide +common.congrats=Félicitations +common.sorry=Désolé +common.invalid=Invalide +common.unavailable=indisponible +common.format=Le format +common.noPermission=Permission refusée +common.allPermission=Toutes les autorisations +common.invalidParam=Paramètre invalide +common.invalidFormat=Format invalide +common.invalidRequest=Type de demande illégale +common.illegalRequest=Demande illégale +common.expiredRequest=La demande a expiré +common.errorExpiredRequest=Demande invalide ou a expiré +common.migrating=Migration +common.migrated=Migration terminée +common.maintenanceTips=Pendant la maintenance du système, veuillez visiter plus tard ... +common.done=terminé +common.disabled=désactivée +common.sizeTotal=Taille totale +common.sqlStatement=[Instruction SQL]: +common.env.check=Tests environnementaux +common.env.errorLib=La bibliothèque PHP est manquante +common.env.errorIgnore=Ignorer et entrer +common.env.errorVersion=La version de PHP ne peut pas être inférieure à 5.0 +common.env.errorPath=Non inscriptible +common.env.errorListDir=La fonction de liste de répertoires est activée sur votre serveur Web. Veuillez la désactiver pour des raisons de sécurité! Comment ça marche? +common.env.errorGd=La bibliothèque PHP GD doit être activée, sinon l'utilisation des codes de vérification et des vignettes sera anormale. +common.env.invalidExt=L'extension %s n'est pas disponible, veuillez vérifier si elle est installée +common.env.installWithBtTips=La version php du serveur requiert la version 5.3 ou supérieure. Je ne suis pas familiarisé avec la configuration en un clic du panneau de pagode recommandé.
    Version actuelle +common.env.phpCacheOpenTips=Votre serveur a la mise en cache php activée et les mises à jour de fichiers n'ont pas encore pris effet;
    Veuillez désactiver le cache ou actualiser la page et réessayer dans 1 minute!
    En savoir plus +common.env.dataPathNotExists=Le répertoire de données n'existe pas!
    (Vérifiez DATA_PATH); +common.env.pathPermissionError=[Code d'erreur: 1002] Erreur d'autorisation de répertoire! Veuillez définir le répertoire du programme et tous les sous-répertoires en lecture et en écriture.
    Linux exécute la commande suivante:
     su -c 'setenforce 0' 
    chmod -R 777 +common.version.free=Gratuit +common.version.nameQ=Enterprise Edition +common.version.vipFree=Édition gratuite +common.version.useFree=Continuer à utiliser la version gratuite +common.version.notSupport=Votre version ne supporte pas cette opération, veuillez vous rendre sur le site officiel pour acheter la version avancée! +common.version.notSupportNumber=Cette opération n'est pas prise en charge en raison du nombre limité, veuillez vous rendre sur le site officiel pour acheter la version avancée! +common.version.toVip=Mise à niveau vers commercial +common.version.license=Autorisation d'achat +common.version.authCode=Code d'activation de l'autorisation +common.version.authActive=Autorisation d'activation +common.version.authorization=Autorisation d'inscription +common.version.authorizeSuccess=Félicitations, l'autorisation de mise à niveau en ligne a été réussie! +common.version.networkError=La demande au serveur a échoué. Vérifiez si le serveur peut accéder au réseau.
    Remarque: le serveur ne peut pas être un proxy pour accéder à Internet. +common.version.authActiveOnline=Activer en ligne +common.version.authActiveOffline=Activer hors ligne +common.version.offlineTips=Le serveur ne peut pas accéder à Internet? +common.version.menuTitle=Paramètres d'informations d'entreprise +common.version.timeout=expiré +common.version.timeToService=Heure d'expiration du service +common.version.timeTo=Délai d'expiration de l'autorisation +common.version.licenseAll=Autorisation perpétuelle +common.version.kodVersion=Version du programme +common.version.userLimitTitle=Numéro d'utilisateur +common.version.userUse=Utilisé +common.version.userAllow=Nombre d'utilisateurs pris en charge +common.version.userTo=Objet autorisé +common.version.userTitle=Informations d'autorisation +common.version.basicInfo=Informations de base +common.version.appInfo=Information produit +common.version.tipsWarning=Attention, veuillez ne pas modifier le copyright sans autorisation; si nécessaire, veuillez contacter pour acheter! +common.version.tipsCopyLink=Copiez avec succès! Collez et enregistrez dans un fichier txt,
    Ouvrez ce lien sur un ordinateur avec un réseau via une clé USB, etc. +common.version.tipsHistory=La version gratuite ne prend en charge que 5 versions d'historique ; achetez un nombre illimité de versions sous licence ! +common.version.codeLink=Lien de demande de code d'autorisation +common.version.codeLinkHelp=1. Copiez le lien ci-dessus et visitez d'autres ordinateurs avec accès à Internet.
    2. Remplissez le "Code d’authentification d’autorisation" obtenu ci-dessus, puis activez et autorisez +common.copyright.logoTitle=Ensemble de logo d'identité d'entreprise +common.copyright.licenseInfo=Informations d'autorisation +common.copyright.licenseReset=Réautoriser +common.copyright.licenseResetTips=Réactivez pour plus d'informations! +common.copyright.formLogo=Type de logo de la page de connexion +common.copyright.formLogoTypeWord=Logo texte +common.copyright.formLogoTypeImage=Logo de l'image +common.copyright.formLogoDesc=Le logo texte utilise le nom de l'entreprise et le logo image utilise l'ensemble d'images comme suit. +common.copyright.formLogoImage=Image du logo de la page de connexion +common.copyright.formLogoImageDesc=Page de connexion et logo de fond de gestion, taille recommandée 250x100, format png translucide +common.copyright.formLogoMain=Logo du menu de l'interface principale +common.copyright.formLogoMainDesc=Logo de gestion des fichiers dans le coin supérieur gauche, taille recommandée 200x200, format png translucide blanc +common.copyright.formPowerByInfo=Paramètres d'informations sur les droits d'auteur de l'entreprise +common.copyright.formPowerBy=Nom de la société de droits d'auteur en bas +common.copyright.formHomePage=Saut de lien de copyright en bas +common.copyright.formConcat=Contact contextuel +common.copyright.formDesc=Description détaillée de la couche contextuelle du produit +common.copyright.formDescTips=Une fois la modification enregistrée, la page d'actualisation prend effet +common.copyright.formMetaKeywords=Mots clés du site (utilisés par les moteurs de recherche) +common.copyright.formMetaName=Nom du site (utilisé par les moteurs de recherche) +common.copyright.downloadApp=Téléchargement d'application +common.copyright.downloadLink= +common.copyright.about=À propos +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=Identification automatique +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=Arabe +common.charset.ISO_8859_6=Arabe +common.charset.ISO_8859_10=Langue nordique +common.charset.CP1257=Langues autour de la Baltique +common.charset.ISO_8859_13=Langues autour de la Baltique +common.charset.ISO_8859_4=Langues autour de la Baltique +common.charset.BIG5_HKSCS=Hong Kong traditionnel +common.charset.BIG5=Traditionnel-Taiwan +common.charset.Georgian_Academy=Géorgien +common.charset.PT154=Kazakh +common.charset.CP949=Coréen +common.charset.EUC_KR=Coréen +common.charset.GB18030=Chinois simplifié +common.charset.GBK=Chinois simplifié +common.charset.ISO_8859_14=Celtique +common.charset.CP1133=Lao +common.charset.ISO_8859_16=Le roumain +common.charset.ISO_8859_3=Langues d'Europe du sud +common.charset.EUC_JP=Japonais +common.charset.ISO_2022_JP=Japonais +common.charset.SHIFT_JIS=Japonais +common.charset.KOI8_T=Tadjik +common.charset.ISO_8859_11=Thaï +common.charset.TIS_620=Thaï +common.charset.CP1254=Turc +common.charset.CP1251=Cyrillique +common.charset.ISO_8859_5=Cyrillique +common.charset.KOI8_R=Cyrillique +common.charset.KOI8_U=Cyrillique +common.charset.CP1252=Langues d'Europe occidentale +common.charset.ISO_8859_1=Langues d'Europe occidentale +common.charset.ISO_8859_15=Langues d'Europe occidentale +common.charset.Macintosh=Langues d'Europe occidentale +common.charset.CP1255=L'hébreu +common.charset.ISO_8859_8=L'hébreu +common.charset.CP1253=Grec +common.charset.ISO_8859_7=Grec +common.charset.ARMSCII_8=Arménien +common.charset.CP1258=Vietnamien +common.charset.VISCII=Vietnamien +common.charset.CP1250=Langues d'Europe centrale +common.charset.ISO_8859_2=Langues d'Europe centrale +common.charset.defaultSet=Codage de fichier +common.charset.convertSave=Converti en +common.date.near=Tout à l'heure +common.date.miniteBefore=Il y a quelques minutes +common.date.today=Aujourd'hui +common.date.yestoday=Hier +common.date.before=avant de +common.faceDefault=Émoticône par défaut +common.loadMore=charger plus +common.numberLimit=La quantité dépasse la limite maximale! +common.lengthLimit=La longueur dépasse la limite maximale! +common.task.name=Gestionnaire des tâches +common.task.title=nom de la mission +common.task.user=Utilisateur exécutif +common.task.porcess=programme +common.task.start=Lancer la tâche +common.task.useTime=Temps écoulé +common.task.running=Exécution +common.task.stoping=En pause +common.task.killing=Fin +common.task.stop=Tâche suspendue +common.task.kill=Tâche finale +common.task.removeTips=Êtes-vous sûr de mettre fin à cette opération? +common.task.killAll=Tout finir +common.task.killAllTips=Êtes-vous sûr de terminer toutes les tâches? +common.task.timeStart=Commencer à +common.task.timeNeed=Restant environ +common.task.timeUse=Déjà en train de courir +ERROR_DB_PWD=Accès à la base de données refusé : nom d'utilisateur ou mot de passe erroné. +ERROR_DB_TIMEOUT=La connexion à la base de données a expiré, veuillez vérifier si l'adresse est correcte. +ERROR_DB_CONN_RFS=Connexion à la base de données refusée : informations de configuration incorrectes ou service non démarré. +ERROR_DB_ADR=Erreur de connexion à la base de données, veuillez vérifier si l'adresse est correcte. +ERROR_DB_NOT_SUPPORT=Type de base de données non pris en charge, veuillez vérifier si le service ou le fichier de configuration correspondant est normal. +ERROR_DB_XS_DENNIED=Accès à la base de données refusé : privilèges insuffisants. +ERROR_DB_NOT_EXIST=La base de données n'existe pas ou un nom incorrect a été spécifié. +explorer.pathNotSupport=Ce type de répertoire ne supporte pas cette opération! +explorer.pathIsRoot=Vous avez atteint le répertoire racine! +explorer.pathNull=Le dossier est vide +explorer.zipFileLarge=Le fichier est trop volumineux, veuillez le décompresser avant de le prévisualiser! +explorer.charNoSupport=Caractères spéciaux non pris en charge: +explorer.moveError=Déplacement échoué +explorer.lockError=Une erreur s'est produite, le verrouillage simultané a expiré +explorer.lockErrorDesc=Veuillez réduire la fréquence des requêtes, ou optimiser la configuration liée à la simultanéité du serveur, ou améliorer la configuration matérielle du serveur ; +explorer.moveSubPathError=Quelque chose s'est mal passé, le répertoire parent ne peut pas être déplacé vers le répertoire enfant! +explorer.spaceIsFull=Pas assez d'espace disponible, s'il vous plaît contactez l'administrateur! +explorer.sessionSaveError=Échec de l'écriture de session! Vérifiez si le disque est plein ou consultez votre fournisseur de services. +explorer.networkError=Erreur de connexion réseau (net :: ERR_CONNECTION_RESET), la connexion a été réinitialisée.
    Veuillez contacter la société hôte ou l'administrateur du réseau pour vérifier la configuration du pare-feu! +explorer.folderManage=Répertoire de gestion +explorer.clickEdit=Cliquez pour éditer +explorer.shortLink=Raccourci +explorer.upper=Couche supérieure +explorer.historyNext=Avance +explorer.historyBack=Retour +explorer.loading=En fonctionnement ... +explorer.getting=Obtenir ... +explorer.sending=Envoi de données ... +explorer.pullTips=Tirez vers le bas pour rafraîchir la page +explorer.pullDropTips=Gratuit pour rafraîchir la page +explorer.getSuccess=Obtenez le succès! +explorer.saveSuccess=Enregistré avec succès! +explorer.saveError=Échec de la sauvegarde! +explorer.success=Opération réussie +explorer.error=Opération a échoué +explorer.dataError=Les données sont anormales! +explorer.pathError=Erreur de chemin de document +explorer.repeatError=L'opération a échoué, le nom existe déjà! +explorer.systemError=Erreur système +explorer.mistake=Quelque chose s'est mal passé! +explorer.recycleClear=Vider la corbeille +explorer.recycleClearForce=Il y a trop de contenu dans la corbeille, veuillez d'abord vider la corbeille! +explorer.recycleRestore=Restaurer la corbeille +explorer.recycleRestoreItem=Restaurer +explorer.recycleRestoreAll=Tout restaurer +explorer.recycleClearInfo=Êtes-vous sûr de vouloir vider complètement la corbeille? +explorer.zipDownloadReady=Télécharger automatiquement après compression, veuillez patienter ... +explorer.removeItem=Contenu de l'article +explorer.uploading=Mise en ligne +explorer.uploadTipsMore=Trop de fichiers, il est recommandé de télécharger après la compression, puis de décompresser en ligne! +explorer.uploadingMove=Fusionner et transférer ... +explorer.viewNewPage=Aperçu de la nouvelle page +explorer.unknowFileTitle=Conseils d'ouverture de fichier! +explorer.unknowFileTips=Sans une application prenant en charge ce fichier, vous pouvez: +explorer.unknowAppTips=Sans l'application: +explorer.unknowFileTry=Essayer +explorer.unknowFileDown=Télécharger le fichier +explorer.authFileDown=Téléchargement de fichier +explorer.authShare=Partager +explorer.usersShare=De partage +explorer.clipboard=Voir le presse-papier +explorer.clipboardClear=Presse-papiers vide +explorer.fullScreen=Plein écran +explorer.folderItem=Articles +explorer.folderItemSelect=Sélectionné +explorer.dbLoadAll=Double-cliquez pour tout charger ... +explorer.ziping=Compressant ... +explorer.unziping=Décompresser ... +explorer.zipingTips=Opération de compression, veuillez patienter ... +explorer.unzipingTips=Opération de décompression, veuillez patienter ... +explorer.unzipRarTips=Le contenu du fichier est endommagé ou l'analyse du fichier n'est pas prise en charge. Il est recommandé d'utiliser le format ZIP. +explorer.parsing=Récupération ... +explorer.moving=Opération de déménagement ... +explorer.copyMove=Copier le mouvement +explorer.removeTitle=Supprimer la confirmation +explorer.removeInfo=Êtes-vous sûr de vouloir supprimer la sélection? +explorer.removeTitleForce=Supprimer pour toujours +explorer.removeInfoForce=Êtes-vous sûr de vouloir supprimer définitivement ce document? +explorer.pathInRecycle=Le dossier est dans la corbeille, veuillez le restaurer et réessayer ! +explorer.pathInRecycleFile=Le fichier est dans la corbeille, veuillez le restaurer et réessayer ! +explorer.downOffline=Télécharger hors connexion +explorer.savePath=Chemin de sauvegarde +explorer.uploadSelectMuti=Sélectionnez plusieurs fichiers à télécharger +explorer.goTo=Aller à +explorer.selectFile=Sélectionnez le fichier +explorer.selectFolder=Sélectionner un dossier +explorer.selectImage=S'il vous plaît sélectionner une image ... +explorer.selectValidFolder=Veuillez sélectionner un dossier pour être valide! +explorer.selectFolderFile=Sélectionnez un fichier ou un dossier +explorer.selectMulti=Choix multiple +explorer.notNull=Les champs obligatoires ne peuvent pas être vides! +explorer.picCannotNull=L'adresse de l'image ne peut pas être vide! +explorer.renameSuccess=Renommé avec succès! +explorer.inputSearchWords=Veuillez entrer la chaîne à rechercher +explorer.search.optionContent=contenu du document +explorer.search.searchContentTips=Contenu du fichier de recherche par mot-clé, fichier texte de soutien +explorer.search.optionMutil=Recherche groupée +explorer.search.optionMutilDesc=Un terme de recherche par ligne, les résultats de la recherche sont triés en fonction du terme de recherche +explorer.removeSuccess=Supprimé avec succès! +explorer.removeFail=La suppression a échoué! +explorer.clipboardNull=Le presse-papiers est vide! +explorer.createSuccess=Nouveau succès! +explorer.createError=Nouvelle création a échoué, s'il vous plaît vérifier les autorisations de répertoire! +explorer.copySuccess=[Copie] -Overwrite presse-papiers avec succès! +explorer.cuteSuccess=[Cut] -Overwrite presse-papiers avec succès! +explorer.clipboardState=Statut du presse-papier: +explorer.copyOK=Copié avec succès! +explorer.copyNotExists=La source n'existe pas +explorer.currentHasParent=Le dossier de destination est un sous-dossier du dossier source! +explorer.pastSuccess=Opération de collage terminée +explorer.cutePastSuccess=Opération de coupe terminée +explorer.zipSuccess=Compression terminée +explorer.notZip=Pas un fichier compressé +explorer.zipNull=Aucun fichier ou répertoire sélectionné +explorer.unzipSuccess=Décompressez complet +explorer.pathIsCurrent=Le chemin ouvert est le même que le chemin actuel! +explorer.pathExists=Le nom existe déjà! +explorer.serverDownDesc=Tâches ajoutées à la liste de téléchargement +explorer.parentPermission=Autorisations de répertoire parent +explorer.confirm=Êtes-vous sûr +explorer.ifSaveFileTips=Il n'y a pas de fichiers enregistrés, êtes-vous sûr de vouloir fermer la fenêtre? +explorer.ifSaveFile=Le fichier n'a pas encore été sauvegardé. +explorer.ifStopUploadTips=Un fichier est en cours de téléchargement, êtes-vous sûr de fermer la fenêtre? +explorer.noPermissionRead=Vous n'avez pas de permission de lecture! +explorer.noPermissionDownload=Vous n'avez pas la permission de télécharger! +explorer.noPermissionWrite=Le répertoire n'a pas de permission d'écriture +explorer.noPermissionAction=Vous n'avez pas cette permission, s'il vous plaît contactez l'administrateur! +explorer.noPermissionWriteAll=Le fichier ou le répertoire n'a pas le droit d'écriture +explorer.noPermissionWriteFile=Le fichier n'a pas de permission d'écriture +explorer.noPermissionReadAll=Le fichier ou le répertoire n'a pas les autorisations de lecture +explorer.noPermission=L'administrateur a désactivé cette autorisation! +explorer.noPermissionExt=Un administrateur a désactivé ce type d'autorisations de fichier +explorer.noPermissionGroup=Vous n'êtes pas dans ce groupe d'utilisateurs! +explorer.pathNoWrite=Le répertoire n’est pas accessible en écriture. Définissez le répertoire et tous les sous-répertoires en lecture et en écriture, puis réessayez! +explorer.onlyReadDesc=Ce répertoire ne dispose pas d'autorisations en écriture, vous pouvez définir des autorisations sur ce répertoire sur le serveur. +explorer.settingSuccess=La modification a pris effet! +explorer.noRepeat=Pas de doublons autorisés +explorer.dataNotFull=La soumission des données est incomplète! +explorer.tooManyToView=Contient trop de contenu (%s éléments), veuillez l’ouvrir localement pour le visualiser; +explorer.jumpAfterWhile=Saute automatiquement après%ss, Saute immédiatement +explorer.retryTips=Veuillez vérifier et réessayer +explorer.selectObject=Sélectionner des objets +explorer.parentGroup=Département supérieur +explorer.actionAuth=Autorité de l'opération +explorer.notSelectDesc=Aucune donnée, choisissez s'il vous plaît! +explorer.groupAuthCopy=Copiez la combinaison +explorer.groupAuthCopyDesc=Copier la combinaison d'autorisations +explorer.groupAuthPasteDesc=Coller la combinaison d'autorisations copiée +explorer.groupAuthSave=Enregistrer dans les favoris +explorer.groupAuthRecent=Utilisé récemment +explorer.selectDesc=Choisir le contenu +explorer.cannotLoad=Impossible de charger les résultats. +explorer.loadMore=Charger plus de résultats ... +explorer.noSearchData=Aucun résultat trouvé +explorer.delAllItem=Supprimer tous les éléments +explorer.pleaseDel=S'il vous plaît supprimer +explorer.pleaseInput=S'il vous plaît entrer au moins +explorer.canChoose=Seulement sélectionner au plus +explorer.theChars=Les personnages +explorer.theItems=Articles +explorer.noData=Aucune donnée +explorer.ifPathAuthClear=Tous les paramètres d'autorisations de sous-fichiers et de dossiers seront effacés. Voulez-vous vraiment continuer? +explorer.fileDescAdd=Ajouter une description du document +explorer.fileDesc=Description du document +explorer.fileLog=Journal des documents +explorer.ifResetOpen=Êtes-vous sûr de vouloir réinitialiser toutes les méthodes d'ouverture personnalisées? +explorer.ResetOpen=Réinitialiser toutes les méthodes ouvertes personnalisées +explorer.openWith=Ouvrir comme ... +explorer.openWithAce=L'éditeur s'ouvre +explorer.openWithLocal=Ouvrir localement +explorer.openWithLocalEdit=Édition locale +explorer.editorSaveTips=Le fichier n'a pas été créé, veuillez d'abord enregistrer le nouveau fichier. +explorer.editor.fileTooBig=Le fichier est trop volumineux et ne peut pas dépasser 20 Mo +explorer.errorFunctionTips=Ce type de fichier ne supporte pas les listes de fonctions! +explorer.errorFormatTips=Le type de fichier actuel ne correspond pas à la méthode de formatage par défaut.
    Veuillez sélectionner manuellement +explorer.cuteToThe=Déplacer vers: +explorer.copyToThe=Copier vers: +explorer.addToFav=Ajouter aux Favoris +explorer.addFav=Ajouter des favoris +explorer.delFav=Annuler la collecte +explorer.addFavSuccess=Ajouter un favori avec succès +explorer.pathHasFaved=Le chemin a été favorisé +explorer.delFavSuccess=Annuler la collecte avec succès +explorer.fileLock=Modifier le verrou +explorer.fileLockNow=verrouillage +explorer.fileLockCancle=Ouvrir +explorer.fileLockTitle=fermé à clé +explorer.fileLockTips=Verrouillé (les autres ne peuvent pas modifier le fichier) +explorer.fileLockUser=Casier +explorer.fileLockError=Le fichier actuel est verrouillé, veuillez contacter le casier pour le déverrouiller et réessayer; +explorer.downloaded=Téléchargement terminé +explorer.openAutoTips=S'ouvrira automatiquement +explorer.historyAutoTips=Générer automatiquement des versions historiques +explorer.saved=Enregistré avec succès +explorer.opened=Ouvrez avec succès! +explorer.openFail=Ouvert a échoué! +explorer.openingWithLoc=Le fichier est ouvert localement ... +explorer.openOnlyView=Le mode lecture seule est activé +explorer.saving=Sauvegarde de fichier ... +explorer.notSupport=Une erreur s'est produite, le format de contenu n'est pas pris en charge ! +explorer.unzipErrorTips=Quelque chose s'est mal passé! Format de fichier compressé non reconnu;
    Veuillez vérifier si le fichier est compressé ou endommagé. +explorer.wordLoading=Chargement ... +explorer.noFunction=Aucun moyen! +explorer.paramFormatError=Le format du paramètre est faux! +explorer.descTooLong=La description est trop longue +explorer.noMoreThan=Pas plus que +explorer.desktopDelError=Désolé, le dossier du bureau ne prend pas en charge la suppression! +explorer.copy=Copie +explorer.past=Coller +explorer.clone=Créer une copie +explorer.cute=Couper +explorer.cuteTo=Déplacer vers ... +explorer.copyTo=Copier vers ... +explorer.info=Attribut +explorer.searchInPath=Rechercher dans le dossier +explorer.addToPlay=Ajouter à la playlist +explorer.manageFav=Gérer les favoris +explorer.refreshTree=Actualiser le répertoire de l'arborescence +explorer.zip=Créer un package compressé +explorer.unzip=Décompressez pour ... +explorer.unzipFolder=Extraire dans un dossier +explorer.unzipThis=Décompresser au courant +explorer.unzipTo=Décompressez pour ... +explorer.openProject=Editeur de projet ouvert +explorer.createLink=Créer un raccourci +explorer.createLinkHome=Envoyer au bureau raccourci +explorer.setBackground=Définir comme fond d'écran +explorer.favRemove=Annuler cette collection +explorer.openPath=Aller au répertoire +explorer.openPathFinished=Déjà entré dans le répertoire +explorer.openIE=Le navigateur s'ouvre +explorer.newFile=Nouveau fichier +explorer.newFolder=Nouveau dossier +explorer.fileSaveTo=Fichier enregistré dans +explorer.openFather=Affichage du dossier supérieur +explorer.uploadFile=Télécharger le fichier +explorer.uploadFolder=Dossier de téléchargement +explorer.appOpenDefault=Définir pour ouvrir par défaut +explorer.appOpenAways=Ouvrez ce fichier toujours avec le programme de votre choix +explorer.appSelectDesc=Choisissez le programme que vous souhaitez utiliser pour ouvrir ce fichier +explorer.appSelectMenu=Définir comme mode d'ouverture par défaut +explorer.appSelectMenuCancel=Non défini comme ouverture par défaut avec +explorer.appSelectWarning=Veuillez sélectionner une application! +explorer.appTypeSupport=Applications de support +explorer.appTypeAll=Toutes les applications +explorer.appSearch=Recherche d'installations d'applications connexes +explorer.recent.createTime=Créé le +explorer.recent.modifyTime=Modifié le +explorer.recent.viewTime=Ouvert à +explorer.urlLink=Adresse du lien externe +explorer.downloading=Téléchargement en cours ... +explorer.downReady=À venir +explorer.downError=Le téléchargement a échoué! +explorer.max=Maximiser +explorer.min=Minimiser +explorer.minAll=Minimiser tout +explorer.displayAll=Afficher toutes les fenêtres +explorer.closeAll=Fermer tout +explorer.authDtl=Cliquez pour afficher vos autorisations dans le répertoire +explorer.authDialog=Membres internes, table des autorisations de niveau de collaboration de document +explorer.authNote=Remarque: Les fonctions de gestion incluent la définition des autorisations des membres / la gestion des commentaires, etc. Attention! [Administrateur système] Le rôle n'est limité par aucune autorisation +explorer.auth.toOuter=Autorisation externe (autres services ou utilisateurs) +explorer.auth.share=Sharer +explorer.auth.owner=Propriétaire +explorer.auth.disableDeep=Pas d'accès par permission uniquement +explorer.auth.disableDeepDesc=Le répertoire factor dispose des autorisations de lecture et d'écriture des documents et du chemin d'accès établi. +explorer.auth.tips=Peut contacter les utilisateurs ci-dessus pour définir des autorisations pour vous +explorer.notSystemPath=Pas un chemin de fichier système +explorer.toolbar.rootPath=Espace personnel +explorer.toolbar.fav=Les favoris +explorer.toolbar.desktop=Bureau +explorer.toolbar.client=Client +explorer.toolbar.myComputer=Mon ordinateur +explorer.toolbar.recycle=Corbeille +explorer.toolbar.myDocument=Mon document +explorer.toolbar.myPicture=Ma photo +explorer.toolbar.myMusic=Ma musique +explorer.toolbar.myMovie=Ma vidéo +explorer.toolbar.myDownload=Mon téléchargement +explorer.toolbar.uiDesktop=Bureau +explorer.toolbar.uiExplorer=Gestion de fichiers +explorer.toolbar.uiEditor=Éditeur +explorer.toolbar.uiProjectHome=Projet Home +explorer.toolbar.uiLogout=Sortie +explorer.toolbar.uiGroup=Structure organisationnelle +explorer.toolbar.myGroup=Mon département +explorer.toolbar.publicPath=Annuaire public +explorer.toolbar.recentDoc=Documents récents +explorer.toolbar.myShare=Ma part +explorer.toolbar.shareToMe=Collaborez avec moi +explorer.toolbar.shareTo=Ma collaboration +explorer.toolbar.shareLink=Partage de lien externe +explorer.toolbar.photo=album photo +explorer.photo.desc=Classement des albums d'utilisateurs +explorer.photo.group=Regroupement d'albums +explorer.photo.setting=Paramètres des albums +explorer.photo.pathRoot=Répertoire de numérisation d'albums +explorer.photo.pathRootSelect=Sélectionnez un dossier comme répertoire racine pour la numérisation d'images d'album +explorer.photo.fileType=Spécifiez le type de fichier +explorer.photo.fileSize=filtre de taille de fichier +explorer.photo.fileSizeDesc=Ne filtrer que les fichiers plus grands que ce paramètre, s'il est 0, il n'y a pas de limite +explorer.toolbar.folder=album de catalogue +explorer.toolbar.folderSelect=Sélectionnez un dossier à afficher en mode album +explorer.pathDesc.fav=Une fois le fichier ajouté à la collection, il est accessible rapidement et directement +explorer.pathDesc.home=L'espace personnel est votre espace de stockage privé, Visible uniquement par vous, pas par les autres utilisateurs +explorer.pathDesc.groupRoot=C'est l'espace public de l'entreprise/unité, Tous les membres sont visibles par défaut +explorer.pathDesc.myGroup=Gérez ici les documents de votre service, Les documents du département ne sont visibles et utilisables que par les membres de ce département, et non visibles par les autres membres du département +explorer.pathDesc.group=Disque réseau départemental, visible uniquement par les membres du département, L'autorité d'exploitation est attribuée et définie par l'administrateur du département. +explorer.pathDesc.recentDoc=Fichiers récemment créés, téléchargés, modifiés et ouverts +explorer.pathDesc.shareTo=Consultez et gérez vos projets de [collaboration interne] initiés par d'autres ici +explorer.pathDesc.shareLink=Affichez et gérez le partage de chaîne externe initié par vous ici +explorer.pathDesc.recycle=Gérez vos fichiers (dossiers) supprimés ici +explorer.pathDesc.fileType=Classer les fichiers par type, uniquement les fichiers dans l'espace personnel +explorer.pathDesc.tag=Ajoutez des balises aux fichiers (dossiers) pour obtenir une classification efficace et une requête rapide +explorer.pathDesc.tagItem=Essayez d'ajouter une étiquette au fichier/dossier ! +explorer.pathDesc.mount=Ici, vous pouvez gérer plusieurs stockages back-end, ainsi que les disques montés sur le serveur +explorer.pathDesc.shareToMe=Affichage en mosaïque : tout le contenu avec lequel j'ai collaboré +explorer.pathDesc.shareToMeUser=Afficher par partageur - le contenu avec lequel j'ai collaboré est classé par l'initiateur +explorer.pathDesc.shareToMeUserItem=Collaboration initiée par cet utilisateur +explorer.pathDesc.shareToMeGroup=Le contenu avec lequel je collabore est catégorisé par le département où se trouve le dossier +explorer.pathDesc.shareToMeGroupGroup=Partage collaboratif depuis le disque réseau du service +explorer.pathDesc.search= +explorer.pathDesc.searchMore=Définir plus de conditions de recherche +explorer.pathDesc.shareFrom=Chemin source +explorer.pathGroup.shareGroup=Espace départemental +explorer.pathGroup.shareGroupDesc=Accès lorsqu'il y a du contenu dans le département de niveau inférieur +explorer.pathGroup.shareUser=Partage de l'espace personnel des membres du département +explorer.pathGroup.shareUserDesc=Source : Partage de l'espace personnel de l'utilisateur, partage de documents du service externe initié par l'utilisateur. +explorer.pathGroup.shareContent=L'espace de collaboration et de partage du département +explorer.pathGroup.group=sous-département +explorer.pathGroup.groupContent=Document ministériel +explorer.pathGroup.shareUserOuter=Partage de collaboration externe +explorer.pathGroup.shareUserOuterDesc=Partage collaboratif d'utilisateurs externes ne relevant pas de leur propre structure organisationnelle +explorer.pathGroup.shareSelf=espace personnel +explorer.toolbar.fileSizeTitle=Taille de l'icône +explorer.toolbar.fileSizeSuper=Super petit +explorer.toolbar.fileSizeSmall=Petite icône +explorer.toolbar.fileSizeDefault=Icône moyenne +explorer.toolbar.fileSizeBig=Grosse icône +explorer.toolbar.fileSizeBigSuper=Icône surdimensionnée +explorer.toolbar.PagePC=Version PC +explorer.toolbar.pagePhone=Version mobile +explorer.file.name=Nom +explorer.file.type=Type +explorer.file.contain=Contient +explorer.file.address=Emplacement +explorer.file.detil=Description +explorer.file.linkCount=Citations +explorer.file.size=La taille +explorer.file.count=Quantité +explorer.file.byte=Octet +explorer.file.path=Chemin +explorer.file.action=Opération +explorer.file.creator=Créateur +explorer.file.editor=Modifié par +explorer.file.location=Emplacement +explorer.file.timeInfo=Informations de temps +explorer.file.createTime=Heure de création +explorer.file.modifyTime=Temps de modification +explorer.file.lastTime=Dernière visite +explorer.file.sortType=Trier par +explorer.file.sortDisable=Le contenu ne prend pas en charge le tri spécifié! +explorer.file.timeType=J / m / j H: i: s +explorer.file.timeTypeInfo=J / m / j H: i: s +explorer.file.listType=Voir +explorer.file.listIcon=Arrangement d'icônes +explorer.file.listList=Trier par liste +explorer.file.listListSplit=Mode colonne +explorer.file.listTypeGroup=Mode d'affichage et méthode de tri +explorer.file.listTypeKeep=mode d'affichage +explorer.file.listTypeKeepDesc=Choisissez un mode d'affichage pour chaque dossier ou utilisez le même mode d'affichage pour tous les dossiers +explorer.file.listSortKeep=Trier par +explorer.file.listSortKeepDesc=Configurez l'ordre de tri des colonnes pour chaque dossier ou utilisez le même ordre pour tous les dossiers +explorer.file.listViewKeep=Fonctionne avec un seul dossier +explorer.file.listViewAll=s'applique à tous les dossiers +explorer.file.listViewReset=réinitialiser par défaut +explorer.file.sortUp=En augmentation +explorer.file.sortDown=Décrémenter +explorer.file.orderType=Trier par +explorer.file.orderDesc=Descendant +explorer.file.orderAsc=Ordre croissant +explorer.file.imageSize=Taille de l'image +explorer.file.sharer=Sharer +explorer.file.shareTime=Temps de partage +explorer.file.viewCnt=Les visites +explorer.file.downCnt=Téléchargements +explorer.file.readWriteLock=Cette opération n'est temporairement pas prise en charge, d'autres tâches de lecture et d'écriture sont en cours de traitement, veuillez réessayer plus tard! +explorer.app.app=Application légère +explorer.app.createLink=Nouvelle URL +explorer.app.create=Créer une application légère +explorer.app.edit=Modifier l'application light +explorer.app.open=App lumière ouverte +explorer.app.groupGame=Jeu +explorer.app.groupTools=Des outils +explorer.app.groupReader=Lire +explorer.app.groupMovie=Le film +explorer.app.groupMusic=Musique +explorer.app.groupLife=La vie +explorer.app.desc=Description de l'application +explorer.app.icon=Icône d'application +explorer.app.iconShow=adresse URL ou le répertoire +explorer.app.group=Regroupement d'applications +explorer.app.type=Type +explorer.app.typeUrl=Lien +explorer.app.typeCode=extension js +explorer.app.display=Apparence +explorer.app.displayBorder=Sans frontières (sélectionné sans frontières) +explorer.app.displaySize=Redimensionner (sélectionner pour ajuster) +explorer.app.size=La taille +explorer.app.url=Adresse du lien +explorer.app.code=code js +explorer.app.appType=Type d'application +explorer.app.website=URL +explorer.app.shortLink=Raccourci de fichier +explorer.app.imgIcon=Icône d'image +explorer.app.imgIconUrl=Sélectionnez l'image ou collez l'URL de l'image Web. +explorer.app.path=Chemin +explorer.app.pathDesc=Ne supporte pas la modification manuelle, vous pouvez cliquer avec le bouton droit sur le fichier pour créer un raccourci +explorer.app.link=Lien URL +explorer.app.linkDesc=Veuillez entrer le lien http / https +explorer.app.linkDragTips=Vous pouvez faire glisser le lien URL dans la zone du fichier pour créer automatiquement un lien URL ! +explorer.app.openType=Manière ouverte +explorer.app.openWindow=Nouvelle fenetre +explorer.app.openDialog=Boite de dialogue +explorer.app.openCurrent=page actuelle +explorer.app.openInline=Intégrer la page +explorer.app.dialogSize=Taille du dialogue +explorer.app.with=Largeur +explorer.app.height=Hauteur +explorer.app.moreSet=Plus de réglages +explorer.app.canDiyWith=Permettre le réglage de la largeur +explorer.app.miniBlock=Barre de titre minimaliste +explorer.app.runCode=Exécuter le code js +explorer.app.name=Nom de l'application +explorer.app.nameDesc=Veuillez entrer un nom d'application. +explorer.app.descDesc=Veuillez saisir une description d'application +explorer.embed.title=Fichier incorporé +explorer.embed.desc=Incorporer le fichier dans une page Web ou un blog +explorer.embed.url=Incorporer l'URL +explorer.embed.code=Code intégré +explorer.upload.ready=En attente de téléchargement +explorer.upload.success=Envoyé avec succès +explorer.upload.secPassSuccess=Succès en quelques secondes +explorer.upload.pathCurrent=Passer au répertoire actuel +explorer.upload.select=Sélectionnez le fichier +explorer.upload.maxSize=Maximum autorisé +explorer.upload.sizeInfo=Si vous souhaitez configurer une version plus grande, veuillez modifier le nombre maximal de téléchargements autorisés dans le fichier php.ini. Lors de la sélection d'un fichier, les fichiers plus volumineux que cette configuration seront automatiquement filtrés. +explorer.upload.error=Échec du téléchargement +explorer.upload.mergeError=Fusionner des fichiers a échoué +explorer.upload.errorHttp=Erreur réseau ou pare-feu +explorer.upload.muti=Téléchargement de plusieurs fichiers +explorer.upload.drag=Glissez et déposez le téléchargement +explorer.upload.dragFolder=Faites glisser et déposez dans le dossier pour télécharger +explorer.upload.dragTips=Relâchez pour télécharger! +explorer.upload.pathNotAllow=Le nom de fichier n'est pas autorisé +explorer.upload.errorNull=Aucun document! +explorer.upload.errorBig=La taille du fichier dépasse la limite du serveur +explorer.upload.errorMove=Échec du déplacement des fichiers! +explorer.upload.errorExists=Le fichier existe déjà +explorer.upload.local=Télécharger localement +explorer.upload.tips=Utilisez le téléchargement de fragments, non plus limité par php.ini; faites glisser et téléchargez le dossier d'expérience Chrome +explorer.upload.exist=Traitement de fichier avec le même nom +explorer.upload.clearAll=Effacer tout +explorer.upload.clear=Vidage terminé +explorer.upload.addMore=Ajouter en vrac +explorer.upload.errorEmpty=Ne peut pas être vide! +explorer.upload.errorExt=Les extensions de fichier ne correspondent pas! +explorer.upload.fileSizeDisable=Il y a trop de fichiers téléchargés / transférés en même temps, veuillez contacter l'administrateur pour ajuster! +explorer.upload.moreDesc=(Recommandé pas plus de 2000) +explorer.upload.scan=Numérisation +explorer.upload.merge=Vérification de la fusion +explorer.upload.needTime=Restant env. +explorer.upload.checkError=La vérification de l'importation a échoué, veuillez réessayer +explorer.upload.saveError=Échec de l'enregistrement des informations sur le fichier téléchargé +explorer.upload.downloadDesc=Prend uniquement en charge les liens réseau http / https +explorer.table.first=Accueil +explorer.table.last=Dernière page +explorer.table.prev=Précédent +explorer.table.next=Page suivante +explorer.table.one=Total 1 pages +explorer.table.page=Page +explorer.table.itemPage=/page +explorer.table.searchTotal=Trouvé +explorer.table.items=Records +explorer.table.list=Liste de données +explorer.search.ing=Recherche ... +explorer.search.result=Résultat de la recherche +explorer.search.resultTooMore=Trop de résultats de recherche suggèrent un autre répertoire ou mot +explorer.search.resultNull=Aucun résultat de recherche! +explorer.search.caseSensitive=Sensible à la casse +explorer.search.content=Rechercher le contenu du fichier +explorer.search.extDesc=Entrez les extensions à filtrer, séparées par des espaces. +explorer.search.byItems=Filtrage conditionnel +explorer.search.extNull=Type illimité +explorer.search.extFile=Tout fichier +explorer.search.extDiy=Personnaliser +explorer.search.inputDesc=Veuillez entrer des mots-clés ou fournir des filtres! +explorer.search.path=Rechercher dans le répertoire: +explorer.search.rootPath=Rechercher dans le répertoire racine: +explorer.search.range=Plage de recherche +explorer.search.allFolder=Tous les dossiers +explorer.search.currentFolder=Dossier actuel +explorer.search.ext=Type de fichier +explorer.search.timeRange=Intervalle de temps +explorer.search.timeAll=Temps illimité +explorer.search.lastDay=Presque 1 jour +explorer.search.lastWeek=7 derniers jours +explorer.search.lastMonth=30 derniers jours +explorer.search.lastYear=L'année dernière +explorer.search.sizeAll=Taille illimitée +explorer.search.inputNullDesc=Si non rempli, cela signifie plus ou moins qu'une certaine valeur, qui peut être une décimale. +explorer.search.selectUser=Sélectionnez un utilisateur ... +explorer.search.byUserDesc=Recherche par créateur / modificateur +explorer.search.total=Trouvé +explorer.search.noResult=Désolé, il n'y a pas de résultats de recherche, veuillez utiliser un autre terme! +explorer.search.advance=Recherche avancée +explorer.search.clear=Effacer le contenu +explorer.history.list=Historique du fichier +explorer.history.lastModify=Dernière modification +explorer.history.modifyUser=Modifié par +explorer.history.noHistory=Aucune version historique! +explorer.history.current=Version actuelle +explorer.history.detil=Description +explorer.history.detilAdd=Ajouter une empreinte +explorer.history.uploadNew=Télécharger la nouvelle version +explorer.history.diff=Comparaison des versions historiques +explorer.history.setCurrent=Définir comme version actuelle +explorer.history.delCurrent=Supprimer cette version +explorer.history.delAll=Supprimer tout l'historique des versions +explorer.history.ifDelAll=Êtes-vous sûr de vouloir supprimer tout l'historique? +explorer.history.ifDelCurrent=Supprimer cette version? +explorer.history.ifRollback=Êtes-vous sûr de vouloir revenir à cette version? +explorer.history.changeEvent=Changement de version historique +explorer.history.before=Avant de +explorer.history.after=après +explorer.recycle.clearUser=Vider la corbeille de l'utilisateur +explorer.recycle.restoreSelect=Restaurer ce contenu +explorer.recycle.moveTo=Remettre +explorer.recycle.config=Paramètres de la corbeille +explorer.recycle.configTitle=Paramètres de la corbeille système +explorer.recycle.configOpen=Ouvrez la corbeille du système +explorer.recycle.configOpenDesc=Suggérer d'ouvrir +explorer.recycle.configCloseInfo=Lors de la suppression du contenu, il n'entrera pas dans la corbeille du système; il sera supprimé directement. +explorer.recycle.configOpenInfo=
  • Documents personnels ou documents ministériels, après avoir complètement supprimé ou vidé la corbeille, entrez dans la corbeille du système
  • Le contenu supprimé est classé dans le dossier de l'utilisateur ou du service en fonction de l'utilisateur ou du service où se trouve le fichier, et l'administrateur peut choisir de restaurer ces fichiers;
  • Les fichiers avant le moment de la suppression automatique complète seront automatiquement vidés régulièrement;
  • Remarque: les fichiers supprimés ici ne peuvent pas être récupérés.
  • +explorer.recycle.configClear=Supprimer complètement automatiquement +explorer.recycle.restoreConfirm=Êtes-vous sûr de vouloir restaurer le document?
    Après la restauration, le document sera déplacé vers le répertoire racine cible +explorer.recycle.moveConfirm=Confirmer la remise +explorer.recycle.moveSelectTarget=Sélectionnez un utilisateur ou un service +explorer.recycle.moveDesc=
  • Remettre à l'utilisateur ou au service désigné; il migrera vers le répertoire racine de l'objet
  • Après le transfert, les descriptions de documents, les échanges et les discussions, les versions historiques et d'autres informations continueront d'être conservées; les informations de collaboration et d'autorisation partagées seront supprimées.
  • +explorer.recycle.taskTitle=Nettoyage de la corbeille du système +explorer.recycle.taskDesc=Supprimez automatiquement le contenu de la corbeille dépassant la durée définie pour libérer de l'espace de stockage +explorer.share.add=Ajouter un partage +explorer.share.edit=Editer Partager +explorer.share.remove=Annuler le partage +explorer.share.path=Partager le chemin +explorer.share.source=Partage de ressources +explorer.share.name=Partager le titre +explorer.share.nameDesc=Nom de fichier partagé par défaut, personnalisable +explorer.share.time=Temps d'expiration +explorer.share.timeLimit=Temps limité +explorer.share.timeLimitDesc=Après avoir allumé et paramétré, le partage sera automatiquement désactivé une fois le temps écoulé +explorer.share.timeDesc=Non défini si vide +explorer.share.pwd=Extraire le mot de passe +explorer.share.pwdDesc=Aucun mot de passe n'est défini +explorer.share.randomPwd=Généré aléatoirement +explorer.share.randomPwdDesc=Il ne peut être visualisé qu'en extrayant le mot de passe, qui est plus privé et sûr. +explorer.share.cancel=Annuler le partage +explorer.share.create=Créer un lien public +explorer.share.url=Adresse partagée +explorer.share.noDown=Téléchargement interdit +explorer.share.codeRead=Lecture de code +explorer.share.configSave=Sauvegarder la configuration +explorer.share.errorParam=Erreur de paramètre! +explorer.share.errorUser=Les informations utilisateur sont fausses! +explorer.share.errorSid=Partager n'existe pas! +explorer.share.errorTime=Vous êtes en retard, cette part a expiré! +explorer.share.errorPath=Le fichier partagé n'existe pas, il a été supprimé ou déplacé! +explorer.share.errorPwd=Le mot de passe est faux! +explorer.share.errorShowTips=Ce type de fichier ne supporte pas la prévisualisation! +explorer.share.expiredTips=Désolé, ce partage a expiré, veuillez contacter le partage! +explorer.share.downExceedTips=Désolé, les téléchargements de partage ont dépassé la limite définie par le partageur. +explorer.share.store=Enregistrer sur SkyDrive +explorer.share.loginTips=Désolé, ce partage doit être connecté pour pouvoir y accéder! +explorer.share.noDownTips=Désolé, le partage a désactivé le téléchargement! +explorer.share.noViewTips=Désolé, ce partage a désactivé la prévisualisation! +explorer.share.noUploadTips=Désolé, l'envoi est désactivé par ce partage! +explorer.share.needPwd=Ce partage nécessite un mot de passe +explorer.share.notExist=Le partage n'existe pas! +explorer.share.viewNum=Parcourir: +explorer.share.downNum=Téléchargements +explorer.share.openPage=Ouvrir la page partagée +explorer.share.openLink=Ouvrir le lien de partage +explorer.share.copyLink=Copier les informations de partage +explorer.share.link=Partager le lien: +explorer.share.accessPwd=Mot de passe d'accès: +explorer.share.copied=Copié +explorer.share.actionNotSupport=Partager le contenu, cette opération n'est pas supportée +explorer.share.errorPathTips=Le lien de partage est incorrect ou le partage a annulé le partage du lien externe. +explorer.share.shareTo=Partage collaboratif +explorer.share.shareToTarget=Membre collaborateur +explorer.share.innerTo=Collaboration interne +explorer.share.linkTo=Partage de liens externes +explorer.share.selectTarget=Sélectionnez un département ou un utilisateur pour le partage collaboratif +explorer.share.afterShareDesc=Après avoir partagé avec l'autre partie ou le service auquel ils appartiennent, les utilisateurs peuvent le voir dans [Partager avec moi]. +explorer.share.openOuterLink=Partage de chaîne externe ouvert +explorer.share.openOuterLinkDesc=Après avoir créé un lien externe, vous pouvez l'envoyer à d'autres personnes par courrier électronique ou QQ. +explorer.share.outerLink=Partager le lien +explorer.share.advanceSet=Configuration avancée +explorer.share.loginLimit=Disponible uniquement pour les utilisateurs connectés +explorer.share.loginLimitDesc=Après ouverture, seuls les membres internes peuvent accéder. +explorer.share.authLimit=Droits et restrictions +explorer.share.canUpload=Autoriser le téléchargement +explorer.share.notView=Désactiver l'aperçu +explorer.share.notDown=Désactiver les téléchargements +explorer.share.downNumLimit=Limite de téléchargement +explorer.share.downNumLimitDesc=Après ce nombre de fois, le lien de partage expire automatiquement. +explorer.share.learnAuth=Comprendre les autorisations de collaboration de documents +explorer.share.shareToRemove=Êtes-vous sûr d'annuler ce partage collaboratif?
    L'utilisateur cible qui a partagé avec ne peut plus voir le partage collaboratif! +explorer.share.shareLinkRemove=Êtes-vous sûr d'annuler le partage de lien externe?
    Après annulation, le lien externe sera invalide! +explorer.share.shareToCopy=Copier le chemin d'accès +explorer.share.shareToCopyDesc=Le lien peut être envoyé à la personne collaboratrice et entrer rapidement dans la collaboration +explorer.share.specifyAuthTips=En plus des utilisateurs spécifiés ci-dessus +explorer.share.specifyAuthDesc=Autorité d'utilisateur désigné> Autorité du département de l'utilisateur désigné> Autorité d'une autre personne +explorer.share.selfAuthDesc=Impossible de modifier ses propres autorisations, d'autres gestionnaires peuvent définir +explorer.share.authTypeDesc=Hériter des autorisations du dossier parent par défaut +explorer.share.rootPathAuthDesc=Choix de l'utilisateur et du service du service racine +explorer.share.subPathAuthDesc=Sous-département, sélectionnez uniquement les membres du département +explorer.share.myAuth=Mes permissions +explorer.share.othersAuth=Autres autorisations +explorer.share.keepAuth=Conserver les autorisations originales +explorer.share.specifyAuth=Spécifiez les autorisations +explorer.share.userAuth=Droits d'utilisateur +explorer.share.specifyUserAuth=Spécifier les permissions de l'utilisateur +explorer.share.rptTitle=Si vous trouvez des informations illégales ou préjudiciables, veuillez sélectionner la raison ci-dessous pour soumettre un rapport. +explorer.share.illegal=Information illégale +explorer.share.inputRptDesc=Veuillez saisir la raison du signalement +explorer.share.rptSend=La soumission est réussie, l'administrateur s'en occupera à temps +explorer.share.rptSended=Le rapport a été soumis, en attente de traitement par l'administrateur +explorer.auth.mutil=Définir les autorisations par lots +explorer.auth.mutilTips=Remarque : si le contenu sélectionné dispose déjà d'une autorisation, il sera écrasé. +explorer.auth.mutilDesc=En même temps que les autorisations par défaut suivantes +explorer.auth.showMore=Détails de l'autorisation +explorer.auth.tabUser=membre du département +explorer.auth.tabChildren=Autorisations de sous-dossier +explorer.auth.tabUserTips=Autorisations initiales des membres du département +explorer.auth.tabChildrenTips=Contenu avec autorisations définies dans ce dossier +explorer.auth.resetUser=Remplacer la définition de cette autorisation d'utilisateur +explorer.auth.resetUserBtn=Remplacer les autorisations +explorer.auth.resetUserBtnTips=Remplacer les autorisations de l'utilisateur et de tous les sous-dossiers (dossiers) dans ce dossier +explorer.auth.resetUserHeader=Le dossier de niveau inférieur contient le contenu spécifiant les autorisations de l'utilisateur et définit tous les remplacements sur les autorisations ci-dessus +explorer.auth.resetUserContiner=Contient le contenu de l'autorisation de l'utilisateur +explorer.auth.resetUserEmpty1=Il n'y a pas de contenu pour lequel des autorisations sont définies pour cet utilisateur, pas besoin de remplacer +explorer.auth.resetUserEmpty2=Tout le contenu enfant hérite des autorisations de dossier du niveau actuel +explorer.rename.mutil=Renommage par lots +explorer.rename.nameBefore=Nom du fichier d'origine +explorer.rename.nameTo=Renommé +explorer.rename.start=Renommer maintenant +explorer.rename.clearFinished=Vidange terminée +explorer.rename.clearAll=Tout effacer +explorer.rename.typeReplaceAll=Remplacer tout +explorer.rename.typePrepend=Ajouter avant +explorer.rename.typeAppend=Ajouter plus tard +explorer.rename.typeReplace=Rechercher et remplacer +explorer.rename.typeChangeCase=Conversion de cas +explorer.rename.typeRemove=Supprimer des caractères +explorer.rename.typeReplaceSet=Spécifier le remplacement par lot +explorer.rename.typeReplaceSetDesc=Remplacez-les s'ils sont égaux; chaque ligne est séparée par un espace et le nom de fichier n'autorise pas d'espaces; par exemple: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Contenu additionnel +explorer.rename.find=Trouver +explorer.rename.replaceTo=Remplacé par +explorer.rename.caseUpperFirst=Capital initial +explorer.rename.caseUpper=Toutes les casquettes +explorer.rename.caseLower=Tout en minuscules +explorer.rename.removeStart=Retirer de zéro +explorer.rename.removeEnd=Retirer de la fin +explorer.rename.chars=Personnage +explorer.editor.beautifyCode=Mise en forme du code +explorer.editor.convertCase=Conversion de cas +explorer.editor.convertUpperCase=Convertir en majuscule +explorer.editor.convertLowerCase=Convertir en minuscule +explorer.editor.currentTime=Heure actuelle +explorer.editor.md5=cryptage md5 +explorer.editor.qrcode=String QR code +explorer.editor.regx=Test d'expression régulière +explorer.editor.chinese=Conversion simplifiée +explorer.editor.chineseSimple=Convertir en chinois simplifié +explorer.editor.chineseTraditional=Convertir en chinois traditionnel +explorer.editor.base64=codec base64 +explorer.editor.base64Encode=encodage base64 +explorer.editor.base64Decode=décodage en base64 +explorer.editor.url=URL codec +explorer.editor.urlEncode=Encodage d'URL +explorer.editor.urlDecode=Décodage d'URL +explorer.editor.unicode=Codec Unicode +explorer.editor.unicodeEncode=Codage Unicode +explorer.editor.unicodeDecode=Décodage Unicode +explorer.editor.toolsSelectTips=Veuillez sélectionner le bon contenu à traiter! +explorer.editor.toolsRandString=Générer une chaîne aléatoire de 32 bits +explorer.editor.textEncode=Encodage / décodage de texte +explorer.editor.textParse=Traitement de texte +explorer.editor.timeShow=Horodatage dans le temps +explorer.editor.timeInt=Heure de l'horodatage +explorer.editor.lineRemoveEmpty=Supprimer les lignes vides (y compris les espaces) +explorer.editor.lineUnoin=Supprimer les lignes en double +explorer.editor.lineTrim=Supprimer les espaces de début et de fin +explorer.editor.lineSort=Trier par ligne (ordre croissant) +explorer.editor.lineReverse=Échangez toutes les lignes de haut en bas +explorer.editor.lineSum=Somme +explorer.editor.lineAverage=valeur moyenne +explorer.editor.calc=Calculatrice gratuite +explorer.editor.goToLine=Aller à la ligne +explorer.editor.keyboardType=Mode clavier +explorer.editor.fontFamily=Police +explorer.editor.codeMode=Surligner la syntaxe +explorer.editor.closeAll=Fermer tout +explorer.editor.closeLeft=Fermer l'onglet gauche +explorer.editor.closeRight=Fermer l'onglet droit +explorer.editor.closeOthers=Fermer autre +explorer.editor.wordwrap=Word Wrap +explorer.editor.showGutter=Afficher le numéro de ligne +explorer.editor.charAllDisplay=Afficher les caractères invisibles +explorer.editor.autoComplete=Invite automatique +explorer.editor.autoSave=Enregistrement automatique +explorer.editor.functionList=Liste de fonction +explorer.editor.codeTheme=Style de code +explorer.editor.fontSize=Taille de la police +explorer.editor.completeCurrent=Courant automatique +explorer.editor.createProject=Ajouter à l'éditeur du projet +explorer.editor.markdownContent=Répertoire de contenu +explorer.editor.undo=Révoquer +explorer.editor.redo=Anti-révocation +explorer.editor.shortcut=Raccourci +explorer.editor.replace=Remplacer +explorer.editor.reload=Recharger +explorer.editor.view=Voir +explorer.editor.tools=Des outils +explorer.editor.help=L'aide +explorer.sync.data=Synchronisation de données +explorer.sync.openLoc=Ouvrir le répertoire local +explorer.sync.syncing=Synchronisation +explorer.sync.synced=Synchronisation terminée +explorer.sync.syncedError=Journal des erreurs +explorer.sync.syncStart=Lancer la synchronisation +explorer.sync.syncStop=Arrêtez la synchronisation +explorer.sync.notOpenTips=Vous n'avez pas activé la synchronisation locale +explorer.sync.setNow=Configurer la synchronisation maintenant +explorer.sync.error=Échec du téléchargement +explorer.sync.success=Synchronisation réussie +explorer.sync.statusScan=Numérisation +explorer.sync.statusNone=La synchronisation n'est pas configurée +explorer.sync.statusScanEnd=Analyse terminée +explorer.sync.statusDoing=Synchronisation +explorer.sync.statusDone=Synchronisation terminée +explorer.sync.statusStop=Pause +explorer.sync.clearCacheSuccess=Vider le cache avec succès! +explorer.sync.emptyTask=Aucune tâche de synchronisation +explorer.sync.openCloud=Emplacement cloud ouvert +explorer.sync.openLocal=Ouvert localement +explorer.sync.statusFiles=Documenter la progression +explorer.sync.statusLastTime=Délai d'achèvement +explorer.sync.configName=Paramètres de synchronisation +explorer.sync.configClient=Paramètres client +explorer.sync.configAbout=À propos +explorer.sync.configSyncFrom=Chemin local +explorer.sync.configSyncFromDesc=Sélectionnez un dossier local à synchroniser +explorer.sync.configSyncTo=Synchroniser avec +explorer.sync.configSyncToDesc=Synchroniser avec l'emplacement du serveur +explorer.sync.configIgnore=Types de fichiers ignorés +explorer.sync.configIgnoreDesc=Les fichiers de ce type ne sont pas synchronisés +explorer.sync.autorun=Auto-démarrage +explorer.sync.configThread=Nombre de threads simultanés +explorer.sync.configThreadDesc=Nombre de fichiers téléchargés en même temps +explorer.sync.configDownloadPath=Chemin de téléchargement +explorer.sync.configDownloadPathDesc=Chemin de téléchargement par défaut lors du téléchargement de dossiers de fichiers +explorer.sync.configClearCacheAuto=Vider automatiquement le cache +explorer.sync.configClearCacheAutoDesc=Effacer automatiquement le fichier cache il y a N jours +explorer.sync.configClearCache=Vider le cache +explorer.sync.configChangeSite=Quitter le site actuel +explorer.sync.configVersion=Version actuelle +explorer.sync.configUpdateDesc=Instructions de mise à jour +explorer.sync.configUpdateCheck=Détection des mises à jour +explorer.sync.confirmReset=Synchronisez la modification du répertoire, les informations de synchronisation seront réinitialisées. Voulez-vous vraiment enregistrer? +explorer.sync.listClearDone=Vidange terminée +explorer.sync.listClearError=Effacer la liste des erreurs +explorer.sync.listRetryAll=Réessayer tout +explorer.async.tipsDisablePath=Ne prend pas en charge le choix de synchroniser le chemin +explorer.async.tipsIsMoving=Détecté qu'une grande quantité de contenu est actuellement déplacée ou copiée dans le répertoire synchronisé;
    Il est recommandé de rafraîchir la page pour la synchronisation après l'achèvement local! +explorer.async.tipsStartUser=Lancer la synchronisation manuellement +explorer.download.title=Gestion des téléchargements +explorer.download.waiting=Attendre +explorer.download.stop=Suspendre le téléchargement +explorer.download.start=Commencer Le Téléchargement +explorer.download.remove=Supprimer la tâche +explorer.download.stopAll=Mettre tout en pause +explorer.download.startAll=Continuez tout +explorer.download.clearAll=Effacer toutes les tâches +explorer.download.doing=En traitement +explorer.download.done=Téléchargement terminé +explorer.download.clearAllTips=Êtes-vous sûr de supprimer toutes les tâches de téléchargement? +explorer.tag.name=Balise de fichier +explorer.tag.edit=Gestion des étiquettes +explorer.tag.add=Créer une étiquette +explorer.tag.remove=Voulez-vous vraiment supprimer cette balise ? +explorer.tag.inputHolder=Veuillez saisir un nom d'étiquette +explorer.tag.addTo=Définir l'étiquette +explorer.tag.default1=Matériel d'apprentissage +explorer.tag.default2=Données de test +explorer.tag.default3=Contrat +explorer.tag.filter=Filtrer par étiquette +explorer.groupTag.title=Marque publique +explorer.groupTag.menuTtitle=Label public départemental +explorer.groupTag.titleDesc=Label public au sein du département +explorer.groupTag.empty=Une fois que l'administrateur du département a défini l'étiquette publique, elle est automatiquement activée. Lorsqu'il n'y a pas de contenu d'étiquette, l'étiquette publique est automatiquement désactivée ! +explorer.tag.pathDesc=Filtrer par étiquette personnelle +explorer.groupTag.pathDesc=Filtrer par label public départemental +explorer.groupTag.removeTypeTips=Êtes-vous sûr de supprimer ce groupe ? Tous les documents associés au libellé seront supprimés après la suppression ! +explorer.groupTag.removeTagTips=Êtes-vous sûr de vouloir supprimer la balise ? Le document associé à la balise sera supprimé après la suppression ! +explorer.groupTag.typeAdd=ajouter une catégorie +explorer.groupTag.typeName=Nom de catégorie +explorer.groupTag.addDesc=Après avoir ajouté des balises, les balises de service sont automatiquement activées et le nombre maximum de balises est de 1000 +explorer.panel.info=Les attributs +explorer.panel.version=version +explorer.panel.chat=discuter +explorer.panel.log=dynamique +explorer.panel.meta=Métadonnées +explorer.panel.chatName=Échange de discussion +explorer.panel.chat.send=envoyer +explorer.panel.chat.noAuth=Vous n'êtes pas autorisé à commenter ce document! +explorer.panel.chat.placeholder=Entrez ici, [Entrée] pour envoyer, [Ctrl + Entrée] saut de ligne +explorer.panel.chat.placeholderCtrl=Entrez ici, Ctrl + Entrée pour envoyer, Entrée pour envelopper +explorer.panel.chat.reply=Répondre +explorer.panel.chat.empty=sans commentaire +explorer.panel.chat.sendTo=Vers l'avant +explorer.panel.metaName=Extension de métadonnées +explorer.panel.metaDesc=Propriétés étendues du champ de document +explorer.panel.thumbClear=vignette claire +explorer.panel.thumbClearDesc=Effacer les vignettes des fichiers, couverture à régénérer. +explorer.panel.historyName=version historique +explorer.panel.historyDesc=Notes de version +explorer.panel.infoTips=Sélectionnez le fichier (dossier) pour afficher les propriétés détaillées +explorer.panel.info.space=Capacité d'espace +explorer.panel.info.groupAt=Emplacement du département +explorer.panel.info.tagEmpty=Pas de balises, cliquez sur paramètres +explorer.panel.logName=Nouvelles du document +explorer.panel.logEmpty=Aucune activité +explorer.type.doc=Doc +explorer.type.image=image +explorer.type.music=la musique +explorer.type.movie=vidéo +explorer.type.zip=Archiver +explorer.type.others=autre +explorer.secret.title=Gestion de la confidentialité des documents +explorer.secret.isOpen=Que ce soit pour activer +explorer.secret.isOpenDesc=Activer et désactiver la gestion du niveau de sécurité +explorer.secret.setUser=gestionnaire secret +explorer.secret.setUserDesc=Spécifiez l'utilisateur qui peut définir le niveau de confidentialité (doit être le propriétaire dans le service correspondant en même temps) +explorer.secret.type=Type de classement +explorer.secret.add=Ajouter un niveau de sécurité +explorer.secret.edit=modifier le niveau de sécurité +explorer.secret.name=Nom du cours +explorer.secret.style=style +explorer.secret.auth=Autorisation de niveau secret +explorer.secret.authHas=Les autorisations confidentielles incluent +explorer.secret.createUser=setter +explorer.secret.folderAt=dossier confidentiel +explorer.secret.tips=Les autorisations sont contrôlées par le niveau de secret, et les autorisations de niveau secret sont supérieures aux autorisations de document +explorer.secret.tips1=Uniquement pour le contenu sous le disque réseau départemental, l'utilisateur spécifié ci-dessus peut définir le niveau de confidentialité (et doit être le propriétaire du dossier en même temps) +explorer.secret.tips2=Tout le contenu de la couche inférieure du dossier avec le niveau de confidentialité est défini, et cette autorité est la plus haute autorité +explorer.secret.tips3=Après le réglage, l'autorisation de niveau secret est supérieure à l'autorisation de document (le document est également contrôlé par l'autorisation de niveau secret, le super administrateur système n'est pas soumis à cette restriction et le créateur du niveau secret n'est pas soumis à cette restriction) +explorer.secret.tips4=Autorisations de niveau confidentiel : peuvent être ajoutées dans "Gestion des services et des membres - Gestion des droits sur les documents" et définies comme masquées +user.displayHideFile=Afficher les fichiers cachés +user.displayHideFileDesc=Fichiers cachés: fichiers commençant par., Et noms de fichiers cachés définis en arrière-plan du système; les fichiers cachés seront affichés après ouverture; +user.soundOpen=Activer le son +user.animateOpen=Lancer l'animation +user.recycleOpen=Ouvrir la corbeille +user.recycleDesc=Après ouverture, la suppression se déplacera dans la corbeille, il est recommandé d'ouvrir +user.animateDesc=Animations telles que l'ouverture d'une fenêtre, vous pouvez envisager de fermer lorsque l'opération n'est pas fluide +user.soundDesc=Ouvrir des fichiers, supprimer des fichiers, vider la corbeille, etc. +user.thumbOpen=Ouvrir la vignette +user.thumbDesc=Meilleure expérience de navigation dans les images après ouverture +user.fileSelect=Icône de fichier ouvert +user.fileSelectDesc=Clic gauche sur l'icône du fichier, entrée de raccourci dans le menu contextuel +user.fileShowDesc=Afficher l'introduction du dossier +user.fileShowDescTips=mode icône uniquement +user.fileOpenClick=Ouvrez le fichier (dossier) comme suit +user.fileOpenClick.dbclick=Ouvrir avec un double-clic +user.fileOpenClick.click=Ouvrir en cliquant +user.viewSetting=Afficher les options +user.thirdAccount=Compte tiers +user.bindAccount=Compte lié +user.thirdBindFirst=Le compte n'a pas été lié, veuillez utiliser après la liaison. +user.account=Compte +user.bind=Lier +user.unbind=Délier +user.binded=Lié +user.clickBind=Cliquez sur lier +user.clickToBind=Non lié, cliquez sur lier +user.clickEditPwd=Cliquez sur Modifier le mot de passe +user.userAvatar=Photo de profil +user.userNickName=Pseudo personnel +user.userAccount=Compte personnel +user.uploadAvatar=Télécharger l'avatar +user.userAvatarCrop=Veuillez sélectionner une zone appropriée comme avatar +user.userAvatarExt=Prend uniquement en charge les formats d'image JPG, JPEG, PNG +user.resetPwdDesc=Mot de passe oublié? Vous pouvez +user.inputEmailCode=S'il vous plaît entrer votre code de vérification email +user.inputSmsCode=S'il vous plaît entrer le code de vérification SMS +user.emailVerifyDesc=Certaines entreprises exigent une vérification de courrier électronique +user.phoneVerifyDesc=Certaines entreprises exigent une vérification de leur téléphone portable +user.bindOthers=Déjà lié à un autre compte +user.notBind=Pas encore lié +user.regist=Enregistrement de l'utilisateur +user.notRegist=Non enregistré +user.registed=Déjà inscrit +user.signError=La signature de rappel est incorrecte +user.repeat=Répéter +user.noRepeat=Ne peut pas répéter +user.newPwd=Nouveau mot de passe +user.unAuthFile=Accès aux fichiers non autorisé +user.unbindWarning=Veuillez modifier le mot de passe avant de dissocier, sinon le compte ne fonctionnera pas correctement +user.isLoginTips=Il est détecté que vous êtes actuellement connecté! +user.isLoginEnter=Entrez maintenant +user.ifUnbind=Êtes-vous sûr de vouloir dissocier? +user.bindFirst=S'il vous plaît lier votre email ou numéro de téléphone en premier +user.inputNewPwd=S'il vous plaît entrer un nouveau mot de passe +user.inputNewValue=S'il vous plaît remplir le nouveau contenu +user.guestLogin=Login touristique +user.name=Compte de connexion +user.nickName=Pseudo de l'utilisateur +user.code=Code de vérification +user.codeError=Erreur du code de vérification +user.imgCode=Captcha +user.rootPwd=Définir le mot de passe administrateur +user.rootPwdRepeat=Confirmer le mot de passe à nouveau +user.rootPwdEqual=Les mots de passe ne correspondent pas deux fois! +user.rootPwdTips=Veuillez définir un mot de passe administrateur! +user.pwdError=Le nom d'utilisateur ou le mot de passe est incorrect! +user.pwdNotNull=Le mot de passe ne peut pas être vide! +user.oldPwdError=Le mot de passe d'origine est faux! +user.keepPwd=Mémoriser mon mot de passe +user.forgetPwd=Mot de passe oublié +user.directLogin=Se connecter avec un compte +user.moreLogin=Plus de façons de vous connecter +user.loginNow=Connectez-vous maintenant +user.registNow=Inscrivez-vous maintenant +user.backHome=Retour à l'accueil +user.ifHasAccount=Vous avez déjà un compte? +user.userEnabled=Le compte est désactivé ou pas encore activé! S'il vous plaît contacter l'administrateur +user.roleError=Le groupe de permissions n'existe pas, veuillez contacter l'administrateur +user.invalidEmail=Vous n’avez pas une adresse électronique valide, veuillez contacter l’administrateur pour le modifier. +user.codeRefresh=Cliquez sur Actualiser +user.emailVerify=Authentification boîte aux lettres +user.sendSuccess=Envoyé avec succès +user.sendFail=Envoi échoué +user.sendSuccessDesc=Code de vérification envoyé avec succès, s'il vous plaît aller voir +user.sendFailDesc=Échec d'envoi du code de vérification, veuillez contacter l'administrateur. +user.inputVerifyCode=S'il vous plaît entrer le code de vérification +user.getCode=Obtenir le code de vérification +user.inputPwd=S'il vous plaît entrer le mot de passe +user.inputPwdAgain=Veuillez entrer le mot de passe à nouveau +user.inputNickName=Veuillez entrer un pseudo +user.inputEmail=Veuillez entrer votre adresse email +user.inputPhone=S'il vous plaît entrez votre numéro de téléphone +user.inputPhoneEmail=S'il vous plaît entrer téléphone mobile / Email +user.invalidPhoneEmail=Téléphone / Email invalide +user.findPwd=Récupérer mot de passe +user.inputNotMatch=Le %s entré ne correspond pas à la limite +user.usingDesc=Vous utilisez +user.improveInfo=Veuillez compléter les informations +user.codeExpired=Le code de vérification a expiré, veuillez le récupérer à nouveau. +user.codeErrorTooMany=Trop d'erreurs de code de vérification, veuillez ré-acquérir +user.codeErrorFreq=La fréquence d'envoi est trop élevée, veuillez réessayer plus tard! +user.codeErrorCnt=Le nombre d'envois a dépassé la limite et sera verrouillé pendant %s heures. +user.registSuccess=Enregistré avec succès +user.waitCheck=En attente de l'examen de l'administrateur +user.nameHolder=Veuillez entrer votre numéro de téléphone / email +user.loginNoPermission=Désolé, vous n'avez pas cette permission, veuillez vous connecter avec un compte avec cette permission! +user.loginFirst=Vous n'êtes pas connecté! Veuillez vous connecter en premier +user.bindSignError=La signature est anormale, veuillez réessayer! +user.bindUpdateError=Échec de la mise à jour des informations utilisateur. Veuillez réessayer. +user.bindTypeError=Type de liaison non valide +user.bindWxConfigError=Obtention des informations de configuration d'exception +user.loginTimeout=La connexion actuelle a expiré, veuillez vous reconnecter! +user.theme=Style de thème +user.theme.desc=Système de suivi automatique des représentants +user.theme.light=Couleur claire +user.theme.dark=Couleur sombre +user.theme.auto=automatique +user.theme.title=Paramètres de thème personnalisés +user.theme.background=Le fond +user.theme.image=Des photos +user.theme.colorBlur=Dégradé de couleur +user.theme.imageBlur=Traitement du flou d'image +user.theme.imageUrl=Adresse de l'image +user.theme.colorStart=Couleur de départ +user.theme.colorEnd=Couleur finale +user.theme.colorRadius=Angle de dégradé +user.theme.themeImage=Image d'arrière-plan +user.theme.themeImageDesc=Support: URL de l'image, couleur dégradée css, suivre le fond d'écran +user.theme.imageWall=Suivre le papier peint +user.wall.random=Fond d'écran aléatoire +user.wall.paperDesktop=Fonds d'écran +user.wall.paperDeskMgt=Gestion du papier peint de bureau +user.wall.paperLoginMgt=Gestion des papiers peints de connexion +user.wall.paperLoginTips=Lorsqu'il y a plus d'une image, l'arrière-plan de l'interface de connexion tournera au hasard +log-type-create-mkdir=nouveau dossier +log-type-create-mkfile=créer un nouveau fichier +log-type-create-upload=télécharger des fichiers +log-type-create-copy=Coller le fichier +log-type-edit=Fichier de mise à jour +log-type-move=Déplacer le fichier +log-type-moveOut=Supprimer des fichiers +log-type-share-shareLinkAdd=Création d'un partage de lien externe +log-type-share-shareToAdd=Le partage collaboratif est activé +log-type-share-shareLinkRemove=Partage de liens fermés +log-type-share-shareToRemove=Désactiver le partage collaboratif +log-type-share-shareEdit=Modifier le partage +log-type-rename=Renommer +log-type-recycle-toRecycle=Passer à la corbeille +log-type-recycle-restore=Restaurer à partir de la corbeille +log-type-remove=supprimer +log-type-addDesc=Modifier la description +log-type-addComment=Poste un commentaire +log-event-create-mkdir=A créé ce dossier +log-event-create-mkfile=Créé le fichier +log-event-create-upload=Téléchargé le fichier +log-event-create-copy=Le fichier a été créé par collage +log-event-create-mkdir-current=Créé un nouveau dossier ici {0} +log-event-create-mkfile-current=Nouveau fichier créé ici {0} +log-event-create-upload-current=Téléchargé ici {0} +log-event-create-copy-current=Collé {0} ici +log-event-create-mkdir-item=Création d'un nouveau dossier dans {0} {1} +log-event-create-mkfile-item=Nouveau fichier créé dans {0} {1} +log-event-create-upload-item=Téléchargé {1} sur {0} +log-event-create-copy-item=Coller {0} à {1} +log-event-create-mkdir-more={0} dossiers créés ici +log-event-create-mkfile-more={0} nouveaux fichiers créés ici +log-event-create-upload-more={0} fichiers téléchargés ici +log-event-create-copy-more=Coller {0} fichiers ici +log-event-create-mkdir-more-at={1} nouveaux dossiers créés dans {0} +log-event-create-mkfile-more-at={1} nouveaux fichiers créés dans {0} +log-event-create-upload-more-at={1} fichiers téléchargés sur {0} +log-event-create-copy-more-at=Collé {0} documents dans {1} +log-event-view-item=Vu {0} +log-event-edit=mis à jour le fichier +log-event-edit-item=Modifier mis à jour {0} +log-event-edit-more=Modifier les fichiers {0} mis à jour +log-event-edit-more-user=Modification et mise à jour du fichier {0} {1} fois +log-event-edit-more-at=Fichiers {1} modifiés et mis à jour dans {0} +log-event-move=Déplacer le document de {0} à {1} +log-event-move-item=Déplacer {0} de {1} vers [3] +log-event-move-current=Déplacer {0} de {1} ici +log-event-move-more={0} documents déplacés +log-event-move-more-desc=Déplacer {0} de {1} vers [3] +log-event-moveOut-more-desc=Supprimé de {0} {1} +log-event-moveOut=Supprimé d'ici {0} +log-event-moveOut-item=Supprimé de {0} {1} +log-event-moveOut-more={0} documents supprimés +log-event-share-shareLinkAdd=Création d'un lien externe pour partager ce document +log-event-share-shareLinkAdd-item={0} a créé un lien externe à partager +log-event-share-shareLinkAdd-more=Création de {0} liens à partager +log-event-share-shareToAdd=Activer le partage collaboratif de ce document +log-event-share-shareToAdd-item={0} a activé le partage collaboratif +log-event-share-shareToAdd-more={0} partages collaboratifs créés +log-event-share-shareLinkRemove=Fermé le partage de liens du document +log-event-share-shareLinkRemove-item=Partage de lien fermé {0} +log-event-share-shareLinkRemove-more=Fermer {0} partage de liens externes +log-event-share-shareToRemove=Désactiver le partage collaboratif de ce document +log-event-share-shareToRemove-item=Désactiver le partage de collaboration pour {0} +log-event-share-shareToRemove-more=Fermer {0} partage collaboratif +log-event-share-shareEdit=Edité la part de ce document +log-event-share-shareEdit-item=Part éditée {0} +log-event-share-shareEdit-more=Documents édités {0} à partager +log-event-rename=Renommé le document +log-event-rename-item=Renommé {0} +log-event-rename-more={0} documents renommés +log-event-recycle-toRecycle=Déplacé le document dans la corbeille +log-event-recycle-toRecycle-current=Déplacé {0} dans la corbeille ici +log-event-recycle-toRecycle-item=Déplacé {1} dans la corbeille le {0} +log-event-recycle-toRecycle-more={0} documents déplacés vers la corbeille +log-event-recycle-toRecycle-more-at={1} documents ont été déplacés dans la corbeille le {0} +log-event-recycle-restore=Restaurer le document à partir de la corbeille +log-event-recycle-restore-item=Restaurer {0} à partir de la corbeille +log-event-recycle-restore-more=Restaurer {0} des documents à partir de la corbeille +log-event-remove=Supprimé {0} ici +log-event-remove-current=Supprimé {0} ici +log-event-remove-item=Supprimé {1} dans {0} +log-event-remove-more={0} documents supprimés ici +log-event-remove-more-at={1} documents supprimés le {0} +log-event-addDesc=Modification de la description du document +log-event-addDesc-item=Description du document {0} modifiée +log-event-addDesc-more=Description des documents {0} modifiés +log-event-addComment=Commenté ce document +log-event-addComment-item=A commenté {0} +log-event-addComment-more=Répertorié {1} commentaires dans {0} +log-event-fav-fileAdd=Favoris {0} +log-event-fav-dirAdd=Dossiers marqués d'un signet {0} +log-event-down-item=Téléchargé {1} depuis {0} +log-event-down-items=Téléchargé depuis {0} +log-event-recycle-del-item=Supprimer {0} des fichiers de la corbeille +log-event-recycle-rst-item=Restaurer {0} des fichiers à partir de la corbeille +log-event-del-item={0} fichiers supprimés +log.file.move=Déplacer / copier +log.file.fav=Fonctionnement des favoris +log.file.shareLink=Partage de lien externe +log.file.shareTo=Partage collaboratif +log.user.edit=Modifier les informations de compte +log.group.edit=Gestion du département +log.member.edit=Gestion des utilisateurs +log.role.edit=Gestion des rôles +log.auth.edit=Gestion des droits sur les documents +meta.user_sourceAlias=Fichiers associés (pièces jointes) +meta.user_fileEncodeType=Confidentialité des fichiers +meta.user_fileEncodeType.A=Un top secret +meta.user_fileEncodeType.B=B-confidentiel +meta.user_fileEncodeType.C=C-Secret +meta.user_sourceNumber=Numéro de volume +meta.user_sourceParticipant=Participant +explorer.fileInfo.createTime=Date de création +explorer.fileInfo.modifyTime=Date modifiée +explorer.fileInfo.softwareCreate=Logiciel de production +explorer.fileInfo.software=Logiciel de codage +explorer.fileInfo.playTime=Récréation +explorer.fileInfo.imageSize=taille de l'image +explorer.fileInfo.imageDpi=Résolution +explorer.fileInfo.imageBits=Peu profond +explorer.fileInfo.imageDesc=Annotation +explorer.fileInfo.imageAuthor=créateur +explorer.fileInfo.imageColor=Espace colorimétrique +explorer.fileInfo.cameraType=Modèle d'appareil +explorer.fileInfo.cameraApertureFNumber=Numéro d'ouverture +explorer.fileInfo.cameraApertureValue=Valeur d'ouverture +explorer.fileInfo.cameraShutterSpeedValue=Vitesse d'obturation +explorer.fileInfo.cameraExposureTime=Temps d'exposition +explorer.fileInfo.cameraFocalLength=distance focale +explorer.fileInfo.cameraFocusDistance=Distance de mise au point +explorer.fileInfo.cameraISOSpeedRatings=Sensibilité ISO +explorer.fileInfo.cameraWhiteBalance=balance des blancs +explorer.fileInfo.cameraUser=Manuel +explorer.fileInfo.cameraAuto=automatique +explorer.fileInfo.cameraExposureMode=Mode d'exposition +explorer.fileInfo.cameraExposureBiasValue=La compensation d'exposition +explorer.fileInfo.imageGps=Lieu de tournage +explorer.fileInfo.imageCreateTime=Date de tournage +explorer.fileInfo.audioChannel=Canal audio +explorer.fileInfo.audioChannel1=Mono +explorer.fileInfo.audioChannel2=stéréo +explorer.fileInfo.audioChannels=À canaux multiples +explorer.fileInfo.audioRate=Taux d'échantillonnage audio +explorer.fileInfo.audioBits=Profondeur de bits audio +explorer.fileInfo.audioBitrate=Bitrate audio +explorer.fileInfo.vedioFormat=Encodage vidéo +explorer.fileInfo.audioTitle=Titre +explorer.fileInfo.audioAuthor=Auteur +explorer.fileInfo.audioAlbum=Album +explorer.fileInfo.audioStyle=style +explorer.fileInfo.audioYear=Année de l'album +explorer.fileInfo.vedioSize=Taille de l'écran +explorer.fileInfo.vedioFrame=Frame rate vidéo +explorer.fileInfo.vedioBitrate=Bitrate vidéo +explorer.fileInfo.title=Titre +explorer.fileInfo.author=Auteur +explorer.fileInfo.pageTotal=pages totales +explorer.fileInfo.pageSize=Taille de la page +explorer.fileInfo.pagePower=Créateur de contenu +explorer.fileInfo.pdfVersion=Version PDF +explorer.filter.shareCopyLimit=Le nombre de fichiers à vider dépasse la limite ; le nombre maximum de fichiers que vous pouvez vider est : +explorer.filter.shareSizeLimit=La taille du fichier partagé dépasse la limite ; le maximum que vous pouvez partager est : +explorer.filter.unzipSizeLimit=La taille du fichier décompressé dépasse la limite ; le maximum que vous pouvez décompresser est : +explorer.filter.zipSizeLimit=La taille du fichier compressé dépasse la limite ; vos documents compressibles maximum : +explorer.filter.uploadSizeLimit=La taille de téléchargement dépasse la limite ; le maximum que vous pouvez télécharger est : +explorer.fileEditError=Le fichier actuel %s est en cours d'édition, réessayez plus tard +explorer.groupDelError=Désolé le dossier Département ne supporte pas la suppression +admin.info.typeDelError=Suppression échouée, avec sous - catégories ou données +admin.info.domainIdentifyError=Site non reconnu +admin.info.articleIdentifyError=Article non reconnu +admin.info.domainSupportError=Le site ne supporte pas la collecte +admin.info.fileTooLarge=Fichiers surdimensionnés +explorer.toolbar.info=Informations +source.shareDisabled=Ressources actuelles interdites de partage +admin.exceeds.limit=Au - delà des limites +admin.design.deleted=L'état activé ne peut pas être supprimé +admin.design.url.locked=L'URL actuelle est verrouillée et temporairement indisponible +explorer.SING_INVALID=Anomalie de signature +explorer.TEMP_AUTH_INVALID=Code d'autorisation temporaire invalide (invalidé) +explorer.QR_INVALID=Le Code QR est invalide +explorer.toolbar.toolbox=Boîte à outils +explorer.toolbox.desc= +logs-detail-mkdir=Nouveau dossier +logs-detail-mkfile=Nouveau fichier +logs-detail-editFile=Edit mis à jour +logs-detail-upload=Fichier téléchargé +logs-detail-uploadNew=Edité +logs-detail-file.upload=Téléchargé +logs-detail-file-copy=Coller crée le fichier +logs-detail-folder-copy=Coller crée un dossier +logs-detail-paste=Coller +logs-detail-from=À partir de +logs-detail-to=à +logs-detail-rename=Renommé +logs-detail-rename-file=Renommé le fichier +logs-detail-rename-folder=Renommé le dossier +logs-detail-user=Utilisateurs: +logs-detail-moveFrom-restore=Sera +logs-detail-moveTo-restore=Restauration à partir de la corbeille +logs-detail-move=Sera +logs-detail-moveTo=Déplacer vers +logs-detail-moveFrom-toRecycle=Sera +logs-detail-moveTo-toRecycle=Déplacé à la station de recyclage +logs-detail-file-toRecycle=Le fichier a été déplacé vers la corbeille +logs-detail-file-restore=Restaurer ce fichier de la corbeille +logs-detail-folder-toRecycle=Le dossier a été déplacé vers la corbeille +logs-detail-folder-restore=Restaurer le dossier de la corbeille +logs-detail-favAdd=La collection est +logs-detail-favDel=Collection annulée +logs-detail-unstar=Le nom: +logs-detail-moveOut=Enlevé +logs-detail-remove=Supprimé +logs-detail-file.copy=Collé +explorer.noPermissionAuthAll={0} ,Aucune autorisation pour cette action \ No newline at end of file diff --git a/src/main/resources/i18n/messages_it_IT.properties b/src/main/resources/i18n/messages_it_IT.properties new file mode 100644 index 0000000..2afd772 --- /dev/null +++ b/src/main/resources/i18n/messages_it_IT.properties @@ -0,0 +1,2563 @@ +admin.serverInfo=Informazioni sul server +admin.today=Oggi +admin.yesterday=Ieri +admin.weekDay=Ultimi 7 giorni +admin.monthDay=Ultimi 30 giorni +admin.ing=In corso +admin.paused=In pausa +admin.serverDownload=Download remoto +admin.memberManage=Gestione utenti +admin.fileManage=Gestione file +admin.pwdEdit=Cambia password +admin.fileEdit=Modifica file di salvataggio +admin.list=Vista elenco +admin.configError=Salvataggio della configurazione non riuscito, l'amministratore ha disabilitato questa autorizzazione +admin.userManage=Profilo +admin.manage=Gestione sistema +admin.pluginManage=Gestione plugin +admin.emailDear=Ciao %s, +admin.emailCodeText=Stai verificando il tuo indirizzo email. Il codice di verifica per questa richiesta è il seguente. Per garantire la sicurezza del tuo account, completa la verifica in tempo. +admin.emailVerifyInTime=Per proteggere la sicurezza del tuo account, completa la verifica in tempo. +admin.dear=caro +admin.dearUser=Gentile utente, +admin.emailResetLink=Stai reimpostando la password di accesso per %s via e-mail, fai clic sul link in basso per reimpostarla. Se il collegamento non salta, copiarlo nella barra degli indirizzi del browser per accedervi: +admin.emailExpireTime=Il collegamento scade dopo 20 minuti. +admin.jobName=Titolo di lavoro +admin.jobDesc=Descrizione del lavoro +admin.jobNameInput=Inserisci un nome lavoro +admin.jobEdit=Post editor +admin.menu.home=Home +admin.menu.dashboard=Panoramica +admin.menu.dashboardTitle=Panoramica delle statistiche +admin.menu.notice=Gestione delle notifiche +admin.menu.groupMember=Utenti e gruppi +admin.menu.member=Utenti e gruppi +admin.menu.role=Ruoli +admin.menu.job=Job +admin.menu.auth=Autorizzazioni +admin.menu.storage=Archiviazione +admin.menu.storageDriver=Archivi +admin.menu.plugin=Centro plugin +admin.menu.tools=Controllo di sicurezza +admin.menu.server=Gestione server +admin.menu.backup=Backups +admin.menu.share=Condivisioni +admin.menu.loginLog=Registro di accesso +admin.menu.log=Registro delle operazioni +admin.menu.task=Attività pianificate +admin.autoTask.restart=Riavvia le attività pianificate +admin.autoTask.restartEnd=L'attività pianificata è stata riavviata +admin.index.userSpace=Spazio utente +admin.index.groupSpace=Spazio gruppo +admin.index.folderCount=Numero di cartelle +admin.index.fileCount=Numero di file +admin.index.loginToday=Accessi di oggi +admin.index.useTotal=Utilizzo totale +admin.index.userLogin=Login utente +admin.index.spaceUsed=Occupa spazio +admin.index.useSpace=Spazio utilizzato +admin.index.usedSpace=Utilizzato +admin.index.freeSpace=Libero +admin.index.sizeLimit=Limite dimensioni +admin.index.vipCount=Utenti registrati +admin.index.loginCurrent=Attualmente online +admin.index.fileDel=Cancellati +admin.index.fileEdit=Modificati +admin.index.fileUpload=Upload +admin.index.fileDown=Download +admin.index.spaceUse=Utilizzato +admin.index.spaceSave=Salvataggi +admin.index.spaceUser=Usato dall'utente +admin.index.spaceGroup=Usato dal gruppo +admin.index.lastLogin=Ora dell'ultimo accesso +admin.index.totalUsers=Utenti totali +admin.index.loginUsers=Accessi utente +admin.index.spaceActUsed=Occupazione effettiva +admin.index.source=Fonte di accesso +admin.index.address=Indirizzo di accesso +admin.index.userInfo=Informazioni utenti +admin.index.userValid=Account validi +admin.index.userInvalid=Account non validi +admin.index.fileInfo=Informazioni sui file +admin.index.fileCnt=Numero di file +admin.index.fileAdd=Caricati oggi +admin.index.accInfo=Statistiche sui file +admin.index.accCnt=Numero di richieste +admin.index.accUser=Utenti serviti +admin.index.serverInfo=Informazioni di sistema +admin.index.serverDisk=Disco +admin.index.serverStore=Archiviazione +admin.index.serverName=Nome del server +admin.index.normal=Normale +admin.index.scoreDesc=I seguenti fattori influenzeranno il punteggio del sistema, che può essere ottimizzato per garantire il corretto funzionamento del sistema:
    1. Lo spazio rimanente del disco di sistema e dell'archiviazione su disco di rete;
    2. Metodo di memorizzazione nella cache dei dati (si consiglia il redis);
    Versione della piattaforma 3.php (php7 + a 64 bit consigliato). +admin.index.fileRatio=Panoramica utilizzo spazio +admin.setting.system=Impostazioni di sistema +admin.setting.account=Impostazioni account +admin.setting.theme=Impostazioni tema +admin.setting.wall=Impostazioni sfondo +admin.setting.stats=Statistiche di utilizzo +admin.setting.safeMgt=Gestione della sicurezza +admin.setting.base=Impostazioni di base +admin.setting.others=Altre impostazioni +admin.setting.sync=Sincronizza impostazioni +admin.setting.plugin=Impostazioni plugin +admin.setting.auth=Autorizzazioni +admin.setting.safe=Impostazioni di sicurezza +admin.setting.loginLog=Registro di accesso +admin.setting.loginDevice=Dispositivo di accesso +admin.setting.deviceType=Tipo di apparecchiatura +admin.setting.lastLoginTime=Ora dell'ultimo accesso +admin.setting.email=Impostazioni e-mail +admin.setting.user=Registrazione e login +admin.setting.pwdOld=Password originale +admin.setting.pwdNew=Modifica in +admin.setting.wallDiy=Sfondo personalizzato: +admin.setting.fav=Gestione dei preferiti +admin.setting.help=Aiuto +admin.setting.about=About +admin.setting.homePage=Home Kodcloud +admin.setting.subMenu=Sottomenu +admin.setting.menuName=Nome del menu +admin.setting.menuUrl=Indirizzo URL +admin.setting.menuUrlDesc=Indirizzo URL o codice JS +admin.setting.safeAccount=Sicurezza account e accesso +admin.setting.safeData=Sicurezza dati e trasmissione +admin.setting.passwordErrorLock=Blocco password +admin.setting.passwordErrorLockDesc=Dopo 5 tentativi di accesso falliti, l'account viene bloccato per 30 secondi. Utile per prevenire attacchi con metodi brute force +admin.setting.passwordRule=Forza password +admin.setting.passwordRuleDesc=Imposta la forza minima delle password utenti +admin.setting.passwordRuleNone=Nessuna +admin.setting.passwordRuleStrong=Media +admin.setting.passwordRuleStrongMore=Alta +admin.setting.passwordRuleNoneDesc=Nessuna forza password +admin.setting.passwordRuleStrongDesc=Lunghezza maggiore di 6 caratteri; Deve contenere sia lettere che numeri +admin.setting.passwordRuleStrongMoreDesc=Lunghezza maggiore di 6 caratteri; Deve contenere sia lettere che numeri; Deve contenere sia maiuscole e minuscole +admin.setting.passwordRuleTips=La tua password attuale non è abbastanza forte, si consiglia di cambiarla immediatamente +admin.loginCheck.menu=Controllo accesso +admin.loginCheck.ipCheck=Restrizione IP +admin.loginCheck.ipCheckNone=non limitato +admin.loginCheck.ipCheckAllow=Whitelist IP +admin.loginCheck.ipCheckDisable=Lista nera IP +admin.loginCheck.loginIpAllowDesc=Dopo l'apertura, solo gli utenti con l'ip specificato possono accedere, fai attenzione +admin.loginCheck.ipAllow=IP consentito +admin.loginCheck.ipAllowDesc=Completare le regole come segue (ogni riga, l'IP locale del server è consentito per impostazione predefinita e l'amministratore di sistema consente l'IP LAN) +admin.loginCheck.ipDisable=Regole IP nella lista nera +admin.loginCheck.ipDisableDesc=Dopo l'apertura, gli utenti che soddisfano le condizioni ip non saranno in grado di eseguire alcuna operazione, maneggiare con cautela!
    Se tutti sono specificati, tutte le richieste verranno bloccate! +admin.loginCheck.ipDescTitle=Compila le regole come segue (una riga per voce) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=priorità +admin.loginCheck.name=Nome regola +admin.loginCheck.user=Utente designato +admin.loginCheck.device=Attrezzatura designata +admin.loginCheck.deviceWeb=ragnatela +admin.loginCheck.devicePc=Lato PC +admin.loginCheck.deviceAndroid=Android +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc=
    Istruzioni per il controllo della restrizione dell'accesso utente (restrizioni IP e dispositivo):
  • Rileva in sequenza secondo l'ordine di priorità della regola; l'utente specificato dalla regola include l'utente attualmente connesso; quindi la regola viene determinata come risultato
  • Si consiglia di mettere i gruppi di utenti e gli utenti dipartimentali sul retro e specificare le impostazioni dell'utente sul davanti; (trascina e rilascia per regolare l'ordine)
  • +admin.setting.checkCode=Codice login +admin.setting.checkCodeDesc=Nella finestra di login sarà necessario inserire anche un codice di verifica generato casualmente +admin.setting.csrfProtect=Protezione CSRF +admin.setting.csrfProtectDesc=Può prevenire efficacemente gli attacchi CSRF +admin.setting.setRootPath=Accesso alla root +admin.setting.setRootPathDesc=Solo l'amministratore di sistema può accedere a tutte le directory.
    Se si desidera abilitare o disabilitare l'accesso per altri amministratori ad altre directory, bisogna modificare il parametro open_basedir cross-site di PHP. Guida +admin.setting.encode=Crittografia file +admin.setting.encodeAll=Crittografa tutto +admin.setting.encodeName=Mantieni l'estensione +admin.setting.encodeNone=Nessuna crittografia +admin.setting.encodeAllDesc=Crittografia completa: Crittografia sia il nome del file che l'estensione. Anche se si dispone delle autorizzazioni del server, non sarà possibile ottenere il contenuto reale del file. Aiuta a prevenire i danni causati dai ransomware +admin.setting.encodeNameDesc=Conserva estensione: Crittografia il nome del file ma conserva l'estensione. +admin.setting.encodeNullDesc=Nessuna crittografia: Il nome del file non viene crittografato. (Per garantire una maggiore sicurezza, le cartelle di caricamento hanno comunque una struttura crittografata) +admin.setting.encodeTips1=La modifica alla crittografia avrà effetto solo sui file caricati successivamente al salvataggio delle impostazioni +admin.setting.encodeTips2=Per evitare errori, non eliminare o rinominare i file in dati / file +admin.setting.encodeTips3=Al fine di competere con la concorrenza su larga scala, (la trasmissione, il raggruppamento, la distribuzione, l'espansione automatica e altre funzioni) la struttura delle cartelle viene registrata nel database. Tale struttura può essere importata e ripristinata copiando e incollando i file e cartelle +admin.setting.thirdLogin=Login di terze parti +admin.setting.thirdLoginDesc=Consenti la registrazione, l'associazione e l'accesso tramite account di terze parti +admin.setting.registOpen=Registrazione utenti +admin.setting.registOpenDesc=Per evitare conflitti di dati, la sincronizzazione dei dati di terze parti e la registrazione dell'utente non possono essere abilitate contemporaneamente +admin.setting.registCheck=Apri la recensione della registrazione +admin.setting.registCheckDesc=Dev'essere abilitato anche in [Utenti e Gruppi] affinché gli utenti registrati possano utilizzarlo +admin.setting.clearUserRecycle=Svuota tutti i cestini +admin.setting.clearCache=Cancella cache +admin.setting.icp=Copyright +admin.setting.icpDesc=Puoi anche inserire un link HTML +admin.setting.globalCss=CSS globale personalizzato +admin.setting.globalCssDesc=Il CSS personalizzato avrà effetto su tutte le pagine +admin.setting.globalHtml=Codice HTML statico +admin.setting.globalHtmlDesc=Il codice HTML verrà inserito in tutte le pagine. (Può essere usato un codice di terze parti) +admin.setting.dateFormat=Formato data +admin.setting.dateFormatDesc=Visualizzazione del formato della data ed orio, ora di modifica del file, ecc. +admin.setting.menu=Gestione dei menu +admin.setting.systemName=Nome sito +admin.setting.systemNameDesc=Imposta il titolo del sito +admin.setting.systemDesc=Sottotitolo del sito +admin.setting.pathHidden=Directory nascoste +admin.setting.pathHiddenDesc=Directory e file da nascondere, separati da virgole +admin.setting.defaultFolder=Cartelle di default +admin.setting.defaultFolderDesc=Cartelle separate da virgole +admin.setting.defaultApp=App di default +admin.setting.defaultAppDesc=Applicazioni predefinite separate da virgole +admin.setting.autoLogin=Login automatico +admin.setting.autoLoginDesc=L'utente di accesso predefinito è l'utente guest, assicurarsi che questo utente sia presente e abilitato +admin.setting.firstIn=Apri a login +admin.setting.registReviewOpen=Apri audit di registrazione: +admin.setting.registRoleEmpty=Il ruolo di autorizzazione non può essere vuoto +admin.setting.registNotSync= +admin.setting.registNeedRewiew=Dopo l'apertura, l'amministratore deve riesaminarlo e abilitarlo negli utenti e nei gruppi prima che gli utenti registrati possano utilizzarlo normalmente. +admin.setting.roleRight=Autorizzazioni di ruolo +admin.setting.emailHost=Indirizzo server +admin.setting.emailHostInput=smtp.server.com +admin.setting.emailHostTips=Si prega di inserire l'indirizzo del server di posta +admin.setting.emailHostDesc=Indirizzo completo del server SMTP da utilizzare per l'invio di email, la porta può essere personalizzata (il valore predefinito è 465) +admin.setting.emailSend=Indirizzo email +admin.setting.emailSendInput=email@domain.com +admin.setting.emailSendTips=Si prega di inserire l'indirizzo email di invio +admin.setting.emailSendDesc=È necessario abilitare il servizio POP3 / SMTP del server +admin.setting.emailPwd=Password +admin.setting.emailPwdTips=Password casella email di invio +admin.setting.secureType=Crittografia +admin.setting.emailSendTest=Test invio email +admin.setting.ensureEmailOk=Assicurati che la posta possa essere inviata normalmente +admin.setting.emailTo=Write-mail +admin.setting.emailGoToTips=Per favore, vai alla casella di posta +admin.setting.emailCheckTips=Vista +admin.setting.emailInputError=Impostazioni e-mail errate +admin.setting.emailPwdError=La password dell'impostazione e-mail non è corretta +admin.setting.emailDesc=Configura il server di posta per le email di registrazione utente e l'invio di link per il recupero password +admin.setting.sendEmail=Sistema invio email +admin.setting.sendEmailDesc=Predefinito: Usa la funzione di invio email di PHP; Personalizzato: Configura manualmente il server di posta +admin.setting.systemBackup=Backup del sistema +admin.setting.enableFunction=Funzioni varie +admin.setting.treeOpen=Cartelle nella directory laterale +admin.setting.treeOpenDesc=Cartelle abiliate nella direcotry ad albero laterale +admin.setting.groupListChild=Mostra sottogruppi +admin.setting.groupListChildDesc=Vengono mostrate le cartelle dei sottogruppi, le autorizzazioni vengono ereditate dal gruppo padre +admin.setting.groupRootListChild=Sottogruppi root +admin.setting.groupRootListChildDesc=Vengono mostrate le cartelle dei sottogruppi della directory di root (directory principale), le autorizzazioni vengono ereditate dal gruppo padre +admin.setting.shareToMeAllowTree=Mostra per struttura collaborazione +admin.setting.shareToMeAllowTreeTips=Dopo l'apertura, il supporto dei contenuti per la collaborazione con me è classificato in base alla struttura organizzativa del gruppo, che è adatta a situazioni in cui la struttura organizzativa è più complessa +admin.setting.groupTagAllow=Etichetta pubblica del gruppo +admin.setting.groupTagAllowTips=Dopo l'abilitazione, tutti i membri del gruppo saranno visibili dopo aver impostato l'etichetta pubblica per i file nel gruppo.L'amministratore del gruppo può mantenere il contenuto dell'etichetta. +admin.setting.shareToMeList=Mostra lista +admin.setting.shareToMeGroup=Mostra per struttura organizzativa +admin.setting.shareToMeUser=Mostra per condivisore +admin.setting.sysSrvState=Stato del server +admin.setting.sysSrvInfo=Informazioni sul server +admin.setting.sysPhpInfo=Informazioni PHP +admin.setting.database=Database +admin.setting.cache=Cache +admin.setting.sysMyInfo=Le mie informazioni +admin.setting.srvStateCpu=Uso della CPU +admin.setting.srvStateMem=Utilizzo della memoria +admin.setting.srvStateSrv=Spazio di archiviazione del server +admin.setting.srvStateDef=Spazio di archiviazione del disco +admin.setting.srvInfoName=Nome del server +admin.setting.srvInfoIp=IP del server +admin.setting.srvInfoTime=Orario del server +admin.setting.srvInfoUpTime=Tempo di esecuzione continuo +admin.setting.srvInfoWeb=Software +admin.setting.srvInfoPhpV=Versione PHP +admin.setting.srvInfoSys=Sistema +admin.setting.srvInfoPath=Percorso del sito +admin.setting.srvPhpDtl=Dettagli PHP +admin.setting.memLimit=Limite di memoria +admin.setting.postLimit=Limite di invio POST +admin.setting.uploadLimit=Limite upload file +admin.setting.execTime=Tempo massimo di esecuzione +admin.setting.inputTime=Tempo massimo di richiesta +admin.setting.disFunction=Funzioni disabilitate +admin.setting.phpExtSugst=Estensioni PHP consigliate +admin.setting.phpExtLoad=Estensioni caricate +admin.setting.myClientIp=Il mio IP +admin.setting.myClientUa=Il mio browser UA +admin.setting.myClientLng=La lingua del browser +admin.setting.disFuncDesc=Funzioni richieste dal sistema, si consiglia di abilitare +admin.setting.srvMemFree=Memoria rimanente +admin.setting.srvMemUse=Usa la memoria +admin.setting.srvCpuUse=Attualmente occupato +admin.setting.srvCpuFree=Inutilizzato +admin.setting.noLimit=Illimitato +admin.setting.disFunNo=No +admin.setting.systemCache=Cache di sistema +admin.setting.systemDb=Database di sistema +admin.setting.sysCacheTab=Cambia tipo cache +admin.setting.sysDbTab=Cambia tipo database +admin.setting.sysRecTab=Recupera database +admin.setting.cacheDesc=Descrizione cache +admin.setting.fileCacheDesc=File cache: Scrivere i dati di cache direttamente nei file sul disco, adatto per test o uso su piccola scala. +admin.setting.redisDesc=Redis: Un database non relazionale di valore-chiave ad alte prestazioni, adatto a situazioni di lettura e scrittura simultanee elevate. Consigliato. +admin.setting.memcachedDesc=Memcached: Un sistema di cache a oggetti di memoria distribuita ad alte prestazioni, adatto per letture simultanee elevate. +admin.setting.saveAfterTest=Può essere salvato solo se il test viene superato con successo +admin.setting.checkPassed=Passato +admin.setting.ifSaveCache=Dopo il passaggio, tutti i dati memorizzati nella cache verranno cancellati!
    Sei sicuro di voler eseguire? +admin.setting.ifSaveDb=Il cambio di database consiste nell'importare i dati del database di sistema corrente in un nuovo database e impostare il nuovo database come database di sistema. Sei sicuro di voler eseguire? +admin.setting.dbCurrent=Configurazione attuale +admin.setting.dbType=Tipo di database +admin.setting.dbName=Nome database +admin.setting.dbInfo=Informazioni sul database +admin.setting.dbSwitch=Cambia +admin.setting.dbSwitchDesc=Se abilitato, sarà possibile modificare il tipo di database in base alle proprie esigenze, operare con cautela. +admin.setting.dbTable=Tabelle +admin.setting.dbCnt=Totale +admin.setting.dbNeedNew=Il database esiste già, specificare nuovamente +admin.setting.dbInsertError=Impossibile scrivere i dati della tabella +admin.setting.dbNeedOthers=Seleziona un altro tipo di database +admin.setting.dbNeedChange=Modificare i parametri di configurazione +admin.setting.dbCreateError=Creazione del file di database non riuscita, controllare le autorizzazioni di lettura e scrittura della directory +admin.setting.dbTaskProcess=Avanzamento dell'esecuzione +admin.setting.dbTasking=Essere giustiziato +admin.setting.dbTaskDesc=Non chiudere la finestra e non eseguire altre operazioni per evitare che i dati vengano danneggiati. +admin.setting.recTaskDesc=Non chiudere la finestra al termine dell'operazione, questa sarà eseguita in backgroud fino al suo completamento. +admin.setting.dbCreate=Nuovo database +admin.setting.dbSelect=Leggi database +admin.setting.dbInsert=Scrivi nel database +admin.setting.dbSetSave=Salva le informazioni di configurazione +admin.setting.recDesc=Istruzioni per l'uso +admin.setting.recDescInfo11=Questa operazione ripristinerà i dati del sistema, il mancato funzionamento e la manutenzione o il relativo personale tecnico non dovrebbero operare! +admin.setting.recDescInfo21=Scrivendo il database di backup nel nuovo database e impostandolo come predefinito del sistema, si ottiene il ripristino dei dati. +admin.setting.recDescInfo22=I nuovi parametri di configurazione del database verranno aggiunti al file di configurazione del sistema config/setting_user.php Se il sistema è anomalo dopo l'esecuzione del ripristino, la parte aggiunta del file può essere rimossa senza influire sui dati di sistema precedenti. +admin.setting.recDescInfo23=Questa funzione supporta solo l'elaborazione dei dati di backup generati dalla gestione del backup del sistema e il database di cui si è eseguito il backup deve essere elaborato in altri modi. +admin.setting.recDescInfo31=Nota: quando il tipo di database è MySQL, verrà creata una nuova libreria (nome libreria originale_data corrente_ricostruzione) in base alle informazioni di configurazione correnti.Gli utenti non root potrebbero non disporre di autorizzazioni sufficienti, quindi è necessario impostare prima le autorizzazioni per l'utente. +admin.setting.recDescInfo32=Ad esempio, le informazioni di configurazione del database corrente sono: utente: kod; password: kod123. Utilizzare l'account root per accedere al database ed eseguire l'istruzione SQL corrispondente per impostare le autorizzazioni (le autorizzazioni possono essere revocate dopo che il test è stato superato e il ripristino è riuscito). +admin.setting.recDescInfo33=Impostazione delle autorizzazioni: +admin.setting.recDescInfo34=Revoca autorizzazioni: +admin.setting.recOpen=Attiva il ripristino +admin.setting.recOpenDesc=Dopo l'attivazione, è possibile selezionare il database di cui è stato eseguito il backup da ripristinare in base alle esigenze. Operare con cautela. +admin.setting.recTypeDesc=Dipende dal tipo di sistema attualmente utilizzato +admin.setting.recPath=Directory di backup del database +admin.setting.recPathErr=Directory di backup del database non valida +admin.setting.ifSaveRec=Il ripristino del database importerà i dati di backup nel nuovo database e lo imposterà come predefinito.
    Sei sicuro di volerlo eseguire? +admin.setting.recDiyPathErr=Quando si utilizza il backup automatico per il ripristino, selezionare il file del database di cui eseguire il backup +admin.setting.recDiyFileNull=Il file del database è vuoto +admin.setting.recDiyPhpErr=Per eseguire autonomamente il backup di SQLite, selezionare il file del database formattato come php +admin.setting.recDiySqlErr=Per eseguire autonomamente il backup di MySQL, selezionare il file di database formattato come sql +admin.setting.recSysPathErr=Quando si utilizza la gestione del backup per il ripristino, selezionare la directory del database di backup +admin.setting.recSysTbErr=La directory di backup del database non è valida o manca il file della struttura del database +admin.setting.recDbFileErr=Il file della libreria selezionato non corrisponde al sistema o manca una tabella dati valida +admin.setting.dbFileDown=Leggi il file della libreria +admin.setting.dbFileDownErr=Impossibile leggere il file della libreria +admin.notice.waiting=Aspettando la spinta +admin.notice.done=Eseguito +admin.notice.time=Data esecuzione +admin.notice.target=Invia a +admin.notice.level=Priorità +admin.notice.level0=Normale +admin.notice.level1=Alta +admin.notice.levelDesc=Normale: Viene visualizzato un punto rosso nella barra delle notifiche nell'angolo inferiore sinistro. Alta: Verrà visualizzats una finestra pop-up subito dopo che l'utente ha effettuato l'accesso. +admin.notice.targetAuth=Scegli di inviare a tutti o inviare a utenti, gruppi di utenti e gruppi di autorizzazioni specificati +admin.notice.title=Titolo messaggio +admin.notice.content=Contenuto +admin.notice.timeType=Metodo push +admin.notice.timeNow=Immediato +admin.notice.timePlan=Programmato +admin.notice.listTitle=Notifiche +admin.notice.clearAll=Svuota tutto +admin.notice.noMsg=Nessuna novità +admin.notice.ifClearAll=Sei sicuro di voler cancellare tutti i messaggi? +admin.group.role=Identità del ruolo +admin.group.name=Nome del gruppo +admin.group.parent=Gruppo superiore +admin.group.authShow=L'ambito della struttura organizzativa visibile ai membri del gruppo +admin.group.authShowAll=Tutti i gruppi +admin.group.authShowHide=Solo questo gruppo e sottogruppo +admin.group.authShowSelect=Gruppo designato +admin.group.authShowAllTips=Quando i membri di questo gruppo collaborano per condividere, possono selezionare tutti gli altri gruppi (e utenti) +admin.group.authShowHideTips=Quando i membri di questo gruppo collaborano e condividono, sono supportati solo il gruppo e il sottogruppo correnti (e gli utenti) +admin.group.authShowSelectTips=Quando i membri del gruppo collaborano e condividono, possono selezionare il gruppo designato e il sottogruppo (e l'utente), inclusi il dipartimento e il sottogruppo correnti +admin.group.addSub=Aggiungi sottosettore +admin.group.remove=Elimina gruppo +admin.group.switch=Dipartimento Migrazione +admin.group.swtichDesc=Esegui la migrazione di utenti e file dal dipartimento selezionato (e dai suoi sottoreparti) al dipartimento di destinazione. +admin.group.switchSameError=Il reparto di destinazione non può essere lo stesso del reparto selezionato +admin.group.switching=Migrazione, attendere... +admin.group.groupSwitching=Il reparto selezionato sta migrando +admin.group.parentNullError=Il gruppo superiore non può essere vuoto +admin.group.selected=Gruppo selezionato +admin.group.setSizeBatch=Imposta la dimensione dello spazio in batch +admin.group.multiSelect=È possibile selezionare più gruppi per l'impostazione batch +admin.group.ifDisAll=Tutti i sottogruppi verranno disabilitati. Sei sicuro di volerlo eseguire? +admin.member.manage=Utenti e gruppi +admin.member.add=Nuovo utente +admin.member.role=Ruolo utente +admin.member.group=Gruppo +admin.member.groupAdd=Aggiungi gruppo +admin.member.groupEdit=Modifica gruppo +admin.member.remove=Elimina utente +admin.member.import=Importa multipli +admin.member.enable=Abilita +admin.member.batchSet=Operazioni in blocco +admin.member.groupRemove=Rimuovi dal gruppo +admin.member.groupInsert=Aggiungi al gruppo +admin.member.groupSwitch=Sposta in altro gruppo +admin.member.groupTarget=Gruppo di destinazione +admin.member.groupReset=Ripristina gruppo +admin.member.groupSwtichDesc=Migra gli utenti selezionati dal gruppo corrente al gruppo di destinazione +admin.member.roleSet=Modifica autorizzazioni +admin.member.sizeSet=Modifica quota +admin.member.name=Account +admin.member.nickName=Nickname +admin.member.userInfo=Informazioni utente +admin.member.userImport=Importa utenti in blocco +admin.member.uploadFirst=Carica prima il file +admin.member.downTpl=Scarica modello +admin.member.downTplDesc=, Compila il formato del modello e carica. +admin.member.uploadInvalid=Non ci sono dati validi nel file caricato, controlla e carica di nuovo +admin.member.uploadDataInvalid=I dati di caricamento non sono validi o scaduti, si prega di caricare di nuovo +admin.member.importSuccess=Importazione completata +admin.member.importFail=Importazione non riuscita +admin.member.importFailDesc=Successo: {0}; Falliti: {1} +admin.member.importName=Account di accesso (richiesto, unico) +admin.member.importNickName=Soprannome (unico) +admin.member.importPwd=Password (richiesta) +admin.member.importSex=Sesso (maschio-1, femmina-0) +admin.member.importPhone=Numero di cellulare (unico) +admin.member.importEmail=E-mail (unica) +admin.member.groupRemoveTips=Gli utenti di questo gruppo di utenti non possono accedere dopo l'eliminazione
    (È necessario reimpostare il gruppo utenti), sei sicuro di voler continuare? +admin.member.memberRemoveTips=Dopo l'eliminazione, la directory dell'utente verrà spostata nel cestino del sistema,
    Sei sicuro di voler continuare? +admin.member.selectUserTips=Si prega di selezionare l'account per operare +admin.member.ifRemoveGroup=Sei sicuro di voler rimuovere gli utenti selezionati da questo gruppo? +admin.member.importDesc=Un utente per riga,
    Ignora automaticamente se esiste già +admin.member.roleAdminTips=Nota: Le autorizzazioni dell'amministratore di sistema non possono essere modificate +admin.member.space=Imposta la dimensione dello spazio utente +admin.member.spaceTips=0 = illimitato +admin.member.spaceTipsDefault=(GB) 0 non è limitato +admin.member.spaceTipsFull=Illimitato +admin.member.spaceSize=Spazio riservato +admin.member.spaceSizeUse=Uso totale dello spazio +admin.member.memberAdd=Aggiungi utente +admin.member.allAdd=Aggiungi utente o gruppo +admin.member.nullNotUpdate=Lascia vuoto +admin.member.search=Cerca utenti (Account / Nickname / Email / Telefono) +admin.member.searchUser=Cerca utenti (Supporta corrispondenza approssimata) +admin.member.searchGroup=Cerca gruppo (Supporta corrispondenza approssimata) +admin.member.searchAll=Cerca utenti o gruppi (Supporta corrispondenza approssimata) +admin.member.editNoAuth=Spiacenti, non hai questo permesso,
    Solo gli amministratori di sistema possono aggiungere e modificare amministratori di sistema +admin.member.disabledUsers=Account disabilitato +admin.member.disabledTips=Cambia gruppi per deselezionare +admin.member.userGroup=Gruppo utenti +admin.member.userRole=Ruolo dell'utente +admin.member.userSelected=Utenti selezionati +admin.member.authCopy=Copia autorizzazioni del gruppo +admin.member.authPaste=Incolla il permesso del gruppo +admin.member.ifAuthPaste=Sei sicuro di voler impostare le autorizzazioni del gruppo copiate per l'utente corrente? +ERROR_USER_NOT_EXISTS=L'utente non esiste +ERROR_USER_PASSWORD_ERROR=Password errata +ERROR_USER_EXIST_NAME=Il nome utente esiste già +ERROR_USER_EXIST_PHONE=Il numero di telefono esiste già +ERROR_USER_EXIST_EMAIL=La cassetta postale esiste già +ERROR_USER_EXIST_NICKNAME=Nickname già esistente +ERROR_USER_LOGIN_LOCK=Siamo spiacenti, ci sono troppi tentativi di password e l'account corrente è bloccato. Riprova tra 1 minuto! +ERROR_IP_NOT_ALLOW=Il tuo attuale IP o dispositivo di accesso non è autorizzato ad accedere, contatta l'amministratore! +user.passwordCheckError=Il formato della password non soddisfa le regole di sicurezza della password! +admin.role.administrator=Amministratore +admin.role.group=Amministratore di gruppo +admin.role.default=Utente generale +admin.role.ignoreExt=Limitazioni di estensione +admin.role.ignoreExtDesc=Tipi di file che non possono essere caricati, non ci sono restrizioni per il vuoto +admin.role.ignoreFileSize=Limite upload +admin.role.ignoreFileSizeDesc=Caricamento massimo file singolo. [0 = illimitato] +admin.role.ignoreExtTips=Spiacenti, le impostazioni di sistema correnti non supportano l'upload di questo tipo di file. Per ulteriori dettagli, contatta l'amministratore +admin.role.ignoreFileSizeTips=Siamo spiacenti, quando il file supera il limite di dimensioni; si prega di contattare l'amministratore per i dettagli! +admin.role.desc=Descrizione +admin.role.adminDesc=Super amministratore, dispone dei diritti di gestione del server; tutte le impostazioni di file e cartelle non sono valide per questo utente! +admin.role.read=Leggi +admin.role.readList=Elenco dei file +admin.role.readInfo=Vista attributo file (cartella), ricerca cartelle +admin.role.readCopy=Copia del file +admin.role.readPreview=Anteprima file (immagini, documenti, audio e video, ecc.) +admin.role.readDownload=Download di file (cartella) +admin.role.write=Scrivi +admin.role.writeAdd=Crea file (cartelle), comprimi e decomprimi file +admin.role.writeChange=Rinomina, regola la struttura della directory +admin.role.writeUpload=Caricamento file (cartella), download remoto +admin.role.writeRemove=File (cartella) cancella, taglia +admin.role.adminSetDesc=L'amministratore di sistema ha tutte le autorizzazioni, non è necessario impostare! +admin.role.displayDesc=Se visualizzare quando si impostano i ruoli utente +admin.role.defaultRoleDesc=Suggerimento: Il sistema ha ruoli di default che non supportano la modifica delle autorizzazioni. Per la personalizzazione, puoi creare nuovi ruoli +admin.role.actionSetTitle=Permessi sui file +admin.role.userSetTitle=Impostazioni utente +admin.role.adminSetTitle=Amministrazione +admin.role.fileAdd=Nuovo (file / Cartella) +admin.role.fileRemove=Elimina +admin.role.fileMove=Sposta (Copia / Taglia / Incolla / Sposta) +admin.role.userConfig=Modifica configurazione (Imposta avatar / Cambia password, ecc.) +admin.role.userEdit=Modifica utente (Aggiungi / Modifica / Elimina) +admin.role.userFav=Gestione Preferiti +admin.role.itemEdit=Aggiungi / Modifica / Elimina +admin.role.groupEdit=Modifica gruppo (Aggiungi / Modifica / Elimina) +admin.role.delErrTips=Questo ruolo ha uno o più utenti associati quindi non può essere eliminato +admin.authFrom.setUser=Specifica i tuoi permessi +admin.authFrom.setGroup=Specificare le autorizzazioni del gruppo +admin.authFrom.setAll=Altri permessi utente +admin.authFrom.groupAt=Autorizzazioni del gruppo +admin.authFrom.groupParent=Autorizzazioni del gruppo superiore +admin.authFrom.pathOnly=Solo accesso, il livello inferiore ha contenuto e autorizzazione +admin.authFrom.groupRoot=Directory principale del gruppo +admin.auth.owner=Amministratore +admin.auth.editor=Editore +admin.auth.editUploader=Modificatore / Uploader +admin.auth.viewer=Visualizzatore +admin.auth.previewer=Spettatore +admin.auth.uploader=Uploader +admin.auth.invisible=Invisibile +admin.auth.user=Dati dell'utente +admin.auth.pathDelete=Cancellazione dei file +admin.auth.pathInfo=Attributi del file +admin.auth.pathMove=Sposta (Copia / Taglia / Incolla / Sposta) +admin.auth.canUpload=Upload consentito +admin.auth.config=Dati di configurazione +admin.auth.fav=Operazione Preferiti (Aggiungi / Modifica / Elimina) +admin.auth.extWarning=Il caricamento di tali file non è consentito,
    Rinomina (rinominato nell'estensione specificata),
    Modifica salvataggio, download remoto, decompressione +admin.auth.error=Errore ruolo autorizzazione (nessuna impostazione di autorizzazione) +admin.auth.errorAdmin=Autorità insufficiente +admin.auth.targetError=Il tipo di oggetto autorizzazione è errato, deve essere utente o gruppo +admin.auth.errorAuthToGroup=Un gruppo secondario non supporta la delega ai gruppi +admin.auth.errorAuthToUsers=Settore non root, non supporta la delega a membri esterni al settore +admin.auth.displayDesc=Visualizzare nell'elenco autorizzazioni +admin.auth.defaultAuthDesc=Suggerimento: il sistema ha un gruppo di autorizzazioni integrato per impostazione predefinita e non supporta la modifica delle autorizzazioni. È possibile creare nuovi gruppi di autorizzazioni +admin.auth.show=Elenco file +admin.auth.showAction=Visualizza i file +admin.auth.view=Anteprima +admin.auth.viewAction=Visualizza anteprima file +admin.auth.download=Download e copia +admin.auth.downloadAction=Download / Copia / Visualizza anteprima file +admin.auth.uploadAction=Caricamento di file e cartelle / Download remoto +admin.auth.edit=Modifica +admin.auth.editAction=Nuovo file o cartella / Rinomina / Incolla / Modifica / Aggiungi note / Crea copia / Decomprimi +admin.auth.removeAction=Taglia / Sposta +admin.auth.shareAction=Condivisione esterna / Collaborazione con altri utenti +admin.auth.comment=Commenti +admin.auth.commentAction=Visualizza i commenti / Commanta / Elimina i tuoi commenti (è richiesta l'autorizzazione alla modifica) +admin.auth.event=Eventi dei file +admin.auth.eventAction=Visualizzazione eventi file / Sottoscrizione eventi +admin.auth.root=Autorizzazioni amministrative +admin.auth.rootAction=Assegna autorizzazioni utente / Gestione commenti / Gestione versioni cronologia +admin.auth.delErrTips=Questa autorizzazione è in uso e non può essere cancellata! +admin.plugin.center=Centro plugin +admin.plugin.installed=Installato +admin.plugin.type=classificazione +admin.plugin.typeFile=Elaborazione file +admin.plugin.typeSafe=Strumenti di sicurezza +admin.plugin.typeTools=Utilità +admin.plugin.typeMedia=Multimedia +admin.plugin.typeCompany=Enterprise +admin.plugin.typeOem=Personalizzati +admin.plugin.needNetwork=Extranet +admin.plugin.install=Installa il plugin +admin.plugin.enable=Abilita plugin +admin.plugin.remove=Disinstalla plugin +admin.plugin.config=Configura plugin +admin.plugin.statusEnabled=Abilitato +admin.plugin.statusDisabled=Non abilitato +admin.plugin.statusNotInstall=Non installato +admin.plugin.installing=Installazione in corso ... +admin.plugin.hasUpdate=aggiornamenti +admin.plugin.updateStart=Aggiorna plugin +admin.plugin.needConfig=Richiede la configurazione iniziale per abilitare +admin.plugin.notNull=I campi obbligatori non possono essere vuoti! +admin.plugin.auther=autore +admin.plugin.downloadNumber=installazioni +admin.plugin.back=Indietro +admin.plugin.detail=Descrizione +admin.plugin.resetConfig=Ripristina le impostazioni predefinite +admin.plugin.installSelf=Installazione manuale +admin.plugin.updateSelf=Aggiornamento manuale +admin.plugin.updateAll=Aggiorna tutto +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=Errore di rete. Verificare se il server può accedere a Internet. +admin.plugin.auth=Autorizzazioni +admin.plugin.authDesc=Autorizza tutti oppure specifica utenti, gruppi o ruoli +admin.plugin.authOpen=Accesso aperto +admin.plugin.authOpenDesc=È possibile accedervi senza login, può essere utilizzato per chiamate di interfaccia esterne +admin.plugin.authAll=Tutti +admin.plugin.authUser=Utente +admin.plugin.authGroup=Gruppo +admin.plugin.authRole=Ruolo +admin.plugin.openWith=Apri come ... +admin.plugin.openWithDilog=Dialogo interno +admin.plugin.openWithWindow=Apri in una nuova finestra +admin.plugin.fileSort=Priorità dell'associazione di estensione +admin.plugin.fileSortDesc=Maggiore è l'estensione, maggiore è la priorità +admin.plugin.fileExt=Formati di file supportati +admin.plugin.fileExtDesc=Associa l'estensione al plugin +admin.plugin.tabServer=Configurazione del server +admin.plugin.defaultAceEditor=Editor di testo +admin.plugin.defaultHtmlView=Anteprima Web +admin.plugin.defaultZipView=Decompressione online +admin.plugin.authViewList=Elenco di plugin +admin.plugin.authStatus=Apri Chiudi +admin.plugin.authInstall=Installa / Disinstalla +admin.plugin.disabled=Il plugin non esiste o non è stato avviato +admin.plugin.menuAdd=Se aggiungere al menu principale +admin.plugin.menuAddDesc=Utilizzare come applicazione autonoma +admin.plugin.menuSubMenuDesc=Riduci nel menu [Altro] +admin.storage.type=Tipo archiviazione +admin.storage.local=locale +admin.storage.localStore=Archiviazione locale +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=Sette nuvole di mucca +admin.storage.s3=Amazon S3 +admin.storage.ftp=FTP +admin.storage.oos=Tianyi Cloud OOS +admin.storage.moss=Hongshan MOSS +admin.storage.eos=XSKY EOS +admin.storage.nos=Ex cloud NOS +admin.storage.minio=MinIO +admin.storage.uss=Prendi un'altra nuvola USS +admin.storage.eds=Sangfor EDS +admin.storage.driver=Disco locale +admin.storage.useage=Utilizzo dello spazio +admin.storage.default=Predefinito +admin.storage.current=Attuale +admin.storage.edit=Memoria di configurazione +admin.storage.setConfig=Modifica configurazione +admin.storage.moveData=Migrare i dati +admin.storage.delStore=Smonta spazio di archiviazione +admin.storage.ifMove=Questo spazio di archiviazione contiene {0} file del disco di rete e verrà migrato allo spazio di archiviazione predefinito corrente. Continuare? +admin.storage.ifDel=Sei sicuro di voler smontare il negozio corrente? +admin.storage.ifDelWithFile=Questa memoria contiene {0} file del disco di rete, che verranno migrati nella memoria predefinita corrente una volta eliminati. Continuare? +admin.storage.sysFile=File del disco di rete: file nello spazio personale e nei reparti +admin.storage.delErrTips=Operazione riuscita:%s; Errore:%s, riprovare o migrare manualmente +admin.storage.delLocTips=Tieni almeno un negozio locale +admin.storage.delStoreTips=Questa memoria contiene dati di backup, elaborali prima di procedere! +admin.storage.nameDesc=Nome dell'archiviazione +admin.storage.path=Directory +admin.storage.pathLocDesc=Directory dove verranno archiviati i file, assicurarsi che disponga delle autorizzazioni di lettura e scrittura +admin.storage.pathDesc=Directory iniziale +admin.storage.defaultDesc=Se abilitato, diventerà lo spazio di archiviazione predefinito. Quello attuale verrà dismesso. (Procedere con cautela) +admin.storage.forceEdit=Modifica obbligatoria +admin.storage.editTips=Abilita modifica impostazioni. Attenzione! I file già caricati potrebbero non essere più accessibili +admin.storage.folderTips=L'attuale posizione di archiviazione del file di sistema, si prega di operare con cautela +admin.storage.sizeTips=La dimensione dello spazio deve essere maggiore di 0 +admin.storage.sizeDesc=Compilare in base allo spazio libero effettivo della directory di archiviazione selezionata (GB) +admin.storage.region=Area di stoccaggio +admin.storage.domain=Nome dominio spaziale +admin.storage.bucket=Nome del secchio +admin.storage.bucketDesc=Nome della benna inserito durante la creazione dello spazio +admin.storage.userName=Nome dell'account +admin.storage.userPwd=Password +admin.storage.server=Indirizzo del server +admin.storage.serverDesc=FTP(S)://IP, il protocollo FTP è facoltativo +admin.storage.refer=Riferimento: +admin.storage.endpoint=Endpoint +admin.storage.ossDomain=Nome di dominio associato nello spazio OSS +admin.storage.ossKeyDesc=Accedi all'ID chiave dell'account Alibaba Cloud, crea o visualizza in [Pannello di controllo-Gestione chiavi di accesso] +admin.storage.ossSecretDesc=Accedi al segreto chiave dell'account Alibaba Cloud +admin.storage.ossEndpoint=Endpoint, se utilizzi un nodo Intranet, devi abilitare il trasferimento del server +admin.storage.cosKeyDesc=Accedi all'ID chiave dell'account Tencent Cloud, crea o visualizza in [Pannello di controllo-Gestione accesso-Gestione chiavi API] +admin.storage.cosSecretDesc=Accedi al segreto chiave dell'account Tencent Cloud +admin.storage.qiniuDomain=Nome di dominio associato da Qiniu Space +admin.storage.qiniuKeyDesc=Chiave di accesso per l'account Qiniu, creare o visualizzare in [Pannello di controllo-Centro personale-Gestione chiavi] +admin.storage.qiniuSecretDesc=Chiave segreta per l'account Qiniu, il metodo per ottenere è lo stesso di cui sopra +admin.storage.qnz0=Cina orientale - Zhejiang +admin.storage.qnz02=Cina orientale - Zhejiang 2 +admin.storage.qnz1=Cina del Nord - Hebei +admin.storage.qnz2=Cina meridionale - Guangdong +admin.storage.qnna0=Nord America - Los Angeles +admin.storage.qnas0=Asia Pacifico - Singapore +admin.storage.qnas02=Asia Pacifico - Seul +admin.storage.awsDomain=Nome di dominio associato nello spazio AWS +admin.storage.awsKeyDesc=Accedi all'ID chiave dell'account AWS, crealo in [Pannello di controllo - Le tue credenziali di sicurezza] +admin.storage.awsSecretDesc=Accedi a Key Secret per l'account AWS +admin.storage.oosDomain=Nome di dominio associato a Tianyi Cloud Space +admin.storage.oosKeyDesc=Accedi all'ID chiave dell'account Tianyi Cloud, crealo in [Pannello di controllo - Le tue credenziali di sicurezza] +admin.storage.oosSecretDesc=Il segreto della chiave di accesso dell'account cloud Tianyi è lo stesso di cui sopra +admin.storage.ftpDisabled=FTP non è disponibile, si prega di abilitare l'estensione php_ftp +admin.storage.ifDefaultTips=Questa operazione annullerà altri metodi di archiviazione predefiniti. +admin.storage.spaceUsed=Uso pratico +admin.storage.spaceLave=Importo residuo +admin.storage.delError=Il file esiste già in questo archivio e non può essere eliminato +admin.storage.corsError=Se la configurazione è corretta, fare clic su [Use Help] per controllare le impostazioni cross-domain del bucket. +admin.storage.saveError=Impossibile connettersi all'archivio specificato, controllare se le informazioni di configurazione sono corrette. +admin.storage.ftpCharset=Codifica server +admin.storage.ftpCharsetDesc=Se il server FTP è Windows, può essere impostato su GBK +admin.storage.ftpPasvOn=ON +admin.storage.ftpPasvOff=OFF +admin.storage.ftpPasv=Modalità passiva +admin.storage.ftpPasvDesc=Modalità di trasferimento dati +admin.storage.uploadSrv=Trasferimento del server (caricamento) +admin.storage.fileoutSrv=Trasferimento server (download) +admin.storage.uploadSrvDesc=Dopo l'accensione, il file verrà caricato nell'object storage tramite il server; in caso contrario, verrà caricato direttamente tramite il client. +admin.storage.fileoutSrvDesc=Dopo l'accensione, il file di archiviazione verrà ottenuto tramite il server per il download; in caso contrario, il file verrà ottenuto per il download diretto. +admin.storage.closeDefError=Proibisci la disattivazione della memoria predefinita +admin.storage.ussBucket=Nome di Servizio +admin.storage.ussBucketDesc=Nome del servizio di archiviazione cloud +admin.storage.ussUser=Nome operatore +admin.storage.ussUserDesc=Nome operatore +admin.storage.ussUserPwd=Password operatore +admin.storage.ussDomain=Scatta un'altra foto del nome di dominio associato allo spazio cloud +admin.storage.ussToken=Token +admin.storage.ussTokenDesc=Chiave segreta della catena antifurto token (non richiesta) +admin.storage.configError=Il parametro di configurazione è anomalo! +admin.storage.sizePercent=Rapporto file di sistema: +admin.storage.fileCount=Numero di file: +admin.storage.error=Eccezione di archiviazione +admin.task.name=Nome dell'attività +admin.task.edit=Modifica attività +admin.task.type=Tipo di attività +admin.task.method=Metodi integrati +admin.task.methodName=Nome del metodo +admin.task.methodDesc=Nome del metodo del modulo di sistema, compilare con cura +admin.task.url=Indirizzo URL +admin.task.urlDesc=Indirizzo della risorsa da interrogare +admin.task.cycle=Ciclo esecuzione +admin.task.desc=Descrizione +admin.task.nMinutes=N minuti +admin.task.default=Sistema predefinito +admin.task.timeInterval=Tempo di intervallo +admin.task.timeStart=Ora di inizio +admin.task.timeStartRun=Inizia il tempo di esecuzione +admin.task.timeLastRun=Ultima esecuzione +admin.task.timeLastLogin=Ultimo accesso +admin.task.isOpen=Abilita +admin.task.open=Apri +admin.task.content=Contenuto +admin.task.param=Parametro di esecuzione +admin.task.ifRun=Sei sicuro di voler eseguire questa attività? +admin.task.backup=backup dei dati +admin.task.backupDesc=Inizia il backup dei dati di sistema ogni giorno alle 02:00. +admin.install.install=Installazione +admin.install.databaseSet=Configurazione database +admin.install.dataUpdate=Migrazione dei dati +admin.install.installSuccess=Installato correttamente +admin.install.dbWasSet=Hai configurato il database. Se devi reimpostare, puoi modificare la configurazione nel file config / setting_user.php e reinstallarlo! +admin.install.errorRequest=Il sistema è installato, non sono consentite ulteriori richieste +admin.install.databaseError=Errore di connessione al database, si prega di controllare la configurazione +admin.install.cacheError=%s connessione fallita, controlla la configurazione +admin.install.cacheConnectError=%s non riesce a connettersi al server, controlla la configurazione +admin.install.dbSetError=Scrittura delle informazioni di configurazione del database non riuscita +admin.install.dbCreateTips=Il database non esiste e la creazione automatica non riesce. Crearla manualmente +admin.install.ifDelDb=I dati esistono già nel database specificato Fare clic su [OK] per eliminarli. Vuoi continuare? +admin.install.dbCreateError=Eccezione per la creazione di tabelle di dati +admin.install.dbFileError=Il file di database non esiste +admin.install.dbTypeError=Il tipo di database selezionato (%s) non è disponibile, installa il servizio e l'estensione corrispondenti o scegli un altro tipo +admin.install.createSuccess=Creato con successo +admin.install.defSetError=Impossibile aggiungere la configurazione predefinita del sistema +admin.install.defStoreError=Aggiunta di archiviazione predefinita non riuscita +admin.install.defPathError=Aggiunta della directory di sistema non riuscita +admin.install.defAdminError=Impossibile aggiungere l'account amministratore +admin.install.defRoleError=Aggiunta di ruolo predefinita non riuscita +admin.install.defGroupError=Aggiunta del gruppo di sistema non riuscita +admin.install.dataPathNotExists=la directory dei dati non esiste +admin.install.defaultUpdate=Aggiornamento delle informazioni sulla configurazione del sistema +admin.install.pluginUpdated=Aggiornamento del plugin completato +admin.install.defCacheError=Eccezione dati cache directory iniziale +admin.install.serverDir=Server column directory +admin.install.dirRight=Autorizzazioni sulle directory +admin.install.suggestOpen=Si consiglia di abilitare +admin.install.suggestClose=Si consiglia di disabilitare +admin.install.phpVersionTips=PHP 5.3 e versioni successive +admin.install.phpBitTips=Consigliato 64 bit +admin.install.phpBitDesc=I sistemi a 32 bit non supportano il caricamento e il download di file oltre 2GB +admin.install.pathNeedWirte=La directory del programma e tutte le sottodirectory devono essere leggibili e scrivibili +admin.install.mustOpen=Dev'essere abilitato +admin.install.setPathWrt=Imposta i permessi di lettura e scrittura per la directory del progetto +admin.install.ensureNoError=Assicurarsi che quanto segue sia corretto: +admin.install.setAdminName=Configura un account amministratore +admin.install.setAdminPwd=Si prega di impostare una password amministratore +admin.install.database=Database +admin.install.dbType=Database +admin.install.dbName=Nome del database +admin.install.userName=Nome utente +admin.install.dbPort=Porta +admin.install.dbPortDesc=La porta predefinita è 3306 ma può essere personalizzata come da esempio: 127.0.0.1:3307 +admin.install.dbEngine=Motore di archiviazione +admin.install.sqliteDesc=PHP ha un database incorporato, leggero versatile (adatto per test o uso su piccola scala). +admin.install.mysqlDesc=Supporta la distribuzione di cluster, la separazione di database master e slave. +admin.install.pdoDesc=Un tipo database più sicuro ma richiede che l'estensione PDO sia abilitata nel PHP. +admin.install.cacheType=Cache di sistema +admin.install.cacheTypeDesc=Utilizzato per memorizzare nella cache dati generali e sessioni di sessione per accelerare l'accesso al sistema +admin.install.fileCache=Cache dei file +admin.install.groupFile=Documento del gruppo +admin.install.userFile=Documentazione per l'utente +admin.install.role=ruolo +admin.install.fileAuth=Autorizzazioni per file +admin.install.userList=Elenco utenti +admin.install.setInfo=Informazioni sulla configurazione del sistema +admin.install.favShare=Preferiti e condivisioni dell'utente +admin.install.waitUpdate=In attesa di aggiornamento +admin.install.updateSuccess=Aggiornamento riuscito +admin.install.fileCount=Numero di file +admin.install.settingDesc=Gli elementi di errore possono essere configurati manualmente nella gestione in background +admin.install.reInstallTips=Il risultato della restituzione è anormale, reinstallare +admin.log.accountEdit=Modifica le informazioni dell'account +admin.log.thirdBind=Associa un account di terze parti +admin.log.delBind=sciogliere +admin.log.viewFile=file di anteprima +admin.log.delFile=Elimina il file +admin.log.editFile=Modifica file +admin.log.downFile=File scaricato +admin.log.downFolder=Cartella scaricata +admin.log.moveFile=File spostato +admin.log.addUser=Nuovo utente +admin.log.editUser=Utente modificato +admin.log.addUserTo=Utente assegnato al gruppo +admin.log.removeUserFrom=Utente rimosso dal gruppo +admin.log.switchUserGroup=Migrazione degli utenti ai gruppi +admin.log.stausUser=Utente abilitato / disabilitato +admin.log.addRole=Nuovo ruolo +admin.log.editRole=Ruolo modificato +admin.log.delRole=Ruolo eliminato +admin.log.addAuth=Autorizzazioni aggiunte +admin.log.editAuth=Autorizzazioni modificate +admin.log.delAuth=Autorizzazioni eliminate +admin.log.editShare=Condivisione modificata +admin.log.delLinkTo=Condivisione esterna annullata +admin.log.delShareTo=Condivisione collaborativa annullata +admin.log.recycleTo=Spostato nel cestino +admin.log.newName=Nuovo nome +admin.log.oldName=Nome originale +admin.log.newPath=Nuova directory +admin.log.oldPath=Directory originale +admin.log.typeFile=Operazioni sui file +admin.log.typeUser=Configurazione utente +admin.log.queryByIp=Fare clic sul pulsante per interrogare i record di registro del giorno in base all'IP. +admin.backup.setting=Impostazioni +admin.backup.edit=Modifica del backup +admin.backup.ing=Backup +admin.backup.success=Backup riuscito +admin.backup.fail=Backup fallito +admin.backup.complete=Backup completato +admin.backup.db=Database +admin.backup.dbFile=File database +admin.backup.fileError=Backup di alcuni file non riuscito +admin.backup.checkLog=Si prega di controllare il registro di backup: data/temp/log/backup/date of the day__log.php +admin.backup.pathNoWrite=La directory temporanea non dispone dell'autorizzazione di scrittura +admin.backup.errorMsg=Parte del backup del file non è riuscita, è possibile copiare manualmente in base al registro oppure eliminare ed eseguire nuovamente il backup. +admin.backup.logFile=File di registro +admin.backup.manual=Backup manuale +admin.backup.continue=Continua il backup +admin.backup.start=Inizia il backup +admin.backup.open=Attiva il backup +admin.backup.notOpen=Il backup non è abilitato +admin.backup.location=Posizione del backup +admin.backup.content=Contenuto del backup +admin.backup.dbOnly=Database +admin.backup.time=Pianificazione +admin.backup.notStart=Non iniziato +admin.backup.notEnabled=Non abilitato +admin.backup.killed=al di sopra di +admin.backup.ifKill=Sei sicuro di voler terminare questo backup? +admin.backup.kill=Fine +admin.backup.error=Errore +admin.backup.timeBeen=Richiede tempo +admin.backup.timeTotal=Trascorsi +admin.backup.backed=Eseguito il backup +admin.backup.storage=Si prega di creare un archivio dedicato per il backup. +admin.backup.ifSave=Il backup richiede molto tempo.Sei sicuro di volerlo eseguire? +admin.backup.ifContinue=Sei sicuro di voler continuare il backup? +admin.backup.saveTips=L'attività di backup è stata inviata, si prega di pazientare +admin.backup.fileSize=Dimensione dei file +admin.backup.dbSize=Dimensione del database +admin.backup.dbCnt=Totale +admin.backup.notFinished=Non completato +admin.backup.timeTaken=Tempo trascorso +admin.backup.node=Nodo +admin.backup.notYet=No +admin.backup.storeNotExist=La memoria di backup non esiste, per favore ripristinala +admin.backup.timeNote=Nota: il sistema conserva solo i backup del database degli ultimi 7 giorni e del 1° di ogni mese. Tempo di backup: +admin.backup.recover=Si prega di contattare il fornitore di servizi per il recupero dei dati. +admin.backup.optionTime=Il backup richiede molto tempo, impostalo durante le ore non lavorative +admin.backup.optionLocation=Crea prima uno spazio di archiviazione dedicato al backup +admin.backup.optionTips1=Il backup è diviso in: Backup del database e backup dei file. +admin.backup.optionTips2=Backup del database: Genera un file SQL clonando i dati del databse e lo salva nella posizione impostata. +admin.backup.optionTips3=Backup di file: Crea copie di backups incrementali che vengono salvate nella posizione impostata. +admin.backup.optionTips4=Il sistema conserva solo i backup del database degli ultimi 7 giorni e del 1° di ogni mese. +admin.backup.needStorage=L'archivio di backup non può essere vuoto +admin.backup.needNoDefault=Non scegliere l'archiviazione predefinita come posizione di backup dei file +admin.backup.contentDesc=La versione con licenza supporta il backup simultaneo del database e dei file +admin.backup.action=Gestione +admin.backup.recovery=Ripristina +admin.backup.sysRecovery=Ripristino +admin.backup.bakErr2Rec=Questo backup è incompleto e non può essere ripristinato +admin.recycle.menu=Cestino di sistema +admin.share.name=Condividi nome +admin.share.type=Tipo di condivisione +admin.share.expiryTime=Scadenza +admin.share.expired=Scaduto +admin.share.link=Link esterno +admin.share.linkView=Fare clic per visualizzare la condivisione +admin.share.ifDel=Sei sicuro di voler annullare questa condivisione? +admin.share.disFile=Questo file è stato segnalato dagli utenti ed è stata vietata la condivisione +admin.share.disFolder=Questa directory contiene file illegali di cui è vietata la condivisione +admin.share.shareTab=Gestione della condivisione +admin.share.reportTab=Condivisioni segnalate +admin.share.rptType1=Pirateria +admin.share.rptType2=Pornoggrafia +admin.share.rptType3=Incitazione all'odio +admin.share.rptType4=Virus / Phising +admin.share.rptType5=Altre motivazioni +admin.share.doRptClose=Sei sicuro di voler chiudere la segnalazione? +admin.share.doRptDisable=La modifica avrà effetto su utte le risorse corrispondenti al file condiviso.Sei sicuro di voler effettuare questa operazione? +admin.share.rptUser=Utente +admin.share.rptTitle=Elemento segnalato +admin.share.rptDesc=Motivo della segnalazione +admin.share.rptTime=Data e ora +admin.share.rptResult=Esito segnalazione +admin.share.rptDone=Controllato +admin.share.rptNoDone=Non controllato +admin.share.rptClose=Chiudi segnalazione +admin.share.rptShareDel=Annulla condivisione +admin.share.rptShareAllow=Consenti condivisione +admin.share.rptShareDisable=Disabilita condivisione +admin.share.rptDoDisable=Proibisci/consenti condivisione +admin.share.rptSelectTips=Seleziona prima un elemento +admin.setting.transfer=Upload / Download +admin.setting.transferChunkSize=Dimensione chunk +admin.setting.transferChunkSizeDesc=[Consigliato = 5 MB] Quando si carica un file di grandi dimensioni, questo viene tagliato in pezzi per il caricamento simultaneo in modo da ottenere l'accelerazione di upload e il possibile ripristino.
    Questo valore deve essere inferiore alla configurazione sottostante. In caso contrario, si potrebbero verificare errori in fare di caricamento +admin.setting.transferChunkSizeDescError1=La dimensione del frammento di caricamento non può superare l'impostazione in php.ini +admin.setting.transferChunkSizeDescError2=Modificalo in php.ini e riprova (modifica upload_max_filesize, post_max_size, è necessario riavviare) +admin.setting.transferThreads=Upload simultanei +admin.setting.transferThreadsDesc=[Consigliato = 10] Numero di upload simultanei di file o frammenti. +admin.setting.transferIgnore=Ignora file +admin.setting.transferIgnoreDesc=Nomi di file che verranno automaticamente ignorati in fase di upload. Multipli separati da virgole, ad esempio: .DS_store, thumb.db +admin.setting.transferChunkRetry=Ripristini automatici +admin.setting.transferChunkRetryDesc=[Consigliato = 5] Il numero di tentativi di ripristino che verrà eseguito automaticamente se il caricamento non riesce. Se impostato su 0 significa nessuna ritrasmissione automatica +admin.setting.transferOsChunkSize=Dimensioni del frammento di archiviazione degli oggetti +admin.setting.transferOsChunkSizeDesc=Caricamento dell'archiviazione di oggetti, la dimensione del frammento varia da 5 MB a 5 GB e il numero massimo di richieste è 1000, il che significa che la dimensione massima di caricamento del file è 5 TB.
    Si consigliano 10 ~ 20 MB. Al momento, la dimensione massima del file supportata è 9,7 ~ 19,5 GB e gli utenti possono regolare la dimensione del file caricato in base alle proprie esigenze. +admin.setting.transferHttpSendFile=Scarica l'accelerazione del web server +admin.setting.transferHttpSendFileDesc=Il download di file viene trasmesso direttamente tramite il server Web; la velocità di download viene migliorata; è efficace solo quando l'archiviazione predefinita è configurata come archiviazione locale. +admin.setting.downloadZipClient=Download compresso front-end +admin.setting.downloadZipClientDesc=È necessario essere in grado di collegarsi alla rete esterna, altrimenti il sito è https +admin.setting.downloadZipLimit=Limite di download del pacchetto di cartelle +admin.setting.downloadZipLimitDesc=0 significa nessun limite; per evitare un consumo eccessivo di prestazioni del server, il download del pacchetto viene limitato quando la cartella è troppo grande e viene richiesto che il file possa essere scaricato direttamente tramite il client del PC +admin.setting.downloadZipLimitTips=Il contenuto compresso supera il limite di sistema, contatta l'amministratore!Puoi scaricare la cartella direttamente tramite il client del PC senza compressione. +admin.setting.dragDownload=Trascina e rilascia sul desktop per scaricare +admin.setting.dragDownloadDesc=Supportato solo dal browser del kernel Chrome lato PC (chrome edge 360 fast, ecc.) +admin.setting.dragDownloadZip=Download multiplo di compressione e trascinamento della selezione +admin.setting.dragDownloadZipDesc=Selezione multipla o supporto per il download con trascinamento della selezione delle cartelle, devono essere impacchettati e compressi sul server prima del download +admin.setting.dragDownloadLimit=Trascina e rilascia il limite delle dimensioni del contenuto +admin.setting.dragDownloadLimitDesc=0 significa nessun limite; la dimensione del contenuto trascinato sarà soggetta a questo limite. Poiché al momento non è presente una barra di avanzamento per il trascinamento e il download di Chrome, non può essere annullato. Si consiglia di limitare la dimensione a 20 milioni. +admin.setting.dragDownloadUrlTips=L'URL è troppo lungo, riduci la selezione e riprova! +admin.setting.dragDownloadOpenTips=Si prega di contattare l'amministratore per abilitarlo nelle impostazioni in background! +admin.setting.dragDownloadNotOpen=Il download trascina e comprimi non è abilitato +admin.setting.dragDownloadSizeTips=La dimensione del contenuto trascinato supera il limite +admin.setting.showFileSafe=Sicurezza dell'accesso ai file +admin.setting.showFileLink=Link diretto +admin.setting.showFileLinkDesc=Abilita il link diretto esterno al file +admin.setting.showFileMd5=Hash MD5 +admin.setting.showFileMd5Desc=Se disattivato, non sarà mostrato l'hash MD5 del file +admin.setting.shareLinkAllow=Condivisione file +admin.setting.shareLinkAllowDesc=Abilita o disabilita la condivisione esterna dei file +admin.setting.shareLinkAllowTips=Il sistema attuale ha disabilitato la condivisione di link esterni, contatta l'amministratore! +admin.setting.shareLinkPasswordAllowEmpty=Password link +admin.setting.shareLinkPasswordAllowEmptyDesc=Se disattivata, sarà obbligatorio impostare una password per tutte le nuove condivisioni +admin.setting.shareLinkAllowGuest=Condivisioni pubbliche +admin.setting.shareLinkAllowGuestDesc=Se disattivato, sarà necessario effettuare il login per visualizzare/scaricare i file condivisi +admin.setting.shareLinkZip=Download cartelle +admin.setting.shareLinkZipDesc=Abilita il download di cartelle sottoforma di file compresso. Attenzione, se le dimensioni sono eccessive, le prestazioni del server ne risentiranno. +admin.setting.shareLinkZipTips=Il download diretto dell'intera cartella non è consentito dall'amministratore +admin.setting.transferDownSpeed=Limite velocità download +admin.setting.transferDownSpeedDesc=Limita la velocità di download dei file così da non sovraccaricare il server +admin.setting.transferDownSpeedNum=Limite di velocità di download +admin.setting.transferDownSpeedNumDesc=Nota: Il limite influenza anche la velocità di navigazione del sito web. Inoltre,
    c'è da tenere conto anche della velocità di connessione e della rete dell'utente. +explorer.uploadSizeError=Il tuo server non supporta i file di dimensioni maggiore di 2 GB,
    Aggiorna a PHP 64 bit. Si consiglia PHP 7 a 64 bit
    (Nota: PHP a 64 bit può essere installato solo su sistemi operativi a 64 bit); +common.width=Larghezza +common.height=Altezza +common.test=Test +common.absolutePath=Indirizzo assoluto +common.qrcode=URL Codice QR +common.wechat=WeChat +common.group=Gruppo +common.user=Utente +common.online=Online +common.use=Usato +common.total=Totale +common.year=Anno +common.month=Mese +common.week=Settimana +common.daytime=Giorno +common.mon=Lunedì +common.tue=Martedì +common.wed=Mercoledì +common.thu=Giovedì +common.fri=Venerdì +common.sat=Sabato +common.sun=Domenica +common.second=secondo +common.minute=minuto +common.hour=ora +common.day=giorno +common.every=ogni +common.everyMonth=Mensile +common.everyWeek=Settimanale +common.everyDay=Quotidiana +common.language=Lingua +common.all=Tutti +common.item=Elementi +common.items=Elementi +common.itemsEmpyt=Nessun contenuto +common.detail=Dettagli +common.me=Me +common.others=Altre +common.guest=I visitatori +common.more=Altro +common.learnMore=Ulteriori informazioni +common.yes=Si +common.no=No +common.omit=Omettere +common.unknow=Sconosciuto +common.title=Titolo +common.time=Data +common.scan=Visualizzato +common.report=Segnala +common.name=Nome +common.nickName=Nickname +common.tools=Strumenti +common.tag=Etichette +common.position=Directory +common.mount=Montaggio in rete +common.type=Tipo +common.auth=Autorizzazioni +common.status=Stato +common.run=Avvia +common.file=File +common.folder=Cartella +common.fileType=Tipo di file +common.fileSize=Dimensioni +common.attributeInfo=Attributi +common.actionType=Tipo di operazione +common.isDisplay=Visualizza +common.hide=Nascondi +common.isHide=Nascosto +common.cancelHide=Mostra +common.default=Predefinito +common.display=display +common.moveDown=Sposta in basso +common.moveUp=Sposta in alto +common.drag=Trascina +common.dragSort=Trascina per regolare l'ordine +common.warning=Attenzione +common.tips=Informazioni +common.desc=Descrizione +common.tipsDesc=Descrizione +common.tipsOthers=Altre istruzioni +common.view=Visualizza +common.log=Log +common.task=Task Manager +common.important=importante +common.icon=Icona +common.menu=Menu +common.system=Sistema +common.basic=universale +common.systemSet=Configurazione di sistema +common.systemDefault=Sistema predefinito +common.diy=Personalizzato +common.input=Per favore, inserisci +common.select=Seleziona +common.add=Nuovo +common.edit=Modifica +common.action=Operazioni +common.upload=Upload +common.uploadTo=carica su +common.download=Download +common.export=Esporta +common.cover=Sovrascrivi +common.retry=Riprova +common.zip=Comprimi +common.unzip=Estrai +common.preview=Anteprima +common.share=Condivisione +common.search=Cerca +common.query=Filtra informazioni +common.delete=Elimina +common.deleteForce=Rimuovi completamente +common.deleteEnd=cancellato +common.refresh=Aggiorna +common.open=Apri +common.close=Chiudi +common.from=fonte +common.greater=Maggiore di +common.less=Minore di +common.print=stampa +common.selectInvert=Inverti selezione +common.selectAll=Seleziona tutto / Seleziona inversa +common.selectAllItem=Seleziona tutto +common.selectNum=Selezionati +common.selectNull=Niente affatto +common.sizeMore=o più +common.showMore=Estendi +common.showLess=Riduci +common.sizeSmall=Piccolo +common.sizeMiddle=Medio +common.sizeBig=Grande +common.rename=Rinomina +common.method=funzione +common.extend=Estensione +common.fav=Preferiti +common.reset=Ripristina +common.testing=Effettua test +common.install=installare +common.update=Aggiornare +common.version=Versione +common.sysVersion=Versione della piattaforma +common.login=Accedi +common.regist=Iscriviti +common.password=Password +common.operateTime=Tempo di funzionamento +common.createTime=Tempo di creazione +common.modifyTime=Tempo di modifica +common.activeTime=Tempo di archiviazione +common.startTime=Avvio +common.endTime=Termine +common.finishTime=Fine +common.disable=Disabilita +common.goOn=continuare +common.ok=OK +common.startRun=Avvia +common.confirmTips=Conferma di sicurezza +common.confirmAsk=Sei sicuro di voler effettuare questa operazione? +common.submit=Invia +common.skip=Salta +common.nextStep=Prossimo passo +common.start=iniziare +common.stop=pausa +common.set=Imposta +common.cancel=Annulla +common.save=Salva +common.empty=Vuoto! +common.isOpen=Acceso +common.isClose=Chiuso +common.apply=Applica +common.saveAll=Salva tutto +common.notSave=Non salvare +common.appAdd=Aggiungi +common.backAdd=Torna da aggiungere +common.saveEdit=Salva le modifiche +common.saveSubmit=Salva commit +common.saveAndAdd=Salva e continua ad aggiungere +common.sex=Genere +common.male=Uomo +common.female=Donna +common.address=Indirizzo +common.email=E-mail +common.phone=Telefono cellulare +common.sms=SMS +common.phoneNumber=Numero di telefono +common.server=Server +common.handheld=Dispositivo mobile +common.success=Successo +common.fail=Fallito +common.error=Errore +common.result=Risultato +common.expired=Scaduto +common.valid=Valido +common.inAll=totale +common.allAndNull=Seleziona Tutto / Annulla +common.moveTop=Sposta in cima +common.moveBottom=Sposta alla fine +common.moveTopCancle=Non in evidenza +common.ECN=Cina orientale +common.NCN=Cina del Nord +common.SCN=Cina meridionale +common.USA=Nord America +common.SEA=Sud-est asiatico +common.noLimit=Illimitato +common.notExists=Non esiste +common.cannotWrite=Sola lettura, non scrittura +common.readOnly=Sola lettura +common.cannotRead=illeggibile +common.ifDel=Sei sicuro di voler cancellare? +common.pageNotExists=La pagina non esiste! +common.pathNotExists=Il documento non esiste! +common.fileShare=Condivisione di file +common.logining=Accesso in corso ... +common.loginTokenError=Login scaduto, effettua nuovamente il login! +common.loginSuccess=Accesso riuscito! +common.loginError=Accesso fallito +common.connectSuccess=Connesso con successo! +common.bindSuccess=Associa con successo! +common.bindError=Bind fallito +common.clear=Svuota +common.congrats=Congratulazioni, +common.sorry=Siamo spiacenti, +common.invalid=Non valido +common.unavailable=Non disponibile +common.format=formato +common.noPermission=Permesso negato +common.allPermission=Tutti i permessi +common.invalidParam=Parametro non valido +common.invalidFormat=Formato non valido +common.invalidRequest=Tipo di richiesta illegale +common.illegalRequest=Richiesta illegale +common.expiredRequest=La richiesta è scaduta +common.errorExpiredRequest=Richiesta non valida o scaduta +common.migrating=Migrazione +common.migrated=Migrazione completata +common.maintenanceTips=Durante la manutenzione del sistema, visitare più tardi ... +common.done=completato +common.disabled=Disabilitato +common.sizeTotal=Dimensione totale +common.sqlStatement=[Istruzione SQL]: +common.env.check=Requisiti +common.env.errorLib=Manca la libreria PHP +common.env.errorIgnore=Ignora ed entra +common.env.errorVersion=La versione di PHP non può essere inferiore a 5.0 +common.env.errorPath=Non scrivibile +common.env.errorListDir=Il tuo server Web ha la funzione di elenco delle directory abilitata. Disabilitala per motivi di sicurezza! Come funziona +common.env.errorGd=La libreria GD PHP deve essere attivata, altrimenti l'uso di codici di verifica e miniature sarà anormale. +common.env.invalidExt=L'estensione %s non è disponibile, controlla se è installata +common.env.installWithBtTips=La versione php del server richiede 5.3 e successive Non ho familiarità con la configurazione con un clic del pannello di pagoda raccomandato.
    Versione corrente +common.env.phpCacheOpenTips=La tua cache php è abilitata sul tuo server e gli aggiornamenti dei file non sono ancora entrati in vigore;
    Disattiva la cache o aggiorna la pagina e riprova tra 1 minuto!
    Ulteriori informazioni +common.env.dataPathNotExists=La directory dei dati non esiste!
    (Controlla DATA_PATH); +common.env.pathPermissionError=[Codice errore: 1002] Errore autorizzazione directory! Si prega di impostare la directory del programma e tutte le sottodirectory per leggere e scrivere.
    Linux esegue il seguente comando:
     su -c 'setenforce 0' 
    chmod -R 777 +common.version.free=Gratuito +common.version.nameQ=Enterprise +common.version.vipFree=Licenza Free +common.version.useFree=Continua a utilizzare la versione gratuita +common.version.notSupport=La tua versione non supporta questa operazione, per favore vai al sito ufficiale per acquistare la versione avanzata! +common.version.notSupportNumber=Questa operazione non è supportata a causa del numero limitato, visitare il sito Web ufficiale per acquistare la versione avanzata! +common.version.toVip=Passa a Commerciale +common.version.license=Licenza +common.version.authCode=Codice di attivazione dell'autorizzazione +common.version.authActive=Autorizzazione all'attivazione +common.version.authorization=Autorizzazione alla registrazione +common.version.authorizeSuccess=Congratulazioni, l'autorizzazione per l'aggiornamento online ha avuto successo! +common.version.networkError=Richiesta al server non riuscita Controllare se il server può accedere alla rete.
    Nota: il server non può essere un proxy per accedere a Internet +common.version.authActiveOnline=Attiva online +common.version.authActiveOffline=Attiva offline +common.version.offlineTips=Il server non può accedere a Internet? +common.version.menuTitle=Impostazioni delle informazioni aziendali +common.version.timeout=scaduto +common.version.timeToService=Tempo di scadenza del servizio +common.version.timeTo=Tempo di scadenza dell'autorizzazione +common.version.licenseAll=Autorizzazione perpetua +common.version.kodVersion=Aggiornamenti +common.version.userLimitTitle=Utenti +common.version.userUse=Usati +common.version.userAllow=Supportati +common.version.userTo=Oggetto autorizzato +common.version.userTitle=Informazioni sull'autorizzazione +common.version.basicInfo=Informazioni di base +common.version.appInfo=Informazioni sul prodotto +common.version.tipsWarning=Attenzione, non modificare il copyright senza autorizzazione; se necessario, si prega di contattare per l'acquisto! +common.version.tipsCopyLink=Copia correttamente! Incolla e salva nel file txt,
    Apri questo collegamento su un computer con una rete tramite un'unità flash USB, ecc. +common.version.tipsHistory=La versione gratuita supporta solo 5 versioni della cronologia; acquista un numero illimitato di versioni con licenza! +common.version.codeLink=Link per la richiesta del codice di autorizzazione +common.version.codeLinkHelp=1. Copia il link sopra e visita altri computer con accesso a Internet.
    2. Compilare il "Codice di autenticazione dell'autorizzazione" ottenuto sopra, quindi attivare e autorizzare +common.copyright.logoTitle=Set di logo di identità aziendale +common.copyright.licenseInfo=Informazioni sull'autorizzazione +common.copyright.licenseReset=riautorizzazione +common.copyright.licenseResetTips=Riattiva per maggiori informazioni! +common.copyright.formLogo=Tipo di logo della pagina di accesso +common.copyright.formLogoTypeWord=Logo di testo +common.copyright.formLogoTypeImage=Logo dell'immagine +common.copyright.formLogoDesc=Il logo di testo utilizza il nome dell'azienda e il logo dell'immagine utilizza l'immagine impostata come segue. +common.copyright.formLogoImage=Immagine del logo della pagina di accesso +common.copyright.formLogoImageDesc=Pagina di accesso e logo di sfondo di gestione, dimensioni consigliate 250x100, formato png traslucido +common.copyright.formLogoMain=Logo del menu dell'interfaccia principale +common.copyright.formLogoMainDesc=Gestione file logo nell'angolo in alto a sinistra, dimensioni consigliate 200x200, formato png traslucido bianco +common.copyright.formPowerByInfo=Impostazioni delle informazioni sul copyright dell'azienda +common.copyright.formPowerBy=Nome della società con copyright inferiore +common.copyright.formHomePage=Salto di collegamento del copyright inferiore +common.copyright.formConcat=Contatto pop-up +common.copyright.formDesc=Descrizione dettagliata del livello pop-up del prodotto +common.copyright.formDescTips=Dopo aver salvato la modifica, la pagina di aggiornamento diventa effettiva +common.copyright.formMetaKeywords=Parole chiave del sito (utilizzate dai motori di ricerca) +common.copyright.formMetaName=Nome del sito (utilizzato dai motori di ricerca) +common.copyright.downloadApp=Download dell'app +common.copyright.downloadLink= +common.copyright.about=About +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=Identificazione automatica +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=arabo +common.charset.ISO_8859_6=arabo +common.charset.ISO_8859_10=Lingua nordica +common.charset.CP1257=Lingue nel Baltico +common.charset.ISO_8859_13=Lingue nel Baltico +common.charset.ISO_8859_4=Lingue nel Baltico +common.charset.BIG5_HKSCS=Hong Kong tradizionale +common.charset.BIG5=Tradizionale - Taiwan +common.charset.Georgian_Academy=georgiano +common.charset.PT154=kazako +common.charset.CP949=coreano +common.charset.EUC_KR=coreano +common.charset.GB18030=Cinese semplificato +common.charset.GBK=Cinese semplificato +common.charset.ISO_8859_14=celtico +common.charset.CP1133=Lao +common.charset.ISO_8859_16=rumeno +common.charset.ISO_8859_3=Lingue dell'Europa meridionale +common.charset.EUC_JP=giapponese +common.charset.ISO_2022_JP=giapponese +common.charset.SHIFT_JIS=giapponese +common.charset.KOI8_T=lingua tagika +common.charset.ISO_8859_11=Thai +common.charset.TIS_620=Thai +common.charset.CP1254=turco +common.charset.CP1251=cirillico +common.charset.ISO_8859_5=cirillico +common.charset.KOI8_R=cirillico +common.charset.KOI8_U=cirillico +common.charset.CP1252=Lingue dell'Europa occidentale +common.charset.ISO_8859_1=Lingue dell'Europa occidentale +common.charset.ISO_8859_15=Lingue dell'Europa occidentale +common.charset.Macintosh=Lingue dell'Europa occidentale +common.charset.CP1255=ebraico +common.charset.ISO_8859_8=ebraico +common.charset.CP1253=greco +common.charset.ISO_8859_7=greco +common.charset.ARMSCII_8=armeno +common.charset.CP1258=vietnamita +common.charset.VISCII=vietnamita +common.charset.CP1250=Lingue dell'Europa centrale +common.charset.ISO_8859_2=Lingue dell'Europa centrale +common.charset.defaultSet=Codifica dei file +common.charset.convertSave=Convertito in +common.date.near=Proprio ora +common.date.miniteBefore=Minuti fa +common.date.today=Oggi +common.date.yestoday=Ieri +common.date.before=Prima di +common.faceDefault=Emoticons predefinite +common.loadMore=Carica di più +common.numberLimit=La quantità supera il limite massimo! +common.lengthLimit=La lunghezza supera il limite massimo! +common.task.name=Task Manager +common.task.title=Nome task +common.task.user=Utente esecutivo +common.task.porcess=Processo +common.task.start=Inizia l'attività +common.task.useTime=Tempo trascorso +common.task.running=Esecuzione +common.task.stoping=In pausa +common.task.killing=Fine +common.task.stop=Compito sospeso +common.task.kill=Ultimo compito +common.task.removeTips=Sei sicuro di terminare questa operazione? +common.task.killAll=Finisci tutto +common.task.killAllTips=Sei sicuro di terminare tutte le attività? +common.task.timeStart=Iniziare a +common.task.timeNeed=Restano +common.task.timeUse=Già correndo +ERROR_DB_PWD=Accesso al database negato: nome utente o password errati. +ERROR_DB_TIMEOUT=Timeout di connessione al database, verificare se l'indirizzo è corretto. +ERROR_DB_CONN_RFS=Connessione al database rifiutata: informazioni di configurazione errate o servizio non avviato. +ERROR_DB_ADR=Errore di connessione al database, verificare se l'indirizzo è corretto. +ERROR_DB_NOT_SUPPORT=Tipo di database non supportato, verificare se il servizio o il file di configurazione corrispondente è normale. +ERROR_DB_XS_DENNIED=Accesso al database negato: privilegi insufficienti. +ERROR_DB_NOT_EXIST=Il database non esiste oppure è stato specificato un nome errato. +explorer.pathNotSupport=Questo tipo di directory non supporta questa operazione +explorer.pathIsRoot=Hai raggiunto la directory principale +explorer.pathNull=La cartella è vuota +explorer.zipFileLarge=Il file è troppo grande, estrailo prima di visualizzarlo in anteprima +explorer.charNoSupport=Caratteri speciali non supportati: +explorer.moveError=Sposta non riuscita +explorer.lockError=Si è verificato un errore, il blocco simultaneo è scaduto +explorer.lockErrorDesc=Ridurre la frequenza delle richieste o ottimizzare la configurazione relativa alla concorrenza del server o migliorare la configurazione hardware del server; +explorer.moveSubPathError=Qualcosa è andato storto, la directory padre non può essere spostata nella directory figlio! +explorer.spaceIsFull=Spazio insufficiente, contattare l'amministratore! +explorer.sessionSaveError=Scrittura della sessione non riuscita! Verifica se il disco è pieno o consulta il tuo fornitore di servizi. +explorer.networkError=Errore di connessione di rete (net :: ERR_CONNECTION_RESET), la connessione è stata ripristinata.
    Si prega di contattare la società ospitante o l'amministratore di rete per verificare la configurazione del firewall! +explorer.folderManage=Gestione directory +explorer.clickEdit=Fai clic per modificare +explorer.shortLink=Tasti di scelta rapida +explorer.upper=Strato superiore +explorer.historyNext=Avanti +explorer.historyBack=Indietro +explorer.loading=Caricamento ... +explorer.getting=Acquisizione ... +explorer.sending=Invio dati in corso ... +explorer.pullTips=Tirare giù per aggiornare la pagina +explorer.pullDropTips=Gratuito per aggiornare la pagina +explorer.getSuccess=Accesso autorizzato +explorer.saveSuccess=Salvato +explorer.saveError=Salvataggio fallito +explorer.success=Operazione riuscita +explorer.error=Operazione fallita +explorer.dataError=I dati sono anormali! +explorer.pathError=Errore percorso documento +explorer.repeatError=Operazione fallita, il nome esiste già! +explorer.systemError=Errore di sistema +explorer.mistake=Qualcosa è andato storto! +explorer.recycleClear=Svuota cestino +explorer.recycleClearForce=C'è troppo contenuto nel cestino, per favore svuota prima il cestino! +explorer.recycleRestore=Ripristina Cestino +explorer.recycleRestoreItem=Ripristina +explorer.recycleRestoreAll=Ripristina tutto +explorer.recycleClearInfo=Sei sicuro di voler svuotare completamente il cestino? +explorer.zipDownloadReady=Compressione in corso, attendi ... +explorer.removeItem=Elementi +explorer.uploading=Caricamento +explorer.uploadTipsMore=Troppi file, si consiglia di caricare dopo la compressione e quindi decomprimere online! +explorer.uploadingMove=Unione e trasferimento in corso ... +explorer.viewNewPage=Anteprima della nuova pagina +explorer.unknowFileTitle=Suggerimenti per l'apertura dei file! +explorer.unknowFileTips=Senza un'app che supporti questo file, puoi: +explorer.unknowAppTips=Senza l'app: +explorer.unknowFileTry=provare +explorer.unknowFileDown=Download +explorer.authFileDown=Download +explorer.authShare=Shared +explorer.usersShare=Condiviso +explorer.clipboard=Visualizza appunti +explorer.clipboardClear=Appunti vuoti +explorer.fullScreen=Schermo intero +explorer.folderItem=elementi +explorer.folderItemSelect=selezionati +explorer.dbLoadAll=Fare doppio clic per caricare tutto ... +explorer.ziping=Compressione ... +explorer.unziping=Estrazione ... +explorer.zipingTips=Compressione in corso, attendere ... +explorer.unzipingTips=Estrazione in corso, attendere ... +explorer.unzipRarTips=Il contenuto del file è danneggiato o l'analisi del file non è supportata Si consiglia di utilizzare il formato ZIP. +explorer.parsing=Analisi in corso ... +explorer.moving=Spostamento dei files in corso ... +explorer.copyMove=Copia mossa +explorer.removeTitle=Elimina la conferma +explorer.removeInfo=Sei sicuro di voler eliminare la selezione? +explorer.removeTitleForce=Elimina per sempre +explorer.removeInfoForce=Sei sicuro di voler eliminare definitivamente questo documento? +explorer.pathInRecycle=La cartella è nel cestino, ripristinala e riprova! +explorer.pathInRecycleFile=Il file è nel cestino, ripristinalo e riprova! +explorer.downOffline=Download da URL +explorer.savePath=Salva percorso +explorer.uploadSelectMuti=Seleziona più file da caricare +explorer.goTo=Vai a +explorer.selectFile=Seleziona il file +explorer.selectFolder=Seleziona cartella +explorer.selectImage=Seleziona un'immagine ... +explorer.selectValidFolder=Seleziona una cartella per essere valida! +explorer.selectFolderFile=Seleziona il file o la cartella +explorer.selectMulti=Selezione multipla +explorer.notNull=I campi obbligatori non possono essere vuoti! +explorer.picCannotNull=L'indirizzo dell'immagine non può essere vuoto! +explorer.renameSuccess=Rinominato con successo! +explorer.inputSearchWords=Inserisci la stringa da cercare +explorer.search.optionContent=Contenuto dei file +explorer.search.searchContentTips=Contenuto del file di ricerca per parole chiave, file di testo di supporto +explorer.search.optionMutil=Ricerca multipla +explorer.search.optionMutilDesc=Un termine di ricerca per riga. I risultati della ricerca vengono ordinati in base al termine di ricerca +explorer.removeSuccess=Cancellato con successo +explorer.removeFail=Eliminazione fallita +explorer.clipboardNull=Gli appunti sono vuoti +explorer.createSuccess=Creato con successo +explorer.createError=Nuova creazione non riuscita, controlla le autorizzazioni della directory! +explorer.copySuccess=[Copia] - Appunti sovrascritti correttamente +explorer.cuteSuccess=[Taglia] - Appunti sovrascritti correttamente +explorer.clipboardState=Stato degli Appunti: +explorer.copyOK=Copiato con successo +explorer.copyNotExists=La fonte non esiste +explorer.currentHasParent=La cartella di destinazione è una sottocartella della cartella di origine! +explorer.pastSuccess=Operazione Incolla completata +explorer.cutePastSuccess=Operazione taglia e incolla completa (i file di origine e gli appunti sono stati eliminati) +explorer.zipSuccess=Compressione completata +explorer.notZip=Non è un file compresso +explorer.zipNull=Nessun file o directory selezionati +explorer.unzipSuccess=Estrazione completa +explorer.pathIsCurrent=Il percorso aperto è uguale al percorso corrente! +explorer.pathExists=Il nome esiste già! +explorer.serverDownDesc=Attività aggiunte all'elenco di download +explorer.parentPermission=Autorizzazioni per la directory principale +explorer.confirm=Sei sicuro? +explorer.ifSaveFileTips=Ci sono modifiche non salvate,sei sicuro di voler uscire? +explorer.ifSaveFile=Il file non è stato ancora salvato. È salvato? +explorer.ifStopUploadTips=È in corso il caricamento di un file, sei sicuro di chiudere la finestra? +explorer.noPermissionRead=Non hai il permesso di lettura +explorer.noPermissionDownload=Non sei autorizzato a scaricare +explorer.noPermissionWrite=La directory non ha autorizzazioni di scrittura +explorer.noPermissionAction=Non disponi di questa autorizzazione. Contatta l'amministratore +explorer.noPermissionWriteAll=Il file o la directory non dispone dell'autorizzazione di scrittura +explorer.noPermissionWriteFile=Il file non dispone dell'autorizzazione di scrittura +explorer.noPermissionReadAll=Il file o la directory non ha autorizzazioni di lettura +explorer.noPermission=L'amministratore ha disabilitato questa autorizzazione +explorer.noPermissionExt=Un amministratore ha disabilitato questo tipo di autorizzazioni per i file +explorer.noPermissionGroup=Non sei in questo gruppo di utenti +explorer.pathNoWrite=La directory non è scrivibile, si prega di impostare la directory e tutte le sottodirectory per leggere e scrivere e riprovare! +explorer.onlyReadDesc=Questa directory non ha autorizzazioni di scrittura, è possibile impostare autorizzazioni su questa directory sul server +explorer.settingSuccess=La modifica ha avuto effetto +explorer.noRepeat=Nessun duplicato consentito +explorer.dataNotFull=L'invio dei dati è incompleto! +explorer.tooManyToView=Contiene troppo contenuto (%s elementi), per favore aprilo localmente per vederlo; +explorer.jumpAfterWhile=Salta automaticamente dopo%ss, Salta immediatamente +explorer.retryTips=Verifica e riprova +explorer.selectObject=Oggetto +explorer.parentGroup=Gruppo superiore +explorer.actionAuth=Autorità operativa +explorer.notSelectDesc=Nessun dato, per favore scegli! +explorer.groupAuthCopy=Copia +explorer.groupAuthCopyDesc=Copia la combinazione di autorizzazione +explorer.groupAuthPasteDesc=Incolla la combinazione di autorizzazioni copiata +explorer.groupAuthSave=Salva nei preferiti +explorer.groupAuthRecent=Usato di recente +explorer.selectDesc=Seleziona contenuto +explorer.cannotLoad=Impossibile caricare i risultati. +explorer.loadMore=Carica altri risultati ... +explorer.noSearchData=Nessun risultato trovato +explorer.delAllItem=Elimina tutti gli elementi +explorer.pleaseDel=Per favore cancella +explorer.pleaseInput=Per favore, inserisci almeno +explorer.canChoose=Seleziona solo al massimo +explorer.theChars=personaggi +explorer.theItems=elementi +explorer.noData=Nessun dato +explorer.ifPathAuthClear=Tutte le impostazioni delle autorizzazioni per i file secondari e le cartelle verranno cancellate. Vuoi continuare? +explorer.fileDescAdd=Aggiungi la descrizione del documento +explorer.fileDesc=Descrizione del documento +explorer.fileLog=Registro operazioni +explorer.ifResetOpen=Sei sicuro di voler ripristinare tutti i metodi di apertura personalizzati? +explorer.ResetOpen=Ripristina impostazioni predefinite +explorer.openWith=Apri come ... +explorer.openWithAce=Apri nell'editor +explorer.openWithLocal=Apri localmente +explorer.openWithLocalEdit=Editing locale +explorer.editorSaveTips=Il file non è stato creato, salvare prima il nuovo file +explorer.editor.fileTooBig=Il file è troppo grande e non può essere più grande di 20M +explorer.errorFunctionTips=Questo tipo di file non supporta gli elenchi di funzioni! +explorer.errorFormatTips=Il tipo di file corrente non corrisponde al metodo di formattazione predefinito.
    Si prega di selezionare manualmente +explorer.cuteToThe=Sposta in: +explorer.copyToThe=Copia in: +explorer.addToFav=Aggiungi ai preferiti +explorer.addFav=Aggiunto ai preferiti +explorer.delFav=Rimosso dai preferiti +explorer.addFavSuccess=Preferito aggiunto correttamente +explorer.pathHasFaved=Il percorso è stato favorito +explorer.delFavSuccess=Preferito rimosso correttamente +explorer.fileLock=Blocca +explorer.fileLockNow=Blocca +explorer.fileLockCancle=Sblocca +explorer.fileLockTitle=Bloccato +explorer.fileLockTips=Bloccato (gli altri non possono modificare il file) +explorer.fileLockUser=Locker +explorer.fileLockError=Il file corrente è bloccato, contatta l'armadietto per sbloccarlo e riprova; +explorer.downloaded=Download completato +explorer.openAutoTips=Si aprirà automaticamente +explorer.historyAutoTips=Genera automaticamente versioni storiche +explorer.saved=Salvato! +explorer.opened=Aperto +explorer.openFail=Errore nell'apertura! +explorer.openingWithLoc=Il file è aperto localmente ... +explorer.openOnlyView=La modalità di sola lettura è attiva +explorer.saving=Salvataggio file ... +explorer.notSupport=Qualcosa è andato storto, il formato del contenuto non è supportato! +explorer.unzipErrorTips=Qualcosa è andato storto! Formato file compresso non riconosciuto;
    Verifica se il file è compresso o danneggiato. +explorer.wordLoading=Caricamento in corso ... +explorer.noFunction=Assolutamente no! +explorer.paramFormatError=Parametro errato o mancante +explorer.descTooLong=La descrizione è troppo lunga +explorer.noMoreThan=Non più di +explorer.desktopDelError=Spiacenti, la cartella del desktop non supporta l'eliminazione! +explorer.copy=Copia +explorer.past=Incolla +explorer.clone=Crea una copia +explorer.cute=Taglia +explorer.cuteTo=Sposta in ... +explorer.copyTo=Copia in ... +explorer.info=Proprietà +explorer.searchInPath=Cerca nella cartella +explorer.addToPlay=Aggiungi alla playlist +explorer.manageFav=Gestisci Preferiti +explorer.refreshTree=Aggiorna lista directory +explorer.zip=Crea pacchetto compresso +explorer.unzip=Estrai ... +explorer.unzipFolder=Estrai in cartella +explorer.unzipThis=Estrai qui +explorer.unzipTo=Estra in ... +explorer.openProject=Editor progetto aperto +explorer.createLink=Crea collegamento +explorer.createLinkHome=Invia collegamento sul desktop +explorer.setBackground=Imposta come sfondo del desktop +explorer.favRemove=Rimuovi dai preferiti +explorer.openPath=Vai alla directory +explorer.openPathFinished=Già inserito nella directory +explorer.openIE=Apri nel browser +explorer.newFile=Nuovo file +explorer.newFolder=Nuova cartella +explorer.fileSaveTo=File salvato in +explorer.openFather=Apri cartella ... +explorer.uploadFile=Upload file +explorer.uploadFolder=Upload cartella +explorer.appOpenDefault=Impostazione apertura predefinita +explorer.appOpenAways=Utilizza sempre questa applicazione +explorer.appSelectDesc=Scegli il programma che vuoi utilizzare per aprire questo file +explorer.appSelectMenu=Imposta come modalità di apertura predefinita +explorer.appSelectMenuCancel=Disimposta come predefinito aperto con +explorer.appSelectWarning=Seleziona un'applicazione! +explorer.appTypeSupport=Applicazioni supportate +explorer.appTypeAll=Tutte le applicazioni +explorer.appSearch=Cerca installazioni di app correlate +explorer.recent.createTime=Creato il +explorer.recent.modifyTime=Modificato il +explorer.recent.viewTime=Apri alle +explorer.urlLink=URL esterno +explorer.downloading=Download in corso ... +explorer.downReady=Prossimamente +explorer.downError=Download fallito! +explorer.max=Ingrandisci +explorer.min=Riduci +explorer.minAll=Riduci a icona tutto +explorer.displayAll=Mostra tutte le finestre +explorer.closeAll=Chiudi tutto +explorer.authDtl=Fare clic per visualizzare le autorizzazioni nella directory +explorer.authDialog=Membri interni, tabella autorizzazioni livello collaborazione documento +explorer.authNote=Nota: le funzioni di gestione includono l'impostazione delle autorizzazioni dei membri / la gestione dei commenti, ecc. Fare attenzione! [Amministratore di sistema] Il ruolo non è limitato da alcuna autorizzazione +explorer.auth.toOuter=Autorizzazione esterna (altri gruppi o utenti) +explorer.auth.share=Sharer +explorer.auth.owner=Amministratore +explorer.auth.disableDeep=Nessun permesso di accesso solo +explorer.auth.disableDeepDesc=La directory dei fattori dispone delle autorizzazioni di lettura e scrittura del documento e del percorso di accesso stabilito. +explorer.auth.tips=Puoi contattare gli utenti di cui sopra per impostare le autorizzazioni per te +explorer.notSystemPath=Non è un percorso di file di sistema +explorer.toolbar.rootPath=Spazio personale +explorer.toolbar.fav=Preferiti +explorer.toolbar.desktop=Desktop +explorer.toolbar.client=Client +explorer.toolbar.myComputer=Il mio computer +explorer.toolbar.recycle=Cestino +explorer.toolbar.myDocument=I miei documenti +explorer.toolbar.myPicture=Le mie foto +explorer.toolbar.myMusic=La mia musica +explorer.toolbar.myMovie=I miei video +explorer.toolbar.myDownload=I miei download +explorer.toolbar.uiDesktop=Desktop +explorer.toolbar.uiExplorer=Explorer +explorer.toolbar.uiEditor=Editore +explorer.toolbar.uiProjectHome=Home del progetto +explorer.toolbar.uiLogout=Disconnettiti +explorer.toolbar.uiGroup=Struttura organizzativa +explorer.toolbar.myGroup=Il mio gruppo +explorer.toolbar.publicPath=Directory pubblica +explorer.toolbar.recentDoc=Documenti recenti +explorer.toolbar.myShare=La mia parte +explorer.toolbar.shareToMe=Condivisi con me +explorer.toolbar.shareTo=In collaborazione +explorer.toolbar.shareLink=File condivisi +explorer.toolbar.photo=Album di foto +explorer.photo.desc=Classificazione degli album degli utenti +explorer.photo.group=Raggruppamento degli album +explorer.photo.setting=Impostazioni dell'album +explorer.photo.pathRoot=Directory di scansione dell'album +explorer.photo.pathRootSelect=Selezionare una cartella come directory principale per la scansione delle immagini dell'album +explorer.photo.fileType=Specifica il tipo di file +explorer.photo.fileSize=Filtro dimensioni del file +explorer.photo.fileSizeDesc=Filtra solo i file più grandi di questa impostazione, se è 0, non c'è limite +explorer.toolbar.folder=Album del catalogo +explorer.toolbar.folderSelect=Seleziona una cartella da visualizzare in modalità album +explorer.pathDesc.fav=Dopo che il file è stato aggiunto alla raccolta, è possibile accedervi rapidamente e direttamente +explorer.pathDesc.home=Lo spazio personale è il tuo spazio di archiviazione privato, Visibile solo a te, non ad altri utenti +explorer.pathDesc.groupRoot=Questo è lo spazio pubblico dell'impresa/unità, Tutti i membri sono visibili per impostazione predefinita +explorer.pathDesc.myGroup=Gestisci qui i documenti del tuo dipartimento, I documenti del dipartimento sono visibili e utilizzabili solo dai membri di questo dipartimento e non sono visibili agli altri membri del dipartimento +explorer.pathDesc.group=Disco di rete dipartimentale, visibile solo ai membri del dipartimento, L'autorizzazione all'operazione viene assegnata e impostata dall'amministratore del reparto. +explorer.pathDesc.recentDoc=File creati, caricati, modificati e aperti di recente +explorer.pathDesc.shareTo=Visualizza e gestisci i tuoi progetti di [collaborazione interna] avviati da altri qui +explorer.pathDesc.shareLink=Visualizza e gestisci la condivisione della catena esterna avviata da te qui +explorer.pathDesc.recycle=Gestisci i tuoi file cancellati (cartelle) qui +explorer.pathDesc.fileType=Classifica i file per tipo, solo i file nello spazio personale +explorer.pathDesc.tag=Aggiungi tag ai file (cartelle) per ottenere una classificazione efficiente e una query veloce +explorer.pathDesc.tagItem=Prova ad aggiungere un'etichetta al file/cartella! +explorer.pathDesc.mount=Qui puoi gestire più storage back-end, così come i dischi montati sul server +explorer.pathDesc.shareToMe=Vista lista: tutti i contenuti con cui ho collaborato +explorer.pathDesc.shareToMeUser=Mostra per utente: il contenuto con cui ho collaborato è classificato dall'iniziatore +explorer.pathDesc.shareToMeUserItem=Collaborazione avviata da questo utente +explorer.pathDesc.shareToMeGroup=Il contenuto con cui collaboro è classificato dal dipartimento in cui si trova la cartella +explorer.pathDesc.shareToMeGroupGroup=Condivisione collaborativa dal disco di rete del dipartimento +explorer.pathDesc.search= +explorer.pathDesc.searchMore=Imposta più condizioni di ricerca +explorer.pathDesc.shareFrom=Percorso sorgente +explorer.pathGroup.shareGroup=Sotto dipartimento +explorer.pathGroup.shareGroupDesc=Accesso quando sono presenti contenuti nel reparto di livello inferiore +explorer.pathGroup.shareUser=Condivisione dello spazio personale dei membri del dipartimento +explorer.pathGroup.shareUserDesc=Fonte: condivisione dello spazio personale dell'utente, condivisione di documenti del reparto esterno avviata dall'utente. +explorer.pathGroup.shareContent=La collaborazione e la condivisione dello spazio del dipartimento +explorer.pathGroup.group=Sotto dipartimento +explorer.pathGroup.groupContent=Documento dipartimentale +explorer.pathGroup.shareUserOuter=Condivisione di collaborazioni esterne +explorer.pathGroup.shareUserOuterDesc=Condivisione collaborativa di utenti esterni al di fuori della propria struttura organizzativa +explorer.pathGroup.shareSelf=spazio personale +explorer.toolbar.fileSizeTitle=Dimensione icone +explorer.toolbar.fileSizeSuper=Super piccolo +explorer.toolbar.fileSizeSmall=Piccola icona +explorer.toolbar.fileSizeDefault=Icona media +explorer.toolbar.fileSizeBig=Icona grande +explorer.toolbar.fileSizeBigSuper=Icona di grandi dimensioni +explorer.toolbar.PagePC=Versione per PC +explorer.toolbar.pagePhone=Versione mobile +explorer.file.name=Nome +explorer.file.type=Tipo +explorer.file.contain=Contiene +explorer.file.address=posizione +explorer.file.detil=Commenti +explorer.file.linkCount=Conteggio +explorer.file.size=Dimensioni +explorer.file.count=Quantità +explorer.file.byte=Byte +explorer.file.path=Percorso +explorer.file.action=Operazioni +explorer.file.creator=Creato da +explorer.file.editor=Modificato da +explorer.file.location=Directory +explorer.file.timeInfo=Informazioni sul tempo +explorer.file.createTime=Creato il +explorer.file.modifyTime=Ultima modifica +explorer.file.lastTime=Ultima visita +explorer.file.sortType=Ordina per +explorer.file.sortDisable=Il contenuto non supporta l'ordinamento specificato! +explorer.file.timeType=S / m / d H: i: s +explorer.file.timeTypeInfo=S / m / d H: i: s +explorer.file.listType=Vista +explorer.file.listIcon=Disposizione delle icone +explorer.file.listList=Elenco ordinamento +explorer.file.listListSplit=Modalità colonna +explorer.file.listTypeGroup=Modalità di visualizzazione e metodo di ordinamento +explorer.file.listTypeKeep=modalità display +explorer.file.listTypeKeepDesc=Scegli una modalità di visualizzazione per ciascuna cartella o utilizza la stessa modalità di visualizzazione per tutte le cartelle +explorer.file.listSortKeep=ordina per +explorer.file.listSortKeepDesc=Configura l'ordinamento delle colonne per ciascuna cartella o utilizza lo stesso ordine per tutte le cartelle +explorer.file.listViewKeep=Funziona con una singola cartella +explorer.file.listViewAll=si applica a tutte le cartelle +explorer.file.listViewReset=riportare alle condizioni originali +explorer.file.sortUp=Crescente +explorer.file.sortDown=Decrescente +explorer.file.orderType=Ordina per +explorer.file.orderDesc=Discendente +explorer.file.orderAsc=Crescente +explorer.file.imageSize=Dimensioni dell'immagine +explorer.file.sharer=Sharer +explorer.file.shareTime=Condiviso il +explorer.file.viewCnt=Numero visualizzazioni +explorer.file.downCnt=Numero download +explorer.file.readWriteLock=Questa operazione non è temporaneamente supportata, ci sono altre attività di lettura e scrittura in corso di elaborazione, riprova più tardi! +explorer.app.app=Applicazioni +explorer.app.createLink=Nuovo URL +explorer.app.create=Crea un'applicazione +explorer.app.edit=Modifica app +explorer.app.open=Apri l'app +explorer.app.groupGame=Giochi +explorer.app.groupTools=Strumenti +explorer.app.groupReader=Leggi +explorer.app.groupMovie=Televisione +explorer.app.groupMusic=Musica +explorer.app.groupLife=Life +explorer.app.desc=Descrizione dell'applicazione +explorer.app.icon=Icona dell'applicazione +explorer.app.iconShow=indirizzo url o directory +explorer.app.group=Raggruppamento di applicazioni +explorer.app.type=tipo +explorer.app.typeUrl=collegamento +explorer.app.typeCode=estensione js +explorer.app.display=esterno +explorer.app.displayBorder=Senza bordi (selezionato è senza bordi) +explorer.app.displaySize=Ridimensiona (selezionare per regolare) +explorer.app.size=Dimensioni +explorer.app.url=Indirizzo di collegamento +explorer.app.code=codice js +explorer.app.appType=Tipo di applicazione +explorer.app.website=URL +explorer.app.shortLink=Collegamento al file +explorer.app.imgIcon=Icona immagine +explorer.app.imgIconUrl=Seleziona l'immagine o incolla l'URL dell'immagine web. +explorer.app.path=Percorso +explorer.app.pathDesc=Non supporta la modifica manuale, è possibile fare clic con il pulsante destro del mouse sul file per creare un collegamento +explorer.app.link=Collegamento URL +explorer.app.linkDesc=Inserisci il link http / https +explorer.app.linkDragTips=Puoi trascinare il collegamento URL nell'area del file per creare automaticamente un collegamento URL! +explorer.app.openType=Apri come +explorer.app.openWindow=Nuova finestra +explorer.app.openDialog=Finestra di dialogo +explorer.app.openCurrent=Stessa pagina +explorer.app.openInline=Pagina incorporata +explorer.app.dialogSize=Dimensione della finestra di dialogo +explorer.app.with=Larghezza +explorer.app.height=Altezza +explorer.app.moreSet=Altre impostazioni +explorer.app.canDiyWith=Consenti regolazione della larghezza +explorer.app.miniBlock=Barra del titolo minimalista +explorer.app.runCode=Eseguire il codice js +explorer.app.name=Nome dell'applicazione +explorer.app.nameDesc=Inserisci un nome per l'applicazione. +explorer.app.descDesc=Inserisci una descrizione dell'applicazione +explorer.embed.title=File da incorporare +explorer.embed.desc=Incorpora il file in una pagina web o in un blog +explorer.embed.url=URL incorporamento +explorer.embed.code=Codice di incorporamento +explorer.upload.ready=In attesa di caricamento +explorer.upload.success=Caricato con successo +explorer.upload.secPassSuccess=Successo in pochi secondi +explorer.upload.pathCurrent=Passa alla directory corrente +explorer.upload.select=Seleziona file +explorer.upload.maxSize=Massimo consentito +explorer.upload.sizeInfo=Se vuoi configurare dimensioni maggiori, modifica il caricamento massimo consentito in php.ini. Quando si seleziona un file, quelli più grandi di questa configurazione verranno automaticamente filtrati. +explorer.upload.error=Caricamento non riuscito +explorer.upload.mergeError=Unisci file non riuscito +explorer.upload.errorHttp=Errore di rete o firewall +explorer.upload.muti=Caricamento di più file +explorer.upload.drag=Trascina e rilascia il caricamento +explorer.upload.dragFolder=Trascina e rilascia nella cartella per caricare +explorer.upload.dragTips=Rilascia per caricare +explorer.upload.pathNotAllow=Il nome del file non è consentito +explorer.upload.errorNull=Nessun documento +explorer.upload.errorBig=La dimensione del file supera il limite del server +explorer.upload.errorMove=Impossibile spostare i file +explorer.upload.errorExists=Il file esiste già +explorer.upload.local=Upload locale +explorer.upload.tips=Utilizza il caricamento di frammenti, non più limitato da php.ini; si consiglia di trascinare e caricare le cartelle di Chrome experience +explorer.upload.exist=File con stesso nome +explorer.upload.clearAll=Cancella tutto +explorer.upload.clear=Pulisci completati +explorer.upload.addMore=Download multipli +explorer.upload.errorEmpty=Non può essere vuoto! +explorer.upload.errorExt=Le estensioni dei file non corrispondono! +explorer.upload.fileSizeDisable=Ci sono troppi file caricati / trasferiti allo stesso tempo, contatta l'amministratore per modificare! +explorer.upload.moreDesc=(Consigliato non più di 2000) +explorer.upload.scan=scansione +explorer.upload.merge=Verifica unione +explorer.upload.needTime=Resta ca. +explorer.upload.checkError=Verifica del caricamento non riuscita, riprova +explorer.upload.saveError=Impossibile salvare le informazioni sul file di caricamento +explorer.upload.downloadDesc=Supporta solo collegamenti http/https +explorer.table.first=casa +explorer.table.last=Ultima pagina +explorer.table.prev=precedente +explorer.table.next=Pagina successiva +explorer.table.one=Totale 1 pagine +explorer.table.page=pagina +explorer.table.itemPage=/pagina +explorer.table.searchTotal=Trovati: +explorer.table.items=Records +explorer.table.list=Elenco dei dati +explorer.search.ing=Ricerca in corso ... +explorer.search.result=Risultato della ricerca +explorer.search.resultTooMore=Troppi risultati della ricerca, suggerisci un'altra directory o parola +explorer.search.resultNull=Nessun risultato di ricerca! +explorer.search.caseSensitive=Case sensitive +explorer.search.content=Cerca il contenuto del file +explorer.search.extDesc=Inserisci le estensioni da filtrare, separate da spazi. +explorer.search.byItems=Elementi filtrati +explorer.search.extNull=Nessun tipo +explorer.search.extFile=Qualsiasi file +explorer.search.extDiy=Personalizzato +explorer.search.inputDesc=Devi inserire delle parole chiave oppure impostare dei filtri +explorer.search.path=Cerca nella directory: +explorer.search.rootPath=Cerca nella directory principale: +explorer.search.range=Cerca in +explorer.search.allFolder=Tutte le cartelle +explorer.search.currentFolder=Cartella corrente +explorer.search.ext=Tipo di file +explorer.search.timeRange=Data +explorer.search.timeAll=Qualsiasi data +explorer.search.lastDay=Ieri +explorer.search.lastWeek=Ultimi 7 giorni +explorer.search.lastMonth=Ultimi 30 giorni +explorer.search.lastYear=Ultimo anno +explorer.search.sizeAll=Qualsiasi dimensione +explorer.search.inputNullDesc=Si può cercare per range di dimensioni. Possono essere utilizzati anche i decimali +explorer.search.selectUser=Seleziona utente ... +explorer.search.byUserDesc=Cerca per utente creatore / modificatore +explorer.search.total=Trovati +explorer.search.noResult=Spiacenti, non ci sono risultati di ricerca, prova un altro termine di ricerca! +explorer.search.advance=Ricerca avanzata +explorer.search.clear=Cancella contenuto +explorer.history.list=Cronologia del file +explorer.history.lastModify=Ultima modifica +explorer.history.modifyUser=Modificato da +explorer.history.noHistory=Nessuna versione storica! +explorer.history.current=Versione corrente +explorer.history.detil=Commenti +explorer.history.detilAdd=Aggiungi impronta +explorer.history.uploadNew=Upload nuova versione +explorer.history.diff=Confronto tra versioni +explorer.history.setCurrent=Imposta come versione corrente +explorer.history.delCurrent=Elimina questa versione +explorer.history.delAll=Elimina tutta la cronologia delle versioni +explorer.history.ifDelAll=Sei sicuro di voler eliminare tutta la cronologia? +explorer.history.ifDelCurrent=Elimina questa versione? +explorer.history.ifRollback=Sei sicuro di voler tornare a questa versione? +explorer.history.changeEvent=Cambio di versione storica +explorer.history.before=Prima +explorer.history.after=dopo +explorer.recycle.clearUser=Svuota il cestino dell'utente +explorer.recycle.restoreSelect=Ripristina questo contenuto +explorer.recycle.moveTo=Devolvere +explorer.recycle.config=Impostazioni del cestino +explorer.recycle.configTitle=Impostazioni del cestino di sistema +explorer.recycle.configOpen=Apri il cestino del sistema +explorer.recycle.configOpenDesc=Suggerisci di aprire +explorer.recycle.configCloseInfo=Quando si elimina il contenuto, non entrerà nel cestino del sistema; verrà eliminato direttamente. +explorer.recycle.configOpenInfo=
  • Documenti personali o documenti dipartimentali, dopo aver completamente cancellato o svuotato il cestino, entrare nel cestino del sistema
  • Il contenuto eliminato viene classificato nella cartella dell'utente o del reparto in base all'utente o al reparto in cui si trova il file e l'amministratore può scegliere di ripristinare questi file;
  • I file prima del momento della cancellazione automatica completa verranno automaticamente svuotati regolarmente;
  • Nota: i file eliminati qui non possono essere recuperati.
  • +explorer.recycle.configClear=Elimina completamente automaticamente +explorer.recycle.restoreConfirm=Sei sicuro di ripristinare il documento?
    Dopo il ripristino, il documento verrà spostato nella directory principale di destinazione +explorer.recycle.moveConfirm=Conferma la consegna +explorer.recycle.moveSelectTarget=Seleziona utente o gruppo +explorer.recycle.moveDesc=
  • Consegnare all'utente o al reparto designato; migrerà alla directory principale dell'oggetto
  • Dopo la consegna, le descrizioni dei documenti, gli scambi e le discussioni, le versioni storiche e altre informazioni continueranno a essere conservate; la collaborazione condivisa e le informazioni sui permessi verranno rimosse
  • +explorer.recycle.taskTitle=Pulizia del cestino del sistema +explorer.recycle.taskDesc=Elimina automaticamente il contenuto del cestino che supera il tempo impostato per liberare spazio di archiviazione +explorer.share.add=Aggiungi condivisione +explorer.share.edit=Modifica condivisione +explorer.share.remove=Annulla condivisione +explorer.share.path=Condividi percorso +explorer.share.source=Condivisione delle risorse +explorer.share.name=Titolo link +explorer.share.nameDesc=Condividi il nome del file per impostazione predefinita, può essere personalizzato +explorer.share.time=Scadenza +explorer.share.timeLimit=Tempo limitato +explorer.share.timeLimitDesc=Se attivo, la condivisione si annullerà automaticamente quando impostato +explorer.share.timeDesc=Non impostato se vuoto +explorer.share.pwd=Password +explorer.share.pwdDesc=Nessuna password impostata +explorer.share.randomPwd=Genera +explorer.share.randomPwdDesc=Può essere visualizzato solo inserendo questa password. +explorer.share.cancel=Annulla condivisione +explorer.share.create=Crea link pubblico +explorer.share.url=Indirizzo condiviso +explorer.share.noDown=Download vietato +explorer.share.codeRead=Lettura del codice +explorer.share.configSave=Salva la configurazione +explorer.share.errorParam=Errore nei parametri! +explorer.share.errorUser=Le informazioni dell'utente sono errate! +explorer.share.errorSid=La condivisione non esiste! +explorer.share.errorTime=Sei in ritardo, questa quota è scaduta! +explorer.share.errorPath=Il file condiviso non esiste, è stato eliminato o spostato! +explorer.share.errorPwd=Password errata +explorer.share.errorShowTips=Questo tipo di file non supporta l'anteprima +explorer.share.expiredTips=Spiacenti, questa condivisione è scaduta! +explorer.share.downExceedTips=Spiacenti, è stato superato il limite massimo di download per questa condivisione! +explorer.share.store=Salva su SkyDrive +explorer.share.loginTips=Spiacenti, per accedere è necessario che l'utente abbia effettuato l'accesso. +explorer.share.noDownTips=Spiacente, il downloader ha disabilitato il download! +explorer.share.noViewTips=Spiacenti, questo condivisore ha disabilitato l'anteprima! +explorer.share.noUploadTips=Spiacenti, il caricamento è disabilitato da questo condivisore! +explorer.share.needPwd=Questa condivisione richiede una password +explorer.share.notExist=Link condivisione non valido! +explorer.share.viewNum=Visualizzazioni: +explorer.share.downNum=Limite download +explorer.share.openPage=Apri pagina condivisa +explorer.share.openLink=Apri link di condivisione +explorer.share.copyLink=Copia link condivisione +explorer.share.link=Link condivisione: +explorer.share.accessPwd=Password d'accesso: +explorer.share.copied=Copiato +explorer.share.actionNotSupport=Condividi contenuti, questa operazione non è supportata +explorer.share.errorPathTips=Il link di condivisione è errato, scaduto o annullato +explorer.share.shareTo=Condivisione collaborativa +explorer.share.shareToTarget=Collaboratore +explorer.share.innerTo=Collaborazione interna +explorer.share.linkTo=Condividi +explorer.share.selectTarget=Seleziona un gruppo o un utente per la condivisione collaborativa +explorer.share.afterShareDesc=Dopo aver condiviso con l'altra parte o il reparto a cui appartengono, gli utenti possono vederlo in [Condividi con me]. +explorer.share.openOuterLink=Condivisione +explorer.share.openOuterLinkDesc=Dopo aver creato un link di condivisione, è possibile inviarlo ad altri via e-mail oppure condividerlo su altre apps. +explorer.share.outerLink=Link condivisione +explorer.share.advanceSet=Configurazione avanzata +explorer.share.loginLimit=Solo utenti interni +explorer.share.loginLimitDesc=Possono accedere al file solo i membri interni registrati. +explorer.share.authLimit=Diritti e restrizioni +explorer.share.canUpload=Consenti upload +explorer.share.notView=Disabilita anteprima +explorer.share.notDown=Disabilita download +explorer.share.downNumLimit=Limite di download +explorer.share.downNumLimitDesc=Dopo questo numero di volte, il collegamento di condivisione scade automaticamente. +explorer.share.learnAuth=Panoramica permessi +explorer.share.shareToRemove=Sei sicuro di annullare questa condivisione collaborativa?
    L'utente di destinazione con cui ha effettuato la collaborazione, non potrà più accedere ai file +explorer.share.shareLinkRemove=Sei sicuro di annullare la condivisione del link esterno?
    Dopo la cancellazione, il link esterno non sarà più valido +explorer.share.shareToCopy=Copia percorso di accesso +explorer.share.shareToCopyDesc=Il collegamento può essere inviato alla persona che collabora e accedere rapidamente alla collaborazione +explorer.share.specifyAuthTips=Oltre agli utenti sopra specificati +explorer.share.specifyAuthDesc=Specifica diritti utente Utente> Specifica reparto diritti utente> Altri diritti +explorer.share.selfAuthDesc=Impossibile modificare le proprie autorizzazioni, è possibile impostare altri gestori +explorer.share.authTypeDesc=Eredita le autorizzazioni dalla cartella principale per impostazione predefinita +explorer.share.rootPathAuthDesc=Reparto di appartenenza e selezione utenti +explorer.share.subPathAuthDesc=Sotto-gruppo, seleziona solo i membri del gruppo +explorer.share.myAuth=Autorizzazioni +explorer.share.othersAuth=Altre autorizzazioni +explorer.share.keepAuth=Mantieni le autorizzazioni originali +explorer.share.specifyAuth=Specifica le autorizzazioni +explorer.share.userAuth=Diritti dell'utente +explorer.share.specifyUserAuth=Specifica delle autorizzazioni utente +explorer.share.rptTitle=Se ritieni che questa condivisione sia illegale o dannosa, puoi inviare una segnalazione all'amministratore di sistema. +explorer.share.illegal=Contenuti illegali +explorer.share.inputRptDesc=Inserisci il motivo della segnalazione +explorer.share.rptSend=Segnalazione inviata all'amministratore +explorer.share.rptSended=Segnalazione già inviata, attendi che l'amministratore la elabori +explorer.auth.mutil=Imposta le autorizzazioni in batch +explorer.auth.mutilTips=Nota: Se l'oggetto dispone già di un autorizzazione, questa verrà sovrascritta. +explorer.auth.mutilDesc=Contemporaneamente ai successivi permessi di default +explorer.auth.showMore=Dettagli di autorizzazione +explorer.auth.tabUser=membro del dipartimento +explorer.auth.tabChildren=Autorizzazioni per le sottocartelle +explorer.auth.tabUserTips=Autorizzazioni iniziali dei membri del dipartimento +explorer.auth.tabChildrenTips=Contenuti con autorizzazioni impostate in questa cartella +explorer.auth.resetUser=Sostituisci l'impostazione di questa autorizzazione utente +explorer.auth.resetUserBtn=Sostituisci le autorizzazioni +explorer.auth.resetUserBtnTips=Sostituisci le autorizzazioni dell'utente e di tutte le sottocartelle (cartelle) in questa cartella +explorer.auth.resetUserHeader=La cartella di livello inferiore contiene il contenuto che specifica le autorizzazioni dell'utente e imposta tutte le sostituzioni sulle autorizzazioni precedenti +explorer.auth.resetUserContiner=Contiene il contenuto dell'autorizzazione dell'utente +explorer.auth.resetUserEmpty1=Non sono presenti contenuti per i quali sono impostate autorizzazioni per questo utente, non è necessario sovrascriverlo +explorer.auth.resetUserEmpty2=Tutto il contenuto figlio eredita le autorizzazioni della cartella del livello corrente +explorer.rename.mutil=Rinomina in batch +explorer.rename.nameBefore=Nome del file originale +explorer.rename.nameTo=Rinomina +explorer.rename.start=Rinomina ora +explorer.rename.clearFinished=Pulisci completati +explorer.rename.clearAll=Cancella tutto +explorer.rename.typeReplaceAll=Sostituisci tutto +explorer.rename.typePrepend=Aggiungi prima +explorer.rename.typeAppend=Aggiungi più tardi +explorer.rename.typeReplace=Trova e sostituisci +explorer.rename.typeChangeCase=Conversione di casi +explorer.rename.typeRemove=Elimina caratteri +explorer.rename.typeReplaceSet=Specificare la sostituzione in batch +explorer.rename.typeReplaceSetDesc=Sostituisci se sono uguali; ogni riga è separata da uno spazio e il nome del file non consente spazi; ad esempio: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Contenuto aggiuntivo +explorer.rename.find=ricercare +explorer.rename.replaceTo=Sostituito con +explorer.rename.caseUpperFirst=Capitale iniziale +explorer.rename.caseUpper=Tutto maiuscolo +explorer.rename.caseLower=Tutto minuscolo +explorer.rename.removeStart=Rimuovi da zero +explorer.rename.removeEnd=Rimuovi dalla fine +explorer.rename.chars=carattere +explorer.editor.beautifyCode=Formattazione codice +explorer.editor.convertCase=Conversione di casi +explorer.editor.convertUpperCase=Converti in maiuscolo +explorer.editor.convertLowerCase=Converti in minuscolo +explorer.editor.currentTime=Ora corrente +explorer.editor.md5=Genera hash MD5 +explorer.editor.qrcode=Codice QR stringa +explorer.editor.regx=Test espressioni regolare +explorer.editor.chinese=Conversione semplificata +explorer.editor.chineseSimple=Converti in cinese semplificato +explorer.editor.chineseTraditional=Converti in cinese tradizionale +explorer.editor.base64=codec base64 +explorer.editor.base64Encode=Codifica base64 +explorer.editor.base64Decode=Decodifica base64 +explorer.editor.url=Codec URL +explorer.editor.urlEncode=Codifica URL +explorer.editor.urlDecode=Decodifica URL +explorer.editor.unicode=Codec Unicode +explorer.editor.unicodeEncode=Codifica Unicode +explorer.editor.unicodeDecode=Decodifica Unicode +explorer.editor.toolsSelectTips=Seleziona il contenuto corretto da elaborare! +explorer.editor.toolsRandString=Genera una stringa casuale a 32 bit +explorer.editor.textEncode=Codifica / decodifica del testo +explorer.editor.textParse=Elaborazione del testo +explorer.editor.timeShow=Timestamp al tempo +explorer.editor.timeInt=È ora di timestamp +explorer.editor.lineRemoveEmpty=Rimuovi righe vuote (spazi inclusi) +explorer.editor.lineUnoin=Rimuovi le righe duplicate +explorer.editor.lineTrim=Rimuovi gli spazi iniziali e finali +explorer.editor.lineSort=Ordina per riga (ordine crescente) +explorer.editor.lineReverse=Inverti tutte le righe +explorer.editor.lineSum=Somma +explorer.editor.lineAverage=Valore medio +explorer.editor.calc=Calcolatrice gratuita +explorer.editor.goToLine=Vai alla linea +explorer.editor.keyboardType=Modalità tastiera +explorer.editor.fontFamily=Caratteri +explorer.editor.codeMode=Evidenzia sintassi +explorer.editor.closeAll=Chiudi tutto +explorer.editor.closeLeft=Chiudi la scheda a sinistra +explorer.editor.closeRight=Chiudi scheda destra +explorer.editor.closeOthers=Chiudi altro +explorer.editor.wordwrap=A capo automatico +explorer.editor.showGutter=Mostra il numero di riga +explorer.editor.charAllDisplay=Mostra caratteri invisibili +explorer.editor.autoComplete=Prompt automatico +explorer.editor.autoSave=Salva automaticamente +explorer.editor.functionList=Elenco delle funzioni +explorer.editor.codeTheme=Stile codice +explorer.editor.fontSize=Dimensione carattere +explorer.editor.completeCurrent=Corrente di completamento automatico +explorer.editor.createProject=Aggiungi al progetto dell'editor +explorer.editor.markdownContent=Directory dei contenuti +explorer.editor.undo=Annulla +explorer.editor.redo=Ripeti +explorer.editor.shortcut=Tasti di scelta rapida +explorer.editor.replace=Sostituisci +explorer.editor.reload=Ricarica +explorer.editor.view=Vista +explorer.editor.tools=Strumenti +explorer.editor.help=Aiuto +explorer.sync.data=Sincronizzazione dei dati +explorer.sync.openLoc=Apri la directory locale +explorer.sync.syncing=sincronizzazione +explorer.sync.synced=Sincronizzazione completata +explorer.sync.syncedError=Registro degli errori +explorer.sync.syncStart=Inizia la sincronizzazione +explorer.sync.syncStop=Interrompere la sincronizzazione +explorer.sync.notOpenTips=Non hai attivato la sincronizzazione locale +explorer.sync.setNow=Imposta la sincronizzazione ora +explorer.sync.error=Caricamento non riuscito +explorer.sync.success=Sincronizzazione riuscita +explorer.sync.statusScan=scansione +explorer.sync.statusNone=La sincronizzazione non è configurata +explorer.sync.statusScanEnd=Scansione completata +explorer.sync.statusDoing=sincronizzazione +explorer.sync.statusDone=Sincronizzazione completata +explorer.sync.statusStop=pausa +explorer.sync.clearCacheSuccess=Svuota cache con successo! +explorer.sync.emptyTask=Nessuna attività di sincronizzazione +explorer.sync.openCloud=Apri posizione cloud +explorer.sync.openLocal=Apri localmente +explorer.sync.statusFiles=Progresso del documento +explorer.sync.statusLastTime=Tempo di completamento +explorer.sync.configName=Sincronizza impostazioni +explorer.sync.configClient=Impostazioni client +explorer.sync.configAbout=About +explorer.sync.configSyncFrom=Percorso locale +explorer.sync.configSyncFromDesc=Seleziona una cartella locale da sincronizzare +explorer.sync.configSyncTo=Sincronizza con +explorer.sync.configSyncToDesc=Sincronizzazione con la posizione del server +explorer.sync.configIgnore=Tipi di file ignorati +explorer.sync.configIgnoreDesc=I file di questo tipo non sono sincronizzati +explorer.sync.autorun=Boot fin dall'inizio +explorer.sync.configThread=Numero di thread simultanei +explorer.sync.configThreadDesc=Numero di file caricati contemporaneamente +explorer.sync.configDownloadPath=Percorso di download +explorer.sync.configDownloadPathDesc=Percorso di download predefinito durante il download di cartelle di file +explorer.sync.configClearCacheAuto=Cancella automaticamente la cache +explorer.sync.configClearCacheAutoDesc=Cancella automaticamente il file della cache N giorni fa +explorer.sync.configClearCache=Cancella cache +explorer.sync.configChangeSite=Esci dal sito corrente +explorer.sync.configVersion=Versione corrente +explorer.sync.configUpdateDesc=Istruzioni per l'aggiornamento +explorer.sync.configUpdateCheck=Controlla aggiornamenti +explorer.sync.confirmReset=Sincronizza modifica directory, le informazioni di sincronizzazione verranno ripristinate. Sei sicuro di salvare? +explorer.sync.listClearDone=Pulisci completati +explorer.sync.listClearError=Cancella elenco errori +explorer.sync.listRetryAll=Riprova tutto +explorer.async.tipsDisablePath=Non supporta la scelta di sincronizzare il percorso +explorer.async.tipsIsMoving= +explorer.async.tipsStartUser=Inizia la sincronizzazione manualmente +explorer.download.title=Gestione dei download +explorer.download.waiting=In attesa +explorer.download.stop=Metti in pausa il download +explorer.download.start=Inizia il download +explorer.download.remove=Rimuovi attività +explorer.download.stopAll=Metti tutto in pausa +explorer.download.startAll=Continua tutto +explorer.download.clearAll=Cancella tutte le attività +explorer.download.doing=in lavorazione +explorer.download.done=Download completato +explorer.download.clearAllTips=Sei sicuro di eliminare tutte le attività di download? +explorer.tag.name=Etichette +explorer.tag.edit=Gestione delle etichette +explorer.tag.add=Crea un'etichetta +explorer.tag.remove=Sei sicuro di voler eliminare questo tag? +explorer.tag.inputHolder=Inserisci un nome per l'etichetta +explorer.tag.addTo=Imposta etichetta +explorer.tag.default1=Libri da leggere +explorer.tag.default2=Album foto gita +explorer.tag.default3=Contabilità +explorer.tag.filter=Filtra per etichette +explorer.groupTag.title=Etichetta pubblica +explorer.groupTag.menuTtitle=Etichetta pubblica del gruppo +explorer.groupTag.titleDesc=Etichetta pubblica all'interno del gruppo +explorer.groupTag.empty= +explorer.tag.pathDesc=Filtra per etichetta personale +explorer.groupTag.pathDesc=Filtra per etichetta pubblica del gruppo +explorer.groupTag.removeTypeTips=Eliminare questo gruppo? Tutti i documenti associati all'etichetta verranno rimossi! +explorer.groupTag.removeTagTips=Sei sicuro di voler eliminare questa etichetta? I documenti associati al tag verranno rimossi! +explorer.groupTag.typeAdd=Aggiungi categoria +explorer.groupTag.typeName=Nome della categoria +explorer.groupTag.addDesc=Dopo aver aggiunto un etichetta, questa verrà abilitata automaticamente e il numero massimo è 1000 +explorer.panel.info=Attributi +explorer.panel.version=Versione +explorer.panel.chat=Chat +explorer.panel.log=Log +explorer.panel.meta=Metadati +explorer.panel.chatName=Messaggi +explorer.panel.chat.send=Invia +explorer.panel.chat.noAuth=Non sei autorizzato a commentare questo documento! +explorer.panel.chat.placeholder=Scrivi qui, [Invio] per inviare, [Ctrl + Invio] nuova riga +explorer.panel.chat.placeholderCtrl=Scrivi qui, Ctrl + Invio per inviare, Invio per andare a capo +explorer.panel.chat.reply=Rispondi +explorer.panel.chat.empty=Nessun messaggio +explorer.panel.chat.sendTo=Inoltra +explorer.panel.metaName=Estensione dei metadati +explorer.panel.metaDesc=Proprietà +explorer.panel.thumbClear=Svuota miniature +explorer.panel.thumbClearDesc=Cancella e rigenera le miniature dei file. +explorer.panel.historyName=Storico versioni +explorer.panel.historyDesc=Note di rilascio +explorer.panel.infoTips=Seleziona il file (cartella) per visualizzare le proprietà dettagliate +explorer.panel.info.space=Spazio disponibile +explorer.panel.info.groupAt=Posizione del gruppo +explorer.panel.info.tagEmpty=Nessuna etichetta, fai clic su Impostazioni +explorer.panel.logName=Cronologia attività +explorer.panel.logEmpty=Nessuna attività +explorer.type.doc=Documenti +explorer.type.image=Immagini +explorer.type.music=Musica +explorer.type.movie=Video +explorer.type.zip=Archivio +explorer.type.others=Altro +explorer.secret.title=Gestione della riservatezza dei documenti +explorer.secret.isOpen=Se abilitare +explorer.secret.isOpenDesc=Abilita e disabilita la gestione del livello di sicurezza +explorer.secret.setUser=gestore segreto +explorer.secret.setUserDesc=Specificare l'utente che può impostare il livello di riservatezza (deve essere contemporaneamente titolare nel reparto corrispondente) +explorer.secret.type=Tipo di classificazione +explorer.secret.add=Aggiungi livello di sicurezza +explorer.secret.edit=modificare il livello di sicurezza +explorer.secret.name=Nome della classe +explorer.secret.style=stile +explorer.secret.auth=Autorizzazione a livello segreto +explorer.secret.authHas=Le autorizzazioni riservate includono +explorer.secret.createUser=setter +explorer.secret.folderAt=cartella riservata +explorer.secret.tips=Le autorizzazioni sono controllate dal livello di segreto e le autorizzazioni a livello di segreto sono superiori alle autorizzazioni del documento +explorer.secret.tips1= +explorer.secret.tips2=Viene impostato tutto il contenuto nel livello inferiore della cartella con il livello di riservatezza e questa autorità è l'autorità più alta +explorer.secret.tips3= +explorer.secret.tips4=Autorizzazioni a livello di riservatezza: possono essere aggiunte in "Gestione reparto e membri--Gestione diritti documento" e impostate come nascoste +user.displayHideFile=Mostra file nascosti +user.displayHideFileDesc=I file che iniziano con '.' e i file nascosti dal sistema serranno visualizzati +user.soundOpen=Abilita suoni +user.animateOpen=Abilita animazioni +user.recycleOpen=Abilita il cestino +user.recycleDesc=Se abilitato, i file eliminati saranno spotati nel cestino. Si consiglia di abilitare +user.animateDesc=Abilita animazioni delle finestre +user.soundDesc=Abilita i suoni su: apri file, elimina file, svuota cestino, ecc. +user.thumbOpen=Abilita anteprima +user.thumbDesc=Se abilitato, permette la visualizzazione delle anteprime delle immagini +user.fileSelect=Icona apri file +user.fileSelectDesc=Abilita il menu di scelta rapida sull'icona del file +user.fileShowDesc=Mostra introduzione cartella +user.fileShowDescTips=Modalità solo icone +user.fileOpenClick=Aprire il file (cartella) come segue +user.fileOpenClick.dbclick=Apri con doppio clic +user.fileOpenClick.click=Apri cliccando +user.viewSetting=Mostra opzioni +user.thirdAccount=App di terze parti +user.bindAccount=Conto vincolante +user.thirdBindFirst=L'account non è stato vincolato, si prega di utilizzare dopo l'associazione +user.account=Account +user.bind=legame +user.unbind=unbundling +user.binded=legato +user.clickBind=Fai clic su Associa +user.clickToBind=Nessun impegno, fare clic su Associa +user.clickEditPwd=Fai clic su Modifica password +user.userAvatar=Foto del profilo +user.userNickName=Nickname +user.userAccount=Conto personale +user.uploadAvatar=Carica avatar +user.userAvatarCrop=Seleziona un'area adatta come avatar +user.userAvatarExt=Supporta solo i formati di immagine JPG, JPEG, PNG +user.resetPwdDesc=Hai dimenticato la password? +user.inputEmailCode=Inserisci il tuo codice di verifica e-mail +user.inputSmsCode=Inserisci il codice di verifica SMS +user.emailVerifyDesc=Alcune aziende richiedono la verifica tramite e-mail +user.phoneVerifyDesc=Alcune aziende richiedono la verifica del telefono cellulare +user.bindOthers=Già associato a un altro account +user.notBind=Non ancora legato +user.regist=Registrazione dell'utente +user.notRegist=Non registrato +user.registed=Già registrato +user.signError=La firma del callback è errata +user.repeat=Ripeti +user.noRepeat=Non sono ammessi duplicati +user.newPwd=Nuova password +user.unAuthFile=Accesso ai file non autorizzato +user.unbindWarning=Modifica la password prima di annullare l'associazione, altrimenti l'account non funzionerà correttamente +user.isLoginTips=Viene rilevato che sei attualmente connesso! +user.isLoginEnter=Entra ora +user.ifUnbind=Sei sicuro di voler rilassare? +user.bindFirst=Si prega di associare prima l'e-mail o il numero di cellulare +user.inputNewPwd=Per favore inserisci una nuova password +user.inputNewValue=Si prega di compilare il nuovo contenuto +user.guestLogin=Login guest +user.name=Account +user.nickName=Nickname +user.code=Codice di verifica +user.codeError=Errore del codice di verifica +user.imgCode=Captcha +user.rootPwd=Imposta la password dell'amministratore +user.rootPwdRepeat=Conferma di nuovo la password +user.rootPwdEqual=Le password non corrispondono due volte! +user.rootPwdTips=Si prega di impostare una password amministratore! +user.pwdError=Nome utente o password errati! +user.pwdNotNull=La password non può essere vuota! +user.oldPwdError=La password originale è sbagliata! +user.keepPwd=Ricorda password +user.forgetPwd=Password dimenticata +user.directLogin=Accedi con un account +user.moreLogin=Altri modi per accedere +user.loginNow=Accedi ora +user.registNow=Iscriviti adesso +user.backHome=Torna alla home +user.ifHasAccount=Hai già un account? +user.userEnabled=L'account è disabilitato o non ancora abilitato! Si prega di contattare l'amministratore +user.roleError=Il gruppo di autorizzazioni non esiste, contattare l'amministratore +user.invalidEmail=Non hai un indirizzo email valido, contatta l'amministratore per modificarlo +user.codeRefresh=Fare clic su Aggiorna +user.emailVerify=Autenticazione della cassetta postale +user.sendSuccess=Inviato con successo +user.sendFail=Invio non riuscito +user.sendSuccessDesc=Codice di verifica inviato con successo, vai alla visualizzazione +user.sendFailDesc=Impossibile inviare il codice di verifica, contattare l'amministratore +user.inputVerifyCode=Inserisci il codice di verifica +user.getCode=Ottieni il codice di verifica +user.inputPwd=Per favore inserisci la password +user.inputPwdAgain=Inserisci di nuovo la password +user.inputNickName=Per favore, inserisci un soprannome +user.inputEmail=Per favore inserisci il tuo indirizzo email +user.inputPhone=Per favore inserisci il tuo numero di telefono +user.inputPhoneEmail=Si prega di inserire cellulare / email +user.invalidPhoneEmail=Telefono / Email non valido +user.findPwd=Recupera password +user.inputNotMatch=Il %s inserito non corrisponde al limite +user.usingDesc=Stai usando +user.improveInfo=Si prega di completare le informazioni +user.codeExpired=Il codice di verifica è scaduto, ti preghiamo di ottenerlo di nuovo +user.codeErrorTooMany=Troppi errori del codice di verifica, acquisire nuovamente +user.codeErrorFreq=La frequenza di invio è troppo alta, riprova più tardi! +user.codeErrorCnt=Il numero di invii ha superato il limite e verrà bloccato per %s ore. +user.registSuccess=Registrato con successo +user.waitCheck=In attesa di revisione da parte dell'amministratore +user.nameHolder=Inserisci il tuo numero di telefono / e-mail +user.loginNoPermission=Siamo spiacenti, non disponi di questa autorizzazione, accedi con un account con questa autorizzazione! +user.loginFirst=Non sei loggato! Effettua prima il login +user.bindSignError=La firma è anormale, riprova! +user.bindUpdateError=Aggiornamento informazioni utente non riuscito, riprovare +user.bindTypeError=Tipo di associazione non valido +user.bindWxConfigError=Ottieni l'eccezione delle informazioni di configurazione +user.loginTimeout=Il login attuale è scaduto, accedi di nuovo! +user.theme=Stile tema +user.theme.desc=Selezionando 'Automatico' il tema cambia in base al sistema +user.theme.light=Colore chiaro +user.theme.dark=Colore scuro +user.theme.auto=Automatico +user.theme.title=Impostazioni del tema personalizzate +user.theme.background=sfondo +user.theme.image=immagine +user.theme.colorBlur=Colore sfumato +user.theme.imageBlur=Elaborazione della sfocatura dell'immagine +user.theme.imageUrl=Indirizzo immagine +user.theme.colorStart=Inizia il colore +user.theme.colorEnd=Colore finale +user.theme.colorRadius=Angolo di gradiente +user.theme.themeImage=Immagine di sfondo +user.theme.themeImageDesc=Supporta: URL dell'immagine, colore CSS sfumato, sfondo del desktop +user.theme.imageWall=Sfondo del desktop +user.wall.random=Sfondo casuale +user.wall.paperDesktop=Sfondi desktop +user.wall.paperDeskMgt=Gestione dello sfondo del desktop +user.wall.paperLoginMgt=Gestione sfondi per l'accesso +user.wall.paperLoginTips=Quando è presente più di un'immagine, lo sfondo dell'interfaccia di accesso ruoterà in modo casuale +log-type-create-mkdir=nuova cartella +log-type-create-mkfile=crea un nuovo file +log-type-create-upload=caricare files +log-type-create-copy=Incolla file +log-type-edit=File di aggiornamento +log-type-move=Sposta file +log-type-moveOut=Rimuovi i file +log-type-share-shareLinkAdd=Creata condivisione link +log-type-share-shareToAdd=Creata condivisione collaborativa +log-type-share-shareLinkRemove=Condivisione link chiusa +log-type-share-shareToRemove=Condivisione collaborativa chiusa +log-type-share-shareEdit=Condivisione modificata +log-type-rename=Rinomina +log-type-recycle-toRecycle=Sposta nel cestino +log-type-recycle-restore=Ripristina dal cestino +log-type-remove=Elimina +log-type-addDesc=Modifica descrizione +log-type-addComment=Posta un commento +log-event-create-mkdir=Creata questa cartella +log-event-create-mkfile=Creato il file +log-event-create-upload=Ha caricato il file +log-event-create-copy=Il file è stato creato incollando +log-event-create-mkdir-current=Creata una nuova cartella {0} +log-event-create-mkfile-current=Nuovo file creato {0} +log-event-create-upload-current=Caricato {0} +log-event-create-copy-current=Incollato {0} +log-event-create-mkdir-item=Creata una nuova cartella {1} in {0} +log-event-create-mkfile-item=Creato {1} in {0} +log-event-create-upload-item=Caricato {1} in {0} +log-event-create-copy-item=Incolla {0} in {1} +log-event-create-mkdir-more=Create {0} cartelle +log-event-create-mkfile-more={0} nuovi file creati +log-event-create-upload-more={0} file caricati +log-event-create-copy-more=File {0} incollati +log-event-create-mkdir-more-at=Creato {1} nuove cartelle in {0} +log-event-create-mkfile-more-at=Creato {1} nuovi file in {0} +log-event-create-upload-more-at={1} file caricati su {0} +log-event-create-copy-more-at={0} file incollati su {1} +log-event-view-item=Visto {0} +log-event-edit=File aggiornato +log-event-edit-item=Modificato {0} nell'editor +log-event-edit-more=L'editor ha aggiornato il file {0} volte +log-event-edit-more-user=Modificato e aggiornato il file {0} {1} volte +log-event-edit-more-at=File modificati e aggiornati {1} in {0} +log-event-move=Spostato il documento da {0} a {1} +log-event-move-item=Spostato {0} da {1} a [3] +log-event-move-current=Spostato {0} da {1} +log-event-move-more={0} file spostati +log-event-move-more-desc=Spostato {0} da {1} a [3] +log-event-moveOut-more-desc=Rimosso {1} da {0} +log-event-moveOut=Rimosso da qui {0} +log-event-moveOut-item=Rimosso {1} da {0} +log-event-moveOut-more={0} file rimossi +log-event-share-shareLinkAdd=Creato un link condivisione +log-event-share-shareLinkAdd-item={0} ha creato un link di condivisione +log-event-share-shareLinkAdd-more=Creato {0} collegamenti di condivisione +log-event-share-shareToAdd=Attivata la condivisione collaborativa +log-event-share-shareToAdd-item=Attivata la condivisione collaborativa di {0} +log-event-share-shareToAdd-more={0} condivisioni condivise create +log-event-share-shareLinkRemove=Annullata la condivisione esterna del documento +log-event-share-shareLinkRemove-item=Condivisione esterna di {0} annullata +log-event-share-shareLinkRemove-more=Chiusa {0} condivisione link esterno +log-event-share-shareToRemove=Disattivata la condivisione collaborativa +log-event-share-shareToRemove-item=Disattivata la condivisione della collaborazione per {0} +log-event-share-shareToRemove-more=Chiusa {0} condivisione collaborativa +log-event-share-shareEdit=Condivisione modificata +log-event-share-shareEdit-item=Condivisione di {0} modificata +log-event-share-shareEdit-more=Modificati {0} file da condividere +log-event-rename=Rinominato +log-event-rename-item=Rinominato {0} +log-event-rename-more={0} file rinominati +log-event-recycle-toRecycle=Spostato nel cestino +log-event-recycle-toRecycle-current=Spostato {0} nel cestino +log-event-recycle-toRecycle-item=Spostato {1} da {0} nel cestino +log-event-recycle-toRecycle-more=Spostati {0} file nel Cestino +log-event-recycle-toRecycle-more-at=Spostato {1} file su {0} nel Cestino +log-event-recycle-restore=Ripristinato dal cestino +log-event-recycle-restore-item=Ripristinato {0} dal cestino +log-event-recycle-restore-more=Ripristinati {0} file dal cestino +log-event-remove=Eliminato {0} qui +log-event-remove-current=Eliminato {0} qui +log-event-remove-item=Eliminato {1} da {0} +log-event-remove-more={0} file eliminati +log-event-remove-more-at=Eliminati {1} file su {0} +log-event-addDesc=Modificata la descrizione del documento +log-event-addDesc-item=Descrizione del documento {0} modificata +log-event-addDesc-more=Descrizioni di documento {0} modificate +log-event-addComment=Commentato su questo documento +log-event-addComment-item=Commentato su {0} +log-event-addComment-more=Elencati {1} commenti in {0} +log-event-fav-fileAdd=Segnalibro {0} +log-event-fav-dirAdd=Cartelle con segnalibro {0} +log-event-down-item=Scaricato {1} da {0} +log-event-down-items=Scaricato da {0} +log-event-recycle-del-item=Elimina {0} file dal cestino +log-event-recycle-rst-item=Ripristina {0} file dal cestino +log-event-del-item={0} file eliminati +log.file.move=Sposta +log.file.fav=Operazione Preferiti +log.file.shareLink=Condividi tramite link +log.file.shareTo=Condivisione collaborativa +log.user.edit=Modifica le informazioni sull'account +log.group.edit=Gruppo modificato +log.member.edit=Gestione utenti +log.role.edit=Gestione dei ruoli +log.auth.edit=Gestione dei diritti sui file +meta.user_sourceAlias=File correlati (allegati) +meta.user_fileEncodeType=Riservatezza dei file +meta.user_fileEncodeType.A=Top secret +meta.user_fileEncodeType.B=Confidenziale +meta.user_fileEncodeType.C=Segreto +meta.user_sourceNumber=Numero di volume +meta.user_sourceParticipant=Partecipante +explorer.fileInfo.createTime=Data di creazione +explorer.fileInfo.modifyTime=Data modificata +explorer.fileInfo.softwareCreate=Software di produzione +explorer.fileInfo.software=Software di codifica +explorer.fileInfo.playTime=Durata +explorer.fileInfo.imageSize=Dimensione +explorer.fileInfo.imageDpi=Risoluzione +explorer.fileInfo.imageBits=Profondità bit +explorer.fileInfo.imageDesc=Annotazione +explorer.fileInfo.imageAuthor=Autore +explorer.fileInfo.imageColor=Spazio colore +explorer.fileInfo.cameraType=Modello dispositivo +explorer.fileInfo.cameraApertureFNumber=Numero di apertura +explorer.fileInfo.cameraApertureValue=Valore di apertura +explorer.fileInfo.cameraShutterSpeedValue=Velocità otturatore +explorer.fileInfo.cameraExposureTime=Tempo di esposizione +explorer.fileInfo.cameraFocalLength=lunghezza focale +explorer.fileInfo.cameraFocusDistance=Distanza di messa a fuoco +explorer.fileInfo.cameraISOSpeedRatings=Sensibilità ISO +explorer.fileInfo.cameraWhiteBalance=Bilanciamento bianco +explorer.fileInfo.cameraUser=Manuale +explorer.fileInfo.cameraAuto=Automatico +explorer.fileInfo.cameraExposureMode=Modalità di esposizione +explorer.fileInfo.cameraExposureBiasValue=Compensazione dell'esposizione +explorer.fileInfo.imageGps=Coordinate +explorer.fileInfo.imageCreateTime=Data e ora +explorer.fileInfo.audioChannel=Canale audio +explorer.fileInfo.audioChannel1=Mono +explorer.fileInfo.audioChannel2=Stereo +explorer.fileInfo.audioChannels=Multicanale +explorer.fileInfo.audioRate=Frequenza di campionamento +explorer.fileInfo.audioBits=Profondità bit audio +explorer.fileInfo.audioBitrate=Bitrate audio +explorer.fileInfo.vedioFormat=Codifica video +explorer.fileInfo.audioTitle=Titolo +explorer.fileInfo.audioAuthor=Autore +explorer.fileInfo.audioAlbum=Album +explorer.fileInfo.audioStyle=Genere +explorer.fileInfo.audioYear=Anno album +explorer.fileInfo.vedioSize=Dimensioni +explorer.fileInfo.vedioFrame=Frequenza fotogrammi +explorer.fileInfo.vedioBitrate=Bitrate video +explorer.fileInfo.title=Titolo +explorer.fileInfo.author=Autore +explorer.fileInfo.pageTotal=Pagine totali +explorer.fileInfo.pageSize=Dimensioni della pagina +explorer.fileInfo.pagePower=Creatore del contenuto +explorer.fileInfo.pdfVersion=Versione PDF +explorer.filter.shareCopyLimit=Il numero di file da scaricare supera il limite; il numero massimo di file che puoi scaricare è: +explorer.filter.shareSizeLimit=La dimensione del file condiviso supera il limite; il massimo che puoi condividere è: +explorer.filter.unzipSizeLimit=La dimensione del file da decomprimere supera il limite; il massimo che puoi decomprimere è: +explorer.filter.zipSizeLimit=La dimensione dei file compressi supera il limite; i tuoi file comprimibili massimi: +explorer.filter.uploadSizeLimit=La dimensione del caricamento supera il limite; il massimo che puoi caricare è: +explorer.fileEditError=Il file %s corrente è attualmente in fase di modifica. Riprova più tardi +explorer.groupDelError=Spiacenti, le cartelle dei reparti non supportano la cancellazione +admin.info.typeDelError=Eliminazione non riuscita con sottocategorie o dati +admin.info.domainIdentifyError=Sito web non riconosciuto +admin.info.articleIdentifyError=Articolo non riconosciuto +admin.info.domainSupportError=Questo sito attualmente non supporta la raccolta +admin.info.fileTooLarge=File troppo grande +explorer.toolbar.info=informazioni in tempo reale +source.shareDisabled=La risorsa corrente è vietata dalla condivisione +admin.exceeds.limit=Superamento del limite +admin.design.deleted=Impossibile eliminare lo stato di abilitazione +admin.design.url.locked=L'URL corrente è bloccato e non può essere utilizzato temporaneamente +explorer.SING_INVALID=Eccezione di firma +explorer.TEMP_AUTH_INVALID=Il codice di autorizzazione temporanea non è valido (non valido) +explorer.QR_INVALID=Il codice QR è scaduto +explorer.toolbar.toolbox=Scatola degli strumenti +explorer.toolbox.desc= +logs-detail-mkdir=Creata una nuova cartella +logs-detail-mkfile=Creato un nuovo file +logs-detail-editFile=L'editor ha aggiornato +logs-detail-upload=File caricati +logs-detail-uploadNew=Modificato +logs-detail-file.upload=Caricato +logs-detail-file-copy=Incolla file creato +logs-detail-folder-copy=Incolla cartella creata +logs-detail-paste=pasta +logs-detail-from=da +logs-detail-to=reach +logs-detail-rename=Rinominato +logs-detail-rename-file=Rinominato il file +logs-detail-rename-folder=Rinominata la cartella +logs-detail-user=utente: +logs-detail-moveFrom-restore=prendere +logs-detail-moveTo-restore=Ripristina dal cestino +logs-detail-move=prendere +logs-detail-moveTo=Sposta a +logs-detail-moveFrom-toRecycle=prendere +logs-detail-moveTo-toRecycle=Spostato nel cestino +logs-detail-file-toRecycle=Spostato il file nel Cestino +logs-detail-file-restore=Ripristina questo file dal Cestino +logs-detail-folder-toRecycle=Spostata questa cartella nel Cestino +logs-detail-folder-restore=Ripristina questa cartella dal Cestino +logs-detail-favAdd=Raccolta +logs-detail-favDel=Raccolta annullata +logs-detail-unstar=nome: +logs-detail-moveOut=Rimosso +logs-detail-remove=Rimosso +logs-detail-file.copy=Incollato +explorer.noPermissionAuthAll={0} ,Nessuna autorizzazione per questa operazione \ No newline at end of file diff --git a/src/main/resources/i18n/messages_ja_JP.properties b/src/main/resources/i18n/messages_ja_JP.properties new file mode 100644 index 0000000..a5ba927 --- /dev/null +++ b/src/main/resources/i18n/messages_ja_JP.properties @@ -0,0 +1,2559 @@ +admin.serverInfo=サーバー情報 +admin.today=今日 +admin.yesterday=昨日 +admin.weekDay=過去7日間 +admin.monthDay=過去30日 +admin.ing=進行中 +admin.paused=停止中 +admin.serverDownload=リモートダウンロード +admin.memberManage=ユーザー管理 +admin.fileManage=ファイル管理 +admin.pwdEdit=パスワードを変更する +admin.fileEdit=保存ファイルを編集 +admin.list=リストビュー +admin.configError=構成の保存に失敗しました。管理者がこの権限を無効にしています! +admin.userManage=パーソナルセンター +admin.manage=バックグラウンド管理 +admin.pluginManage=プラグイン管理 +admin.emailDear=こんにちは %s 、 +admin.emailCodeText=メールアドレスを確認しています。このリクエストの確認コードは次のとおりです。アカウントのセキュリティを確保するために、時間内に確認を完了してください。 +admin.emailVerifyInTime=アカウントのセキュリティを保護するために、時間内に確認を完了してください。 +admin.dear=尊敬する +admin.dearUser=親愛なるユーザー、 +admin.emailResetLink=%sのログインパスワードをメールアドレスでリセットしていますので、下記のリンクをクリックしてリセットしてください。リンクがジャンプできない場合は、ブラウザのアドレスバーにコピーしてアクセスしてください。 +admin.emailExpireTime=リンクは20分後に期限切れになります。 +admin.jobName=役職 +admin.jobDesc=職務内容 +admin.jobNameInput=ジョブ名を入力してください +admin.jobEdit=投稿エディター +admin.menu.home=ホーム +admin.menu.dashboard=概要 +admin.menu.dashboardTitle=統計の概要 +admin.menu.notice=通知管理 +admin.menu.groupMember=部門およびメンバー管理 +admin.menu.member=部門とユーザー +admin.menu.role=ロール管理 +admin.menu.job=ジョブ管理 +admin.menu.auth=ドキュメント権利管理 +admin.menu.storage=ストレージ/ファイル +admin.menu.storageDriver=ストレージ管理 +admin.menu.plugin=プラグインセンター +admin.menu.tools=安全管理 +admin.menu.server=サーバー管理 +admin.menu.backup=バックアップ管理 +admin.menu.share=共有管理 +admin.menu.loginLog=ログインログ +admin.menu.log=操作ログ +admin.menu.task=スケジュールされたタスク +admin.autoTask.restart=スケジュールされたタスクを再開する +admin.autoTask.restartEnd=スケジュールされたタスクが再開されました +admin.index.userSpace=ユーザースペース +admin.index.groupSpace=部門スペース +admin.index.folderCount=フォルダーの数: +admin.index.fileCount=ファイル数: +admin.index.loginToday=今日ログイン +admin.index.useTotal=総使用量: +admin.index.userLogin=ユーザーログイン +admin.index.spaceUsed=スペースをとる +admin.index.useSpace=使用スペース +admin.index.usedSpace=使用済みスペース +admin.index.freeSpace=残りスペース +admin.index.sizeLimit=限定サイズ +admin.index.vipCount=登録ユーザー +admin.index.loginCurrent=現在オンライン +admin.index.fileDel=ファイルの削除 +admin.index.fileEdit=ファイル編集 +admin.index.fileUpload=ファイルのアップロード +admin.index.fileDown=ドキュメントをダウンロード +admin.index.spaceUse=実用化 +admin.index.spaceSave=省スペース +admin.index.spaceUser=ユーザーの使用 +admin.index.spaceGroup=部門の使用 +admin.index.lastLogin=最終ログイン時刻 +admin.index.totalUsers=総ユーザー数 +admin.index.loginUsers=ログインユーザー +admin.index.spaceActUsed=実際の職業 +admin.index.source=ログインソース +admin.index.address=ログインアドレス +admin.index.userInfo=ユーザー情報 +admin.index.userValid=有効なアカウント +admin.index.userInvalid=無効なアカウント +admin.index.fileInfo=ファイル情報 +admin.index.fileCnt=ファイル数 +admin.index.fileAdd=今日追加されました +admin.index.accInfo=アクセス情報 +admin.index.accCnt=リクエスト +admin.index.accUser=アクセスユーザー +admin.index.serverInfo=システムメッセージ +admin.index.serverDisk=システムディスク +admin.index.serverStore=ネットワークストレージ +admin.index.serverName=サーバー名 +admin.index.normal=正常 +admin.index.scoreDesc=次の要因がシステムスコアに影響します。システムスコアは、システムが適切に実行されるように最適化できます。
    1.システムディスクおよびネットワークディスクストレージの残りのスペース。
    2.データキャッシュ方法(redisを推奨)。
    3.phpプラットフォームのバージョン(64ビットphp7 +を推奨)。 +admin.index.fileRatio=ファイル使用率 +admin.setting.system=システム設定 +admin.setting.account=アカウント設定 +admin.setting.theme=テーマ設定 +admin.setting.wall=壁紙の設定 +admin.setting.stats=使用統計 +admin.setting.safeMgt=セキュリティ管理 +admin.setting.base=基本設定 +admin.setting.others=その他の設定 +admin.setting.sync=同期設定 +admin.setting.plugin=プラグイン設定 +admin.setting.auth=許可設定 +admin.setting.safe=セキュリティ +admin.setting.loginLog=ログインログ +admin.setting.loginDevice=ログインデバイス +admin.setting.deviceType=機器タイプ +admin.setting.lastLoginTime=最終ログイン時間 +admin.setting.email=メール設定 +admin.setting.user=登録とログイン +admin.setting.pwdOld=元のパスワード +admin.setting.pwdNew=変更する +admin.setting.wallDiy=カスタム壁紙: +admin.setting.fav=お気に入り管理 +admin.setting.help=ヘルプを使用する +admin.setting.about=作品について +admin.setting.homePage=kodcloudホーム +admin.setting.subMenu=サブメニュー +admin.setting.menuName=メニュー名 +admin.setting.menuUrl=URLアドレス +admin.setting.menuUrlDesc=URLアドレスまたはjsコード +admin.setting.safeAccount=アカウントとログインのセキュリティ +admin.setting.safeData=データセキュリティ/伝送セキュリティ +admin.setting.passwordErrorLock=パスワード入力エラーロック +admin.setting.passwordErrorLockDesc=パスワードが5回連続して間違っていると、アカウントは1分間ロックされ、ログインできなくなります。開いた後は、パスワードが無理矢理解読されるのを効果的に防ぐことができます。 +admin.setting.passwordRule=ユーザーパスワードの強度設定 +admin.setting.passwordRuleDesc=パスワードの強度を指定すると、弱いパスワードを効果的に排除できます +admin.setting.passwordRuleNone=無制限 +admin.setting.passwordRuleStrong=中強度 +admin.setting.passwordRuleStrongMore=高強度 +admin.setting.passwordRuleNoneDesc=無制限のパスワード強度 +admin.setting.passwordRuleStrongDesc=長さが6を超えています。英語と数字の両方を含める必要があります。 +admin.setting.passwordRuleStrongMoreDesc=長さは6より大きく、数字、大文字の英語、小文字の英語を含める必要があります。 +admin.setting.passwordRuleTips=現在のパスワードは十分に強力ではありません。すぐにパスワードを変更することをお勧めします! +admin.loginCheck.menu=ログイン制御 +admin.loginCheck.ipCheck=IP制限 +admin.loginCheck.ipCheckNone=無制限 +admin.loginCheck.ipCheckAllow=IPホワイトリスト +admin.loginCheck.ipCheckDisable=IPブラックリスト +admin.loginCheck.loginIpAllowDesc=開いた後は、指定したIPのユーザーのみログインできますのでご注意ください +admin.loginCheck.ipAllow=許可されたIP +admin.loginCheck.ipAllowDesc=次のようにルールを入力します(各行、サーバーのローカルIPはデフォルトで許可され、システム管理者はLAN IPを許可します) +admin.loginCheck.ipDisable=ブラックリストIPルール +admin.loginCheck.ipDisableDesc=開封後は、ip条件を満たすユーザーは操作できなくなりますので、ご注意ください!
    全員が指定されている場合、すべてのリクエストがブロックされます! +admin.loginCheck.ipDescTitle=次のようにルールを入力します(エントリごとに1行) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=優先度 +admin.loginCheck.name=ルール名 +admin.loginCheck.user=指定ユーザー +admin.loginCheck.device=指定機器 +admin.loginCheck.deviceWeb=ウェブ +admin.loginCheck.devicePc=PC側 +admin.loginCheck.deviceAndroid=アンドロイド +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc= +admin.setting.checkCode=ログイン確認コードの有効化 +admin.setting.checkCodeDesc=ログイン後、確認コードを入力する必要があります。 +admin.setting.csrfProtect=csrf保護の有効化 +admin.setting.csrfProtectDesc=有効にすると、csrf攻撃を効果的に防ぐことができます +admin.setting.setRootPath=ルートアクセス +admin.setting.setRootPathDesc= +admin.setting.encode=ファイルストレージの暗号化 +admin.setting.encodeAll=すべてを暗号化 +admin.setting.encodeName=拡張機能を保持する +admin.setting.encodeNone=暗号化なし +admin.setting.encodeAllDesc=完全な暗号化: [デフォルトの推奨事項];サーバーの権限がある場合でも、ファイルの実際の内容がわからないため、ランサムウェアやその他の損傷から効果的に保護できます。 +admin.setting.encodeNameDesc=拡張子の保持:ファイル名の暗号化、拡張子の保持 +admin.setting.encodeNullDesc=暗号化なし:ファイル名は暗号化されず、元のファイル名が保持されます(セキュリティを確保するために、アップロードフォルダーには暗号化された構造の名前が付けられます)。 +admin.setting.encodeTips1=設定変更後のファイルのみが影響を受け、以前に存在していたファイルは影響を受けません。 +admin.setting.encodeTips2=エラーを回避するために、data / files内のファイルを削除したり、名前を変更したりしないでください。 +admin.setting.encodeTips3=大規模な同時実行、2番目の送信、クラスタリング、分散、自動拡張などの機能をサポートするために、フォルダ階層がデータベースに記録され、フォルダ構造をコピーして貼り付けることでインポートおよび復元できます。 +admin.setting.thirdLogin=サードパーティのログイン +admin.setting.thirdLoginDesc=サードパーティのアカウントを介した登録、バインド、ログインを許可します +admin.setting.registOpen=オープンユーザー登録 +admin.setting.registOpenDesc=データの競合を避けるために、サードパーティのデータ同期とユーザー登録を同時に有効にすることはできません +admin.setting.registCheck=登録審査を開く +admin.setting.registCheckDesc=開いた後、管理者は、登録ユーザーが通常使用できるように、[ユーザーと部門]で確認して有効にする必要があります。 +admin.setting.clearUserRecycle=すべてのユーザーのごみ箱を空にする +admin.setting.clearCache=キャッシュをクリア +admin.setting.icp=著作権またはレコード番号 +admin.setting.icpDesc=リンクを生成する必要がある場合は、自分でタグを追加できます +admin.setting.globalCss=カスタムグローバルCSS +admin.setting.globalCssDesc=すべてのページにカスタムcssが挿入されます +admin.setting.globalHtml=統計コードHTML +admin.setting.globalHtmlDesc=すべてのページにこのhtmlコードが挿入され、サードパーティの統計コードを配置できます +admin.setting.dateFormat=日付形式 +admin.setting.dateFormatDesc=年月日時刻形式の表示、ファイル変更時刻など。 +admin.setting.menu=メニュー管理 +admin.setting.systemName=会社の製品名 +admin.setting.systemNameDesc=製品ロゴのタイトルについて +admin.setting.systemDesc=製品のサブタイトル +admin.setting.pathHidden=ディレクトリの除外 +admin.setting.pathHiddenDesc=デフォルトでは表示されず、コンマで区切られたディレクトリとファイル +admin.setting.defaultFolder=新しいユーザーはデフォルトでディレクトリを作成します +admin.setting.defaultFolderDesc=カンマ区切り +admin.setting.defaultApp=新しいユーザーはデフォルトでアプリを作成します +admin.setting.defaultAppDesc=カンマで区切られた複数のアプリケーションセンターアプリケーション +admin.setting.autoLogin=自動ログイン +admin.setting.autoLoginDesc=デフォルトのログインユーザーはguest/guestユーザーです;このユーザーが存在することを確認してください +admin.setting.firstIn=ログイン後にデフォルトで表示される画面 +admin.setting.registReviewOpen=オープン登録監査: +admin.setting.registRoleEmpty=権限ロールは空にできません +admin.setting.registNotSync=データの競合を避けるために、サードパーティのデータ同期とユーザー登録を同時に有効にすることはできません +admin.setting.registNeedRewiew=開いた後、管理者は、登録されたユーザーが通常使用する前に、ユーザーと部門で確認して有効にする必要があります。 +admin.setting.roleRight=役割の許可 +admin.setting.emailHost=メールボックスサーバー +admin.setting.emailHostInput=メールサーバーのアドレスを入力してください +admin.setting.emailHostTips=メールサーバーのアドレスを入力してください +admin.setting.emailHostDesc=smtp.163.comなどのメールボックスサーバーでは、ポートをカスタマイズできます(デフォルトは465) +admin.setting.emailSend=送信トレイ +admin.setting.emailSendInput=メールアドレスを入力してください +admin.setting.emailSendTips=送信メールアドレスを入力してください +admin.setting.emailSendDesc=システムのメールアドレス、POP3 / SMTPサービスを有効にする必要があります +admin.setting.emailPwd=認可パスワード +admin.setting.emailPwdTips=メール認証パスワードを入力してください +admin.setting.secureType=暗号化 +admin.setting.emailSendTest=送信検出 +admin.setting.ensureEmailOk=メールが正常に送信できることを確認してください +admin.setting.emailTo=受信トレイ +admin.setting.emailGoToTips=メールボックスにアクセスしてください +admin.setting.emailCheckTips=表示する +admin.setting.emailInputError=間違ったメール設定 +admin.setting.emailPwdError=メール設定パスワードが間違っています +admin.setting.emailDesc=ユーザー登録、パスワード回復メール送信用のメールサーバーを設定する +admin.setting.sendEmail=メールを送る +admin.setting.sendEmailDesc=システムのデフォルト:クラウドメールサーバーを送信するために呼び出す、送信する;カスタム:メールサーバーを自分で構成する +admin.setting.systemBackup=システムのバックアップ +admin.setting.enableFunction=機能とスイッチ +admin.setting.treeOpen=ツリーディレクトリ機能スイッチ +admin.setting.treeOpenDesc=ファイル管理、ツリーディレクトリ対応機能をグローバルにオン/オフ +admin.setting.groupListChild=サブセクターのリスト +admin.setting.groupListChildDesc=部門フォルダがサブ部門を表示するかどうかにかかわらず、権限は上位に継承されます +admin.setting.groupRootListChild=エンタープライズWebディスクはサブセクターをリストします +admin.setting.groupRootListChildDesc=企業ネットワークのディスクフォルダーにサブ部門が表示され、権限が上位に継承されるかどうか +admin.setting.shareToMeAllowTree=私と協力する-組織構造ごとに表示 +admin.setting.shareToMeAllowTreeTips=開業後、私とのコラボレーションのコンテンツサポートは、部門の組織構造に応じて分類されており、組織構造がより複雑な状況に適しています。 +admin.setting.groupTagAllow=部門のパブリックレーベル +admin.setting.groupTagAllowTips=有効にすると、部門内のファイルのパブリックラベルを設定すると、すべての部門メンバーが表示されます。部門管理者は、ラベルの内容を管理できます。 +admin.setting.shareToMeList=タイル張りのディスプレイ +admin.setting.shareToMeGroup=組織構造別に表示 +admin.setting.shareToMeUser=共有者による表示 +admin.setting.sysSrvState=サーバーステータス +admin.setting.sysSrvInfo=サーバー情報 +admin.setting.sysPhpInfo=PHP情報 +admin.setting.database=データベース +admin.setting.cache=キャッシュ +admin.setting.sysMyInfo=私の情報 +admin.setting.srvStateCpu=CPU使用率 +admin.setting.srvStateMem=メモリ使用量 +admin.setting.srvStateSrv=サーバーシステムのストレージスペース +admin.setting.srvStateDef=ネットワークディスクのデフォルトのストレージスペース +admin.setting.srvInfoName=サーバーの名前 +admin.setting.srvInfoIp=サーバーIP +admin.setting.srvInfoTime=サーバー時間 +admin.setting.srvInfoUpTime=連続稼働時間 +admin.setting.srvInfoWeb=サーバーソフトウェア +admin.setting.srvInfoPhpV=PHPバージョン +admin.setting.srvInfoSys=サーバーシステム +admin.setting.srvInfoPath=サイトパス +admin.setting.srvPhpDtl=PHPの詳細 +admin.setting.memLimit=メモリ制限 +admin.setting.postLimit=POST送信制限 +admin.setting.uploadLimit=アップロードファイルの制限 +admin.setting.execTime=最大実行時間 +admin.setting.inputTime=最大リクエスト時間 +admin.setting.disFunction=機能を無効にする +admin.setting.phpExtSugst=推奨されるPHP拡張機能 +admin.setting.phpExtLoad=ロードされた拡張機能 +admin.setting.myClientIp=私のIP +admin.setting.myClientUa=私のブラウザUA +admin.setting.myClientLng=私のブラウザ言語 +admin.setting.disFuncDesc=システムに必要な機能。有効にすることをお勧めします +admin.setting.srvMemFree=残りのメモリ +admin.setting.srvMemUse=メモリを使用する +admin.setting.srvCpuUse=現在占領中 +admin.setting.srvCpuFree=未使用 +admin.setting.noLimit=無制限 +admin.setting.disFunNo=番号 +admin.setting.systemCache=システムキャッシュ +admin.setting.systemDb=システムデータベース +admin.setting.sysCacheTab=キャッシュスイッチ +admin.setting.sysDbTab=データベーススイッチ +admin.setting.sysRecTab=データベースの回復 +admin.setting.cacheDesc=キャッシュの説明 +admin.setting.fileCacheDesc=ファイルキャッシュ:データをキャッシュファイルに直接書き込みます。テストや小規模な使用に適しています。 +admin.setting.redisDesc=Redis:高性能なKey-Valueの非リレーショナルデータベースで、読み取りと書き込みの同時実行が多い状況に適しています。使用をお勧めします。 +admin.setting.memcachedDesc=Memcached:高パフォーマンスの分散メモリオブジェクトキャッシュシステム。同時並行読み取りに適しています。 +admin.setting.saveAfterTest=テストに合格すると、保存できます +admin.setting.checkPassed=合格しました +admin.setting.ifSaveCache=切り替え後、キャッシュされたデータはすべてクリアされます!
    実行してもよろしいですか? +admin.setting.ifSaveDb=データベーススイッチは、システムの現在のデータを新しいデータベースにインポートし、それをデフォルトとして設定します。実行してもよろしいですか? +admin.setting.dbCurrent=現在の構成 +admin.setting.dbType=データベースタイプ +admin.setting.dbName=名前データベース +admin.setting.dbInfo=データベース情報 +admin.setting.dbSwitch=スイッチオン +admin.setting.dbSwitchDesc=開いた後、必要に応じてデータベースの種類を変更できますので、ご注意ください。 +admin.setting.dbTable=データシート +admin.setting.dbCnt=合計 +admin.setting.dbNeedNew=データベースはすでに存在します。再指定してください +admin.setting.dbInsertError=テーブルデータの書き込みに失敗しました +admin.setting.dbNeedOthers=別のデータベースタイプを選択してください +admin.setting.dbNeedChange=構成パラメーターを変更してください +admin.setting.dbCreateError=データベースファイルの作成に失敗しました。ディレクトリの読み取りおよび書き込み権限を確認してください +admin.setting.dbTaskProcess=実行の進捗状況 +admin.setting.dbTasking=実行中 +admin.setting.dbTaskDesc=不一致データの生成を回避するために、ウィンドウを閉じたり、システムで他の操作を実行したりしないでください。 +admin.setting.recTaskDesc=ウィンドウを閉じないでください。リクエストが中断された後、タスクが終了するまでバックグラウンドが実行され続けます。 +admin.setting.dbCreate=新しいデータベース +admin.setting.dbSelect=データベースを読む +admin.setting.dbInsert=データベースに書き込む +admin.setting.dbSetSave=構成情報を保存する +admin.setting.recDesc=使用説明書 +admin.setting.recDescInfo11=この操作により、システムデータがリセットされます。非操作および保守、または関連する技術者は操作しないでください。 +admin.setting.recDescInfo21=バックアップデータベースを新しいデータベースに書き込み、それをシステムのデフォルトとして設定することにより、データの回復が実現されます。 +admin.setting.recDescInfo22=新しいデータベース構成パラメーターは、システム構成ファイルconfig / settings_user.phpに追加されます。リカバリーの実行後にシステムが異常である場合、ファイルの追加された部分は、以前のシステムデータに影響を与えることなく削除できます。 +admin.setting.recDescInfo23=この機能は、システムのバックアップ管理によって生成されたバックアップデータの処理のみをサポートします。自分でバックアップしたデータベースは、他の方法で処理する必要があります。 +admin.setting.recDescInfo31= +admin.setting.recDescInfo32= +admin.setting.recDescInfo33=権限の設定: +admin.setting.recDescInfo34=権限を取り消す: +admin.setting.recOpen=リカバリをオンにします +admin.setting.recOpenDesc=電源を入れた後、必要に応じてバックアップデータベースを選択して復元できますので、ご注意ください。 +admin.setting.recTypeDesc=現在使用しているシステムの種類によって異なります +admin.setting.recPath=データベースバックアップディレクトリ +admin.setting.recPathErr=無効なデータベースバックアップディレクトリ +admin.setting.ifSaveRec=データベースの復元では、バックアップデータが新しいデータベースにインポートされ、デフォルトとして設定されます。
    実行してもよろしいですか? +admin.setting.recDiyPathErr=セルフバックアップを使用して復元する場合は、バックアップするデータベースファイルを選択してください +admin.setting.recDiyFileNull=データベースファイルが空です +admin.setting.recDiyPhpErr=SQLiteを自分でバックアップするには、php形式のデータベースファイルを選択してください。 +admin.setting.recDiySqlErr=MySQLを自分でバックアップするには、sql形式のデータベースファイルを選択してください。 +admin.setting.recSysPathErr=バックアップ管理を使用して復元する場合は、バックアップデータベースディレクトリを選択してください +admin.setting.recSysTbErr=データベースバックアップディレクトリが無効であるか、データベース構造ファイルがありません +admin.setting.recDbFileErr=選択したライブラリファイルがシステムと一致しないか、有効なデータテーブルがありません +admin.setting.dbFileDown=ライブラリファイルを読む +admin.setting.dbFileDownErr=ライブラリファイルの読み取りに失敗しました +admin.notice.waiting=プッシュを待っています +admin.notice.done=プッシュ +admin.notice.time=プッシュタイム +admin.notice.target=オブジェクトをプッシュ +admin.notice.level=プロンプトレベル +admin.notice.level0=弱いヒント +admin.notice.level1=強いプロンプト +admin.notice.levelDesc=弱いリマインダー:左下隅の通知バーに赤い点が表示されます。強いリマインダー:ユーザーがログインした直後に通知がポップアップ表示されます。 +admin.notice.targetAuth=全員にプッシュするか、指定したユーザー、ユーザーグループ、権限グループにプッシュするかを選択します +admin.notice.title=メッセージのタイトル +admin.notice.content=メッセージ内容 +admin.notice.timeType=プッシュ方式 +admin.notice.timeNow=すぐに押す +admin.notice.timePlan=スケジュールされたプッシュ +admin.notice.listTitle=通知情報 +admin.notice.clearAll=すべて空にする +admin.notice.noMsg=通知はありません +admin.notice.ifClearAll=すべてのメッセージを消去してもよろしいですか? +admin.group.role=ロールアイデンティティ +admin.group.name=部署名 +admin.group.parent=優れた部門 +admin.group.authShow=部門のメンバーに見える組織構造の範囲 +admin.group.authShowAll=すべての部門 +admin.group.authShowHide=この部門とサブ部門のみ +admin.group.authShowSelect=指定部門 +admin.group.authShowAllTips=この部門のメンバーが協力して共有すると、他のすべての部門(およびユーザー)を選択できます +admin.group.authShowHideTips=この部門のメンバーが共同作業して共有する場合、現在の部門とサブ部門(およびユーザー)のみがサポートされます +admin.group.authShowSelectTips=部門のメンバーが共同で共有する場合、現在の部門とサブ部門を含む、指定された部門とサブ部門(およびユーザー)を選択できます。 +admin.group.addSub=サブセクターを追加 +admin.group.remove=部門を削除 +admin.group.switch=移行部 +admin.group.swtichDesc=選択した部門 (およびそのサブ部門) のユーザーとファイルをターゲット部門に移行します。 +admin.group.switchSameError=対象部門を選択した部門と同じにすることはできません +admin.group.switching=移行中、お待ちください... +admin.group.groupSwitching=選択した部門が移行中です +admin.group.parentNullError=上層部を空にすることはできません +admin.group.selected=選択した部門 +admin.group.setSizeBatch=スペースサイズをバッチで設定する +admin.group.multiSelect=複数の部門をバッチ設定用に選択できます +admin.group.ifDisAll=すべてのサブ部門が無効になります。実行してもよろしいですか? +admin.member.manage=ユーザーと部門 +admin.member.add=新しいユーザー +admin.member.role=権限の役割 +admin.member.group=部門 +admin.member.groupAdd=部門を追加 +admin.member.groupEdit=編集部 +admin.member.remove=ユーザーを削除 +admin.member.import=一括追加 +admin.member.enable=有効にする +admin.member.batchSet=一括操作 +admin.member.groupRemove=部門から削除 +admin.member.groupInsert=部門に追加 +admin.member.groupSwitch=部門に移行する +admin.member.groupTarget=対象部門 +admin.member.groupReset=部門のリセット +admin.member.groupSwtichDesc=選択したユーザーを現在の部門からターゲット部門に移行します +admin.member.roleSet=権限の役割の設定 +admin.member.sizeSet=スペースサイズ設定 +admin.member.name=ログインアカウント +admin.member.nickName=ユーザーのニックネーム +admin.member.userInfo=ユーザー情報 +admin.member.userImport=ユーザーを一括でインポートする +admin.member.uploadFirst=最初にファイルをアップロードしてください +admin.member.downTpl=テンプレートをダウンロード +admin.member.downTplDesc=、テンプレート形式を入力してアップロードしてください。 +admin.member.uploadInvalid=アップロードされたファイルに有効なデータがありません。もう一度確認してアップロードしてください +admin.member.uploadDataInvalid=アップロードデータが無効か期限切れです。もう一度アップロードしてください +admin.member.importSuccess=インポートが完了しました +admin.member.importFail=インポートに失敗しました +admin.member.importFailDesc=成功:{0}、失敗:{1} +admin.member.importName=ログインアカウント(必須、一意) +admin.member.importNickName=ニックネーム(ユニーク) +admin.member.importPwd=パスワードが必要) +admin.member.importSex=性別(男性-1、女性-0) +admin.member.importPhone=携帯電話番号(一意) +admin.member.importEmail=メール(のみ) +admin.member.groupRemoveTips=削除後、このユーザーグループのユーザーはログインできません
    (ユーザーグループをリセットする必要があります)、続行してもよろしいですか? +admin.member.memberRemoveTips=削除後、ユーザーディレクトリはシステムのごみ箱に移動されます。
    続行してもよろしいですか? +admin.member.selectUserTips=運用するアカウントを選択してください +admin.member.ifRemoveGroup=選択したユーザーをこのグループから削除してもよろしいですか? +admin.member.importDesc=1行に1人のユーザー、
    既に存在する場合は自動的に無視します +admin.member.roleAdminTips=注:システム管理者は権限によって制御されません +admin.member.space=ユーザースペースサイズを設定する +admin.member.spaceTips=0は制限されていません +admin.member.spaceTipsDefault=(GB)0は制限されません +admin.member.spaceTipsFull=制限なし +admin.member.spaceSize=スペースの容量 +admin.member.spaceSizeUse=スペース使用 +admin.member.memberAdd=ユーザーを追加 +admin.member.allAdd=ユーザーまたは部門を追加 +admin.member.nullNotUpdate=空白のままにする +admin.member.search=ユーザーの検索(アカウント/ニックネーム/メール/電話) +admin.member.searchUser=ユーザーの検索(ピンインとあいまい一致のサポート) +admin.member.searchGroup=検索部門(ピンインとあいまい一致のサポート) +admin.member.searchAll=ユーザーまたは部門の検索(ピンインとあいまい一致のサポート) +admin.member.editNoAuth=申し訳ありませんが、この許可はありません。
    システム管理者のみがシステム管理者を追加および変更できます +admin.member.disabledUsers=アカウントが無効になっています +admin.member.disabledTips=部門を切り替えてチェックを外します +admin.member.userGroup=ユーザー部門 +admin.member.userRole=ユーザー役割 +admin.member.userSelected=選択したユーザー +admin.member.authCopy=部門の権限をコピーする +admin.member.authPaste=部門許可ペースト +admin.member.ifAuthPaste=コピーした部門の権限を現在のユーザーに設定してもよろしいですか? +ERROR_USER_NOT_EXISTS=ユーザーが存在しません +ERROR_USER_PASSWORD_ERROR=間違ったパスワード +ERROR_USER_EXIST_NAME=ユーザー名は既に存在します +ERROR_USER_EXIST_PHONE=電話番号は既に存在します +ERROR_USER_EXIST_EMAIL=メールボックスは既に存在します +ERROR_USER_EXIST_NICKNAME=ニックネームはすでに存在します +ERROR_USER_LOGIN_LOCK=パスワードの入力が多すぎて現在のアカウントがロックされています。1分後にもう一度お試しください。 +ERROR_IP_NOT_ALLOW=現在のIPまたはアクセスデバイスはログインを許可されていません。管理者に連絡してください。 +user.passwordCheckError=パスワードの形式がパスワード強度のルールを満たしていません! +admin.role.administrator=システム管理者 +admin.role.group=部門管理者 +admin.role.default=一般ユーザー +admin.role.ignoreExt=拡張制限 +admin.role.ignoreExtDesc=アップロードが許可されていないファイルタイプ、空に制限はありません +admin.role.ignoreFileSize=アップロードファイルのサイズ制限 +admin.role.ignoreFileSizeDesc=単一ファイルの最大アップロード、0は無制限 +admin.role.ignoreExtTips=申し訳ありませんが、現在のシステム設定ではこのタイプのファイルのアップロードはサポートされていません。詳細については管理者にお問い合わせください! +admin.role.ignoreFileSizeTips=ファイルがサイズ制限を超えた場合、申し訳ありませんが、詳細については管理者にお問い合わせください! +admin.role.desc=役割の説明 +admin.role.adminDesc=スーパー管理者、サーバー管理者権限があります。このユーザーのファイルとフォルダーの設定はすべて無効です。 +admin.role.read=読む +admin.role.readList=ファイルリスト +admin.role.readInfo=ファイル(フォルダー)属性ビュー、フォルダー検索 +admin.role.readCopy=ファイルコピー +admin.role.readPreview=ファイルのプレビュー(写真、ドキュメント、オーディオ、ビデオなど) +admin.role.readDownload=ファイル(フォルダー)のダウンロード +admin.role.write=書きます +admin.role.writeAdd=ファイル(フォルダー)の作成、ファイルの圧縮および解凍 +admin.role.writeChange=名前の変更、ディレクトリ構造の調整 +admin.role.writeUpload=ファイル(フォルダー)アップロード、リモートダウンロード +admin.role.writeRemove=ファイル(フォルダー)の削除、切り取り +admin.role.adminSetDesc=システム管理者にはすべての権限があり、設定する必要はありません! +admin.role.displayDesc=ユーザー役割を設定するときに表示するかどうか +admin.role.defaultRoleDesc=ヒント:システムにはデフォルトで組み込みの役割があり、権限の変更はサポートされていません。新しい役割を作成できます +admin.role.actionSetTitle=ドキュメントと構成 +admin.role.userSetTitle=ユーザー構成データ +admin.role.adminSetTitle=バックグラウンド機能 +admin.role.fileAdd=新しいファイル(フォルダー) +admin.role.fileRemove=ドキュメントの削除 +admin.role.fileMove=移動(コピー/切り取り/貼り付け/ドラッグ操作) +admin.role.userConfig=構成の変更(アバターの設定/パスワードの変更など) +admin.role.userEdit=ユーザーの編集(追加/変更/削除) +admin.role.userFav=お気に入り操作 +admin.role.itemEdit=追加/変更/削除 +admin.role.groupEdit=部門の編集(追加/変更/削除) +admin.role.delErrTips=キャラクターは使用中のため削除できません! +admin.authFrom.setUser=独自の権限を指定する +admin.authFrom.setGroup=部門の権限を指定する +admin.authFrom.setAll=その他のユーザー権限 +admin.authFrom.groupAt=部門当局 +admin.authFrom.groupParent=上位部門の権限 +admin.authFrom.pathOnly=アクセスのみ、下位レベルにはコンテンツと権限があります +admin.authFrom.groupRoot=部門のルートディレクトリ +admin.auth.owner=所有者 +admin.auth.editor=編集者 +admin.auth.editUploader=編集/アップローダー +admin.auth.viewer=視聴者 +admin.auth.previewer=プレビューア +admin.auth.uploader=アップローダー +admin.auth.invisible=見えない +admin.auth.user=ユーザーデータ +admin.auth.pathDelete=ファイル削除 +admin.auth.pathInfo=ファイルプロパティ +admin.auth.pathMove=移動(コピー/切り取り/貼り付け/ドラッグ操作) +admin.auth.canUpload=ダウンロードをアップロード +admin.auth.config=構成データ +admin.auth.fav=お気に入りの操作(追加/編集/削除) +admin.auth.extWarning=そのようなファイルのアップロードは許可されていません。
    名前の変更(指定された拡張子に変更)、
    保存、リモートダウンロード、解凍の編集 +admin.auth.error=権限ロールエラー(権限設定なし) +admin.auth.errorAdmin=権限が不十分 +admin.auth.targetError=権限オブジェクトの種類が間違っています。ユーザーまたは部門である必要があります +admin.auth.errorAuthToGroup=非ルート部門、部門への委任はサポートしていません +admin.auth.errorAuthToUsers=非ルートセクター、セクター外のメンバーへの委任はサポートしていません +admin.auth.displayDesc=部門のユーザー権限を設定するときに表示するかどうか +admin.auth.defaultAuthDesc=ヒント:システムにはデフォルトで組み込みの許可グループがあり、許可の変更はサポートしていません。新しい許可グループを作成できます +admin.auth.show=ファイルリスト +admin.auth.showAction=ファイルリストビュー +admin.auth.view=ファイルプレビュー +admin.auth.viewAction=ファイルを開くプレビュー +admin.auth.download=ダウンロード/コピー +admin.auth.downloadAction=ダウンロード/コピー/ファイルプレビュー印刷 +admin.auth.uploadAction=ファイル(フォルダー)アップロード/リモートダウンロード +admin.auth.edit=新規編集 +admin.auth.editAction=新規ファイル(フォルダー)/名前の変更/フォルダーに貼り付け/ファイルの編集/メモの設定/コピーの作成/解凍、圧縮 +admin.auth.removeAction=切り取り/コピー/移動 +admin.auth.shareAction=外部チェーン共有/他者とのコラボレーション共有 +admin.auth.comment=ドキュメントのコメント +admin.auth.commentAction=ドキュメントのコメントを表示し、独自のコメントを追加/削除します(編集権限が必要です) +admin.auth.event=ドキュメントのダイナミクス +admin.auth.eventAction=ドキュメントの動的表示、サブスクリプションの動的 +admin.auth.root=管理権 +admin.auth.rootAction=メンバー権限の設定/コメント管理/履歴バージョン管理 +admin.auth.delErrTips=この権限は使用中のため削除できません! +admin.plugin.center=プラグインセンター +admin.plugin.installed=インストール済み +admin.plugin.type=カテゴリー +admin.plugin.typeFile=ファイルの機能強化 +admin.plugin.typeSafe=セキュリティツール +admin.plugin.typeTools=実用性 +admin.plugin.typeMedia=マルチメディア +admin.plugin.typeCompany=エンタープライズアプリケーション +admin.plugin.typeOem=排他的なカスタマイズ +admin.plugin.needNetwork=エクストラネット +admin.plugin.install=プラグインをインストールする +admin.plugin.enable=プラグインを有効にする +admin.plugin.remove=プラグインをアンインストールする +admin.plugin.config=プラグインを構成する +admin.plugin.statusEnabled=有効化 +admin.plugin.statusDisabled=有効になっていない +admin.plugin.statusNotInstall=インストールされていません +admin.plugin.installing=インストール中... +admin.plugin.hasUpdate=更新 +admin.plugin.updateStart=プラグインを更新 +admin.plugin.needConfig=有効にするには初期設定が必要です +admin.plugin.notNull=必須フィールドは空にできません! +admin.plugin.auther=作者 +admin.plugin.downloadNumber=インストールする +admin.plugin.back=に戻る +admin.plugin.detail=説明 +admin.plugin.resetConfig=デフォルト設定に戻す +admin.plugin.installSelf=手動インストール +admin.plugin.updateSelf=手動更新 +admin.plugin.updateAll=すべて更新 +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=ネットワークエラー:サーバーがインターネットにアクセスできるかどうかを確認してください。 +admin.plugin.auth=使用権 +admin.plugin.authDesc=全員を利用可能にするか、使用するユーザー、ユーザーグループ、およびアクセス許可グループを指定します +admin.plugin.authOpen=オープンアクセス +admin.plugin.authOpenDesc=ログインせずにアクセスでき、外部インターフェイス呼び出しに使用できます +admin.plugin.authAll=みなさん +admin.plugin.authUser=指定されたユーザー +admin.plugin.authGroup=指定部門 +admin.plugin.authRole=許可グループを指定する +admin.plugin.openWith=オープンスタイル +admin.plugin.openWithDilog=内部ダイアログ +admin.plugin.openWithWindow=新しいページが開きます +admin.plugin.fileSort=拡張機能の関連付けの優先順位 +admin.plugin.fileSortDesc=拡張機能が大きいほど、優先度が高くなります +admin.plugin.fileExt=サポートされているファイル形式 +admin.plugin.fileExtDesc=拡張機能をプラグインに関連付ける +admin.plugin.tabServer=サーバー構成 +admin.plugin.defaultAceEditor=エースエディター +admin.plugin.defaultHtmlView=Webプレビュー +admin.plugin.defaultZipView=オンライン減圧 +admin.plugin.authViewList=プラグインのリスト +admin.plugin.authStatus=開く閉じる +admin.plugin.authInstall=インストール/アンインストール +admin.plugin.disabled=プラグインが存在しないか、開始されていません +admin.plugin.menuAdd=メインメニューに追加するかどうか +admin.plugin.menuAddDesc=スタンドアロンアプリケーションとして使用 +admin.plugin.menuSubMenuDesc=[その他]メニューで縮小 +admin.storage.type=保管タイプ +admin.storage.local=ローカル +admin.storage.localStore=ローカルストレージ +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=七つの牛の雲 +admin.storage.s3=アマゾンS3 +admin.storage.ftp=FTP +admin.storage.oos=天一クラウドOOS +admin.storage.moss=紅山MOSS +admin.storage.eos=XSKY EOS +admin.storage.nos=以前のクラウドNOS +admin.storage.minio=MinIO +admin.storage.uss=別のクラウドUSSを取る +admin.storage.eds=Sangfor EDS +admin.storage.driver=ローカルディスク +admin.storage.useage=スペースの使用 +admin.storage.default=デフォルトとして設定 +admin.storage.current=現在のデフォルト +admin.storage.edit=構成ストレージ +admin.storage.setConfig=構成を変更する +admin.storage.moveData=データの移行 +admin.storage.delStore=ストレージのマウントを解除 +admin.storage.ifMove=このストレージには{0}ネットワークディスクファイルが含まれており、現在のデフォルトストレージに移行されます。続行しますか? +admin.storage.ifDel=現在のストアをアンマウントしてもよろしいですか? +admin.storage.ifDelWithFile=このストレージには{0}ネットワークディスクファイルが含まれており、削除すると現在のデフォルトストレージに移行されます。続行しますか? +admin.storage.sysFile=ネットワークディスクファイル:個人用スペースおよび部門の下のファイル +admin.storage.delErrTips=成功:%s; 失敗:%s、再試行または手動で移動してください。 +admin.storage.delLocTips=少なくとも1つのローカルストアを保持してください +admin.storage.delStoreTips=このストレージにはバックアップ データが含まれています。続行する前に処理してください。 +admin.storage.nameDesc=異なるストレージを区別するためのストレージ名 +admin.storage.path=ストレージディレクトリ +admin.storage.pathLocDesc=ファイルストレージディレクトリ。入力されたディレクトリに読み取りおよび書き込み権限があることを確認してください +admin.storage.pathDesc=ファイル保存ディレクトリ +admin.storage.defaultDesc= +admin.storage.forceEdit=必須の変更 +admin.storage.editTips=開いた後、禁止されている変更フィールドを編集できます。保存前のファイルにアクセスできない可能性があります。注意してください。 +admin.storage.folderTips=現在のシステム ファイルの保存場所です。注意して操作してください +admin.storage.sizeTips=スペースサイズは0より大きくなければなりません +admin.storage.sizeDesc=(GB)、選択したストレージディレクトリの実際の空き容量に応じて入力してください +admin.storage.region=保管場所 +admin.storage.domain=スペースドメイン名 +admin.storage.bucket=バケット名 +admin.storage.bucketDesc=スペースを作成するときに入力されるバケット名 +admin.storage.userName=アカウント名 +admin.storage.userPwd=アカウントのパスワード +admin.storage.server=サーバーアドレス +admin.storage.serverDesc=ftp(s):// ip、デフォルトはプロトコルなしのftp +admin.storage.refer=参照: +admin.storage.endpoint=エンドポイント +admin.storage.ossDomain=OSSスペースにバインドされたドメイン名 +admin.storage.ossKeyDesc=Alibaba CloudアカウントのアクセスキーID。[コントロールパネル-アクセスキー管理]で作成または表示してください +admin.storage.ossSecretDesc=Alibaba CloudアカウントのKey Secret +admin.storage.ossEndpoint=エンドポイント、イントラネットノードを使用する場合は、サーバー転送を有効にする必要があります +admin.storage.cosKeyDesc=Tencent CloudアカウントのキーIDにアクセスするには、[コントロールパネル-アクセス管理-APIキー管理]で作成または表示してください +admin.storage.cosSecretDesc=Tencent Cloudアカウントのキーシークレットにアクセスする +admin.storage.qiniuDomain=Qiniu Spaceによってバインドされたドメイン名 +admin.storage.qiniuKeyDesc=Qiniuアカウントのアクセスキー、[コントロールパネル-パーソナルセンター-キー管理]で作成または表示してください +admin.storage.qiniuSecretDesc=Qiniuアカウントのシークレットキー、取得方法は上記と同じ +admin.storage.qnz0=中国東部 - 浙江省 +admin.storage.qnz02=中国東部 - 浙江 2 +admin.storage.qnz1=中国北部 - 河北省 +admin.storage.qnz2=中国南部 - 広東省 +admin.storage.qnna0=北米 - ロサンゼルス +admin.storage.qnas0=アジア太平洋 - シンガポール +admin.storage.qnas02=アジア太平洋 - ソウル +admin.storage.awsDomain=AWSスペースでバインドされたドメイン名 +admin.storage.awsKeyDesc=AWSアカウントのキーIDにアクセスするには、[コントロールパネル-セキュリティ認証情報]で作成してください +admin.storage.awsSecretDesc=AWSアカウントのアクセスキーシークレット +admin.storage.oosDomain=天一クラウドスペースバウンドドメイン名 +admin.storage.oosKeyDesc=Tianyi CloudアカウントのアクセスキーID、[コントロールパネル-セキュリティ資格情報]で作成してください +admin.storage.oosSecretDesc=Tianyiクラウドアカウントのアクセスキーシークレットは上記と同じです +admin.storage.ftpDisabled=FTPは利用できません。php_ftp拡張機能を有効にしてください +admin.storage.ifDefaultTips=この操作により、他のデフォルトの保存方法がキャンセルされます。よろしいですか? +admin.storage.spaceUsed=実用化 +admin.storage.spaceLave=残額 +admin.storage.delError=ファイルはこのストアに既に存在し、削除できません +admin.storage.corsError=構成が正しい場合は、[ヘルプを使用]をクリックしてバケットのクロスドメイン設定を確認してください。 +admin.storage.saveError=指定されたストレージに接続できません。構成情報が正しいかどうかを確認してください。 +admin.storage.ftpCharset=FTPサーバーのエンコード +admin.storage.ftpCharsetDesc=FTPサーバーがWindowsの場合、状況に応じてGBKに設定できます。 +admin.storage.ftpPasvOn=オンにする +admin.storage.ftpPasvOff=閉鎖 +admin.storage.ftpPasv=パッシブモード +admin.storage.ftpPasvDesc=データ転送モード +admin.storage.uploadSrv=サーバー転送(アップロード) +admin.storage.fileoutSrv=サーバー転送(ダウンロード) +admin.storage.uploadSrvDesc=オンにすると、ファイルはサーバーを介してオブジェクトストレージにアップロードされます。それ以外の場合は、クライアントを介して直接アップロードされます。 +admin.storage.fileoutSrvDesc=オンにすると、ストレージファイルはサーバーを介してダウンロード用に取得されます。それ以外の場合、ファイルは直接ダウンロード用に取得されます。 +admin.storage.closeDefError=デフォルトのストレージをオフにすることを禁止する +admin.storage.ussBucket=サービス名 +admin.storage.ussBucketDesc=クラウドストレージサービス名 +admin.storage.ussUser=オペレーター名 +admin.storage.ussUserDesc=オペレーター名 +admin.storage.ussUserPwd=オペレーターパスワード +admin.storage.ussDomain=クラウドスペースにバインドされたドメイン名の別のショットを撮ります +admin.storage.ussToken=ヒル防止トークン +admin.storage.ussTokenDesc=トークン盗難防止チェーン秘密鍵(必須ではありません) +admin.storage.configError=設定パラメータが異常です! +admin.storage.sizePercent=システムファイルの比率: +admin.storage.fileCount=ファイル数: +admin.storage.error=ストレージ例外 +admin.task.name=タスク名 +admin.task.edit=タスク編集 +admin.task.type=タスクの種類 +admin.task.method=組み込みメソッド +admin.task.methodName=メソッド名 +admin.task.methodDesc=これは、システムモジュール-コントローラー-メソッド名で構成されています。慎重に入力してください。 +admin.task.url=リクエストURL +admin.task.urlDesc=ユーザー定義のURLアドレス、定期的にリクエストを実行するためのスケジュールされたタスク。 +admin.task.cycle=実行サイクル +admin.task.desc=ミッション詳細 +admin.task.nMinutes=N分 +admin.task.default=システムデフォルト +admin.task.timeInterval=インターバル時間 +admin.task.timeStart=開始時間 +admin.task.timeStartRun=実行時間を開始 +admin.task.timeLastRun=最終実行時間 +admin.task.timeLastLogin=ログイン時間 +admin.task.isOpen=有効にするかどうか +admin.task.open=開く +admin.task.content=実装内容 +admin.task.param=実行パラメータ +admin.task.ifRun=このタスクを実行してもよろしいですか? +admin.task.backup=データバックアップ +admin.task.backupDesc=毎日02:00にシステムデータのバックアップを開始します。 +admin.install.install=システムのインストール +admin.install.databaseSet=データベース構成 +admin.install.dataUpdate=データ移行 +admin.install.installSuccess=正常にインストールされました +admin.install.dbWasSet=データベースを構成しました。リセットする必要がある場合は、config / setting_user.phpファイルの構成を変更して再インストールできます。 +admin.install.errorRequest=システムがインストールされ、それ以上の要求は許可されません +admin.install.databaseError=データベース接続エラー、構成を確認してください +admin.install.cacheError=%s接続に失敗しました。設定を確認してください +admin.install.cacheConnectError=%sサーバに接続できませんでした。設定を確認してください +admin.install.dbSetError=データベース構成情報の書き込みに失敗しました +admin.install.dbCreateTips=データベースが存在せず、自動作成に失敗しました。手動で作成してください +admin.install.ifDelDb=データは指定されたデータベースに既に存在します。[OK]をクリックして削除します。続行しますか? +admin.install.dbCreateError=データテーブル作成例外 +admin.install.dbFileError=データベースファイルが存在しません +admin.install.dbTypeError=選択したデータベースタイプ(%s)は利用できません。対応するサービスや拡張機能をインストールするか、他のタイプを選択してください +admin.install.createSuccess=正常に作成されました +admin.install.defSetError=システムのデフォルト設定を追加できませんでした +admin.install.defStoreError=デフォルトのストレージの追加に失敗しました +admin.install.defPathError=システムディレクトリの追加に失敗しました +admin.install.defAdminError=管理者アカウントを追加できませんでした +admin.install.defRoleError=デフォルトの役割の追加に失敗しました +admin.install.defGroupError=システム部門の追加に失敗しました +admin.install.dataPathNotExists=データディレクトリが存在しません +admin.install.defaultUpdate=システム構成情報の更新 +admin.install.pluginUpdated=プラグインの更新が完了しました +admin.install.defCacheError=初期ディレクトリキャッシュデータの例外 +admin.install.serverDir=サーバー列ディレクトリ +admin.install.dirRight=ディレクトリ権限 +admin.install.suggestOpen=開くことをお勧めします +admin.install.suggestClose=閉じることをお勧めします +admin.install.phpVersionTips=PHP5.3以降 +admin.install.phpBitTips=64ビットを推奨 +admin.install.phpBitDesc=32ビットは、2Gを超えるファイルのアップロードとダウンロードをサポートしていません +admin.install.pathNeedWirte=プログラムディレクトリとすべてのサブディレクトリは、読み取りと書き込みが可能である必要があります。 +admin.install.mustOpen=開く必要があります +admin.install.setPathWrt=プロジェクトディレクトリの読み取りおよび書き込み権限を設定してください +admin.install.ensureNoError=以下が正しいことを確認してください。 +admin.install.setAdminName=管理者アカウントを設定してください +admin.install.setAdminPwd=管理者パスワードを設定してください +admin.install.database=データベース +admin.install.dbType=データベースの種類 +admin.install.dbName=データベース名 +admin.install.userName=ユーザー名 +admin.install.dbPort=ポート番号 +admin.install.dbPortDesc=デフォルトのポートは3306です。カスタマイズする必要がある場合は、127.0.0.1:3307のように追加できます。 +admin.install.dbEngine=ストレージエンジン +admin.install.sqliteDesc=PHPには、緑色の軽量データベースが組み込まれています(テストまたは小規模な使用に適しています)。 +admin.install.mysqlDesc=クラスターの展開、マスターデータベースとスレーブデータベースの分離をサポートします。 +admin.install.pdoDesc=より安全なデータベース汎用ドライバーを使用するには、PHPにPDO拡張機能をインストールする必要があります。 +admin.install.cacheType=システムキャッシュタイプ +admin.install.cacheTypeDesc=システムアクセスを高速化するために、一般的なデータとセッションセッションをキャッシュするために使用されます +admin.install.fileCache=ファイルキャッシュ +admin.install.groupFile=部門文書 +admin.install.userFile=ユーザードキュメント +admin.install.role=役割 +admin.install.fileAuth=ドキュメントのアクセス許可 +admin.install.userList=ユーザーリスト +admin.install.setInfo=システム構成情報 +admin.install.favShare=ユーザーのお気に入りと共有 +admin.install.waitUpdate=更新待ち +admin.install.updateSuccess=更新成功 +admin.install.fileCount=ファイル数 +admin.install.settingDesc=障害項目はバックグラウンド管理で手動で構成できます +admin.install.reInstallTips=返品結果が異常です。再インストールしてください +admin.log.accountEdit=アカウント情報を変更する +admin.log.thirdBind=サードパーティのアカウントをバインドする +admin.log.delBind=バインド解除 +admin.log.viewFile=プレビュー ファイル +admin.log.delFile=ファイルを削除 +admin.log.editFile=ファイルを編集 +admin.log.downFile=ダウンロードファイル +admin.log.downFolder=ダウンロードフォルダ +admin.log.moveFile=ファイルを移動 +admin.log.addUser=ユーザーを追加 +admin.log.editUser=ユーザーを編集 +admin.log.addUserTo=ユーザーを部門に追加する +admin.log.removeUserFrom=ユーザーが部門から削除されました +admin.log.switchUserGroup=ユーザー移行部門 +admin.log.stausUser=ユーザーを有効/無効にする +admin.log.addRole=新しい役割 +admin.log.editRole=役割を編集 +admin.log.delRole=役割を削除 +admin.log.addAuth=許可を追加する +admin.log.editAuth=権限を編集 +admin.log.delAuth=削除許可 +admin.log.editShare=共有を編集 +admin.log.delLinkTo=外部リンクの共有をキャンセル +admin.log.delShareTo=共同共有をキャンセルする +admin.log.recycleTo=ごみ箱に移動します +admin.log.newName=新しい名前 +admin.log.oldName=元の名前 +admin.log.newPath=新しいカタログ +admin.log.oldPath=オリジナルカタログ +admin.log.typeFile=ファイル操作 +admin.log.typeUser=ユーザー構成 +admin.log.queryByIp=ボタンをクリックして、IPに基づいてその日のログレコードを照会します。 +admin.backup.setting=バックアップ設定 +admin.backup.edit=バックアップ編集 +admin.backup.ing=バックアップ +admin.backup.success=バックアップが成功しました +admin.backup.fail=バックアップに失敗しました +admin.backup.complete=バックアップが完了しました +admin.backup.db=データベース +admin.backup.dbFile=データベースファイル +admin.backup.fileError=一部のファイルのバックアップに失敗しました +admin.backup.checkLog=バックアップログを確認してください:data / temp / log / backup / date of the day__log.php +admin.backup.pathNoWrite=一時ディレクトリには書き込み権限がありません +admin.backup.errorMsg=ファイルバックアップの一部が失敗しました。ログに従って手動でコピーするか、削除して再度バックアップすることができます。 +admin.backup.logFile=ログファイル +admin.backup.manual=手動バックアップ +admin.backup.continue=バックアップを続行 +admin.backup.start=バックアップを開始 +admin.backup.open=バックアップをオンにする +admin.backup.notOpen=バックアップが有効になっていません +admin.backup.location=バックアップ場所 +admin.backup.content=コンテンツのバックアップ +admin.backup.dbOnly=データベース +admin.backup.time=バックアップ時間 +admin.backup.notStart=始まっていない +admin.backup.notEnabled=有効になっていません +admin.backup.killed=以上 +admin.backup.ifKill=このバックアップを終了してもよろしいですか? +admin.backup.kill=終わり +admin.backup.error=アボート +admin.backup.timeBeen=時間がかかる +admin.backup.timeTotal=合計時間 +admin.backup.backed=バックアップ済み +admin.backup.storage=バックアップ専用のストレージを作成してください。 +admin.backup.ifSave=バックアップに時間がかかります。バックアップしてもよろしいですか? +admin.backup.ifContinue=バックアップを続行してもよろしいですか? +admin.backup.saveTips=バックアップタスクが送信されました。しばらくお待ちください +admin.backup.fileSize=原稿サイズ +admin.backup.dbSize=データベースのサイズ +admin.backup.dbCnt=合計 +admin.backup.notFinished=まだ終わってない +admin.backup.timeTaken=時間がかかる +admin.backup.node=ノード +admin.backup.notYet=番号 +admin.backup.storeNotExist=バックアップストレージが存在しません。リセットしてください +admin.backup.timeNote=注: システムは、過去 7 日間と毎月 1 日のデータベース バックアップのみを保持します。バックアップ時間: +admin.backup.recover=データ復旧については、サービスプロバイダーにお問い合わせください。 +admin.backup.optionTime=バックアップには時間がかかります。非稼働時間中に選択してください。 +admin.backup.optionLocation=ファイルをバックアップする必要がある場合は、バックアップ専用の新しいストレージを作成してください +admin.backup.optionTips1=バックアップは、データベースバックアップとファイルバックアップの2つの部分に分かれています。 +admin.backup.optionTips2=データベースのバックアップ:データベースのコンテンツからSQLファイルを生成し、ターゲットストレージデータベースディレクトリにバックアップします。 +admin.backup.optionTips3=ファイルバックアップ:元のストレージパスに従って、システムストレージファイルをターゲットストレージに段階的にバックアップします。 +admin.backup.optionTips4=システムは、過去 7 日間と毎月 1 日のデータベース バックアップのみを保持します。 +admin.backup.needStorage=バックアップストレージを空にすることはできません +admin.backup.needNoDefault=ファイルのバックアップ場所としてデフォルトのストレージを選択しないでください +admin.backup.contentDesc=ライセンス版は、データベースとファイルの同時バックアップをサポートします +admin.backup.action=運用管理 +admin.backup.recovery=割引 +admin.backup.sysRecovery=システムの復元 +admin.backup.bakErr2Rec=このバックアップは不完全であり、復元できません +admin.recycle.menu=システムごみ箱 +admin.share.name=共有名 +admin.share.type=共有タイプ +admin.share.expiryTime=有効期限 +admin.share.expired=期限切れ +admin.share.link=外部リンク +admin.share.linkView=クリックして共有を表示 +admin.share.ifDel=この共有をキャンセルしてもよろしいですか? +admin.share.disFile=このファイルはユーザーによって報告され、共有が禁止されています +admin.share.disFolder=このディレクトリには、共有が禁止されている違法なファイルが含まれています +admin.share.shareTab=共有管理 +admin.share.reportTab=レポート管理の共有 +admin.share.rptType1=海賊行為 +admin.share.rptType2=卑猥なポルノ +admin.share.rptType3=血まみれの暴力 +admin.share.rptType4=政治は有害です +admin.share.rptType5=他の理由 +admin.share.doRptClose=共有コンテンツの処理後にレポートを閉じるか、直接閉じます +admin.share.doRptDisable=共有を禁止/許可すると、ファイルに対応するすべてのリソースが影響を受けます。この操作を実行してもよろしいですか? +admin.share.rptUser=ホイッスルブロワー +admin.share.rptTitle=レポートの共有 +admin.share.rptDesc=報告の理由 +admin.share.rptTime=報告時間 +admin.share.rptResult=プロセス結果 +admin.share.rptDone=処理済み +admin.share.rptNoDone=未処理 +admin.share.rptClose=レポートを閉じる +admin.share.rptShareDel=共有解除 +admin.share.rptShareAllow=共有を許可する +admin.share.rptShareDisable=共有なし +admin.share.rptDoDisable=共有を禁止/許可する +admin.share.rptSelectTips=操作するアイテムを選択してください! +admin.setting.transfer=アップロード/ダウンロード +admin.setting.transferChunkSize=シャードサイズをアップロードする +admin.setting.transferChunkSizeDesc= +admin.setting.transferChunkSizeDescError1=アップロード断片サイズは、php.iniの設定を超えることはできません +admin.setting.transferChunkSizeDescError2= +admin.setting.transferThreads=同時スレッドのアップロード +admin.setting.transferThreadsDesc=推奨= 10;ファイルまたはシャードの同時アップロード +admin.setting.transferIgnore=無視ファイルをアップロード +admin.setting.transferIgnoreDesc=自動的に無視されるファイル名をアップロードします。たとえば、.DS_store、thumb.dbのように、複数のコンマで区切られた一時ファイルを除外できます。 +admin.setting.transferChunkRetry=アップロードが失敗した場合の自動再送信 +admin.setting.transferChunkRetryDesc=推奨= 5;アップロードが失敗した場合、再送信の数は自動的に実行されます。0は自動再送信がないことを意味します +admin.setting.transferOsChunkSize=オブジェクトストレージシャードサイズ +admin.setting.transferOsChunkSizeDesc= +admin.setting.transferHttpSendFile=Webサーバーアクセラレーションをダウンロードする +admin.setting.transferHttpSendFileDesc=ファイルのダウンロードはWebサーバーを介して直接送信され、ダウンロード速度が向上します;デフォルトストレージがローカルストレージとして設定されている場合にのみ有効です。 +admin.setting.downloadZipClient=フロントエンド圧縮ダウンロード +admin.setting.downloadZipClientDesc=外部ネットワークにリンクできる必要があります。そうでない場合、サイトはhttpsです。 +admin.setting.downloadZipLimit=圧縮されたダウンロードサイズの制限 +admin.setting.downloadZipLimitDesc= +admin.setting.downloadZipLimitTips=圧縮されたコンテンツがシステム制限を超えています。管理者に連絡してください!圧縮せずにPCクライアントから直接フォルダをダウンロードできます。 +admin.setting.dragDownload=デスクトップにドラッグ&ドロップしてダウンロード +admin.setting.dragDownloadDesc=PC 側の Chrome カーネル ブラウザでのみサポートされます (chrome edge 360 fast など)。 +admin.setting.dragDownloadZip=複数選択ドラッグ アンド ドロップ圧縮ダウンロード +admin.setting.dragDownloadZipDesc=複数選択またはフォルダーのドラッグ アンド ドロップによるダウンロードのサポート。ダウンロードする前に、サーバー上でパッケージ化および圧縮する必要があります。 +admin.setting.dragDownloadLimit=ドラッグ アンド ドロップのコンテンツ サイズ制限 +admin.setting.dragDownloadLimitDesc= +admin.setting.dragDownloadUrlTips=URL が長すぎます。選択範囲を減らして、もう一度お試しください。 +admin.setting.dragDownloadOpenTips=管理者に連絡して、バックグラウンド設定で有効にしてください。 +admin.setting.dragDownloadNotOpen=ドラッグ アンド コンプレス ダウンロードが有効になっていません +admin.setting.dragDownloadSizeTips=ドラッグされたコンテンツのサイズが制限を超えています +admin.setting.showFileSafe=ファイルアクセスセキュリティ +admin.setting.showFileLink=ファイル外部リンク表示 +admin.setting.showFileLinkDesc=閉じた後、ファイルのプロパティに外部リンクが表示されなくなります +admin.setting.showFileMd5=ファイルmd5ディスプレイ +admin.setting.showFileMd5Desc=閉じた後、ファイルのプロパティにファイルmd5が表示されなくなります +admin.setting.shareLinkAllow=外部リンク共有を有効にする +admin.setting.shareLinkAllowDesc=終了後、外部チェーン共有はサポートされなくなり、共有コンテンツは影響を受けなくなります +admin.setting.shareLinkAllowTips=現在のシステムでは外部リンク共有が無効になっています。管理者に連絡してください。 +admin.setting.shareLinkPasswordAllowEmpty=外部チェーン共有により、パスワードを空にすることができます +admin.setting.shareLinkPasswordAllowEmptyDesc=閉じた後、外部リンク共有用のパスワードを設定する必要があります。共有コンテンツは影響を受けません。 +admin.setting.shareLinkAllowGuest=外部リンク共有により、ログに記録されていない訪問者がアクセスできます +admin.setting.shareLinkAllowGuestDesc=閉じた後、外部リンクにアクセスするときにログインする必要があります。共有コンテンツは影響を受けません。 +admin.setting.shareLinkZip=外部リンク共有パッケージのダウンロード +admin.setting.shareLinkZipDesc=開いた後、外部チェーン共有フォルダーはパッケージ化と圧縮ダウンロードをサポートします。同時実行性が大きい場合、サーバーのパフォーマンスが消費されます。 +admin.setting.shareLinkZipTips=外部リンクの共有により、パッケージ化されたダウンロードが無効になります。構成については、管理者に問い合わせてください。 +admin.setting.transferDownSpeed=ダウンロード速度制限 +admin.setting.transferDownSpeedDesc=ダウンロード速度を制限し、大規模な同時ウェブサイトの速度を均一に制限する +admin.setting.transferDownSpeedNum=ダウンロード速度制限 +admin.setting.transferDownSpeedNumDesc= +common.width=横幅 +common.height=高さ +common.test=テスト +common.absolutePath=絶対アドレス +common.qrcode=URL QRコード +common.wechat=WeChat +common.group=部門 +common.user=ユーザー +common.online=オンライン +common.use=使用するには +common.total=合計 +common.year=年 +common.month=月 +common.week=週 +common.daytime=日 +common.mon=月曜日に +common.tue=火曜日に +common.wed=水曜日に +common.thu=木曜日 +common.fri=金曜日 +common.sat=土曜日 +common.sun=日曜日 +common.second=第二 +common.minute=分 +common.hour=営業時間 +common.day=日 +common.every=各 +common.everyMonth=月額 +common.everyWeek=毎週 +common.everyDay=毎日 +common.language=多言語 +common.all=全部 +common.item=アイテム +common.items=アイテムの内容 +common.itemsEmpyt=コンテンツなし +common.detail=詳細 +common.me=私 +common.others=その他 +common.guest=訪問者 +common.more=その他 +common.learnMore=さらに詳しく +common.yes=はい +common.no=いや +common.omit=省略 +common.unknow=不明 +common.title=題名 +common.time=時間 +common.scan=ブラウズ +common.report=報告書 +common.name=お名前 +common.nickName=ニックネーム +common.tools=ツール +common.tag=ラベル +common.position=場所 +common.mount=ネットワークマウント +common.type=種類 +common.auth=権威 +common.status=ステータス +common.run=走る +common.file=ファイル +common.folder=フォルダー +common.fileType=ファイルの種類 +common.fileSize=ファイルサイズ +common.attributeInfo=プロパティ +common.actionType=操作タイプ +common.isDisplay=表示するかどうか +common.hide=隠す +common.isHide=隠し +common.cancelHide=再表示 +common.default=デフォルト +common.display=ショー +common.moveDown=下に移動 +common.moveUp=上に移動 +common.drag=引っ張る +common.dragSort=ドラッグして順序を調整します +common.warning=警告 +common.tips=ヒント +common.desc=説明 +common.tipsDesc=プロンプトの説明 +common.tipsOthers=その他の指示 +common.view=見る +common.log=ログ +common.task=タスク +common.important=重要な +common.icon=アイコン +common.menu=メニュー +common.system=システム +common.basic=ユニバーサル +common.systemSet=システム構成 +common.systemDefault=システムデフォルト +common.diy=カスタム +common.input=入力してください +common.select=選択してください +common.add=追加する +common.edit=編集 +common.action=運営 +common.upload=アップロードする +common.uploadTo=にアップロード +common.download=ダウンロードする +common.export=出力 +common.cover=カバー +common.retry=再試行 +common.zip=圧縮された +common.unzip=解凍する +common.preview=プレビュー +common.share=共有する +common.search=検索する +common.query=お問い合わせ +common.delete=削除する +common.deleteForce=完全に削除 +common.deleteEnd=削除された +common.refresh=リフレッシュ +common.open=開く +common.close=閉じる +common.from=ソース +common.greater=より大きい +common.less=より小さい +common.print=印刷する +common.selectInvert=逆選挙 +common.selectAll=すべて選択/逆選択 +common.selectAllItem=すべて選択 +common.selectNum=選択済み +common.selectNull=まったくない +common.sizeMore=上記 +common.showMore=展開する +common.showLess=崩壊 +common.sizeSmall=小 +common.sizeMiddle=中 +common.sizeBig=大 +common.rename=名前を変更 +common.method=機能 +common.extend=延長 +common.fav=お気に入り +common.reset=リセットする +common.testing=テスト中 +common.install=インストールする +common.update=更新する +common.version=バージョン +common.sysVersion=プラットフォームバージョン +common.login=サインイン +common.regist=サインアップ +common.password=パスワード +common.operateTime=稼働時間 +common.createTime=作成時間 +common.modifyTime=変更時間 +common.activeTime=アーカイブ時間 +common.startTime=開始時間 +common.endTime=終了時間 +common.finishTime=終了時間 +common.disable=無効にする +common.goOn=続ける +common.ok=OK +common.startRun=始める +common.confirmTips=もう一度確認してください +common.confirmAsk=この操作を実行してもよろしいですか? +common.submit=提出する +common.skip=スキップする +common.nextStep=次のステップ +common.start=開始する +common.stop=一時停止 +common.set=設定する +common.cancel=キャンセルする +common.save=保存する +common.empty=コンテンツなし! +common.isOpen=オン +common.isClose=閉まっている +common.apply=申込み +common.saveAll=すべて保存 +common.notSave=保存しない +common.appAdd=追加する +common.backAdd=追加に戻る +common.saveEdit=変更を保存 +common.saveSubmit=コミットを保存 +common.saveAndAdd=保存して追加を続行 +common.sex=性別 +common.male=男性 +common.female=女性 +common.address=住所 +common.email=メール +common.phone=携帯電話 +common.sms=SMS +common.phoneNumber=電話番号 +common.server=サーバー +common.handheld=モバイル機器 +common.success=成功 +common.fail=失敗する +common.error=間違った +common.result=結果 +common.expired=期限切れ +common.valid=効果的 +common.inAll=合計 +common.allAndNull=すべて選択/キャンセル +common.moveTop=ピン留め +common.moveBottom=最後に移動 +common.moveTopCancle=ピン留めを解除 +common.ECN=東中国 +common.NCN=華北 +common.SCN=華南 +common.USA=北アメリカ +common.SEA=東南アジア +common.noLimit=無制限 +common.notExists=存在しない +common.cannotWrite=読み取り専用、書き込み不可 +common.readOnly=読み取り専用 +common.cannotRead=読めない +common.ifDel=本当に削除しますか? +common.pageNotExists=ページが存在しません! +common.pathNotExists=ドキュメントが存在しません! +common.fileShare=ドキュメント共有 +common.logining=サインインしています... +common.loginTokenError=ログインの有効期限が切れました。もう一度ログインしてください! +common.loginSuccess=ログインに成功しました! +common.loginError=ログインに失敗しました +common.connectSuccess=接続に成功しました! +common.bindSuccess=バインドに成功しました! +common.bindError=バインドに失敗しました +common.clear=空の +common.congrats=おめでとう、 +common.sorry=ごめんなさい +common.invalid=無効です +common.unavailable=利用できません +common.format=書式 +common.noPermission=アクセス拒否 +common.allPermission=すべての権限 +common.invalidParam=無効なパラメーター +common.invalidFormat=無効な形式 +common.invalidRequest=不正なリクエストタイプ +common.illegalRequest=不正なリクエスト +common.expiredRequest=リクエストは期限切れです +common.errorExpiredRequest=リクエストが無効か、有効期限が切れています +common.migrating=移行中 +common.migrated=移行が完了しました +common.maintenanceTips=システムメンテナンス中は、後でご覧ください... +common.done=完成した +common.disabled=無効 +common.sizeTotal=全体の大きさ +common.sqlStatement=[SQLステートメント]: +common.env.check=環境試験 +common.env.errorLib=PHPライブラリがありません +common.env.errorIgnore=無視して入力 +common.env.errorVersion=PHPバージョンは5.0より低くすることはできません +common.env.errorPath=書き込み不可 +common.env.errorListDir= +common.env.errorGd=PHP GDライブラリを有効にする必要があります。有効にしないと、検証コードとサムネイルの使用が異常になります。 +common.env.invalidExt=%s拡張は利用できません。インストールされているか確認してください +common.env.installWithBtTips= +common.env.dataPathNotExists=データディレクトリが存在しません!
    (DATA_PATHを確認); +common.env.pathPermissionError= +common.version.free=無料 +common.version.nameQ=エンタープライズ版 +common.version.vipFree=無料版 +common.version.useFree=無料版の使用を続ける +common.version.notSupport=お使いのバージョンはこの操作をサポートしていません。公式ウェブサイトにアクセスして、高度なバージョンを購入してください! +common.version.notSupportNumber=数が限られているため、この操作はサポートされていません。公式Webサイトにアクセスして、高度なバージョンを購入してください! +common.version.toVip=コマーシャルにアップグレード +common.version.license=ライセンスの購入 +common.version.authCode=認証アクティベーションコード +common.version.authActive=アクティベーション認証 +common.version.authorization=登録認証 +common.version.authorizeSuccess=おめでとうございます、オンラインアップグレードの認証が成功しました! +common.version.networkError= +common.version.authActiveOnline=オンラインでアクティベート +common.version.authActiveOffline=オフラインでアクティブ化 +common.version.offlineTips=サーバーはインターネットにアクセスできませんか? +common.version.menuTitle=エンタープライズ情報の設定 +common.version.timeout=期限切れ +common.version.timeToService=サービスの有効期限 +common.version.timeTo=承認の有効期限 +common.version.licenseAll=永続的な承認 +common.version.kodVersion=プログラムバージョン +common.version.userLimitTitle=ユーザー番号 +common.version.userUse=中古 +common.version.userAllow=サポートされているユーザーの数 +common.version.userTo=許可されたオブジェクト +common.version.userTitle=承認情報 +common.version.basicInfo=基本情報 +common.version.appInfo=製品情報 +common.version.tipsWarning=警告、著作権を許可なく変更しないでください。必要に応じて、購入に連絡してください。 +common.version.tipsCopyLink=コピーに成功しました。貼り付けてtxtファイルに保存してください。
    USBフラッシュドライブなどを介してネットワークに接続されたコンピューターでこのリンクを開きます。 +common.version.tipsHistory=無料版は5つの履歴バージョンのみをサポートします;ライセンスされたバージョンの無制限の数を購入してください! +common.version.codeLink=承認コード要求リンク +common.version.codeLinkHelp=1.チェーンをコピーして、他のネットワーク上のコンピュータにアクセスします。
    2.取得した認証コードを入力し、ライセンス認証を有効にします。 +common.copyright.logoTitle=コーポレートアイデンティティのロゴセット +common.copyright.licenseInfo=認可情報 +common.copyright.licenseReset=再認証 +common.copyright.licenseResetTips=詳細については、再アクティブ化してください。 +common.copyright.formLogo=ログインページのロゴタイプ +common.copyright.formLogoTypeWord=テキストロゴ +common.copyright.formLogoTypeImage=画像ロゴ +common.copyright.formLogoDesc=文字ロゴは会社名、画像ロゴは以下の画像セットを使用しています。 +common.copyright.formLogoImage=ログインページのロゴ画像 +common.copyright.formLogoImageDesc=ログインページと管理背景ロゴ、推奨サイズ250x100、半透明のpng形式 +common.copyright.formLogoMain=メインインターフェイスメニューのロゴ +common.copyright.formLogoMainDesc=ファイル管理の左上隅のロゴ、推奨サイズ200x200、白い半透明のpng形式 +common.copyright.formPowerByInfo=会社著作権情報設定 +common.copyright.formPowerBy=下の著作権会社名 +common.copyright.formHomePage=下の著作権リンクのジャンプ +common.copyright.formConcat=ポップアップ連絡先 +common.copyright.formDesc=製品ポップアップ層の詳細な説明 +common.copyright.formDescTips=変更が保存されると、ページの更新が有効になります +common.copyright.formMetaKeywords=サイトのキーワード(検索エンジンで使用) +common.copyright.formMetaName=サイト名(検索エンジンで使用) +common.copyright.downloadApp=アプリのダウンロード +common.copyright.downloadLink= +common.copyright.about=について +common.copyright.desc= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=自動識別 +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=アラビア語 +common.charset.ISO_8859_6=アラビア語 +common.charset.ISO_8859_10=北欧言語 +common.charset.CP1257=バルト海周辺の言語 +common.charset.ISO_8859_13=バルト海周辺の言語 +common.charset.ISO_8859_4=バルト海周辺の言語 +common.charset.BIG5_HKSCS=伝統的な香港 +common.charset.BIG5=伝統的な台湾 +common.charset.Georgian_Academy=グルジア語 +common.charset.PT154=カザフ +common.charset.CP949=韓国人 +common.charset.EUC_KR=韓国人 +common.charset.GB18030=簡体字中国語 +common.charset.GBK=簡体字中国語 +common.charset.ISO_8859_14=ケルト +common.charset.CP1133=ラオス +common.charset.ISO_8859_16=ルーマニア語 +common.charset.ISO_8859_3=南ヨーロッパの言語 +common.charset.EUC_JP=日本語 +common.charset.ISO_2022_JP=日本語 +common.charset.SHIFT_JIS=日本語 +common.charset.KOI8_T=タジク人 +common.charset.ISO_8859_11=タイ語 +common.charset.TIS_620=タイ語 +common.charset.CP1254=トルコ語 +common.charset.CP1251=キリル文字 +common.charset.ISO_8859_5=キリル文字 +common.charset.KOI8_R=キリル文字 +common.charset.KOI8_U=キリル文字 +common.charset.CP1252=西ヨーロッパ言語 +common.charset.ISO_8859_1=西ヨーロッパ言語 +common.charset.ISO_8859_15=西ヨーロッパ言語 +common.charset.Macintosh=西ヨーロッパ言語 +common.charset.CP1255=ヘブライ語 +common.charset.ISO_8859_8=ヘブライ語 +common.charset.CP1253=ギリシャ語 +common.charset.ISO_8859_7=ギリシャ語 +common.charset.ARMSCII_8=アルメニア人 +common.charset.CP1258=ベトナム人 +common.charset.VISCII=ベトナム人 +common.charset.CP1250=中央ヨーロッパの言語 +common.charset.ISO_8859_2=中央ヨーロッパの言語 +common.charset.defaultSet=ファイルエンコーディング +common.charset.convertSave=に変換 +common.date.near=たった今 +common.date.miniteBefore=数分前 +common.date.today=今日 +common.date.yestoday=昨日 +common.date.before=前 +common.faceDefault=デフォルトの絵文字 +common.loadMore=もっと読み込む +common.numberLimit=数量が上限を超えました! +common.lengthLimit=長さが上限を超えています! +common.task.name=タスクマネージャー +common.task.title=ミッション名 +common.task.user=エグゼクティブユーザー +common.task.porcess=スケジュール +common.task.start=タスクを開始 +common.task.useTime=経過時間 +common.task.running=実行中 +common.task.stoping=一時停止 +common.task.killing=エンディング +common.task.stop=中断されたタスク +common.task.kill=タスクを終了する +common.task.removeTips=この操作を終了してもよろしいですか? +common.task.killAll=すべて終了 +common.task.killAllTips=すべてのタスクを終了してもよろしいですか? +common.task.timeStart=で始まる +common.task.timeNeed=残り +common.task.timeUse=既に実行中 +ERROR_DB_PWD=データベースアクセスが拒否されました:ユーザー名またはパスワードが間違っています。 +ERROR_DB_TIMEOUT=データベース接続がタイムアウトしました。アドレスが正しいかどうかを確認してください。 +ERROR_DB_CONN_RFS=データベース接続が拒否されました:構成情報が正しくないか、サービスが開始されていません。 +ERROR_DB_ADR=データベース接続エラーです。アドレスが正しいか確認してください。 +ERROR_DB_NOT_SUPPORT=サポートされていないデータベースタイプ。対応するサービスまたは構成ファイルが正常かどうかを確認してください。 +ERROR_DB_XS_DENNIED=データベースアクセスが拒否されました:権限が不十分です。 +ERROR_DB_NOT_EXIST=データベースが存在しないか、間違った名前が指定されました。 +explorer.pathNotSupport=このタイプのディレクトリは、この操作をサポートしていません! +explorer.pathIsRoot=ルートディレクトリに到達しました! +explorer.pathNull=フォルダが空です +explorer.zipFileLarge=ファイルが大きすぎます。プレビューする前に解凍してください! +explorer.charNoSupport=サポートされていない特殊文字: +explorer.moveError=移動に失敗しました +explorer.lockError=エラーが発生し、同時ロックがタイムアウトしました +explorer.lockErrorDesc=要求の頻度を減らすか、サーバーの同時実行に関連する構成を最適化するか、サーバーのハードウェア構成を改善してください。 +explorer.moveSubPathError=何か問題が発生したため、親ディレクトリを子ディレクトリに移動できません! +explorer.spaceIsFull=十分な空き容量がありません。管理者に連絡してください! +explorer.sessionSaveError=セッションの書き込みに失敗しました!ディスクがいっぱいかどうかを確認するか、サービスプロバイダーにご相談ください。 +explorer.networkError=ネットワーク接続エラー(net :: ERR_CONNECTION_RESET)、接続がリセットされました。
    ホスト会社またはネットワーク管理者に連絡して、ファイアウォールの構成を確認してください! +explorer.folderManage=管理ディレクトリ +explorer.clickEdit=クリックして編集 +explorer.shortLink=ショートカット +explorer.upper=上層 +explorer.historyNext=アドバンス +explorer.historyBack=戻る +explorer.loading=動作中... +explorer.getting=取得中... +explorer.sending=データを送信しています... +explorer.pullTips=プルダウンしてページを更新します +explorer.pullDropTips=ページを自由に更新 +explorer.getSuccess=成功する! +explorer.saveSuccess=正常に保存されました! +explorer.saveError=保存できませんでした! +explorer.success=操作が成功しました +explorer.error=操作に失敗しました +explorer.dataError=データが異常です! +explorer.pathError=ドキュメントパスエラー +explorer.repeatError=操作が失敗しました。名前は既に存在します! +explorer.systemError=システムエラー +explorer.mistake=何かがうまくいきませんでした! +explorer.recycleClear=空のごみ箱 +explorer.recycleClearForce=ごみ箱の内容が多すぎます。最初にごみ箱を空にしてください。 +explorer.recycleRestore=ごみ箱を復元する +explorer.recycleRestoreItem=復元する +explorer.recycleRestoreAll=すべて復元 +explorer.recycleClearInfo=ごみ箱を完全に空にしますか? +explorer.zipDownloadReady=圧縮後に自動的にダウンロードします。お待ちください... +explorer.removeItem=アイテムの内容 +explorer.uploading=アップロード中 +explorer.uploadTipsMore=ファイルが多すぎる場合は、圧縮後にアップロードしてから、オンラインで解凍することをお勧めします! +explorer.uploadingMove=マージと転送... +explorer.viewNewPage=新しいページのプレビュー +explorer.unknowFileTitle=ファイルを開くためのヒント! +explorer.unknowFileTips=このファイルをサポートするアプリがなければ、次のことができます。 +explorer.unknowAppTips=アプリなし: +explorer.unknowFileTry=お試しください +explorer.unknowFileDown=ファイルをダウンロードする +explorer.authFileDown=ファイルのダウンロード +explorer.authShare=共有する +explorer.usersShare=共有の +explorer.clipboard=クリップボードを表示 +explorer.clipboardClear=空のクリップボード +explorer.fullScreen=フルスクリーン +explorer.folderItem=アイテム +explorer.folderItemSelect=選択済み +explorer.dbLoadAll=ダブルクリックしてすべてをロードします... +explorer.ziping=圧縮しています... +explorer.unziping=解凍... +explorer.zipingTips=操作を圧縮しています。お待ちください... +explorer.unzipingTips=解凍操作、お待ちください... +explorer.unzipRarTips=ファイルの内容が破損しているか、ファイルの解析がサポートされていません。ZIP 形式を使用することをお勧めします。 +explorer.parsing=取得しています... +explorer.moving=移動操作... +explorer.copyMove=コピー移動 +explorer.removeTitle=確認を削除 +explorer.removeInfo=選択を削除してもよろしいですか? +explorer.removeTitleForce=完全に削除 +explorer.removeInfoForce=このドキュメントを完全に削除してもよろしいですか? +explorer.pathInRecycle=フォルダはごみ箱にあります。復元してもう一度お試しください。 +explorer.pathInRecycleFile=ファイルはごみ箱にあります。復元して再試行してください。 +explorer.downOffline=オフラインでダウンロード +explorer.savePath=パスを保存 +explorer.uploadSelectMuti=アップロードする複数のファイルを選択 +explorer.goTo=にジャンプ +explorer.selectFile=ファイルを選択 +explorer.selectFolder=フォルダーを選択 +explorer.selectImage=写真を選択してください... +explorer.selectValidFolder=有効にするフォルダーを選択してください! +explorer.selectFolderFile=ファイルまたはフォルダーを選択 +explorer.selectMulti=複数選択 +explorer.notNull=必須フィールドは空にできません! +explorer.picCannotNull=画像アドレスは空にできません! +explorer.renameSuccess=名前を変更しました! +explorer.inputSearchWords=検索する文字列を入力してください +explorer.search.optionContent=ドキュメントの内容 +explorer.search.searchContentTips=キーワード検索ファイルの内容、サポートテキストファイル +explorer.search.optionMutil=一括検索 +explorer.search.optionMutilDesc=1行に1つの検索語、検索結果は検索語に従って並べ替えられます +explorer.removeSuccess=削除しました! +explorer.removeFail=削除に失敗しました! +explorer.clipboardNull=クリップボードが空です! +explorer.createSuccess=新しい成功! +explorer.createError=新規作成に失敗しました。ディレクトリの権限を確認してください! +explorer.copySuccess=[コピー]-クリップボードを正常に上書きします! +explorer.cuteSuccess=[カット]-クリップボードを正常に上書きします! +explorer.clipboardState=クリップボードの状態: +explorer.copyOK=コピーしました! +explorer.copyNotExists=ソースが存在しません +explorer.currentHasParent=宛先フォルダーは、ソースフォルダーのサブフォルダーです! +explorer.pastSuccess=貼り付け操作が完了しました +explorer.cutePastSuccess=カット操作完了 +explorer.zipSuccess=圧縮完了 +explorer.notZip=圧縮ファイルではありません +explorer.zipNull=ファイルまたはディレクトリが選択されていません +explorer.unzipSuccess=解凍完了 +explorer.pathIsCurrent=開いたパスは現在のパスと同じです! +explorer.pathExists=名前はすでに存在します! +explorer.serverDownDesc=ダウンロードリストに追加されたタスク +explorer.parentPermission=親ディレクトリのアクセス許可 +explorer.confirm=よろしいですか? +explorer.ifSaveFileTips=未保存のファイルはありますか? +explorer.ifSaveFile=ファイルはまだ保存されていません。保存されていますか? +explorer.ifStopUploadTips=ファイルをアップロードしていますが、ウィンドウを閉じてもよろしいですか? +explorer.noPermissionRead=読み取り許可がありません! +explorer.noPermissionDownload=ダウンロードする権限がありません! +explorer.noPermissionWrite=ディレクトリに書き込み権限がありません +explorer.noPermissionAction=あなたにはこの許可がありません。管理者に連絡してください! +explorer.noPermissionWriteAll=ファイルまたはディレクトリに書き込み権限がありません +explorer.noPermissionWriteFile=ファイルに書き込み権限がありません +explorer.noPermissionReadAll=ファイルまたはディレクトリに読み取り権限がありません +explorer.noPermission=管理者がこの権限を無効にしています! +explorer.noPermissionExt=管理者がこのタイプのファイル許可を無効にしました +explorer.noPermissionGroup=あなたはこのユーザーグループにいません! +explorer.pathNoWrite=ディレクトリは書き込み可能ではありません。ディレクトリとすべてのサブディレクトリを読み取りと書き込みに設定し、再試行してください! +explorer.onlyReadDesc=このディレクトリには書き込み権限がありません。サーバー上のこのディレクトリに権限を設定できます +explorer.settingSuccess=変更が有効になりました! +explorer.noRepeat=重複は許可されません +explorer.dataNotFull=データの提出が不完全です! +explorer.tooManyToView=コンテンツ(%s アイテム)が多すぎます。ローカルで開いて表示してください。 +explorer.jumpAfterWhile=%ss後に自動的にジャンプ、今すぐジャンプ +explorer.retryTips=確認してもう一度お試しください +explorer.selectObject=オブジェクトを選択 +explorer.parentGroup=優れた部門 +explorer.actionAuth=操作権限 +explorer.notSelectDesc=データがありません、選択してください! +explorer.groupAuthCopy=組み合わせをコピーする +explorer.groupAuthCopyDesc=権限の組み合わせをコピーする +explorer.groupAuthPasteDesc=コピーした権限の組み合わせを貼り付けます +explorer.groupAuthSave=お気に入りに保存 +explorer.groupAuthRecent=最近使用された +explorer.selectDesc=コンテンツを選択 +explorer.cannotLoad=結果を読み込めません。 +explorer.loadMore=さらに結果を読み込む... +explorer.noSearchData=結果が見つかりません +explorer.delAllItem=すべてのアイテムを削除 +explorer.pleaseDel=削除してください +explorer.pleaseInput=少なくとも入力してください +explorer.canChoose=最大でのみ選択 +explorer.theChars=キャラクター +explorer.theItems=アイテム +explorer.noData=データなし +explorer.ifPathAuthClear=すべてのサブファイルとフォルダーのアクセス許可設定がクリアされます。続行してもよろしいですか? +explorer.fileDescAdd=ドキュメントの説明を追加 +explorer.fileDesc=ドキュメントの説明 +explorer.fileLog=ドキュメントログ +explorer.ifResetOpen=すべてのカスタムオープニングメソッドをリセットしてもよろしいですか? +explorer.ResetOpen=すべてのカスタムオープンメソッドをリセットする +explorer.openWith=他の方法で開く +explorer.openWithAce=エディターで開く +explorer.openWithLocal=ローカルで開く +explorer.openWithLocalEdit=ローカル編集 +explorer.editorSaveTips=ファイルは作成されていません。最初に新しいファイルを保存してください +explorer.editor.fileTooBig=ファイルが大きすぎ、20Mを超えることはできません +explorer.errorFunctionTips=このタイプのファイルは関数リストをサポートしていません! +explorer.errorFormatTips=現在のファイルタイプはデフォルトのフォーマット方法と一致しません。
    手動で選択してください +explorer.cuteToThe=移動先: +explorer.copyToThe=コピー先: +explorer.addToFav=お気に入りに追加 +explorer.addFav=お気に入りを追加 +explorer.delFav=収集をキャンセル +explorer.addFavSuccess=お気に入りを追加しました +explorer.pathHasFaved=パスがお気に入りになっています +explorer.delFavSuccess=収集をキャンセルします +explorer.fileLock=ファイルを保護 +explorer.fileLockNow=保護 +explorer.fileLockCancle=保護を解除する +explorer.fileLockTitle=保護されています +explorer.fileLockTips=保護されています(他の人はファイルを編集できません) +explorer.fileLockUser=ロッカー +explorer.fileLockError=現在のファイルは保護されています。保護しているユーザーに連絡して保護を解除し、再試行してください。 +explorer.downloaded=ダウンロード完了 +explorer.openAutoTips=自動的に開きます +explorer.historyAutoTips=履歴バージョンを自動生成 +explorer.saved=正常に保存されました +explorer.opened=正常に開きます! +explorer.openFail=オープンに失敗しました! +explorer.openingWithLoc=ファイルはローカルで開いています... +explorer.openOnlyView=読み取り専用モードがオンになっている +explorer.saving=ファイルの保存... +explorer.notSupport=問題が発生しました。コンテンツ形式はサポートされていません。 +explorer.unzipErrorTips=何かがうまくいきませんでした!認識されない圧縮ファイル形式。
    ファイルが圧縮されているか、破損していないか確認してください。 +explorer.wordLoading=読み込み中... +explorer.noFunction=まさか! +explorer.paramFormatError=パラメータの形式が間違っています! +explorer.descTooLong=説明が長すぎます +explorer.noMoreThan=せいぜい +explorer.desktopDelError=申し訳ありませんが、デスクトップフォルダーは削除をサポートしていません! +explorer.copy=コピー +explorer.past=貼り付け +explorer.clone=コピーを作成する +explorer.cute=カット +explorer.cuteTo=に移動... +explorer.copyTo=コピー先... +explorer.info=プロパティ +explorer.searchInPath=フォルダー内を検索 +explorer.addToPlay=プレイリストに追加 +explorer.manageFav=お気に入りを管理 +explorer.refreshTree=ツリーディレクトリを更新する +explorer.zip=圧縮パッケージを作成する +explorer.unzip=解凍 +explorer.unzipFolder=フォルダに出力 +explorer.unzipThis=直接解凍 +explorer.unzipTo=フォルダを指定して解凍 +explorer.openProject=エディターオープンプロジェクト +explorer.createLink=ショートカットを作成する +explorer.createLinkHome=デスクトップへのショートカットを送信 +explorer.setBackground=デスクトップの壁紙として設定 +explorer.favRemove=このコレクションをキャンセル +explorer.openPath=ディレクトリに移動します +explorer.openPathFinished=すでにディレクトリに入っています +explorer.openIE=ブラウザが開きます +explorer.newFile=新しいファイル +explorer.newFolder=新しいフォルダー +explorer.fileSaveTo=ファイルを保存しました +explorer.openFather=上部フォルダー表示 +explorer.uploadFile=ファイルをアップロード +explorer.uploadFolder=アップロードフォルダ +explorer.appOpenDefault=デフォルトで開くように設定 +explorer.appOpenAways=常に選択したプログラムでこのファイルを開きます +explorer.appSelectDesc=このファイルを開くために使用するプログラムを選択します +explorer.appSelectMenu=デフォルトのオープン モードとして設定 +explorer.appSelectMenuCancel=で開くデフォルトとして設定解除 +explorer.appSelectWarning=アプリケーションを選択してください! +explorer.appTypeSupport=サポートアプリケーション +explorer.appTypeAll=すべてのアプリケーション +explorer.appSearch=関連するアプリのインストールを検索する +explorer.recent.createTime=作成日 +explorer.recent.modifyTime=変更日 +explorer.recent.viewTime=で開く +explorer.urlLink=外部リンクアドレス +explorer.downloading=ダウンロードしています... +explorer.downReady=近日公開 +explorer.downError=ダウンロードに失敗しました! +explorer.max=最大化 +explorer.min=最小化 +explorer.minAll=すべてを最小化 +explorer.displayAll=すべてのウィンドウを表示 +explorer.closeAll=すべて閉じる +explorer.authDtl=クリックして、ディレクトリ内の権限を表示します +explorer.authDialog=内部メンバー、ドキュメントコラボレーションレベルの権限テーブル +explorer.authNote=注:管理機能には、メンバー許可の設定/コメント管理などが含まれます。注意してください! [システム管理者]役割は権限によって制限されません +explorer.auth.toOuter=外部認証(他の部門またはユーザー) +explorer.auth.share=共有者 +explorer.auth.owner=所有者 +explorer.auth.disableDeep=権限なしアクセスのみ +explorer.auth.disableDeepDesc=ファクタディレクトリには、ドキュメントの読み取りおよび書き込み権限と、確立されたアクセスパスがあります。 +explorer.auth.tips=上記のユーザーに連絡して権限を設定できます +explorer.notSystemPath=システムファイルパスではありません +explorer.toolbar.rootPath=パーソナルスペース +explorer.toolbar.fav=お気に入り +explorer.toolbar.desktop=デスクトップ +explorer.toolbar.client=クライアント +explorer.toolbar.myComputer=コンピューター +explorer.toolbar.recycle=ごみ箱 +explorer.toolbar.myDocument=ドキュメント +explorer.toolbar.myPicture=ピクチャ +explorer.toolbar.myMusic=ミュージック +explorer.toolbar.myMovie=ビデオ +explorer.toolbar.myDownload=ダウンロード +explorer.toolbar.uiDesktop=デスクトップ +explorer.toolbar.uiExplorer=ファイル管理 +explorer.toolbar.uiEditor=編集者 +explorer.toolbar.uiProjectHome=プロジェクトホーム +explorer.toolbar.uiLogout=ログアウト +explorer.toolbar.uiGroup=組織構造 +explorer.toolbar.myGroup=私の部署 +explorer.toolbar.publicPath=パブリックディレクトリ +explorer.toolbar.recentDoc=最近使用したファイル +explorer.toolbar.myShare=共有 +explorer.toolbar.shareToMe=私と協力する +explorer.toolbar.shareTo=共有されたファイル +explorer.toolbar.shareLink=外部リンク共有 +explorer.toolbar.photo=フォトアルバム +explorer.photo.desc=ユーザーアルバムの分類 +explorer.photo.group=アルバムのグループ化 +explorer.photo.setting=アルバム設定 +explorer.photo.pathRoot=アルバムスキャンディレクトリ +explorer.photo.pathRootSelect=アルバム画像スキャンのルートディレクトリとしてフォルダを選択します +explorer.photo.fileType=ファイルの種類を指定する +explorer.photo.fileSize=ファイルサイズフィルター +explorer.photo.fileSizeDesc=この設定より大きいファイルのみをフィルタリングします。0の場合、制限はありません。 +explorer.toolbar.folder=カタログアルバム +explorer.toolbar.folderSelect=アルバムモードで表示するフォルダを選択します +explorer.pathDesc.fav=ファイルがコレクションに追加された後、すばやく直接アクセスできます +explorer.pathDesc.home=パーソナルスペースはあなたのプライベートストレージスペースです、他のユーザーには表示されず、自分だけに表示されます +explorer.pathDesc.groupRoot=これは、企業/ユニットのパブリックスペースです。デフォルトでは、すべてのメンバーが表示されます +explorer.pathDesc.myGroup=ここであなたの部門のドキュメントを管理し、部門のドキュメントは、この部門のメンバーのみが表示および操作でき、他の部門のメンバーには表示されません。 +explorer.pathDesc.group=部門のメンバーにのみ表示される部門のネットワークディスク、運用権限は、部門管理者が割り当て、設定します。 +explorer.pathDesc.recentDoc=最近作成、アップロード、変更、および開かれたファイル +explorer.pathDesc.shareTo=他の人が開始した[内部コラボレーション]プロジェクトをここで表示および管理します +explorer.pathDesc.shareLink=ここであなたが開始した外部チェーン共有を表示および管理します +explorer.pathDesc.recycle=ここで削除したファイル(フォルダ)を管理します +explorer.pathDesc.fileType=ファイルをタイプ別に分類します。個人用スペースのファイルのみです。 +explorer.pathDesc.tag=効率的な分類と高速クエリを実現するために、ファイル(フォルダー)にタグを追加します +explorer.pathDesc.tagItem=ファイル/フォルダにラベルを追加してみてください! +explorer.pathDesc.mount=ここでは、複数のバックエンドストレージと、サーバーにマウントされたディスクを管理できます +explorer.pathDesc.shareToMe=タイル表示-私がコラボレーションしたすべてのコンテンツ +explorer.pathDesc.shareToMeUser=共有者による表示-私が共同作業したコンテンツは、開始者によって分類されます +explorer.pathDesc.shareToMeUserItem=このユーザーによって開始されたコラボレーション +explorer.pathDesc.shareToMeGroup=私がコラボレーションしているコンテンツは、フォルダーが配置されている部門によって分類されています +explorer.pathDesc.shareToMeGroupGroup=部門のネットワークディスクからの共同共有 +explorer.pathDesc.search=ファイル/タグ/メモ/コンテンツの検索をサポートします。拼音、最初の文字のあいまい一致をサポート +explorer.pathDesc.searchMore=より多くの検索条件を設定する +explorer.pathDesc.shareFrom=ソースパス +explorer.pathGroup.shareGroup=部門スペース +explorer.pathGroup.shareGroupDesc=下位部門にコンテンツがある場合のアクセス +explorer.pathGroup.shareUser=部門メンバーの個人的なスペース共有 +explorer.pathGroup.shareUserDesc=出典:ユーザーの個人用スペースの共有、ユーザーが開始した外部部門のドキュメント共有。 +explorer.pathGroup.shareContent=部門の宇宙コラボレーションと共有 +explorer.pathGroup.group=サブ部門 +explorer.pathGroup.groupContent=部門文書 +explorer.pathGroup.shareUserOuter=外部コラボレーション共有 +explorer.pathGroup.shareUserOuterDesc=独自の組織構造に属さない外部ユーザーの共同共有 +explorer.pathGroup.shareSelf=パーソナルスペース +explorer.toolbar.fileSizeTitle=アイコンサイズ +explorer.toolbar.fileSizeSuper=超小 +explorer.toolbar.fileSizeSmall=小さなアイコン +explorer.toolbar.fileSizeDefault=中アイコン +explorer.toolbar.fileSizeBig=大きなアイコン +explorer.toolbar.fileSizeBigSuper=特大のアイコン +explorer.toolbar.PagePC=PC版 +explorer.toolbar.pagePhone=モバイル版 +explorer.file.name=名前 +explorer.file.type=種類 +explorer.file.contain=含む +explorer.file.address=場所 +explorer.file.detil=説明 +explorer.file.linkCount=引用 +explorer.file.size=大きさ +explorer.file.count=量 +explorer.file.byte=バイト +explorer.file.path=パス +explorer.file.action=運営 +explorer.file.creator=作成者 +explorer.file.editor=変更者 +explorer.file.location=場所 +explorer.file.timeInfo=時間情報 +explorer.file.createTime=作成時間 +explorer.file.modifyTime=変更時間 +explorer.file.lastTime=最後の訪問 +explorer.file.sortType=並べ替え +explorer.file.sortDisable=コンテンツは指定された並べ替えをサポートしていません! +explorer.file.timeType=Y / m / d H:i:s +explorer.file.timeTypeInfo=Y / m / d H:i:s +explorer.file.listType=表示する +explorer.file.listIcon=アイコンの配置 +explorer.file.listList=リストの並べ替え +explorer.file.listListSplit=列モード +explorer.file.listTypeGroup=表示モードと並べ替え方法 +explorer.file.listTypeKeep=ディスプレイモード +explorer.file.listTypeKeepDesc=フォルダごとに表示モードを選択するか、すべてのフォルダに同じ表示モードを使用します +explorer.file.listSortKeep=並び替え +explorer.file.listSortKeepDesc=フォルダーごとに列の並べ替え順序を構成するか、すべてのフォルダーに同じ順序を使用します +explorer.file.listViewKeep=単一のフォルダーで動作します +explorer.file.listViewAll=すべてのフォルダに適用されます +explorer.file.listViewReset=デフォルトにリセット +explorer.file.sortUp=昇順 +explorer.file.sortDown=降順 +explorer.file.orderType=並べ替え +explorer.file.orderDesc=降順 +explorer.file.orderAsc=昇順 +explorer.file.imageSize=画像サイズ +explorer.file.sharer=共有者 +explorer.file.shareTime=共有時間 +explorer.file.viewCnt=訪問数 +explorer.file.downCnt=ダウンロード +explorer.file.readWriteLock=この操作は一時的にサポートされていません。他の読み取りおよび書き込みタスクが処理されています。後でもう一度やり直してください。 +explorer.app.app=アプリケーション +explorer.app.createLink=新しい URL +explorer.app.create=アプリケーションを作成する +explorer.app.edit=アプリを編集する +explorer.app.open=アプリを開く +explorer.app.groupGame=ゲーム +explorer.app.groupTools=ツール +explorer.app.groupReader=読む +explorer.app.groupMovie=ムービー +explorer.app.groupMusic=ミュージック +explorer.app.groupLife=人生 +explorer.app.desc=アプリケーションの説明 +explorer.app.icon=アプリケーションアイコン +explorer.app.iconShow=URLアドレスまたはディレクトリ +explorer.app.group=アプリケーションのグループ化 +explorer.app.type=種類 +explorer.app.typeUrl=リンク +explorer.app.typeCode=js拡張 +explorer.app.display=外観 +explorer.app.displayBorder=フチなし +explorer.app.displaySize=サイズ変更(選択して調整) +explorer.app.size=大きさ +explorer.app.url=リンクアドレス +explorer.app.code=jsコード +explorer.app.appType=アプリケーションの種類 +explorer.app.website=URL +explorer.app.shortLink=ファイルのショートカット +explorer.app.imgIcon=画像アイコン +explorer.app.imgIconUrl=画像を選択するか、Web画像のURLを貼り付けます。 +explorer.app.path=パス +explorer.app.pathDesc=手動変更をサポートしていません。ファイルを右クリックしてショートカットを作成できます +explorer.app.link=URLリンク +explorer.app.linkDesc=http / httpsリンクを入力してください +explorer.app.linkDragTips=URL リンクをファイル領域にドラッグすると、URL リンクが自動的に作成されます。 +explorer.app.openType=道を開く +explorer.app.openWindow=新しい窓 +explorer.app.openDialog=ダイアログボックス +explorer.app.openCurrent=現在のページ +explorer.app.openInline=ページを埋め込む +explorer.app.dialogSize=ダイアログサイズ +explorer.app.with=幅 +explorer.app.height=身長 +explorer.app.moreSet=その他の設定 +explorer.app.canDiyWith=幅調整を許可する +explorer.app.miniBlock=ミニマリストのタイトルバー +explorer.app.runCode=jsコードを実行する +explorer.app.name=アプリケーション名 +explorer.app.nameDesc=アプリケーション名を入力してください。 +explorer.app.descDesc=アプリケーションの説明を入力してください +explorer.embed.title=埋め込みファイル +explorer.embed.desc=Webページまたはブログにファイルを埋め込みます +explorer.embed.url=埋め込みURL +explorer.embed.code=埋め込みコード +explorer.upload.ready=アップロードを待っています +explorer.upload.success=アップロードしました +explorer.upload.secPassSuccess=数秒で成功 +explorer.upload.pathCurrent=現在のディレクトリに変更します +explorer.upload.select=ファイルを選択 +explorer.upload.maxSize=最大許容 +explorer.upload.sizeInfo=より大きく設定する場合は、php.iniで許可される最大アップロードを変更してください。ファイルを選択すると、この構成より大きいファイルは自動的に除外されます。 +explorer.upload.error=アップロードに失敗しました +explorer.upload.mergeError=ファイルのマージに失敗しました +explorer.upload.errorHttp=ネットワークまたはファイアウォールのエラー +explorer.upload.muti=複数ファイルのアップロード +explorer.upload.drag=ドラッグアンドドロップでアップロード +explorer.upload.dragFolder=アップロードするフォルダにドラッグアンドドロップします +explorer.upload.dragTips=リリースしてアップロード! +explorer.upload.pathNotAllow=ファイル名は許可されていません +explorer.upload.errorNull=文書はありません! +explorer.upload.errorBig=ファイルサイズがサーバーの制限を超えています +explorer.upload.errorMove=ファイルを移動できませんでした! +explorer.upload.errorExists=ファイルは既に存在します +explorer.upload.local=ローカルにアップロードする +explorer.upload.tips=php.iniで制限されなくなったフラグメントアップロードを使用します。Chromeエクスペリエンスフォルダーのドラッグアンドアップロードが推奨されます +explorer.upload.exist=同じ名前のファイル処理 +explorer.upload.clearAll=すべてクリア +explorer.upload.clear=排出完了 +explorer.upload.addMore=一括追加 +explorer.upload.errorEmpty=空にすることはできません! +explorer.upload.errorExt=ファイル拡張子が一致しません! +explorer.upload.fileSizeDisable=同時にアップロード/転送されるファイルが多すぎます。管理者に連絡して調整してください。 +explorer.upload.moreDesc=(2000以下を推奨)、現在合計: +explorer.upload.scan=スキャン中 +explorer.upload.merge=マージの検証 +explorer.upload.needTime=残り約 +explorer.upload.checkError=アップロードの確認に失敗しました。もう一度お試しください +explorer.upload.saveError=ファイル情報のアップロードに失敗しました +explorer.upload.downloadDesc=http / httpsネットワークリンクのみをサポート +explorer.table.first=ホーム +explorer.table.last=最後のページ +explorer.table.prev=前へ +explorer.table.next=次のページ +explorer.table.one=合計1ページ +explorer.table.page=ページ +explorer.table.itemPage=/ページ +explorer.table.searchTotal=見つかった +explorer.table.items=記録 +explorer.table.list=データリスト +explorer.search.ing=検索しています... +explorer.search.result=検索結果 +explorer.search.resultTooMore=検索結果が多すぎるため、別のディレクトリまたは単語を提案してください +explorer.search.resultNull=検索結果がありません! +explorer.search.caseSensitive=大文字と小文字を区別 +explorer.search.content=ファイルのコンテンツを検索する +explorer.search.extDesc=フィルタリングする拡張子をスペースで区切って入力します。 +explorer.search.byItems=条件付きフィルタリング +explorer.search.extNull=指定なし +explorer.search.extFile=任意のファイル +explorer.search.extDiy=カスタム +explorer.search.inputDesc=キーワードを入力するか、フィルターを提供してください! +explorer.search.path=ディレクトリを検索します。 +explorer.search.rootPath=ルートディレクトリを検索します。 +explorer.search.range=検索範囲 +explorer.search.allFolder=すべてのフォルダー +explorer.search.currentFolder=現在のフォルダー +explorer.search.ext=ファイルの種類 +explorer.search.timeRange=時間範囲 +explorer.search.timeAll=全ての時間 +explorer.search.lastDay=1日前 +explorer.search.lastWeek=過去7日間 +explorer.search.lastMonth=過去30日間 +explorer.search.lastYear=過去1年間 +explorer.search.sizeAll=全てのサイズ +explorer.search.inputNullDesc=入力されていない場合、特定の値よりも大きいあるいは小さいことを意味します。 +explorer.search.selectUser=ユーザーを選択してください... +explorer.search.byUserDesc=作成者/変更者で検索 +explorer.search.total=見つかった +explorer.search.noResult=申し訳ありませんが、検索結果はありません。別の検索語を試してください! +explorer.search.advance=高度な検索 +explorer.search.clear=明確なコンテンツ +explorer.history.list=ファイル履歴 +explorer.history.lastModify=最終変更 +explorer.history.modifyUser=変更者 +explorer.history.noHistory=過去のバージョンはありません! +explorer.history.current=現在のバージョン +explorer.history.detil=説明 +explorer.history.detilAdd=インプリントを追加 +explorer.history.uploadNew=新しいバージョンをアップロード +explorer.history.diff=過去のバージョンの比較 +explorer.history.setCurrent=現在のバージョンとして設定 +explorer.history.delCurrent=このバージョンを削除 +explorer.history.delAll=すべてのバージョン履歴を削除する +explorer.history.ifDelAll=すべての履歴を削除してもよろしいですか? +explorer.history.ifDelCurrent=このバージョンを削除しますか? +explorer.history.ifRollback=このバージョンにロールバックしてもよろしいですか? +explorer.history.changeEvent=過去のバージョンの切り替え +explorer.history.before=前 +explorer.history.after=後 +explorer.recycle.clearUser=ユーザーのごみ箱を空にします +explorer.recycle.restoreSelect=このコンテンツを復元する +explorer.recycle.moveTo=引き渡す +explorer.recycle.config=ごみ箱の設定 +explorer.recycle.configTitle=システムのごみ箱の設定 +explorer.recycle.configOpen=システムのごみ箱を開く +explorer.recycle.configOpenDesc=開くことを提案する +explorer.recycle.configCloseInfo=コンテンツを削除すると、システムのごみ箱には入れられず、直接削除されます。 +explorer.recycle.configOpenInfo= +explorer.recycle.restoreConfirm=ドキュメントを復元してもよろしいですか?
    復元後、ドキュメントはターゲットルートディレクトリに移動されます +explorer.recycle.moveConfirm=ハンドオーバーの確認 +explorer.recycle.moveSelectTarget=ユーザーまたは部門を選択します +explorer.recycle.moveDesc= +explorer.recycle.taskTitle=システムのごみ箱の清掃 +explorer.recycle.taskDesc=設定時間を超えたごみ箱の内容を自動的に削除して、ストレージスペースを解放します +explorer.share.add=共有を追加 +explorer.share.edit=共有を編集 +explorer.share.remove=共有をキャンセル +explorer.share.path=共有パス +explorer.share.source=リソース共有 +explorer.share.name=タイトルを共有する +explorer.share.nameDesc=デフォルトでファイル名を共有し、カスタマイズ可能 +explorer.share.time=有効期限 +explorer.share.timeLimit=期間限定 +explorer.share.timeLimitDesc=電源を入れて設定すると、時間が経過すると自動的に共有が無効になります +explorer.share.timeDesc=空の場合は設定されません +explorer.share.pwd=パスワードを抽出する +explorer.share.pwdDesc=パスワードが設定されていません +explorer.share.randomPwd=ランダムに生成 +explorer.share.randomPwdDesc=よりプライベートで安全なパスワードを抽出することでのみ表示できます。 +explorer.share.cancel=共有をキャンセル +explorer.share.create=公開リンクを作成 +explorer.share.url=共有アドレス +explorer.share.noDown=ダウンロード禁止 +explorer.share.codeRead=コード読み取り +explorer.share.configSave=設定を保存する +explorer.share.errorParam=パラメータエラー! +explorer.share.errorUser=ユーザー情報が間違っています! +explorer.share.errorSid=共有は存在しません! +explorer.share.errorTime=あなたは遅れています、この共有は期限切れです! +explorer.share.errorPath=共有ファイルは存在せず、削除または移動されました! +explorer.share.errorPwd=パスワードが間違っています! +explorer.share.errorShowTips=このタイプのファイルはプレビューをサポートしていません! +explorer.share.expiredTips=申し訳ありませんが、この共有は有効期限が切れています。共有者に連絡してください! +explorer.share.downExceedTips=共有のダウンロードが共有者が設定した制限を超えました +explorer.share.store=SkyDriveに保存 +explorer.share.loginTips=申し訳ありませんが、アクセスするにはこの共有にログインしている必要があります! +explorer.share.noDownTips=申し訳ありませんが、共有者はダウンロードを無効にしています! +explorer.share.noViewTips=申し訳ありませんが、この共有者はプレビューを無効にしています! +explorer.share.noUploadTips=申し訳ありませんが、この共有者はアップロードを無効にしています! +explorer.share.needPwd=この共有にはパスワードが必要です +explorer.share.notExist=共有は存在しません! +explorer.share.viewNum=閲覧: +explorer.share.downNum=ダウンロード +explorer.share.openPage=共有ページを開く +explorer.share.openLink=共有リンクを開く +explorer.share.copyLink=共有リンクをコピーする +explorer.share.link=リンクを共有: +explorer.share.accessPwd=アクセスパスワード: +explorer.share.copied=コピー済み +explorer.share.actionNotSupport=コンテンツを共有します。この操作はサポートされていません +explorer.share.errorPathTips=共有リンクが間違っているか、共有者が外部リンクの共有をキャンセルしました +explorer.share.shareTo=共同共有 +explorer.share.shareToTarget=共同メンバー +explorer.share.innerTo=内部コラボレーション +explorer.share.linkTo=外部リンクの共有 +explorer.share.selectTarget=共同共有する部門またはユーザーを選択します +explorer.share.afterShareDesc=相手または所属する部門と共有すると、ユーザーは[共有]でそれを見ることができます。 +explorer.share.openOuterLink=オープンな外部チェーン共有 +explorer.share.openOuterLinkDesc=外部リンクを作成したら、メールまたはQQで他の人に送信できます。 +explorer.share.outerLink=リンクを共有 +explorer.share.advanceSet=高度な構成 +explorer.share.loginLimit=ログインしているユーザーのみが利用可能 +explorer.share.loginLimitDesc=開いた後は、内部メンバーのみがアクセスできます。 +explorer.share.authLimit=権利と制限 +explorer.share.canUpload=アップロードを許可 +explorer.share.notView=プレビューを無効にする +explorer.share.notDown=ダウンロードを無効にする +explorer.share.downNumLimit=ダウンロード制限 +explorer.share.downNumLimitDesc=この回数を過ぎると、共有リンクは自動的に期限切れになります。 +explorer.share.learnAuth=ドキュメントコラボレーション許可について +explorer.share.shareToRemove=この共同共有をキャンセルしてもよろしいですか?
    共有したターゲットユーザーは、共同共有を表示できなくなります。 +explorer.share.shareLinkRemove=外部リンクの共有をキャンセルしてもよろしいですか?
    キャンセル後、外部リンクは無効になります! +explorer.share.shareToCopy=アクセスパスをコピーする +explorer.share.shareToCopyDesc=リンクを共同作業者に送信して、すぐに共同作業に参加できます +explorer.share.specifyAuthTips=上記の指定ユーザーに加えて +explorer.share.specifyAuthDesc=指定ユーザー権限>指定ユーザーの部門権限>その他の個人権限 +explorer.share.selfAuthDesc=自分の権限を変更することはできません。他のマネージャーが設定できます +explorer.share.authTypeDesc=既定で親フォルダーからアクセス許可を継承する +explorer.share.rootPathAuthDesc=ルート部門のサポートユーザーおよび部門の選択 +explorer.share.subPathAuthDesc=サブ部門、部門のメンバーのみを選択 +explorer.share.myAuth=私の許可 +explorer.share.othersAuth=その他の許可 +explorer.share.keepAuth=元の権限を保持 +explorer.share.specifyAuth=許可を指定する +explorer.share.userAuth=ユーザー権利 +explorer.share.specifyUserAuth=ユーザー許可の指定 +explorer.share.rptTitle=違法で有害な情報を見つけた場合は、以下の理由を選択して報告してください。 +explorer.share.illegal=違法な情報 +explorer.share.inputRptDesc=報告の理由を入力してください +explorer.share.rptSend=送信は成功し、管理者が時間内に処理します +explorer.share.rptSended=管理者が処理するのを待っているレポートが送信されました +explorer.auth.mutil=権限をバッチで設定する +explorer.auth.mutilTips= :選択したコンテンツに既に権限がある場合は、上書きされます。 +explorer.auth.mutilDesc=後続のデフォルトのアクセス許可と同時に +explorer.auth.showMore=許可の詳細 +explorer.auth.tabUser=部門メンバー +explorer.auth.tabChildren=サブフォルダーのアクセス許可 +explorer.auth.tabUserTips=部門メンバーの初期権限 +explorer.auth.tabChildrenTips=このフォルダに権限が設定されているコンテンツ +explorer.auth.resetUser=このユーザー権限の設定を上書きする +explorer.auth.resetUserBtn=権限を上書きする +explorer.auth.resetUserBtnTips=このフォルダー内のユーザーとすべてのサブフォルダー(フォルダー)のアクセス許可を上書きします +explorer.auth.resetUserHeader=下位フォルダーには、ユーザーのアクセス許可を指定するコンテンツが含まれており、すべてのオーバーライドを上記のアクセス許可に設定します +explorer.auth.resetUserContiner=ユーザーの許可の内容が含まれています +explorer.auth.resetUserEmpty1=このユーザーに権限が設定されているコンテンツはありません。オーバーライドする必要はありません。 +explorer.auth.resetUserEmpty2=すべての子コンテンツは、現在のレベルのフォルダーのアクセス許可を継承します +explorer.rename.mutil=名前の一括変更 +explorer.rename.nameBefore=元のファイル名 +explorer.rename.nameTo=名前を変更 +explorer.rename.start=名前を変更 +explorer.rename.clearFinished=空になりました +explorer.rename.clearAll=すべてクリア +explorer.rename.typeReplaceAll=すべてを交換 +explorer.rename.typePrepend=前に追加 +explorer.rename.typeAppend=後で追加 +explorer.rename.typeReplace=検索して置き換える +explorer.rename.typeChangeCase=大文字小文字変換 +explorer.rename.typeRemove=文字を削除する +explorer.rename.typeReplaceSet=交換品を一括で指定 +explorer.rename.typeReplaceSetDesc=それらが等しい場合は置き換えます。各行はスペースで区切られており、ファイル名にはスペースを使用できません。次に例を示します。 +explorer.rename.numberStart=Offset +explorer.rename.appendContent=追加コンテンツ +explorer.rename.find=探す +explorer.rename.replaceTo=に置き換え +explorer.rename.caseUpperFirst=初期資本 +explorer.rename.caseUpper=すべて大文字 +explorer.rename.caseLower=すべて小文字 +explorer.rename.removeStart=ゼロから削除 +explorer.rename.removeEnd=最後から削除 +explorer.rename.chars=キャラクター +explorer.editor.beautifyCode=コードのフォーマット +explorer.editor.convertCase=ケース変換 +explorer.editor.convertUpperCase=大文字に変換 +explorer.editor.convertLowerCase=小文字に変換 +explorer.editor.currentTime=現在の時刻 +explorer.editor.md5=md5暗号化 +explorer.editor.qrcode=文字列QRコード +explorer.editor.regx=正規表現テスト +explorer.editor.chinese=簡素化された変換 +explorer.editor.chineseSimple=簡体字中国語に変換 +explorer.editor.chineseTraditional=繁体字中国語に変換 +explorer.editor.base64=base64コーデック +explorer.editor.base64Encode=base64エンコーディング +explorer.editor.base64Decode=base64デコード +explorer.editor.url=URLコーデック +explorer.editor.urlEncode=URLエンコーディング +explorer.editor.urlDecode=URLデコード +explorer.editor.unicode=Unicodeコーデック +explorer.editor.unicodeEncode=Unicodeエンコード +explorer.editor.unicodeDecode=Unicodeデコード +explorer.editor.toolsSelectTips=処理する正しいコンテンツを選択してください! +explorer.editor.toolsRandString=32ビットのランダム文字列を生成する +explorer.editor.textEncode=テキストのエンコード/デコード +explorer.editor.textParse=テキスト処理 +explorer.editor.timeShow=タイムスタンプ +explorer.editor.timeInt=タイムスタンプまでの時間 +explorer.editor.lineRemoveEmpty=空白行(スペースを含む)を削除する +explorer.editor.lineUnoin=重複する行を削除する +explorer.editor.lineTrim=先頭と末尾のスペースを削除する +explorer.editor.lineSort=行でソート(昇順) +explorer.editor.lineReverse=すべての行を上下に入れ替えます +explorer.editor.lineSum=和 +explorer.editor.lineAverage=平均値 +explorer.editor.calc=無料の電卓 +explorer.editor.goToLine=行にジャンプ +explorer.editor.keyboardType=キーボードモード +explorer.editor.fontFamily=フォント +explorer.editor.codeMode=ハイライト構文 +explorer.editor.closeAll=すべて閉じる +explorer.editor.closeLeft=左のタブを閉じる +explorer.editor.closeRight=右のタブを閉じる +explorer.editor.closeOthers=他を閉じる +explorer.editor.wordwrap=ワードラップ +explorer.editor.showGutter=行番号を表示 +explorer.editor.charAllDisplay=不可視の文字を表示する +explorer.editor.autoComplete=自動プロンプト +explorer.editor.autoSave=自動保存 +explorer.editor.functionList=機能リスト +explorer.editor.codeTheme=コードスタイル +explorer.editor.fontSize=フォントサイズ +explorer.editor.completeCurrent=オートコンプリート電流 +explorer.editor.createProject=エディタープロジェクトに追加 +explorer.editor.markdownContent=コンテンツディレクトリ +explorer.editor.undo=取り消す +explorer.editor.redo=取消し禁止 +explorer.editor.shortcut=ショートカット +explorer.editor.replace=交換 +explorer.editor.reload=リロード +explorer.editor.view=表示する +explorer.editor.tools=道具 +explorer.editor.help=助けて +explorer.sync.data=データ同期 +explorer.sync.openLoc=ローカルディレクトリを開く +explorer.sync.syncing=同期中 +explorer.sync.synced=同期完了 +explorer.sync.syncedError=エラーログ +explorer.sync.syncStart=同期を開始 +explorer.sync.syncStop=同期を停止 +explorer.sync.notOpenTips=ローカル同期を有効にしていません +explorer.sync.setNow=今すぐ同期を設定する +explorer.sync.error=アップロードに失敗しました +explorer.sync.success=成功した同期 +explorer.sync.statusScan=スキャン中 +explorer.sync.statusNone=同期が構成されていません +explorer.sync.statusScanEnd=スキャン完了 +explorer.sync.statusDoing=同期中 +explorer.sync.statusDone=同期完了 +explorer.sync.statusStop=一時停止 +explorer.sync.clearCacheSuccess=キャッシュのクリアに成功しました! +explorer.sync.emptyTask=同期タスクなし +explorer.sync.openCloud=クラウドの場所を開く +explorer.sync.openLocal=ローカルで開く +explorer.sync.statusFiles=ドキュメントの進捗 +explorer.sync.statusLastTime=完了時間 +explorer.sync.configName=同期設定 +explorer.sync.configClient=クライアント設定 +explorer.sync.configAbout=について +explorer.sync.configSyncFrom=ローカルパス +explorer.sync.configSyncFromDesc=同期するローカルフォルダーを選択します +explorer.sync.configSyncTo=に同期 +explorer.sync.configSyncToDesc=サーバーの場所に同期 +explorer.sync.configIgnore=無視されるファイルの種類 +explorer.sync.configIgnoreDesc=このタイプのファイルは同期されません +explorer.sync.autorun=自己始動 +explorer.sync.configThread=同時スレッドの数 +explorer.sync.configThreadDesc=同時にアップロードされたファイルの数 +explorer.sync.configDownloadPath=ダウンロードパス +explorer.sync.configDownloadPathDesc=ファイルフォルダをダウンロードするときのデフォルトのダウンロードパス +explorer.sync.configClearCacheAuto=キャッシュを自動的にクリアします +explorer.sync.configClearCacheAutoDesc=N日前にキャッシュファイルを自動的にクリアする +explorer.sync.configClearCache=キャッシュをクリア +explorer.sync.configChangeSite=現在のサイトを終了します +explorer.sync.configVersion=現在のバージョン +explorer.sync.configUpdateDesc=更新手順 +explorer.sync.configUpdateCheck=更新の確認 +explorer.sync.confirmReset=ディレクトリの変更を同期すると、同期情報がリセットされます。保存してもよろしいですか? +explorer.sync.listClearDone=排出完了 +explorer.sync.listClearError=エラーリストをクリア +explorer.sync.listRetryAll=すべて再試行 +explorer.async.tipsDisablePath=パスの同期の選択をサポートしていません +explorer.async.tipsIsMoving=現在、大量のコンテンツが同期ディレクトリに移動またはコピーされていることが検出されました。
    ローカルでの完了後、同期のためにページを更新することをお勧めします! +explorer.async.tipsStartUser=手動で同期を開始する +explorer.download.title=ダウンロード管理 +explorer.download.waiting=待っています +explorer.download.stop=ダウンロードを一時停止 +explorer.download.start=ダウンロード開始 +explorer.download.remove=タスクを削除 +explorer.download.stopAll=すべて一時停止 +explorer.download.startAll=すべて続行 +explorer.download.clearAll=すべてのタスクをクリアする +explorer.download.doing=処理 +explorer.download.done=ダウンロードが完了しました +explorer.download.clearAllTips=すべてのダウンロードタスクを削除してもよろしいですか? +explorer.tag.name=ファイルタグ +explorer.tag.edit=ラベル管理 +explorer.tag.add=ラベルを作成 +explorer.tag.remove=ラベルを削除してもよろしいですか? +explorer.tag.inputHolder=ラベル名を入力してください +explorer.tag.addTo=ラベルを設定する +explorer.tag.default1=学ぶ +explorer.tag.default2=テストデータ +explorer.tag.default3=契約する +explorer.tag.filter=ラベルでフィルタリング +explorer.groupTag.title=パブリックレーベル +explorer.groupTag.menuTtitle=部門のパブリックレーベル +explorer.groupTag.titleDesc=部門内のパブリックラベル +explorer.groupTag.empty=部門管理者がパブリックラベルを設定すると、自動的に有効になります。ラベルの内容がない場合、パブリックラベルは自動的にオフになります。 +explorer.tag.pathDesc=個人ラベルでフィルタリング +explorer.groupTag.pathDesc=部門のパブリックラベルでフィルタリング +explorer.groupTag.removeTypeTips=このグループを削除してもよろしいですか?ラベルに関連付けられているすべてのドキュメントは、削除後に削除されます。 +explorer.groupTag.removeTagTips=タグを削除してもよろしいですか?タグに関連付けられているドキュメントは削除後に削除されます。 +explorer.groupTag.typeAdd=カテゴリを追加 +explorer.groupTag.typeName=種別名 +explorer.groupTag.addDesc=タグを追加すると、部門タグが自動的に有効になり、タグの最大数は1000になります +explorer.panel.info=全般 +explorer.panel.version=バージョン +explorer.panel.chat=チャット +explorer.panel.log=ログ +explorer.panel.meta=メタデータ +explorer.panel.chatName=交換ディスカッション +explorer.panel.chat.send=送る +explorer.panel.chat.noAuth=このドキュメントにコメントする権限がありません! +explorer.panel.chat.placeholder=ここに入力して[Enter]で送信し、[Ctrl + Enter]で改行します +explorer.panel.chat.placeholderCtrl=ここに入力し、Ctrl + Enterを押して送信し、Enterを押して折り返します +explorer.panel.chat.reply=返答 +explorer.panel.chat.empty=コメント無し +explorer.panel.chat.sendTo=進む +explorer.panel.metaName=メタデータ拡張 +explorer.panel.metaDesc=拡張ドキュメントフィールドプロパティ +explorer.panel.thumbClear=クリアサムネイル +explorer.panel.thumbClearDesc=ファイルのサムネイルをクリアし、アートをカバーして再生成します。 +explorer.panel.historyName=歴史的なバージョン +explorer.panel.historyDesc=リリースノート +explorer.panel.infoTips=詳細なプロパティを表示するには、ファイル(フォルダ)を選択してください +explorer.panel.info.space=スペース容量 +explorer.panel.info.groupAt=部門の場所 +explorer.panel.info.tagEmpty=タグなし、設定をクリック +explorer.panel.logName=ドキュメントニュース +explorer.panel.logEmpty=活動なし +explorer.type.doc=ドキュメント +explorer.type.image=画像 +explorer.type.music=音楽 +explorer.type.movie=ビデオ +explorer.type.zip=アーカイブ +explorer.type.others=その他 +explorer.secret.title=文書の機密管理 +explorer.secret.isOpen=有効にするかどうか +explorer.secret.isOpenDesc=セキュリティ レベル管理の有効化と無効化 +explorer.secret.setUser=シークレットマネージャー +explorer.secret.setUserDesc=機密レベルを設定できるユーザーを指定します (同時に、該当する部門の所有者である必要があります)。 +explorer.secret.type=分類の種類 +explorer.secret.add=セキュリティレベルを追加 +explorer.secret.edit=セキュリティレベルを編集 +explorer.secret.name=クラス名 +explorer.secret.style=スタイル +explorer.secret.auth=秘密レベルの許可 +explorer.secret.authHas=機密許可には以下が含まれます +explorer.secret.createUser=セッター +explorer.secret.folderAt=親展フォルダ +explorer.secret.tips=アクセス許可はシークレット レベルによって制御され、シークレット レベルのアクセス許可はドキュメントのアクセス許可よりも高くなります。 +explorer.secret.tips1=部門のネットワーク ディスク配下のコンテンツのみ、上記の指定ユーザーが機密レベルを設定できます (同時にフォルダーの所有者である必要があります)。 +explorer.secret.tips2=機密レベルを持つフォルダの下層のすべてのコンテンツが設定され、この権限は最高の権限です +explorer.secret.tips3=設定後は文書権限よりも機密レベル権限の方が高い(文書も機密レベル権限で管理されており、システム管理者はこの制限の対象外、秘密レベル設定者はこの制限対象外) +explorer.secret.tips4=機密レベルの権限: \"部門およびメンバー管理 - ドキュメント著作権管理\"で追加でき、非表示に設定できます +user.displayHideFile=隠しファイルを表示 +user.displayHideFileDesc=隠しファイル:で始まるファイル、およびシステムのバックグラウンドで設定された隠しファイル名;隠しファイルは開いた後に表示されます。 +user.soundOpen=サウンドをオンにする +user.animateOpen=アニメーションの有効化 +user.recycleOpen=ごみ箱を開く +user.recycleDesc=開いた後、削除はごみ箱に移動します。開くことをお勧めします +user.animateDesc=ウィンドウを開くなどのアニメーション、操作がスムーズでない場合は閉じることを検討できます +user.soundDesc=ファイルを開く、ファイルを削除する、ごみ箱を空にするなど +user.thumbOpen=画像のサムネイルを開く +user.thumbDesc=開いた後の画像ブラウジングエクスペリエンスの向上 +user.fileSelect=ファイルを開くアイコン +user.fileSelectDesc=ファイルアイコンを右クリックし、右クリックメニューへのショートカット +user.fileShowDesc=フォルダの紹介を表示 +user.fileShowDescTips=アイコンのみのモード +user.fileOpenClick=次のようにファイル(フォルダ)を開きます +user.fileOpenClick.dbclick=ダブルクリックで開く +user.fileOpenClick.click=クリックして開く +user.viewSetting=オプションを表示 +user.thirdAccount=サードパーティのアカウント +user.bindAccount=アカウントをバインド +user.thirdBindFirst=アカウントはバインドされていません。バインド後に使用してください +user.account=アカウント +user.bind=バインド +user.unbind=ほどく +user.binded=バウンド +user.clickBind=バインドをクリック +user.clickToBind=非バインド、バインドをクリック +user.clickEditPwd=パスワードの変更をクリックします +user.userAvatar=プロフィール写真 +user.userNickName=個人的なニックネーム +user.userAccount=個人アカウント +user.uploadAvatar=アバターをアップロード +user.userAvatarCrop=アバターとして適切なエリアを選択してください +user.userAvatarExt=JPG、JPEG、PNG画像形式のみをサポート +user.resetPwdDesc=パスワードを忘れましたか? +user.inputEmailCode=メール確認コードを入力してください +user.inputSmsCode=SMS確認コードを入力してください +user.emailVerifyDesc=一部のビジネスではメールの確認が必要です +user.phoneVerifyDesc=一部の企業では携帯電話の確認が必要です +user.bindOthers=別のアカウントに既にバインドされています +user.notBind=まだバインドされていません +user.regist=ユーザー登録 +user.notRegist=未登録 +user.registed=登録済み +user.signError=コールバック署名が間違っています +user.repeat=繰り返す +user.noRepeat=繰り返すことはできません +user.newPwd=新しいパスワード +user.unAuthFile=不正なファイルアクセス +user.unbindWarning=バインドを解除する前にパスワードを変更してください。変更しないと、アカウントは正しく機能しません。 +user.isLoginTips=現在ログインしていることが検出されました! +user.isLoginEnter=今すぐ入る +user.ifUnbind=バインドを解除してもよろしいですか? +user.bindFirst=最初にメールまたは携帯電話番号をバインドしてください +user.inputNewPwd=新しいパスワードを入力してください +user.inputNewValue=新しいコンテンツを入力してください +user.guestLogin=観光客ログイン +user.name=ログインアカウント +user.nickName=ユーザーのニックネーム +user.code=検証コード +user.codeError=検証コードエラー +user.imgCode=キャプチャ +user.rootPwd=管理者パスワードを設定する +user.rootPwdRepeat=もう一度パスワードを確認してください +user.rootPwdEqual=パスワードが2回一致しません! +user.rootPwdTips=管理者パスワードを設定してください! +user.pwdError=ユーザー名またはパスワードが間違っています! +user.pwdNotNull=パスワードを空にすることはできません! +user.oldPwdError=元のパスワードが間違っています! +user.keepPwd=パスワードを記憶する +user.forgetPwd=パスワードを忘れた +user.directLogin=アカウントでログインする +user.moreLogin=他のログイン方法 +user.loginNow=今すぐサインイン +user.registNow=今すぐサインアップ +user.backHome=ホームに戻る +user.ifHasAccount=すでにアカウントをお持ちですか? +user.userEnabled=アカウントが無効になっているか、まだ有効になっていません!管理者に連絡してください +user.roleError=許可グループが存在しません。管理者に連絡してください +user.invalidEmail=有効なメールアドレスがありません。管理者に連絡して変更してください +user.codeRefresh=[更新]をクリックします +user.emailVerify=メールボックス認証 +user.sendSuccess=正常に送信されました +user.sendFail=送信に失敗しました +user.sendSuccessDesc=確認コードを送信しました。表示してください +user.sendFailDesc=確認コードを送信できませんでした。管理者に連絡してください +user.inputVerifyCode=確認コードを入力してください +user.getCode=確認コードを取得する +user.inputPwd=パスワードを入力してください +user.inputPwdAgain=もう一度パスワードを入力してください +user.inputNickName=ニックネームを入力してください +user.inputEmail=メールアドレスを入力してください +user.inputPhone=電話番号を入力してください +user.inputPhoneEmail=携帯電話/メールアドレスを入力してください +user.invalidPhoneEmail=無効な電話番号/メールアドレス +user.findPwd=パスワードを取得する +user.inputNotMatch=入力された %s が境界と一致しません +user.usingDesc=あなたが使用しています +user.improveInfo=情報を入力してください +user.codeExpired=確認コードの有効期限が切れています。もう一度入手してください +user.codeErrorTooMany=確認コードエラーが多すぎます。再取得してください +user.codeErrorFreq=送信頻度が高すぎます。しばらくしてからもう一度お試しください。 +user.codeErrorCnt=送信数が制限を超えたため、 %s 時間ロックされます。 +user.registSuccess=正常に登録されました +user.waitCheck=管理者のレビューを待っています +user.nameHolder=電話番号/メールアドレスを入力してください +user.loginNoPermission=申し訳ありませんが、この権限はありません。この権限を持つアカウントでログインしてください! +user.loginFirst=ログインしていません!最初にログインしてください +user.bindSignError=署名が異常です。もう一度お試しください! +user.bindUpdateError=ユーザー情報の更新に失敗しました。もう一度お試しください +user.bindTypeError=無効なバインディングタイプ +user.bindWxConfigError=構成情報の例外を取得する +user.loginTimeout=現在のログインがタイムアウトしました。もう一度ログインしてください! +user.theme=テーマスタイル +user.theme.desc=テーマを変更することができます +user.theme.light=ライト +user.theme.dark=ダーク +user.theme.auto=自動 +user.theme.title=テーマ設定 +user.theme.background=背景 +user.theme.image=写真 +user.theme.colorBlur=グラデーションカラー +user.theme.imageBlur=画像ぼかし処理 +user.theme.imageUrl=画像アドレス +user.theme.colorStart=開始色 +user.theme.colorEnd=終了色 +user.theme.colorRadius=勾配角 +user.theme.themeImage=背景画像 +user.theme.themeImageDesc=サポート:画像のURL、CSSのグラデーションカラー、壁紙に従う +user.theme.imageWall=壁紙に従ってください +user.wall.random=ランダムな壁紙 +user.wall.paperDesktop=デスクトップの壁紙 +user.wall.paperDeskMgt=デスクトップの壁紙管理 +user.wall.paperLoginMgt=ログイン壁紙管理 +user.wall.paperLoginTips=複数の画像がある場合、ログインインターフェイスの背景がランダムに回転します +log-type-create-mkdir=新しいフォルダ +log-type-create-mkfile=新しいファイルを作成する +log-type-create-upload=ファイルをアップロードする +log-type-create-copy=ファイルを貼り付け +log-type-edit=ファイルを更新 +log-type-move=ファイルを移動 +log-type-moveOut=ファイルを削除する +log-type-share-shareLinkAdd=外部リンク共有を作成しました +log-type-share-shareToAdd=共同共有がオンになっています +log-type-share-shareLinkRemove=閉じたリンクの共有 +log-type-share-shareToRemove=共同共有をオフにする +log-type-share-shareEdit=共有を編集 +log-type-rename=名前を変更 +log-type-recycle-toRecycle=ごみ箱に移動します +log-type-recycle-restore=ごみ箱から復元 +log-type-remove=削除する +log-type-addDesc=説明を変更 +log-type-addComment=コメントを投稿 +log-event-create-mkdir=このフォルダを作成しました +log-event-create-mkfile=ファイルを作成しました +log-event-create-upload=ファイルをアップロードしました +log-event-create-copy=ファイルは貼り付けによって作成されました +log-event-create-mkdir-current=ここに新しいフォルダを作成しました{0} +log-event-create-mkfile-current=ここに作成された新しいファイル{0} +log-event-create-upload-current=ここにアップロード{0} +log-event-create-copy-current={0}をここに貼り付けました +log-event-create-mkdir-item={0} {1}に新しいフォルダを作成しました +log-event-create-mkfile-item={0} {1}で作成された新しいファイル +log-event-create-upload-item={0}に{1}をアップロードしました +log-event-create-copy-item={0}から{1}を貼り付け +log-event-create-mkdir-more=ここに{0}個のフォルダを作成しました +log-event-create-mkfile-more={0}ここで作成された新しいファイル +log-event-create-upload-more={0}ここにアップロードされたファイル +log-event-create-copy-more=ここに{0}ファイルを貼り付けました +log-event-create-mkdir-more-at={0}に{1}個の新しいフォルダーを作成しました +log-event-create-mkfile-more-at={0}に{1}個の新しいファイルを作成しました +log-event-create-upload-more-at={1}ファイルが{0}にアップロードされました +log-event-create-copy-more-at={0}個のドキュメントを{1}に貼り付けました +log-event-view-item={0} を閲覧 +log-event-edit=ファイルを更新しました +log-event-edit-item=更新された編集{0} +log-event-edit-more=更新された{0}ファイルを編集する +log-event-edit-more-user=ファイルを{0} {1}回編集および更新しました +log-event-edit-more-at={0}の{1}ファイルを編集および更新しました +log-event-move=ドキュメントを{0}から{1}に移動します +log-event-move-item={0}を{1}から[3]に移動します +log-event-move-current={1}から{0}をここに移動 +log-event-move-more={0}ドキュメントを移動しました +log-event-move-more-desc={0}を{1}から[3]に移動します +log-event-moveOut-more-desc={0} {1}から削除 +log-event-moveOut=ここから削除{0} +log-event-moveOut-item={0} {1}から削除 +log-event-moveOut-more={0}削除されたドキュメント +log-event-share-shareLinkAdd=このドキュメントを共有するための外部リンクを作成しました +log-event-share-shareLinkAdd-item={0}共有する外部リンクを作成しました +log-event-share-shareLinkAdd-more=共有する{0}リンクを作成しました +log-event-share-shareToAdd=このドキュメントの共同共有を有効にする +log-event-share-shareToAdd-item={0}共同共有を有効にしました +log-event-share-shareToAdd-more={0}共同シェアが作成されました +log-event-share-shareLinkRemove=ドキュメントのリンク共有を閉じました +log-event-share-shareLinkRemove-item={0}のリンク共有を閉じました +log-event-share-shareLinkRemove-more={0}外部リンク共有を閉じる +log-event-share-shareToRemove=このドキュメントの共同共有をオフにする +log-event-share-shareToRemove-item={0}のコラボレーション共有をオフにする +log-event-share-shareToRemove-more=閉じる{0}共同共有 +log-event-share-shareEdit=このドキュメントの共有を編集しました +log-event-share-shareEdit-item={0}の共有を編集しました +log-event-share-shareEdit-more=共有する{0}個のドキュメントを編集しました +log-event-rename=ドキュメントの名前を変更しました +log-event-rename-item={0}に名前変更 +log-event-rename-more={0}ドキュメントの名前が変更されました +log-event-recycle-toRecycle=ドキュメントをゴミ箱に移動しました +log-event-recycle-toRecycle-current={0}をごみ箱に移動しました +log-event-recycle-toRecycle-item={1}を{0}のごみ箱に移動しました +log-event-recycle-toRecycle-more={0}個のドキュメントをゴミ箱に移動しました +log-event-recycle-toRecycle-more-at={1}ドキュメントを{0}のごみ箱に移動しました +log-event-recycle-restore=ごみ箱からドキュメントを復元する +log-event-recycle-restore-item=ごみ箱から{0}を復元 +log-event-recycle-restore-more={0}個のドキュメントをごみ箱から復元します +log-event-remove=ここ{0}を削除しました +log-event-remove-current=ここ{0}を削除しました +log-event-remove-item={0}の{1}を削除しました +log-event-remove-more={0}ここで削除されたドキュメント +log-event-remove-more-at={0}の{1}個のドキュメントを削除しました +log-event-addDesc=ドキュメントの説明を変更しました +log-event-addDesc-item=変更された{0}ドキュメントの説明 +log-event-addDesc-more=変更された{0}ドキュメントの説明 +log-event-addComment=このドキュメントにコメント +log-event-addComment-item={0}にコメントしました +log-event-addComment-more={1}件のコメントを{0}にリストしました +log-event-fav-fileAdd=ブックマーク{0} +log-event-fav-dirAdd=ブックマークされたフォルダ{0} +log-event-down-item={0}から{1}をダウンロードしました +log-event-down-items={0}からダウンロード +log-event-recycle-del-item=ごみ箱から{0}ファイルを削除 +log-event-recycle-rst-item=ごみ箱から{0}ファイルを復元する +log-event-del-item={0}個のファイルが削除されました +log.file.move=移動/コピー +log.file.fav=お気に入り操作 +log.file.shareLink=外部リンク共有 +log.file.shareTo=共同共有 +log.user.edit=アカウント情報を変更する +log.group.edit=部門管理 +log.member.edit=ユーザー管理 +log.role.edit=役割管理 +log.auth.edit=ドキュメントの権利管理 +meta.user_sourceAlias=関連ファイル(添付ファイル) +meta.user_fileEncodeType=ファイルの機密性 +meta.user_fileEncodeType.A=A-Topシークレット +meta.user_fileEncodeType.B=B機密 +meta.user_fileEncodeType.C=シークレット +meta.user_sourceNumber=巻数 +meta.user_sourceParticipant=参加者 +explorer.fileInfo.createTime=作成日 +explorer.fileInfo.modifyTime=変更日 +explorer.fileInfo.softwareCreate=プロダクションソフトウェア +explorer.fileInfo.software=コーディングソフトウェア +explorer.fileInfo.playTime=再生時間 +explorer.fileInfo.imageSize=写真のサイズ +explorer.fileInfo.imageDpi=解決 +explorer.fileInfo.imageBits=ビット深度 +explorer.fileInfo.imageDesc=注釈 +explorer.fileInfo.imageAuthor=作成者 +explorer.fileInfo.imageColor=色空間 +explorer.fileInfo.cameraType=デバイスモデル +explorer.fileInfo.cameraApertureFNumber=絞り値 +explorer.fileInfo.cameraApertureValue=絞り値 +explorer.fileInfo.cameraShutterSpeedValue=シャッター速度 +explorer.fileInfo.cameraExposureTime=曝露時間 +explorer.fileInfo.cameraFocalLength=焦点距離 +explorer.fileInfo.cameraFocusDistance=焦点距離 +explorer.fileInfo.cameraISOSpeedRatings=ISO感度 +explorer.fileInfo.cameraWhiteBalance=ホワイトバランス +explorer.fileInfo.cameraUser=マニュアル +explorer.fileInfo.cameraAuto=自動 +explorer.fileInfo.cameraExposureMode=露出モード +explorer.fileInfo.cameraExposureBiasValue=露出補正 +explorer.fileInfo.imageGps=撮影場所 +explorer.fileInfo.imageCreateTime=撮影日 +explorer.fileInfo.audioChannel=オーディオチャンネル +explorer.fileInfo.audioChannel1=単核症 +explorer.fileInfo.audioChannel2=ステレオ +explorer.fileInfo.audioChannels=マルチチャネル +explorer.fileInfo.audioRate=オーディオサンプリングレート +explorer.fileInfo.audioBits=オーディオビット深度 +explorer.fileInfo.audioBitrate=オーディオビットレート +explorer.fileInfo.vedioFormat=ビデオエンコーディング +explorer.fileInfo.audioTitle=題名 +explorer.fileInfo.audioAuthor=著者 +explorer.fileInfo.audioAlbum=アルバム +explorer.fileInfo.audioStyle=スタイル +explorer.fileInfo.audioYear=アルバム年 +explorer.fileInfo.vedioSize=画面サイズ +explorer.fileInfo.vedioFrame=ビデオフレームレート +explorer.fileInfo.vedioBitrate=ビデオビットレート +explorer.fileInfo.title=題名 +explorer.fileInfo.author=著者 +explorer.fileInfo.pageTotal=総ページ数 +explorer.fileInfo.pageSize=ページサイズ +explorer.fileInfo.pagePower=コンテンツクリエータ +explorer.fileInfo.pdfVersion=PDF版 +explorer.filter.shareCopyLimit=ダンプされるファイルの数が制限を超えています。ダンプできるファイルの最大数は次のとおりです。 +explorer.filter.shareSizeLimit=共有ファイルのサイズが制限を超えています。共有できる最大値は次のとおりです。 +explorer.filter.unzipSizeLimit=解凍ファイルのサイズが制限を超えています。解凍できる最大値は次のとおりです。 +explorer.filter.zipSizeLimit=圧縮ファイルのサイズが制限を超えています。圧縮可能なドキュメントの最大数は次のとおりです。 +explorer.filter.uploadSizeLimit=アップロードサイズが制限を超えています。アップロードできる最大数は次のとおりです。 +explorer.fileEditError=現在のファイル %s は編集中です。後で再試行してください +explorer.groupDelError=申し訳ありませんが、部門フォルダは削除をサポートしていません +admin.info.typeDelError=サブカテゴリまたはデータを持つ削除に失敗しました +admin.info.domainIdentifyError=Webサイトが認識されません +admin.info.articleIdentifyError=文章が認識できない +admin.info.domainSupportError=このサイトは収集をサポートしていません +admin.info.fileTooLarge=ファイルサイズが大きすぎる +explorer.toolbar.info=情報 +source.shareDisabled=現在のリソースの共有は禁止されています +admin.exceeds.limit=制限を超える +admin.design.deleted=有効状態は削除できません +admin.design.url.locked=現在urlはロックされており、しばらく使用できません +explorer.SING_INVALID=署名例外 +explorer.TEMP_AUTH_INVALID=一時認証コードが無効(無効) +explorer.QR_INVALID=QRコードが無効になりました +explorer.toolbar.toolbox=ツールボックス +explorer.toolbox.desc= +logs-detail-mkdir=フォルダを新規作成しました +logs-detail-mkfile=新しいファイルが作成されました +logs-detail-editFile=編集が更新されました +logs-detail-upload=ファイルをアップロードしました +logs-detail-uploadNew=編集されました +logs-detail-file.upload=アップロードしました +logs-detail-file-copy=貼り付け作成ファイル +logs-detail-folder-copy=貼り付けフォルダを作成しました +logs-detail-paste=貼り付け +logs-detail-from=開始 +logs-detail-to=まで +logs-detail-rename=名前が変更されました +logs-detail-rename-file=ファイル名を変更しました +logs-detail-rename-folder=フォルダの名前を変更しました +logs-detail-user=ユーザー: +logs-detail-moveFrom-restore=この +logs-detail-moveTo-restore=ごみ箱からリストア +logs-detail-move=この +logs-detail-moveTo=移動先 +logs-detail-moveFrom-toRecycle=この +logs-detail-moveTo-toRecycle=ごみ箱に移動しました +logs-detail-file-toRecycle=ファイルをごみ箱に移動しました +logs-detail-file-restore=ファイルをごみ箱からリストア +logs-detail-folder-toRecycle=フォルダをごみ箱に移動しました +logs-detail-folder-restore=ごみ箱からフォルダをリストアする +logs-detail-favAdd=コレクション +logs-detail-favDel=コレクションをキャンセルしました +logs-detail-unstar=の名前をあげる: +logs-detail-moveOut=移動しました +logs-detail-remove=削除されました +logs-detail-file.copy=貼り付け済み +explorer.noPermissionAuthAll={0} ,この操作権限はありません \ No newline at end of file diff --git a/src/main/resources/i18n/messages_ko_KR.properties b/src/main/resources/i18n/messages_ko_KR.properties new file mode 100644 index 0000000..c476a9c --- /dev/null +++ b/src/main/resources/i18n/messages_ko_KR.properties @@ -0,0 +1,2564 @@ +admin.serverInfo=서버 정보 +admin.today=오늘 +admin.yesterday=어제 +admin.weekDay=거의 7 일 +admin.monthDay=거의 30 일 +admin.ing=진행중 +admin.paused=일시 중지됨 +admin.serverDownload=원격 다운로드 +admin.memberManage=사용자 관리 +admin.fileManage=파일 관리 +admin.pwdEdit=비밀번호 변경 +admin.fileEdit=저장 파일 편집 +admin.list=목록보기 +admin.configError=구성 저장에 실패했습니다. 관리자가이 권한을 비활성화했습니다! +admin.userManage=개인 센터 +admin.manage=백그라운드 관리 +admin.pluginManage=플러그인 관리 +admin.emailDear=안녕하세요 %s님 +admin.emailCodeText=이메일 주소를 확인하는 중입니다. 이 요청에 대한 확인 코드는 다음과 같습니다. 계정 보안을 위해 시간 내에 확인을 완료하세요. +admin.emailVerifyInTime=계정의 보안을 유지하려면 제 시간에 확인을 완료하십시오. +admin.dear=존중 +admin.dearUser=친애하는 사용자, +admin.emailResetLink=이메일을 통해 %s 의 로그인 비밀번호를 재설정하고 있습니다. 아래 링크를 클릭하여 재설정하십시오. 링크가 이동하지 않으면 브라우저의 주소 표시 줄에 복사하여 액세스하십시오. +admin.emailExpireTime=링크는 20 분 후에 만료됩니다. +admin.jobName=직책 +admin.jobDesc=직업 설명 +admin.jobNameInput=직업 명을 입력하십시오 +admin.jobEdit=포스트 에디터 +admin.menu.home=홈 +admin.menu.dashboard=개요 +admin.menu.dashboardTitle=통계 개요 +admin.menu.notice=알림 관리 +admin.menu.groupMember=부서 및 회원 관리 +admin.menu.member=부서 및 사용자 +admin.menu.role=역할 관리 +admin.menu.job=직무 관리 +admin.menu.auth=문서 권한 관리 +admin.menu.storage=저장 / 파일 +admin.menu.storageDriver=스토리지 관리 +admin.menu.plugin=플러그인 센터 +admin.menu.tools=안전 관리 +admin.menu.server=서버 관리 +admin.menu.backup=백업 관리 +admin.menu.share=나눔 경영 +admin.menu.loginLog=로그인 로그 +admin.menu.log=작업 로그 +admin.menu.task=예약 된 작업 +admin.autoTask.restart=예약 된 작업 다시 시작 +admin.autoTask.restartEnd=예약 된 작업이 다시 시작되었습니다. +admin.index.userSpace=사용자 공간 +admin.index.groupSpace=부서 공간 +admin.index.folderCount=폴더 수 : +admin.index.fileCount=파일 수 : +admin.index.loginToday=오늘 로그인 +admin.index.useTotal=총 사용량 : +admin.index.userLogin=사용자 로그인 +admin.index.spaceUsed=공간을 차지 +admin.index.useSpace=공간 사용 +admin.index.usedSpace=사용 된 공간 +admin.index.freeSpace=남은 공간 +admin.index.sizeLimit=한정 사이즈 +admin.index.vipCount=등록 된 사용자 +admin.index.loginCurrent=현재 온라인 +admin.index.fileDel=파일 삭제 +admin.index.fileEdit=파일 편집 +admin.index.fileUpload=파일 업로드 +admin.index.fileDown=문서 다운로드 +admin.index.spaceUse=실용 +admin.index.spaceSave=공간 절약 +admin.index.spaceUser=사용자 사용 +admin.index.spaceGroup=부서 사용 +admin.index.lastLogin=마지막 로그인 시간 +admin.index.totalUsers=총 사용자 수 +admin.index.loginUsers=로그인 사용자 +admin.index.spaceActUsed=실제 직업 +admin.index.source=로그인 소스 +admin.index.address=로그인 주소 +admin.index.userInfo=사용자 정보 +admin.index.userValid=유효한 계정 +admin.index.userInvalid=잘못된 계정 +admin.index.fileInfo=파일 정보 +admin.index.fileCnt=파일 수 +admin.index.fileAdd=오늘 추가 +admin.index.accInfo=액세스 정보 +admin.index.accCnt=요청 +admin.index.accUser=액세스 사용자 +admin.index.serverInfo=시스템 메시지 +admin.index.serverDisk=시스템 디스크 +admin.index.serverStore=네트워크 스토리지 +admin.index.serverName=서버 이름 +admin.index.normal=표준 +admin.index.scoreDesc=다음 요소는 시스템 점수에 영향을 미치며, 시스템 점수를 최적화하여 시스템이 제대로 실행되도록합니다.
    1. 시스템 디스크 및 네트워크 디스크 스토리지의 나머지 공간;
    2. 데이터 캐싱 방법 (redis 권장);
    3.php 플랫폼 버전 (권장 64 비트 php7 +). +admin.index.fileRatio=파일 사용률 +admin.setting.system=시스템 설정 +admin.setting.account=계정 설정 +admin.setting.theme=테마 설정 +admin.setting.wall=배경 화면 설정 +admin.setting.stats=사용 통계 +admin.setting.safeMgt=안전 관리 +admin.setting.base=기본 설정 +admin.setting.others=다른 설정 +admin.setting.sync=설정 동기화 +admin.setting.plugin=플러그인 설정 +admin.setting.auth=권한 설정 +admin.setting.safe=보안 설정 +admin.setting.loginLog=로그인 로그 +admin.setting.loginDevice=로그인 장치 +admin.setting.deviceType=장비 유형 +admin.setting.lastLoginTime=마지막 로그인 시간 +admin.setting.email=이메일 설정 +admin.setting.user=등록 및 로그인 +admin.setting.pwdOld=원래 비밀번호 +admin.setting.pwdNew=로 수정 +admin.setting.wallDiy=커스텀 벽지 : +admin.setting.fav=즐겨 찾기 관리 +admin.setting.help=도움말 사용 +admin.setting.about=작품에 대해 +admin.setting.homePage=kodcloud 홈 +admin.setting.subMenu=하위 메뉴 +admin.setting.menuName=메뉴 이름 +admin.setting.menuUrl=URL 주소 +admin.setting.menuUrlDesc=URL 주소 또는 JS 코드 +admin.setting.safeAccount=계정 및 로그인 보안 +admin.setting.safeData=데이터 보안 / 전송 보안 +admin.setting.passwordErrorLock=비밀번호 입력 오류 잠금 +admin.setting.passwordErrorLockDesc=비밀번호가 5회 연속 틀리면 계정이 1분 동안 잠기고 로그인이 허용되지 않습니다. 개설 후에는 비밀번호가 무차별적으로 해킹되는 것을 효과적으로 방지할 수 있습니다. +admin.setting.passwordRule=사용자 비밀번호 강도 설정 +admin.setting.passwordRuleDesc=비밀번호 강도를 지정한 후 취약한 비밀번호를 효과적으로 제거 할 수 있습니다. +admin.setting.passwordRuleNone=무제한 +admin.setting.passwordRuleStrong=중간 강도 +admin.setting.passwordRuleStrongMore=고강도 +admin.setting.passwordRuleNoneDesc=무제한 비밀번호 안전성 +admin.setting.passwordRuleStrongDesc=길이가 6보다 크며 영어와 숫자를 모두 포함해야합니다. +admin.setting.passwordRuleStrongMoreDesc=길이가 6보다 크고 숫자, 대문자 영어, 소문자 영어를 포함해야합니다. +admin.setting.passwordRuleTips=현재 비밀번호가 충분하지 않으므로 즉시 비밀번호를 변경하는 것이 좋습니다. +admin.loginCheck.menu=로그인 제어 +admin.loginCheck.ipCheck=IP 제한 +admin.loginCheck.ipCheckNone=제한되지 않음 +admin.loginCheck.ipCheckAllow=IP 화이트리스트 +admin.loginCheck.ipCheckDisable=IP 블랙리스트 +admin.loginCheck.loginIpAllowDesc=개봉 후에는 지정된 IP를 가진 사용자 만 로그인이 가능하므로주의하여 사용하시기 바랍니다. +admin.loginCheck.ipAllow=허용 된 IP +admin.loginCheck.ipAllowDesc=다음과 같이 규칙을 입력하십시오 (각 줄마다 서버의 로컬 IP는 기본적으로 허용되며 시스템 관리자는 LAN IP를 허용합니다) +admin.loginCheck.ipDisable=블랙리스트 IP 규칙 +admin.loginCheck.ipDisableDesc= +admin.loginCheck.ipDescTitle=다음과 같이 규칙을 작성하십시오 (항목 당 한 줄). +admin.loginCheck.ipDesc +admin.loginCheck.sort=우선 순위 +admin.loginCheck.name=규칙 이름 +admin.loginCheck.user=지정된 사용자 +admin.loginCheck.device=지정 장비 +admin.loginCheck.deviceWeb=편물 +admin.loginCheck.devicePc=PC 측 +admin.loginCheck.deviceAndroid=기계적 인조 인간 +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc +admin.setting.checkCodeDesc=로그인 후 인증 코드를 입력해야합니다. +admin.setting.csrfProtect=csrf 보호 활성화 +admin.setting.csrfProtectDesc=활성화되면 csrf 공격을 효과적으로 방지 할 수 있습니다 +admin.setting.setRootPath=루트 액세스 +admin.setting.setRootPathDesc= +admin.setting.encode=파일 저장소 암호화 +admin.setting.encodeAll=모두 암호화 +admin.setting.encodeName=확장 유지 +admin.setting.encodeNone=암호화 없음 +admin.setting.encodeAllDesc=전체 암호화 : [기본 권장 사항], 서버 권한이 있어도 파일의 실제 내용을 알 수 없으며 랜섬웨어 및 기타 손상으로부터 효과적으로 보호 할 수 있습니다. +admin.setting.encodeNameDesc=확장자 유지 : 파일 이름 암호화, 확장자 유지 +admin.setting.encodeNullDesc=암호화 없음 : 파일 이름이 암호화되지 않고 원래 파일 이름이 유지됩니다 (보안을 위해 업로드 폴더의 이름은 암호화 된 구조입니다). +admin.setting.encodeTips1=설정 변경 후의 파일 만 영향을 받고 이전의 파일은 영향을받지 않습니다. +admin.setting.encodeTips2=오류를 피하려면 데이터 / 파일의 파일을 삭제하거나 이름을 바꾸지 마십시오. +admin.setting.encodeTips3=대규모 동시성, 두 번째 전송, 클러스터링, 분산, 자동 확장 및 기타 기능을 지원하기 위해 폴더 계층 구조는 데이터베이스에 기록되며 폴더 구조는 복사 및 붙여 넣기를 통해 가져오고 복원 할 수 있습니다. +admin.setting.thirdLogin=타사 로그인 +admin.setting.thirdLoginDesc=타사 계정을 통한 등록, 바인딩 및 로그인 허용 +admin.setting.registOpen=공개 사용자 등록 +admin.setting.registOpenDesc=데이터 충돌을 피하기 위해 타사 데이터 동기화와 사용자 등록을 동시에 활성화 할 수 없습니다 +admin.setting.registCheck=공개 등록 검토 +admin.setting.registCheckDesc=등록 후 관리자는 등록 된 사용자가 사용할 수 있도록 [사용자 및 부서]에서 관리자를 검토하고 활성화해야합니다. +admin.setting.clearUserRecycle=모든 사용자 휴지통 비우기 +admin.setting.clearCache=캐시 지우기 +admin.setting.icp=저작권 또는 기록 번호 +admin.setting.icpDesc=링크를 생성해야하는 경우 직접 태그를 추가 할 수 있습니다 +admin.setting.globalCss=사용자 정의 글로벌 CSS +admin.setting.globalCssDesc=모든 페이지는 사용자 정의 CSS를 삽입합니다 +admin.setting.globalHtml=통계 코드 HTML +admin.setting.globalHtmlDesc=모든 페이지에이 HTML 코드가 삽입되며 타사 통계 코드를 배치 할 수 있습니다 +admin.setting.dateFormat=날짜 형식 +admin.setting.dateFormatDesc=년-월-일 시간 형식 표시, 파일 수정 시간 등 +admin.setting.menu=메뉴 관리 +admin.setting.systemName=회사 제품 이름 +admin.setting.systemNameDesc=제품 로고 제목 +admin.setting.systemDesc=제품 자막 +admin.setting.pathHidden=디렉토리 제외 +admin.setting.pathHiddenDesc=기본적으로 디렉토리와 파일은 쉼표로 구분되어 표시되지 않습니다 +admin.setting.defaultFolder=새로운 사용자는 기본적으로 디렉토리를 만듭니다 +admin.setting.defaultFolderDesc=쉼표로 구분 +admin.setting.defaultApp=신규 사용자는 기본적으로 앱을 만듭니다 +admin.setting.defaultAppDesc=쉼표로 구분 된 응용 프로그램 센터 응용 프로그램 +admin.setting.autoLogin=자동 로그인 +admin.setting.autoLoginDesc=기본 로그인 사용자는 guest/guest 사용자입니다;이 사용자가 열린 후에 존재하는지 확인하십시오 +admin.setting.firstIn=로그인 후 기본적으로 입력 +admin.setting.registReviewOpen=공개 등록 감사 : +admin.setting.registRoleEmpty=권한 역할은 비워 둘 수 없습니다 +admin.setting.registNotSync=데이터 충돌을 피하기 위해 타사 데이터 동기화와 사용자 등록을 동시에 활성화 할 수 없습니다 +admin.setting.registNeedRewiew=관리자가 열리면 관리자는 등록 된 사용자가 사용할 수 있도록 사용자 및 부서에서이를 검토하고 활성화해야합니다. +admin.setting.roleRight=역할 권한 +admin.setting.emailHost=사서함 서버 +admin.setting.emailHostInput=메일 서버 주소를 입력하십시오 +admin.setting.emailHostTips=메일 서버 주소를 입력하십시오 +admin.setting.emailHostDesc=smtp.163.com과 같은 사서함 서버, 포트를 사용자 지정할 수 있습니다(기본값은 465). +admin.setting.emailSend=보낼 편지함 +admin.setting.emailSendInput=이메일 주소를 입력하십시오 +admin.setting.emailSendTips=보내는 이메일 주소를 입력하십시오 +admin.setting.emailSendDesc=시스템 이메일 주소, POP3 / SMTP 서비스를 활성화해야합니다 +admin.setting.emailPwd=인증 비밀번호 +admin.setting.emailPwdTips=이메일 인증 비밀번호를 입력하십시오 +admin.setting.secureType=암호화 +admin.setting.emailSendTest=전송 감지 +admin.setting.ensureEmailOk=메일을 정상적으로 보낼 수 있는지 확인하십시오 +admin.setting.emailTo=받은 편지함 +admin.setting.emailGoToTips=사서함으로 이동하십시오 +admin.setting.emailCheckTips=보기 +admin.setting.emailInputError=잘못된 이메일 설정 +admin.setting.emailPwdError=이메일 설정 비밀번호가 잘못되었습니다 +admin.setting.emailDesc=사용자 등록 및 비밀번호 검색 이메일을위한 메일 서버 설정 +admin.setting.sendEmail=메일 보내기 +admin.setting.sendEmailDesc=시스템 기본값 : 보낼 클라우드 메일 서버를 보내려면 호출; 사용자 정의 : 직접 메일 서버를 구성하십시오. +admin.setting.systemBackup=시스템 백업 +admin.setting.enableFunction=기능과 스위치 +admin.setting.treeOpen=트리 디렉토리 기능 스위치 +admin.setting.treeOpenDesc=파일 관리, 트리 디렉토리 해당 기능이 전체적으로 켜지고 꺼집니다 +admin.setting.groupListChild=하위 부문 목록 +admin.setting.groupListChildDesc=부서 폴더에 하위 부서가 표시되는지 여부는 권한이 위쪽으로 상속됩니다. +admin.setting.groupRootListChild=엔터프라이즈 웹 디스크 목록 하위 섹터 +admin.setting.groupRootListChildDesc=회사 네트워크 디스크 폴더에 하위 부서가 표시되고 권한이 위쪽으로 상속되는지 여부 +admin.setting.shareToMeAllowTree=조직구성별 미쇼와 협업 +admin.setting.shareToMeAllowTreeTips=오픈 후 나와 협업을 위한 콘텐츠 지원은 부서의 조직 구조에 따라 분류되어 조직 구조가 더 복잡한 상황에 적합 +admin.setting.groupTagAllow=부서 공개 레이블 +admin.setting.groupTagAllowTips=활성화 후 해당 부서의 파일에 대한 공개 레이블을 설정한 후 모든 부서 구성원이 표시되며 부서 관리자는 레이블 내용을 유지할 수 있습니다. +admin.setting.shareToMeList=타일 디스플레이 +admin.setting.shareToMeGroup=조직 구조별로 표시 +admin.setting.shareToMeUser=공유자별로 표시 +admin.setting.sysSrvState=서버 상태 +admin.setting.sysSrvInfo=서버 정보 +admin.setting.sysPhpInfo=PHP 정보 +admin.setting.database=데이터 베이스 +admin.setting.cache=은닉처 +admin.setting.sysMyInfo=내 정보 +admin.setting.srvStateCpu=CPU 사용량 +admin.setting.srvStateMem=메모리 사용량 +admin.setting.srvStateSrv=서버 시스템 저장 공간 +admin.setting.srvStateDef=네트워크 디스크의 기본 저장 공간 +admin.setting.srvInfoName=서버 이름 +admin.setting.srvInfoIp=서버 IP +admin.setting.srvInfoTime=서버 시간 +admin.setting.srvInfoUpTime=연속 실행 시간 +admin.setting.srvInfoWeb=서버 소프트웨어 +admin.setting.srvInfoPhpV=PHP 버전 +admin.setting.srvInfoSys=서버 시스템 +admin.setting.srvInfoPath=사이트 경로 +admin.setting.srvPhpDtl=PHP 세부 정보 +admin.setting.memLimit=메모리 제한 +admin.setting.postLimit=POST 제출 제한 +admin.setting.uploadLimit=업로드 파일 제한 +admin.setting.execTime=최대 실행 시간 +admin.setting.inputTime=최대 요청 시간 +admin.setting.disFunction=기능 비활성화 +admin.setting.phpExtSugst=권장 PHP 확장 +admin.setting.phpExtLoad=로드 된 확장 +admin.setting.myClientIp=내 IP +admin.setting.myClientUa=내 브라우저 UA +admin.setting.myClientLng=내 브라우저 언어 +admin.setting.disFuncDesc=시스템에 필요한 기능을 활성화하는 것이 좋습니다. +admin.setting.srvMemFree=남은 메모리 +admin.setting.srvMemUse=메모리 사용 +admin.setting.srvCpuUse=현재 점유 +admin.setting.srvCpuFree=미사용 +admin.setting.noLimit=제한 없는 +admin.setting.disFunNo=아니 +admin.setting.systemCache=시스템 캐시 +admin.setting.systemDb=시스템 데이터베이스 +admin.setting.sysCacheTab=캐시 스위치 +admin.setting.sysDbTab=데이터베이스 스위치 +admin.setting.sysRecTab=데이터베이스 복구 +admin.setting.cacheDesc=캐시 설명 +admin.setting.fileCacheDesc=파일 캐시 : 테스트 또는 소규모 사용에 적합한 캐시 파일에 직접 데이터를 씁니다. +admin.setting.redisDesc=Redis : 높은 동시 읽기 및 쓰기 상황에 적합한 고성능 키-값 비 관계형 데이터베이스. 사용을 권장합니다. +admin.setting.memcachedDesc=Memcached : 고성능 동시 메모리 읽기에 적합한 고성능 분산 메모리 객체 캐시 시스템. +admin.setting.saveAfterTest=테스트를 통과 한 후 저장할 수 있습니다 +admin.setting.checkPassed=합격 +admin.setting.ifSaveCache=전환 후 모든 캐시 된 데이터가 지워집니다!
    실행 하시겠습니까? +admin.setting.ifSaveDb=데이터베이스 스위치는 시스템의 현재 데이터를 새 데이터베이스로 가져와 기본값으로 설정합니다. 실행하시겠습니까? +admin.setting.dbCurrent=현재 구성 +admin.setting.dbType=데이터베이스 유형 +admin.setting.dbName=이름 데이터베이스 +admin.setting.dbInfo=데이터베이스 정보 +admin.setting.dbSwitch=켜기 +admin.setting.dbSwitchDesc=개봉 후 필요에 따라 데이터베이스 유형을 변경할 수 있으므로주의하여 조작하시기 바랍니다. +admin.setting.dbTable=데이터 시트 +admin.setting.dbCnt=합계 +admin.setting.dbNeedNew=데이터베이스가 이미 있습니다. 다시 지정하십시오. +admin.setting.dbInsertError=테이블 데이터를 쓰지 못했습니다. +admin.setting.dbNeedOthers=다른 데이터베이스 유형을 선택하십시오 +admin.setting.dbNeedChange=구성 매개 변수를 수정하십시오. +admin.setting.dbCreateError=데이터베이스 파일 생성에 실패했습니다. 디렉토리 읽기 및 쓰기 권한을 확인하십시오. +admin.setting.dbTaskProcess=실행 진행 +admin.setting.dbTasking=처형 중 +admin.setting.dbTaskDesc=불일치 데이터 생성을 피하기 위해 창을 닫거나 시스템에서 다른 작업을 수행하지 마십시오. +admin.setting.recTaskDesc=창을 닫지 마십시오. 요청이 중단된 후 작업이 끝날 때까지 백그라운드가 계속 실행됩니다. +admin.setting.dbCreate=새 데이터베이스 +admin.setting.dbSelect=데이터베이스 읽기 +admin.setting.dbInsert=데이터베이스에 쓰기 +admin.setting.dbSetSave=구성 정보 저장 +admin.setting.recDesc=사용 지침 +admin.setting.recDescInfo11=이 작업은 시스템 데이터를 재설정하므로 비 작동 및 유지 보수 또는 관련 기술 인력은 작동하지 않아야 합니다! +admin.setting.recDescInfo21=백업 데이터베이스를 새 데이터베이스에 쓰고 이를 시스템 기본값으로 설정하면 데이터 복구가 이루어집니다. +admin.setting.recDescInfo22=새로운 데이터베이스 설정 매개변수는 시스템 설정 파일 config/setting_user.php에 추가되며, 복구 실행 후 시스템이 비정상적일 경우 이전 시스템 데이터에 영향을 주지 않고 파일의 추가된 부분을 제거할 수 있습니다. +admin.setting.recDescInfo23=이 기능은 시스템 백업 관리에서 생성된 백업 데이터의 처리만 지원하며, 자신이 백업한 데이터베이스는 다른 방식으로 처리해야 합니다. +admin.setting.recDescInfo31=참고: 데이터베이스 유형이 MySQL인 경우 현재 구성 정보를 기반으로 새 라이브러리(원본 라이브러리 이름_현재 날짜_재구축)가 생성됩니다. 루트가 아닌 사용자는 권한이 충분하지 않을 수 있으므로 사용자에 대한 권한을 먼저 설정해야 합니다. +admin.setting.recDescInfo32=예를 들어, 현재 데이터베이스 구성 정보는 사용자: kod, 암호: kod123입니다. 루트 계정을 사용하여 데이터베이스에 로그인하고 해당 SQL 문을 실행하여 권한을 설정합니다(테스트 통과 및 복구 성공 후 권한 취소 가능). +admin.setting.recDescInfo33=권한 설정: +admin.setting.recDescInfo34=권한 취소: +admin.setting.recOpen=복구 켜기 +admin.setting.recOpenDesc=전원을 켠 후 필요에 따라 백업된 데이터베이스를 선택하여 복원할 수 있으므로 주의하여 작업하시기 바랍니다. +admin.setting.recTypeDesc=현재 사용 중인 시스템 유형에 따라 다름 +admin.setting.recPath=데이터베이스 백업 디렉토리 +admin.setting.recPathErr=잘못된 데이터베이스 백업 디렉토리 +admin.setting.ifSaveRec=데이터베이스 복원은 백업 데이터를 새 데이터베이스로 가져와 기본값으로 설정합니다.
    실행하시겠습니까? +admin.setting.recDiyPathErr=자가 백업을 사용하여 복원할 때 백업할 데이터베이스 파일을 선택하십시오. +admin.setting.recDiyFileNull=데이터베이스 파일이 비어 있습니다. +admin.setting.recDiyPhpErr=SQLite를 직접 백업하려면 php 형식의 데이터베이스 파일을 선택하세요. +admin.setting.recDiySqlErr=MySQL을 직접 백업하려면 sql 형식의 데이터베이스 파일을 선택하십시오. +admin.setting.recSysPathErr=백업 관리를 사용하여 복원할 때 백업 데이터베이스 디렉터리를 선택하십시오. +admin.setting.recSysTbErr=데이터베이스 백업 디렉터리가 잘못되었거나 데이터베이스 구조 파일이 없습니다. +admin.setting.recDbFileErr=선택한 라이브러리 파일이 시스템과 일치하지 않거나 유효한 데이터 테이블이 없습니다. +admin.setting.dbFileDown=라이브러리 파일 읽기 +admin.setting.dbFileDownErr=라이브러리 파일을 읽지 못했습니다. +admin.notice.waiting=푸시를 기다리는 중 +admin.notice.done=푸시 됨 +admin.notice.time=푸시 시간 +admin.notice.target=푸시 개체 +admin.notice.level=프롬프트 수준 +admin.notice.level0=약한 힌트 +admin.notice.level1=강력한 프롬프트 +admin.notice.levelDesc=약한 알림 : 왼쪽 하단의 알림 표시 줄에 빨간색 점이 표시됩니다. 강한 알림 : 사용자가 로그인 한 직후 알림이 표시됩니다. +admin.notice.targetAuth=모든 사용자에게 푸시하거나 지정된 사용자, 사용자 그룹 및 권한 그룹에 푸시하도록 선택합니다. +admin.notice.title=메시지 제목 +admin.notice.content=메시지 내용 +admin.notice.timeType=푸시 방식 +admin.notice.timeNow=즉시 푸시 +admin.notice.timePlan=예약 된 푸시 +admin.notice.listTitle=역 뉴스 알림 +admin.notice.clearAll=모두 비우기 +admin.notice.noMsg=무소식 +admin.notice.ifClearAll=모든 메시지를 지우시겠습니까? +admin.group.role=역할 정체성 +admin.group.name=부서명 +admin.group.parent=우수 부서 +admin.group.authShow=부서의 구성원이 볼 수 있는 조직 구조의 범위 +admin.group.authShowAll=모든 부서 +admin.group.authShowHide=이 부서 및 하위 부서만 +admin.group.authShowSelect=지정부서 +admin.group.authShowAllTips=이 부서의 구성원이 공동으로 공유할 때 다른 모든 부서(및 사용자)를 선택할 수 있습니다. +admin.group.authShowHideTips=이 부서의 구성원이 협업하고 공유할 때 현재 부서와 하위 부서(및 사용자)만 지원됩니다. +admin.group.authShowSelectTips=부서의 구성원이 협업 및 공유할 때 현재 부서 및 하위 부서를 포함하여 지정된 부서 및 하위 부서(및 사용자)를 선택할 수 있습니다. +admin.group.addSub=하위 부서 추가 +admin.group.remove=부서 삭제 +admin.group.switch=이민부 +admin.group.swtichDesc=선택한 부서(및 하위 부서) 아래의 사용자 및 파일을 대상 부서로 마이그레이션합니다. +admin.group.switchSameError=대상 부서는 선택한 부서와 같을 수 없습니다. +admin.group.switching=마이그레이션 중입니다. 잠시만 기다려 주십시오... +admin.group.groupSwitching=선택한 부서가 마이그레이션 중입니다. +admin.group.parentNullError=상급 부서는 비워 둘 수 없습니다 +admin.group.selected=선택한 부서 +admin.group.setSizeBatch=배치로 공간 크기 설정 +admin.group.multiSelect=일괄 설정을 위해 여러 부서를 선택할 수 있습니다. +admin.group.ifDisAll=모든 하위 부서가 비활성화됩니다. 실행 하시겠습니까? +admin.member.manage=사용자 및 부서 +admin.member.add=새로운 사용자 +admin.member.role=권한 역할 +admin.member.group=학과 +admin.member.groupAdd=부서 추가 +admin.member.groupEdit=편집부 +admin.member.remove=사용자 삭제 +admin.member.import=대량으로 추가 +admin.member.enable=사용 +admin.member.batchSet=대량 작업 +admin.member.groupRemove=부서에서 제거 +admin.member.groupInsert=부서에 추가 +admin.member.groupSwitch=부서로 마이그레이션 +admin.member.groupTarget=대상 부서 +admin.member.groupReset=부서 재설정 +admin.member.groupSwtichDesc=선택한 사용자를 현재 부서에서 대상 부서로 마이그레이션 +admin.member.roleSet=권한 역할 설정 +admin.member.sizeSet=공간 크기 설정 +admin.member.name=로그인 계정 +admin.member.nickName=사용자 닉네임 +admin.member.userInfo=사용자 정보 +admin.member.userImport=대량으로 사용자 가져 오기 +admin.member.uploadFirst=먼저 파일을 업로드하십시오 +admin.member.downTpl=템플릿 다운로드 +admin.member.downTplDesc=, 템플릿 형식을 작성하고 업로드하십시오. +admin.member.uploadInvalid=업로드 한 파일에 유효한 데이터가 없습니다. 확인 후 다시 업로드하십시오 +admin.member.uploadDataInvalid=업로드 데이터가 유효하지 않거나 만료되었습니다. 다시 업로드하십시오 +admin.member.importSuccess=가져오기 완료 +admin.member.importFail=가져 오기 실패 +admin.member.importFailDesc=성공: {0}, 실패: {1} +admin.member.importName=로그인 계정(필수, 고유) +admin.member.importNickName=별명(고유) +admin.member.importPwd=비밀번호 필요) +admin.member.importSex=성별(남성-1, 여성-0) +admin.member.importPhone=휴대폰 번호(고유) +admin.member.importEmail=이메일(만) +admin.member.groupRemoveTips=이 사용자 그룹의 사용자는 삭제 후 로그인 할 수 없습니다.
    (사용자 그룹을 재설정해야합니다.) 계속 하시겠습니까? +admin.member.memberRemoveTips=삭제 후 사용자 디렉토리는 시스템 휴지통으로 이동됩니다.
    정말로 계속하기를 원하십니까? +admin.member.selectUserTips=운영 할 계정을 선택하세요 +admin.member.ifRemoveGroup=이 그룹에서 선택한 사용자를 제거 하시겠습니까? +admin.member.importDesc=한 줄에 한 명의 사용자
    이미 존재하는 경우 자동 무시 +admin.member.roleAdminTips=참고 : 시스템 관리자는 권한에 의해 제어되지 않습니다 +admin.member.space=사용자 공간 크기 설정 +admin.member.spaceTips=0은 제한되지 않습니다 +admin.member.spaceTipsDefault=(GB) 0은 제한되지 않습니다 +admin.member.spaceTipsFull=제한되지 않음 +admin.member.spaceSize=공간 크기 +admin.member.spaceSizeUse=공간 사용 +admin.member.memberAdd=사용자 추가 +admin.member.allAdd=사용자 또는 부서 추가 +admin.member.nullNotUpdate=비워 두십시오 +admin.member.search=사용자 검색 (계정 / 닉네임 / 이메일 / 전화) +admin.member.searchUser=사용자 검색 (병음 및 퍼지 일치 지원) +admin.member.searchGroup=검색 부서 (병음 및 퍼지 일치 지원) +admin.member.searchAll=사용자 또는 부서 검색 (병음 및 퍼지 일치 지원) +admin.member.editNoAuth=죄송합니다.이 권한이 없습니다.
    시스템 관리자 만 시스템 관리자를 추가하고 수정할 수 있습니다 +admin.member.disabledUsers=계정 비활성화 +admin.member.disabledTips=선택을 해제하기 위해 부서 전환 +admin.member.userGroup=사용자 부서 +admin.member.userRole=사용자 역할 +admin.member.userSelected=선택된 사용자 +admin.member.authCopy=부서 권한 복사 +admin.member.authPaste=부서 권한 붙여넣기 +admin.member.ifAuthPaste=복사한 부서 권한을 현재 사용자에게 설정하시겠습니까? +ERROR_USER_NOT_EXISTS=사용자가 존재하지 않습니다 +ERROR_USER_PASSWORD_ERROR=잘못된 비밀번호 +ERROR_USER_EXIST_NAME=사용자 이름이 이미 존재합니다 +ERROR_USER_EXIST_PHONE=전화 번호가 이미 존재합니다 +ERROR_USER_EXIST_EMAIL=사서함이 이미 존재합니다 +ERROR_USER_EXIST_NICKNAME=닉네임이 이미 존재합니다. +ERROR_USER_LOGIN_LOCK=비밀번호 시도 횟수가 너무 많아 현재 계정이 잠겨 있습니다. 1 분 후에 다시 시도하십시오! +ERROR_IP_NOT_ALLOW=현재 IP 또는 액세스 장치로 로그인 할 수 없습니다. 관리자에게 문의하십시오! +user.passwordCheckError=비밀번호 형식이 비밀번호 강도 규칙을 충족하지 않습니다! +admin.role.administrator=시스템 관리자 +admin.role.group=부서 관리자 +admin.role.default=일반 사용자 +admin.role.ignoreExt=확장 제한 +admin.role.ignoreExtDesc=업로드가 허용되지 않는 파일 형식, 비어있는 것에 대한 제한은 없습니다 +admin.role.ignoreFileSize=파일 크기 제한 업로드 +admin.role.ignoreFileSizeDesc=단일 파일 업로드 최대 값, 0은 무제한 +admin.role.ignoreExtTips=현재 시스템 설정은이 유형의 파일 업로드를 지원하지 않습니다. 자세한 내용은 관리자에게 문의하십시오! +admin.role.ignoreFileSizeTips=파일이 크기 제한을 초과하면 죄송합니다. 자세한 내용은 관리자에게 문의하십시오! +admin.role.desc=역할 설명 +admin.role.adminDesc=최고 관리자, 서버 관리 권한이 있으며 이 사용자에 대한 모든 파일 및 폴더 설정이 유효하지 않습니다! +admin.role.read=읽기 +admin.role.readList=파일리스트 +admin.role.readInfo=파일 (폴더) 속성보기, 폴더 검색 +admin.role.readCopy=파일 복사 +admin.role.readPreview=파일 미리보기 (사진, 문서, 오디오 및 비디오 등) +admin.role.readDownload=파일 (폴더) 다운로드 +admin.role.write=쓰다 +admin.role.writeAdd=파일 (폴더) 생성, 파일 압축 및 압축 해제 +admin.role.writeChange=디렉토리 구조 이름 변경, 조정 +admin.role.writeUpload=파일 (폴더) 업로드, 원격 다운로드 +admin.role.writeRemove=파일 (폴더) 삭제, 잘라 내기 +admin.role.adminSetDesc=시스템 관리자는 모든 권한을 가지므로 설정할 필요가 없습니다! +admin.role.displayDesc=사용자 역할 설정시 표시 여부 +admin.role.defaultRoleDesc=팁 : 시스템에는 기본적으로 기본 제공 역할이 있으며 권한 수정을 지원하지 않습니다. 새로운 역할을 만들 수 있습니다 +admin.role.actionSetTitle=설명서 및 구성 +admin.role.userSetTitle=사용자 구성 데이터 +admin.role.adminSetTitle=백그라운드 기능 +admin.role.fileAdd=새 파일 (폴더) +admin.role.fileRemove=문서 삭제 +admin.role.fileMove=이동 (복사 / 잘라 내기 / 붙여 넣기 / 드래그 조작) +admin.role.userConfig=구성 수정 (아바타 설정 / 비밀번호 변경 등) +admin.role.userEdit=사용자 편집 (추가 / 수정 / 삭제) +admin.role.userFav=즐겨 찾기 작업 +admin.role.itemEdit=추가 / 수정 / 삭제 +admin.role.groupEdit=부서 편집 (추가 / 수정 / 삭제) +admin.role.delErrTips=캐릭터가 사용 중이며 삭제할 수 없습니다! +admin.authFrom.setUser=자신의 권한 지정 +admin.authFrom.setGroup=부서 권한 지정 +admin.authFrom.setAll=기타 사용자 권한 +admin.authFrom.groupAt=부서 권한 +admin.authFrom.groupParent=상위 부서 권한 +admin.authFrom.pathOnly=액세스만 가능, 하위 레벨에는 콘텐츠 및 권한이 있습니다. +admin.authFrom.groupRoot=부서 루트 디렉토리 +admin.auth.owner=소유자 +admin.auth.editor=편집자 +admin.auth.editUploader=편집 / 업 로더 +admin.auth.viewer=뷰어 +admin.auth.previewer=미리보기 +admin.auth.uploader=업 로더 +admin.auth.invisible=보이지 않는 +admin.auth.user=사용자 데이터 +admin.auth.pathDelete=파일 삭제 +admin.auth.pathInfo=파일 속성 +admin.auth.pathMove=이동 (복사 / 잘라 내기 / 붙여 넣기 / 드래그 조작) +admin.auth.canUpload=다운로드 업로드 +admin.auth.config=구성 데이터 +admin.auth.fav=즐겨 찾기 작업 (추가 / 편집 / 삭제) +admin.auth.extWarning=이러한 파일은 업로드 할 수 없습니다.
    이름 변경 (지정된 확장명으로 변경)
    저장, 원격 다운로드, 압축 해제 편집 +admin.auth.error=권한 역할 오류 (권한 설정이 없음) +admin.auth.errorAdmin=권한 부족 +admin.auth.targetError=권한 개체 유형이 잘못되었습니다. 사용자 또는 부서 여야합니다. +admin.auth.errorAuthToGroup=비 루트 부서, 부서에 위임을 지원하지 않습니다 +admin.auth.errorAuthToUsers=비 루트 부문, 부문 외부의 회원에게 위임을 지원하지 않습니다 +admin.auth.displayDesc=부서 사용자 권한을 설정할 때 표시할지 여부 +admin.auth.defaultAuthDesc=팁 : 시스템에는 기본적으로 권한 그룹이 내장되어 있으며 권한 수정을 지원하지 않습니다. 새로운 권한 그룹을 만들 수 있습니다 +admin.auth.show=파일리스트 +admin.auth.showAction=파일 목록보기 +admin.auth.view=파일 미리보기 +admin.auth.viewAction=파일 열기 미리보기 +admin.auth.download=다운로드 / 복사 +admin.auth.downloadAction=다운로드 / 복사 / 파일 미리보기 인쇄 +admin.auth.uploadAction=파일 (폴더) 업로드 / 원격 다운로드 +admin.auth.edit=새로 편집 +admin.auth.editAction=새 파일 (폴더) / 이름 바꾸기 / 폴더에 붙여 넣기 / 파일 편집 / 메모 설정 / 복사 만들기 / 압축 해제, 압축 +admin.auth.removeAction=잘라 내기 / 복사 / 이동 +admin.auth.shareAction=외부 체인 공유 / 다른 사람들과의 공동 작업 공유 +admin.auth.comment=문서 의견 +admin.auth.commentAction=문서 주석보기, 자신의 주석 추가 / 삭제 (편집 권한 필요) +admin.auth.event=문서 역학 +admin.auth.eventAction=문서 동적보기, 구독 동적 +admin.auth.root=행정권 +admin.auth.rootAction=회원 권한 설정 / 댓글 관리 / 이력 버전 관리 +admin.auth.delErrTips=이 권한은 사용 중이며 삭제할 수 없습니다! +admin.plugin.center=플러그인 센터 +admin.plugin.installed=설치 +admin.plugin.type=카테고리 +admin.plugin.typeFile=파일 향상 +admin.plugin.typeSafe=보안 도구 +admin.plugin.typeTools=유틸리티 +admin.plugin.typeMedia=멀티미디어 +admin.plugin.typeCompany=엔터프라이즈 애플리케이션 +admin.plugin.typeOem=독점적 인 커스터마이징 +admin.plugin.needNetwork=엑스트라 넷 +admin.plugin.install=플러그인 설치 +admin.plugin.enable=플러그인 사용 +admin.plugin.remove=플러그인 제거 +admin.plugin.config=플러그인 구성 +admin.plugin.statusEnabled=가능 +admin.plugin.statusDisabled=사용하지 않음 +admin.plugin.statusNotInstall=미설치 +admin.plugin.installing=설치 중 ... +admin.plugin.hasUpdate=업데이트 +admin.plugin.updateStart=플러그인 업데이트 +admin.plugin.needConfig=활성화하려면 초기 구성이 필요합니다 +admin.plugin.notNull=필수 입력란은 비워 둘 수 없습니다! +admin.plugin.auther=저자 +admin.plugin.downloadNumber=설치 +admin.plugin.back=돌아 가기 +admin.plugin.detail=설명 +admin.plugin.resetConfig=기본 설정 복원 +admin.plugin.installSelf=수동 설치 +admin.plugin.updateSelf=수동 업데이트 +admin.plugin.updateAll=모두 업데이트 +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=네트워크 오류 서버가 인터넷에 액세스 할 수 있는지 확인하십시오. +admin.plugin.auth=사용권 +admin.plugin.authDesc=모든 사람을 사용할 수있게하거나 사용자, 사용자 그룹 및 권한 그룹을 지정하십시오. +admin.plugin.authOpen=오픈 액세스 +admin.plugin.authOpenDesc=로그인없이 액세스 가능, 외부 인터페이스 호출에 사용 가능 +admin.plugin.authAll=모두 +admin.plugin.authUser=지정된 사용자 +admin.plugin.authGroup=지정 부서 +admin.plugin.authRole=권한 그룹 지정 +admin.plugin.openWith=오픈 스타일 +admin.plugin.openWithDilog=내부 대화 +admin.plugin.openWithWindow=새 페이지가 열립니다 +admin.plugin.fileSort=확장 연관 우선 순위 +admin.plugin.fileSortDesc=확장명이 클수록 우선 순위가 높습니다. +admin.plugin.fileExt=지원되는 파일 형식 +admin.plugin.fileExtDesc=플러그인에 확장 프로그램 연결 +admin.plugin.tabServer=서버 구성 +admin.plugin.defaultAceEditor=에이스 에디터 +admin.plugin.defaultHtmlView=웹 미리보기 +admin.plugin.defaultZipView=온라인 감압 +admin.plugin.authViewList=플러그인 목록 +admin.plugin.authStatus=닫힘 +admin.plugin.authInstall=설치 / 제거 +admin.plugin.disabled=플러그인이 존재하지 않거나 시작되지 않았습니다 +admin.plugin.menuAdd=메인 메뉴에 추가할지 여부 +admin.plugin.menuAddDesc=독립 실행 형 애플리케이션으로 사용 +admin.plugin.menuSubMenuDesc=[More] 메뉴에서 축소 +admin.storage.type=저장 유형 +admin.storage.local=현지 +admin.storage.localStore=로컬 스토리지 +admin.storage.oss=알리바바 클라우드 OSS +admin.storage.cos=텐센트 클라우드 COS +admin.storage.qiniu=일곱 암소 구름 +admin.storage.s3=아마존 S3 +admin.storage.ftp=FTP +admin.storage.oos=톈이 클라우드 OOS +admin.storage.moss=홍산 모스 +admin.storage.eos=XSKY EOS +admin.storage.nos=이전 클라우드 NOS +admin.storage.minio=MinIO +admin.storage.uss=다른 클라우드 USS 가져 가기 +admin.storage.eds=상포 EDS +admin.storage.driver=로컬 디스크 +admin.storage.useage=공간 사용량 +admin.storage.default=기본값으로 설정 +admin.storage.current=현재 기본값 +admin.storage.edit=구성 저장소 +admin.storage.setConfig=구성 수정 +admin.storage.moveData=데이터 마이그레이션 +admin.storage.delStore=스토리지 마운트 해제 +admin.storage.ifMove=이 저장소에는 {0}개의 네트워크 디스크 파일이 포함되어 있으며 현재 기본 저장소로 마이그레이션됩니다. 계속하시겠습니까? +admin.storage.ifDel=현재 저장소를 마운트 해제하시겠습니까? +admin.storage.ifDelWithFile=이 저장소에는 {0}개의 네트워크 디스크 파일이 포함되어 있으며 삭제 시 현재 기본 저장소로 마이그레이션됩니다. 계속하시겠습니까? +admin.storage.sysFile=네트워크 디스크 파일: 개인 공간 및 부서에 있는 파일 +admin.storage.delErrTips=성공 : %s; 실패 : %s, 다시 시도하거나 수동으로 마이그레이션하십시오. +admin.storage.delLocTips=하나 이상의 지역 상점을 유지하십시오 +admin.storage.delStoreTips=이 저장소에는 백업 데이터가 포함되어 있습니다. 계속하기 전에 처리하십시오! +admin.storage.nameDesc=다른 스토리지를 구별하기위한 스토리지 이름 +admin.storage.path=저장 디렉토리 +admin.storage.pathLocDesc=파일 저장 디렉토리, 채워진 디렉토리에 읽기 및 쓰기 권한이 있는지 확인하십시오 +admin.storage.pathDesc=파일 저장 디렉토리 +admin.storage.defaultDesc=기본 항목은 유일하게 유효한 시스템 저장 장치입니다. 사용하도록 선택하면 다른 기본 저장 방법이 자동으로 취소됩니다.주의해서 사용하십시오. +admin.storage.forceEdit=필수 수정 +admin.storage.editTips=연 후 금지 된 수정 필드를 편집 할 수 있습니다. 저장하기 전에 파일에 액세스하지 못할 수 있으므로주의하십시오. +admin.storage.folderTips=현재 시스템 파일 저장 위치, 주의하여 작동하십시오. +admin.storage.sizeTips=공간 크기는 0보다 커야합니다 +admin.storage.sizeDesc=(GB), 선택한 저장소 디렉터리의 실제 여유 공간에 따라 입력하십시오. +admin.storage.region=저장 영역 +admin.storage.domain=공간 도메인 이름 +admin.storage.bucket=버킷 이름 +admin.storage.bucketDesc=공간 생성시 채워진 버킷 이름 +admin.storage.userName=계정 이름 +admin.storage.userPwd=계정 비밀번호 +admin.storage.server=서버 주소 +admin.storage.serverDesc=ftp (s) : // ip, 기본값은 프로토콜이없는 ftp입니다. +admin.storage.refer=참조 : +admin.storage.endpoint=엔드 포인트 +admin.storage.ossDomain=OSS 공간에 바인딩 된 도메인 이름 +admin.storage.ossKeyDesc=Alibaba Cloud 계정의 액세스 키 ID는 [제어판-액세스 키 관리]에서 작성하거나 확인하십시오. +admin.storage.ossSecretDesc=Alibaba Cloud 계정의 액세스 키 비밀 +admin.storage.ossEndpoint=엔드포인트, 인트라넷 노드를 사용하는 경우 서버 전송을 활성화해야 합니다. +admin.storage.cosKeyDesc=Tencent Cloud 계정의 액세스 키 ID는 [제어판-액세스 관리 -API 키 관리]에서 생성하거나 확인하십시오. +admin.storage.cosSecretDesc=Tencent Cloud 계정의 액세스 키 비밀 +admin.storage.qiniuDomain=Qiniu Space에 의해 바인딩 된 도메인 이름 +admin.storage.qiniuKeyDesc=Qiniu 계정의 액세스 키는 [제어판-개인 센터 키 관리]에서 작성하거나 확인하십시오. +admin.storage.qiniuSecretDesc=Qiniu 계정의 비밀 키, 획득 방법은 위와 동일합니다 +admin.storage.qnz0=중국 동부 - 저장성 +admin.storage.qnz02=중국 동부 - Zhejiang 2 +admin.storage.qnz1=중국 북부 - 허베이 +admin.storage.qnz2=중국 남부 - 광동 +admin.storage.qnna0=북미 - 로스앤젤레스 +admin.storage.qnas0=아시아 태평양 - 싱가포르 +admin.storage.qnas02=아시아 태평양 - 서울 +admin.storage.awsDomain=AWS 공간에 바인딩 된 도메인 이름 +admin.storage.awsKeyDesc=AWS 계정의 액세스 키 ID는 [제어판-보안 자격 증명]에서 생성하십시오. +admin.storage.awsSecretDesc=AWS 계정의 액세스 키 비밀 +admin.storage.oosDomain=Tianyi Cloud Space 바운드 도메인 이름 +admin.storage.oosKeyDesc=Tianyi Cloud 계정의 액세스 키 ID는 [제어판-보안 자격 증명]에서 생성하십시오. +admin.storage.oosSecretDesc=Tianyi 클라우드 계정의 액세스 키 비밀은 위와 동일합니다 +admin.storage.ftpDisabled=FTP를 사용할 수 없습니다. php_ftp 확장자를 활성화하십시오 +admin.storage.ifDefaultTips=이 작업으로 다른 기본 저장 방법이 취소됩니다. 계속 하시겠습니까? +admin.storage.spaceUsed=실용 +admin.storage.spaceLave=잔액 +admin.storage.delError=파일이이 저장소에 이미 존재하며 삭제할 수 없습니다 +admin.storage.corsError=구성이 올 바르면 [도움말 사용]을 클릭하여 버킷 교차 도메인 설정을 확인하십시오. +admin.storage.saveError=지정된 스토리지에 연결할 수 없습니다. 구성 정보가 올바른지 확인하십시오. +admin.storage.ftpCharset=FTP 서버 인코딩 +admin.storage.ftpCharsetDesc=FTP 서버가 Windows 인 경우 상황에 따라 GBK로 설정할 수 있습니다. +admin.storage.ftpPasvOn=켜다 +admin.storage.ftpPasvOff=폐쇄 +admin.storage.ftpPasv=패시브 모드 +admin.storage.ftpPasvDesc=데이터 전송 모드 +admin.storage.uploadSrv=서버 전송 (업로드) +admin.storage.fileoutSrv=서버 전송 (다운로드) +admin.storage.uploadSrvDesc=전원을 켜면 파일이 서버를 통해 오브젝트 스토리지에 업로드되고, 그렇지 않으면 클라이언트를 통해 직접 업로드됩니다. +admin.storage.fileoutSrvDesc=전원을 켠 후 다운로드를 위해 서버를 통해 저장 파일을 얻습니다. 그렇지 않으면 직접 다운로드 할 파일을 얻습니다. +admin.storage.closeDefError=기본 저장소 끄기 금지 +admin.storage.ussBucket=서비스 이름 +admin.storage.ussBucketDesc=클라우드 스토리지 서비스 이름 +admin.storage.ussUser=운영자 이름 +admin.storage.ussUserDesc=운영자 이름 +admin.storage.ussUserPwd=운영자 비밀번호 +admin.storage.ussDomain=클라우드 공간에 바인딩 된 도메인 이름을 한 번 더 찍습니다. +admin.storage.ussToken=거머리 방지 토큰 +admin.storage.ussTokenDesc=토큰 도난 방지 체인 비밀 키 (필요하지 않음) +admin.storage.configError=구성 매개변수가 비정상입니다! +admin.storage.sizePercent=시스템 파일 비율: +admin.storage.fileCount=파일 수: +admin.storage.error=스토리지 예외 +admin.task.name=작업 이름 +admin.task.edit=작업 편집 +admin.task.type=작업 유형 +admin.task.method=내장 방법 +admin.task.methodName=방법 이름 +admin.task.methodDesc=시스템 모듈-컨트롤러-방법 이름으로 구성되어 있으며주의해서 입력하십시오. +admin.task.url=요청 URL +admin.task.urlDesc=사용자 정의 URL 주소, 정기적으로 요청을 실행하기위한 예약 된 작업 +admin.task.cycle=실행주기 +admin.task.desc=미션 세부 사항 +admin.task.nMinutes=N 분 +admin.task.default=시스템 기본값 +admin.task.timeInterval=간격 시간 +admin.task.timeStart=시작 시간 +admin.task.timeStartRun=실행 시간 시작 +admin.task.timeLastRun=마지막 실행 시간 +admin.task.timeLastLogin=로그인 시간 +admin.task.isOpen=활성화 여부 +admin.task.open=오픈 +admin.task.content=구현 내용 +admin.task.param=실행 매개 변수 +admin.task.ifRun=이 작업을 실행 하시겠습니까? +admin.task.backup=데이터 백업 +admin.task.backupDesc=매일 02:00에 시스템 데이터 백업을 시작하십시오. +admin.install.install=시스템 설치 +admin.install.databaseSet=데이터베이스 구성 +admin.install.dataUpdate=데이터 마이그레이션 +admin.install.installSuccess=성공적으로 설치되었습니다 +admin.install.dbWasSet=데이터베이스를 구성했습니다. 재설정해야하는 경우 config / setting_user.php 파일에서 구성을 수정하고 다시 설치할 수 있습니다! +admin.install.errorRequest=시스템이 설치되었으며 추가 요청이 허용되지 않습니다 +admin.install.databaseError=데이터베이스 연결 오류, 구성을 확인하십시오 +admin.install.cacheError=%s 연결에 실패했습니다. 구성을 확인하십시오 +admin.install.cacheConnectError=%s 서버에 연결할 수 없습니다. 구성을 확인하십시오 +admin.install.dbSetError=데이터베이스 구성 정보 쓰기 실패 +admin.install.dbCreateTips=데이터베이스가 존재하지 않고 자동 작성에 실패했습니다. 수동으로 작성하십시오 +admin.install.ifDelDb=데이터가 지정된 데이터베이스에 이미 존재합니다. [확인]을 클릭하여 삭제하십시오. 계속 하시겠습니까? +admin.install.dbCreateError=데이터 테이블 생성 예외 +admin.install.dbFileError=데이터베이스 파일이 존재하지 않습니다 +admin.install.dbTypeError=선택한 데이터베이스 유형 (%s)을 사용할 수 없습니다. 해당 서비스 및 확장을 설치하거나 다른 유형을 선택하십시오 +admin.install.createSuccess=성공적으로 생성 +admin.install.defSetError=시스템 기본 구성을 추가하지 못했습니다 +admin.install.defStoreError=기본 스토리지 추가 실패 +admin.install.defPathError=시스템 디렉토리 추가 실패 +admin.install.defAdminError=관리자 계정을 추가하지 못했습니다 +admin.install.defRoleError=기본 역할 추가 실패 +admin.install.defGroupError=시스템 부서 추가 실패 +admin.install.dataPathNotExists=데이터 디렉토리가 존재하지 않습니다 +admin.install.defaultUpdate=시스템 구성 정보 업데이트 +admin.install.pluginUpdated=플러그인 업데이트 완료 +admin.install.defCacheError=초기 디렉토리 캐시 데이터 예외 +admin.install.serverDir=서버 열 디렉토리 +admin.install.dirRight=디렉토리 권한 +admin.install.suggestOpen=열 것을 권장합니다 +admin.install.suggestClose=닫는 것이 좋습니다 +admin.install.phpVersionTips=PHP5.3 이상 +admin.install.phpBitTips=64 비트 권장 +admin.install.phpBitDesc=32 비트는 2G를 통한 파일 업로드 및 다운로드를 지원하지 않습니다 +admin.install.pathNeedWirte=프로그램 디렉토리와 모든 하위 디렉토리는 읽고 쓸 수 있어야합니다. +admin.install.mustOpen=열어야합니다 +admin.install.setPathWrt=프로젝트 디렉토리에 대한 읽기 및 쓰기 권한을 설정하십시오. +admin.install.ensureNoError=다음이 올바른지 확인하십시오. +admin.install.setAdminName=관리자 계정을 설정하십시오 +admin.install.setAdminPwd=관리자 암호를 설정하십시오 +admin.install.database=데이터베이스 +admin.install.dbType=데이터베이스 유형 +admin.install.dbName=데이터베이스 이름 +admin.install.userName=아이디 +admin.install.dbPort=포트 번호 +admin.install.dbPortDesc=기본 포트는 3306이며, 사용자 지정해야 하는 경우 127.0.0.1:3307과 같이 추가할 수 있습니다. +admin.install.dbEngine=스토리지 엔진 +admin.install.sqliteDesc=PHP에는 녹색 경량 데이터베이스가 내장되어 있습니다 (테스트 또는 소규모 사용에 적합). +admin.install.mysqlDesc=클러스터 배포, 마스터 및 슬레이브 데이터베이스 분리를 지원합니다. +admin.install.pdoDesc=보다 안전한 데이터베이스 일반 드라이버를 사용하려면 PHP에 PDO 확장이 설치되어 있어야합니다. +admin.install.cacheType=시스템 캐시 유형 +admin.install.cacheTypeDesc=시스템 액세스 속도를 높이기 위해 일반 데이터 및 세션 세션을 캐시하는 데 사용 +admin.install.fileCache=파일 캐시 +admin.install.groupFile=부서 문서 +admin.install.userFile=사용 설명서 +admin.install.role=역할 +admin.install.fileAuth=문서 권한 +admin.install.userList=사용자 목록 +admin.install.setInfo=시스템 구성 정보 +admin.install.favShare=사용자 즐겨 찾기 및 공유 +admin.install.waitUpdate=업데이트 대기 중 +admin.install.updateSuccess=업데이트 성공 +admin.install.fileCount=파일 수 +admin.install.settingDesc=백그라운드 관리에서 실패 항목을 수동으로 구성 할 수 있습니다 +admin.install.reInstallTips=반품 결과가 비정상입니다. 다시 설치하십시오 +admin.log.accountEdit=계정 정보 수정 +admin.log.thirdBind=타사 계정 바인딩 +admin.log.delBind=바인드 해제 +admin.log.viewFile=미리보기 파일 +admin.log.delFile=파일 삭제 +admin.log.editFile=파일 편집 +admin.log.downFile=파일 다운로드 +admin.log.downFolder=폴더 다운로드 +admin.log.moveFile=파일 이동 +admin.log.addUser=사용자 추가 +admin.log.editUser=사용자 편집 +admin.log.addUserTo=부서에 사용자 추가 +admin.log.removeUserFrom=부서에서 사용자가 삭제됨 +admin.log.switchUserGroup=사용자를 부서로 마이그레이션 +admin.log.stausUser=사용자 활성화 / 비활성화 +admin.log.addRole=새로운 역할 +admin.log.editRole=역할 편집 +admin.log.delRole=역할 삭제 +admin.log.addAuth=권한 추가 +admin.log.editAuth=권한 수정 +admin.log.delAuth=권한 삭제 +admin.log.editShare=공유 편집 +admin.log.delLinkTo=외부 링크 공유 취소 +admin.log.delShareTo=공동 작업 취소 +admin.log.recycleTo=휴지통으로 이동 +admin.log.newName=새로운 이름 +admin.log.oldName=원래 이름 +admin.log.newPath=새로운 카탈로그 +admin.log.oldPath=원본 카탈로그 +admin.log.typeFile=파일 작업 +admin.log.typeUser=사용자 구성 +admin.log.queryByIp=버튼을 클릭하면 IP를 기반으로 해당 날짜의 로그 기록을 조회 할 수 있습니다. +admin.backup.setting=백업 설정 +admin.backup.edit=백업 편집 +admin.backup.ing=백업 +admin.backup.success=백업 성공 +admin.backup.fail=백업 실패 +admin.backup.complete=백업 완료 +admin.backup.db=데이터 베이스 +admin.backup.dbFile=데이터베이스 파일 +admin.backup.fileError=일부 파일 백업 실패 +admin.backup.checkLog=백업 로그를 확인하십시오: data/temp/log/backup/date__log.php +admin.backup.pathNoWrite=임시 디렉토리에 쓰기 권한이 없습니다. +admin.backup.errorMsg=파일 백업에 실패했습니다. 로그에 따라 수동으로 복사하거나 삭제 및 다시 백업 할 수 있습니다. +admin.backup.logFile=로그 파일 +admin.backup.manual=수동 백업 +admin.backup.continue=백업 계속 +admin.backup.start=백업 시작 +admin.backup.open=백업 켜기 +admin.backup.notOpen=백업이 활성화되지 않았습니다 +admin.backup.location=백업 위치 +admin.backup.content=백업 콘텐츠 +admin.backup.dbOnly=데이터 베이스 +admin.backup.time=백업 시간 +admin.backup.notStart=시작하지 않았다 +admin.backup.notEnabled=활성화되지 않음 +admin.backup.killed=위에 +admin.backup.ifKill=이 백업을 종료 하시겠습니까? +admin.backup.kill=종료 +admin.backup.error=중단 +admin.backup.timeBeen=시간 소모 +admin.backup.timeTotal=총 시간 +admin.backup.backed=백업 +admin.backup.storage=백업 전용 스토리지를 생성하십시오. +admin.backup.ifSave=백업 시간이 오래 걸립니다. 백업 하시겠습니까? +admin.backup.ifContinue=백업을 계속 하시겠습니까? +admin.backup.saveTips=백업 작업이 제출되었습니다. 기다려주십시오 +admin.backup.fileSize=문서 크기 +admin.backup.dbSize=데이터베이스 크기 +admin.backup.dbCnt=합계 +admin.backup.notFinished=미완료 +admin.backup.timeTaken=시간이 걸리는 +admin.backup.node=마디 +admin.backup.notYet=아니 +admin.backup.storeNotExist=백업 저장소가 없습니다. 재설정하십시오. +admin.backup.timeNote=참고: 시스템은 지난 7일과 매월 1일의 데이터베이스 백업만 유지합니다. 백업 시간: +admin.backup.recover=데이터 복구는 서비스 제공 업체에 문의하십시오. +admin.backup.optionTime=백업에 시간이 오래 걸리므로 작업하지 않는 시간에 선택하십시오. +admin.backup.optionLocation=파일을 백업해야 하는 경우 백업 전용 저장소를 새로 만드십시오. +admin.backup.optionTips1=백업은 데이터베이스 백업과 파일 백업의 두 부분으로 나뉩니다. +admin.backup.optionTips2=데이터베이스 백업 : 데이터베이스 콘텐츠에서 SQL 파일을 생성하고 대상 스토리지 데이터베이스 디렉터리에 백업합니다. +admin.backup.optionTips3=파일 백업 : 원래 스토리지 경로에 따라 증 분식으로 대상 스토리지에 시스템 스토리지 파일을 백업합니다. +admin.backup.optionTips4=시스템은 지난 7일과 매월 1일의 데이터베이스 백업만 유지합니다. +admin.backup.needStorage=백업 저장소는 비워 둘 수 없습니다. +admin.backup.needNoDefault=파일 백업 위치로 기본 저장소를 선택하지 마십시오 +admin.backup.contentDesc=라이센스 버전은 데이터베이스 및 파일의 동시 백업을 지원합니다. +admin.backup.action=운영 관리 +admin.backup.recovery=절감 +admin.backup.sysRecovery=시스템 복원 +admin.backup.bakErr2Rec=이 백업은 불완전하여 복원할 수 없습니다. +admin.recycle.menu=시스템 휴지통 +admin.share.name=이름 공유 +admin.share.type=공유 유형 +admin.share.expiryTime=만료 +admin.share.expired=만료 +admin.share.link=외부 링크 +admin.share.linkView=공유를 보려면 클릭 +admin.share.ifDel=이 공유를 취소 하시겠습니까? +admin.share.disFile=이 파일은 사용자가 신고했으며 공유가 금지되었습니다. +admin.share.disFolder=이 디렉토리에는 공유가 금지 된 불법 파일이 있습니다. +admin.share.shareTab=나눔 경영 +admin.share.reportTab=공유 보고서 관리 +admin.share.rptType1=불법 복제 +admin.share.rptType2=음란 한 포르노 +admin.share.rptType3=피의 폭력 +admin.share.rptType4=정치는 해롭다 +admin.share.rptType5=다른 이유들 +admin.share.doRptClose=공유 콘텐츠를 처리 한 후 보고서를 닫거나 직접 닫습니다. +admin.share.doRptDisable=공유 금지 / 허용 후 해당 파일에 해당하는 모든 리소스가 영향을받습니다. 이 작업을 수행 하시겠습니까? +admin.share.rptUser=내부 고발자 +admin.share.rptTitle=보고서 공유 +admin.share.rptDesc=신고 이유 +admin.share.rptTime=보고 시간 +admin.share.rptResult=공정 결과 +admin.share.rptDone=처리됨 +admin.share.rptNoDone=미처리 +admin.share.rptClose=보고서 닫기 +admin.share.rptShareDel=공유 해제 +admin.share.rptShareAllow=공유 허용 +admin.share.rptShareDisable=공유 안함 +admin.share.rptDoDisable=공유 금지/허용 +admin.share.rptSelectTips=조작할 항목을 선택해주세요! +admin.setting.transfer=업로드 / 다운로드 +admin.setting.transferChunkSize=샤드 크기 업로드 +admin.setting.transferChunkSizeDesc=큰 파일을 업로드 할 때 가속을 달성하고 재개를 재개하기 위해 동시 업로드를 위해 조각으로 잘립니다.
    5M이 권장됩니다.이 값 다음 구성보다 작아야합니다. 그렇지 않으면 업로드 예외 (업로드 실패, 롤백)가 발생합니다. +admin.setting.transferChunkSizeDescError1=업로드 샤드 크기는 php.ini의 설정을 초과 할 수 없습니다 +admin.setting.transferChunkSizeDescError2=php.ini에서 수정하고 다시 시도하십시오 (upload_max_filesize 수정, post_max_size, 다시 시작해야 함) +admin.setting.transferThreads=동시 스레드 업로드 +admin.setting.transferThreadsDesc=권장 = 10; 파일 또는 샤드의 동시 업로드 +admin.setting.transferIgnore=무시 파일 업로드 +admin.setting.transferIgnoreDesc=자동으로 무시되는 파일 이름을 업로드합니다. 임시 파일은 제외 할 수 있습니다 (예 : .DS_store, thumb.db). +admin.setting.transferChunkRetry=업로드 실패시 자동 재전송 +admin.setting.transferChunkRetryDesc=권장 사항 = 5; 업로드에 실패하면 재전송 횟수가 자동으로 수행됩니다. 0은 자동 재전송이 없음을 의미합니다. +admin.setting.transferOsChunkSize=개체 저장소 샤드 크기 +admin.setting.transferOsChunkSizeDesc= +admin.setting.transferHttpSendFile=웹 서버 가속 다운로드 +admin.setting.transferHttpSendFileDesc=파일 다운로드는 웹 서버를 통해 직접 전송되며 다운로드 속도가 향상되며 기본 저장소가 로컬 저장소로 구성된 경우에만 유효합니다. +admin.setting.downloadZipClient=프런트 엔드 압축 다운로드 +admin.setting.downloadZipClientDesc=외부 네트워크에 연결할 수 있어야 하거나 사이트가 https여야 합니다. +admin.setting.downloadZipLimit=압축 다운로드 크기 제한 +admin.setting.downloadZipLimitDesc=0은 제한 없음을 의미하며 과도한 서버 성능 소모를 방지하기 위해 폴더가 너무 클 경우 패키지 다운로드를 제한하고 PC 클라이언트를 통해 파일을 직접 다운로드할 수 있는지 묻는 메시지를 표시합니다. +admin.setting.downloadZipLimitTips=압축된 콘텐츠가 시스템 제한을 초과합니다 관리자에게 문의하세요 압축 없이 PC 클라이언트를 통해 폴더를 직접 다운로드할 수 있습니다. +admin.setting.dragDownload=데스크탑으로 드래그 앤 드롭하여 다운로드 +admin.setting.dragDownloadDesc=PC측 크롬 커널 브라우저에서만 지원(크롬 엣지 360 ​빠른 등) +admin.setting.dragDownloadZip=다중 선택 드래그 앤 드롭 압축 다운로드 +admin.setting.dragDownloadZipDesc=다중 선택 또는 폴더 끌어서 놓기 다운로드 지원, 다운로드하기 전에 서버에서 패키지 및 압축해야 함 +admin.setting.dragDownloadLimit=드래그 앤 드롭 콘텐츠 크기 제한 +admin.setting.dragDownloadLimitDesc=0은 제한 없음을 의미하며, 드래그한 콘텐츠의 크기에 이 제한이 적용됩니다. 현재 Chrome 드래그 및 다운로드에 대한 진행률 표시줄이 없으므로 취소할 수 없습니다. 크기를 20M로 제한하는 것이 좋습니다. +admin.setting.dragDownloadUrlTips=URL이 너무 깁니다. 선택 항목을 줄이고 다시 시도하십시오! +admin.setting.dragDownloadOpenTips=백그라운드 설정에서 활성화하려면 관리자에게 문의하세요! +admin.setting.dragDownloadNotOpen=드래그 앤 압축 다운로드가 활성화되지 않았습니다. +admin.setting.dragDownloadSizeTips=드래그한 콘텐츠의 크기가 제한을 초과합니다. +admin.setting.showFileSafe=파일 액세스 보안 +admin.setting.showFileLink=파일 외부 링크 표시 +admin.setting.showFileLinkDesc=닫은 후 파일 속성이 더 이상 외부 링크를 표시하지 않습니다. +admin.setting.showFileMd5=파일 md5 디스플레이 +admin.setting.showFileMd5Desc=닫은 후 파일 속성이 더 이상 파일 md5를 표시하지 않습니다. +admin.setting.shareLinkAllow=외부 링크 공유 활성화 +admin.setting.shareLinkAllowDesc=종료 후에는 더 이상 외부 체인 공유를 지원하지 않으며 공유 콘텐츠는 영향을 받지 않습니다. +admin.setting.shareLinkAllowTips=현재 시스템은 외부 링크 공유를 비활성화했습니다. 관리자에게 문의하십시오! +admin.setting.shareLinkPasswordAllowEmpty=외부 체인 공유를 통해 비밀번호를 비워둘 수 있습니다. +admin.setting.shareLinkPasswordAllowEmptyDesc=종료 후 외부 링크 공유를 위한 비밀번호를 설정해야 하며, 공유 콘텐츠는 영향을 받지 않습니다. +admin.setting.shareLinkAllowGuest=외부 링크 공유를 통해 로그인되지 않은 방문자가 액세스할 수 있습니다. +admin.setting.shareLinkAllowGuestDesc=종료 후 외부 링크에 액세스할 때 로그인해야 합니다. 공유 콘텐츠는 영향을 받지 않습니다. +admin.setting.shareLinkZip=외부 링크 공유 패키지 다운로드 +admin.setting.shareLinkZipDesc=오픈 후 외부 체인 공유 폴더는 패키징 및 압축 다운로드를 지원하며 동시성이 크면 서버 성능이 저하됩니다. +admin.setting.shareLinkZipTips=외부 링크 공유는 패키지 다운로드를 비활성화합니다. 구성을 위해 관리자에게 문의하십시오! +admin.setting.transferDownSpeed=다운로드 속도 제한 +admin.setting.transferDownSpeedDesc=다운로드 속도를 제한하고 대규모 동시 웹 사이트의 속도를 균일하게 제한 +admin.setting.transferDownSpeedNum=다운로드 속도 제한 +admin.setting.transferDownSpeedNumDesc=다운로드 속도를 제한하면 동시성이 큰 웹 사이트 속도를 균일하게 제한 할 수 있습니다.
    참고 : 서버 속도는 여기에서 제한되며 특정 다운로드 속도도 서버 대역폭 및 사용자 네트워크의 영향을받습니다. +explorer.uploadSizeError=귀하의 서버는 현재 2G 이상의 파일을 지원하지 않습니다.
    64 비트 PHP로 업그레이드하십시오; 64 비트 PHP7이 권장됩니다
    (참고 : 64 비트 운영 체제는 64 비트 PHP 만 설치할 수 있습니다); +common.----=---- +common.width=넓게 +common.height=높음 +common.test=테스트 +common.absolutePath=절대 주소 +common.qrcode=URL QR 코드 +common.wechat=위챗 +common.group=학과 +common.user=사용자 +common.online=온라인 +common.use=사용하려면 +common.total=합계 +common.year=년 +common.month=월 +common.week=주 +common.daytime=일 +common.mon=월요일에 +common.tue=화요일에 +common.wed=수요일에 +common.thu=목요일 +common.fri=금요일 +common.sat=토요일에 +common.sun=일요일 +common.second=둘째 +common.minute=분 +common.hour=시간 +common.day=일 +common.every=마다 +common.everyMonth=달마다 +common.everyWeek=주간 +common.everyDay=매일 +common.language=언어 +common.all=모두 +common.item=아이템 +common.items=품목 내용 +common.itemsEmpyt=콘텐츠 없음 +common.detail=세부 +common.me=나 +common.others=기타 +common.guest=방문객 +common.more=더 +common.learnMore=더 알아보기 +common.yes=예 +common.no=아니요 +common.omit=생략 +common.unknow=불명 +common.title=표제 +common.time=시각 +common.scan=검색 +common.report=보고서 +common.name=이름 +common.nickName=닉네임 +common.tools=도구 +common.tag=태그 +common.position=위치 +common.mount=네트워크 마운트 +common.type=타입 +common.auth=권위 +common.status=상태 +common.run=뛰다 +common.file=파일 +common.folder=폴더 +common.fileType=파일 타입 +common.fileSize=파일 크기 +common.attributeInfo=속성 정보 +common.actionType=작업 유형 +common.isDisplay=표시 여부 +common.hide=숨기기 +common.isHide=숨겨진 +common.cancelHide=숨기기 해제 +common.default=기본 +common.display=표시 +common.moveDown=아래로 이동 +common.moveUp=위로 이동 +common.drag=견인 +common.dragSort=순서를 조정하려면 드래그하세요. +common.warning=경고 +common.tips=힌트 +common.desc=지침 +common.tipsDesc=프롬프트 설명 +common.tipsOthers=기타 지침 +common.view=전망 +common.log=로그 +common.task=직무 +common.important=중요 +common.icon=아이콘 +common.menu=메뉴 +common.system=체계 +common.basic=만능인 +common.systemSet=시스템 구성 +common.systemDefault=시스템 기본값 +common.diy=관습 +common.input=입력 해주세요 +common.select=선택하세요 +common.add=추가 +common.edit=편집 +common.action=조작 +common.upload=업로드 +common.uploadTo=에 업로드 +common.download=다운로드 +common.export=수출 +common.cover=표지 +common.retry=재시도 +common.zip=압축 +common.unzip=압축 해제 +common.preview=미리보기 +common.share=공유 +common.search=검색 +common.query=문의 +common.delete=삭제 +common.deleteForce=완전히 제거 +common.deleteEnd=삭제됨 +common.refresh=새로 고침 +common.open=오픈 +common.close=닫기 +common.from=원천 +common.greater=보다 큼 +common.less=이하 +common.print=인쇄 +common.selectInvert=역 선거 +common.selectAll=모두 선택 / 역 선택 +common.selectAllItem=모두 선택 +common.selectNum=선정 +common.selectNull=전혀 +common.sizeMore=위 +common.showMore=펴다 +common.showLess=무너짐 +common.sizeSmall=작은 +common.sizeMiddle=에 +common.sizeBig=큰 +common.rename=이름 바꾸기 +common.method=기능 +common.extend=확장 +common.fav=좋아하는 +common.reset=리셋 +common.testing=테스팅 +common.install=설치 +common.update=업데이트 +common.version=버전 +common.sysVersion=플랫폼 버전 +common.login=로그인 +common.regist=가입 +common.password=비밀번호 +common.operateTime=운영 시간 +common.createTime=제작 시간 +common.modifyTime=수정 시간 +common.activeTime=보관 시간 +common.startTime=시작 시간 +common.endTime=종료 시간 +common.finishTime=종료 시간 +common.disable=비활성화 +common.goOn=계속 +common.ok=OK +common.startRun=시작 +common.confirmTips=다시 확인해주세요 +common.confirmAsk=이 작업을 수행하시겠습니까? +common.submit=제출 +common.skip=건너 뛰기 +common.nextStep=다음 단계 +common.start=시작 +common.stop=정지시키다 +common.set=설정 +common.cancel=취소 +common.save=저장 +common.empty=내용이 없습니다! +common.isOpen=켜짐 +common.isClose=닫은 +common.apply=신청 +common.saveAll=모두 저장 +common.notSave=저장하지 마십시오 +common.appAdd=추가 +common.backAdd=추가로 돌아 가기 +common.saveEdit=변경 사항 저장 +common.saveSubmit=커밋 저장 +common.saveAndAdd=저장하고 계속 추가 +common.sex=섹스 +common.male=말레 +common.female=여성 +common.address=주소 +common.email=이메일 +common.phone=핸드폰 +common.sms=SMS +common.phoneNumber=전화 번호 +common.server=서버 +common.handheld=휴대 기기 +common.success=성공 +common.fail=실패 +common.error=잘못 +common.result=결과 +common.expired=만료 +common.valid=효과적 +common.inAll=총 +common.allAndNull=모두 선택 / 취소 +common.moveTop=상단 +common.moveBottom=끝에 설정 +common.moveTopCancle=언 핑크 +common.ECN=동중국 +common.NCN=중국 북부 +common.SCN=중국 남부 +common.USA=북아메리카 +common.SEA=동남아시아 +common.noLimit=제한되지 않음 +common.notExists=존재하지 않습니다 +common.cannotWrite=쓰기 전용이 아닌 읽기 전용 +common.readOnly=읽기 전용 +common.cannotRead=읽을 수 없음 +common.ifDel=정말로 삭제 하시겠습니까? +common.pageNotExists=페이지가 존재하지 않습니다! +common.pathNotExists=문서가 존재하지 않습니다! +common.fileShare=문서 공유 +common.logining=로그인 중 ... +common.loginTokenError=로그인이 만료되었습니다. 다시 로그인하십시오! +common.loginSuccess=로그인 성공! +common.loginError=로그인 실패 +common.connectSuccess=성공적으로 연결되었습니다! +common.bindSuccess=성공적으로 바인딩! +common.bindError=바인드 실패 +common.clear=빈 +common.congrats=축하합니다, +common.sorry=미안 +common.invalid=무효 +common.unavailable=없는 +common.format=체재 +common.noPermission=권한이 거부되었습니다. +common.allPermission=모든 권한 +common.invalidParam=잘못된 매개 변수 +common.invalidFormat=잘못된 형식 +common.invalidRequest=잘못된 요청 유형 +common.illegalRequest=불법 요청 +common.expiredRequest=요청이 만료되었습니다 +common.errorExpiredRequest=잘못된 요청 또는 만료 +common.migrating=마이그레이션 +common.migrated=마이그레이션 완료 +common.maintenanceTips=시스템 유지 보수 중에는 나중에 방문하십시오 ... +common.done=완료 +common.disabled=장애인 +common.sizeTotal=총합 크기 +common.sqlStatement=[SQL 문] : +common.env.check=환경 테스트 +common.env.errorLib=PHP 라이브러리가 없습니다 +common.env.errorIgnore=무시하고 입력 +common.env.errorVersion=PHP 버전은 5.0보다 낮을 수 없습니다 +common.env.errorPath=쓸 수 없음 +common.env.errorListDir= +common.env.errorGd= +common.env.invalidExt +common.env.installWithBtTips= +common.env.phpCacheOpenTips= +common.env.dataPathNotExists=데이터 디렉토리가 존재하지 않습니다!
    (DATA_PATH 확인); +common.env.pathPermissionError=[오류 코드 : 1002] 디렉토리 권한 오류! 프로그램 디렉토리와 모든 하위 디렉토리를 읽고 쓰도록 설정하십시오.
    linux는 다음 명령을 실행합니다 :
     su -c 'setenforce 0' 
    chmod -R 777 +common.version.free=무료 +common.version.nameQ=엔터프라이즈 에디션 +common.version.vipFree=무료 판 +common.version.useFree=무료 버전을 계속 사용하십시오 +common.version.notSupport=사용중인 버전이이 작업을 지원하지 않습니다. 공식 웹 사이트로 이동하여 고급 버전을 구입하십시오! +common.version.notSupportNumber=이 작업은 제한된 수로 인해 지원되지 않습니다. 공식 웹 사이트로 이동하여 고급 버전을 구입하십시오! +common.version.toVip=상업용으로 업그레이드 +common.version.license=구매 승인 +common.version.authCode=인증 활성화 코드 +common.version.authActive=활성화 승인 +common.version.authorization=등록 승인 +common.version.authorizeSuccess=축하합니다. 온라인 업그레이드 승인이 완료되었습니다. +common.version.networkError=서버 요청 실패 서버가 네트워크에 액세스 할 수 있는지 확인하십시오.
    참고 : 서버는 인터넷에 액세스하기위한 프록시 일 수 없습니다 +common.version.authActiveOnline=온라인 활성화 +common.version.authActiveOffline=오프라인으로 활성화 +common.version.offlineTips=서버가 인터넷에 액세스 할 수 없습니까? +common.version.menuTitle=기업 정보 설정 +common.version.timeout=만료 +common.version.timeToService=서비스 만료 시간 +common.version.timeTo=승인 만료 시간 +common.version.licenseAll=영구 승인 +common.version.kodVersion=프로그램 버전 +common.version.userLimitTitle=사용자 번호 +common.version.userUse=익숙한 +common.version.userAllow=지원되는 사용자 수 +common.version.userTo=승인 된 개체 +common.version.userTitle=인증 정보 +common.version.basicInfo=기본 정보 +common.version.appInfo=상품 정보 +common.version.tipsWarning=경고, 허가없이 저작권을 수정하지 마십시오. 필요한 경우 구매 문의하십시오! +common.version.tipsCopyLink=성공적으로 복사했습니다! 붙여 넣어 txt 파일로 저장하십시오.
    USB 플래시 드라이브 등을 통해 네트워크가있는 컴퓨터에서이 링크를 엽니 다. +common.version.tipsHistory=무료 버전은 5개의 기록 버전만 지원하므로 라이선스 버전을 무제한으로 구입하세요! +common.version.codeLink=인증 코드 요청 링크 +common.version.codeLinkHelp=1. 위의 링크를 복사하여 인터넷에 연결된 다른 컴퓨터를 방문하십시오.
    2. 위에서 얻은 "인증 인증 코드"를 입력 한 다음 활성화하고 권한을 부여하십시오 +common.copyright.logoTitle=기업의 정체성 로고 세트 +common.copyright.licenseInfo=인증 정보 +common.copyright.licenseReset=재승 인 +common.copyright.licenseResetTips=자세한 내용은 다시 활성화하십시오! +common.copyright.formLogo=로그인 페이지 로고 유형 +common.copyright.formLogoTypeWord=텍스트 로고 +common.copyright.formLogoTypeImage=사진 로고 +common.copyright.formLogoDesc=텍스트 로고는 회사 이름을 사용하고 이미지 로고는 다음과 같이 설정된 사진을 사용합니다. +common.copyright.formLogoImage=로그인 페이지 로고 이미지 +common.copyright.formLogoImageDesc=로그인 페이지 및 관리 배경 로고, 권장 크기 250x100, 반투명 png 형식 +common.copyright.formLogoMain=메인 인터페이스 메뉴 로고 +common.copyright.formLogoMainDesc=파일 관리 왼쪽 상단 로고, 권장 크기 200x200, 흰색 반투명 PNG 형식 +common.copyright.formPowerByInfo=회사 저작권 정보 설정 +common.copyright.formPowerBy=하단 저작권 회사 이름 +common.copyright.formHomePage=하단 저작권 링크 점프 +common.copyright.formConcat=팝업 연락처 +common.copyright.formDesc=제품 팝업 레이어 자세한 설명 +common.copyright.formDescTips=수정 사항이 저장되면 새로 고침 페이지가 적용됩니다 +common.copyright.formMetaKeywords=사이트 키워드 (검색 엔진에서 사용) +common.copyright.formMetaName=사이트 이름 (검색 엔진에서 사용) +common.copyright.downloadApp=앱 다운로드 +common.copyright.downloadLink= +common.copyright.about=소개 +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=자동 식별 +common.charset.UTF_8=유니 코드 +common.charset.UTF_16=유니 코드 +common.charset.CP1256=아랍어 +common.charset.ISO_8859_6=아랍어 +common.charset.ISO_8859_10=북유럽 언어 +common.charset.CP1257=발트해 주변 언어 +common.charset.ISO_8859_13=발트해 주변 언어 +common.charset.ISO_8859_4=발트해 주변 언어 +common.charset.BIG5_HKSCS=홍콩 전통 +common.charset.BIG5=대만 전통 +common.charset.Georgian_Academy=그루지야 어 +common.charset.PT154=카자흐어 +common.charset.CP949=한국어 +common.charset.EUC_KR=한국어 +common.charset.GB18030=중국어 간체 +common.charset.GBK=중국어 간체 +common.charset.ISO_8859_14=셀틱 +common.charset.CP1133=라오 어 +common.charset.ISO_8859_16=루마니아어 +common.charset.ISO_8859_3=남유럽 언어 +common.charset.EUC_JP=일본어 +common.charset.ISO_2022_JP=일본어 +common.charset.SHIFT_JIS=일본어 +common.charset.KOI8_T=타직 +common.charset.ISO_8859_11=타이 +common.charset.TIS_620=타이 +common.charset.CP1254=터키어 +common.charset.CP1251=키릴 자모 +common.charset.ISO_8859_5=키릴 자모 +common.charset.KOI8_R=키릴 자모 +common.charset.KOI8_U=키릴 자모 +common.charset.CP1252=서유럽 언어 +common.charset.ISO_8859_1=서유럽 언어 +common.charset.ISO_8859_15=서유럽 언어 +common.charset.Macintosh=서유럽 언어 +common.charset.CP1255=히브리어 +common.charset.ISO_8859_8=히브리어 +common.charset.CP1253=그리스어 +common.charset.ISO_8859_7=그리스어 +common.charset.ARMSCII_8=아르메니아어 +common.charset.CP1258=베트남어 +common.charset.VISCII=베트남어 +common.charset.CP1250=중앙 유럽 언어 +common.charset.ISO_8859_2=중앙 유럽 언어 +common.charset.defaultSet=파일 인코딩 +common.charset.convertSave=로 변환 +common.date.near=바로 지금 +common.date.miniteBefore=몇 분 전 +common.date.today=오늘 +common.date.yestoday=어제 +common.date.before=~ 전에 +common.faceDefault=기본 이모티콘 +common.loadMore=더로드 +common.numberLimit=숫자가 최대 한도를 초과했습니다! +common.lengthLimit=길이가 최대 한도를 초과했습니다! +common.task.name=작업 관리자 +common.task.title=미션 이름 +common.task.user=이그제큐티브 사용자 +common.task.porcess=시간표 +common.task.start=작업 시작 +common.task.useTime=경과 시간 +common.task.running=실행 +common.task.stoping=일시 중지됨 +common.task.killing=종결 +common.task.stop=일시 중단 된 작업 +common.task.kill=작업 끝내기 +common.task.removeTips=이 작업을 끝내시겠습니까? +common.task.killAll=모두 종료 +common.task.killAllTips=모든 작업을 종료 하시겠습니까? +common.task.timeStart=에서 시작 +common.task.timeNeed=남은 +common.task.timeUse=이미 달리기 +ERROR_DB_PWD=데이터베이스 액세스 거부됨: 잘못된 사용자 이름 또는 비밀번호입니다. +ERROR_DB_TIMEOUT=데이터베이스 연결 시간이 초과되었습니다. 주소가 올바른지 확인하십시오. +ERROR_DB_CONN_RFS=데이터베이스 연결 거부됨: 잘못된 구성 정보 또는 서비스가 시작되지 않았습니다. +ERROR_DB_ADR=데이터베이스 연결 오류입니다. 주소가 올바른지 확인하십시오. +ERROR_DB_NOT_SUPPORT=지원되지 않는 데이터베이스 유형입니다. 해당 서비스 또는 구성 파일이 정상인지 확인하십시오. +ERROR_DB_XS_DENNIED=데이터베이스 액세스 거부됨: 권한이 충분하지 않습니다. +ERROR_DB_NOT_EXIST=데이터베이스가 존재하지 않거나 잘못된 이름이 지정되었습니다. +explorer.pathNotSupport=이 유형의 디렉토리는이 작업을 지원하지 않습니다! +explorer.pathIsRoot=루트 디렉토리에 도달했습니다! +explorer.pathNull=폴더가 비어 있습니다 +explorer.zipFileLarge=파일이 너무 큽니다. 미리보기 전에 압축을 해제하십시오! +explorer.charNoSupport=지원되지 않는 특수 문자 : +explorer.moveError=이동 실패 +explorer.lockError=오류가 발생했습니다. 동시 잠금 시간이 초과되었습니다. +explorer.lockErrorDesc=요청 빈도를 줄이거나 서버 동시성 관련 구성을 최적화하거나 서버 하드웨어 구성을 개선하십시오. +explorer.moveSubPathError=문제가 발생했습니다. 상위 디렉토리를 하위 디렉토리로 이동할 수 없습니다! +explorer.spaceIsFull=공간이 부족합니다. 관리자에게 문의하십시오! +explorer.sessionSaveError=세션 쓰기 실패 디스크가 꽉 찼는 지 확인하거나 서비스 제공 업체에 문의하십시오. +explorer.networkError=네트워크 연결 오류 (net :: ERR_CONNECTION_RESET), 연결이 재설정되었습니다.
    방화벽 구성을 확인하려면 호스트 회사 또는 네트워크 관리자에게 문의하십시오! +explorer.folderManage=관리 디렉토리 +explorer.clickEdit=클릭하여 수정 +explorer.shortLink=바로 가기 +explorer.upper=상층 +explorer.historyNext=사전 +explorer.historyBack=다시 +explorer.loading=작동 중 ... +explorer.getting=점점 ... +explorer.sending=데이터 전송 ... +explorer.pullTips=페이지를 새로 고치려면 풀다운 +explorer.pullDropTips=페이지 새로 고침 무료 +explorer.getSuccess=성공하십시오! +explorer.saveSuccess=성공적으로 저장되었습니다! +explorer.saveError=저장하지 못했습니다! +explorer.success=작업 성공 +explorer.error=작업 실패 +explorer.dataError=데이터가 비정상입니다! +explorer.pathError=문서 경로 오류 +explorer.repeatError=작업이 실패했습니다. 이름이 이미 존재합니다! +explorer.systemError=시스템 오류 +explorer.mistake=문제가 발생했습니다! +explorer.recycleClear=빈 휴지통 +explorer.recycleClearForce=휴지통에 내용물이 너무 많습니다. 먼저 휴지통을 비우십시오! +explorer.recycleRestore=휴지통 복원 +explorer.recycleRestoreItem=복원 +explorer.recycleRestoreAll=모두 복원 +explorer.recycleClearInfo=휴지통을 완전히 비우시겠습니까? +explorer.zipDownloadReady=압축 후 자동으로 다운로드하십시오. 잠시만 기다려주십시오 ... +explorer.removeItem=품목 내용 +explorer.uploading=업로드 중 +explorer.uploadTipsMore=파일이 너무 많으면 압축 후 업로드 한 다음 온라인 압축을 푸는 것이 좋습니다. +explorer.uploadingMove=병합 및 전송 ... +explorer.viewNewPage=새 페이지 미리보기 +explorer.unknowFileTitle=파일 열기 팁! +explorer.unknowFileTips=이 파일을 지원하는 앱이 없으면 다음을 수행 할 수 있습니다. +explorer.unknowAppTips=앱없이 : +explorer.unknowFileTry=시도 +explorer.unknowFileDown=파일 다운로드 +explorer.authFileDown=파일 다운로드 +explorer.authShare=공유 +explorer.usersShare=공유 +explorer.clipboard=클립 보드보기 +explorer.clipboardClear=빈 클립 보드 +explorer.fullScreen=전체 화면 +explorer.folderItem=아이템 +explorer.folderItemSelect=선정 +explorer.dbLoadAll=두 번 클릭하여 모두로드 ... +explorer.ziping=압축 ... +explorer.unziping=압축 풀기 ... +explorer.zipingTips=압축 작업을 기다려주십시오 ... +explorer.unzipingTips=압축 해제 작업을 기다려주십시오 ... +explorer.unzipRarTips=파일의 내용이 손상되었거나 파싱이 지원되지 않는 파일이므로 ZIP 형식을 사용하는 것을 권장합니다. +explorer.parsing=검색 중 ... +explorer.moving=이동 작업 ... +explorer.copyMove=이동 복사 +explorer.removeTitle=확인 삭제 +explorer.removeInfo=선택 사항을 삭제 하시겠습니까? +explorer.removeTitleForce=영원히 삭제 +explorer.removeInfoForce=이 문서를 완전히 삭제 하시겠습니까? +explorer.pathInRecycle=폴더가 휴지통에 있습니다. 복원하고 다시 시도하십시오! +explorer.pathInRecycleFile=파일이 휴지통에 있습니다. 복원하고 다시 시도하십시오! +explorer.downOffline=오프라인으로 다운로드 +explorer.savePath=경로 저장 +explorer.uploadSelectMuti=업로드 할 파일을 여러 개 선택하십시오 +explorer.goTo=로 이동 +explorer.selectFile=파일 선택 +explorer.selectFolder=폴더 선택 +explorer.selectImage=사진을 선택하십시오 ... +explorer.selectValidFolder=유효한 폴더를 선택하십시오! +explorer.selectFolderFile=파일 또는 폴더를 선택하십시오 +explorer.selectMulti=객관식 +explorer.notNull=필수 입력란은 비워 둘 수 없습니다! +explorer.picCannotNull=사진 주소는 비워 둘 수 없습니다! +explorer.renameSuccess=성공적으로 개명되었습니다! +explorer.inputSearchWords=검색 할 문자열을 입력하십시오 +explorer.search.optionContent=문서 내용 +explorer.search.searchContentTips=키워드 검색 파일 내용, 지원 텍스트 파일 +explorer.search.optionMutil=대량 검색 +explorer.search.optionMutilDesc=한 줄에 하나의 검색어, 검색어에 따라 검색 결과가 정렬됩니다. +explorer.removeSuccess=성공적으로 삭제되었습니다! +explorer.removeFail=삭제하지 못했습니다! +explorer.clipboardNull=클립 보드가 비어 있습니다! +explorer.createSuccess=새로운 성공! +explorer.createError=새로 생성하지 못했습니다. 디렉토리 권한을 확인하십시오! +explorer.copySuccess=[복사]-클립 보드 덮어 쓰기! +explorer.cuteSuccess=[컷]-클립 보드 덮어 쓰기! +explorer.clipboardState=클립 보드 상태 : +explorer.copyOK=성공적으로 복사되었습니다! +explorer.copyNotExists=소스가 존재하지 않습니다 +explorer.currentHasParent=대상 폴더는 소스 폴더의 하위 폴더입니다! +explorer.pastSuccess=붙여넣기 작업 완료 +explorer.cutePastSuccess=컷 작업 완료 +explorer.zipSuccess=압축 완료 +explorer.notZip=압축 파일이 아님 +explorer.zipNull=선택된 파일 또는 디렉토리가 없습니다 +explorer.unzipSuccess=압축 풀기 +explorer.pathIsCurrent=열린 경로는 현재 경로와 동일합니다! +explorer.pathExists=이름이 이미 존재합니다! +explorer.serverDownDesc=다운로드 목록에 추가 된 작업 +explorer.parentPermission=부모 디렉토리 권한 +explorer.confirm=확실합니까? +explorer.ifSaveFileTips=저장되지 않은 파일이 있습니까? +explorer.ifSaveFile=파일이 아직 저장되지 않았습니다. 저장 되었습니까? +explorer.ifStopUploadTips=파일을 업로드하는 중입니다. 창을 닫으시겠습니까? +explorer.noPermissionRead=읽기 권한이 없습니다! +explorer.noPermissionDownload=다운로드 권한이 없습니다! +explorer.noPermissionWrite=디렉토리에 쓰기 권한이 없습니다 +explorer.noPermissionAction=이 권한이 없으면 관리자에게 문의하십시오! +explorer.noPermissionWriteAll=파일 또는 디렉토리에 쓰기 권한이 없습니다 +explorer.noPermissionWriteFile=파일에 쓰기 권한이 없습니다 +explorer.noPermissionReadAll=파일 또는 디렉토리에 읽기 권한이 없습니다 +explorer.noPermission=관리자가이 권한을 비활성화했습니다! +explorer.noPermissionExt=관리자가이 유형의 파일 권한을 비활성화했습니다 +explorer.noPermissionGroup=이 사용자 그룹에 속하지 않습니다! +explorer.pathNoWrite=디렉토리가 쓰기 가능하지 않습니다. 디렉토리 및 모든 서브 디렉토리를 읽고 쓰고 다시 시도하도록 설정하십시오! +explorer.onlyReadDesc=이 디렉토리에는 쓰기 권한이 없습니다. 서버에서이 디렉토리에 대한 권한을 설정할 수 있습니다 +explorer.settingSuccess=수정 사항이 적용되었습니다! +explorer.noRepeat=중복 금지 +explorer.dataNotFull=데이터 제출이 완료되지 않았습니다! +explorer.tooManyToView=내용이 너무 많습니다 (%s 항목). 로컬로 열어서보십시오. +explorer.jumpAfterWhile=%ss 후 자동으로 점프, 즉시 점프 +explorer.retryTips=확인 후 다시 시도하십시오 +explorer.selectObject=객체 선택 +explorer.parentGroup=우수 부서 +explorer.actionAuth=운영 권한 +explorer.notSelectDesc=데이터가 없습니다. 선택하십시오! +explorer.groupAuthCopy=조합 복사 +explorer.groupAuthCopyDesc=권한 조합 복사 +explorer.groupAuthPasteDesc=복사 한 권한 조합 붙여 넣기 +explorer.groupAuthSave=즐겨 찾기에 저장 +explorer.groupAuthRecent=최근 사용 +explorer.selectDesc=내용 선택 +explorer.cannotLoad=결과를로드 할 수 없습니다. +explorer.loadMore=더 많은 결과로드 ... +explorer.noSearchData=결과가 없습니다 +explorer.delAllItem=모든 항목 삭제 +explorer.pleaseDel=삭제하십시오 +explorer.pleaseInput=적어도 입력하십시오 +explorer.canChoose=기껏해야 선택하십시오 +explorer.theChars=캐릭터 +explorer.theItems=아이템 +explorer.noData=아직 데이터가 없습니다 +explorer.ifPathAuthClear=모든 하위 파일 및 폴더 권한 설정이 지워집니다. 계속 하시겠습니까? +explorer.fileDescAdd=문서 설명 추가 +explorer.fileDesc=문서 설명 +explorer.fileLog=문서 로그 +explorer.ifResetOpen=모든 사용자 정의 열기 방법을 재설정 하시겠습니까? +explorer.ResetOpen=모든 사용자 정의 열기 방법 재설정 +explorer.openWith=다른 이름으로 열기 ... +explorer.openWithAce=에디터가 열립니다 +explorer.openWithLocal=로컬로 열기 +explorer.openWithLocalEdit=로컬 편집 +explorer.editorSaveTips=파일이 생성되지 않았습니다. 새 파일을 먼저 저장하십시오 +explorer.editor.fileTooBig=파일이 너무 커서 20M보다 클 수 없습니다 +explorer.errorFunctionTips=이 유형의 파일은 기능 목록을 지원하지 않습니다! +explorer.errorFormatTips=현재 파일 형식이 기본 형식화 방법과 일치하지 않습니다.
    수동으로 선택하십시오 +explorer.cuteToThe=이동 : +explorer.copyToThe=복사 : +explorer.addToFav=즐겨 찾기에 추가 +explorer.addFav=즐겨 찾기 추가 +explorer.delFav=수집 취소 +explorer.addFavSuccess=즐겨 찾기를 성공적으로 추가 +explorer.pathHasFaved=경로가 마음에 들었습니다 +explorer.delFavSuccess=수집 취소 +explorer.fileLock=잠금 수정 +explorer.fileLockNow=잠금 +explorer.fileLockCancle=터놓다 +explorer.fileLockTitle=잠김 +explorer.fileLockTips=잠김 (다른 사용자는 파일을 편집 할 수 없음) +explorer.fileLockUser=사물함 +explorer.fileLockError=현재 파일이 잠겨 있습니다. 보관함에 연락하여 잠금을 해제하고 다시 시도하십시오. +explorer.downloaded=다운로드 완료 +explorer.openAutoTips=자동으로 열립니다 +explorer.historyAutoTips=히스토리 버전 자동 생성 +explorer.saved=성공적으로 저장되었습니다 +explorer.opened=성공적으로 엽니 다! +explorer.openFail=열지 못했습니다! +explorer.openingWithLoc=파일이 로컬로 열려 있습니다 ... +explorer.openOnlyView=읽기 전용 모드가 켜져 있습니다. +explorer.saving=파일 저장 ... +explorer.notSupport=문제가 발생했습니다. 콘텐츠 형식이 지원되지 않습니다! +explorer.unzipErrorTips=문제가 발생했습니다! 인식 할 수없는 압축 파일 형식입니다.
    파일이 압축되었거나 손상되었는지 확인하십시오. +explorer.wordLoading=로딩 중 ... +explorer.noFunction=안돼! +explorer.paramFormatError=매개 변수 형식이 잘못되었습니다! +explorer.descTooLong=설명이 너무 깁니다 +explorer.noMoreThan=더 이상 +explorer.desktopDelError=데스크톱 폴더는 삭제를 지원하지 않습니다. +explorer.copy=복사 +explorer.past=붙여 넣기 +explorer.clone=사본 만들기 +explorer.cute=컷 +explorer.cuteTo=로 이동 ... +explorer.copyTo=복사 ... +explorer.info=속성 +explorer.searchInPath=폴더에서 검색 +explorer.addToPlay=재생 목록에 추가 +explorer.manageFav=즐겨 찾기 관리 +explorer.refreshTree=트리 디렉토리 새로 고침 +explorer.zip=압축 패키지 만들기 +explorer.unzip=압축 해제 ... +explorer.unzipFolder=폴더로 추출 +explorer.unzipThis=현재로 압축 해제 +explorer.unzipTo=압축 해제 ... +explorer.openProject=에디터 오픈 프로젝트 +explorer.createLink=바로 가기 만들기 +explorer.createLinkHome=바탕 화면 바로 가기로 보내기 +explorer.setBackground=바탕 화면 배경 무늬로 설정 +explorer.favRemove=이 컬렉션을 취소 +explorer.openPath=디렉토리로 이동 +explorer.openPathFinished=이미 디렉토리를 입력했습니다. +explorer.openIE=브라우저 열기 +explorer.newFile=새 파일 +explorer.newFolder=새 폴더 +explorer.fileSaveTo=에 저장된 파일 +explorer.openFather=상단 폴더 표시 +explorer.uploadFile=파일 업로드 +explorer.uploadFolder=폴더 업로드 +explorer.appOpenDefault=기본적으로 열리도록 설정 +explorer.appOpenAways=선택한 프로그램으로 항상이 파일을여십시오 +explorer.appSelectDesc=이 파일을 여는 데 사용할 프로그램을 선택하십시오 +explorer.appSelectMenu=기본 열기 모드로 설정 +explorer.appSelectMenuCancel=기본 열기로 설정 해제 +explorer.appSelectWarning=응용 프로그램을 선택하십시오! +explorer.appTypeSupport=지원 응용 +explorer.appTypeAll=모든 응용 +explorer.appSearch=관련 앱 설치 검색 +explorer.recent.createTime=에 만든 +explorer.recent.modifyTime=에 수정 +explorer.recent.viewTime=개점 +explorer.urlLink=외부 링크 주소 +explorer.downloading=다운로드 중 ... +explorer.downReady=출시 예정 +explorer.downError=다운로드 실패! +explorer.max=최대화 +explorer.min=최소화 +explorer.minAll=모두 최소화 +explorer.displayAll=모든 창 표시 +explorer.closeAll=모두 닫기 +explorer.authDtl=디렉토리에서 권한을 보려면 클릭하십시오. +explorer.authDialog=내부 구성원, 문서 협업 레벨 권한 테이블 +explorer.authNote=참고 : 관리 기능에는 멤버 권한 설정 / 댓글 관리 등이 포함됩니다.주의하십시오! [시스템 관리자] 역할은 권한에 의해 제한되지 않습니다 +explorer.auth.toOuter=외부 인증 (다른 부서 또는 사용자) +explorer.auth.share=공유자 +explorer.auth.owner=소유자 +explorer.auth.disableDeep=권한 액세스 만 없음 +explorer.auth.disableDeepDesc=요소 디렉토리에는 문서 읽기 및 쓰기 권한과 설정된 액세스 경로가 있습니다. +explorer.auth.tips=위 사용자에게 연락하여 권한을 설정할 수 있습니다 +explorer.notSystemPath=시스템 파일 경로가 아닙니다. +explorer.toolbar.rootPath=개인 공간 +explorer.toolbar.fav=즐겨 찾기 +explorer.toolbar.desktop=데스크탑 +explorer.toolbar.client=고객 +explorer.toolbar.myComputer=내 컴퓨터 +explorer.toolbar.recycle=휴지통 +explorer.toolbar.myDocument=내 문서 +explorer.toolbar.myPicture=내 사진 +explorer.toolbar.myMusic=내 음악 +explorer.toolbar.myMovie=내 비디오 +explorer.toolbar.myDownload=내 다운로드 +explorer.toolbar.uiDesktop=데스크탑 +explorer.toolbar.uiExplorer=파일 관리 +explorer.toolbar.uiEditor=편집자 +explorer.toolbar.uiProjectHome=프로젝트 홈 +explorer.toolbar.uiLogout=출구 +explorer.toolbar.uiGroup=조직 구조 +explorer.toolbar.myGroup=내 부서 +explorer.toolbar.publicPath=공공 디렉토리 +explorer.toolbar.recentDoc=최근 문서 +explorer.toolbar.myShare=내 몫 +explorer.toolbar.shareToMe=나와 협업 +explorer.toolbar.shareTo=내 협업 +explorer.toolbar.shareLink=외부 링크 공유 +explorer.toolbar.photo=사진 앨범 +explorer.photo.desc=사용자 앨범 분류 +explorer.photo.group=앨범 그룹화 +explorer.photo.setting=앨범 설정 +explorer.photo.pathRoot=앨범 스캔 디렉토리 +explorer.photo.pathRootSelect=앨범 이미지 스캔을 위한 루트 디렉토리로 폴더 선택 +explorer.photo.fileType=파일 형식 지정 +explorer.photo.fileSize=파일 크기 필터 +explorer.photo.fileSizeDesc=이 설정보다 큰 파일만 필터링, 0이면 제한 없음 +explorer.toolbar.folder=카탈로그 앨범 +explorer.toolbar.folderSelect=앨범 모드에서 표시할 폴더 선택 +explorer.pathDesc.fav=파일이 컬렉션에 추가된 후 빠르고 직접 액세스할 수 있습니다. +explorer.pathDesc.home=개인 공간은 개인 저장 공간이며, 나에게만 표시되고 다른 사용자에게는 표시되지 않습니다. +explorer.pathDesc.groupRoot=기업/단위의 공용 공간이며, 기본적으로 모든 구성원이 표시됩니다. +explorer.pathDesc.myGroup=여기에서 부서의 문서를 관리하고, 부서 문서는 이 부서의 구성원만 보고 조작할 수 있으며 다른 부서 구성원은 볼 수 없습니다. +explorer.pathDesc.group=부서 구성원만 볼 수 있는 부서 네트워크 디스크, 운영 권한은 부서 관리자가 할당 및 설정합니다. +explorer.pathDesc.recentDoc=최근에 생성, 업로드, 수정 및 연 파일 +explorer.pathDesc.shareTo=여기에서 다른 사람이 시작한 [내부 협업] 프로젝트를 보고 관리하세요. +explorer.pathDesc.shareLink=여기에서 귀하가 시작한 외부 체인 공유를 보고 관리하십시오. +explorer.pathDesc.recycle=여기에서 삭제된 파일(폴더)을 관리하세요. +explorer.pathDesc.fileType=유형별로 파일 분류, 개인 공간에 있는 파일만 +explorer.pathDesc.tag=파일(폴더)에 태그를 추가하여 효율적인 분류 및 빠른 쿼리 달성 +explorer.pathDesc.tagItem=파일/폴더에 레이블을 추가해 보세요! +explorer.pathDesc.mount=여기에서 여러 백엔드 스토리지와 서버에 탑재된 디스크를 관리할 수 있습니다. +explorer.pathDesc.shareToMe=타일 디스플레이--내가 공동 작업한 모든 콘텐츠 +explorer.pathDesc.shareToMeUser=공유자별 표시-내가 공동 작업한 콘텐츠는 개시자별로 분류됩니다. +explorer.pathDesc.shareToMeUserItem=이 사용자가 시작한 협업 +explorer.pathDesc.shareToMeGroup=내가 협업하는 콘텐츠는 폴더가 위치한 부서별로 분류됩니다. +explorer.pathDesc.shareToMeGroupGroup=부서의 네트워크 디스크에서 협업 공유 +explorer.pathDesc.search=파일/태그/메모/내용 검색 지원; 병음, 첫 글자의 퍼지 매칭 지원 +explorer.pathDesc.searchMore=더 많은 검색 조건 설정 +explorer.pathDesc.shareFrom=소스 경로 +explorer.pathGroup.shareGroup=부서 공간 +explorer.pathGroup.shareGroupDesc=하위 부서에 콘텐츠가 있을 때 접근 +explorer.pathGroup.shareUser=부서 구성원의 개인 공간 공유 +explorer.pathGroup.shareUserDesc=출처: 사용자 개인 공간 공유, 사용자가 시작한 외부 부서 문서 공유. +explorer.pathGroup.shareContent=부서의 공간 협업과 공유 +explorer.pathGroup.group=하위 부서 +explorer.pathGroup.groupContent=부서 문서 +explorer.pathGroup.shareUserOuter=외부 협업 공유 +explorer.pathGroup.shareUserOuterDesc=자신의 조직 구조에 속하지 않는 외부 사용자의 공동 공유 +explorer.pathGroup.shareSelf=개인 공간 +explorer.toolbar.fileSizeTitle=아이콘 크기 +explorer.toolbar.fileSizeSuper=초소형 +explorer.toolbar.fileSizeSmall=작은 아이콘 +explorer.toolbar.fileSizeDefault=중간 아이콘 +explorer.toolbar.fileSizeBig=큰 아이콘 +explorer.toolbar.fileSizeBigSuper=대형 아이콘 +explorer.toolbar.PagePC=PC 버전 +explorer.toolbar.pagePhone=모바일 버전 +explorer.file.name=이름 +explorer.file.type=타입 +explorer.file.contain=포함 +explorer.file.address=위치 +explorer.file.detil=설명 +explorer.file.linkCount=인용 +explorer.file.size=사이즈 +explorer.file.count=수량 +explorer.file.byte=바이트 +explorer.file.path=경로 +explorer.file.action=조작 +explorer.file.creator=제작자 +explorer.file.editor=수정 한 사람 +explorer.file.location=위치 +explorer.file.timeInfo=시간 정보 +explorer.file.createTime=제작 시간 +explorer.file.modifyTime=수정 시간 +explorer.file.lastTime=마지막 방문 +explorer.file.sortType=정렬 +explorer.file.sortDisable=콘텐츠가 지정된 정렬을 지원하지 않습니다! +explorer.file.timeType=Y / m / dH : i : s +explorer.file.timeTypeInfo=Y / m / dH : i : s +explorer.file.listType=보기 +explorer.file.listIcon=아이콘 배열 +explorer.file.listList=리스트 정렬 +explorer.file.listListSplit=열 모드 +explorer.file.listTypeGroup=표시 모드 및 정렬 방법 +explorer.file.listTypeKeep=디스플레이 모드 +explorer.file.listTypeKeepDesc=각 폴더에 대해 보기 모드를 선택하거나 모든 폴더에 대해 동일한 보기 모드를 사용합니다. +explorer.file.listSortKeep=정렬 기준 +explorer.file.listSortKeepDesc=각 폴더에 대해 열 정렬 순서를 구성하거나 모든 폴더에 동일한 순서를 사용합니다. +explorer.file.listViewKeep=단일 폴더에서 작동 +explorer.file.listViewAll=모든 폴더에 적용 +explorer.file.listViewReset=기본값으로 재설정 +explorer.file.sortUp=증가 +explorer.file.sortDown=감소 +explorer.file.orderType=정렬 +explorer.file.orderDesc=내림차순 +explorer.file.orderAsc=오름차순 +explorer.file.imageSize=사진 크기 +explorer.file.sharer=공유자 +explorer.file.shareTime=공유 시간 +explorer.file.viewCnt=방문수 +explorer.file.downCnt=다운로드 +explorer.file.readWriteLock=이 작업은 일시적으로 지원되지 않습니다. 처리중인 다른 읽기 및 쓰기 작업이 있습니다. 나중에 다시 시도하십시오! +explorer.app.app=가벼운 응용 +explorer.app.createLink=새 URL +explorer.app.create=가벼운 응용 프로그램 만들기 +explorer.app.edit=가벼운 앱 편집 +explorer.app.open=오픈 라이트 앱 +explorer.app.groupGame=게임 +explorer.app.groupTools=도구 +explorer.app.groupReader=읽기 +explorer.app.groupMovie=영화 +explorer.app.groupMusic=음악 +explorer.app.groupLife=생활 +explorer.app.desc=응용 프로그램 설명 +explorer.app.icon=응용 프로그램 아이콘 +explorer.app.iconShow=URL 주소 또는 디렉토리 +explorer.app.group=응용 프로그램 그룹화 +explorer.app.type=타입 +explorer.app.typeUrl=링크 +explorer.app.typeCode=JS 확장 +explorer.app.display=외관 +explorer.app.displayBorder=경계선 없음 (선택된 경계선 없음) +explorer.app.displaySize=크기 조정 (선택하여 조정) +explorer.app.size=사이즈 +explorer.app.url=링크 주소 +explorer.app.code=JS 코드 +explorer.app.appType=신청 유형 +explorer.app.website=URL +explorer.app.shortLink=파일 바로 가기 +explorer.app.imgIcon=사진 아이콘 +explorer.app.imgIconUrl=사진을 선택하거나 웹 사진 URL을 붙여 넣습니다. +explorer.app.path=경로 +explorer.app.pathDesc=수동 수정을 지원하지 않으면 파일을 마우스 오른쪽 버튼으로 클릭하여 바로 가기를 만들 수 있습니다 +explorer.app.link=URL 링크 +explorer.app.linkDesc=http / https 링크를 입력하십시오 +explorer.app.linkDragTips=URL 링크를 파일 영역으로 드래그하여 URL 링크를 자동으로 생성할 수 있습니다! +explorer.app.openType=열린 길 +explorer.app.openWindow=새창 +explorer.app.openDialog=대화 상자 +explorer.app.openCurrent=현재 페이지 +explorer.app.openInline=페이지 삽입 +explorer.app.dialogSize=대화 상자 크기 +explorer.app.with=폭 +explorer.app.height=높이 +explorer.app.moreSet=더 많은 설정 +explorer.app.canDiyWith=너비 조정 허용 +explorer.app.miniBlock=미니멀리스트 제목 표시 줄 +explorer.app.runCode=JS 코드 실행 +explorer.app.name=응용 프로그램 이름 +explorer.app.nameDesc=신청서 이름을 입력하십시오. +explorer.app.descDesc=응용 프로그램 설명을 입력하십시오 +explorer.embed.title=포함 된 파일 +explorer.embed.desc=웹 페이지 또는 블로그에 파일 포함 +explorer.embed.url=URL 삽입 +explorer.embed.code=코드 삽입 +explorer.upload.ready=업로드 대기 중 +explorer.upload.success=성공적으로 업로드되었습니다 +explorer.upload.secPassSuccess=몇 초 안에 성공 +explorer.upload.pathCurrent=현재 디렉토리로 변경 +explorer.upload.select=파일 선택 +explorer.upload.maxSize=최대 허용 +explorer.upload.sizeInfo=더 크게 구성하려면 php.ini에서 허용되는 최대 업로드를 수정하십시오. 파일을 선택할 때이 구성보다 큰 파일은 자동으로 필터링됩니다. +explorer.upload.error=업로드 실패 +explorer.upload.mergeError=파일 병합 실패 +explorer.upload.errorHttp=네트워크 또는 방화벽 오류 +explorer.upload.muti=다중 파일 업로드 +explorer.upload.drag=드래그 앤 드롭 업로드 +explorer.upload.dragFolder=업로드할 폴더로 드래그 앤 드롭 +explorer.upload.dragTips=업로드 출시! +explorer.upload.pathNotAllow=파일 이름이 허용되지 않습니다 +explorer.upload.errorNull=문서가 없습니다! +explorer.upload.errorBig=파일 크기가 서버 제한을 초과합니다 +explorer.upload.errorMove=파일을 이동하지 못했습니다! +explorer.upload.errorExists=파일이 이미 존재합니다 +explorer.upload.local=로컬로 업로드 +explorer.upload.tips=더 이상 php.ini에 의해 제한되지 않는 조각 업로드를 사용하십시오; 크롬 경험 폴더 드래그 앤 업로드를 권장합니다 +explorer.upload.exist=같은 이름의 파일 처리 +explorer.upload.clearAll=모두 지우기 +explorer.upload.clear=비우기 완료 +explorer.upload.addMore=대량으로 추가 +explorer.upload.errorEmpty=비워 둘 수 없습니다! +explorer.upload.errorExt=파일 확장자가 일치하지 않습니다! +explorer.upload.fileSizeDisable=동시에 업로드 / 전송 된 파일이 너무 많습니다. 조정하려면 관리자에게 문의하세요! +explorer.upload.moreDesc=(현재 권장되는 2000 이하) : +explorer.upload.scan=스캐닝 +explorer.upload.merge=병합 확인 +explorer.upload.needTime=남은 약. +explorer.upload.checkError=업로드 확인에 실패했습니다. 다시 시도하십시오 +explorer.upload.saveError=파일 정보를 저장하지 못했습니다 +explorer.upload.downloadDesc=http / https 네트워크 링크 만 지원 +explorer.table.first=홈 +explorer.table.last=마지막 페이지 +explorer.table.prev=이전 +explorer.table.next=다음 페이지 +explorer.table.one=총 1 페이지 +explorer.table.page=페이지 +explorer.table.itemPage=/페이지 +explorer.table.searchTotal=발견 +explorer.table.items=기록 +explorer.table.list=데이터리스트 +explorer.search.ing=검색 중 ... +explorer.search.result=검색 결과 +explorer.search.resultTooMore=검색 결과가 너무 많습니다. 다른 디렉토리 나 단어를 제안하십시오. +explorer.search.resultNull=검색 결과가 없습니다! +explorer.search.caseSensitive=대소 문자 구분 +explorer.search.content=파일 내용 검색 +explorer.search.extDesc=필터링 할 확장을 공백으로 구분하여 입력하십시오. +explorer.search.byItems=조건부 필터링 +explorer.search.extNull=무제한 유형 +explorer.search.extFile=모든 파일 +explorer.search.extDiy=맞춤 설정 +explorer.search.inputDesc=키워드를 입력하거나 필터를 제공하십시오! +explorer.search.path=디렉토리를 검색하십시오. +explorer.search.rootPath=루트 디렉토리를 검색하십시오. +explorer.search.range=검색 범위 +explorer.search.allFolder=모든 폴더 +explorer.search.currentFolder=현재 폴더 +explorer.search.ext=파일 타입 +explorer.search.timeRange=시간 범위 +explorer.search.timeAll=무제한 시간 +explorer.search.lastDay=거의 1 일 +explorer.search.lastWeek=지난 7 일 +explorer.search.lastMonth=지난 30 일 +explorer.search.lastYear=작년 +explorer.search.sizeAll=무제한 크기 +explorer.search.inputNullDesc=채워지지 않으면 특정 값보다 크거나 작은 것을 의미하며 10 진수 일 수 있습니다. +explorer.search.selectUser=사용자 선택 ... +explorer.search.byUserDesc=제작자 / 수정 자로 검색 +explorer.search.total=발견 +explorer.search.noResult=죄송합니다. 검색 결과가 없습니다. 다시 시도하십시오 +explorer.search.advance=고급 검색 +explorer.search.clear=명확한 내용 +explorer.history.list=파일 히스토리 +explorer.history.lastModify=마지막 수정 +explorer.history.modifyUser=수정 한 사람 +explorer.history.noHistory=역사적인 버전이 없습니다! +explorer.history.current=현재 버전 +explorer.history.detil=설명 +explorer.history.detilAdd=각인 추가 +explorer.history.uploadNew=새 버전 업로드 +explorer.history.diff=역사적 버전의 비교 +explorer.history.setCurrent=현재 버전으로 설정 +explorer.history.delCurrent=이 버전을 삭제 +explorer.history.delAll=모든 버전 기록 삭제 +explorer.history.ifDelAll=모든 기록을 삭제 하시겠습니까? +explorer.history.ifDelCurrent=이 버전을 삭제 하시겠습니까? +explorer.history.ifRollback=이 버전으로 롤백 하시겠습니까? +explorer.history.changeEvent=과거 버전 전환 +explorer.history.before=고정하기 전에 +explorer.history.after=수정 후 +explorer.recycle.clearUser=사용자의 휴지통 비우기 +explorer.recycle.restoreSelect=이 콘텐츠 복원 +explorer.recycle.moveTo=넘겨 +explorer.recycle.config=휴지통 설정 +explorer.recycle.configTitle=시스템 휴지통 설정 +explorer.recycle.configOpen=시스템 휴지통 열기 +explorer.recycle.configOpenDesc=오픈 제안 +explorer.recycle.configCloseInfo=콘텐츠 삭제시 시스템 휴지통에 들어 가지 않고 바로 삭제됩니다. +explorer.recycle.configOpenInfo= +explorer.recycle.configClear=완전 자동 삭제 +explorer.recycle.restoreConfirm=문서를 복원 하시겠습니까?
    복원 후 문서는 대상 루트 디렉토리로 이동됩니다. +explorer.recycle.moveConfirm=핸드 오버 확인 +explorer.recycle.moveSelectTarget=사용자 또는 부서 선택 +explorer.recycle.moveDesc=
  • 지정된 사용자 또는 부서로 넘기면 개체의 루트 디렉터리로 마이그레이션됩니다.
  • 인계 후에도 문서 설명, 교환 및 토론, 기록 버전 및 기타 정보는 계속 유지되며 공유 된 공동 작업 및 권한 정보는 제거됩니다.
  • +explorer.recycle.taskTitle=시스템 휴지통 청소 +explorer.recycle.taskDesc=저장 공간 확보를 위해 설정된 시간을 초과 한 휴지통 내용물을 자동으로 삭제 +explorer.share.add=공유 추가 +explorer.share.edit=공유 편집 +explorer.share.remove=공유 취소 +explorer.share.path=공유 경로 +explorer.share.source=자원 공유 +explorer.share.name=제목 공유 +explorer.share.nameDesc=기본적으로 파일 이름 공유, 사용자 정의 가능 +explorer.share.time=만료 시간 +explorer.share.timeLimit=제한된 시간 +explorer.share.timeLimitDesc=전원을 켜고 설정 한 후 시간이 초과되면 공유가 자동으로 비활성화됩니다 +explorer.share.timeDesc=비어 있으면 설정되지 않음 +explorer.share.pwd=비밀번호 추출 +explorer.share.pwdDesc=비밀번호가 설정되지 않았습니다 +explorer.share.randomPwd=무작위로 생성 +explorer.share.randomPwdDesc=더 비밀스럽고 안전한 암호를 추출해야만 볼 수 있습니다. +explorer.share.cancel=공유 취소 +explorer.share.create=공개 링크 만들기 +explorer.share.url=공유 주소 +explorer.share.noDown=다운로드 금지 +explorer.share.codeRead=코드 판독 +explorer.share.configSave=구성 저장 +explorer.share.errorParam=파라미터 에러! +explorer.share.errorUser=사용자 정보가 잘못되었습니다! +explorer.share.errorSid=공유가 존재하지 않습니다! +explorer.share.errorTime=늦었습니다.이 공유는 만료되었습니다! +explorer.share.errorPath=공유 파일이 존재하지 않습니다. 삭제 또는 이동되었습니다! +explorer.share.errorPwd=비밀번호가 잘못되었습니다! +explorer.share.errorShowTips=이 형식의 파일은 미리보기를 지원하지 않습니다! +explorer.share.expiredTips=죄송합니다.이 공유가 만료되었습니다. 공유자에게 문의하십시오! +explorer.share.downExceedTips=공유 다운로드가 공유자가 설정 한 한도를 초과했습니다. +explorer.share.store=SkyDrive에 저장 +explorer.share.loginTips=죄송합니다.이 공유에 액세스하려면 사용자로 로그인해야합니다! +explorer.share.noDownTips=죄송합니다. 공유자가 다운로드를 비활성화했습니다! +explorer.share.noViewTips=죄송합니다.이 공유자가 미리보기를 사용 중지했습니다! +explorer.share.noUploadTips=죄송합니다.이 공유자가 업로드를 사용할 수 없습니다! +explorer.share.needPwd=이 공유에는 비밀번호가 필요합니다 +explorer.share.notExist=공유가 존재하지 않습니다! +explorer.share.viewNum=찾아보기 : +explorer.share.downNum=다운로드 +explorer.share.openPage=공유 페이지 열기 +explorer.share.openLink=공개 공유 링크 +explorer.share.copyLink=공유 정보 복사 +explorer.share.link=공유 링크 : +explorer.share.accessPwd=액세스 비밀번호 : +explorer.share.copied=복사 +explorer.share.actionNotSupport=콘텐츠 공유,이 작업은 지원되지 않습니다 +explorer.share.errorPathTips=공유 링크가 잘못되었거나 공유자가 외부 링크 공유를 취소했습니다 +explorer.share.shareTo=공동 작업 공유 +explorer.share.shareToTarget=협력회원 +explorer.share.innerTo=내부 협업 +explorer.share.linkTo=외부 링크 공유 +explorer.share.selectTarget=협업 공유를 위해 부서 또는 사용자를 선택하십시오 +explorer.share.afterShareDesc=상대방 또는 소속 된 부서와 공유 한 후 사용자는 [공유]에서이를 볼 수 있습니다. +explorer.share.openOuterLink=외부 체인 공유 열기 +explorer.share.openOuterLinkDesc=외부 링크를 만든 후에는 이메일 또는 QQ를 통해 다른 사람에게 보낼 수 있습니다. +explorer.share.outerLink=링크 공유 +explorer.share.advanceSet=고급 구성 +explorer.share.loginLimit=로그인 한 사용자 만 사용 가능 +explorer.share.loginLimitDesc=개봉 후에는 내부 회원 만 액세스 할 수 있습니다. +explorer.share.authLimit=권리와 제한 +explorer.share.canUpload=업로드 허용 +explorer.share.notView=미리보기 비활성화 +explorer.share.notDown=다운로드 비활성화 +explorer.share.downNumLimit=다운로드 한도 +explorer.share.downNumLimitDesc=이 횟수가 지나면 공유 링크가 자동으로 만료됩니다. +explorer.share.learnAuth=문서 협업 권한 이해 +explorer.share.shareToRemove=이 공동 작업 공유를 취소 하시겠습니까?
    공유 한 대상 사용자는 더 이상 공동 공유를 볼 수 없습니다! +explorer.share.shareLinkRemove=외부 링크 공유를 취소 하시겠습니까?
    취소 후에는 외부 링크가 무효화됩니다! +explorer.share.shareToCopy=액세스 경로 복사 +explorer.share.shareToCopyDesc=링크는 공동 작업자에게 전송되고 빠르게 공동 작업에 들어갈 수 있습니다. +explorer.share.specifyAuthTips=위의 지정된 사용자 외에 +explorer.share.specifyAuthDesc=지정이용자권한> 지정이용자의 부서권한> 타인권한 +explorer.share.selfAuthDesc=자신의 권한을 수정할 수 없으며 다른 관리자가 설정할 수 있습니다 +explorer.share.authTypeDesc=기본적으로 상위 폴더에서 권한 상속 +explorer.share.rootPathAuthDesc=루트 부서 지원 사용자 및 부서 선택 +explorer.share.subPathAuthDesc=하위 부서, 부서의 일부만 선택 +explorer.share.myAuth=내 권한 +explorer.share.othersAuth=다른 권한 +explorer.share.keepAuth=원래 권한 유지 +explorer.share.specifyAuth=권한 지정 +explorer.share.userAuth=사용자 권리 +explorer.share.specifyUserAuth=사용자 권한 지정 +explorer.share.rptTitle=불법적이고 유해한 정보를 발견 한 경우 아래 사유를 선택하여 신고 해주십시오. +explorer.share.illegal=불법 정보 +explorer.share.inputRptDesc=신고 이유를 입력하세요 +explorer.share.rptSend=제출이 성공하면 관리자가 제때 처리합니다. +explorer.share.rptSended=보고서가 제출되었으며 관리자가 처리 할 때까지 기다립니다. +explorer.auth.mutil=일괄 적으로 권한 설정 +explorer.auth.mutilTips=참고 : 선택한 콘텐츠에 이미 권한이있는 경우 덮어 씁니다. +explorer.auth.mutilDesc=후속 기본 권한과 동시에 +explorer.auth.showMore=권한 세부정보 +explorer.auth.tabUser=부서원 +explorer.auth.tabChildren=하위 폴더 권한 +explorer.auth.tabUserTips=부서 구성원의 초기 권한 +explorer.auth.tabChildrenTips=이 폴더에 권한이 설정된 콘텐츠 +explorer.auth.resetUser=이 사용자 권한 설정 무시 +explorer.auth.resetUserBtn=권한 무시 +explorer.auth.resetUserBtnTips=이 폴더의 사용자 및 모든 하위 폴더(폴더) 권한 무시 +explorer.auth.resetUserHeader=하위 폴더에는 사용자의 권한을 지정하는 콘텐츠가 포함되어 있으며 모든 재정의를 위의 권한으로 설정합니다. +explorer.auth.resetUserContiner=사용자 권한의 내용을 포함합니다. +explorer.auth.resetUserEmpty1=이 사용자에 대해 권한이 설정된 콘텐츠가 없으므로 재정의할 필요가 없습니다. +explorer.auth.resetUserEmpty2=모든 하위 콘텐츠는 현재 수준 폴더 권한을 상속합니다. +explorer.rename.mutil=배치 이름 바꾸기 +explorer.rename.nameBefore=원본 파일 이름 +explorer.rename.nameTo=개명 +explorer.rename.start=지금 이름 바꾸기 +explorer.rename.clearFinished=비우기 완료 +explorer.rename.clearAll=모두 지우기 +explorer.rename.typeReplaceAll=모두 교체 +explorer.rename.typePrepend=전에 추가 +explorer.rename.typeAppend=나중에 추가 +explorer.rename.typeReplace=찾아 교체 +explorer.rename.typeChangeCase=사례 변환 +explorer.rename.typeRemove=문자 삭제 +explorer.rename.typeReplaceSet=일괄 적으로 교체 지정 +explorer.rename.typeReplaceSetDesc=같으면 교체하십시오. 각 행은 공백으로 구분되며 파일 이름은 공백을 허용하지 않습니다. 예 : +explorer.rename.numberStart=Offset +explorer.rename.appendContent=추가 내용 +explorer.rename.find=찾기 +explorer.rename.replaceTo=로 교체 +explorer.rename.caseUpperFirst=초기 자본 +explorer.rename.caseUpper=모든 캡 +explorer.rename.caseLower=모든 소문자 +explorer.rename.removeStart=처음부터 제거 +explorer.rename.removeEnd=끝에서 제거 +explorer.rename.chars=캐릭터 +explorer.editor.beautifyCode=코드 포맷 +explorer.editor.convertCase=사례 변환 +explorer.editor.convertUpperCase=대문자로 변환 +explorer.editor.convertLowerCase=소문자로 변환 +explorer.editor.currentTime=현재 시간 +explorer.editor.md5=md5 암호화 +explorer.editor.qrcode=문자열 QR 코드 +explorer.editor.regx=정규식 시험 +explorer.editor.chinese=단순화 된 변환 +explorer.editor.chineseSimple=중국어 간체로 변환 +explorer.editor.chineseTraditional=중국어 번체로 변환 +explorer.editor.base64=base64 코덱 +explorer.editor.base64Encode=base64 인코딩 +explorer.editor.base64Decode=base64 디코딩 +explorer.editor.url=URL 코덱 +explorer.editor.urlEncode=URL 인코딩 +explorer.editor.urlDecode=URL 디코딩 +explorer.editor.unicode=유니 코드 코덱 +explorer.editor.unicodeEncode=유니 코드 인코딩 +explorer.editor.unicodeDecode=유니 코드 디코딩 +explorer.editor.toolsSelectTips=처리 할 올바른 콘텐츠를 선택하십시오! +explorer.editor.toolsRandString=32 비트 임의 문자열 생성 +explorer.editor.textEncode=텍스트 인코딩 / 디코딩 +explorer.editor.textParse=텍스트 처리 +explorer.editor.timeShow=시간에 대한 타임 스탬프 +explorer.editor.timeInt=타임 스탬프 시간 +explorer.editor.lineRemoveEmpty=빈 줄 제거 (공백 포함) +explorer.editor.lineUnoin=중복 행 제거 +explorer.editor.lineTrim=선행 및 후행 공백 제거 +explorer.editor.lineSort=행별 정렬 (오름차순) +explorer.editor.lineReverse=모든 줄을 위아래로 바꿉니다. +explorer.editor.lineSum=합집합 +explorer.editor.lineAverage=평균값 +explorer.editor.calc=무료 계산기 +explorer.editor.goToLine=줄로 이동 +explorer.editor.keyboardType=키보드 모드 +explorer.editor.fontFamily=폰트 +explorer.editor.codeMode=구문 강조 +explorer.editor.closeAll=모두 닫기 +explorer.editor.closeLeft=왼쪽 탭 닫기 +explorer.editor.closeRight=오른쪽 탭 닫기 +explorer.editor.closeOthers=다른 닫기 +explorer.editor.wordwrap=워드 랩 +explorer.editor.showGutter=줄 번호 표시 +explorer.editor.charAllDisplay=보이지 않는 문자 표시 +explorer.editor.autoComplete=자동 프롬프트 +explorer.editor.autoSave=자동 저장 +explorer.editor.functionList=기능 목록 +explorer.editor.codeTheme=코드 스타일 +explorer.editor.fontSize=폰트 사이즈 +explorer.editor.completeCurrent=자동 완성 전류 +explorer.editor.createProject=에디터 프로젝트에 추가 +explorer.editor.markdownContent=컨텐츠 디렉토리 +explorer.editor.undo=취소 +explorer.editor.redo=해지 방지 +explorer.editor.shortcut=바로 가기 +explorer.editor.replace=교체 +explorer.editor.reload=새로 고침 +explorer.editor.view=보기 +explorer.editor.tools=도구 +explorer.editor.help=도움말 +explorer.sync.data=데이터 동기화 +explorer.sync.openLoc=로컬 디렉토리를 엽니 다 +explorer.sync.syncing=동기화 +explorer.sync.synced=동기화 완료 +explorer.sync.syncedError=에러 로그 +explorer.sync.syncStart=동기화 시작 +explorer.sync.syncStop=동기화 중지 +explorer.sync.notOpenTips=로컬 동기화를 설정하지 않았습니다 +explorer.sync.setNow=지금 동기화 설정 +explorer.sync.error=업로드 실패 +explorer.sync.success=성공적인 동기화 +explorer.sync.statusScan=스캐닝 +explorer.sync.statusNone=동기화가 구성되지 않았습니다 +explorer.sync.statusScanEnd=스캔 완료 +explorer.sync.statusDoing=동기화 +explorer.sync.statusDone=동기화 완료 +explorer.sync.statusStop=일시 중지 +explorer.sync.clearCacheSuccess=캐시 지우기 성공! +explorer.sync.emptyTask=동기화 작업이 없습니다 +explorer.sync.openCloud=열린 구름 위치 +explorer.sync.openLocal=로컬로 열기 +explorer.sync.statusFiles=문서 진행 +explorer.sync.statusLastTime=완료 시간 +explorer.sync.configName=설정 동기화 +explorer.sync.configClient=클라이언트 설정 +explorer.sync.configAbout=소개 +explorer.sync.configSyncFrom=로컬 경로 +explorer.sync.configSyncFromDesc=동기화 할 로컬 폴더를 선택하십시오. +explorer.sync.configSyncTo=동기화 +explorer.sync.configSyncToDesc=서버 위치와 동기화 +explorer.sync.configIgnore=무시 된 파일 형식 +explorer.sync.configIgnoreDesc=이 유형의 파일은 동기화되지 않습니다 +explorer.sync.autorun=자기 시작 +explorer.sync.configThread=동시 스레드 수 +explorer.sync.configThreadDesc=동시에 업로드 된 파일 수 +explorer.sync.configDownloadPath=다운로드 경로 +explorer.sync.configDownloadPathDesc=파일 폴더를 다운로드 할 때 기본 다운로드 경로 +explorer.sync.configClearCacheAuto=캐시 자동 지우기 +explorer.sync.configClearCacheAutoDesc=N 일 전 캐시 파일 자동 지우기 +explorer.sync.configClearCache=캐시 지우기 +explorer.sync.configChangeSite=현재 사이트를 종료 +explorer.sync.configVersion=현재 버전 +explorer.sync.configUpdateDesc=업데이트 지침 +explorer.sync.configUpdateCheck=업데이트 감지 +explorer.sync.confirmReset=디렉토리 수정 동기화, 동기화 정보가 재설정됩니다. 저장 하시겠습니까? +explorer.sync.listClearDone=비우기 완료 +explorer.sync.listClearError=오류 목록 지우기 +explorer.sync.listRetryAll=모두 다시 시도 +explorer.async.tipsDisablePath=경로 동기화 선택을 지원하지 않습니다 +explorer.async.tipsIsMoving=많은 양의 컨텐츠가 현재 동기화 된 디렉토리로 이동되거나 복사되고 있음을 감지했습니다.
    로컬 완료 후 동기화를 위해 페이지를 새로 고치는 것이 좋습니다. +explorer.async.tipsStartUser=수동으로 동기화 시작 +explorer.download.title=다운로드 관리 +explorer.download.waiting=기다리는 +explorer.download.stop=다운로드 일시 중지 +explorer.download.start=다운로드를 시작하다 +explorer.download.remove=할 일 제거 +explorer.download.stopAll=모두 일시 중지 +explorer.download.startAll=모두 계속 +explorer.download.clearAll=모든 작업 지우기 +explorer.download.doing=처리 +explorer.download.done=다운로드 완료 +explorer.download.clearAllTips=모든 다운로드 작업을 삭제 하시겠습니까? +explorer.tag.name=파일 태그 +explorer.tag.edit=라벨 관리 +explorer.tag.add=라벨 만들기 +explorer.tag.remove=이 태그를 삭제하시겠습니까? +explorer.tag.inputHolder=라벨 이름을 입력하십시오 +explorer.tag.addTo=라벨 설정 +explorer.tag.default1=배우다 +explorer.tag.default2=테스트 데이터 +explorer.tag.default3=계약 +explorer.tag.filter=라벨로 필터링 +explorer.groupTag.title=공개 레이블 +explorer.groupTag.menuTtitle=부서 공개 레이블 +explorer.groupTag.titleDesc=부서 내 공공 레이블 +explorer.groupTag.empty=부서 관리자가 공개 라벨을 설정하면 자동으로 활성화되며, 라벨 내용이 없을 경우 공개 라벨은 자동으로 꺼집니다! +explorer.tag.pathDesc=개인 레이블로 필터링 +explorer.groupTag.pathDesc=부서 공개 레이블로 필터링 +explorer.groupTag.removeTypeTips=이 그룹을 삭제하시겠습니까? 삭제 후 레이블과 연결된 모든 문서가 제거됩니다. +explorer.groupTag.removeTagTips=태그를 삭제하시겠습니까? 태그와 연결된 문서는 삭제 후 제거됩니다! +explorer.groupTag.typeAdd=카테고리 추가 +explorer.groupTag.typeName=카테고리 이름 +explorer.groupTag.addDesc=태그 추가 후 부서 태그는 자동으로 활성화되며, 최대 태그 수는 1000개입니다. +explorer.panel.info=속성 +explorer.panel.version=버전 +explorer.panel.chat=논의하다 +explorer.panel.log=동적 +explorer.panel.meta=메타 데이터 +explorer.panel.chatName=교류 토론 +explorer.panel.chat.send=보내다 +explorer.panel.chat.noAuth=이 문서에 대해 의견을 말할 권한이 없습니다! +explorer.panel.chat.placeholder=보내려면 [Enter]를 입력하고 [Ctrl + Enter] 줄 바꿈 +explorer.panel.chat.placeholderCtrl=여기에 입력하고, 보내려면 Ctrl + Enter, 줄 바꿈하려면 Enter를 누르세요. +explorer.panel.chat.reply=댓글 +explorer.panel.chat.empty=코멘트가 없습니다 +explorer.panel.chat.sendTo=앞으로 +explorer.panel.metaName=메타 데이터 확장 +explorer.panel.metaDesc=확장 된 문서 필드 속성 +explorer.panel.thumbClear=썸네일 지우기 +explorer.panel.thumbClearDesc=파일 썸네일을 지우고 표지 아트를 재생성하십시오. +explorer.panel.historyName=역사적인 버전 +explorer.panel.historyDesc=릴리즈 노트 +explorer.panel.infoTips=자세한 속성을 보려면 파일 (폴더)을 선택하십시오 +explorer.panel.info.space=공간 용량 +explorer.panel.info.groupAt=부서 위치 +explorer.panel.info.tagEmpty=태그가 없으며 설정을 클릭하십시오. +explorer.panel.logName=문서 뉴스 +explorer.panel.logEmpty=활동 없음 +explorer.type.doc=문서 +explorer.type.image=영상 +explorer.type.music=음악 +explorer.type.movie=비디오 +explorer.type.zip=보관 +explorer.type.others=다른 +explorer.secret.title=문서비밀관리 +explorer.secret.isOpen=활성화 여부 +explorer.secret.isOpenDesc=보안 수준 관리 활성화 및 비활성화 +explorer.secret.setUser=비밀 관리자 +explorer.secret.setUserDesc=기밀 수준을 설정할 수 있는 사용자 지정(동시에 해당 부서의 소유자여야 함) +explorer.secret.type=분류 유형 +explorer.secret.add=보안 수준 추가 +explorer.secret.edit=보안 수준 수정 +explorer.secret.name=클래스 이름 +explorer.secret.style=스타일 +explorer.secret.auth=비밀 수준 권한 +explorer.secret.authHas=기밀 권한에는 다음이 포함됩니다. +explorer.secret.createUser=세터 +explorer.secret.folderAt=기밀 폴더 +explorer.secret.tips=권한은 비밀 수준에 의해 제어되며 비밀 수준 권한은 문서 권한보다 높습니다. +explorer.secret.tips1=부서별 네트워크 디스크에 있는 콘텐츠에 대해서만 위에서 언급한 지정된 사용자가 기밀 수준을 설정할 수 있습니다(동시에 폴더 소유자여야 함). +explorer.secret.tips2=기밀 수준이 있는 폴더의 하위 레이어에 있는 모든 콘텐츠가 설정되며 이 권한이 가장 높은 권한입니다. +explorer.secret.tips3=설정 후 비밀 수준 권한이 문서 권한보다 높습니다(문서도 비밀 수준 권한으로 제어되며 시스템 최고 관리자는 이 제한이 적용되지 않으며 비밀 수준 설정자는 이 제한이 적용되지 않음). +explorer.secret.tips4=기밀 수준 권한: "부서 및 구성원 관리--문서 권한 관리"에서 추가할 수 있으며 숨김으로 설정할 수 있습니다. +user.----=---- +user.displayHideFile=숨겨진 파일 표시 +user.displayHideFileDesc=숨겨진 파일 : 시작 파일 및 시스템 배경에 숨겨진 파일 이름 설정; 숨겨진 파일은 열면 표시됩니다 +user.soundOpen=소리 켜기 +user.animateOpen=애니메이션 시작 +user.recycleOpen=휴지통 열기 +user.recycleDesc=열면 삭제가 휴지통으로 이동하므로 열 것을 권장합니다 +user.animateDesc=창 열기와 같은 애니메이션, 작업이 부드럽 지 않은 경우 닫기를 고려할 수 있습니다. +user.soundDesc=파일 열기, 파일 삭제, 휴지통 비우기 등 +user.thumbOpen=사진 섬네일 열기 +user.thumbDesc=개봉 후 더 나은 사진 탐색 경험 +user.fileSelect=파일 열기 아이콘 +user.fileSelectDesc=파일 아이콘을 마우스 왼쪽 버튼으로 클릭하고 오른쪽 클릭 메뉴의 바로 가기 항목 +user.fileShowDesc=폴더 소개 표시 +user.fileShowDescTips=아이콘 전용 모드 +user.fileOpenClick=다음과 같이 파일(폴더)을 엽니다. +user.fileOpenClick.dbclick=더블 클릭으로 열기 +user.fileOpenClick.click=클릭하여 열기 +user.viewSetting=옵션 표시 +user.thirdAccount=타사 계정 +user.bindAccount=계정 바인드 +user.thirdBindFirst=계정이 바인딩되지 않았습니다. 바인딩 후 사용하십시오 +user.account=계좌 번호 +user.bind=바인드 +user.unbind=풀다 +user.binded=바운드 +user.clickBind=바인드 클릭 +user.clickToBind=언 바운드, 바인딩 클릭 +user.clickEditPwd=비밀번호 수정을 클릭하십시오. +user.userAvatar=프로필 사진 +user.userNickName=개인 별명 +user.userAccount=개인 계정 +user.uploadAvatar=아바타 업로드 +user.userAvatarCrop=아바타로 적합한 지역을 선택하세요 +user.userAvatarExt=JPG, JPEG, PNG 이미지 형식 만 지원 +user.resetPwdDesc=비밀번호를 잊었습니까? +user.inputEmailCode=이메일 인증 코드를 입력하십시오 +user.inputSmsCode=SMS 인증 코드를 입력하십시오 +user.emailVerifyDesc=일부 비즈니스는 이메일 확인이 필요합니다 +user.phoneVerifyDesc=일부 비즈니스는 휴대 전화 확인이 필요합니다 +user.bindOthers=다른 계정에 이미 연결되어 있음 +user.notBind=아직 묶이지 않은 +user.regist=사용자 등록 +user.notRegist=미등록 +user.registed=이미 등록 +user.signError=콜백 서명이 잘못되었습니다 +user.repeat=반복 +user.noRepeat=반복 할 수 없다 +user.newPwd=새로운 비밀번호 +user.unAuthFile=무단 파일 액세스 +user.unbindWarning=바인딩을 해제하기 전에 비밀번호를 변경하십시오. 그렇지 않으면 계정이 제대로 작동하지 않습니다 +user.isLoginTips=현재 로그인되어 있습니다! +user.isLoginEnter=지금 입력하세요 +user.ifUnbind=바인드 해제 하시겠습니까? +user.bindFirst=이메일 또는 휴대폰 번호를 먼저 묶으십시오 +user.inputNewPwd=새 비밀번호를 입력하십시오 +user.inputNewValue=새로운 내용을 작성하십시오 +user.guestLogin=관광 로그인 +user.name=로그인 계정 +user.nickName=사용자 닉네임 +user.code=인증 코드 +user.codeError=인증 코드 오류 +user.imgCode=Captcha +user.rootPwd=관리자 비밀번호 설정 +user.rootPwdRepeat=비밀번호를 다시 확인하십시오 +user.rootPwdEqual=비밀번호가 두 번 일치하지 않습니다! +user.rootPwdTips=관리자 비밀번호를 설정하십시오! +user.pwdError=사용자 이름 또는 비밀번호가 잘못되었습니다! +user.pwdNotNull=비밀번호는 비워 둘 수 없습니다! +user.oldPwdError=원래 비밀번호가 잘못되었습니다! +user.keepPwd=비밀번호 기억 +user.forgetPwd=비밀번호를 잊어 버렸습니다 +user.directLogin=이미 로그인 +user.moreLogin=더 많은 로그인 방법 +user.loginNow=지금 로그인 +user.registNow=지금 가입하십시오 +user.backHome=집으로 돌아 가기 +user.ifHasAccount=이미 계정이 있습니까? +user.userEnabled=계정이 비활성화되었거나 아직 활성화되지 않았습니다! 관리자에게 문의하십시오 +user.roleError=권한 그룹이 없습니다. 관리자에게 문의하십시오 +user.invalidEmail=유효한 이메일 주소가 없습니다. 수정하려면 관리자에게 문의하십시오. +user.codeRefresh=새로 고침을 클릭하십시오. +user.emailVerify=사서함 인증 +user.sendSuccess=성공적으로 보냄 +user.sendFail=전송 실패 +user.sendSuccessDesc=인증 코드가 성공적으로 전송되었습니다.보기로 이동하십시오 +user.sendFailDesc=인증 코드를 보내지 못했습니다. 관리자에게 문의하십시오. +user.inputVerifyCode=인증 코드를 입력하십시오 +user.getCode=인증 코드 받기 +user.inputPwd=비밀번호를 입력하십시오 +user.inputPwdAgain=비밀번호를 다시 입력하십시오 +user.inputNickName=닉네임을 입력하십시오 +user.inputEmail=이메일 주소를 입력하십시오 +user.inputPhone=전화 번호를 입력하십시오 +user.inputPhoneEmail=휴대 전화 / 이메일을 입력 해주세요 +user.invalidPhoneEmail=잘못된 전화 / 이메일 +user.findPwd=비밀번호 검색 +user.inputNotMatch=입력 한 %s 이 경계와 일치하지 않습니다. +user.usingDesc=사용하고 있습니다 +user.improveInfo=정보를 작성하십시오 +user.codeExpired=인증 코드가 만료되었습니다. 다시 받으십시오. +user.codeErrorTooMany=인증 코드 오류가 너무 많습니다. 다시 획득하십시오 +user.codeErrorFreq=전송 빈도가 너무 높습니다. 나중에 다시 시도하십시오! +user.codeErrorCnt=전송 횟수가 제한을 초과하여 %s 시간 동안 잠 깁니다. +user.registSuccess=성공적으로 등록 +user.waitCheck=관리자 검토 대기 중 +user.nameHolder=전화 번호 / 이메일을 입력하세요 +user.loginNoPermission=죄송합니다.이 권한이 없습니다.이 권한이있는 계정으로 로그인하십시오! +user.loginFirst=접속되지 않았습니다! 먼저 로그인하십시오 +user.bindSignError=서명이 비정상입니다. 다시 시도하십시오! +user.bindUpdateError=사용자 정보 업데이트에 실패했습니다. 다시 시도하십시오 +user.bindTypeError=잘못된 바인딩 유형 +user.bindWxConfigError=구성 정보 가져 오기 예외 +user.loginTimeout=현재 로그인 시간이 초과되었습니다. 다시 로그인하십시오! +user.theme=테마 스타일 +user.theme.desc=자동 대표 추종 시스템 +user.theme.light=밝은 색 +user.theme.dark=어두운 색 +user.theme.auto=자동적 인 +user.theme.title=맞춤 테마 설정 +user.theme.background=배경 +user.theme.image=사진 +user.theme.colorBlur=그라디언트 색상 +user.theme.imageBlur=이미지 블러 처리 +user.theme.imageUrl=사진 주소 +user.theme.colorStart=시작 색상 +user.theme.colorEnd=엔드 컬러 +user.theme.colorRadius=그라데이션 각도 +user.theme.themeImage=배경 그림 +user.theme.themeImageDesc=지원 : 사진 URL, CSS 그라디언트 색상, 배경 화면 따르기 +user.theme.imageWall=바탕 화면 팔로우 +user.wall.random=랜덤 바탕 화면 +user.wall.paperDesktop=데스크탑 월페이퍼 +user.wall.paperDeskMgt=바탕 화면 관리 +user.wall.paperLoginMgt=로그인 배경 화면 관리 +user.wall.paperLoginTips=사진이 두 개 이상인 경우 로그인 인터페이스의 배경이 무작위로 회전합니다. +log-type-create-mkdir=새 폴더 +log-type-create-mkfile=새 파일을 만들다 +log-type-create-upload=파일 업로드하다 +log-type-create-copy=파일 붙여 넣기 +log-type-edit=파일 업데이트 +log-type-move=파일 이동 +log-type-moveOut=파일 제거 +log-type-share-shareLinkAdd=외부 링크 공유를 만들었습니다 +log-type-share-shareToAdd=공동 작업 공유 +log-type-share-shareLinkRemove=닫힌 링크 공유 +log-type-share-shareToRemove=공동 작업 끄기 +log-type-share-shareEdit=공유 편집 +log-type-rename=이름 바꾸기 +log-type-recycle-toRecycle=휴지통으로 이동 +log-type-recycle-restore=휴지통에서 복원 +log-type-remove=지우다 +log-type-addDesc=설명 수정 +log-type-addComment=댓글 달기 +log-event-create-mkdir=이 폴더를 만들었습니다 +log-event-create-mkfile=파일을 만들었습니다 +log-event-create-upload=파일을 올렸습니다 +log-event-create-copy=붙여 넣기하여 파일을 만들었습니다 +log-event-create-mkdir-current=여기에 새 폴더를 만들었습니다 {0} +log-event-create-mkfile-current=여기에 생성 된 새 파일 {0} +log-event-create-upload-current=여기에 업로드 {0} +log-event-create-copy-current=여기에 붙여 넣기 {0} +log-event-create-mkdir-item={0} {1}에 새 폴더를 만들었습니다. +log-event-create-mkfile-item={0} {1}에서 작성된 새 파일 +log-event-create-upload-item={0}에 {1} 업로드 됨 +log-event-create-copy-item=붙여 넣기 {0} ~ {1} +log-event-create-mkdir-more=여기에 {0} 개의 폴더가 생성되었습니다. +log-event-create-mkfile-more={0} 여기에 생성 된 새 파일 +log-event-create-upload-more={0} 여기에 업로드 된 파일 +log-event-create-copy-more=여기에 {0} 개의 파일을 붙여 넣기 +log-event-create-mkdir-more-at={0}에 {1} 개의 새 폴더 생성 +log-event-create-mkfile-more-at={0}에 {1} 개의 새 파일이 생성되었습니다. +log-event-create-upload-more-at={1} {0}에 업로드 된 파일 +log-event-create-copy-more-at={0} 개의 문서를 {1}에 붙여 넣기 +log-event-view-item=조회함 {0} +log-event-edit=파일을 업데이트했습니다 +log-event-edit-item=업데이트된 편집 {0} +log-event-edit-more=업데이트된 {0} 파일 편집 +log-event-edit-more-user=파일을 {0} {1} 번 편집하고 업데이트했습니다. +log-event-edit-more-at={0}에서 편집 및 업데이트 된 {1} 파일 +log-event-move=문서를 {0}에서 {1}로 이동 +log-event-move-item={0}을 {1}에서 [3]으로 이동 +log-event-move-current=여기에서 {0}을 (를) {1}에서 이동 +log-event-move-more={0} 문서 이동 +log-event-move-more-desc={0}을 {1}에서 [3]으로 이동 +log-event-moveOut-more-desc={0} {1}에서 삭제됨 +log-event-moveOut=여기에서 삭제됨 {0} +log-event-moveOut-item={0}에서 제거됨 {1} +log-event-moveOut-more={0} 문서가 삭제되었습니다. +log-event-share-shareLinkAdd=이 문서를 공유하기위한 외부 링크를 만들었습니다 +log-event-share-shareLinkAdd-item={0} 공유 할 외부 링크 생성 +log-event-share-shareLinkAdd-more={0} 개의 링크를 만들어 공유 +log-event-share-shareToAdd=이 문서의 공동 작업 공유 +log-event-share-shareToAdd-item={0} 공동 작업 사용 +log-event-share-shareToAdd-more={0} 공동 주식 생성 +log-event-share-shareLinkRemove=문서의 링크 공유를 닫았습니다. +log-event-share-shareLinkRemove-item=폐쇄 된 {0} 님의 링크 공유 +log-event-share-shareLinkRemove-more={0} 외부 링크 공유 닫기 +log-event-share-shareToRemove=이 문서의 공동 작업 끄기 +log-event-share-shareToRemove-item={0}의 공동 작업 공유 끄기 +log-event-share-shareToRemove-more={0} 공동 작업 공유 +log-event-share-shareEdit=이 문서의 공유를 편집했습니다 +log-event-share-shareEdit-item={0} 님의 공유를 수정 함 +log-event-share-shareEdit-more=공유 할 문서 {0} 개 수정 +log-event-rename=문서 이름 변경 +log-event-rename-item=이름이 변경됨 {0} +log-event-rename-more={0} 문서 이름 변경 +log-event-recycle-toRecycle=문서를 휴지통으로 옮겼습니다. +log-event-recycle-toRecycle-current={0}을 (를) 휴지통으로 옮겼습니다. +log-event-recycle-toRecycle-item={1}를 {0}의 휴지통으로 이동했습니다. +log-event-recycle-toRecycle-more={0} 개의 문서를 휴지통으로 이동 +log-event-recycle-toRecycle-more-at={1} 문서를 {0}의 휴지통으로 이동했습니다. +log-event-recycle-restore=휴지통에서 문서 복원 +log-event-recycle-restore-item=휴지통에서 {0} 복원 +log-event-recycle-restore-more=휴지통에서 {0} 개의 문서 복원 +log-event-remove=여기에서 {0}을 (를) 삭제했습니다. +log-event-remove-current=여기에서 {0}을 (를) 삭제했습니다. +log-event-remove-item={0}에서 삭제 된 {1} +log-event-remove-more={0} 여기에서 삭제 된 문서 +log-event-remove-more-at={0}에서 {1} 개 문서를 삭제했습니다. +log-event-addDesc=문서 설명 수정 +log-event-addDesc-item=수정 된 {0} 문서 설명 +log-event-addDesc-more=수정 된 {0} 문서 설명 +log-event-addComment=이 문서에 댓글을 달았습니다 +log-event-addComment-item=에 댓글을 달았습니다 {0} +log-event-addComment-more={0}에 {1} 개의 댓글이 있습니다. +log-event-fav-fileAdd=즐겨 찾기 {0} +log-event-fav-dirAdd=북마크 된 폴더 {0} +log-event-down-item={0}에서 {1} 다운로드 +log-event-down-items={0}에서 다운로드 함 +log-event-recycle-del-item=휴지통에서 {0} 개 파일 삭제 +log-event-recycle-rst-item=휴지통에서 {0} 파일 복원 +log-event-del-item={0} 파일이 삭제되었습니다. +log.file.move=이동 / 복사 +log.file.fav=즐겨 찾기 작업 +log.file.shareLink=외부 링크 공유 +log.file.shareTo=협업 공유 +log.user.edit=계정 정보 수정 +log.group.edit=부서 관리 +log.member.edit=사용자 관리 +log.role.edit=역할 관리 +log.auth.edit=문서 권한 관리 +meta.user_sourceAlias=관련 파일 (첨부 파일) +meta.user_fileEncodeType=파일 기밀성 +meta.user_fileEncodeType.A=최고 비밀 +meta.user_fileEncodeType.B=B 기밀 +meta.user_fileEncodeType.C=C- 비밀 +meta.user_sourceNumber=볼륨 번호 +meta.user_sourceParticipant=참가자 +explorer.fileInfo.createTime=생산 일자 +explorer.fileInfo.modifyTime=수정 날짜 +explorer.fileInfo.softwareCreate=생산 소프트웨어 +explorer.fileInfo.software=코딩 소프트웨어 +explorer.fileInfo.playTime=플레이 시간 +explorer.fileInfo.imageSize=그림의 크기 +explorer.fileInfo.imageDpi=해결 +explorer.fileInfo.imageBits=비트 깊이 +explorer.fileInfo.imageDesc=주석 +explorer.fileInfo.imageAuthor=창조자 +explorer.fileInfo.imageColor=색 공간 +explorer.fileInfo.cameraType=장치 모델 +explorer.fileInfo.cameraApertureFNumber=조리개 번호 +explorer.fileInfo.cameraApertureValue=조리개 값 +explorer.fileInfo.cameraShutterSpeedValue=셔터 속도 +explorer.fileInfo.cameraExposureTime=노출 시간 +explorer.fileInfo.cameraFocalLength=초점 거리 +explorer.fileInfo.cameraFocusDistance=초점 거리 +explorer.fileInfo.cameraISOSpeedRatings=ISO 감도 +explorer.fileInfo.cameraWhiteBalance=화이트 밸런스 +explorer.fileInfo.cameraUser=설명서 +explorer.fileInfo.cameraAuto=자동적 인 +explorer.fileInfo.cameraExposureMode=노출 모드 +explorer.fileInfo.cameraExposureBiasValue=노출 보정 +explorer.fileInfo.imageGps=촬영 장소 +explorer.fileInfo.imageCreateTime=촬영 날짜 +explorer.fileInfo.audioChannel=오디오 채널 +explorer.fileInfo.audioChannel1=단 핵증 +explorer.fileInfo.audioChannel2=스테레오 +explorer.fileInfo.audioChannels=다 채널 +explorer.fileInfo.audioRate=오디오 샘플링 속도 +explorer.fileInfo.audioBits=오디오 비트 심도 +explorer.fileInfo.audioBitrate=오디오 비트율 +explorer.fileInfo.vedioFormat=비디오 인코딩 +explorer.fileInfo.audioTitle=표제 +explorer.fileInfo.audioAuthor=저자 +explorer.fileInfo.audioAlbum=앨범 +explorer.fileInfo.audioStyle=스타일 +explorer.fileInfo.audioYear=앨범 연도 +explorer.fileInfo.vedioSize=화면 크기 +explorer.fileInfo.vedioFrame=비디오 프레임 속도 +explorer.fileInfo.vedioBitrate=비디오 비트 레이트 +explorer.fileInfo.title=표제 +explorer.fileInfo.author=저자 +explorer.fileInfo.pageTotal=총 페이지 +explorer.fileInfo.pageSize=페이지 크기 +explorer.fileInfo.pagePower=콘텐츠 제작자 +explorer.fileInfo.pdfVersion=PDF 버전 +explorer.filter.shareCopyLimit=덤프할 파일 수가 제한을 초과했습니다. 덤프할 수 있는 최대 파일 수는 다음과 같습니다. +explorer.filter.shareSizeLimit=공유 파일 크기가 제한을 초과했습니다. 공유할 수 있는 최대 크기는 다음과 같습니다. +explorer.filter.unzipSizeLimit=압축 해제 파일 크기가 제한을 초과합니다. 압축을 풀 수 있는 최대 크기는 다음과 같습니다. +explorer.filter.zipSizeLimit=압축된 파일 크기가 제한을 초과했습니다. 최대 압축 가능한 문서: +explorer.filter.uploadSizeLimit=업로드 크기가 제한을 초과했습니다. 업로드할 수 있는 최대값은 다음과 같습니다. +explorer.fileEditError=현재 파일 %s 을(를) 편집 중입니다. 나중에 다시 시도하십시오. +explorer.groupDelError=죄송합니다. 부서 폴더는 삭제를 지원하지 않습니다. +admin.info.typeDelError=삭제 실패, 하위 분류 또는 데이터 +admin.info.domainIdentifyError=웹 사이트를 인식할 수 없음 +admin.info.articleIdentifyError=글이 인식되지 않음 +admin.info.domainSupportError=이 사이트는 아직 채집을 지원하지 않습니다 +admin.info.fileTooLarge=파일이 너무 큽니다. +explorer.toolbar.info=정보 +source.shareDisabled=현재 자원 공유 금지 +admin.exceeds.limit=제한 초과 +admin.design.deleted=사용 상태를 삭제할 수 없습니다. +admin.design.url.locked=현재 URL이 잠겨 당분간 사용할 수 없습니다 +explorer.SING_INVALID=서명 예외 +explorer.TEMP_AUTH_INVALID=유효하지 않은 임시 인증 코드 (유효하지 않음) +explorer.QR_INVALID=QR코드가 작동하지 않음 +explorer.toolbar.toolbox=도구상자 +explorer.toolbox.desc= +logs-detail-mkdir=새 폴더 +logs-detail-mkfile=새 파일 +logs-detail-editFile=편집업데이트됨 +logs-detail-upload=파일 업로드 +logs-detail-uploadNew=편집됨 +logs-detail-file.upload=올렸어 +logs-detail-file-copy=붙여넣기로 파일 생성 +logs-detail-folder-copy=붙여넣기 폴더 만들기 +logs-detail-paste=붙여넣기 +logs-detail-from=부터 +logs-detail-to=도착 +logs-detail-rename=이름이 변경되었습니다. +logs-detail-rename-file=파일 이름이 변경되었습니다. +logs-detail-rename-folder=폴더 이름이 변경되었습니다. +logs-detail-user=사용자: +logs-detail-moveFrom-restore=곧 +logs-detail-moveTo-restore=휴지통에서 복원 +logs-detail-move=곧 +logs-detail-moveTo=다음으로 이동 +logs-detail-moveFrom-toRecycle=곧 +logs-detail-moveTo-toRecycle=휴지통으로 이동 +logs-detail-file-toRecycle=파일을 휴지통으로 이동 +logs-detail-file-restore=휴지통에서 파일 복원 +logs-detail-folder-toRecycle=폴더를 휴지통으로 이동 +logs-detail-folder-restore=휴지통에서 폴더 복원 +logs-detail-favAdd=소장했어 +logs-detail-favDel=모음 해제 +logs-detail-unstar=이름: +logs-detail-moveOut=옮겼어 +logs-detail-remove=삭제됨 +logs-detail-file.copy=붙여넣기 +explorer.noPermissionAuthAll={0} ,이 작업 권한이 없습니다. \ No newline at end of file diff --git a/src/main/resources/i18n/messages_pt_PT.properties b/src/main/resources/i18n/messages_pt_PT.properties new file mode 100644 index 0000000..b763f9d --- /dev/null +++ b/src/main/resources/i18n/messages_pt_PT.properties @@ -0,0 +1,2563 @@ +admin.serverInfo=Informações do servidor +admin.today=Hoje +admin.yesterday=Ontem +admin.weekDay=Quase 7 dias +admin.monthDay=Quase 30 dias +admin.ing=Em andamento +admin.paused=Suspenso +admin.serverDownload=Download remoto +admin.memberManage=Gerenciamento de usuários +admin.fileManage=Gerenciamento de arquivos +admin.pwdEdit=Alterar senha +admin.fileEdit=Editar salvar arquivo +admin.list=Vista de lista +admin.configError=Falha ao salvar a configuração. O administrador desativou esta permissão! +admin.userManage=Centro pessoal +admin.manage=Gerenciamento em segundo plano +admin.pluginManage=Gerenciamento de plug-in +admin.emailDear=Olá %s, +admin.emailCodeText=Você está verificando seu endereço de e-mail. O código de verificação para esta solicitação é o seguinte. Para garantir a segurança de sua conta, conclua a verificação a tempo. +admin.emailVerifyInTime=Para proteger a segurança da sua conta, conclua a verificação a tempo. +admin.dear=Respeito +admin.dearUser=Caro usuário, +admin.emailResetLink=Você está redefinindo a senha de login para %s por e-mail, clique no link abaixo para redefini-la. Se o link não pular, copie-o para a barra de endereços do navegador para acessá-lo: +admin.emailExpireTime=O link expira após 20 minutos. +admin.jobName=Cargo +admin.jobDesc=Descrição do trabalho +admin.jobNameInput=Digite um nome de trabalho +admin.jobEdit=Editor de postagem +admin.menu.home=Página inicial +admin.menu.dashboard=Visão geral +admin.menu.dashboardTitle=Visão Geral das Estatísticas +admin.menu.notice=Gerenciamento de notificação +admin.menu.groupMember=Gerenciamento de Departamento e Membro +admin.menu.member=Departamentos e usuários +admin.menu.role=Gerenciamento de funções +admin.menu.job=Gerenciamento de tarefas +admin.menu.auth=Gerenciamento de direitos de documentos +admin.menu.storage=Armazenamento / arquivo +admin.menu.storageDriver=Gerenciamento de armazenamento +admin.menu.plugin=Centro de plug-ins +admin.menu.tools=Controle de segurança +admin.menu.server=Gerenciamento de servidor +admin.menu.backup=Gerenciamento de backup +admin.menu.share=Gerenciamento de compartilhamento +admin.menu.loginLog=Log de logon +admin.menu.log=Log de operação +admin.menu.task=Tarefas agendadas +admin.autoTask.restart=Reiniciar tarefas agendadas +admin.autoTask.restartEnd=A tarefa agendada foi reiniciada +admin.index.userSpace=Espaço do usuário +admin.index.groupSpace=Espaço departamento +admin.index.folderCount=Número de pastas: +admin.index.fileCount=Número de arquivos: +admin.index.loginToday=Entre hoje +admin.index.useTotal=Uso total: +admin.index.userLogin=Login do usuário +admin.index.spaceUsed=Ocupar espaço +admin.index.useSpace=Use espaço +admin.index.usedSpace=Espaço usado +admin.index.freeSpace=espaço restante +admin.index.sizeLimit=Tamanho limitado +admin.index.vipCount=Usuários registrados +admin.index.loginCurrent=Atualmente online +admin.index.fileDel=Exclusão de arquivo +admin.index.fileEdit=Edição de arquivo +admin.index.fileUpload=Upload de arquivo +admin.index.fileDown=Download do documento +admin.index.spaceUse=Uso prático +admin.index.spaceSave=Economize espaço +admin.index.spaceUser=Uso do usuário +admin.index.spaceGroup=Uso do departamento +admin.index.lastLogin=Hora do último login +admin.index.totalUsers=Total de usuários +admin.index.loginUsers=Usuário de login +admin.index.spaceActUsed=Ocupação real +admin.index.source=Origem do login +admin.index.address=Endereço de login +admin.index.userInfo=informação de usuário +admin.index.userValid=Conta válida +admin.index.userInvalid=Conta inválida +admin.index.fileInfo=Informações do arquivo +admin.index.fileCnt=Número de arquivos +admin.index.fileAdd=Adicionado hoje +admin.index.accInfo=Informações de acesso +admin.index.accCnt=solicitações de +admin.index.accUser=Acessar usuário +admin.index.serverInfo=mensagem do sistema +admin.index.serverDisk=Disco do sistema +admin.index.serverStore=Armazenamento em rede +admin.index.serverName=nome do servidor +admin.index.normal=normal +admin.index.scoreDesc=Os seguintes fatores afetarão a pontuação do sistema, que pode ser otimizada para garantir que o sistema funcione bem:
    1. O espaço restante do disco do sistema e armazenamento em disco da rede;
    2. Método de armazenamento em cache de dados (redis é recomendado);
    Versão da plataforma 3.php (recomendado php7 + de 64 bits). +admin.index.fileRatio=Taxa de uso de arquivo +admin.setting.system=Configurações do sistema +admin.setting.account=Configurações da conta +admin.setting.theme=Configurações do tema +admin.setting.wall=Configurações do papel de parede +admin.setting.stats=Estatísticas de utilização +admin.setting.safeMgt=Gestão da segurança +admin.setting.base=Configurações básicas +admin.setting.others=Outras configurações +admin.setting.sync=Configurações de sincronização +admin.setting.plugin=Configurações de plug-in +admin.setting.auth=Configuração de permissão +admin.setting.safe=Configurações de segurança +admin.setting.loginLog=Log de login +admin.setting.loginDevice=Dispositivo de login +admin.setting.deviceType=Tipo de equipamento +admin.setting.lastLoginTime=Última hora de login +admin.setting.email=Configurações de email +admin.setting.user=Registro e Login +admin.setting.pwdOld=Senha original +admin.setting.pwdNew=Modifique para +admin.setting.wallDiy=Papel de parede personalizado: +admin.setting.fav=Gerenciamento de favoritos +admin.setting.help=Use ajuda +admin.setting.about=Sobre obras +admin.setting.homePage= +admin.setting.subMenu=Submenu +admin.setting.menuName=Nome do menu +admin.setting.menuUrl=Endereço URL +admin.setting.menuUrlDesc=endereço url ou código js +admin.setting.safeAccount=Segurança de conta e login +admin.setting.safeData=Segurança de dados / segurança de transmissão +admin.setting.passwordErrorLock=Bloqueio de erro de entrada de senha +admin.setting.passwordErrorLockDesc=Se a senha estiver incorreta por 5 vezes consecutivas, a conta será bloqueada por 1 minuto e não terá permissão para fazer login. Após a abertura, pode efetivamente impedir que a senha seja quebrada por força bruta; +admin.setting.passwordRule=Configuração de força da senha do usuário +admin.setting.passwordRuleDesc=Depois que a força da senha é especificada, a senha fraca pode ser efetivamente eliminada +admin.setting.passwordRuleNone=Ilimitado +admin.setting.passwordRuleStrong=Intensidade média +admin.setting.passwordRuleStrongMore=Alta resistência +admin.setting.passwordRuleNoneDesc=Força ilimitada da senha +admin.setting.passwordRuleStrongDesc=O comprimento é maior que 6, deve conter inglês e números; +admin.setting.passwordRuleStrongMoreDesc=O comprimento é maior que 6; deve conter números, inglês maiúsculo e inglês minúsculo +admin.setting.passwordRuleTips=Sua senha atual não é forte o suficiente, é recomendável alterar a senha imediatamente! +admin.loginCheck.menu=Controle de login +admin.loginCheck.ipCheck=Restrições de IP +admin.loginCheck.ipCheckNone=não limitado +admin.loginCheck.ipCheckAllow=Lista de permissões de IP +admin.loginCheck.ipCheckDisable=Lista negra de IP +admin.loginCheck.loginIpAllowDesc=Após a abertura, apenas usuários com o ip especificado podem fazer login, por favor, tome cuidado +admin.loginCheck.ipAllow=IP permitido +admin.loginCheck.ipAllowDesc=Preencha as regras da seguinte forma (em cada linha, o IP local do servidor é permitido por padrão, e o administrador do sistema permite o IP LAN) +admin.loginCheck.ipDisable=Regras de lista negra de IP +admin.loginCheck.ipDisableDesc= +admin.loginCheck.ipDescTitle=Preencha as regras da seguinte forma (uma linha por entrada) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=prioridade +admin.loginCheck.name=Nome da regra +admin.loginCheck.user=Usuário designado +admin.loginCheck.device=Equipamento designado +admin.loginCheck.deviceWeb=Rede +admin.loginCheck.devicePc=Lado do PC +admin.loginCheck.deviceAndroid=Android +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc=
    Instruções de controle de restrição de login do usuário (restrições de ip e dispositivo):
  • Detectar em sequência de acordo com a ordem de prioridade da regra; o usuário especificado pela regra inclui o usuário conectado no momento; a regra é determinada como o resultado
  • Recomenda-se colocar os grupos de usuários e usuários departamentais na parte traseira e especificar as configurações do usuário na frente; (arraste e solte para ajustar a ordem)
  • +admin.setting.checkCode=O código de verificação de login está ativado +admin.setting.checkCodeDesc=Após o login, você precisa inserir o código de verificação. +admin.setting.csrfProtect=Ativar proteção csrf +admin.setting.csrfProtectDesc=Pode efetivamente impedir ataques csrf quando ativado +admin.setting.setRootPath=Acesso root +admin.setting.setRootPathDesc=Somente o administrador do sistema pode acessar todos os diretórios, e os usuários em outros grupos de permissão podem ver apenas seus próprios diretórios.
    Se você deseja ativar ou desativar o acesso de administrador a outros diretórios, pode modificar o parâmetro open_basedir entre sites do PHP, como configurar +admin.setting.encode=Criptografia de armazenamento de arquivo +admin.setting.encodeAll=Criptografar tudo +admin.setting.encodeName=Mantenha a extensão +admin.setting.encodeNone=Sem criptografia +admin.setting.encodeAllDesc=Criptografia completa: [recomendação padrão]; mesmo que você tenha permissões de servidor, você não conhece o conteúdo real do arquivo; ele pode proteger efetivamente contra ransomware e outros danos; +admin.setting.encodeNameDesc=Manter extensão: criptografia de nome de arquivo, manter extensão +admin.setting.encodeNullDesc=Sem criptografia: onome do arquivo não é criptografado e o nome original do arquivo é mantido; (para garantir a segurança, a pasta de upload é denominada estrutura criptografada); +admin.setting.encodeTips1=Somente os arquivos após a alteração da configuração são afetados, os arquivos que existiam antes não são afetados; +admin.setting.encodeTips2=Para evitar erros, não exclua ou renomeie arquivos em dados / arquivos; +admin.setting.encodeTips3=Para oferecer suporte a simultaneidade em larga escala, segunda transmissão, clustering, distribuição, expansão automática e outras funções; a hierarquia de pastas é registrada no banco de dados; a estrutura de pastas pode ser importada e restaurada copiando e colando +admin.setting.thirdLogin=Login de terceiros +admin.setting.thirdLoginDesc=Permitir registro, associação e login através de contas de terceiros +admin.setting.registOpen=Abrir registro de usuário +admin.setting.registOpenDesc=Para evitar conflitos de dados, a sincronização de dados de terceiros e o registro do usuário não podem ser ativados ao mesmo tempo +admin.setting.registCheck=Revisão de registro aberto +admin.setting.registCheckDesc=Após a abertura, o administrador precisa revisá-lo e habilitá-lo em [Usuários e Departamentos] para que usuários registrados usem normalmente +admin.setting.clearUserRecycle=Esvaziar todas as lixeiras do usuário +admin.setting.clearCache=Limpar cache +admin.setting.icp=Copyright ou número de registro +admin.setting.icpDesc=Se precisar gerar um link, você mesmo poderá adicionar uma tag +admin.setting.globalCss=CSS global personalizado +admin.setting.globalCssDesc=Todas as páginas inserirão css personalizado +admin.setting.globalHtml=Código estatístico HTML +admin.setting.globalHtmlDesc=Todas as páginas inserirão esse código html, e o código estatístico de terceiros poderá ser colocado +admin.setting.dateFormat=Formato de data +admin.setting.dateFormatDesc=Exibição do formato de hora ano-mês-dia, hora de modificação do arquivo, etc. +admin.setting.menu=Gerenciamento de menu +admin.setting.systemName=Nome do Produto da Empresa +admin.setting.systemNameDesc=Para o título do logotipo do produto +admin.setting.systemDesc=Legenda do Produto +admin.setting.pathHidden=Exclusão de diretório +admin.setting.pathHiddenDesc=Diretórios e arquivos não exibidos por padrão, separados por vírgulas +admin.setting.defaultFolder=Novos usuários criam diretórios por padrão +admin.setting.defaultFolderDesc=Separado por vírgulas +admin.setting.defaultApp=Novos usuários criam aplicativos por padrão +admin.setting.defaultAppDesc=Aplicativos do Application Center, múltiplos separados por vírgulas +admin.setting.autoLogin=Login automático +admin.setting.autoLoginDesc=O usuário de login padrão é o usuário de guest / guest ; verifique se esse usuário existe após abrir +admin.setting.firstIn=Entrar por padrão após o login +admin.setting.registReviewOpen=Auditoria de registro aberta: +admin.setting.registRoleEmpty=A função de permissão não pode estar vazia +admin.setting.registNotSync=Para evitar conflitos de dados, a sincronização de dados de terceiros e o registro do usuário não podem ser ativados ao mesmo tempo +admin.setting.registNeedRewiew=Depois de aberto, o administrador precisa revisar e habilitar nos usuários e departamentos para usuários registrados +admin.setting.roleRight=Permissões de função +admin.setting.emailHost=Servidor de caixa de correio +admin.setting.emailHostInput=Digite o endereço do servidor de correio +admin.setting.emailHostTips=Por favor, preencha o endereço do servidor de correio +admin.setting.emailHostDesc=Servidor de caixa de correio, como: smtp.163.com, a porta pode ser personalizada (o padrão é 465) +admin.setting.emailSend=Caixa de saída +admin.setting.emailSendInput=Digite o endereço de e-mail +admin.setting.emailSendTips=Por favor, preencha o endereço de email de envio +admin.setting.emailSendDesc=Endereço de e-mail do sistema, o serviço POP3 / SMTP precisa estar ativado +admin.setting.emailPwd=Senha de autorização +admin.setting.emailPwdTips=Por favor, preencha a senha de autorização de e-mail +admin.setting.secureType=Encriptação +admin.setting.emailSendTest=Enviar detecção +admin.setting.ensureEmailOk=Verifique se o email pode ser enviado normalmente +admin.setting.emailTo=Caixa de entrada +admin.setting.emailGoToTips=Por favor, vá para a caixa de correio +admin.setting.emailCheckTips=Ver +admin.setting.emailInputError=Configurações de email incorretas +admin.setting.emailPwdError=A senha de configuração de e-mail está incorreta +admin.setting.emailDesc=Configurar um servidor de correio para registro do usuário, envio de e-mail de recuperação de senha +admin.setting.sendEmail=Enviar correio +admin.setting.sendEmailDesc=Padrão do sistema: ligue para enviar o servidor de email na nuvem para enviar; personalizado: configure o servidor de email sozinho +admin.setting.systemBackup=Backup do sistema +admin.setting.enableFunction=Funções e interruptores +admin.setting.treeOpen=Chave de função do diretório em árvore +admin.setting.treeOpenDesc=Gerenciamento de arquivos, função correspondente ao diretório em árvore ativada e desativada globalmente +admin.setting.groupListChild=Listar subsetores +admin.setting.groupListChildDesc=Se a pasta do departamento mostra sub-departamentos, as permissões são herdadas para cima +admin.setting.groupRootListChild=O disco da Web da empresa lista subsetores +admin.setting.groupRootListChildDesc=Se a pasta de disco da rede corporativa exibe sub-departamentos e as permissões são herdadas para cima +admin.setting.shareToMeAllowTree=Colabore comigo - mostre por estrutura organizacional +admin.setting.shareToMeAllowTreeTips=Após a abertura, o conteúdo de suporte para colaboração comigo é classificado de acordo com a estrutura organizacional do departamento, que se adequa a situações em que a estrutura organizacional é mais complexa +admin.setting.groupTagAllow=Selo público do departamento +admin.setting.groupTagAllowTips=Após a habilitação, todos os membros do departamento ficarão visíveis após definir o rótulo público para os arquivos do departamento.O administrador do departamento pode manter o conteúdo do rótulo. +admin.setting.shareToMeList=Tela em mosaico +admin.setting.shareToMeGroup=Mostrar por estrutura organizacional +admin.setting.shareToMeUser=Mostrar por compartilhador +admin.setting.sysSrvState=Status do servidor +admin.setting.sysSrvInfo=informação do servidor +admin.setting.sysPhpInfo=Informação PHP +admin.setting.database=base de dados +admin.setting.cache=Cache +admin.setting.sysMyInfo=Minha informação +admin.setting.srvStateCpu=utilização do CPU +admin.setting.srvStateMem=Uso de memória +admin.setting.srvStateSrv=Espaço de armazenamento do sistema do servidor +admin.setting.srvStateDef=O espaço de armazenamento padrão do disco de rede +admin.setting.srvInfoName=nome do servidor +admin.setting.srvInfoIp=IP do servidor +admin.setting.srvInfoTime=horário do servidor +admin.setting.srvInfoUpTime=Tempo de execução contínua +admin.setting.srvInfoWeb=Software de servidor +admin.setting.srvInfoPhpV=Versão PHP +admin.setting.srvInfoSys=Sistema de servidor +admin.setting.srvInfoPath=Caminho do site +admin.setting.srvPhpDtl=Detalhes de PHP +admin.setting.memLimit=Limite de memória +admin.setting.postLimit=Limite de envio POST +admin.setting.uploadLimit=Restrições de upload de arquivos +admin.setting.execTime=Tempo máximo de execução +admin.setting.inputTime=Tempo máximo de solicitação +admin.setting.disFunction=Desabilitar função +admin.setting.phpExtSugst=Extensões PHP recomendadas +admin.setting.phpExtLoad=Extensão carregada +admin.setting.myClientIp=Meu IP +admin.setting.myClientUa=Meu navegador UA +admin.setting.myClientLng=Idioma do meu navegador +admin.setting.disFuncDesc=Funções exigidas pelo sistema, é recomendado habilitar +admin.setting.srvMemFree=Memória restante +admin.setting.srvMemUse=Usar memória +admin.setting.srvCpuUse=Atualmente ocupado +admin.setting.srvCpuFree=Não utilizado +admin.setting.noLimit=Ilimitado +admin.setting.disFunNo=não +admin.setting.systemCache=Cache do sistema +admin.setting.systemDb=Banco de dados do sistema +admin.setting.sysCacheTab=Mudança de cache +admin.setting.sysDbTab=Mudança de banco de dados +admin.setting.sysRecTab=Recuperação de banco de dados +admin.setting.cacheDesc=Descrição do cache +admin.setting.fileCacheDesc=Cache de arquivo: grave dados diretamente no arquivo de cache, adequado para teste ou uso em pequena escala. +admin.setting.redisDesc=Redis: um banco de dados não relacional de valor-chave e alto desempenho, adequado para situações simultâneas de leitura e gravação. Recomendado para uso. +admin.setting.memcachedDesc=Memcached: um sistema de cache de objetos de memória distribuída de alto desempenho, adequado para leituras simultâneas altas. +admin.setting.saveAfterTest=Após a aprovação do teste, ele pode ser salvo +admin.setting.checkPassed=Passado +admin.setting.ifSaveCache=Após a troca, todos os dados em cache serão apagados!
    Tem certeza que deseja executar? +admin.setting.ifSaveDb=A troca de banco de dados importará os dados atuais do sistema para o novo banco de dados e os definirá como padrão. Tem certeza que deseja executá-lo? +admin.setting.dbCurrent=Configuração atual +admin.setting.dbType=Tipo de banco de dados +admin.setting.dbName=Banco de dados de nomes +admin.setting.dbInfo=Informação de banco de dados +admin.setting.dbSwitch=Ligar +admin.setting.dbSwitchDesc=Após a abertura, você pode alterar o tipo de banco de dados conforme necessário; opere com cuidado. +admin.setting.dbTable=Ficha de dados +admin.setting.dbCnt=total +admin.setting.dbNeedNew=O banco de dados já existe, por favor, especifique novamente +admin.setting.dbInsertError=Falha ao gravar dados da tabela +admin.setting.dbNeedOthers=Selecione outro tipo de banco de dados +admin.setting.dbNeedChange=Modifique os parâmetros de configuração +admin.setting.dbCreateError=Falha na criação do arquivo de banco de dados, verifique as permissões de leitura e gravação +admin.setting.dbTaskProcess=Progresso de execução +admin.setting.dbTasking=Sendo executado +admin.setting.dbTaskDesc=Não feche a janela ou execute outras operações no sistema para evitar a geração de dados discrepantes. +admin.setting.recTaskDesc=Não feche a janela. Depois que a solicitação for interrompida, o plano de fundo continuará a ser executado até que a tarefa termine. +admin.setting.dbCreate=Novo banco de dados +admin.setting.dbSelect=Ler banco de dados +admin.setting.dbInsert=Grave no banco de dados +admin.setting.dbSetSave=Salvar informações de configuração +admin.setting.recDesc=Instruções de uso +admin.setting.recDescInfo11=Esta operação irá redefinir os dados do sistema, não operação e manutenção ou pessoal técnico relacionado não deve operar! +admin.setting.recDescInfo21=Ao gravar o banco de dados de backup no novo banco de dados e defini-lo como o padrão do sistema, a recuperação dos dados é obtida. +admin.setting.recDescInfo22=Os novos parâmetros de configuração do banco de dados serão anexados ao arquivo de configuração do sistema config / setting_user.php. Se o sistema estiver anormal após a execução da recuperação, a parte anexada do arquivo pode ser removida sem afetar os dados anteriores do sistema. +admin.setting.recDescInfo23=Esta função suporta apenas o processamento dos dados de backup gerados pelo gerenciamento de backup do sistema, e o banco de dados cujo backup foi feito por você deve ser processado de outras maneiras. +admin.setting.recDescInfo31=Nota: Quando o tipo de banco de dados é MySQL, uma nova biblioteca (nome da biblioteca original_atualização_atual_data) será criada com base nas informações de configuração atuais. Os usuários não root podem não ter permissões suficientes, portanto, você precisa primeiro definir as permissões para o usuário. +admin.setting.recDescInfo32= +admin.setting.recDescInfo33=Configurando permissões: +admin.setting.recDescInfo34=Revogar permissões: +admin.setting.recOpen=Ativar recuperação +admin.setting.recOpenDesc=Depois de ligado, você pode selecionar o banco de dados do backup para restaurar conforme necessário. Opere com cuidado. +admin.setting.recTypeDesc=Depende do tipo de sistema usado atualmente +admin.setting.recPath=Diretório de backup de banco de dados +admin.setting.recPathErr=Diretório de backup de banco de dados inválido +admin.setting.ifSaveRec=A restauração do banco de dados importará os dados de backup para o novo banco de dados e o definirá como padrão.
    Tem certeza que deseja executá-lo? +admin.setting.recDiyPathErr=Ao usar o backup automático para restaurar, selecione o arquivo de banco de dados para fazer o backup +admin.setting.recDiyFileNull=O arquivo de banco de dados está vazio +admin.setting.recDiyPhpErr=Para que o backup do SQLite seja feito por você mesmo, selecione o arquivo de banco de dados formatado como php +admin.setting.recDiySqlErr=Para que você mesmo faça backup do MySQL, selecione o arquivo de banco de dados formatado como sql +admin.setting.recSysPathErr=Ao usar o gerenciamento de backup para restaurar, selecione o diretório do banco de dados de backup +admin.setting.recSysTbErr=O diretório de backup do banco de dados é inválido ou o arquivo de estrutura do banco de dados está ausente +admin.setting.recDbFileErr=O arquivo de biblioteca selecionado não corresponde ao sistema ou uma tabela de dados válida está faltando +admin.setting.dbFileDown=Ler arquivo de biblioteca +admin.setting.dbFileDownErr=Falha ao ler o arquivo da biblioteca +admin.notice.waiting=Esperando por push +admin.notice.done=Empurrado +admin.notice.time=Tempo de push +admin.notice.target=Objeto push +admin.notice.level=Nível de alerta +admin.notice.level0=Dica fraca +admin.notice.level1=Prompt forte +admin.notice.levelDesc=Lembrete fraco: um ponto vermelho é exibido na barra de notificação no canto esquerdo inferior; lembrete forte: uma notificação aparecerá diretamente após o usuário fazer login. +admin.notice.targetAuth=Escolha enviar para todos ou enviar para usuários, grupos de usuários e grupos de permissão específicos +admin.notice.title=Título da mensagem +admin.notice.content=Conteúdo da mensagem +admin.notice.timeType=Método push +admin.notice.timeNow=Empurre imediatamente +admin.notice.timePlan=Push agendado +admin.notice.listTitle=Notificação de notícias da estação +admin.notice.clearAll=Esvaziar tudo +admin.notice.noMsg=Sem novidades +admin.notice.ifClearAll=Tem certeza de que deseja limpar todas as mensagens? +admin.group.role=Identidade da função +admin.group.name=Nome do departamento +admin.group.parent=Departamento superior +admin.group.authShow=O escopo da estrutura organizacional visível para os membros do departamento +admin.group.authShowAll=Todos os departamentos +admin.group.authShowHide=Apenas este departamento e sub-departamento +admin.group.authShowSelect=Departamento designado +admin.group.authShowAllTips=Quando os membros deste departamento colaboram para compartilhar, eles podem selecionar todos os outros departamentos (e usuários) +admin.group.authShowHideTips=Quando os membros deste departamento colaboram e compartilham, apenas o departamento e subdepartamento (e usuários) atuais são suportados +admin.group.authShowSelectTips=Quando os membros do departamento colaboram e compartilham, eles podem selecionar o departamento e sub-departamento (e usuário) designados, incluindo o departamento e o sub-departamento atuais +admin.group.addSub=Adicionar sub-departamento +admin.group.remove=Excluir departamento +admin.group.switch=Departamento de Migração +admin.group.swtichDesc=Migre usuários e arquivos do departamento selecionado (e seus subdepartamentos) para o departamento de destino. +admin.group.switchSameError=O departamento de destino não pode ser o mesmo que o departamento selecionado +admin.group.switching=Migrando, aguarde... +admin.group.groupSwitching=O departamento selecionado está migrando +admin.group.parentNullError=O departamento superior não pode estar vazio +admin.group.selected=Departamento selecionado +admin.group.setSizeBatch=Defina o tamanho do espaço em lotes +admin.group.multiSelect=Vários departamentos podem ser selecionados para configuração em lote +admin.group.ifDisAll=Todos os subdepartamentos serão desativados. Tem certeza de que deseja executá-lo? +admin.member.manage=Usuários e departamentos +admin.member.add=Novo usuário +admin.member.role=Função de autoridade +admin.member.group=Departamento +admin.member.groupAdd=Adicionar departamento +admin.member.groupEdit=Departamento editorial +admin.member.remove=Excluir usuário +admin.member.import=Adicionar em massa +admin.member.enable=Ativar +admin.member.batchSet=Operações em massa +admin.member.groupRemove=Remover do departamento +admin.member.groupInsert=Adicionar ao departamento +admin.member.groupSwitch=Migrar para o departamento +admin.member.groupTarget=Departamento alvo +admin.member.groupReset=Redefinir departamento +admin.member.groupSwtichDesc=Migrar usuários selecionados do departamento atual para o departamento de destino +admin.member.roleSet=Configurações de função de permissão +admin.member.sizeSet=Configuração do tamanho do espaço +admin.member.name=Conta de login +admin.member.nickName=Apelido do usuário +admin.member.userInfo=Informações do usuário +admin.member.userImport=Importar usuários em massa +admin.member.uploadFirst=Faça o upload do arquivo primeiro +admin.member.downTpl=Baixar modelo +admin.member.downTplDesc=Preencha o formato do modelo e faça o upload. +admin.member.uploadInvalid=Não há dados válidos no arquivo enviado. Verifique e envie novamente +admin.member.uploadDataInvalid=O upload de dados é inválido ou expirou. Faça o upload novamente +admin.member.importSuccess=Importação completa +admin.member.importFail=Falha na importação +admin.member.importFailDesc=Sucesso: {0}; Falha: {1} +admin.member.importName=Conta de login (obrigatório, exclusivo) +admin.member.importNickName=Apelido (único) +admin.member.importPwd=Senha requerida) +admin.member.importSex=Gênero (Masculino-1, Feminino-0) +admin.member.importPhone=Número de celular (único) +admin.member.importEmail=E-mail (somente) +admin.member.groupRemoveTips=Os usuários deste grupo de usuários não podem fazer login após a exclusão
    (É necessário redefinir o grupo de usuários), tem certeza de que deseja continuar? +admin.member.memberRemoveTips=Após a exclusão, o diretório do usuário será movido para a lixeira do sistema,
    Você tem certeza que quer continuar? +admin.member.selectUserTips=Selecione a conta para operar +admin.member.ifRemoveGroup=Tem certeza de que deseja remover os usuários selecionados deste grupo? +admin.member.importDesc=Um usuário por linha,
    Ignorar automaticamente se ele já existir +admin.member.roleAdminTips=Nota: O administrador do sistema não é controlado por permissões +admin.member.space=Definir tamanho do espaço do usuário +admin.member.spaceTips=0 não é restrito +admin.member.spaceTipsDefault=(GB) 0 não é limitado +admin.member.spaceTipsFull=Não restrito +admin.member.spaceSize=Tamanho do espaço +admin.member.spaceSizeUse=Uso do espaço +admin.member.memberAdd=Adicionar usuário +admin.member.allAdd=Adicionar usuário ou departamento +admin.member.nullNotUpdate=Deixe em branco +admin.member.search=Pesquisar usuários (conta / apelido / email / telefone) +admin.member.searchUser=Pesquisar usuários (suporte a correspondência pinyin e difusa) +admin.member.searchGroup=Departamento de pesquisa (suporte pinyin e correspondência difusa) +admin.member.searchAll=Procure usuários ou departamentos (suporte pinyin e correspondência difusa) +admin.member.editNoAuth=Desculpe, você não tem essa permissão,
    Somente administradores de sistema podem adicionar e modificar administradores de sistema +admin.member.disabledUsers=Conta desativada +admin.member.disabledTips=Mudar departamentos para desmarcar +admin.member.userGroup=Departamento do usuário +admin.member.userRole=Papel do usuário +admin.member.userSelected=Usuários selecionados +admin.member.authCopy=Copiar permissões do departamento +admin.member.authPaste=Pasta de permissão do departamento +admin.member.ifAuthPaste=Tem certeza de que deseja definir as permissões de departamento copiadas para o usuário atual? +ERROR_USER_NOT_EXISTS=O usuário não existe +ERROR_USER_PASSWORD_ERROR=Senha incorreta +ERROR_USER_EXIST_NAME=O nome de usuário já existe +ERROR_USER_EXIST_PHONE=O número de telefone já existe +ERROR_USER_EXIST_EMAIL=A caixa de correio já existe +ERROR_USER_EXIST_NICKNAME=Apelido já existe +ERROR_USER_LOGIN_LOCK=Desculpe, existem muitas tentativas de senha e a conta atual está bloqueada. Tente novamente em 1 minuto! +ERROR_IP_NOT_ALLOW=Seu IP atual ou dispositivo de acesso não tem permissão para fazer login, entre em contato com o administrador! +user.passwordCheckError=O formato da senha não atende às regras de força da senha! +admin.role.administrator=Administrador do sistema +admin.role.group=Administrador de Departamento +admin.role.default=usuário geral +admin.role.ignoreExt=Restrições de extensão +admin.role.ignoreExtDesc=Tipos de arquivo que não podem fazer upload, não há restrições quanto ao conteúdo vazio +admin.role.ignoreFileSize=Carregar limite de tamanho de arquivo +admin.role.ignoreFileSizeDesc=Upload de arquivo único máximo, 0 é ilimitado +admin.role.ignoreExtTips=Desculpe, as configurações atuais do sistema não suportam esse tipo de upload de arquivo; entre em contato com o administrador para obter detalhes! +admin.role.ignoreFileSizeTips=Desculpe, quando o arquivo exceder o limite de tamanho; entre em contato com o administrador para obter detalhes! +admin.role.desc=Descrição da função +admin.role.adminDesc=Super administrador, tem direitos de gerenciamento de servidor; todas as configurações de arquivos e pastas são inválidas para este usuário! +admin.role.read=Ler +admin.role.readList=Lista de arquivos +admin.role.readInfo=Visualização de atributo de arquivo (pasta), pesquisa de pasta +admin.role.readCopy=Cópia de arquivo +admin.role.readPreview=Visualização de arquivo (fotos, documentos, áudio e vídeo, etc.) +admin.role.readDownload=Download do arquivo (pasta) +admin.role.write=Escreva +admin.role.writeAdd=Crie arquivos (pastas), comprima e descompacte arquivos +admin.role.writeChange=Renomear, ajustar a estrutura de diretórios +admin.role.writeUpload=Upload de arquivo (pasta), download remoto +admin.role.writeRemove=Arquivo (pasta) excluir, cortar +admin.role.adminSetDesc=O administrador do sistema tem todas as permissões, sem necessidade de definir! +admin.role.displayDesc=Se deve ser exibido ao definir funções de usuário +admin.role.defaultRoleDesc=Dica: O sistema possui funções internas por padrão e não suporta a modificação de permissões. Você pode criar novas funções +admin.role.actionSetTitle=Documentação e configuração +admin.role.userSetTitle=Dados de configuração do usuário +admin.role.adminSetTitle=Funções em segundo plano +admin.role.fileAdd=Novo arquivo (pasta) +admin.role.fileRemove=Exclusão de documentos +admin.role.fileMove=Mover (operação de copiar / recortar / colar / arrastar) +admin.role.userConfig=Modificação da configuração (definir avatar / alterar senha, etc.) +admin.role.userEdit=Editar usuário (adicionar / modificar / excluir) +admin.role.userFav=Operação Favoritos +admin.role.itemEdit=Adicionar / modificar / excluir +admin.role.groupEdit=Editar departamento (adicionar / modificar / excluir) +admin.role.delErrTips=O personagem está sendo usado e não pode ser excluído! +admin.authFrom.setUser=Especifique suas próprias permissões +admin.authFrom.setGroup=Especifique a autoridade do departamento +admin.authFrom.setAll=Outras permissões de usuário +admin.authFrom.groupAt=Autoridade do departamento +admin.authFrom.groupParent=Autoridade de departamento superior +admin.authFrom.pathOnly=Apenas o acesso, o nível inferior tem conteúdo e permissão +admin.authFrom.groupRoot=diretório raiz do departamento +admin.auth.owner=Proprietário +admin.auth.editor=Editor +admin.auth.editUploader=Editar / remetente +admin.auth.viewer=Visualizador +admin.auth.previewer=Previewer +admin.auth.uploader=Uploader +admin.auth.invisible=Invisível +admin.auth.user=Dados do usuário +admin.auth.pathDelete=Exclusão de arquivo +admin.auth.pathInfo=Atributos de arquivo +admin.auth.pathMove=Mover (operação de copiar / recortar / colar / arrastar) +admin.auth.canUpload=Carregar download +admin.auth.config=Dados de configuração +admin.auth.fav=Operação Favoritos (adicionar / editar / excluir) +admin.auth.extWarning=O upload desses arquivos não é permitido,
    Renomear (renomeado para a extensão especificada),
    Editar salvar, baixar remotamente, descomprimir +admin.auth.error=Erro na função de permissão (sem configurações de permissão) +admin.auth.errorAdmin=Autoridade insuficiente +admin.auth.targetError=O tipo de objeto de permissão está incorreto, deve ser usuário ou departamento +admin.auth.errorAuthToGroup=Departamento não raiz, não suporta delegação para departamentos +admin.auth.errorAuthToUsers=Setor não raiz, não suporta delegação a membros fora do setor +admin.auth.displayDesc=Se deve ser exibido ao definir permissões de usuário do departamento +admin.auth.defaultAuthDesc=Dica: O sistema possui um grupo de permissões interno por padrão e não suporta a modificação de permissões. Você pode criar novos grupos de permissão +admin.auth.show=Lista de arquivos +admin.auth.showAction=Visualização de lista de arquivos +admin.auth.view=Visualização do arquivo +admin.auth.viewAction=Visualização de arquivo aberto +admin.auth.download=Download / cópia +admin.auth.downloadAction=Download / cópia / visualização do arquivo +admin.auth.uploadAction=Upload de arquivo (pasta) / download remoto +admin.auth.edit=Editar novo +admin.auth.editAction=Novo arquivo (pasta) / Renomear / Colar na pasta / Editar arquivo / Definir notas / Criar cópia / Descompactar +admin.auth.removeAction=Cortar / copiar / mover +admin.auth.shareAction=Compartilhamento de cadeia externa / compartilhamento de colaboração com outras pessoas +admin.auth.comment=Comentários do documento +admin.auth.commentAction=Ver comentários do documento; adicionar / excluir seus próprios comentários (permissão de edição necessária) +admin.auth.event=Dinâmica de documentos +admin.auth.eventAction=Visualização dinâmica de documentos, dinâmica de assinatura +admin.auth.root=Direitos administrativos +admin.auth.rootAction=Definir permissões de membro / gerenciamento de comentários / gerenciamento de versão do histórico +admin.auth.delErrTips=Esta permissão está sendo usada e não pode ser excluída! +admin.plugin.center=Centro de plug-ins +admin.plugin.installed=Instalado +admin.plugin.type=Categoria +admin.plugin.typeFile=Aprimoramento de arquivo +admin.plugin.typeSafe=Ferramentas de segurança +admin.plugin.typeTools=Utilitário +admin.plugin.typeMedia=Multimídia +admin.plugin.typeCompany=Aplicativo corporativo +admin.plugin.typeOem=Personalização exclusiva +admin.plugin.needNetwork=Extranet +admin.plugin.install=Instale o plugin +admin.plugin.enable=Ativar plugin +admin.plugin.remove=Desinstalar plugin +admin.plugin.config=Configurar plug-in +admin.plugin.statusEnabled=Ativado +admin.plugin.statusDisabled=Não habilitado +admin.plugin.statusNotInstall=Não instalado +admin.plugin.installing=Instalando ... +admin.plugin.hasUpdate=Update +admin.plugin.updateStart=Atualizar plugin +admin.plugin.needConfig=Requer configuração inicial para ativar +admin.plugin.notNull=Os campos obrigatórios não podem estar em branco! +admin.plugin.auther=Autor +admin.plugin.downloadNumber=Instala +admin.plugin.back=Retorno +admin.plugin.detail=Descrição do produto +admin.plugin.resetConfig=Restaurar configurações padrão +admin.plugin.installSelf=Instalação manual +admin.plugin.updateSelf=Atualização manual +admin.plugin.updateAll=Atualizar tudo +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=Erro de rede. Verifique se o servidor pode acessar a Internet. +admin.plugin.auth=Direitos de uso +admin.plugin.authDesc=Disponibilize todos, ou especifique usuários, grupos de usuários e grupos de permissão para usar +admin.plugin.authOpen=Acesso aberto +admin.plugin.authOpenDesc=Pode ser acessado sem login, pode ser usado para chamadas de interface externa +admin.plugin.authAll=Todos +admin.plugin.authUser=Usuário especificado +admin.plugin.authGroup=Departamento designado +admin.plugin.authRole=Especifique o grupo de permissões +admin.plugin.openWith=Estilo aberto +admin.plugin.openWithDilog=Diálogo interno +admin.plugin.openWithWindow=Abre uma nova página +admin.plugin.fileSort=Prioridade de associação de extensão +admin.plugin.fileSortDesc=Quanto maior a extensão, maior a prioridade +admin.plugin.fileExt=Formatos de arquivo suportados +admin.plugin.fileExtDesc=Extensão associada ao plug-in +admin.plugin.tabServer=Configuração do servidor +admin.plugin.defaultAceEditor=Editor Ace +admin.plugin.defaultHtmlView=Visualização da Web +admin.plugin.defaultZipView=Descompressão online +admin.plugin.authViewList=Lista de plugins +admin.plugin.authStatus=Abrir fechar +admin.plugin.authInstall=Instalar / desinstalar +admin.plugin.disabled=O plug-in não existe ou não foi iniciado +admin.plugin.menuAdd=Se deseja adicionar ao menu principal +admin.plugin.menuAddDesc=Use como um aplicativo independente +admin.plugin.menuSubMenuDesc=Encolher no menu [Mais] +admin.storage.type=Tipo de armazenamento +admin.storage.local=Local +admin.storage.localStore=Armazenamento local +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=Qiniu Clouds +admin.storage.s3=Amazon S3 +admin.storage.ftp=FTP +admin.storage.oos=Tianyi Cloud OOS +admin.storage.moss=Hongshan MOSS +admin.storage.eos=XSKY EOS +admin.storage.nos=NOS de nuvem anterior +admin.storage.minio=MinIO +admin.storage.uss=Pegue outra nuvem USS +admin.storage.eds=Sangfor EDS +admin.storage.driver=Disco local +admin.storage.useage=Uso de espaço +admin.storage.default=Definir como padrão +admin.storage.current=Padrão atual +admin.storage.edit=Armazenamento de configuração +admin.storage.setConfig=Modificar configuração +admin.storage.moveData=Migrar dados +admin.storage.delStore=Desmontar armazenamento +admin.storage.ifMove=Este armazenamento contém {0} arquivos de disco de rede e será migrado para o armazenamento padrão atual. Deseja continuar? +admin.storage.ifDel=Tem certeza de que deseja desmontar o armazenamento atual? +admin.storage.ifDelWithFile=Este armazenamento contém {0} arquivos de disco de rede, que serão migrados para o armazenamento padrão atual quando excluídos. Deseja continuar? +admin.storage.sysFile=Arquivos de disco de rede: arquivos em espaço pessoal e departamentos +admin.storage.delErrTips=Êxito:%s; Falha:%s, tente novamente ou migre manualmente +admin.storage.delLocTips=Por favor, mantenha pelo menos uma loja local +admin.storage.delStoreTips=Este armazenamento contém dados de backup, processe-os antes de continuar! +admin.storage.nameDesc=Nome de armazenamento para distinguir diferentes armazenamentos +admin.storage.path=Diretório de armazenamento +admin.storage.pathLocDesc=Diretório de armazenamento de arquivos, verifique se o diretório preenchido possui permissões de leitura e gravação +admin.storage.pathDesc=Diretório de armazenamento de arquivos +admin.storage.defaultDesc=O item padrão é o único armazenamento de sistema válido. Se você optar por ativá-lo, outros métodos de armazenamento padrão serão cancelados automaticamente. Opere com cuidado. +admin.storage.forceEdit=Modificação obrigatória +admin.storage.editTips=Após a abertura, você pode editar os campos de modificação proibidos. O arquivo antes do armazenamento pode não estar acessível, tenha cuidado. +admin.storage.folderTips=O local de armazenamento de arquivos do sistema atual, opere com cuidado +admin.storage.sizeTips=O tamanho do espaço deve ser maior que 0 +admin.storage.sizeDesc=(GB), preencha de acordo com o espaço livre real do diretório de armazenamento selecionado +admin.storage.region=Área de armazenamento +admin.storage.domain=Nome de domínio do espaço +admin.storage.bucket=Nome do bloco +admin.storage.bucketDesc=Nome do intervalo preenchido ao criar espaço +admin.storage.userName=Nome da conta +admin.storage.userPwd=Senha da conta +admin.storage.server=Endereço do servidor +admin.storage.serverDesc=ftp (s): // ip, o padrão é ftp sem protocolo +admin.storage.refer=Referência: +admin.storage.endpoint=Ponto final +admin.storage.ossDomain=Nome de domínio vinculado no espaço OSS +admin.storage.ossKeyDesc=ID da chave de acesso da conta Alibaba Cloud, crie ou visualize em [Painel de controle - Gerenciamento de chaves de acesso] +admin.storage.ossSecretDesc=Segredo chave de acesso da conta Alibaba Cloud +admin.storage.ossEndpoint=Endpoint, se você usa um nó de intranet, precisa habilitar a transferência do servidor +admin.storage.cosKeyDesc=Para acessar a ID da chave da conta Tencent Cloud, crie ou visualize em [Painel de controle - Gerenciamento de acesso - Gerenciamento de chaves da API] +admin.storage.cosSecretDesc=Segredo de chave de acesso da conta Tencent Cloud +admin.storage.qiniuDomain=Nome de domínio vinculado pelo Qiniu Space +admin.storage.qiniuKeyDesc=Chave de acesso para a conta Qiniu, crie ou visualize em [Painel de controle - Gerenciamento de chaves do centro pessoal] +admin.storage.qiniuSecretDesc=Chave secreta para a conta Qiniu, o método de obtenção é o mesmo que acima +admin.storage.qnz0=Leste da China - Zhejiang +admin.storage.qnz02=Leste da China - Zhejiang 2 +admin.storage.qnz1=Norte da China - Hebei +admin.storage.qnz2=Sul da China - Guangdong +admin.storage.qnna0=América do Norte - Los Angeles +admin.storage.qnas0=Ásia-Pacífico - Cingapura +admin.storage.qnas02=Ásia-Pacífico - Seul +admin.storage.awsDomain=Nome de domínio vinculado no espaço da AWS +admin.storage.awsKeyDesc=Para acessar a ID da chave da conta da AWS, crie-a em [Painel de controle - Suas credenciais de segurança] +admin.storage.awsSecretDesc=Segredo da chave de acesso para a conta da AWS +admin.storage.oosDomain=Nome do domínio ligado ao Tianyi Cloud Space +admin.storage.oosKeyDesc=Para acessar a ID da chave da conta Tianyi Cloud, crie-a em [Painel de controle - Suas credenciais de segurança] +admin.storage.oosSecretDesc=O segredo da chave de acesso da conta na nuvem Tianyi é o mesmo que acima +admin.storage.ftpDisabled=O FTP não está disponível, ative a extensão php_ftp +admin.storage.ifDefaultTips=Esta operação cancelará outros métodos de armazenamento padrão. +admin.storage.spaceUsed=Uso prático +admin.storage.spaceLave=Montante restante +admin.storage.delError=O arquivo já existe neste armazenamento e não pode ser excluído +admin.storage.corsError=Se a configuração estiver correta, clique em [Use Help] para verificar as configurações de domínio cruzado do bucket. +admin.storage.saveError=Não foi possível conectar ao armazenamento especificado, verifique se as informações de configuração estão corretas. +admin.storage.ftpCharset=Codificação de servidor FTP +admin.storage.ftpCharsetDesc=Se o servidor FTP for Windows, ele poderá ser definido como GBK de acordo com a situação; +admin.storage.ftpPasvOn=Ligar +admin.storage.ftpPasvOff=fecho +admin.storage.ftpPasv=Modo passivo +admin.storage.ftpPasvDesc=Modo de transferência de dados +admin.storage.uploadSrv=Transferência de servidor (upload) +admin.storage.fileoutSrv=Transferência de servidor (download) +admin.storage.uploadSrvDesc=Depois de ligado, o arquivo será carregado para o armazenamento de objetos através do servidor, caso contrário, será carregado diretamente através do cliente. +admin.storage.fileoutSrvDesc=Depois de ligado, o arquivo de armazenamento será obtido através do servidor para download, caso contrário, o arquivo será obtido para download direto. +admin.storage.closeDefError=Proibir desligar o armazenamento padrão +admin.storage.ussBucket=Nome do Serviço +admin.storage.ussBucketDesc=Nome do serviço de armazenamento em nuvem +admin.storage.ussUser=Nome do operador +admin.storage.ussUserDesc=Nome do operador +admin.storage.ussUserPwd=Senha do operador +admin.storage.ussDomain=Tire outra foto do nome de domínio vinculado ao espaço da nuvem +admin.storage.ussToken=Token anti-sanguessuga +admin.storage.ussTokenDesc=Chave secreta da cadeia anti-roubo de token (não necessária) +admin.storage.configError=O parâmetro de configuração é anormal! +admin.storage.sizePercent=Proporção do arquivo do sistema: +admin.storage.fileCount=Número de arquivos: +admin.storage.error=Exceção de armazenamento +admin.task.name=Nome da tarefa +admin.task.edit=Edição de tarefas +admin.task.type=Tipo de tarefa +admin.task.method=Métodos incorporados +admin.task.methodName=Nome do método +admin.task.methodDesc=Consiste no nome do método do módulo-controlador-método do sistema, preencha cuidadosamente. +admin.task.url=URL de solicitação +admin.task.urlDesc=Endereço URL definido pelo usuário, tarefas agendadas para executar solicitações regularmente. +admin.task.cycle=Ciclo de execução +admin.task.desc=detalhes da missão +admin.task.nMinutes=N minutos +admin.task.default=Padrão do sistema +admin.task.timeInterval=Tempo de intervalo +admin.task.timeStart=Hora de início +admin.task.timeStartRun=Iniciar tempo de execução +admin.task.timeLastRun=Último tempo de execução +admin.task.timeLastLogin=Hora de início de sessão +admin.task.isOpen=Se deve ativar +admin.task.open=Aberto +admin.task.content=Conteúdo de implementação +admin.task.param=Parâmetro de execução +admin.task.ifRun=Tem certeza de que deseja executar esta tarefa? +admin.task.backup=backup de dados +admin.task.backupDesc=Comece a fazer backup dos dados do sistema às 02:00 todos os dias. +admin.install.install=Instalação do sistema +admin.install.databaseSet=Configuração do banco de dados +admin.install.dataUpdate=Migração de dados +admin.install.installSuccess=Instalado com sucesso +admin.install.dbWasSet=Você configurou o banco de dados.Se precisar redefinir, você pode modificar a configuração no arquivo config / setting_user.php e reinstalá-lo! +admin.install.errorRequest=O sistema está instalado, nenhuma solicitação adicional é permitida +admin.install.databaseError=Erro de conexão com o banco de dados, verifique a configuração +admin.install.cacheError=%s conexão falhou, verifique a configuração +admin.install.cacheConnectError=%s não pode se conectar ao servidor, verifique a configuração +admin.install.dbSetError=Falha na gravação das informações de configuração do banco de dados +admin.install.dbCreateTips=O banco de dados não existe e a criação automática falha. Crie-o manualmente +admin.install.ifDelDb=Os dados já existem no banco de dados especificado.Clique em [OK] para excluí-los. Deseja continuar? +admin.install.dbCreateError=Exceção de criação da tabela de dados +admin.install.dbFileError=O arquivo de banco de dados não existe +admin.install.dbTypeError=O tipo de banco de dados selecionado (%s) não está disponível, instale o serviço e a extensão correspondentes ou escolha outro tipo +admin.install.createSuccess=Criado com sucesso +admin.install.defSetError=A configuração padrão do sistema falhou ao adicionar +admin.install.defStoreError=Falha na adição de armazenamento padrão +admin.install.defPathError=Falha na adição do diretório do sistema +admin.install.defAdminError=Falha ao adicionar conta de administrador +admin.install.defRoleError=Falha na adição de função padrão +admin.install.defGroupError=Falha na adição do departamento do sistema +admin.install.dataPathNotExists=diretório de dados não existe +admin.install.defaultUpdate=Atualização de informações de configuração do sistema +admin.install.pluginUpdated=Atualização do plug-in concluída +admin.install.defCacheError=Exceção inicial de dados do cache do diretório +admin.install.serverDir=Diretório de colunas do servidor +admin.install.dirRight=Permissões de diretório +admin.install.suggestOpen=Sugerido para abrir +admin.install.suggestClose=Recomendado para fechar +admin.install.phpVersionTips=PHP5.3 e acima +admin.install.phpBitTips=Recomendado de 64 bits +admin.install.phpBitDesc=32 bits não suporta upload e download de arquivos acima de 2G +admin.install.pathNeedWirte=O diretório do programa e todos os subdiretórios precisam ser legíveis e graváveis +admin.install.mustOpen=Deve abrir +admin.install.setPathWrt=Defina as permissões de leitura e gravação para o diretório do projeto +admin.install.ensureNoError=Verifique se o seguinte está correto: +admin.install.setAdminName=Por favor, configure uma conta de administrador +admin.install.setAdminPwd=Por favor, defina uma senha de administrador +admin.install.database=Banco de Dados +admin.install.dbType=Tipo de banco de dados +admin.install.dbName=Nome do banco de dados +admin.install.userName=Nome de usuário +admin.install.dbPort=Número da porta +admin.install.dbPortDesc=A porta padrão é 3306, se você precisar personalizá-la, pode anexá-la, como: 127.0.0.1:3307 +admin.install.dbEngine=Mecanismo de armazenamento +admin.install.sqliteDesc=O PHP possui um banco de dados leve verde embutido (adequado para teste ou uso em pequena escala). +admin.install.mysqlDesc=Oferece suporte à implantação de cluster, separação de bancos de dados mestre e escravo. +admin.install.pdoDesc=Um driver geral de banco de dados mais seguro requer que o PHP tenha a extensão PDO instalada. +admin.install.cacheType=Tipo de cache do sistema +admin.install.cacheTypeDesc=Usado para armazenar em cache dados gerais e sessões para acelerar o acesso ao sistema +admin.install.fileCache=Cache de arquivo +admin.install.groupFile=Documento do Departamento +admin.install.userFile=Documentação do usuário +admin.install.role=Função +admin.install.fileAuth=Permissões de documento +admin.install.userList=Lista de usuários +admin.install.setInfo=Informações de configuração do sistema +admin.install.favShare=Favoritos e compartilhamentos de usuários +admin.install.waitUpdate=Aguardando atualização +admin.install.updateSuccess=Atualização bem-sucedida +admin.install.fileCount=Número de arquivos +admin.install.settingDesc=Itens de falha podem ser configurados manualmente no gerenciamento em segundo plano +admin.install.reInstallTips=O resultado do retorno é anormal, reinstale +admin.log.accountEdit=Modificar informações da conta +admin.log.thirdBind=Vincular uma conta de terceiros +admin.log.delBind=Desvincular +admin.log.viewFile=arquivo de visualização +admin.log.delFile=Excluir arquivo +admin.log.editFile=Editar arquivo +admin.log.downFile=Baixar arquivo +admin.log.downFolder=Pasta de download +admin.log.moveFile=Mover arquivo +admin.log.addUser=Adicionar usuário +admin.log.editUser=Editar usuário +admin.log.addUserTo=Adicionar usuários ao departamento +admin.log.removeUserFrom=Usuário removido do departamento +admin.log.switchUserGroup=Migrar usuários para departamentos +admin.log.stausUser=Ativar / desativar usuários +admin.log.addRole=Novo papel +admin.log.editRole=Editar função +admin.log.delRole=Excluir função +admin.log.addAuth=Adicionar permissões +admin.log.editAuth=Editar permissões +admin.log.delAuth=Excluir permissão +admin.log.editShare=Editar compartilhamento +admin.log.delLinkTo=Cancelar compartilhamento de link externo +admin.log.delShareTo=Cancelar compartilhamento colaborativo +admin.log.recycleTo=Mover para a lixeira +admin.log.newName=Novo nome +admin.log.oldName=Nome original +admin.log.newPath=Novo catálogo +admin.log.oldPath=Catálogo original +admin.log.typeFile=Operações de arquivo +admin.log.typeUser=Configuração do usuário +admin.log.queryByIp=Clique no botão para consultar os registros do dia com base no IP. +admin.backup.setting=Configurações de backup +admin.backup.edit=Edição de backup +admin.backup.ing=Fazendo backup +admin.backup.success=Backup bem-sucedido +admin.backup.fail=Falha no backup +admin.backup.complete=Backup concluído +admin.backup.db=base de dados +admin.backup.dbFile=arquivo de banco de dados +admin.backup.fileError=Falha no backup de alguns arquivos +admin.backup.checkLog=Verifique o log de backup: data/temp/log/backup/date of the day__log.php +admin.backup.pathNoWrite=O diretório temporário não tem permissão de gravação +admin.backup.errorMsg=Parte do backup do arquivo falhou, você pode copiar manualmente de acordo com o log ou excluir e fazer backup novamente. +admin.backup.logFile=Arquivo de log +admin.backup.manual=Backup manual +admin.backup.continue=Continuar backup +admin.backup.start=Iniciar backup +admin.backup.open=Ativar backup +admin.backup.notOpen=O backup não está ativado +admin.backup.location=Local de backup +admin.backup.content=Conteúdo de backup +admin.backup.dbOnly=base de dados +admin.backup.time=Tempo de backup +admin.backup.notStart=não começou +admin.backup.notEnabled=Não habilitado +admin.backup.killed=sobre +admin.backup.ifKill=Tem certeza de que deseja finalizar esse backup? +admin.backup.kill=Fim +admin.backup.error=Abortar +admin.backup.timeBeen=Demorado +admin.backup.timeTotal=Tempo total +admin.backup.backed=Backup +admin.backup.storage=Por favor, crie um armazenamento dedicado para backup. +admin.backup.ifSave=O backup demora muito tempo. Tem certeza de que deseja fazer backup? +admin.backup.ifContinue=Tem certeza de que deseja continuar o backup? +admin.backup.saveTips=A tarefa de backup foi enviada. Seja paciente. +admin.backup.fileSize=Tamanho do documento +admin.backup.dbSize=Tamanho do banco de dados +admin.backup.dbCnt=total +admin.backup.notFinished=Não completo +admin.backup.timeTaken=demorado +admin.backup.node=nó +admin.backup.notYet=Não +admin.backup.storeNotExist=O armazenamento de backup não existe, reinicie +admin.backup.timeNote=Nota: O sistema mantém apenas os backups de banco de dados dos últimos 7 dias e do dia 1º de cada mês. Tempo de backup: +admin.backup.recover=Entre em contato com o provedor de serviços para recuperação de dados. +admin.backup.optionTime=O backup leva muito tempo, por favor, tente escolhê-lo fora do horário de trabalho +admin.backup.optionLocation=Se você precisar fazer backup de arquivos, crie um novo armazenamento dedicado para backup +admin.backup.optionTips1=O backup é dividido em duas partes: backup de banco de dados e backup de arquivo. +admin.backup.optionTips2=Backup do banco de dados: Gere arquivos SQL do conteúdo do banco de dados e faça backup deles no diretório de banco de dados de armazenamento de destino. +admin.backup.optionTips3=Backup de arquivos: faça backup dos arquivos de armazenamento do sistema para o armazenamento de destino de forma incremental de acordo com o caminho de armazenamento original. +admin.backup.optionTips4=O sistema mantém apenas os backups de banco de dados dos últimos 7 dias e do dia 1º de cada mês. +admin.backup.needStorage=O armazenamento de backup não pode estar vazio +admin.backup.needNoDefault=Não escolha o armazenamento padrão como local de backup do arquivo +admin.backup.contentDesc=A versão licenciada suporta backup simultâneo de bancos de dados e arquivos +admin.backup.action=Gerenciamento de operação +admin.backup.recovery=redução +admin.backup.sysRecovery=Restauração do sistema +admin.backup.bakErr2Rec=Este backup está incompleto e não pode ser restaurado +admin.recycle.menu=Lixeira do sistema +admin.share.name=Nome de compartilhamento +admin.share.type=Tipo de compartilhamento +admin.share.expiryTime=Vencimento +admin.share.expired=expirado +admin.share.link=Link externo +admin.share.linkView=Clique para ver o compartilhamento +admin.share.ifDel=Tem certeza que deseja cancelar este compartilhamento? +admin.share.disFile=Este arquivo foi denunciado por usuários e seu compartilhamento foi proibido +admin.share.disFolder=Este diretório contém arquivos ilegais que são proibidos de serem compartilhados +admin.share.shareTab=Gerenciamento de compartilhamento +admin.share.reportTab=Compartilhando gerenciamento de relatórios +admin.share.rptType1=Pirataria +admin.share.rptType2=Pornografia obscena +admin.share.rptType3=Violência sangrenta +admin.share.rptType4=Política é prejudicial +admin.share.rptType5=outras razões +admin.share.doRptClose=Feche o relatório após processar o conteúdo compartilhado ou feche-o diretamente +admin.share.doRptDisable=Depois de proibir / permitir o compartilhamento, todos os recursos correspondentes ao arquivo serão afetados. Tem certeza de que deseja realizar esta operação? +admin.share.rptUser=Denunciante +admin.share.rptTitle=Compartilhamento de relatórios +admin.share.rptDesc=Razão para relatar +admin.share.rptTime=Hora do relatório +admin.share.rptResult=resultado do processo +admin.share.rptDone=Processado +admin.share.rptNoDone=Sem tratamento +admin.share.rptClose=Fechar relatório +admin.share.rptShareDel=Cancelar compartilhamento +admin.share.rptShareAllow=Permite compartilhamento +admin.share.rptShareDisable=Sem compartilhamento +admin.share.rptDoDisable=Proibir / permitir compartilhamento +admin.share.rptSelectTips=Selecione o item a ser operado! +admin.setting.transfer=Upload / download +admin.setting.transferChunkSize=Carregar tamanho do fragmento +admin.setting.transferChunkSizeDesc=Ao fazer upload de um arquivo grande, ele é cortado em pedaços para upload simultâneo, de modo a obter aceleração e retomar o currículo.
    Recomenda-se 5 milhões; esse valor deve ser menor que a seguinte configuração; caso contrário, causará uma exceção de upload (falha no upload, reversão) +admin.setting.transferChunkSizeDescError1=O tamanho do fragmento de upload não pode exceder a configuração no php.ini +admin.setting.transferChunkSizeDescError2=Modifique-o no php.ini e tente novamente (modifique upload_max_filesize, post_max_size, precisa reiniciar) +admin.setting.transferThreads=Fazendo upload de threads simultâneos +admin.setting.transferThreadsDesc=Recomendado = 10; uploads simultâneos de arquivos ou shards +admin.setting.transferIgnore=Carregar arquivo ignorar +admin.setting.transferIgnoreDesc=Faça o upload de nomes de arquivos que são automaticamente ignorados. Arquivos temporários podem ser excluídos, múltiplos separados por vírgulas, por exemplo: .DS_store, thumb.db +admin.setting.transferChunkRetry=Retransmissão automática quando o upload falha +admin.setting.transferChunkRetryDesc=Recomendação = 5; o número de retransmissões será executado automaticamente se o upload falhar; 0 significa que não há retransmissão automática +admin.setting.transferOsChunkSize=Tamanho do fragmento de armazenamento do objeto +admin.setting.transferOsChunkSizeDesc=Upload de armazenamento de objeto, o tamanho do fragmento varia de 5 MB a 5 GB e o número máximo de solicitações é 1000, o que significa que o tamanho máximo de upload de arquivo é 5 TB.
    Recomenda-se 10 ~ 20 MB. No momento, o tamanho máximo de arquivo suportado é de 9,7 ~ 19,5 GB e os usuários podem ajustar o tamanho do arquivo carregado de acordo com suas necessidades. +admin.setting.transferHttpSendFile=Baixar aceleração do servidor web +admin.setting.transferHttpSendFileDesc=O download do arquivo é transmitido diretamente através do servidor da Web; a velocidade do download é aprimorada; só é efetiva quando o armazenamento padrão estiver configurado como armazenamento local. +admin.setting.downloadZipClient=Download compactado de front-end +admin.setting.downloadZipClientDesc=Precisa ser capaz de vincular à rede externa, ou o site é https +admin.setting.downloadZipLimit=Limite de tamanho de download compactado +admin.setting.downloadZipLimitDesc=0 significa sem limite; para evitar o consumo excessivo de desempenho do servidor, o download do pacote é restrito quando a pasta é muito grande e é solicitado que o arquivo possa ser baixado diretamente pelo cliente do PC +admin.setting.downloadZipLimitTips=O conteúdo compactado excede o limite do sistema, entre em contato com o administrador! Você pode baixar a pasta diretamente pelo cliente do PC sem compactação. +admin.setting.dragDownload=Arraste e solte na área de trabalho para baixar +admin.setting.dragDownloadDesc=Suportado apenas pelo navegador do kernel Chrome do lado do PC (chrome edge 360 fast, etc.) +admin.setting.dragDownloadZip=Download de compactação de arrastar e soltar com seleção múltipla +admin.setting.dragDownloadZipDesc=Suporte para download de seleção múltipla ou arrastar e soltar pasta, deve ser empacotado e compactado no servidor antes do download +admin.setting.dragDownloadLimit=Arraste e solte o limite de tamanho do conteúdo +admin.setting.dragDownloadLimitDesc=0 significa sem limite. O tamanho do conteúdo arrastado estará sujeito a esse limite. Como não há uma barra de progresso para arrastar e fazer download do Chrome no momento, ele não pode ser cancelado. Recomenda-se limitar o tamanho a 20 M. +admin.setting.dragDownloadUrlTips=O URL é muito longo, reduza a seleção e tente novamente! +admin.setting.dragDownloadOpenTips=Entre em contato com o administrador para habilitá-lo nas configurações em segundo plano! +admin.setting.dragDownloadNotOpen=O download de arrastar e compactar não está ativado +admin.setting.dragDownloadSizeTips=O tamanho do conteúdo arrastado excede o limite +admin.setting.showFileSafe=Segurança de acesso a arquivos +admin.setting.showFileLink=Exibição do link externo do arquivo +admin.setting.showFileLinkDesc=Após o fechamento, as propriedades do arquivo não mostram mais links externos +admin.setting.showFileMd5=exibição de arquivo md5 +admin.setting.showFileMd5Desc=Após o fechamento, as propriedades do arquivo não mostram mais o arquivo md5 +admin.setting.shareLinkAllow=Ativar compartilhamento de link externo +admin.setting.shareLinkAllowDesc=Após o fechamento, ele não oferecerá mais suporte ao compartilhamento de cadeia externa e o conteúdo compartilhado não será afetado +admin.setting.shareLinkAllowTips=O sistema atual desativou o compartilhamento de link externo, entre em contato com o administrador! +admin.setting.shareLinkPasswordAllowEmpty=O compartilhamento de cadeia externa permite que a senha fique vazia +admin.setting.shareLinkPasswordAllowEmptyDesc=Após o fechamento, uma senha deve ser definida para compartilhamento de link externo; o conteúdo compartilhado não será afetado +admin.setting.shareLinkAllowGuest=O compartilhamento de link externo permite que visitantes não logados acessem +admin.setting.shareLinkAllowGuestDesc=Após o fechamento, você deve fazer login ao acessar links externos; o conteúdo compartilhado não será afetado +admin.setting.shareLinkZip=Download do pacote de compartilhamento de link externo +admin.setting.shareLinkZipDesc=Após a abertura, a pasta de compartilhamento de cadeia externa suporta download de compactação e empacotamento.Se a simultaneidade for grande, o desempenho do servidor será consumido. +admin.setting.shareLinkZipTips=O compartilhamento de link externo desativa downloads empacotados, entre em contato com o administrador para configuração! +admin.setting.transferDownSpeed=Limite de velocidade de download +admin.setting.transferDownSpeedDesc=Limite a velocidade de download e uniformemente a velocidade de grandes sites simultâneos +admin.setting.transferDownSpeedNum=Limite de velocidade de download +admin.setting.transferDownSpeedNumDesc=Limite a velocidade do download e você pode limitar uniformemente a velocidade do site com grande simultaneidade.
    Nota: A velocidade do servidor é limitada aqui.A velocidade de download específica também é afetada pela largura de banda do servidor e pela rede do usuário. +explorer.uploadSizeError=Seu servidor atualmente não suporta arquivos acima de 2G,
    Atualize para o php de 64 bits; recomenda-se o php7 de 64 bits
    (Nota: o sistema operacional de 64 bits pode instalar apenas o PHP de 64 bits); +common.width=Ampla +common.height=Alta +common.test=Teste +common.absolutePath=Endereço absoluto +common.qrcode=Código QR do URL +common.wechat=WeChat +common.group=Departamento +common.user=Usuário +common.online=Em linha +common.use=Usar +common.total=Total +common.year=Ano +common.month=Mês +common.week=Semana +common.daytime=Dia +common.mon=na segunda-feira +common.tue=na terça-feira +common.wed=na quarta-feira +common.thu=Quinta-feira +common.fri=Sexta-feira +common.sat=no sábado +common.sun=domingo +common.second=Segundo +common.minute=Minutos +common.hour=Horas +common.day=Dia +common.every=cada +common.everyMonth=por mês +common.everyWeek=semanal +common.everyDay=todo dia +common.language=Língua +common.all=Todos +common.item=Item +common.items=Conteúdo do item +common.itemsEmpyt=Sem conteúdo +common.detail=Detalhes +common.me=Eu +common.others=Outros +common.guest=Visitantes +common.more=Mais +common.learnMore=Aprenda mais +common.yes=Sim +common.no=Não +common.omit=Omitir +common.unknow=Desconhecido +common.title=título +common.time=Tempo +common.scan=Squeaky toy +common.report=Relatório +common.name=Nome +common.nickName=Apelido +common.tools=Ferramentas +common.tag=Tags +common.position=Localização +common.mount=Montagem em rede +common.type=Tipo +common.auth=Autoridade +common.status=Status +common.run=Executar +common.file=Ficheiro +common.folder=Pasta +common.fileType=Tipo de arquivo +common.fileSize=Tamanho do arquivo +common.attributeInfo=Informações sobre atributos +common.actionType=Tipo de operação +common.isDisplay=Se mostrar +common.hide=Esconder +common.isHide=Escondido +common.cancelHide=Mostrar +common.default=padrão +common.display=Mostrar +common.moveDown=Mover para baixo +common.moveUp=Mover para cima +common.drag=Arrastar +common.dragSort=Arraste para ajustar a ordem +common.warning=Advertência +common.tips=Sugestão +common.desc=instrução +common.tipsDesc=Descrição do prompt +common.tipsOthers=Outras instruções +common.view=Visão +common.log=Registro +common.task=tarefa +common.important=Importante +common.icon=Ícone +common.menu=Menu +common.system=sistema +common.basic=Universal +common.systemSet=Configuração do sistema +common.systemDefault=Padrão do sistema +common.diy=Custom +common.input=Por favor insira +common.select=Por favor selecione +common.add=Adicionar +common.edit=Editar +common.action=Operação +common.upload=Carregar +common.uploadTo=enviar para +common.download=Baixar +common.export=Exportar +common.cover=Cover +common.retry=Repetir +common.zip=Comprimido +common.unzip=Descompacte +common.preview=Pré-visualização +common.share=Compartilhe +common.search=Pesquisar +common.query=Investigar +common.delete=Excluir +common.deleteForce=Remova completamente +common.deleteEnd=apagado +common.refresh=Atualizar +common.open=Aberto +common.close=Fechar +common.from=fonte +common.greater=Maior que +common.less=Menos que +common.print=Impressão +common.selectInvert=Eleição reversa +common.selectAll=Selecionar Tudo / Selecionar Reversa +common.selectAllItem=Selecionar tudo +common.selectNum=Selecionado +common.selectNull=Nenhuma +common.sizeMore=o de cima +common.showMore=Desdobrar +common.showLess=Colapso +common.sizeSmall=pequena +common.sizeMiddle=no +common.sizeBig=Grande +common.rename=Renomear +common.method=Função +common.extend=Extensão +common.fav=Favorito +common.reset=Reset +common.testing=Teste +common.install=Instalação +common.update=Update +common.version=Versão +common.sysVersion=Versão da plataforma +common.login=Entrar +common.regist=Inscrição +common.password=Senha +common.operateTime=Tempo de operação +common.createTime=Tempo de criação +common.modifyTime=Tempo de modificação +common.activeTime=Hora do arquivo +common.startTime=Hora de início +common.endTime=Fim do tempo +common.finishTime=Fim do tempo +common.disable=Desativar +common.goOn=Continuar +common.ok=OK +common.startRun=Começar +common.confirmTips=Por favor confirme novamente +common.confirmAsk=Tem certeza de que deseja realizar esta operação? +common.submit=Enviar +common.skip=Pular +common.nextStep=Próximo passo +common.start=Iniciar +common.stop=pausa +common.set=Configurar +common.cancel=Cancelar +common.save=Salvar +common.empty=Sem conteúdo! +common.isOpen=Ligadas +common.isClose=fechado +common.apply=Aplicação +common.saveAll=Salvar tudo +common.notSave=Não salve +common.appAdd=Adicionar +common.backAdd=Voltar para adicionar +common.saveEdit=Salvar alterações +common.saveSubmit=Salvar confirmação +common.saveAndAdd=Salve e continue adicionando +common.sex=Sexo +common.male=Masculino +common.female=Feminino +common.address=Morada +common.email=E-mail +common.phone=Celular +common.sms=Sms +common.phoneNumber=Número de telefone +common.server=Servidor +common.handheld=Dispositivo móvel +common.success=Êxito +common.fail=falha +common.error=Errado +common.result=resultado +common.expired=Expirado +common.valid=Eficaz +common.inAll=total +common.allAndNull=Selecionar Tudo / Cancelar +common.moveTop=Topo +common.moveBottom=Definido no final +common.moveTopCancle=Desvincular +common.ECN=Leste da China +common.NCN=Norte da China +common.SCN=Sul da China +common.USA=América do Norte +common.SEA=Sudeste da Ásia +common.noLimit=não limitado +common.notExists=Não existe +common.cannotWrite=Somente leitura, não gravação +common.readOnly=Somente leitura +common.cannotRead=Ilegível +common.ifDel=Tem certeza de que deseja excluir? +common.pageNotExists=A página não existe! +common.pathNotExists=O documento não existe! +common.fileShare=Partilha de documentos +common.logining=A iniciar sessão ... +common.loginTokenError=O login expirou, faça o login novamente! +common.loginSuccess=Login efetuado com sucesso! +common.loginError=Falha no login +common.connectSuccess=Conectado com sucesso! +common.bindSuccess=Vincular com sucesso! +common.bindError=Falha na ligação +common.clear=Vazio +common.congrats=Parabéns +common.sorry=Desculpe +common.invalid=Inválido +common.unavailable=indisponível +common.format=Formatar +common.noPermission=Permissão negada +common.allPermission=Todas as permissões +common.invalidParam=Parâmetro inválido +common.invalidFormat=Formato inválido +common.invalidRequest=Tipo de solicitação ilegal +common.illegalRequest=Pedido ilegal +common.expiredRequest=A solicitação expirou +common.errorExpiredRequest=Pedido inválido ou expirou +common.migrating=Migrando +common.migrated=Migração concluída +common.maintenanceTips=Durante a manutenção do sistema, visite mais tarde ... +common.done=concluído +common.disabled=Desativado +common.sizeTotal=Tamanho total +common.sqlStatement=[Instrução SQL]: +common.env.check=Ensaios ambientais +common.env.errorLib=Falta a biblioteca PHP +common.env.errorIgnore=Ignore e insira +common.env.errorVersion=A versão do PHP não pode ser inferior a 5.0 +common.env.errorPath=Não gravável +common.env.errorListDir=Seu servidor da Web tem a função de listagem de diretórios ativada. Desative-a por motivos de segurança! Como isso funciona? +common.env.errorGd=A biblioteca PHP GD deve estar ativada, caso contrário, o uso de códigos de verificação e miniaturas será anormal. +common.env.invalidExt=A extensão %s está indisponível, verifique se está instalada +common.env.installWithBtTips=A versão php do servidor requer 5.3 e acima. Não estou familiarizado com a configuração com um clique do painel de pagode recomendado.
    Versão atual +common.env.phpCacheOpenTips=Seu servidor possui o cache de php ativado e as atualizações de arquivos ainda não foram efetivadas;
    Desligue o cache ou atualize a página e tente novamente em 1 minuto!
    Aprenda mais +common.env.dataPathNotExists=O diretório de dados não existe!
    (Marque DATA_PATH); +common.env.pathPermissionError=[Código de erro: 1002] Erro de permissão do diretório! Por favor, defina o diretório do programa e todos os subdiretórios para ler e escrever.
    O linux executa o seguinte comando:
     su -c 'setenforce 0' 
    chmod -R 777 +common.version.free=Grátis +common.version.nameQ=Enterprise Edition +common.version.vipFree=Edição grátis +common.version.useFree=Continue a usar a versão gratuita +common.version.notSupport=Sua versão não suporta esta operação, acesse o site oficial para comprar a versão avançada! +common.version.notSupportNumber=Esta operação não é suportada devido ao número limitado, por favor, visite o site oficial para comprar a versão avançada! +common.version.toVip=Atualizar para Comercial +common.version.license=Autorização de compra +common.version.authCode=Código de ativação da autorização +common.version.authActive=Autorização de ativação +common.version.authorization=Autorização de registro +common.version.authorizeSuccess=Parabéns, a autorização para a atualização online foi bem-sucedida! +common.version.networkError=A solicitação ao servidor falhou. Verifique se o servidor pode acessar a rede.
    Nota: O servidor não pode ser um proxy para acessar a Internet +common.version.authActiveOnline=Ativar online +common.version.authActiveOffline=Ativar offline +common.version.offlineTips=O servidor não pode acessar a Internet? +common.version.menuTitle=Configurações de informações da empresa +common.version.timeout=expirado +common.version.timeToService=Tempo de expiração do serviço +common.version.timeTo=Tempo de expiração da autorização +common.version.licenseAll=Autorização perpétua +common.version.kodVersion=Versão do programa +common.version.userLimitTitle=Número do usuário +common.version.userUse=Usava +common.version.userAllow=Número de usuários com suporte +common.version.userTo=Objeto autorizado +common.version.userTitle=Informação de autorização +common.version.basicInfo=informação básica +common.version.appInfo=informação do produto +common.version.tipsWarning=Aviso, não modifique os direitos autorais sem permissão; se necessário, entre em contato para comprar! +common.version.tipsCopyLink=Copie com sucesso! Cole e salve no arquivo txt,
    Abra este link em um computador com uma rede através de uma unidade flash USB, etc. +common.version.tipsHistory=A versão gratuita suporta apenas 5 versões de histórico; compre um número ilimitado de versões licenciadas! +common.version.codeLink=Link de solicitação de código de autorização +common.version.codeLinkHelp=1. Copie o link acima e visite outros computadores com acesso à Internet.
    2. Preencha o "Código de autenticação da autorização" obtido acima e ative e autorize +common.copyright.logoTitle=Conjunto de logotipo de identidade corporativa +common.copyright.licenseInfo=Informações de autorização +common.copyright.licenseReset=Autorizar novamente +common.copyright.licenseResetTips=Reative para obter mais informações! +common.copyright.formLogo=Tipo de logotipo da página de login +common.copyright.formLogoTypeWord=Logotipo do texto +common.copyright.formLogoTypeImage=Logotipo da imagem +common.copyright.formLogoDesc=O logotipo do texto usa o nome da empresa e o logotipo da imagem usa a imagem definida da seguinte maneira. +common.copyright.formLogoImage=Imagem do logotipo da página de login +common.copyright.formLogoImageDesc=Página de login e logotipo de fundo de gerenciamento, tamanho recomendado 250x100, formato translúcido png +common.copyright.formLogoMain=Logotipo do menu da interface principal +common.copyright.formLogoMainDesc=Logotipo do canto superior esquerdo do gerenciamento de arquivos, tamanho recomendado 200x200, formato png translúcido branco +common.copyright.formPowerByInfo=Configurações de informações de direitos autorais da empresa +common.copyright.formPowerBy=Nome da empresa com direitos autorais inferior +common.copyright.formHomePage=Salto inferior do link de direitos autorais +common.copyright.formConcat=Contato pop-up +common.copyright.formDesc=Descrição detalhada da camada pop-up do produto +common.copyright.formDescTips=Depois que a modificação é salva, a página de atualização entra em vigor +common.copyright.formMetaKeywords=Palavras-chave do site (usadas pelos mecanismos de pesquisa) +common.copyright.formMetaName=Nome do site (usado pelos mecanismos de pesquisa) +common.copyright.downloadApp=Download do aplicativo +common.copyright.downloadLink= +common.copyright.about=Sobre +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=Identificação automática +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=Árabe +common.charset.ISO_8859_6=Árabe +common.charset.ISO_8859_10=Idioma nórdico +common.charset.CP1257=Idiomas ao redor do Báltico +common.charset.ISO_8859_13=Idiomas ao redor do Báltico +common.charset.ISO_8859_4=Idiomas ao redor do Báltico +common.charset.BIG5_HKSCS=Tradicional-Hong Kong +common.charset.BIG5=Taiwan tradicional +common.charset.Georgian_Academy=Georgiano +common.charset.PT154=Cazaque +common.charset.CP949=Coreano +common.charset.EUC_KR=Coreano +common.charset.GB18030=Chinês simplificado +common.charset.GBK=Chinês simplificado +common.charset.ISO_8859_14=Celta +common.charset.CP1133=Laos +common.charset.ISO_8859_16=Romeno +common.charset.ISO_8859_3=Línguas do sul da Europa +common.charset.EUC_JP=Japonês +common.charset.ISO_2022_JP=Japonês +common.charset.SHIFT_JIS=Japonês +common.charset.KOI8_T=Tadjique +common.charset.ISO_8859_11=Tailandês +common.charset.TIS_620=Tailandês +common.charset.CP1254=Turco +common.charset.CP1251=Cirílico +common.charset.ISO_8859_5=Cirílico +common.charset.KOI8_R=Cirílico +common.charset.KOI8_U=Cirílico +common.charset.CP1252=Línguas da Europa Ocidental +common.charset.ISO_8859_1=Línguas da Europa Ocidental +common.charset.ISO_8859_15=Línguas da Europa Ocidental +common.charset.Macintosh=Línguas da Europa Ocidental +common.charset.CP1255=Hebraico +common.charset.ISO_8859_8=Hebraico +common.charset.CP1253=Grego +common.charset.ISO_8859_7=Grego +common.charset.ARMSCII_8=Armênio +common.charset.CP1258=Vietnamita +common.charset.VISCII=Vietnamita +common.charset.CP1250=Línguas da Europa Central +common.charset.ISO_8859_2=Línguas da Europa Central +common.charset.defaultSet=Codificação de arquivo +common.charset.convertSave=Convertido para +common.date.near=Só agora +common.date.miniteBefore=Minutos atrás +common.date.today=Hoje +common.date.yestoday=Ontem +common.date.before=antes de +common.faceDefault=Emoticon padrão +common.loadMore=Carregue mais +common.numberLimit=A quantidade excede o limite máximo! +common.lengthLimit=O comprimento excede o limite máximo! +common.task.name=Gerenciador de tarefas +common.task.title=nome da missão +common.task.user=Usuário executivo +common.task.porcess=cronograma +common.task.start=Iniciar tarefa +common.task.useTime=Tempo decorrido +common.task.running=Executando +common.task.stoping=Pausado +common.task.killing=Final +common.task.stop=Tarefa suspensa +common.task.kill=Finalizar tarefa +common.task.removeTips=Tem certeza de que encerra esta operação? +common.task.killAll=Terminar tudo +common.task.killAllTips=Tem certeza que deseja encerrar todas as tarefas? +common.task.timeStart=Começa ás +common.task.timeNeed=Restante sobre +common.task.timeUse=Já correndo +ERROR_DB_PWD=Acesso negado ao banco de dados: nome de usuário ou senha incorretos. +ERROR_DB_TIMEOUT=A conexão do banco de dados expirou, verifique se o endereço está correto. +ERROR_DB_CONN_RFS=Conexão de banco de dados recusada: informações de configuração incorretas ou serviço não iniciado. +ERROR_DB_ADR=Erro de conexão do banco de dados, verifique se o endereço está correto. +ERROR_DB_NOT_SUPPORT=Tipo de banco de dados não suportado, verifique se o serviço ou arquivo de configuração correspondente está normal. +ERROR_DB_XS_DENNIED=Acesso ao banco de dados negado: privilégios insuficientes. +ERROR_DB_NOT_EXIST=O banco de dados não existe ou o nome errado foi especificado. +explorer.pathNotSupport=Este tipo de diretório não suporta esta operação! +explorer.pathIsRoot=Você atingiu o diretório raiz! +explorer.pathNull=Pasta está vazia +explorer.zipFileLarge=O arquivo é muito grande, descompacte-o antes de visualizá-lo! +explorer.charNoSupport=Caracteres especiais não suportados: +explorer.moveError=Falha na movimentação +explorer.lockError=Ocorreu um erro, o bloqueio simultâneo expirou +explorer.lockErrorDesc=Reduza a frequência de solicitações ou otimize a configuração relacionada à simultaneidade do servidor ou melhore a configuração do hardware do servidor; +explorer.moveSubPathError=Ocorreu um erro. O diretório pai não pode ser movido para o diretório filho! +explorer.spaceIsFull=Não há espaço suficiente, entre em contato com o administrador! +explorer.sessionSaveError=Falha na gravação da sessão! Verifique se o disco está cheio ou consulte o seu provedor de serviços. +explorer.networkError=Erro de conexão de rede (net :: ERR_CONNECTION_RESET), a conexão foi redefinida.
    Entre em contato com a empresa anfitriã ou o administrador da rede para verificar a configuração do firewall! +explorer.folderManage=Diretório de gerenciamento +explorer.clickEdit=Clique para editar +explorer.shortLink=Atalho +explorer.upper=Camada superior +explorer.historyNext=Adiantamento +explorer.historyBack=Voltar +explorer.loading=Em operação ... +explorer.getting=Obtendo ... +explorer.sending=Enviando dados ... +explorer.pullTips=Puxe para baixo para atualizar a página +explorer.pullDropTips=Livre para atualizar a página +explorer.getSuccess=Obtenha sucesso! +explorer.saveSuccess=Guardado com sucesso! +explorer.saveError=Falha ao salvar! +explorer.success=Operação bem sucedida +explorer.error=Falha na operação +explorer.dataError=Os dados estão anormais! +explorer.pathError=Erro no caminho do documento +explorer.repeatError=A operação falhou, o nome já existe! +explorer.systemError=Erro no sistema +explorer.mistake=Algo deu errado! +explorer.recycleClear=Lixeira vazia +explorer.recycleClearForce=Há muito conteúdo na lixeira, esvazie a lixeira primeiro! +explorer.recycleRestore=Restaurar Lixeira +explorer.recycleRestoreItem=Restaurar +explorer.recycleRestoreAll=Restaurar tudo +explorer.recycleClearInfo=Tem certeza de que deseja esvaziar completamente a lixeira? +explorer.zipDownloadReady=Baixar automaticamente após a compactação, aguarde ... +explorer.removeItem=Conteúdo do item +explorer.uploading=A carregar +explorer.uploadTipsMore=Muitos arquivos, é recomendável fazer o upload após a compactação e descompactar online! +explorer.uploadingMove=Mesclando e transferindo ... +explorer.viewNewPage=Nova visualização da página +explorer.unknowFileTitle=Dicas de abertura de arquivo! +explorer.unknowFileTips=Sem um aplicativo que suporte esse arquivo, você pode: +explorer.unknowAppTips=Sem o aplicativo: +explorer.unknowFileTry=Experimente +explorer.unknowFileDown=Baixe o arquivo +explorer.authFileDown=Download do arquivo +explorer.authShare=Compartilhe +explorer.usersShare=De compartilhamento +explorer.clipboard=Visualizar área de transferência +explorer.clipboardClear=Área de transferência vazia +explorer.fullScreen=Tela cheia +explorer.folderItem=Itens +explorer.folderItemSelect=Selecionado +explorer.dbLoadAll=Clique duas vezes para carregar tudo ... +explorer.ziping=A compactar ... +explorer.unziping=Descompactando ... +explorer.zipingTips=Operação de compressão, aguarde ... +explorer.unzipingTips=Descompactando a operação, aguarde ... +explorer.unzipRarTips=O conteúdo do arquivo está danificado ou a análise do arquivo não é suportada. Recomenda-se usar o formato ZIP. +explorer.parsing=A recuperar ... +explorer.moving=Movendo operação ... +explorer.copyMove=Copiar movimento +explorer.removeTitle=Excluir confirmação +explorer.removeInfo=Tem certeza de que deseja excluir a seleção? +explorer.removeTitleForce=Excluir para sempre +explorer.removeInfoForce=Tem certeza de que deseja excluir permanentemente este documento? +explorer.pathInRecycle=A pasta está na lixeira, restaure e tente novamente! +explorer.pathInRecycleFile=O arquivo está na lixeira, restaure e tente novamente! +explorer.downOffline=Download offline +explorer.savePath=Salvar caminho +explorer.uploadSelectMuti=Selecione vários arquivos para upload +explorer.goTo=Ir para +explorer.selectFile=Selecionar arquivo +explorer.selectFolder=Selecionar pasta +explorer.selectImage=Por favor selecione uma imagem ... +explorer.selectValidFolder=Por favor, selecione uma pasta para ser válida! +explorer.selectFolderFile=Selecionar arquivo ou pasta +explorer.selectMulti=Múltipla escolha +explorer.notNull=Os campos obrigatórios não podem estar em branco! +explorer.picCannotNull=O endereço da imagem não pode estar vazio! +explorer.renameSuccess=Renomeado com sucesso! +explorer.inputSearchWords=Digite a string para pesquisar +explorer.search.optionContent=conteúdo do documento +explorer.search.searchContentTips=Conteúdo do arquivo de pesquisa de palavra-chave, arquivo de texto de suporte +explorer.search.optionMutil=Bulk search +explorer.search.optionMutilDesc=Um termo de pesquisa por linha, os resultados da pesquisa são classificados de acordo com o termo de pesquisa +explorer.removeSuccess=Excluído com sucesso! +explorer.removeFail=Falha na exclusão! +explorer.clipboardNull=A área de transferência está vazia! +explorer.createSuccess=Novo sucesso! +explorer.createError=Nova criação falhou, verifique as permissões do diretório! +explorer.copySuccess=[Copiar] - Substitua a área de transferência com sucesso! +explorer.cuteSuccess=[Cortar] - Substitua a área de transferência com sucesso! +explorer.clipboardState=Status da área de transferência: +explorer.copyOK=Copiado com sucesso! +explorer.copyNotExists=A fonte não existe +explorer.currentHasParent=A pasta de destino é uma subpasta da pasta de origem! +explorer.pastSuccess=Operação de colagem concluída +explorer.cutePastSuccess=Operação de corte concluída +explorer.zipSuccess=Compressão concluída +explorer.notZip=Não é um arquivo compactado +explorer.zipNull=Nenhum arquivo ou diretório selecionado +explorer.unzipSuccess=Descompacte concluído +explorer.pathIsCurrent=O caminho aberto é o mesmo que o caminho atual! +explorer.pathExists=O nome já existe! +explorer.serverDownDesc=Tarefas adicionadas à lista de downloads +explorer.parentPermission=Permissões do diretório pai +explorer.confirm=Você tem certeza? +explorer.ifSaveFileTips=Existem arquivos não salvos? +explorer.ifSaveFile=O arquivo ainda não foi salvo. Ele foi salvo? +explorer.ifStopUploadTips=Um arquivo está sendo carregado. Tem certeza que quer fechar a janela? +explorer.noPermissionRead=Você não tem permissão de leitura! +explorer.noPermissionDownload=Você não tem permissão para fazer o download! +explorer.noPermissionWrite=O diretório não tem permissões de gravação +explorer.noPermissionAction=Você não tem essa permissão, entre em contato com o administrador! +explorer.noPermissionWriteAll=O arquivo ou diretório não tem permissão de gravação +explorer.noPermissionWriteFile=O arquivo não tem permissão de gravação +explorer.noPermissionReadAll=O arquivo ou diretório não tem permissões de leitura +explorer.noPermission=O administrador desativou esta permissão! +explorer.noPermissionExt=Um administrador desativou este tipo de permissões de arquivo +explorer.noPermissionGroup=Você não está neste grupo de usuários! +explorer.pathNoWrite=O diretório não é gravável. Defina o diretório e todos os subdiretórios para ler e escrever e tente novamente! +explorer.onlyReadDesc=Este diretório não possui permissões de gravação, você pode definir permissões nesse diretório no servidor +explorer.settingSuccess=A modificação entrou em vigor! +explorer.noRepeat=Não são permitidas duplicatas +explorer.dataNotFull=O envio de dados está incompleto! +explorer.tooManyToView=Contém muito conteúdo (%s itens), abra-o localmente para visualização; +explorer.jumpAfterWhile=Saltar automaticamente após%ss, Saltar imediatamente +explorer.retryTips=Verifique e tente novamente +explorer.selectObject=Selecionar objetos +explorer.parentGroup=Departamento superior +explorer.actionAuth=Autoridade de operação +explorer.notSelectDesc=Sem dados, por favor, escolha! +explorer.groupAuthCopy=Copie a combinação +explorer.groupAuthCopyDesc=Copie a combinação de permissão +explorer.groupAuthPasteDesc=Cole a combinação de permissão copiada +explorer.groupAuthSave=Salvar como favorito +explorer.groupAuthRecent=Usado recentemente +explorer.selectDesc=Selecionar conteúdo +explorer.cannotLoad=Não foi possível carregar os resultados. +explorer.loadMore=Carregar mais resultados ... +explorer.noSearchData=Nenhum resultado encontrado +explorer.delAllItem=Excluir todos os itens +explorer.pleaseDel=Por favor apague +explorer.pleaseInput=Digite pelo menos +explorer.canChoose=Selecione apenas no máximo +explorer.theChars=Personagens +explorer.theItems=Itens +explorer.noData=Sem dados +explorer.ifPathAuthClear=Todas as configurações de permissões de subarquivos e pastas serão limpas. Tem certeza de que deseja continuar? +explorer.fileDescAdd=Adicionar descrição do documento +explorer.fileDesc=Descrição do documento +explorer.fileLog=Registro de documentos +explorer.ifResetOpen=Tem certeza de que deseja redefinir todos os métodos de abertura personalizados? +explorer.ResetOpen=Redefinir todos os métodos abertos personalizados +explorer.openWith=Abrir como ... +explorer.openWithAce=Editor abre +explorer.openWithLocal=Abrir localmente +explorer.openWithLocalEdit=Edição local +explorer.editorSaveTips=O arquivo não foi criado, salve o novo arquivo primeiro +explorer.editor.fileTooBig=O arquivo é muito grande e não pode ser maior que 20 milhões +explorer.errorFunctionTips=Este tipo de arquivo não suporta listas de funções! +explorer.errorFormatTips=O tipo de arquivo atual não corresponde ao método de formatação padrão.
    Por favor selecione manualmente +explorer.cuteToThe=Mover para: +explorer.copyToThe=Copiar para: +explorer.addToFav=Adicionar aos favoritos +explorer.addFav=Adicionar favoritos +explorer.delFav=Cancelar coleção +explorer.addFavSuccess=Adicionar favorito com sucesso +explorer.pathHasFaved=O caminho foi favorito +explorer.delFavSuccess=Cancelar coleção com sucesso +explorer.fileLock=Editar bloqueio +explorer.fileLockNow=trancando +explorer.fileLockCancle=Desbloquear +explorer.fileLockTitle=trancado +explorer.fileLockTips=Bloqueado (outras pessoas não podem editar o arquivo) +explorer.fileLockUser=Armário +explorer.fileLockError=O arquivo atual está bloqueado, entre em contato com o armário para desbloqueá-lo e tente novamente; +explorer.downloaded=Download concluído +explorer.openAutoTips=Será aberto automaticamente +explorer.historyAutoTips=Gerar automaticamente versões históricas +explorer.saved=Guardado com sucesso +explorer.opened=Abra com sucesso! +explorer.openFail=Falha na abertura! +explorer.openingWithLoc=O arquivo é aberto localmente ... +explorer.openOnlyView=O modo somente leitura está ativado +explorer.saving=Salvando arquivo ... +explorer.notSupport=Algo deu errado, o formato do conteúdo não é compatível! +explorer.unzipErrorTips=Algo deu errado! Formato de arquivo compactado não reconhecido;
    Por favor, verifique se o arquivo está compactado ou danificado. +explorer.wordLoading=Carregando ... +explorer.noFunction=De jeito nenhum! +explorer.paramFormatError=O formato do parâmetro está errado! +explorer.descTooLong=A descrição é muito longa +explorer.noMoreThan=Não mais que +explorer.desktopDelError=Desculpe, a pasta da área de trabalho não suporta exclusão! +explorer.copy=Copiar +explorer.past=Colar +explorer.clone=Crie uma cópia +explorer.cute=Cut +explorer.cuteTo=Mover para ... +explorer.copyTo=Copiar para ... +explorer.info=Atributo +explorer.searchInPath=Pesquisar na pasta +explorer.addToPlay=Adicionar à playlist +explorer.manageFav=Gerenciar Favoritos +explorer.refreshTree=Atualizar diretório da árvore +explorer.zip=Crie um pacote compactado +explorer.unzip=Descompacte para ... +explorer.unzipFolder=Extrair para a pasta +explorer.unzipThis=Descompactar para atual +explorer.unzipTo=Descompacte para ... +explorer.openProject=Projeto aberto do editor +explorer.createLink=Crie um atalho +explorer.createLinkHome=Enviar para atalho na área de trabalho +explorer.setBackground=Definir como papel de parede da área de trabalho +explorer.favRemove=Cancelar esta coleção +explorer.openPath=Vá para o diretório +explorer.openPathFinished=Já entrei no diretório +explorer.openIE=O navegador é aberto +explorer.newFile=Novo arquivo +explorer.newFolder=Nova pasta +explorer.fileSaveTo=Arquivo salvo em +explorer.openFather=Exibição da pasta superior +explorer.uploadFile=Carregar arquivo +explorer.uploadFolder=Carregar pasta +explorer.appOpenDefault=Defina para abrir por padrão +explorer.appOpenAways=Abra esse arquivo sempre com o programa de sua escolha +explorer.appSelectDesc=Escolha o programa que você deseja usar para abrir este arquivo +explorer.appSelectMenu=Definir como modo de abertura padrão +explorer.appSelectMenuCancel=Desativar como padrão aberto com +explorer.appSelectWarning=Por favor, selecione uma aplicação! +explorer.appTypeSupport=Aplicativos de suporte +explorer.appTypeAll=Todas as aplicações +explorer.appSearch=Pesquisar instalações de aplicativos relacionadas +explorer.recent.createTime=Criado em +explorer.recent.modifyTime=Modificado em +explorer.recent.viewTime=Aberto às +explorer.urlLink=Endereço de link externo +explorer.downloading=Fazendo download ... +explorer.downReady=Em breve +explorer.downError=Falha no download! +explorer.max=Maximizar +explorer.min=Minimizar +explorer.minAll=Minimizar tudo +explorer.displayAll=Mostrar todas as janelas +explorer.closeAll=Fechar tudo +explorer.authDtl=Clique para ver suas permissões no diretório +explorer.authDialog=Membros internos, tabela de permissões no nível de colaboração do documento +explorer.authNote=Nota: As funções de gerenciamento incluem a configuração de permissões de membros / gerenciamento de comentários, etc. Tenha cuidado! A função [Administrador do Sistema] não é restrita por nenhuma permissão +explorer.auth.toOuter=Autorização externa (outros departamentos ou usuários) +explorer.auth.share=Sharer +explorer.auth.owner=Proprietário +explorer.auth.disableDeep=Sem permissão de acesso apenas +explorer.auth.disableDeepDesc=O diretório de fatores possui permissões de leitura e gravação de documentos e o caminho de acesso estabelecido. +explorer.auth.tips=Pode entrar em contato com os usuários acima para definir permissões para você +explorer.notSystemPath=Não é um caminho de arquivo do sistema +explorer.toolbar.rootPath=Espaço pessoal +explorer.toolbar.fav=Favoritos +explorer.toolbar.desktop=Área de trabalho +explorer.toolbar.client=Cliente +explorer.toolbar.myComputer=Meu computador +explorer.toolbar.recycle=Lixeira +explorer.toolbar.myDocument=Meu documento +explorer.toolbar.myPicture=Minha foto +explorer.toolbar.myMusic=Minha musica +explorer.toolbar.myMovie=Meu video +explorer.toolbar.myDownload=Meu download +explorer.toolbar.uiDesktop=Área de trabalho +explorer.toolbar.uiExplorer=Gerenciamento de arquivos +explorer.toolbar.uiEditor=Editor +explorer.toolbar.uiProjectHome=Página inicial do projeto +explorer.toolbar.uiLogout=Sair +explorer.toolbar.uiGroup=Estrutura organizacional +explorer.toolbar.myGroup=Meu departamento +explorer.toolbar.publicPath=Diretório público +explorer.toolbar.recentDoc=Documentos recentes +explorer.toolbar.myShare=Minha parte +explorer.toolbar.shareToMe=Colabore comigo +explorer.toolbar.shareTo=Minha colaboração +explorer.toolbar.shareLink=Compartilhamento de link externo +explorer.toolbar.photo=álbum de foto +explorer.photo.desc=Classificação do álbum do usuário +explorer.photo.group=Agrupamento de álbuns +explorer.photo.setting=Configurações do álbum +explorer.photo.pathRoot=Diretório de digitalização do álbum +explorer.photo.pathRootSelect=Selecione uma pasta como o diretório raiz para a digitalização de imagens do álbum +explorer.photo.fileType=Especifique o tipo de arquivo +explorer.photo.fileSize=filtro de tamanho de arquivo +explorer.photo.fileSizeDesc=Filtre apenas arquivos maiores que essa configuração, se for 0, não há limite +explorer.toolbar.folder=álbum de catálogo +explorer.toolbar.folderSelect=Selecione uma pasta para exibir no modo de álbum +explorer.pathDesc.fav=Depois que o arquivo é adicionado à coleção, ele pode ser acessado de forma rápida e direta +explorer.pathDesc.home=O espaço pessoal é o seu espaço de armazenamento privado, Visível apenas para você, não para outros usuários +explorer.pathDesc.groupRoot=Este é o espaço público da empresa / unidade, Todos os membros são visíveis por padrão +explorer.pathDesc.myGroup=Gerencie os documentos do seu departamento aqui, Os documentos do departamento são apenas visíveis e operáveis por membros deste departamento, e não visíveis para outros membros do departamento +explorer.pathDesc.group=Disco de rede departamental, visível apenas para membros do departamento, A autoridade de operação é atribuída e definida pelo administrador do departamento. +explorer.pathDesc.recentDoc=Arquivos recentemente criados, carregados, modificados e abertos +explorer.pathDesc.shareTo=Visualize e gerencie seus projetos [de colaboração interna] iniciados por outros aqui +explorer.pathDesc.shareLink=Visualize e gerencie o compartilhamento de cadeia externa iniciado por você aqui +explorer.pathDesc.recycle=Gerencie seus arquivos excluídos (pastas) aqui +explorer.pathDesc.fileType=Categorizar arquivos por tipo, apenas arquivos em espaço pessoal +explorer.pathDesc.tag=Adicione marcas a arquivos (pastas) para obter classificação eficiente e consulta rápida +explorer.pathDesc.tagItem=Tente adicionar um rótulo ao arquivo / pasta! +explorer.pathDesc.mount=Aqui você pode gerenciar o armazenamento de back-end múltiplo, bem como os discos montados no servidor +explorer.pathDesc.shareToMe=Tela lado a lado - todo o conteúdo com o qual colaborei +explorer.pathDesc.shareToMeUser=Mostrar por compartilhador - o conteúdo com o qual colaborei é categorizado pelo iniciador +explorer.pathDesc.shareToMeUserItem=Colaboração iniciada por este usuário +explorer.pathDesc.shareToMeGroup=O conteúdo com o qual colaboro é categorizado pelo departamento onde a pasta está localizada +explorer.pathDesc.shareToMeGroupGroup=Compartilhamento colaborativo do disco de rede do departamento +explorer.pathDesc.search=Suporte à pesquisa de arquivos / tags / notas / conteúdo; Suporte a correspondência pinyin e difusa da primeira letra +explorer.pathDesc.searchMore=Defina mais condições de pesquisa +explorer.pathDesc.shareFrom=Caminho de origem +explorer.pathGroup.shareGroup=Espaço departamental +explorer.pathGroup.shareGroupDesc=Acesse quando houver conteúdo no departamento de nível inferior +explorer.pathGroup.shareUser=Compartilhamento de espaço pessoal de membros do departamento +explorer.pathGroup.shareUserDesc=Fonte: Compartilhamento de espaço pessoal do usuário, compartilhamento de documento de departamento externo iniciado pelo usuário. +explorer.pathGroup.shareContent=A colaboração e compartilhamento do espaço do departamento +explorer.pathGroup.group=sub Departamento +explorer.pathGroup.groupContent=Documento Departamental +explorer.pathGroup.shareUserOuter=Compartilhamento de colaboração externa +explorer.pathGroup.shareUserOuterDesc=Compartilhamento colaborativo de usuários externos fora de sua própria estrutura organizacional +explorer.pathGroup.shareSelf=espaço pessoal +explorer.toolbar.fileSizeTitle=Tamanho do ícone +explorer.toolbar.fileSizeSuper=Super pequeno +explorer.toolbar.fileSizeSmall=Ícone pequeno +explorer.toolbar.fileSizeDefault=Ícone médio +explorer.toolbar.fileSizeBig=Ícone grande +explorer.toolbar.fileSizeBigSuper=Ícone de grandes dimensões +explorer.toolbar.PagePC=Versão para PC +explorer.toolbar.pagePhone=Versão móvel +explorer.file.name=Nome +explorer.file.type=Tipo +explorer.file.contain=Contém +explorer.file.address=Localização +explorer.file.detil=Descrição do produto +explorer.file.linkCount=Citações +explorer.file.size=Tamanho +explorer.file.count=Quantidade +explorer.file.byte=Byte +explorer.file.path=Caminho +explorer.file.action=Operação +explorer.file.creator=Criador +explorer.file.editor=Modificado por +explorer.file.location=Localização +explorer.file.timeInfo=Informações de tempo +explorer.file.createTime=Tempo de criação +explorer.file.modifyTime=Tempo de modificação +explorer.file.lastTime=Última visita +explorer.file.sortType=Classificar por +explorer.file.sortDisable=O conteúdo não suporta classificação especificada! +explorer.file.timeType=A / m / d H: i: s +explorer.file.timeTypeInfo=A / m / d H: i: s +explorer.file.listType=Ver +explorer.file.listIcon=Arranjo de ícones +explorer.file.listList=Classificação da lista +explorer.file.listListSplit=Modo de coluna +explorer.file.listTypeGroup=Modo de exibição e método de classificação +explorer.file.listTypeKeep=modo de exibição +explorer.file.listTypeKeepDesc=Escolha um modo de visualização para cada pasta ou use o mesmo modo de visualização para todas as pastas +explorer.file.listSortKeep=ordenar por +explorer.file.listSortKeepDesc=Configure a ordem de classificação das colunas para cada pasta ou use a mesma ordem para todas as pastas +explorer.file.listViewKeep=Funciona com uma única pasta +explorer.file.listViewAll=aplica-se a todas as pastas +explorer.file.listViewReset=restaurar ao padrão +explorer.file.sortUp=Aumentando +explorer.file.sortDown=Decremento +explorer.file.orderType=Classificar por +explorer.file.orderDesc=Descendente +explorer.file.orderAsc=Ordem crescente +explorer.file.imageSize=Tamanho da imagem +explorer.file.sharer=Sharer +explorer.file.shareTime=Compartilhar tempo +explorer.file.viewCnt=Visitas +explorer.file.downCnt=Transferências +explorer.file.readWriteLock=Esta operação não é suportada temporariamente, há outras tarefas de leitura e gravação sendo processadas, tente novamente mais tarde! +explorer.app.app=Aplicação leve +explorer.app.createLink=Novo URL +explorer.app.create=Crie um aplicativo leve +explorer.app.edit=Editar aplicativo leve +explorer.app.open=Abra o aplicativo light +explorer.app.groupGame=Jogo +explorer.app.groupTools=Ferramentas +explorer.app.groupReader=Ler +explorer.app.groupMovie=Filme +explorer.app.groupMusic=Música +explorer.app.groupLife=Vida +explorer.app.desc=Descrição da aplicação +explorer.app.icon=Ícone do aplicativo +explorer.app.iconShow=endereço de URL ou diretório +explorer.app.group=Agrupamento de aplicativos +explorer.app.type=Tipo +explorer.app.typeUrl=Link +explorer.app.typeCode=extensão js +explorer.app.display=Aparência +explorer.app.displayBorder=Sem borda (selecionado sem borda) +explorer.app.displaySize=Redimensionar (selecione para ajustar) +explorer.app.size=Tamanho +explorer.app.url=Endereço do link +explorer.app.code=código js +explorer.app.appType=Tipo de aplicação +explorer.app.website=URL +explorer.app.shortLink=Atalho de arquivo +explorer.app.imgIcon=Ícone de imagem +explorer.app.imgIconUrl=Selecione a imagem ou cole o URL da imagem da web. +explorer.app.path=Caminho +explorer.app.pathDesc=A modificação manual não é suportada; você pode criar atalhos clicando com o botão direito do mouse +explorer.app.link=URL link +explorer.app.linkDesc=Digite o link http / https +explorer.app.linkDragTips=Você pode arrastar o link de URL para a área do arquivo para criar automaticamente um link de URL! +explorer.app.openType=Caminho aberto +explorer.app.openWindow=Nova janela +explorer.app.openDialog=Caixa de diálogo +explorer.app.openCurrent=pagina atual +explorer.app.openInline=Página de incorporação +explorer.app.dialogSize=Tamanho da caixa de diálogo +explorer.app.with=Largura +explorer.app.height=Altura +explorer.app.moreSet=Mais configurações +explorer.app.canDiyWith=Permitir ajuste de largura +explorer.app.miniBlock=Barra de título minimalista +explorer.app.runCode=Executar código js +explorer.app.name=Nome da aplicação +explorer.app.nameDesc=Digite um nome de aplicativo. +explorer.app.descDesc=Por favor, insira uma descrição do aplicativo +explorer.embed.title=Arquivo incorporado +explorer.embed.desc=Incorpore o arquivo em uma página da web ou blog +explorer.embed.url=URL de incorporação +explorer.embed.code=Código embutido +explorer.upload.ready=Aguardando upload +explorer.upload.success=Carregado com sucesso +explorer.upload.secPassSuccess=Sucesso em segundos +explorer.upload.pathCurrent=Mude para o diretório atual +explorer.upload.select=Selecionar arquivo +explorer.upload.maxSize=Máximo permitido +explorer.upload.sizeInfo=Se você deseja configurar um tamanho maior, modifique o upload máximo permitido no php.ini. Ao selecionar um arquivo, aqueles maiores que esta configuração serão filtrados automaticamente. +explorer.upload.error=Falha no upload +explorer.upload.mergeError=Falha na mesclagem de arquivos +explorer.upload.errorHttp=Erro de rede ou firewall +explorer.upload.muti=Upload de vários arquivos +explorer.upload.drag=Arrastar e soltar upload +explorer.upload.dragFolder=Arraste e solte na pasta para fazer upload +explorer.upload.dragTips=Solte para enviar! +explorer.upload.pathNotAllow=O nome do arquivo não é permitido +explorer.upload.errorNull=Sem documentos! +explorer.upload.errorBig=O tamanho do arquivo excede o limite do servidor +explorer.upload.errorMove=Falha ao mover arquivos! +explorer.upload.errorExists=O arquivo já existe +explorer.upload.local=Carregar localmente +explorer.upload.tips=Use o upload de fragmentos, não mais limitado pelo php.ini; arraste e carregue a pasta da experiência do chrome +explorer.upload.exist=Processamento de arquivo com o mesmo nome +explorer.upload.clearAll=Limpar tudo +explorer.upload.clear=Esvaziamento concluído +explorer.upload.addMore=Adicionar em massa +explorer.upload.errorEmpty=Não pode estar vazio! +explorer.upload.errorExt=As extensões de arquivo não correspondem! +explorer.upload.fileSizeDisable=Há muitos arquivos carregados / transferidos ao mesmo tempo, entre em contato com o administrador para ajustar! +explorer.upload.moreDesc=(Recomendado não mais que 2000), total atualmente: +explorer.upload.scan=Digitalização +explorer.upload.merge=Verificando mesclagem +explorer.upload.needTime=Restantes aprox. +explorer.upload.checkError=A verificação do upload falhou. Tente novamente +explorer.upload.saveError=Falha ao salvar informações do arquivo de upload +explorer.upload.downloadDesc=Suporta apenas links de rede http / https +explorer.table.first=Página inicial +explorer.table.last=Última página +explorer.table.prev=Anterior +explorer.table.next=Página seguinte +explorer.table.one=Total 1 páginas +explorer.table.page=Page +explorer.table.itemPage=/página +explorer.table.searchTotal=Encontrado +explorer.table.items=Registros +explorer.table.list=Lista de dados +explorer.search.ing=Pesquisando ... +explorer.search.result=Resultado da pesquisa +explorer.search.resultTooMore=Muitos resultados de pesquisa, sugerem outro diretório ou palavra +explorer.search.resultNull=Nenhum resultado de pesquisa! +explorer.search.caseSensitive=Diferencia maiúsculas de minúsculas +explorer.search.content=Pesquisar conteúdo do arquivo +explorer.search.extDesc=Digite as extensões a serem filtradas, separadas por espaços. +explorer.search.byItems=Filtragem condicional +explorer.search.extNull=Tipo ilimitado +explorer.search.extFile=Qualquer arquivo +explorer.search.extDiy=customizar +explorer.search.inputDesc=Digite palavras-chave ou forneça filtros! +explorer.search.path=Pesquise o diretório: +explorer.search.rootPath=Procure o diretório raiz: +explorer.search.range=Intervalo de pesquisa +explorer.search.allFolder=Todas as pastas +explorer.search.currentFolder=Pasta atual +explorer.search.ext=Tipo de arquivo +explorer.search.timeRange=Intervalo de tempo +explorer.search.timeAll=Tempo ilimitado +explorer.search.lastDay=Quase 1 dia +explorer.search.lastWeek=Últimos 7 dias +explorer.search.lastMonth=Últimos 30 dias +explorer.search.lastYear=Ano passado +explorer.search.sizeAll=Tamanho ilimitado +explorer.search.inputNullDesc=Se não preenchido, significa maior ou menor que um determinado valor, que pode ser um decimal. +explorer.search.selectUser=Selecionar usuário ... +explorer.search.byUserDesc=Pesquisa por criador / modificador +explorer.search.total=Encontrado +explorer.search.noResult=Desculpe, não houve resultados de pesquisa, tente novamente +explorer.search.advance=Pesquisa avançada +explorer.search.clear=Limpar conteúdo +explorer.history.list=Histórico do arquivo +explorer.history.lastModify=Última modificação +explorer.history.modifyUser=Modificado por +explorer.history.noHistory=Nenhuma versão histórica! +explorer.history.current=Versão atual +explorer.history.detil=Descrição do produto +explorer.history.detilAdd=Adicionar impressão +explorer.history.uploadNew=Carregar nova versão +explorer.history.diff=Comparação de versões históricas +explorer.history.setCurrent=Definir como versão atual +explorer.history.delCurrent=Excluir esta versão +explorer.history.delAll=Excluir todo o histórico de versões +explorer.history.ifDelAll=Tem certeza de que deseja excluir todo o histórico? +explorer.history.ifDelCurrent=Excluir esta versão? +explorer.history.ifRollback=Tem certeza de que deseja reverter para esta versão? +explorer.history.changeEvent=Troca de versão histórica +explorer.history.before=Antes de +explorer.history.after=depois de +explorer.recycle.clearUser=Esvazie a lixeira do usuário +explorer.recycle.restoreSelect=Restaure este conteúdo +explorer.recycle.moveTo=Entregar +explorer.recycle.config=Configurações da lixeira +explorer.recycle.configTitle=Configurações da lixeira do sistema +explorer.recycle.configOpen=Abra a lixeira do sistema +explorer.recycle.configOpenDesc=Sugerir para abrir +explorer.recycle.configCloseInfo=Ao excluir o conteúdo, ele não entrará na lixeira do sistema; ele será excluído diretamente. +explorer.recycle.configOpenInfo=
  • Documentos pessoais ou departamentais, após excluir completamente ou esvaziar a lixeira, entrar na lixeira do sistema
  • O conteúdo excluído é classificado na pasta do usuário ou departamento de acordo com o usuário ou departamento onde o arquivo está localizado, e o administrador pode optar por restaurar esses arquivos;
  • Os arquivos antes do momento da exclusão completa automática serão automaticamente esvaziados regularmente;
  • Nota: Os arquivos excluídos aqui não podem ser recuperados.
  • +explorer.recycle.configClear=Exclua completamente automaticamente +explorer.recycle.restoreConfirm=Tem certeza que deseja restaurar o documento?
    Após a restauração, o documento será movido para o diretório raiz de destino +explorer.recycle.moveConfirm=Confirme a transferência +explorer.recycle.moveSelectTarget=Selecione o usuário ou departamento +explorer.recycle.moveDesc=
  • Passe para o usuário ou departamento designado; ele irá migrar para o diretório raiz do objeto
  • Após a transferência, descrições de documentos, trocas e discussões, versões históricas e outras informações continuarão a ser retidas; colaboração compartilhada e informações de permissão serão removidas
  • +explorer.recycle.taskTitle=Limpeza da lixeira do sistema +explorer.recycle.taskDesc=Exclua automaticamente o conteúdo da lixeira excedendo o tempo definido para liberar espaço de armazenamento +explorer.share.add=Adicionar compartilhamento +explorer.share.edit=Editar compartilhamento +explorer.share.remove=Cancelar compartilhamento +explorer.share.path=Compartilhar caminho +explorer.share.source=Compartilhamento de recursos +explorer.share.name=Compartilhar título +explorer.share.nameDesc=Compartilhar o nome do arquivo por padrão, pode ser personalizado +explorer.share.time=Tempo de expiração +explorer.share.timeLimit=Tempo limitado +explorer.share.timeLimitDesc=Depois de ativar e configurar, o compartilhamento será desativado automaticamente após o tempo exceder +explorer.share.timeDesc=Não definido se vazio +explorer.share.pwd=Extrair senha +explorer.share.pwdDesc=Nenhuma senha está definida +explorer.share.randomPwd=Gerado aleatoriamente +explorer.share.randomPwdDesc=Ele só pode ser visualizado extraindo a senha, que é mais privada e segura. +explorer.share.cancel=Cancelar compartilhamento +explorer.share.create=Criar link público +explorer.share.url=Endereço compartilhado +explorer.share.noDown=Download proibido +explorer.share.codeRead=Leitura de código +explorer.share.configSave=Salve a configuração +explorer.share.errorParam=Erro de parâmetro! +explorer.share.errorUser=As informações do usuário estão erradas! +explorer.share.errorSid=O compartilhamento não existe! +explorer.share.errorTime=Você está atrasado, esse compartilhamento expirou! +explorer.share.errorPath=O arquivo compartilhado não existe, foi excluído ou movido! +explorer.share.errorPwd=A senha está errada! +explorer.share.errorShowTips=Este tipo de arquivo não suporta visualização! +explorer.share.expiredTips=Desculpe, este compartilhamento expirou, entre em contato com o participante! +explorer.share.downExceedTips=Desculpe, os downloads de compartilhamento excederam o limite definido pelo compartilhador +explorer.share.store=Salvar no SkyDrive +explorer.share.loginTips=Desculpe, este compartilhamento deve estar conectado ao usuário para acessar! +explorer.share.noDownTips=Desculpe, o compartilhador desativou o download! +explorer.share.noViewTips=Desculpe, este compartilhador desativou a visualização! +explorer.share.noUploadTips=Desculpe, o upload foi desativado por este participante! +explorer.share.needPwd=Este compartilhamento requer uma senha +explorer.share.notExist=Compartilhamento não existe! +explorer.share.viewNum=Procurar: +explorer.share.downNum=Transferências +explorer.share.openPage=Abrir página compartilhada +explorer.share.openLink=Abrir link de compartilhamento +explorer.share.copyLink=Copiar informações de compartilhamento +explorer.share.link=Compartilhar link: +explorer.share.accessPwd=Senha de acesso: +explorer.share.copied=Copiado +explorer.share.actionNotSupport=Compartilhar conteúdo, esta operação não é suportada +explorer.share.errorPathTips=O link de compartilhamento está errado ou o compartilhador cancelou o link externo +explorer.share.shareTo=Compartilhamento colaborativo +explorer.share.shareToTarget=Membro colaborador +explorer.share.innerTo=Colaboração interna +explorer.share.linkTo=Compartilhamento de link externo +explorer.share.selectTarget=Selecione um departamento ou usuário para compartilhamento colaborativo +explorer.share.afterShareDesc=Após compartilhar com a outra parte ou o departamento ao qual pertencem, os usuários podem vê-lo em [Compartilhar comigo]. +explorer.share.openOuterLink=Compartilhamento de cadeia externa aberta +explorer.share.openOuterLinkDesc=Após criar um link externo, você pode enviá-lo para outras pessoas por email ou QQ. +explorer.share.outerLink=Compartilhar link +explorer.share.advanceSet=Configuração avançada +explorer.share.loginLimit=Disponível apenas para usuários conectados +explorer.share.loginLimitDesc=Após a abertura, apenas membros internos podem acessar. +explorer.share.authLimit=Direitos e restrições +explorer.share.canUpload=Permitir upload +explorer.share.notView=Desativar visualização +explorer.share.notDown=Desativar downloads +explorer.share.downNumLimit=Limite de download +explorer.share.downNumLimitDesc=Após esse número de vezes, o link de compartilhamento expira automaticamente. +explorer.share.learnAuth=Noções básicas sobre permissões de colaboração de documentos +explorer.share.shareToRemove=Tem certeza que deseja cancelar este compartilhamento colaborativo?
    O usuário-alvo com quem compartilhou não pode mais ver o compartilhamento colaborativo! +explorer.share.shareLinkRemove=Tem certeza que deseja cancelar o compartilhamento de link externo?
    Após o cancelamento, o link externo ficará inválido! +explorer.share.shareToCopy=Copiar caminho de acesso +explorer.share.shareToCopyDesc=Você pode enviar o link para a pessoa colaboradora e entrar rapidamente na colaboração +explorer.share.specifyAuthTips=Além dos usuários especificados acima +explorer.share.specifyAuthDesc=Autoridade de usuário designado> Autoridade de departamento do usuário designado> Autoridade de outra pessoa +explorer.share.selfAuthDesc=Não é possível modificar as próprias permissões, outros gerentes podem definir +explorer.share.authTypeDesc=Herdar permissões da pasta pai por padrão +explorer.share.rootPathAuthDesc=Seleção de usuário e departamento de suporte ao departamento raiz +explorer.share.subPathAuthDesc=Sub-departamento, selecione apenas membros do departamento +explorer.share.myAuth=Minhas permissões +explorer.share.othersAuth=Outras permissões +explorer.share.keepAuth=Manter permissões originais +explorer.share.specifyAuth=Especifique permissões +explorer.share.userAuth=Direitos do usuário +explorer.share.specifyUserAuth=Especificando permissões de usuário +explorer.share.rptTitle=Se você encontrar informações ilegais e prejudiciais, selecione o motivo abaixo para enviar um relatório. +explorer.share.illegal=Informação ilegal +explorer.share.inputRptDesc=Insira o motivo do relatório +explorer.share.rptSend=O envio foi bem sucedido, o administrador tratará disso a tempo +explorer.share.rptSended=O relatório foi enviado, aguardando o processamento do administrador +explorer.auth.mutil=Definir permissões em lotes +explorer.auth.mutilTips=Nota : Se o conteúdo selecionado já tiver permissão, ele será sobrescrito. +explorer.auth.mutilDesc=Ao mesmo tempo que as permissões padrão subsequentes +explorer.auth.showMore=Detalhes da permissão +explorer.auth.tabUser=membro do departamento +explorer.auth.tabChildren=Permissões de subpasta +explorer.auth.tabUserTips=Permissões iniciais dos membros do departamento +explorer.auth.tabChildrenTips=Conteúdo com permissões definidas nesta pasta +explorer.auth.resetUser=Substituir a configuração desta permissão de usuário +explorer.auth.resetUserBtn=Substituir permissões +explorer.auth.resetUserBtnTips=Substituir o usuário e todas as permissões de subpastas (pastas) nesta pasta +explorer.auth.resetUserHeader=A pasta de nível inferior contém o conteúdo que especifica as permissões do usuário e define todas as substituições para as permissões acima +explorer.auth.resetUserContiner=Contém o conteúdo da permissão do usuário +explorer.auth.resetUserEmpty1=Não há conteúdo para o qual as permissões estejam definidas para este usuário, não há necessidade de substituir +explorer.auth.resetUserEmpty2=Todo o conteúdo filho herda as permissões de pasta do nível atual +explorer.rename.mutil=Renomeação de lotes +explorer.rename.nameBefore=Nome do arquivo original +explorer.rename.nameTo=Renomeado +explorer.rename.start=Renomeie agora +explorer.rename.clearFinished=Esvaziamento concluído +explorer.rename.clearAll=Limpar tudo +explorer.rename.typeReplaceAll=Substitua tudo +explorer.rename.typePrepend=Anexar antes +explorer.rename.typeAppend=Anexar mais tarde +explorer.rename.typeReplace=Encontre e substitua +explorer.rename.typeChangeCase=Conversão de caso +explorer.rename.typeRemove=Excluir caracteres +explorer.rename.typeReplaceSet=Especifique a substituição em lote +explorer.rename.typeReplaceSetDesc=Substitua se eles forem iguais; cada linha é separada por um espaço e o nome do arquivo não permite espaços; por exemplo: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Conteúdo adicional +explorer.rename.find=Localizar +explorer.rename.replaceTo=Substituído por +explorer.rename.caseUpperFirst=Capital inicial +explorer.rename.caseUpper=Todas as maiúsculas +explorer.rename.caseLower=Todas minúsculas +explorer.rename.removeStart=Remover do zero +explorer.rename.removeEnd=Remover do final +explorer.rename.chars=Personagem +explorer.editor.beautifyCode=Formatação de código +explorer.editor.convertCase=Conversão de caso +explorer.editor.convertUpperCase=Converter em maiúsculas +explorer.editor.convertLowerCase=Converter em minúsculas +explorer.editor.currentTime=Hora atual +explorer.editor.md5=criptografia md5 +explorer.editor.qrcode=Código QR da string +explorer.editor.regx=Teste de expressão regular +explorer.editor.chinese=Conversão simplificada +explorer.editor.chineseSimple=Converta para Chinês simplificado +explorer.editor.chineseTraditional=Converta para Chinês Tradicional +explorer.editor.base64=codec base64 +explorer.editor.base64Encode=codificação base64 +explorer.editor.base64Decode=decodificação base64 +explorer.editor.url=Codec de URL +explorer.editor.urlEncode=Codificação de URL +explorer.editor.urlDecode=Decodificação de URL +explorer.editor.unicode=Codec Unicode +explorer.editor.unicodeEncode=Codificação Unicode +explorer.editor.unicodeDecode=Decodificação Unicode +explorer.editor.toolsSelectTips=Selecione o conteúdo correto a ser processado! +explorer.editor.toolsRandString=Gerar string aleatória de 32 bits +explorer.editor.textEncode=Codificação / decodificação de texto +explorer.editor.textParse=Processamento de texto +explorer.editor.timeShow=Timestamp to time +explorer.editor.timeInt=Tempo para carimbo de data / hora +explorer.editor.lineRemoveEmpty=Remova as linhas em branco (incluindo espaços) +explorer.editor.lineUnoin=Remova as linhas duplicadas +explorer.editor.lineTrim=Remova os espaços à esquerda e à direita +explorer.editor.lineSort=Classificar por linha (ordem crescente) +explorer.editor.lineReverse=Trocar todas as linhas para cima e para baixo +explorer.editor.lineSum=Soma +explorer.editor.lineAverage=valor médio +explorer.editor.calc=Calculadora Grátis +explorer.editor.goToLine=Ir para a linha +explorer.editor.keyboardType=Modo de teclado +explorer.editor.fontFamily=Fonte +explorer.editor.codeMode=Realçar sintaxe +explorer.editor.closeAll=Fechar tudo +explorer.editor.closeLeft=Fechar separador esquerdo +explorer.editor.closeRight=Feche a guia direita +explorer.editor.closeOthers=Fechar outro +explorer.editor.wordwrap=Quebra de linha +explorer.editor.showGutter=Mostrar número da linha +explorer.editor.charAllDisplay=Mostrar caracteres invisíveis +explorer.editor.autoComplete=Prompt automático +explorer.editor.autoSave=Salvamento automático +explorer.editor.functionList=Lista de funções +explorer.editor.codeTheme=Estilo do código +explorer.editor.fontSize=Tamanho da fonte +explorer.editor.completeCurrent=Corrente de preenchimento automático +explorer.editor.createProject=Adicionar ao projeto do editor +explorer.editor.markdownContent=Diretório de conteúdo +explorer.editor.undo=Revogar +explorer.editor.redo=Anti-revogação +explorer.editor.shortcut=Atalho +explorer.editor.replace=Substituir +explorer.editor.reload=Recarregar +explorer.editor.view=Ver +explorer.editor.tools=Ferramentas +explorer.editor.help=Ajuda +explorer.sync.data=Sincronização de dados +explorer.sync.openLoc=Abrir diretório local +explorer.sync.syncing=A sincronizar +explorer.sync.synced=Sincronização concluída +explorer.sync.syncedError=Log de erro +explorer.sync.syncStart=Comece a sincronizar +explorer.sync.syncStop=Pare de sincronizar +explorer.sync.notOpenTips=Você não ativou a sincronização local +explorer.sync.setNow=Configure a sincronização agora +explorer.sync.error=Falha no upload +explorer.sync.success=Sincronização bem sucedida +explorer.sync.statusScan=Digitalização +explorer.sync.statusNone=A sincronização não está configurada +explorer.sync.statusScanEnd=Digitalização concluída +explorer.sync.statusDoing=A sincronizar +explorer.sync.statusDone=Sincronização concluída +explorer.sync.statusStop=Pausar +explorer.sync.clearCacheSuccess=Limpar cache bem-sucedido! +explorer.sync.emptyTask=Nenhuma tarefa de sincronização +explorer.sync.openCloud=Localização na nuvem aberta +explorer.sync.openLocal=Abrir localmente +explorer.sync.statusFiles=Progresso do documento +explorer.sync.statusLastTime=Tempo de conclusão +explorer.sync.configName=Configurações de sincronização +explorer.sync.configClient=Configurações do cliente +explorer.sync.configAbout=Sobre +explorer.sync.configSyncFrom=Caminho local +explorer.sync.configSyncFromDesc=Selecione uma pasta local para sincronizar +explorer.sync.configSyncTo=Sincronizar com +explorer.sync.configSyncToDesc=Sincronizar com o local do servidor +explorer.sync.configIgnore=Tipos de arquivo ignorados +explorer.sync.configIgnoreDesc=Arquivos deste tipo não são sincronizados +explorer.sync.autorun=Auto-partida +explorer.sync.configThread=Número de threads simultâneos +explorer.sync.configThreadDesc=Número de arquivos carregados ao mesmo tempo +explorer.sync.configDownloadPath=Caminho do download +explorer.sync.configDownloadPathDesc=Caminho de download padrão ao baixar pastas de arquivos +explorer.sync.configClearCacheAuto=Limpar automaticamente o cache +explorer.sync.configClearCacheAutoDesc=Limpar automaticamente o arquivo de cache N days ago +explorer.sync.configClearCache=Limpar cache +explorer.sync.configChangeSite=Sair do site atual +explorer.sync.configVersion=Versão atual +explorer.sync.configUpdateDesc=Instruções de atualização +explorer.sync.configUpdateCheck=Detectando atualizações +explorer.sync.confirmReset=Sincronize a modificação do diretório, as informações de sincronização serão redefinidas. +explorer.sync.listClearDone=Esvaziamento concluído +explorer.sync.listClearError=Limpar lista de erros +explorer.sync.listRetryAll=Repetir tudo +explorer.async.tipsDisablePath=Não suporta a opção de sincronizar o caminho +explorer.async.tipsIsMoving=Detectou que uma grande quantidade de conteúdo está sendo movida ou copiada no diretório sincronizado;
    É recomendável atualizar a página para sincronização após a conclusão local! +explorer.async.tipsStartUser=Iniciar sincronização manualmente +explorer.download.title=Gerenciamento de download +explorer.download.waiting=Espera +explorer.download.stop=Pausar download +explorer.download.start=iniciar o download +explorer.download.remove=Remover tarefa +explorer.download.stopAll=Pausar tudo +explorer.download.startAll=Continuar tudo +explorer.download.clearAll=Limpe todas as tarefas +explorer.download.doing=em processamento +explorer.download.done=Transferência concluída +explorer.download.clearAllTips=Tem certeza de que deseja excluir todas as tarefas de download? +explorer.tag.name=Tag de arquivo +explorer.tag.edit=Gerenciamento de etiquetas +explorer.tag.add=Criar etiqueta +explorer.tag.remove=Tem certeza de que deseja excluir esta tag? +explorer.tag.inputHolder=Digite um nome de etiqueta +explorer.tag.addTo=Definir rótulo +explorer.tag.default1=Materiais de aprendizagem +explorer.tag.default2=Dados de teste +explorer.tag.default3=contrato +explorer.tag.filter=Filtrar por rótulo +explorer.groupTag.title=Etiqueta pública +explorer.groupTag.menuTtitle=Selo público do departamento +explorer.groupTag.titleDesc=Etiqueta pública dentro do departamento +explorer.groupTag.empty=Depois que o administrador do departamento define o rótulo público, ele é habilitado automaticamente. Quando não há conteúdo do rótulo, o rótulo público é automaticamente desativado! +explorer.tag.pathDesc=Filtrar por etiqueta pessoal +explorer.groupTag.pathDesc=Filtrar por rótulo público do departamento +explorer.groupTag.removeTypeTips=Tem certeza que deseja excluir este grupo? Todos os documentos associados ao marcador serão removidos após a exclusão! +explorer.groupTag.removeTagTips=Tem certeza que deseja excluir a tag? O documento associado à tag será removido após a exclusão! +explorer.groupTag.typeAdd=Adicionar categoria +explorer.groupTag.typeName=Nome da Categoria +explorer.groupTag.addDesc=Depois de adicionar tags, as tags de departamento são ativadas automaticamente e o número máximo de tags é 1000 +explorer.panel.info=Atributos +explorer.panel.version=versão +explorer.panel.chat=discutir +explorer.panel.log=dinâmico +explorer.panel.meta=Metadados +explorer.panel.chatName=Troca de discussão +explorer.panel.chat.send=enviar +explorer.panel.chat.noAuth=Você não tem permissão para comentar sobre este documento! +explorer.panel.chat.placeholder=Digite aqui, [Enter] para enviar, [Ctrl + Enter] feed de linha +explorer.panel.chat.placeholderCtrl=Digite aqui, Ctrl + Enter para enviar, Enter para embrulhar +explorer.panel.chat.reply=Resposta +explorer.panel.chat.empty=sem comentários +explorer.panel.chat.sendTo=frente +explorer.panel.metaName=Extensão de metadados +explorer.panel.metaDesc=Propriedades do campo de documento estendido +explorer.panel.thumbClear=limpar miniatura +explorer.panel.thumbClearDesc=Limpar miniaturas de arquivos, arte da capa para regenerar. +explorer.panel.historyName=versão histórica +explorer.panel.historyDesc=Notas de versão +explorer.panel.infoTips=Selecione o arquivo (pasta) para visualizar propriedades detalhadas +explorer.panel.info.space=Capacidade de espaço +explorer.panel.info.groupAt=Localização do Departamento +explorer.panel.info.tagEmpty=Sem tags, clique em configurações +explorer.panel.logName=Notícias sobre documentos +explorer.panel.logEmpty=Nenhuma atividade +explorer.type.doc=Doc +explorer.type.image=imagem +explorer.type.music=música +explorer.type.movie=vídeo +explorer.type.zip=Arquivo +explorer.type.others=de outros +explorer.secret.title=Gerenciamento de confidencialidade de documentos +explorer.secret.isOpen=Se deve habilitar +explorer.secret.isOpenDesc=Habilitar e desabilitar o gerenciamento do nível de segurança +explorer.secret.setUser=gerente secreto +explorer.secret.setUserDesc=Especifique o usuário que pode definir o nível de confidencialidade (deve ser o proprietário no departamento correspondente ao mesmo tempo) +explorer.secret.type=Tipo de classificação +explorer.secret.add=Adicionar nível de segurança +explorer.secret.edit=editar nível de segurança +explorer.secret.name=Nome da classe +explorer.secret.style=estilo +explorer.secret.auth=Permissão de nível secreto +explorer.secret.authHas=As permissões confidenciais incluem +explorer.secret.createUser=normatizador +explorer.secret.folderAt=pasta confidencial +explorer.secret.tips=As permissões são controladas pelo nível secreto e as permissões do nível secreto são mais altas que as permissões do documento +explorer.secret.tips1=Apenas para o conteúdo no disco de rede departamental, o usuário especificado acima pode definir o nível de confidencialidade (e deve ser o proprietário da pasta ao mesmo tempo) +explorer.secret.tips2=Todo o conteúdo na camada inferior da pasta com o nível de confidencialidade é definido e essa autoridade é a mais alta autoridade +explorer.secret.tips3=Após a configuração, a permissão do nível secreto é maior que a permissão do documento (o documento também é controlado pela permissão do nível secreto, o superadministrador do sistema não está sujeito a essa restrição e o configurador do nível secreto não está sujeito a essa restrição) +explorer.secret.tips4=Permissões de nível confidencial: podem ser adicionadas em "Gerenciamento de departamentos e membros - Gerenciamento de direitos de documentos" e definidas como ocultas +user.displayHideFile=Mostrar arquivos ocultos +user.displayHideFileDesc=Arquivos ocultos: arquivos iniciados com., E nomes de arquivos ocultos definidos no plano de fundo do sistema; os arquivos ocultos serão exibidos após a abertura; +user.soundOpen=Ativar som +user.animateOpen=Iniciar animação +user.recycleOpen=Lixeira aberta +user.recycleDesc=Após a abertura, a exclusão será movida para a lixeira, é recomendável abrir +user.animateDesc=Animações como abertura de janela, você pode considerar fechar quando a operação não for suave +user.soundDesc=Abra arquivos, exclua arquivos, lixeira vazia, etc. +user.thumbOpen=Abrir miniatura da imagem +user.thumbDesc=Melhor experiência de navegação de fotos após a abertura +user.fileSelect=Ícone de arquivo aberto +user.fileSelectDesc=Clique com o botão esquerdo do mouse no ícone do arquivo, atalho para o menu de atalho +user.fileShowDesc=Mostrar introdução da pasta +user.fileShowDescTips=modo somente ícone +user.fileOpenClick=Abra o arquivo (pasta) da seguinte forma +user.fileOpenClick.dbclick=Abrir com duplo clique +user.fileOpenClick.click=Abra clicando +user.viewSetting=Mostrar opções +user.thirdAccount=Conta de terceiros +user.bindAccount=Vincular conta +user.thirdBindFirst=A conta não foi vinculada, use após a ligação +user.account=Conta +user.bind=Vincular +user.unbind=Desatar +user.binded=Limite +user.clickBind=Clique em vincular +user.clickToBind=Não vinculado, clique em vincular +user.clickEditPwd=Clique em Modificar senha +user.userAvatar=Foto do perfil +user.userNickName=Apelido pessoal +user.userAccount=Conta pessoal +user.uploadAvatar=Upload +user.userAvatarCrop=Selecione uma área adequada como avatar +user.userAvatarExt=Suporta apenas formatos de imagem JPG, JPEG, PNG +user.resetPwdDesc=Esqueceu sua senha? Você pode +user.inputEmailCode=Digite seu código de verificação de e-mail +user.inputSmsCode=Digite o código de verificação por SMS +user.emailVerifyDesc=Algumas empresas exigem verificação de e-mail +user.phoneVerifyDesc=Algumas empresas exigem verificação de celular +user.bindOthers=Já está associado a outra conta +user.notBind=Ainda não vinculado +user.regist=Registro de usuário +user.notRegist=Não registrado +user.registed=Já está registrado +user.signError=A assinatura de retorno de chamada está incorreta +user.repeat=Repetir +user.noRepeat=Não pode repetir +user.newPwd=Nova senha +user.unAuthFile=Acesso a arquivos não autorizado +user.unbindWarning=Altere a senha antes de desvincular, caso contrário, a conta não funcionará corretamente +user.isLoginTips=Foi detectado que você está logado no momento! +user.isLoginEnter=Entre agora +user.ifUnbind=Tem certeza de que deseja desassociar? +user.bindFirst=Ligue primeiro o seu email ou número de telemóvel +user.inputNewPwd=Digite uma nova senha +user.inputNewValue=Por favor, preencha o novo conteúdo +user.guestLogin=Login do turista +user.name=Conta de login +user.nickName=Apelido do usuário +user.code=Código de verificação +user.codeError=Erro no código de verificação +user.imgCode=CAPTCHA +user.rootPwd=Definir senha do administrador +user.rootPwdRepeat=Confirme a senha novamente +user.rootPwdEqual=As senhas não coincidem duas vezes! +user.rootPwdTips=Defina uma senha de administrador! +user.pwdError=Nome de usuário ou senha incorretos! +user.pwdNotNull=A senha não pode estar vazia! +user.oldPwdError=A senha original está errada! +user.keepPwd=Lembrar senha +user.forgetPwd=Esqueci minha senha +user.directLogin=Já está logado +user.moreLogin=Mais maneiras de fazer login +user.loginNow=Entre agora +user.registNow=Inscreva-se agora +user.backHome=Voltar à página inicial +user.ifHasAccount=Já tem uma conta? +user.userEnabled=A conta está desativada ou ainda não está ativada! Entre em contato com o administrador +user.roleError=O grupo de permissões não existe, entre em contato com o administrador +user.invalidEmail=Você não possui um endereço de e-mail válido, entre em contato com o administrador para modificar +user.codeRefresh=Clique em atualizar +user.emailVerify=Autenticação de caixa de correio +user.sendSuccess=Enviado com sucesso +user.sendFail=Falha no envio +user.sendSuccessDesc=Código de verificação enviado com sucesso, acesse +user.sendFailDesc=Falha no envio do código de verificação. Entre em contato com o administrador +user.inputVerifyCode=Digite o código de verificação +user.getCode=Obter código de verificação +user.inputPwd=Digite a senha +user.inputPwdAgain=Digite a senha novamente +user.inputNickName=Digite um apelido +user.inputEmail=Digite seu endereço de e-mail +user.inputPhone=Digite seu número de telefone +user.inputPhoneEmail=Por favor, digite o telefone móvel / E-mail +user.invalidPhoneEmail=Telefone / email inválido +user.findPwd=Recuperar senha +user.inputNotMatch=O %s inserido não corresponde ao limite +user.usingDesc=Você está usando +user.improveInfo=Por favor complete as informações +user.codeExpired=O código de verificação expirou, obtenha-o novamente +user.codeErrorTooMany=Demasiados erros no código de verificação, adquira novamente +user.codeErrorFreq=A frequência de envio é muito alta, tente novamente mais tarde! +user.codeErrorCnt=O número de envios excedeu o limite e ficará bloqueado por %s horas. +user.registSuccess=Registrado com sucesso +user.waitCheck=Aguardando revisão do administrador +user.nameHolder=Por favor insira seu número de telefone / e-mail +user.loginNoPermission=Desculpe, você não tem essa permissão, faça o login com uma conta com essa permissão! +user.loginFirst=Você não está logado! Faça o login primeiro +user.bindSignError=A assinatura está anormal, tente novamente! +user.bindUpdateError=Falha na atualização das informações do usuário. Tente novamente +user.bindTypeError=Tipo de ligação inválido +user.bindWxConfigError=Obter exceção de informações de configuração +user.loginTimeout=O login atual expirou, faça o login novamente! +user.theme=Estilo do tema +user.theme.desc=Sistema de acompanhamento de representante automático +user.theme.light=Cor clara +user.theme.dark=Cor escura +user.theme.auto=automático +user.theme.title=Configurações de tema personalizadas +user.theme.background=Antecedentes +user.theme.image=Imagens +user.theme.colorBlur=Cor gradiente +user.theme.imageBlur=Processamento de desfoque de imagem +user.theme.imageUrl=Endereço da imagem +user.theme.colorStart=Iniciar cor +user.theme.colorEnd=Cor final +user.theme.colorRadius=Ângulo de inclinação +user.theme.themeImage=Imagem de fundo +user.theme.themeImageDesc=Suporte: url da imagem, cor gradiente css, seguir papel de parede +user.theme.imageWall=Seguir papel de parede +user.wall.random=Papel de parede aleatório +user.wall.paperDesktop=Papéis de parede +user.wall.paperDeskMgt=Gerenciamento de papel de parede da área de trabalho +user.wall.paperLoginMgt=Gerenciamento de papel de parede de login +user.wall.paperLoginTips=Quando houver mais de uma imagem, o plano de fundo da interface de login irá girar aleatoriamente +log-type-create-mkdir=nova pasta +log-type-create-mkfile=crie um novo arquivo +log-type-create-upload=fazer upload de arquivos +log-type-create-copy=Colar arquivo +log-type-edit=Atualizar arquivo +log-type-move=Mover arquivo +log-type-moveOut=Remover arquivos +log-type-share-shareLinkAdd=Criou um compartilhamento de link externo +log-type-share-shareToAdd=Compartilhamento colaborativo ativado +log-type-share-shareLinkRemove=Compartilhamento de link fechado +log-type-share-shareToRemove=Desativar compartilhamento colaborativo +log-type-share-shareEdit=Editar compartilhamento +log-type-rename=Renomear +log-type-recycle-toRecycle=Mover para a lixeira +log-type-recycle-restore=Restaurar da lixeira +log-type-remove=excluir +log-type-addDesc=Modificar descrição +log-type-addComment=Publicar um comentário +log-event-create-mkdir=Criou esta pasta +log-event-create-mkfile=Criou o arquivo +log-event-create-upload=Carregou o arquivo +log-event-create-copy=O arquivo foi criado colando +log-event-create-mkdir-current=Criou uma nova pasta aqui {0} +log-event-create-mkfile-current=Novo arquivo criado aqui {0} +log-event-create-upload-current=Carregado aqui {0} +log-event-create-copy-current=Colado {0} aqui +log-event-create-mkdir-item=Criou uma nova pasta em {0} {1} +log-event-create-mkfile-item=Novo arquivo criado em {0} {1} +log-event-create-upload-item=Carregado {1} em {0} +log-event-create-copy-item=Cole {0} a {1} +log-event-create-mkdir-more=Criou {0} pastas aqui +log-event-create-mkfile-more={0} novos arquivos criados aqui +log-event-create-upload-more={0} arquivos enviados aqui +log-event-create-copy-more={0} arquivos colados aqui +log-event-create-mkdir-more-at=Criou {1} novas pastas em {0} +log-event-create-mkfile-more-at=Criou {1} novos arquivos em {0} +log-event-create-upload-more-at={1} arquivos enviados em {0} +log-event-create-copy-more-at=Documentos colados {0} em {1} +log-event-view-item=Visto {0} +log-event-edit=atualizou o arquivo +log-event-edit-item=Edição atualizada {0} +log-event-edit-more=Editar {0} arquivos atualizados +log-event-edit-more-user=Editou e atualizou o arquivo {0} {1} vezes +log-event-edit-more-at=Editado e atualizado {1} arquivos em {0} +log-event-move=Mova o documento de {0} para {1} +log-event-move-item=Mover {0} de {1} para [3] +log-event-move-current=Mover {0} de {1} para cá +log-event-move-more={0} documentos movidos +log-event-move-more-desc=Mova {0} de {1} para [3] +log-event-moveOut-more-desc=Removido de {0} {1} +log-event-moveOut=Removido daqui {0} +log-event-moveOut-item=Removido de {0} {1} +log-event-moveOut-more={0} documentos removidos +log-event-share-shareLinkAdd=Criou um link externo para compartilhar este documento +log-event-share-shareLinkAdd-item={0} criou um link externo para compartilhar +log-event-share-shareLinkAdd-more=Criou {0} links para compartilhar +log-event-share-shareToAdd=Ative o compartilhamento colaborativo deste documento +log-event-share-shareToAdd-item={0} ativou o compartilhamento de colaboração +log-event-share-shareToAdd-more={0} compartilhamentos colaborativos criados +log-event-share-shareLinkRemove=Fechou o compartilhamento de links do documento +log-event-share-shareLinkRemove-item=Compartilhamento de link fechado {0} +log-event-share-shareLinkRemove-more=Fechar {0} compartilhamento de link externo +log-event-share-shareToRemove=Desative o compartilhamento colaborativo deste documento +log-event-share-shareToRemove-item=Desative o compartilhamento de colaboração para {0} +log-event-share-shareToRemove-more=Fechar {0} compartilhamento colaborativo +log-event-share-shareEdit=Editou o compartilhamento deste documento +log-event-share-shareEdit-item=Partilha de {0} editada +log-event-share-shareEdit-more=Documentos {0} editados para compartilhar +log-event-rename=Renomeou o documento +log-event-rename-item=Renomeado {0} +log-event-rename-more={0} documentos renomeados +log-event-recycle-toRecycle=Moveu o documento para a lixeira +log-event-recycle-toRecycle-current=Movido {0} para a lixeira aqui +log-event-recycle-toRecycle-item=Movido {1} para a lixeira em {0} +log-event-recycle-toRecycle-more=Movidos {0} documentos para a lixeira +log-event-recycle-toRecycle-more-at=Moveram {1} documentos para a lixeira em {0} +log-event-recycle-restore=Restaurar o documento da lixeira +log-event-recycle-restore-item=Restaure {0} da lixeira +log-event-recycle-restore-more=Restaurar {0} documentos da lixeira +log-event-remove=Excluído {0} aqui +log-event-remove-current=Excluído {0} aqui +log-event-remove-item=Excluído {1} em {0} +log-event-remove-more={0} documentos excluídos aqui +log-event-remove-more-at=Excluiu {1} documentos em {0} +log-event-addDesc=Modificou a descrição do documento +log-event-addDesc-item=Descrição do documento {0} modificada +log-event-addDesc-more=Descrições de documentos {0} modificadas +log-event-addComment=Comentou este documento +log-event-addComment-item=Comentado em {0} +log-event-addComment-more=Listados {1} comentários em {0} +log-event-fav-fileAdd=Marcado como favorito {0} +log-event-fav-dirAdd=Pastas marcadas {0} +log-event-down-item=Transferido {1} de {0} +log-event-down-items=Baixado de {0} +log-event-recycle-del-item=Exclua {0} arquivos da lixeira +log-event-recycle-rst-item=Restaurar {0} arquivos da lixeira +log-event-del-item={0} arquivos excluídos +log.file.move=Mover / copiar +log.file.fav=Operação de favoritos +log.file.shareLink=Compartilhamento de link externo +log.file.shareTo=Compartilhamento colaborativo +log.user.edit=Modificar as informações da conta +log.group.edit=Gestão de departamento +log.member.edit=Gestão de Usuários +log.role.edit=Gestão de funções +log.auth.edit=Gestão de direitos de documentos +meta.user_sourceAlias=Arquivos relacionados (anexos) +meta.user_fileEncodeType=Confidencialidade do arquivo +meta.user_fileEncodeType.A=Segredo A-Top +meta.user_fileEncodeType.B=Confidencial B +meta.user_fileEncodeType.C=C-Secret +meta.user_sourceNumber=Número do volume +meta.user_sourceParticipant=Participante +explorer.fileInfo.createTime=Data de criação +explorer.fileInfo.modifyTime=Data modificada +explorer.fileInfo.softwareCreate=Software de produção +explorer.fileInfo.software=Software de codificação +explorer.fileInfo.playTime=Hora do jogo +explorer.fileInfo.imageSize=tamanho da imagem +explorer.fileInfo.imageDpi=Resolução +explorer.fileInfo.imageBits=Profundidade de bits +explorer.fileInfo.imageDesc=Anotação +explorer.fileInfo.imageAuthor=O Criador +explorer.fileInfo.imageColor=Espaço colorido +explorer.fileInfo.cameraType=Modelo do dispositivo +explorer.fileInfo.cameraApertureFNumber=Número de abertura +explorer.fileInfo.cameraApertureValue=Valor de abertura +explorer.fileInfo.cameraShutterSpeedValue=Velocidade do obturador +explorer.fileInfo.cameraExposureTime=Tempo de exposição +explorer.fileInfo.cameraFocalLength=comprimento focal +explorer.fileInfo.cameraFocusDistance=Distância de foco +explorer.fileInfo.cameraISOSpeedRatings=Sensibilidade ISO +explorer.fileInfo.cameraWhiteBalance=Equilíbrio de branco +explorer.fileInfo.cameraUser=Manual +explorer.fileInfo.cameraAuto=automático +explorer.fileInfo.cameraExposureMode=Modo de exposição +explorer.fileInfo.cameraExposureBiasValue=Compensação de exposição +explorer.fileInfo.imageGps=Local de filmagem +explorer.fileInfo.imageCreateTime=Data de filmagem +explorer.fileInfo.audioChannel=Canal de áudio +explorer.fileInfo.audioChannel1=Mono +explorer.fileInfo.audioChannel2=estéreo +explorer.fileInfo.audioChannels=Multicanal +explorer.fileInfo.audioRate=Taxa de amostragem de áudio +explorer.fileInfo.audioBits=Profundidade de bits de áudio +explorer.fileInfo.audioBitrate=Taxa de bits do áudio +explorer.fileInfo.vedioFormat=Codificação de vídeo +explorer.fileInfo.audioTitle=título +explorer.fileInfo.audioAuthor=Autor +explorer.fileInfo.audioAlbum=Álbum +explorer.fileInfo.audioStyle=estilo +explorer.fileInfo.audioYear=Ano do álbum +explorer.fileInfo.vedioSize=Tamanho da tela +explorer.fileInfo.vedioFrame=Taxa de quadros de vídeo +explorer.fileInfo.vedioBitrate=Taxa de bits de vídeo +explorer.fileInfo.title=título +explorer.fileInfo.author=Autor +explorer.fileInfo.pageTotal=páginas totais +explorer.fileInfo.pageSize=Tamanho da página +explorer.fileInfo.pagePower=Criador de conteúdo +explorer.fileInfo.pdfVersion=Versão em PDF +explorer.filter.shareCopyLimit=O número de arquivos a serem despejados excede o limite; o número máximo de arquivos que você pode despejar é: +explorer.filter.shareSizeLimit=O tamanho do arquivo compartilhado excede o limite; o máximo que você pode compartilhar é: +explorer.filter.unzipSizeLimit=O tamanho do arquivo descompactado excede o limite; o máximo que você pode descompactar é: +explorer.filter.zipSizeLimit=O tamanho do arquivo compactado excede o limite; seus documentos compactados máximos: +explorer.filter.uploadSizeLimit=O tamanho do upload excede o limite; o máximo que você pode fazer upload é: +explorer.fileEditError=O ficheiro actual %s está a ser editado. Tente novamente mais tarde +explorer.groupDelError=Lamentamos, as pastas do departamento não suportam a eliminação +admin.info.typeDelError=A eliminação falhou com subcategorias ou dados +admin.info.domainIdentifyError=Sítio Web não reconhecido +admin.info.articleIdentifyError=Artigo não reconhecido +admin.info.domainSupportError=Este site atualmente não suporta coleta +admin.info.fileTooLarge=Ficheiro demasiado grande +explorer.toolbar.info=Informação em tempo real +source.shareDisabled=O recurso atual está proibido de compartilhar +admin.exceeds.limit=Exceder o limite +admin.design.deleted=O estado de activação não pode ser apagado +admin.design.url.locked=O URL atual está bloqueado e não pode ser usado temporariamente +explorer.SING_INVALID=Excepção de assinatura +explorer.TEMP_AUTH_INVALID=O código de autorização temporária é inválido (inválido) +explorer.QR_INVALID=O código QR expirou +explorer.toolbar.toolbox=Caixa de Ferramentas +explorer.toolbox.desc= +logs-detail-mkdir=Criada uma nova pasta +logs-detail-mkfile=Criou um novo ficheiro +logs-detail-editFile=O editor atualizou +logs-detail-upload=Ficheiros enviados +logs-detail-uploadNew=Editado +logs-detail-file.upload=Carregado +logs-detail-file-copy=Colar o ficheiro criado +logs-detail-folder-copy=Colar a pasta criada +logs-detail-paste=colar +logs-detail-from=de +logs-detail-to=alcance +logs-detail-rename=Renomeado +logs-detail-rename-file=Renomeou o ficheiro +logs-detail-rename-folder=Renomeou a pasta +logs-detail-user=utilizador: +logs-detail-moveFrom-restore=tomar +logs-detail-moveTo-restore=Restaurar da Lixeira +logs-detail-move=tomar +logs-detail-moveTo=Mover para +logs-detail-moveFrom-toRecycle=tomar +logs-detail-moveTo-toRecycle=Movedo para a Lixeira +logs-detail-file-toRecycle=Moveu o ficheiro para a Lixeira +logs-detail-file-restore=Restaurar este ficheiro a partir da Lixeira +logs-detail-folder-toRecycle=Moveu esta pasta para a Lixeira +logs-detail-folder-restore=Restaurar esta pasta a partir da Lixeira +logs-detail-favAdd=Recolhido +logs-detail-favDel=Recolha cancelada +logs-detail-unstar=nome: +logs-detail-moveOut=Removido +logs-detail-remove=Removido +logs-detail-file.copy=Colado +explorer.noPermissionAuthAll={0} ,Sem permissão para esta operação \ No newline at end of file diff --git a/src/main/resources/i18n/messages_ru_RU.properties b/src/main/resources/i18n/messages_ru_RU.properties new file mode 100644 index 0000000..bc41bb5 --- /dev/null +++ b/src/main/resources/i18n/messages_ru_RU.properties @@ -0,0 +1,2563 @@ +admin.serverInfo=Информация о сервере +admin.today=сегодня +admin.yesterday=вчера +admin.weekDay=Почти 7 дней +admin.monthDay=Почти 30 дней +admin.ing=В процессе +admin.paused=Приостановлено +admin.serverDownload=Удаленная загрузка +admin.memberManage=Управление пользователями +admin.fileManage=Управление файлами +admin.pwdEdit=Сменить пароль +admin.fileEdit=Изменить файл сохранения +admin.list=Представление списка +admin.configError=Ошибка сохранения конфигурации, администратор отключил это разрешение! +admin.userManage=Персональный центр +admin.manage=Фоновое управление +admin.pluginManage=Управление плагинами +admin.emailDear=Здравствуйте %s, +admin.emailCodeText=Вы подтверждаете свой адрес электронной почты. Код подтверждения для этого запроса выглядит следующим образом. Чтобы обеспечить безопасность вашей учетной записи, своевременно завершите проверку. +admin.emailVerifyInTime=Для обеспечения безопасности вашей учетной записи, пожалуйста, завершите проверку вовремя. +admin.dear=дорогой +admin.dearUser=Уважаемый пользователь, +admin.emailResetLink=Вы сбрасываете логин-пароль для %s по электронной почте, пожалуйста, нажмите на ссылку ниже, чтобы сбросить его. Если ссылка не переходит, скопируйте ее в адресную строку браузера, чтобы получить к ней доступ: +admin.emailExpireTime=Срок действия ссылки истекает через 20 минут. +admin.jobName=Должность +admin.jobDesc=Описание работы +admin.jobNameInput=Пожалуйста, введите название работы +admin.jobEdit=Редактор постов +admin.menu.home=дома +admin.menu.dashboard=обзор +admin.menu.dashboardTitle=Обзор статистики +admin.menu.notice=Управление уведомлениями +admin.menu.groupMember=Департамент и члены управления +admin.menu.member=Отделы и пользователи +admin.menu.role=Ролевое управление +admin.menu.job=Управление работой +admin.menu.auth=Управление правами на документы +admin.menu.storage=Хранение / файл +admin.menu.storageDriver=Управление хранением +admin.menu.plugin=Плагин Центр +admin.menu.tools=Контроль безопасности +admin.menu.server=Управление сервером +admin.menu.backup=Управление резервным копированием +admin.menu.share=Совместное управление +admin.menu.loginLog=Вход в систему +admin.menu.log=Журнал операций +admin.menu.task=Запланированные задачи +admin.autoTask.restart=Перезапустить запланированные задачи +admin.autoTask.restartEnd=Запланированная задача перезапущена +admin.index.userSpace=Пространство пользователя +admin.index.groupSpace=Космический отдел +admin.index.folderCount=Количество папок: +admin.index.fileCount=Количество файлов: +admin.index.loginToday=Войти сегодня +admin.index.useTotal=Общее использование: +admin.index.userLogin=Логин пользователя +admin.index.spaceUsed=Занять место +admin.index.useSpace=Использовать пространство +admin.index.usedSpace=Используемое пространство +admin.index.freeSpace=оставшееся пространство +admin.index.sizeLimit=Ограниченный размер +admin.index.vipCount=Зарегистрированные пользователи +admin.index.loginCurrent=Сейчас на сайте +admin.index.fileDel=Удаление файла +admin.index.fileEdit=Редактирование файлов +admin.index.fileUpload=Файл загружен +admin.index.fileDown=Скачать документ +admin.index.spaceUse=Практическое использование +admin.index.spaceSave=Сэкономить место +admin.index.spaceUser=Использование пользователя +admin.index.spaceGroup=Отдел использования +admin.index.lastLogin=Время последнего входа +admin.index.totalUsers=Всего пользователей +admin.index.loginUsers=Логин пользователя +admin.index.spaceActUsed=Фактическое занятие +admin.index.source=Источник входа +admin.index.address=Адрес для входа +admin.index.userInfo=Информация о пользователе +admin.index.userValid=Действительный аккаунт +admin.index.userInvalid=Неверный аккаунт +admin.index.fileInfo=Информация о файле +admin.index.fileCnt=Количество файлов +admin.index.fileAdd=Добавлено сегодня +admin.index.accInfo=Доступ к информации +admin.index.accCnt=Запросы +admin.index.accUser=Доступ пользователя +admin.index.serverInfo=системное сообщение +admin.index.serverDisk=Системный диск +admin.index.serverStore=Сетевое хранилище +admin.index.serverName=название сервера +admin.index.normal=нормальный +admin.index.scoreDesc=Следующие факторы будут влиять на оценку системы, которая может быть оптимизирована для обеспечения нормальной работы системы:
    1. Оставшееся место на системном диске и сетевом диске;
    2. Метод кэширования данных (рекомендуется redis);
    Версия платформы 3.php (рекомендуется 64-битная версия php7 +). +admin.index.fileRatio=Коэффициент использования файлов +admin.setting.system=Системные настройки +admin.setting.account=Настройки аккаунта +admin.setting.theme=Настройки темы +admin.setting.wall=Настройки обоев +admin.setting.stats=Статистика использования +admin.setting.safeMgt=Управление безопасностью +admin.setting.base=Основные настройки +admin.setting.others=Другие настройки +admin.setting.sync=Настройки синхронизации +admin.setting.plugin=Настройки плагина +admin.setting.auth=Настройка разрешения +admin.setting.safe=Настройки безопасности +admin.setting.loginLog=Журнал входа +admin.setting.loginDevice=Устройство входа +admin.setting.deviceType=Тип оборудования +admin.setting.lastLoginTime=Время последнего входа +admin.setting.email=Настройки электронной почты +admin.setting.user=Регистрация и вход +admin.setting.pwdOld=Оригинальный пароль +admin.setting.pwdNew=Изменить на +admin.setting.wallDiy=Пользовательские обои: +admin.setting.fav=Управление избранным +admin.setting.help=Используйте помощь +admin.setting.about=О работах +admin.setting.homePage=Kodcloud домой +admin.setting.subMenu=Подменю +admin.setting.menuName=Название меню +admin.setting.menuUrl=URL-адрес +admin.setting.menuUrlDesc=URL-адрес или код JS +admin.setting.safeAccount=Безопасность учетной записи и входа +admin.setting.safeData=Безопасность данных / безопасность передачи +admin.setting.passwordErrorLock=Блокировка ввода пароля +admin.setting.passwordErrorLockDesc=Если пароль неверный 5 раз подряд, учетная запись будет заблокирована на 1 минуту и не позволит войти в систему. После открытия она может эффективно предотвратить взлом пароля; +admin.setting.passwordRule=Настройка надежности пароля пользователя +admin.setting.passwordRuleDesc=После того, как сила пароля указана, слабый пароль может быть эффективно устранен +admin.setting.passwordRuleNone=Без ограничения +admin.setting.passwordRuleStrong=Средней интенсивности +admin.setting.passwordRuleStrongMore=Высокая прочность +admin.setting.passwordRuleNoneDesc=Неограниченная надежность пароля +admin.setting.passwordRuleStrongDesc=Длина больше 6, должна содержать как английский, так и цифры; +admin.setting.passwordRuleStrongMoreDesc=Длина больше 6, должна содержать цифры, прописные буквы английского алфавита, строчные буквы английского алфавита; +admin.setting.passwordRuleTips=Ваш текущий пароль недостаточно надежен, рекомендуется сменить пароль немедленно! +admin.loginCheck.menu=Контроль входа в систему +admin.loginCheck.ipCheck=Ограничения IP +admin.loginCheck.ipCheckNone=не ограничен +admin.loginCheck.ipCheckAllow=Белый список IP-адресов +admin.loginCheck.ipCheckDisable=Черный список IP +admin.loginCheck.loginIpAllowDesc=После открытия войти могут только пользователи с указанным ip, будьте осторожны +admin.loginCheck.ipAllow=Разрешенный IP +admin.loginCheck.ipAllowDesc=Заполните правила следующим образом (каждая строка, локальный IP-адрес сервера разрешен по умолчанию, а системный администратор разрешает IP-адрес LAN) +admin.loginCheck.ipDisable=Черный список IP-правил +admin.loginCheck.ipDisableDesc= +admin.loginCheck.ipDescTitle=Заполните правила следующим образом (по одной строке на запись) +admin.loginCheck.ipDesc= +admin.loginCheck.sort=приоритет +admin.loginCheck.name=Название правила +admin.loginCheck.user=Назначенный пользователь +admin.loginCheck.device=Специальное оборудование +admin.loginCheck.deviceWeb=Интернет +admin.loginCheck.devicePc=Сторона ПК +admin.loginCheck.deviceAndroid=Android +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc=
    Инструкции по контролю ограничения входа пользователя (ограничения IP и устройства):
  • Обнаруживать последовательно в соответствии с порядком приоритета правила; пользователь, указанный правилом, включает в себя текущего пользователя, вошедшего в систему; тогда правило определяется как результат
  • Рекомендуется помещать группы пользователей и пользователей отдела на обороте, а параметры пользователя указывать на передней панели; (перетащите и отпустите, чтобы изменить порядок)
  • +admin.setting.checkCode=Код подтверждения входа включен +admin.setting.checkCodeDesc=После входа необходимо ввести код подтверждения. +admin.setting.csrfProtect=Включить защиту CSRF +admin.setting.csrfProtectDesc=Может эффективно предотвращать атаки CSR при включении +admin.setting.setRootPath=Root доступ +admin.setting.setRootPathDesc=Только системный администратор может получить доступ ко всем каталогам, а пользователи в других группах разрешений могут видеть только свои собственные пользовательские каталоги.
    Если вы хотите , чтобы включить или отключить доступ администратора к другим каталогам, вы можете изменить PHP open_basedir параметров анти-межсайтовых, как настроить +admin.setting.encode=Шифрование хранилища файлов +admin.setting.encodeAll=Зашифровать все +admin.setting.encodeName=Сохранить расширение +admin.setting.encodeNone=Без шифрования +admin.setting.encodeAllDesc=Полное шифрование: [рекомендация по умолчанию], даже если у вас есть права доступа к серверу, вы не знаете истинного содержимого файла, он может эффективно защитить от вымогателей и других повреждений; +admin.setting.encodeNameDesc=Сохранить расширение: шифрование имени файла, сохранить расширение +admin.setting.encodeNullDesc=Без шифрования: имя файла не зашифровано, а исходное имя файла сохраняется; (для обеспечения безопасности папка загрузки называется зашифрованной структурой); +admin.setting.encodeTips1=Изменяются только файлы после изменения настроек, файлы, которые существовали ранее, не затрагиваются; +admin.setting.encodeTips2=Чтобы избежать ошибок, пожалуйста, не удаляйте и не переименовывайте файлы в data / files; +admin.setting.encodeTips3=Для поддержки крупномасштабного параллелизма, второй передачи, кластеризации, распределенного, автоматического расширения и других функций, иерархия папок записывается в базу данных, структуру папок можно импортировать и восстанавливать путем копирования и вставки; +admin.setting.thirdLogin=Сторонний логин +admin.setting.thirdLoginDesc=Разрешить регистрацию, привязку и вход через сторонние аккаунты +admin.setting.registOpen=Открытая регистрация пользователя +admin.setting.registOpenDesc=Во избежание конфликтов данных синхронизация сторонних данных и регистрация пользователей не могут быть включены одновременно +admin.setting.registCheck=Открыть регистрационный обзор +admin.setting.registCheckDesc=После открытия администратор должен просмотреть и включить его в [Пользователи и отделы], чтобы зарегистрированные пользователи могли нормально пользоваться +admin.setting.clearUserRecycle=Очистить все корзины пользователя +admin.setting.clearCache=Очистить кеш +admin.setting.icp=Авторское право или номер записи +admin.setting.icpDesc=Если вам нужно сгенерировать ссылку, вы можете добавить тег самостоятельно +admin.setting.globalCss=Пользовательские глобальные CSS +admin.setting.globalCssDesc=Все страницы будут вставлять пользовательские CSS +admin.setting.globalHtml=Статистический код HTML +admin.setting.globalHtmlDesc=Все страницы будут вставлять этот HTML-код, и сторонний статистический код может быть размещен +admin.setting.dateFormat=Формат даты +admin.setting.dateFormatDesc=Отображение формата времени год-месяц-день, время модификации файла и т. д. +admin.setting.menu=Управление меню +admin.setting.systemName=Название продукта компании +admin.setting.systemNameDesc=Для названия продукта логотип +admin.setting.systemDesc=Субтитры продукта +admin.setting.pathHidden=Исключение каталогов +admin.setting.pathHiddenDesc=Каталоги и файлы не отображаются по умолчанию, разделенные запятыми +admin.setting.defaultFolder=Новые пользователи создают каталоги по умолчанию +admin.setting.defaultFolderDesc=Разделенные запятыми +admin.setting.defaultApp=Новые пользователи создают приложения по умолчанию +admin.setting.defaultAppDesc=Приложения центра приложений, несколько разделенных запятыми +admin.setting.autoLogin=Автоматический вход +admin.setting.autoLoginDesc=Пользователь по умолчанию для входа - guest/guest , убедитесь, что он существует после открытия +admin.setting.firstIn=Введите по умолчанию после входа в систему +admin.setting.registReviewOpen=Открытый регистрационный аудит: +admin.setting.registRoleEmpty=Роль разрешения не может быть пустой +admin.setting.registNotSync=Во избежание конфликтов данных синхронизация сторонних данных и регистрация пользователей не могут быть включены одновременно +admin.setting.registNeedRewiew=После его открытия администратор должен просмотреть и включить его в пользователях и отделах, прежде чем зарегистрированные пользователи смогут использовать его в обычном режиме. +admin.setting.roleRight=Роль разрешений +admin.setting.emailHost=Сервер почтовых ящиков +admin.setting.emailHostInput=Пожалуйста, введите адрес почтового сервера +admin.setting.emailHostTips=Пожалуйста, заполните адрес почтового сервера +admin.setting.emailHostDesc=Сервер почтовых ящиков, например: smtp.163.com, порт можно настроить (по умолчанию 465) +admin.setting.emailSend=исходящая корреспонденция +admin.setting.emailSendInput=Пожалуйста, введите адрес электронной почты +admin.setting.emailSendTips=Пожалуйста, заполните отправляющий адрес электронной почты +admin.setting.emailSendDesc=Адрес электронной почты системы, служба POP3 / SMTP должна быть включена +admin.setting.emailPwd=Пароль авторизации +admin.setting.emailPwdTips=Пожалуйста, заполните пароль авторизации электронной почты +admin.setting.secureType=Шифрование +admin.setting.emailSendTest=Отправить обнаружение +admin.setting.ensureEmailOk=Пожалуйста, убедитесь, что письмо может быть отправлено в обычном режиме +admin.setting.emailTo=Написать почта +admin.setting.emailGoToTips=Пожалуйста, перейдите на почтовый ящик +admin.setting.emailCheckTips=вид +admin.setting.emailInputError=Неверные настройки электронной почты +admin.setting.emailPwdError=Неверный пароль для настройки электронной почты +admin.setting.emailDesc=Настроить почтовый сервер для регистрации пользователя, отправки пароля для восстановления электронной почты +admin.setting.sendEmail=Отправить почту +admin.setting.sendEmailDesc=Системное значение по умолчанию: вызов для отправки на облачный почтовый сервер для отправки; custom: настройка почтового сервера самостоятельно +admin.setting.systemBackup=Резервное копирование системы +admin.setting.enableFunction=Функции и переключатели +admin.setting.treeOpen=Переключатель функции дерева каталогов +admin.setting.treeOpenDesc=Управление файлами, соответствующая функция дерева каталогов глобально включена и выключена +admin.setting.groupListChild=Список подсекторов +admin.setting.groupListChildDesc=Независимо от того, отображаются ли в папке отдела подотделы, разрешения наследуются вверх +admin.setting.groupRootListChild=Корпоративный веб-диск содержит списки подсекторов +admin.setting.groupRootListChildDesc=Отображает ли папка диска корпоративной сети подотделы и права наследуются вверх +admin.setting.shareToMeAllowTree=Сотрудничайте со мной-шоу по организационной структуре +admin.setting.shareToMeAllowTreeTips=После открытия контент-поддержка для совместной работы со мной классифицируется в соответствии с организационной структурой отдела, что подходит для ситуаций, когда организационная структура более сложная. +admin.setting.groupTagAllow=Общественный лейбл отдела +admin.setting.groupTagAllowTips=После включения все члены отдела будут видны после установки общедоступной метки для файлов в отделе.Администратор отдела может поддерживать содержание метки. +admin.setting.shareToMeList=Плиточный дисплей +admin.setting.shareToMeGroup=Показать по организационной структуре +admin.setting.shareToMeUser=Показать по авторам +admin.setting.sysSrvState=Состояние сервера +admin.setting.sysSrvInfo=информация о сервере +admin.setting.sysPhpInfo=Информация PHP +admin.setting.database=база данных +admin.setting.cache=Кеш +admin.setting.sysMyInfo=моя информация +admin.setting.srvStateCpu=использование процессора +admin.setting.srvStateMem=Использование памяти +admin.setting.srvStateSrv=Место для хранения серверной системы +admin.setting.srvStateDef=Объем памяти по умолчанию на сетевом диске +admin.setting.srvInfoName=название сервера +admin.setting.srvInfoIp=IP-адрес сервера +admin.setting.srvInfoTime=серверное время +admin.setting.srvInfoUpTime=Время непрерывной работы +admin.setting.srvInfoWeb=Серверное программное обеспечение +admin.setting.srvInfoPhpV=Версия PHP +admin.setting.srvInfoSys=Серверная система +admin.setting.srvInfoPath=Путь к сайту +admin.setting.srvPhpDtl=Детали PHP +admin.setting.memLimit=Ограничение памяти +admin.setting.postLimit=Лимит отправки POST +admin.setting.uploadLimit=Ограничения на загрузку файлов +admin.setting.execTime=Максимальное время исполнения +admin.setting.inputTime=Максимальное время запроса +admin.setting.disFunction=Отключить функцию +admin.setting.phpExtSugst=Рекомендуемые расширения PHP +admin.setting.phpExtLoad=Загруженное расширение +admin.setting.myClientIp=Мой IP +admin.setting.myClientUa=Мой браузер UA +admin.setting.myClientLng=Мой язык браузера +admin.setting.disFuncDesc=Функции, требуемые системой, рекомендуется включить +admin.setting.srvMemFree=Оставшаяся память +admin.setting.srvMemUse=Использовать память +admin.setting.srvCpuUse=В настоящее время занято +admin.setting.srvCpuFree=Неиспользованный +admin.setting.noLimit=Безлимитный +admin.setting.disFunNo=нет +admin.setting.systemCache=Системный кеш +admin.setting.systemDb=Системная база данных +admin.setting.sysCacheTab=Переключатель кеша +admin.setting.sysDbTab=Переключатель базы данных +admin.setting.sysRecTab=Восстановление базы данных +admin.setting.cacheDesc=Описание кеша +admin.setting.fileCacheDesc=Файловый кеш: запись данных непосредственно в кеш-файл, пригодный для тестирования или небольшого использования. +admin.setting.redisDesc=Redis: высокопроизводительная нереляционная база данных со значением ключа, подходящая для ситуаций одновременного чтения и записи. Рекомендуется для использования. +admin.setting.memcachedDesc=Memcached: высокопроизводительная система кеширования объектов с распределенной памятью, подходящая для одновременных операций чтения. +admin.setting.saveAfterTest=После прохождения теста его можно сохранить +admin.setting.checkPassed=Прошло +admin.setting.ifSaveCache=После переключения все кешированные данные будут очищены!
    Вы уверены, что хотите выполнить? +admin.setting.ifSaveDb=Переключатель базы данных импортирует текущие данные системы в новую базу данных и установит их по умолчанию. Вы уверены, что хотите его выполнить? +admin.setting.dbCurrent=Текущая конфигурация +admin.setting.dbType=Тип базы данных +admin.setting.dbName=База данных имен +admin.setting.dbInfo=Информация о базе данных +admin.setting.dbSwitch=Включить +admin.setting.dbSwitchDesc=После открытия вы можете изменить тип базы данных по мере необходимости, будьте осторожны. +admin.setting.dbTable=техническая спецификация +admin.setting.dbCnt=Всего +admin.setting.dbNeedNew=База данных уже существует, укажите еще раз +admin.setting.dbInsertError=Не удалось записать данные таблицы +admin.setting.dbNeedOthers=Пожалуйста, выберите другой тип базы данных +admin.setting.dbNeedChange=Измените параметры конфигурации +admin.setting.dbCreateError=Не удалось создать файл базы данных, проверьте права доступа на чтение и запись для каталога. +admin.setting.dbTaskProcess=Ход выполнения +admin.setting.dbTasking=Выполняется +admin.setting.dbTaskDesc=Не закрывайте окно и не выполняйте другие операции в системе, чтобы избежать генерации несоответствия данных. +admin.setting.recTaskDesc=Не закрывайте окно - после прерывания запроса фон будет продолжать выполняться до завершения задачи. +admin.setting.dbCreate=Новая база данных +admin.setting.dbSelect=Читать базу данных +admin.setting.dbInsert=Запись в базу данных +admin.setting.dbSetSave=Сохранить информацию о конфигурации +admin.setting.recDesc=Инструкция по применению +admin.setting.recDescInfo11=Эта операция приведет к сбросу системных данных, отключение и обслуживание или связанный с ней технический персонал не должен работать! +admin.setting.recDescInfo21=Восстановление данных достигается путем записи резервной базы данных в новую базу данных и установки ее в качестве системной по умолчанию. +admin.setting.recDescInfo22=Новые параметры конфигурации базы данных будут добавлены к файлу конфигурации системы config / setting_user.php. Если система работает ненормально после выполнения восстановления, добавленную часть файла можно удалить, не затрагивая предыдущие системные данные. +admin.setting.recDescInfo23=Эта функция поддерживает только обработку данных резервного копирования, созданных системой управления резервным копированием, а база данных, резервная копия которой была создана вами, должна обрабатываться другими способами. +admin.setting.recDescInfo31=Примечание. Если тип базы данных - MySQL, новая библиотека (исходная библиотека name_current date_rebuild) будет создана на основе информации о текущей конфигурации. Пользователи без полномочий root могут не иметь достаточных разрешений, поэтому вам необходимо сначала установить разрешения для пользователя. +admin.setting.recDescInfo32=Например, текущая информация о конфигурации базы данных: пользователь: kod; пароль: kod123. Используйте учетную запись root для входа в базу данных и выполните соответствующий оператор SQL, чтобы установить разрешения (разрешения можно отозвать после прохождения теста и успешного восстановления). +admin.setting.recDescInfo33=Настройка разрешений: +admin.setting.recDescInfo34=Отменить разрешения: +admin.setting.recOpen=Включите восстановление +admin.setting.recOpenDesc=После включения вы можете выбрать резервную копию базы данных для восстановления по мере необходимости. Будьте осторожны. +admin.setting.recTypeDesc=Зависит от типа используемой системы +admin.setting.recPath=Каталог резервных копий базы данных +admin.setting.recPathErr=Неверный каталог резервной копии базы данных +admin.setting.ifSaveRec=Восстановление базы данных импортирует данные резервной копии в новую базу данных и установит ее по умолчанию.
    Вы уверены, что хотите его выполнить? +admin.setting.recDiyPathErr=При использовании самостоятельного резервного копирования для восстановления выберите файл базы данных для резервного копирования. +admin.setting.recDiyFileNull=Файл базы данных пуст +admin.setting.recDiyPhpErr=Чтобы создать резервную копию SQLite самостоятельно, выберите файл базы данных в формате php. +admin.setting.recDiySqlErr=Чтобы создать резервную копию MySQL самостоятельно, выберите файл базы данных в формате sql. +admin.setting.recSysPathErr=При использовании управления резервным копированием для восстановления выберите каталог базы данных резервных копий. +admin.setting.recSysTbErr=Каталог резервной копии базы данных недействителен или отсутствует файл структуры базы данных +admin.setting.recDbFileErr=Выбранный файл библиотеки не соответствует системе, или отсутствует действительная таблица данных +admin.setting.dbFileDown=Прочитать файл библиотеки +admin.setting.dbFileDownErr=Не удалось прочитать файл библиотеки +admin.notice.waiting=В ожидании толчка +admin.notice.done=Выдвинутый +admin.notice.time=Время нажатия +admin.notice.target=Отправить объект +admin.notice.level=Быстрый уровень +admin.notice.level0=Слабый намек +admin.notice.level1=Сильная подсказка +admin.notice.levelDesc=Слабое напоминание: на панели уведомлений в левом нижнем углу отображается красная точка; сильное напоминание: уведомление появляется сразу после входа пользователя в систему. +admin.notice.targetAuth=Выберите отправку для всех или отправку для определенных пользователей, групп пользователей и групп разрешений +admin.notice.title=Заголовок сообщения +admin.notice.content=Содержание сообщения +admin.notice.timeType=Метод выталкивания +admin.notice.timeNow=Нажмите немедленно +admin.notice.timePlan=Запланированный push +admin.notice.listTitle=Уведомление о новостях станции +admin.notice.clearAll=Очистить все +admin.notice.noMsg=Нет новостей +admin.notice.ifClearAll=Вы уверены, что хотите удалить все сообщения? +admin.group.role=Роль личности +admin.group.name=Название отдела +admin.group.parent=Начальник отдела +admin.group.authShow=Объем организационной структуры, видимый членам отдела +admin.group.authShowAll=Все отделы +admin.group.authShowHide=Только этот отдел и подотдел +admin.group.authShowSelect=Назначенный отдел +admin.group.authShowAllTips=Когда члены этого отдела совместно работают над предоставлением общего доступа, они могут выбрать все другие отделы (и пользователей). +admin.group.authShowHideTips=Когда члены этого отдела сотрудничают и обмениваются данными, поддерживаются только текущий отдел и подотдел (и пользователи). +admin.group.authShowSelectTips=Когда члены отдела сотрудничают и обмениваются данными, они могут выбрать назначенный отдел и подотдел (и пользователя), включая текущий отдел и подотдел. +admin.group.addSub=Добавить подсектор +admin.group.remove=Удалить отдел +admin.group.switch=Департамент миграции +admin.group.swtichDesc=Перенесите пользователей и файлы из выбранного отдела (и его подотделов) в целевой отдел. +admin.group.switchSameError=Целевой отдел не может совпадать с выбранным отделом +admin.group.switching=Перенос, пожалуйста, подождите... +admin.group.groupSwitching=Выбранный отдел переносится +admin.group.parentNullError=Начальник не может быть пустым +admin.group.selected=Выбранный отдел +admin.group.setSizeBatch=Установить размер пространства партиями +admin.group.multiSelect=Для пакетной настройки можно выбрать несколько отделов +admin.group.ifDisAll=Все подразделения будут отключены. Вы уверены, что хотите выполнить это действие? +admin.member.manage=Пользователи и отделы +admin.member.add=Новый пользователь +admin.member.role=Роль власти +admin.member.group=Где отдел +admin.member.groupAdd=Добавить отдел +admin.member.groupEdit=Редакционный отдел +admin.member.remove=Удалить пользователя +admin.member.import=Добавить оптом +admin.member.enable=Включить +admin.member.batchSet=Массовые операции +admin.member.groupRemove=Удалить из отдела +admin.member.groupInsert=Добавить в отдел +admin.member.groupSwitch=Перейти в отдел +admin.member.groupTarget=Целевой отдел +admin.member.groupReset=Отдел сброса +admin.member.groupSwtichDesc=Перенести выбранных пользователей из текущего отдела в целевой отдел +admin.member.roleSet=Настройки роли разрешений +admin.member.sizeSet=Установка размера пространства +admin.member.name=Вход в систему +admin.member.nickName=Ник пользователя +admin.member.userInfo=Информация о пользователе +admin.member.userImport=Массовый импорт пользователей +admin.member.uploadFirst=Пожалуйста, загрузите файл первым +admin.member.downTpl=Скачать шаблон +admin.member.downTplDesc=Пожалуйста, заполните формат шаблона и загрузите. +admin.member.uploadInvalid=В загруженном файле нет действительных данных, пожалуйста, проверьте и загрузите снова +admin.member.uploadDataInvalid=Загрузка данных недействительна или истек, пожалуйста, загрузите снова +admin.member.importSuccess=Импорт завершен +admin.member.importFail=Не удалось импортировать +admin.member.importFailDesc=Успех: {0} Неудача: {1} +admin.member.importName=Учетная запись для входа (обязательно, уникальная) +admin.member.importNickName=Никнейм (уникальный) +admin.member.importPwd=Требуется пароль) +admin.member.importSex=Пол (Мужской-1, Женский-0) +admin.member.importPhone=Мобильный номер (уникальный) +admin.member.importEmail=Электронная почта (только) +admin.member.groupRemoveTips=Пользователи этой группы пользователей не могут войти в систему после удаления
    (Необходимо сбросить группу пользователей), вы уверены, что хотите продолжить? +admin.member.memberRemoveTips=После удаления каталог пользователя будет перемещен в корзину системы,
    Вы уверены что хотите продолжить? +admin.member.selectUserTips=Пожалуйста, выберите учетную запись для работы +admin.member.ifRemoveGroup=Вы уверены, что хотите удалить выбранных пользователей из этой группы? +admin.member.importDesc=Один пользователь в строке,
    Автоматически игнорировать, если он уже существует +admin.member.roleAdminTips=Примечание. Системный администратор не контролируется разрешениями. +admin.member.space=Установить размер пользовательского пространства +admin.member.spaceTips=0 не ограничено +admin.member.spaceTipsDefault=(ГБ) 0 не ограничено +admin.member.spaceTipsFull=Не ограничено +admin.member.spaceSize=Размер пространства +admin.member.spaceSizeUse=Использование пространства +admin.member.memberAdd=Добавить пользователя +admin.member.allAdd=Добавить пользователя или отдел +admin.member.nullNotUpdate=Оставьте пустым +admin.member.search=Поиск пользователей (аккаунт / никнейм / email / телефон) +admin.member.searchUser=Поиск пользователей (поддержка пиньинь и нечетких совпадений) +admin.member.searchGroup=Отдел поиска (поддержка пиньинь и нечетких совпадений) +admin.member.searchAll=Поиск пользователей или отделов (поддержка пиньинь и нечетких совпадений) +admin.member.editNoAuth=Извините, у вас нет этого разрешения,
    Только системные администраторы могут добавлять и изменять системных администраторов. +admin.member.disabledUsers=Аккаунт отключен +admin.member.disabledTips=Переключите отделы, чтобы снять отметку +admin.member.userGroup=Пользовательский отдел +admin.member.userRole=Роль пользователя +admin.member.userSelected=Выбранные пользователи +admin.member.authCopy=Копировать разрешения отдела +admin.member.authPaste=Вставка разрешения отдела +admin.member.ifAuthPaste=Вы уверены, что хотите установить скопированные разрешения отдела для текущего пользователя? +ERROR_USER_NOT_EXISTS=Пользователь не существует +ERROR_USER_PASSWORD_ERROR=Неверный пароль +ERROR_USER_EXIST_NAME=Имя пользователя уже существует +ERROR_USER_EXIST_PHONE=Номер телефона уже существует +ERROR_USER_EXIST_EMAIL=Почтовый ящик уже существует +ERROR_USER_EXIST_NICKNAME=Псевдоним уже существует +ERROR_USER_LOGIN_LOCK=Извините, слишком много попыток ввода пароля и текущая учетная запись заблокирована. Повторите попытку через 1 минуту! +ERROR_IP_NOT_ALLOW=Ваш текущий IP-адрес или устройство доступа не позволяют войти в систему, обратитесь к администратору! +user.passwordCheckError=Формат пароля не соответствует правилам надежности пароля! +admin.role.administrator=Системный администратор +admin.role.group=Заведующий отделом +admin.role.default=обычный пользователь +admin.role.ignoreExt=Ограничения расширения +admin.role.ignoreExtDesc=Типы файлов, которые нельзя загружать, нет ограничений на пустые +admin.role.ignoreFileSize=Ограничение на размер загружаемого файла +admin.role.ignoreFileSizeDesc=Максимальная загрузка одного файла, 0 не ограничено +admin.role.ignoreExtTips=Извините, текущие настройки системы не поддерживают этот тип загрузки файлов, пожалуйста, свяжитесь с администратором для получения подробной информации! +admin.role.ignoreFileSizeTips=Извините, если размер файла превышает ограничение размера, пожалуйста, свяжитесь с администратором для получения подробной информации! +admin.role.desc=Описание роли +admin.role.adminDesc=Суперадминистратор, имеет права на управление сервером, все настройки файлов и папок недействительны для этого пользователя! +admin.role.read=Читать +admin.role.readList=Список файлов +admin.role.readInfo=Просмотр атрибутов файлов (папок), поиск по папкам +admin.role.readCopy=Копия файла +admin.role.readPreview=Предварительный просмотр файлов (картинки, документы, аудио и видео и т. Д.) +admin.role.readDownload=Файл (папка) скачать +admin.role.write=Написать +admin.role.writeAdd=Создание файлов (папок), сжатие и распаковка файлов +admin.role.writeChange=Переименовать, настроить структуру каталогов +admin.role.writeUpload=Загрузка файла (папки), удаленная загрузка +admin.role.writeRemove=Файл (папка) удалить, вырезать +admin.role.adminSetDesc=Системный администратор имеет все разрешения, не нужно устанавливать! +admin.role.displayDesc=Отображать ли при настройке пользовательских ролей +admin.role.defaultRoleDesc=Совет: по умолчанию система имеет встроенные роли и не поддерживает изменение разрешений. Вы можете создавать новые роли +admin.role.actionSetTitle=Документация и конфигурация +admin.role.userSetTitle=Данные конфигурации пользователя +admin.role.adminSetTitle=Фоновые функции +admin.role.fileAdd=Новый файл (папка) +admin.role.fileRemove=Удаление документа +admin.role.fileMove=Переместить (операция копирования / вырезания / вставки / перетаскивания) +admin.role.userConfig=Изменение конфигурации (установка аватара / смена пароля и т. Д.) +admin.role.userEdit=Изменить пользователя (добавить / изменить / удалить) +admin.role.userFav=Операция «Избранное» +admin.role.itemEdit=Добавить / изменить / удалить +admin.role.groupEdit=Редактировать отдел (добавить / изменить / удалить) +admin.role.delErrTips=Персонаж уже используется и не может быть удален! +admin.authFrom.setUser=Укажите свои разрешения +admin.authFrom.setGroup=Укажите полномочия отдела +admin.authFrom.setAll=Другие разрешения пользователя +admin.authFrom.groupAt=Авторитет отдела +admin.authFrom.groupParent=Орган высшего звена +admin.authFrom.pathOnly=Только доступ, на нижнем уровне есть контент и разрешение +admin.authFrom.groupRoot=корневой каталог отдела +admin.auth.owner=владелец +admin.auth.editor=редактор +admin.auth.editUploader=Редактировать / загрузить +admin.auth.viewer=Зрителям +admin.auth.previewer=Просмотр по +admin.auth.uploader=загрузчик +admin.auth.invisible=невидимый +admin.auth.user=Пользовательские данные +admin.auth.pathDelete=Удаление файла +admin.auth.pathInfo=Атрибуты файла +admin.auth.pathMove=Переместить (операция копирования / вырезания / вставки / перетаскивания) +admin.auth.canUpload=Загрузить скачать +admin.auth.config=Данные конфигурации +admin.auth.fav=Операция «Избранное» (добавление / редактирование / удаление) +admin.auth.extWarning=Загрузка таких файлов не допускается,
    Переименовать (переименовано в указанное расширение),
    Редактирование сохранения, удаленная загрузка, распаковка +admin.auth.error=Ошибка роли разрешения (нет настроек разрешения) +admin.auth.errorAdmin=Недостаточный авторитет +admin.auth.targetError=Тип объекта разрешения неправильный, должен быть пользователем или отделом +admin.auth.errorAuthToGroup=Некорневой отдел, не поддерживает делегирование в отделы +admin.auth.errorAuthToUsers=Некорневой сектор, не поддерживает делегирование членам за пределами сектора +admin.auth.displayDesc=Отображать ли при настройке прав пользователей отдела +admin.auth.defaultAuthDesc=Совет. По умолчанию система имеет встроенную группу разрешений и не поддерживает изменение разрешений. Вы можете создавать новые группы разрешений +admin.auth.show=Список файлов +admin.auth.showAction=Просмотр списка файлов +admin.auth.view=Предварительный просмотр файла +admin.auth.viewAction=Предварительный просмотр файла +admin.auth.download=Скачать / скопировать +admin.auth.downloadAction=Загрузка / копирование / предварительный просмотр файла печать +admin.auth.uploadAction=Загрузка файла (папки) / удаленная загрузка +admin.auth.edit=Редактировать новый +admin.auth.editAction=Новый файл (папка) / Переименовать / Вставить в папку / Редактировать файл / Установить заметки / Создать копию / Разархивировать, Сжать +admin.auth.removeAction=Вырезать / копировать / перемещать +admin.auth.shareAction=Совместное использование внешних цепочек / совместная работа с другими +admin.auth.comment=Комментарии к документу +admin.auth.commentAction=Просмотр комментариев к документу; добавление / удаление собственных комментариев (требуется разрешение на редактирование) +admin.auth.event=Динамика документа +admin.auth.eventAction=Динамический просмотр документов, динамическая подписка +admin.auth.root=Административные права +admin.auth.rootAction=Установить права доступа для участников / управление комментариями / управление историей версий +admin.auth.delErrTips=Это разрешение используется и не может быть удалено! +admin.plugin.center=Плагин Центр +admin.plugin.installed=Был установлен +admin.plugin.type=классификация +admin.plugin.typeFile=Улучшение файла +admin.plugin.typeSafe=Инструменты безопасности +admin.plugin.typeTools=утилита +admin.plugin.typeMedia=мультимедиа +admin.plugin.typeCompany=Корпоративное приложение +admin.plugin.typeOem=Эксклюзивная настройка +admin.plugin.needNetwork=Экстранет +admin.plugin.install=Установите плагин +admin.plugin.enable=Включить плагин +admin.plugin.remove=Удалить плагин +admin.plugin.config=Настроить плагин +admin.plugin.statusEnabled=Включено +admin.plugin.statusDisabled=Не включен +admin.plugin.statusNotInstall=Не установлено +admin.plugin.installing=Установка ... +admin.plugin.hasUpdate=Обновления +admin.plugin.updateStart=Обновить плагин +admin.plugin.needConfig=Требуется начальная конфигурация для включения +admin.plugin.notNull=Обязательные поля не могут быть пустыми! +admin.plugin.auther=автор +admin.plugin.downloadNumber=Установлено +admin.plugin.back=возвращение +admin.plugin.detail=описание +admin.plugin.resetConfig=Восстановить настройки по умолчанию +admin.plugin.installSelf=Ручная установка +admin.plugin.updateSelf=Ручное обновление +admin.plugin.updateAll=Обновить все +admin.plugin.installSelfDesc= +admin.plugin.installNetworkError=Ошибка сети. Проверьте, может ли сервер выходить в Интернет. +admin.plugin.auth=Права на использование +admin.plugin.authDesc=Сделайте всех доступными или укажите пользователей, группы пользователей и группы разрешений для использования +admin.plugin.authOpen=Открытый доступ +admin.plugin.authOpenDesc=Можно получить доступ без входа в систему, можно использовать для вызовов внешнего интерфейса +admin.plugin.authAll=держатель +admin.plugin.authUser=Указанный пользователь +admin.plugin.authGroup=Назначенный отдел +admin.plugin.authRole=Укажите группу разрешений +admin.plugin.openWith=Открытый стиль +admin.plugin.openWithDilog=Внутренний диалог +admin.plugin.openWithWindow=Новая страница открывается +admin.plugin.fileSort=Приоритет расширения ассоциации +admin.plugin.fileSortDesc=Чем больше расширение, тем выше приоритет +admin.plugin.fileExt=Поддерживаемые форматы файлов +admin.plugin.fileExtDesc=Связать расширение с плагином +admin.plugin.tabServer=Конфигурация сервера +admin.plugin.defaultAceEditor=Ace редактор +admin.plugin.defaultHtmlView=Веб-просмотр +admin.plugin.defaultZipView=Онлайн декомпрессия +admin.plugin.authViewList=Список плагинов +admin.plugin.authStatus=Открыть закрыть +admin.plugin.authInstall=Установить / удалить +admin.plugin.disabled=Плагин не существует или не был запущен +admin.plugin.menuAdd=Следует ли добавлять в главное меню +admin.plugin.menuAddDesc=Использовать как отдельное приложение +admin.plugin.menuSubMenuDesc=Сжать в меню [Подробнее] +admin.storage.type=Тип хранения +admin.storage.local=местный +admin.storage.localStore=Локальное хранилище +admin.storage.oss=Alibaba Cloud OSS +admin.storage.cos=Tencent Cloud COS +admin.storage.qiniu=Семь коровьих облаков +admin.storage.s3=Amazon S3 +admin.storage.ftp=FTP +admin.storage.oos=Тяньи Облако ООС +admin.storage.moss=Хуншань МОСС +admin.storage.eos=XSKY EOS +admin.storage.nos=Бывший облачный NOS +admin.storage.minio=MinIO +admin.storage.uss=Возьмите еще один облачный USS +admin.storage.eds=Сангфор ЭДС +admin.storage.driver=Локальный диск +admin.storage.useage=Использование пространства +admin.storage.default=Установить по умолчанию +admin.storage.current=Текущее значение по умолчанию +admin.storage.edit=Хранилище настроек +admin.storage.setConfig=Изменить конфигурацию +admin.storage.moveData=Перенести данные +admin.storage.delStore=Размонтировать хранилище +admin.storage.ifMove=Это хранилище содержит {0} файлов сетевого диска и будет перенесено в текущее хранилище по умолчанию. Продолжить? +admin.storage.ifDel=Вы уверены, что хотите размонтировать текущий магазин? +admin.storage.ifDelWithFile=Это хранилище содержит {0} файлов сетевого диска, которые при удалении будут перенесены в текущее хранилище по умолчанию. Продолжить? +admin.storage.sysFile=Файлы сетевого диска: файлы в личном пространстве и отделах +admin.storage.delErrTips=Успешно:%s; Сбой:%s, повторите попытку или перенесите вручную +admin.storage.delLocTips=Сохраните хотя бы один местный магазин +admin.storage.delStoreTips=Это хранилище содержит резервные данные, пожалуйста, обработайте их, прежде чем продолжить! +admin.storage.nameDesc=Имя хранилища, чтобы различать разные хранилища +admin.storage.path=Каталог хранения +admin.storage.pathLocDesc=Каталог хранения файлов, убедитесь, что заполненный каталог имеет разрешения на чтение и запись +admin.storage.pathDesc=Каталог хранения файлов +admin.storage.defaultDesc=Элемент по умолчанию - единственное допустимое системное хранилище. Если вы решите включить его, другие методы хранения по умолчанию будут автоматически отменены. Будьте осторожны. +admin.storage.forceEdit=Обязательная модификация +admin.storage.editTips=После открытия вы можете редактировать поля запрещенных модификаций. Файл до хранения может быть недоступен, пожалуйста, соблюдайте осторожность. +admin.storage.folderTips=Текущее место хранения системных файлов, действуйте с осторожностью +admin.storage.sizeTips=Размер пространства должен быть больше 0 +admin.storage.sizeDesc=(ГБ), пожалуйста, заполните в соответствии с фактическим свободным пространством в выбранном каталоге хранения +admin.storage.region=Складская площадь +admin.storage.domain=Пространственное доменное имя +admin.storage.bucket=Название ковша +admin.storage.bucketDesc=Имя ковша, которое указывается при создании пространства +admin.storage.userName=Имя учетной записи +admin.storage.userPwd=Пароль учетной записи +admin.storage.server=Адрес сервера +admin.storage.serverDesc=ftp (s): // ip, по умолчанию ftp без протокола +admin.storage.refer=Ссылка: +admin.storage.endpoint=Региональный узел +admin.storage.ossDomain=Доменное имя связано в пространстве OSS +admin.storage.ossKeyDesc=Идентификатор ключа доступа к учетной записи Alibaba Cloud, пожалуйста, создайте или просмотрите в [Панель управления-Управление ключами доступа] +admin.storage.ossSecretDesc=Ключ доступа Секрет учетной записи Alibaba Cloud +admin.storage.ossEndpoint=Конечная точка, если вы используете узел интрасети, вам необходимо включить передачу сервера +admin.storage.cosKeyDesc=Идентификатор ключа доступа к учетной записи Tencent Cloud, пожалуйста, создайте или просмотрите в [Панель управления-Управление доступом-Управление ключами API] +admin.storage.cosSecretDesc=Ключ доступа Секрет учетной записи Tencent Cloud +admin.storage.qiniuDomain=Доменное имя связано с Qiniu Space +admin.storage.qiniuKeyDesc=Ключ доступа для учетной записи Qiniu, пожалуйста, создайте или просмотрите в [Панель управления-Персональный центр-Управление ключами] +admin.storage.qiniuSecretDesc=Секретный ключ для аккаунта Qiniu, способ получения такой же, как и выше +admin.storage.qnz0=Восточный Китай - Чжэцзян +admin.storage.qnz02=Восточный Китай - Чжэцзян 2 +admin.storage.qnz1=Северный Китай - Хэбэй +admin.storage.qnz2=Южный Китай - Гуандун +admin.storage.qnna0=Северная Америка - Лос-Анджелес +admin.storage.qnas0=Азиатско-Тихоокеанский регион – Сингапур +admin.storage.qnas02=Азиатско-Тихоокеанский регион – Сеул +admin.storage.awsDomain=Доменное имя связано в пространстве AWS +admin.storage.awsKeyDesc=Идентификатор ключа доступа к учетной записи AWS, пожалуйста, создайте его в [Панель управления - Ваши учетные данные безопасности] +admin.storage.awsSecretDesc=Секрет ключа доступа для учетной записи AWS +admin.storage.oosDomain=Tianyi Cloud Space связано доменное имя +admin.storage.oosKeyDesc=Идентификатор ключа доступа к учетной записи Tianyi Cloud, создайте его в [Панель управления - Ваши учетные данные безопасности] +admin.storage.oosSecretDesc=Секрет ключа доступа к облачной учетной записи Tianyi такой же, как и выше +admin.storage.ftpDisabled=FTP недоступен, пожалуйста, включите расширение php_ftp +admin.storage.ifDefaultTips=Эта операция отменит другие способы хранения по умолчанию. Вы уверены? +admin.storage.spaceUsed=Практическое использование +admin.storage.spaceLave=Оставшаяся сумма +admin.storage.delError=Файл уже существует в этом магазине и не может быть удален +admin.storage.corsError=Если конфигурация верна, нажмите [Использовать справку], чтобы проверить настройки междоменного сегмента. +admin.storage.saveError=Невозможно подключиться к указанному хранилищу, проверьте правильность информации о конфигурации. +admin.storage.ftpCharset=Кодировка FTP сервера +admin.storage.ftpCharsetDesc=Если FTP-сервер является Windows, он может быть установлен на GBK в зависимости от ситуации; +admin.storage.ftpPasvOn=Включить +admin.storage.ftpPasvOff=закрытие +admin.storage.ftpPasv=Пассивный режим +admin.storage.ftpPasvDesc=Режим передачи данных +admin.storage.uploadSrv=Перенос сервера (загрузка) +admin.storage.fileoutSrv=Перенос сервера (скачать) +admin.storage.uploadSrvDesc=После его включения файл будет загружен в хранилище объектов через сервер, в противном случае он будет загружен напрямую через клиента. +admin.storage.fileoutSrvDesc=После включения файл хранилища будет получен через сервер для загрузки; в противном случае файл будет получен для прямой загрузки. +admin.storage.closeDefError=Запретить отключение хранилища по умолчанию +admin.storage.ussBucket=наименование услуги +admin.storage.ussBucketDesc=Название сервиса облачного хранилища +admin.storage.ussUser=Имя оператора +admin.storage.ussUserDesc=Имя оператора +admin.storage.ussUserPwd=Пароль оператора +admin.storage.ussDomain=Сделайте еще один снимок доменного имени, привязанного к облачному пространству +admin.storage.ussToken=Жетон анти-пиявки +admin.storage.ussTokenDesc=Секретный ключ противоугонной цепочки токенов (не требуется) +admin.storage.configError=Неправильный параметр конфигурации! +admin.storage.sizePercent=Соотношение системных файлов: +admin.storage.fileCount=Количество файлов: +admin.storage.error=Исключение хранилища +admin.task.name=Название задачи +admin.task.edit=Редактирование задач +admin.task.type=Тип задачи +admin.task.method=Встроенные методы +admin.task.methodName=Название метода +admin.task.methodDesc=Он состоит из имени системного модуля-контроллера-метода, заполняйте внимательно. +admin.task.url=Запросить URL +admin.task.urlDesc=Пользовательский URL-адрес, запланированные задачи для регулярного выполнения запросов. +admin.task.cycle=Цикл исполнения +admin.task.desc=детали миссии +admin.task.nMinutes=N минут +admin.task.default=Система по умолчанию +admin.task.timeInterval=Интервал времени +admin.task.timeStart=Время начала +admin.task.timeStartRun=Время начала выполнения +admin.task.timeLastRun=Время последнего исполнения +admin.task.timeLastLogin=Время входа +admin.task.isOpen=Ли включить +admin.task.open=открытый +admin.task.content=Содержание реализации +admin.task.param=Параметр выполнения +admin.task.ifRun=Вы уверены, что хотите запустить эту задачу? +admin.task.backup=резервное копирование данных +admin.task.backupDesc=Начните резервное копирование системных данных в 02:00 каждый день. +admin.install.install=Установка системы +admin.install.databaseSet=Конфигурация базы данных +admin.install.dataUpdate=Миграция данных +admin.install.installSuccess=Установлен успешно +admin.install.dbWasSet=Вы настроили базу данных. Если вам необходимо выполнить сброс, вы можете изменить конфигурацию в файле config / setting_user.php и переустановить ее! +admin.install.errorRequest=Система установлена, дальнейшие запросы не разрешены +admin.install.databaseError=Ошибка подключения к базе данных, пожалуйста, проверьте конфигурацию +admin.install.cacheError=%s соединение не удалось, пожалуйста, проверьте конфигурацию +admin.install.cacheConnectError=%s не может подключиться к серверу, пожалуйста, проверьте конфигурацию +admin.install.dbSetError=Ошибка записи информации о конфигурации базы данных +admin.install.dbCreateTips=База данных не существует, и автоматическое создание не удалось. Пожалуйста, создайте ее вручную +admin.install.ifDelDb=Данные уже существуют в указанной базе данных. Нажмите [OK], чтобы удалить их. Вы хотите продолжить? +admin.install.dbCreateError=Исключение при создании таблицы данных +admin.install.dbFileError=Файл базы данных не существует +admin.install.dbTypeError=Выбранный тип базы данных (%s) недоступен, установите соответствующую службу и расширение или выберите другой тип. +admin.install.createSuccess=Создан успешно +admin.install.defSetError=Системную конфигурацию по умолчанию не удалось добавить +admin.install.defStoreError=Ошибка добавления хранилища по умолчанию +admin.install.defPathError=Ошибка добавления системного каталога +admin.install.defAdminError=Не удалось добавить учетную запись администратора +admin.install.defRoleError=Не удалось добавить роль по умолчанию +admin.install.defGroupError=Не удалось добавить системный отдел +admin.install.dataPathNotExists=каталог данных не существует +admin.install.defaultUpdate=Обновление информации о конфигурации системы +admin.install.pluginUpdated=Обновление плагина завершено +admin.install.defCacheError=Исходное исключение данных кэша каталога +admin.install.serverDir=Каталог столбцов сервера +admin.install.dirRight=Разрешения каталога +admin.install.suggestOpen=Рекомендуется открыть +admin.install.suggestClose=Рекомендуется закрыть +admin.install.phpVersionTips=PHP5.3 и выше +admin.install.phpBitTips=Рекомендуется 64-бит +admin.install.phpBitDesc=32-разрядная версия не поддерживает загрузку и загрузку файлов более 2G +admin.install.pathNeedWirte=Каталог программы и все подкаталоги должны быть доступны для чтения и записи. +admin.install.mustOpen=Должен открыться +admin.install.setPathWrt=Установите разрешения на чтение и запись для каталога проекта +admin.install.ensureNoError=Убедитесь в правильности следующего: +admin.install.setAdminName=Пожалуйста, настройте учетную запись администратора +admin.install.setAdminPwd=Пожалуйста, установите пароль администратора +admin.install.database=база данных +admin.install.dbType=Тип базы данных +admin.install.dbName=Имя базы данных +admin.install.userName=имя пользователя +admin.install.dbPort=Номер порта +admin.install.dbPortDesc=Порт по умолчанию — 3306, если вам нужно его настроить, вы можете добавить его, например: 127.0.0.1:3307. +admin.install.dbEngine=Механизм хранения +admin.install.sqliteDesc=В PHP есть встроенная зеленая облегченная база данных (подходит для тестирования или небольшого использования). +admin.install.mysqlDesc=Поддерживает развертывание кластера, разделение баз данных master и slave. +admin.install.pdoDesc=Более безопасный драйвер базы данных требует, чтобы PHP установил расширение PDO. +admin.install.cacheType=Тип системного кэша +admin.install.cacheTypeDesc=Используется для кэширования общих данных и сеансов для ускорения доступа к системе. +admin.install.fileCache=Файловый кеш +admin.install.groupFile=Документ отдела +admin.install.userFile=Пользовательская документация +admin.install.role=роль +admin.install.fileAuth=Разрешения на документы +admin.install.userList=Список пользователей +admin.install.setInfo=Информация о конфигурации системы +admin.install.favShare=Избранное пользователя и акции +admin.install.waitUpdate=В ожидании обновления +admin.install.updateSuccess=Обновление успешно +admin.install.fileCount=Количество файлов +admin.install.settingDesc=Элементы отказа могут быть настроены вручную в фоновом управлении +admin.install.reInstallTips=Возвращаемый результат ненормальный, пожалуйста, переустановите +admin.log.accountEdit=Изменить информацию аккаунта +admin.log.thirdBind=Привязать сторонний аккаунт +admin.log.delBind=Unbind +admin.log.viewFile=файл предварительного просмотра +admin.log.delFile=Удалить файл +admin.log.editFile=Редактировать файл +admin.log.downFile=Скачать файл +admin.log.downFolder=Папка для скачивания +admin.log.moveFile=Переместить файл +admin.log.addUser=Добавить пользователя +admin.log.editUser=Изменить пользователя +admin.log.addUserTo=Добавить пользователей в отдел +admin.log.removeUserFrom=Пользователь удален из отдела +admin.log.switchUserGroup=Перенос пользователей в отделы +admin.log.stausUser=Включить / отключить пользователей +admin.log.addRole=Новая роль +admin.log.editRole=Изменить роль +admin.log.delRole=Удалить роль +admin.log.addAuth=Добавить разрешения +admin.log.editAuth=Изменить разрешения +admin.log.delAuth=Удалить разрешение +admin.log.editShare=Изменить общий доступ +admin.log.delLinkTo=Отменить совместное использование внешней ссылки +admin.log.delShareTo=Отменить совместный доступ +admin.log.recycleTo=Переместить в корзину +admin.log.newName=Новое имя +admin.log.oldName=Оригинальное имя +admin.log.newPath=Новый каталог +admin.log.oldPath=Оригинальный каталог +admin.log.typeFile=Файловые операции +admin.log.typeUser=Конфигурация пользователя +admin.log.queryByIp=Нажмите кнопку, чтобы запросить записи журнала дня на основе IP. +admin.backup.setting=Настройки резервного копирования +admin.backup.edit=Редактирование резервной копии +admin.backup.ing=Резервное копирование +admin.backup.success=Резервное копирование выполнено +admin.backup.fail=Ошибка резервного копирования +admin.backup.complete=Резервное копирование завершено +admin.backup.db=база данных +admin.backup.dbFile=файл базы данных +admin.backup.fileError=Сбой резервного копирования некоторых файлов +admin.backup.checkLog=Пожалуйста, проверьте журнал резервного копирования: data/temp/log/backup/date of the day__log.php +admin.backup.pathNoWrite=Временный каталог не имеет разрешения на запись +admin.backup.errorMsg=Часть резервной копии файла не удалась, вы можете вручную скопировать в соответствии с журналом или удалить и снова создать резервную копию. +admin.backup.logFile=Лог-файл +admin.backup.manual=Ручное резервное копирование +admin.backup.continue=Продолжить резервное копирование +admin.backup.start=Начать резервное копирование +admin.backup.open=Включить резервное копирование +admin.backup.notOpen=Резервное копирование не включено +admin.backup.location=Местоположение резервной копии +admin.backup.content=Резервное копирование содержимого +admin.backup.dbOnly=база данных +admin.backup.time=Время резервного копирования +admin.backup.notStart=еще не начался +admin.backup.notEnabled=Не включено +admin.backup.killed=над +admin.backup.ifKill=Вы уверены, что хотите завершить эту резервную копию? +admin.backup.kill=Конец +admin.backup.error=Прервать +admin.backup.timeBeen=Кропотливый +admin.backup.timeTotal=Общее время +admin.backup.backed=Резервное копирование +admin.backup.storage=Пожалуйста, создайте выделенное хранилище для резервного копирования. +admin.backup.ifSave=Резервное копирование занимает много времени. Вы уверены, что хотите сделать резервную копию? +admin.backup.ifContinue=Вы уверены, что хотите продолжить резервное копирование? +admin.backup.saveTips=Задание резервного копирования отправлено, наберитесь терпения +admin.backup.fileSize=Размер документа +admin.backup.dbSize=Размер базы данных +admin.backup.dbCnt=общее количество +admin.backup.notFinished=Не завершен +admin.backup.timeTaken=кропотливый +admin.backup.node=узел +admin.backup.notYet=нет +admin.backup.storeNotExist=Хранилище резервных копий не существует, пожалуйста, сбросьте +admin.backup.timeNote=Примечание. Система хранит резервные копии базы данных только за последние 7 дней и 1 числа каждого месяца. Время резервного копирования: +admin.backup.recover=Пожалуйста, свяжитесь с поставщиком услуг для восстановления данных. +admin.backup.optionTime=Резервное копирование занимает много времени, попробуйте выбрать его в нерабочее время +admin.backup.optionLocation=Если вам нужно создать резервную копию файлов, создайте новое хранилище, предназначенное для резервного копирования. +admin.backup.optionTips1=Резервное копирование делится на две части: резервное копирование базы данных и резервное копирование файлов. +admin.backup.optionTips2=Резервное копирование базы данных: создание файлов SQL из содержимого базы данных и их резервное копирование в каталог целевой базы данных хранилища. +admin.backup.optionTips3=Резервное копирование файлов: резервное копирование файлов системного хранилища в целевое хранилище постепенно в соответствии с исходным путем хранения. +admin.backup.optionTips4=Система хранит только резервные копии базы данных за последние 7 дней и 1-е число каждого месяца. +admin.backup.needStorage=Хранилище резервных копий не может быть пустым +admin.backup.needNoDefault=Не выбирайте хранилище по умолчанию в качестве хранилища резервных копий файлов. +admin.backup.contentDesc=Лицензионная версия поддерживает одновременное резервное копирование баз данных и файлов. +admin.backup.action=Руководство операцией +admin.backup.recovery=снижение +admin.backup.sysRecovery=восстановление системы +admin.backup.bakErr2Rec=Эта резервная копия является неполной и не может быть восстановлена. +admin.recycle.menu=Системная корзина +admin.share.name=Поделиться именем +admin.share.type=Тип обмена +admin.share.expiryTime=Срок действия +admin.share.expired=истекший +admin.share.link=Внешняя ссылка +admin.share.linkView=Нажмите, чтобы просмотреть поделиться +admin.share.ifDel=Вы уверены, что хотите отменить этот доступ? +admin.share.disFile=На этот файл пожаловались пользователи, и ему запрещено делиться +admin.share.disFolder=Этот каталог содержит запрещенные файлы, к которым запрещено делиться. +admin.share.shareTab=Совместное управление +admin.share.reportTab=Совместное управление отчетами +admin.share.rptType1=Пиратство +admin.share.rptType2=Непристойное порно +admin.share.rptType3=Кровавое насилие +admin.share.rptType4=Политика вредна +admin.share.rptType5=другие причины +admin.share.doRptClose=Закройте отчет после обработки общего содержимого или закройте его напрямую +admin.share.doRptDisable=После запрета / разрешения совместного использования все ресурсы, соответствующие файлу, будут затронуты. Вы уверены, что хотите выполнить эту операцию? +admin.share.rptUser=осведомитель +admin.share.rptTitle=Обмен отчетами +admin.share.rptDesc=Причина сообщения +admin.share.rptTime=Сообщить время +admin.share.rptResult=результат процесса +admin.share.rptDone=Обработанный +admin.share.rptNoDone=Необработанный +admin.share.rptClose=Закрыть отчет +admin.share.rptShareDel=Не делиться +admin.share.rptShareAllow=Разрешить обмен +admin.share.rptShareDisable=Нет обмена +admin.share.rptDoDisable=Запретить / разрешить совместное использование +admin.share.rptSelectTips=Пожалуйста, выберите элемент для работы! +admin.setting.transfer=Загрузить / скачать +admin.setting.transferChunkSize=Загрузить размер шарда +admin.setting.transferChunkSizeDesc=При загрузке большого файла он разрезается на части для одновременной загрузки, чтобы добиться ускорения и возобновления возобновления.
    5M рекомендуется, это значение должно быть меньше, чем в следующей конфигурации, в противном случае это приведет к исключению загрузки (ошибка загрузки, откат) +admin.setting.transferChunkSizeDescError1=Размер загружаемого шарда не может превышать значение в php.ini +admin.setting.transferChunkSizeDescError2=Измените его в php.ini и попробуйте снова (измените upload_max_filesize, post_max_size, нужно перезагрузить) +admin.setting.transferThreads=Загрузка параллельных тем +admin.setting.transferThreadsDesc=Рекомендуется = 10, одновременная загрузка файлов или шардов +admin.setting.transferIgnore=Загрузить файл игнорирования +admin.setting.transferIgnoreDesc=Загружать имена файлов, которые автоматически игнорируются. Временные файлы могут быть исключены, несколько разделенных запятыми, например: .DS_store, thumb.db +admin.setting.transferChunkRetry=Автоматическая повторная передача при сбое загрузки +admin.setting.transferChunkRetryDesc=Рекомендация = 5; количество повторных передач будет выполнено автоматически, если загрузка не удалась, 0 означает отсутствие автоматической повторной передачи +admin.setting.transferOsChunkSize=Размер осколка хранилища объектов +admin.setting.transferOsChunkSizeDesc=Загрузка объектного хранилища, размер фрагмента варьируется от 5 МБ до 5 ГБ, а максимальное количество запросов - 1000, что означает, что максимальный размер загружаемого файла составляет 5 ТБ.
    Рекомендуется 10 ~ 20 МБ.В настоящее время максимальный поддерживаемый размер файла составляет 9,7 ~ 19,5 ГБ, и пользователи могут настроить размер загружаемого файла в соответствии со своими потребностями. +admin.setting.transferHttpSendFile=Скачать ускорение веб-сервера +admin.setting.transferHttpSendFileDesc=Загрузка файла напрямую передается через веб-сервер, скорость загрузки улучшается, она эффективна только тогда, когда хранилище по умолчанию настроено как локальное хранилище. +admin.setting.downloadZipClient=Фронтальная сжатая загрузка +admin.setting.downloadZipClientDesc=Должна быть возможность подключения к внешней сети, иначе сайт https +admin.setting.downloadZipLimit=Ограничение размера сжатой загрузки +admin.setting.downloadZipLimitDesc=0 означает отсутствие ограничений; во избежание чрезмерного потребления производительности сервера загрузка пакета ограничивается, когда папка слишком велика, и предлагается загрузить файл напрямую через клиент для ПК. +admin.setting.downloadZipLimitTips=Сжатое содержимое превышает системный лимит, обратитесь к администратору!Вы можете загрузить папку напрямую через клиент для ПК без сжатия. +admin.setting.dragDownload=Перетащите на рабочий стол, чтобы скачать +admin.setting.dragDownloadDesc=Поддерживается только браузером ядра Chrome на стороне ПК (chrome edge 360 fast и т. д.) +admin.setting.dragDownloadZip=Множественный выбор перетаскивания, сжатие, загрузка +admin.setting.dragDownloadZipDesc=Поддержка загрузки с множественным выбором или перетаскиванием папок, перед загрузкой необходимо упаковать и сжать на сервере +admin.setting.dragDownloadLimit=Ограничение размера содержимого с помощью перетаскивания +admin.setting.dragDownloadLimitDesc=0 означает отсутствие ограничений; размер перетаскиваемого содержимого будет зависеть от этого ограничения. Поскольку в настоящее время в Chrome нет индикатора выполнения перетаскивания и загрузки, его нельзя отменить. Рекомендуется ограничить размер до 20 МБ. +admin.setting.dragDownloadUrlTips=URL слишком длинный, сократите выделение и повторите попытку! +admin.setting.dragDownloadOpenTips=Пожалуйста, свяжитесь с администратором, чтобы включить его в фоновых настройках! +admin.setting.dragDownloadNotOpen=Перетаскивание и сжатие загрузки не включены +admin.setting.dragDownloadSizeTips=Размер перетаскиваемого содержимого превышает лимит +admin.setting.showFileSafe=Безопасность доступа к файлам +admin.setting.showFileLink=Отображение внешней ссылки на файл +admin.setting.showFileLinkDesc=После закрытия в свойствах файла больше не отображаются внешние ссылки +admin.setting.showFileMd5=отображение файла md5 +admin.setting.showFileMd5Desc=После закрытия свойства файла больше не показывают файл md5 +admin.setting.shareLinkAllow=Включить обмен внешними ссылками +admin.setting.shareLinkAllowDesc=После закрытия он больше не будет поддерживать общий доступ к внешней цепочке, и общий контент не будет затронут. +admin.setting.shareLinkAllowTips=Текущая система отключила обмен внешними ссылками, обратитесь к администратору! +admin.setting.shareLinkPasswordAllowEmpty=Общий доступ к внешней цепочке позволяет оставить пароль пустым +admin.setting.shareLinkPasswordAllowEmptyDesc=После закрытия необходимо установить пароль для обмена внешними ссылками; общий контент не будет затронут +admin.setting.shareLinkAllowGuest=Обмен внешними ссылками позволяет незарегистрированным посетителям получить доступ +admin.setting.shareLinkAllowGuestDesc=После закрытия вы должны войти в систему при доступе к внешним ссылкам; общий контент не будет затронут +admin.setting.shareLinkZip=Загрузка пакета для обмена внешними ссылками +admin.setting.shareLinkZipDesc=После открытия папка общего доступа к внешней цепочке поддерживает упаковку и загрузку с сжатием.Если параллелизм велик, производительность сервера снижается. +admin.setting.shareLinkZipTips=Совместное использование внешних ссылок отключает пакетную загрузку, обратитесь к администратору для настройки! +admin.setting.transferDownSpeed=Ограничение скорости загрузки +admin.setting.transferDownSpeedDesc=Ограничьте скорость загрузки и равномерно ограничьте скорость больших одновременных веб-сайтов. +admin.setting.transferDownSpeedNum=Ограничение скорости загрузки +admin.setting.transferDownSpeedNumDesc=Ограничьте скорость загрузки, и вы сможете равномерно ограничить скорость веб-сайта с большим параллелизмом.
    Примечание: здесь скорость сервера ограничена. На конкретную скорость загрузки также влияют пропускная способность сервера и пользовательская сеть. +explorer.uploadSizeError=Ваш сервер в настоящее время не поддерживает файлы более 2G,
    Пожалуйста, обновитесь до 64-битного php; рекомендуется 64-битный php7
    (Примечание: 64-битная операционная система может устанавливать только 64-битный PHP); +common.width=ширина +common.height=высокая +common.test=тест +common.absolutePath=Абсолютный адрес +common.qrcode=URL QR код +common.wechat=Micro письмо +common.group=отдел +common.user=пользователь +common.online=Интернет +common.use=Использовать +common.total=Общее +common.year=год +common.month=месяц +common.week=Чжоу +common.daytime=день +common.mon=в понедельник +common.tue=во вторник +common.wed=в среду +common.thu=Четверг +common.fri=пятница +common.sat=в субботу +common.sun=Воскресенье +common.second=второй +common.minute=минут +common.hour=час +common.day=день +common.every=каждый +common.everyMonth=в месяц +common.everyWeek=еженедельно +common.everyDay=ежедневно +common.language=Язык +common.all=полный +common.item=пункт +common.items=Содержание элемента +common.itemsEmpyt=Без содержания +common.detail=подробности +common.me=Я +common.others=другое +common.guest=посетители +common.more=более +common.learnMore=Узнать больше +common.yes=Здесь +common.no=нет +common.omit=Опустить +common.unknow=неизвестный +common.title=заглавие +common.time=время +common.scan=Просматривать +common.report=Отчет +common.name=имя +common.nickName=кличка +common.tools=инструмент +common.tag=тег +common.position=расположение +common.mount=Сетевое крепление +common.type=тип +common.auth=компетентность +common.status=состояние +common.run=пробег +common.file=файл +common.folder=скоросшиватель +common.fileType=Тип файла +common.fileSize=Размер файла +common.attributeInfo=Информация об атрибутах +common.actionType=Тип операции +common.isDisplay=Стоит ли показывать +common.hide=Скрыть +common.isHide=Скрытый +common.cancelHide=Показать +common.default=по умолчанию +common.display=дисплей +common.moveDown=Двигаться вниз +common.moveUp=Двигаться вверх +common.drag=Тащить, тянуть +common.dragSort=Перетащите, чтобы изменить порядок +common.warning=предупреждение +common.tips=подсказка +common.desc=инструкция +common.tipsDesc=Быстрое описание +common.tipsOthers=Другие инструкции +common.view=Посмотреть +common.log=Журнал +common.task=задача +common.important=важно +common.icon=иконка +common.menu=меню +common.system=система +common.basic=Универсальный +common.systemSet=Конфигурация системы +common.systemDefault=Система по умолчанию +common.diy=изготовленный на заказ +common.input=Пожалуйста, введите +common.select=Пожалуйста, выберите +common.add=новый +common.edit=редактировать +common.action=операционная +common.upload=Загрузить +common.uploadTo=загрузить на +common.download=скачать +common.export=экспорт +common.cover=покрытие +common.retry=Retry +common.zip=компрессия +common.unzip=декомпрессия +common.preview=предварительный просмотр +common.share=доля +common.search=Поиск +common.query=Узнать +common.delete=Удалить +common.deleteForce=Удалить полностью +common.deleteEnd=удалено +common.refresh=обновление +common.open=открытый +common.close=близко +common.from=источник +common.greater=Больше чем +common.less=Меньше чем +common.print=печать +common.selectInvert=Обратные выборы +common.selectAll=Выбрать все / Обратный выбор +common.selectAllItem=Выбрать все +common.selectNum=выбранный +common.selectNull=Нет вообще +common.sizeMore=над +common.showMore=Открываются +common.showLess=коллапс +common.sizeSmall=маленький +common.sizeMiddle=в +common.sizeBig=Большой +common.rename=Переименование +common.method=функция +common.extend=распространение +common.fav=Collect +common.reset=Сброс +common.testing=детектировать +common.install=устанавливать +common.update=обновление +common.version=издание +common.sysVersion=Версия платформы +common.login=Войти в систему +common.regist=Зарегистрироваться +common.password=пароль +common.operateTime=Время работы +common.createTime=Время создания +common.modifyTime=Время модификации +common.activeTime=Время архива +common.startTime=Время начала +common.endTime=Время окончания +common.finishTime=Время окончания +common.disable=Отключить +common.goOn=продолжать +common.ok=определить +common.startRun=Начинать +common.confirmTips=Пожалуйста, подтвердите еще раз +common.confirmAsk=Вы уверены, что хотите выполнить эту операцию? +common.submit=представить +common.skip=Пропустить +common.nextStep=Следующий шаг +common.start=начать +common.stop=Пауза +common.set=Настроить +common.cancel=отменен +common.save=Сохранить +common.empty=Нет контента! +common.isOpen=Включенный +common.isClose=закрыто +common.apply=приложение +common.saveAll=Сохранить все +common.notSave=Не сохраняй +common.appAdd=добавлять +common.backAdd=Вернуться, чтобы добавить +common.saveEdit=Сохранить изменения +common.saveSubmit=Сохранить коммит +common.saveAndAdd=Сохранить и продолжить добавление +common.sex=пол +common.male=мужчина +common.female=женщина +common.address=адрес +common.email=E-mail +common.phone=Мобильный телефон +common.sms=SMS +common.phoneNumber=Номер телефона +common.server=сервер +common.handheld=Мобильное устройство +common.success=успех +common.fail=недостаточность +common.error=ошибка +common.result=результат +common.expired=истек +common.valid=эффективный +common.inAll=Всего +common.allAndNull=Выбрать все / Отмена +common.moveTop=верхний +common.moveBottom=Установить в конце +common.moveTopCancle=Unpink +common.ECN=Восточный Китай +common.NCN=Северный Китай +common.SCN=Южный Китай +common.USA=Северная Америка +common.SEA=Юго-Восточная Азия +common.noLimit=не ограничен +common.notExists=Не существует +common.cannotWrite=Только чтение, а не запись +common.readOnly=Только чтение +common.cannotRead=нечитаемый +common.ifDel=Вы уверены, что хотите удалить? +common.pageNotExists=Страница не существует! +common.pathNotExists=Документ не существует! +common.fileShare=Совместное использование документов +common.logining=Вход в систему ... +common.loginTokenError=Логин истек, пожалуйста, войдите снова! +common.loginSuccess=Войти успешно! +common.loginError=Ошибка входа +common.connectSuccess=Успешно подключен! +common.bindSuccess=Свяжись успешно! +common.bindError=Связать не удалось +common.clear=Пустой +common.congrats=Поздравляю, +common.sorry=К сожалению, +common.invalid=недействительный +common.unavailable=недоступен +common.format=формат +common.noPermission=Доступ запрещен +common.allPermission=Все разрешения +common.invalidParam=Неверный параметр +common.invalidFormat=Неверный формат +common.invalidRequest=Неверный тип запроса +common.illegalRequest=Незаконный запрос +common.expiredRequest=Запрос истек +common.errorExpiredRequest=Неверный запрос или срок его действия истек +common.migrating=Перенастройка +common.migrated=Миграция завершена +common.maintenanceTips=Во время обслуживания системы, пожалуйста, посетите позже ... +common.done=завершено +common.disabled=отключен +common.sizeTotal=Общий размер +common.sqlStatement=[Оператор SQL]: +common.env.check=Экологические испытания +common.env.errorLib=Отсутствует библиотека PHP +common.env.errorIgnore=Игнорировать и войти +common.env.errorVersion=Версия PHP не может быть ниже 5.0 +common.env.errorPath=Не для записи +common.env.errorListDir=На вашем веб-сервере включена функция списка каталогов. Пожалуйста, отключите ее из соображений безопасности! Как это работает? +common.env.errorGd=Библиотека PHP GD должна быть включена, иначе использование проверочных кодов и миниатюр будет ненормальным. +common.env.invalidExt=Расширение %s недоступно, проверьте, установлено ли оно +common.env.installWithBtTips=Версия php сервера требует 5.3 и выше. Я не знаком с настройкой одним щелчком рекомендуемой панели пагоды .
    Текущая версия +common.env.phpCacheOpenTips=На вашем сервере включено php-кэширование, а обновления файлов еще не вступили в силу;
    Пожалуйста, выключите кеш или обновите страницу и попробуйте снова через 1 минуту!
    Узнать больше +common.env.dataPathNotExists=Каталог данных не существует!
    (Проверьте DATA_PATH); +common.env.pathPermissionError=[Код ошибки: 1002] Ошибка разрешения каталога! Пожалуйста, установите каталог программы и все подкаталоги для чтения и записи.
    Linux запускает следующую команду:
     su -c 'setenforce 0' 
    chmod -R 777 +common.version.free=Бесплатно +common.version.nameQ=Enterprise Edition +common.version.vipFree=Бесплатное издание +common.version.useFree=Продолжайте использовать бесплатную версию +common.version.notSupport=Ваша версия не поддерживает эту операцию, перейдите на официальный сайт, чтобы приобрести расширенную версию! +common.version.notSupportNumber=Эта операция не поддерживается из-за ограниченного количества, перейдите на официальный сайт, чтобы купить расширенную версию! +common.version.toVip=Обновление до коммерческого +common.version.license=Авторизация покупки +common.version.authCode=Код активации авторизации +common.version.authActive=Активация авторизации +common.version.authorization=Авторизация регистрации +common.version.authorizeSuccess=Поздравляем, авторизация для онлайн-обновления прошла успешно! +common.version.networkError=Сбой запроса к серверу. Проверьте, может ли сервер получить доступ к сети.
    Примечание. Сервер не может быть прокси для доступа в Интернет. +common.version.authActiveOnline=Активировать онлайн +common.version.authActiveOffline=Активировать в автономном режиме +common.version.offlineTips=Сервер не может получить доступ к Интернету? +common.version.menuTitle=Настройки корпоративной информации +common.version.timeout=истекший +common.version.timeToService=Срок действия услуги +common.version.timeTo=Срок действия авторизации +common.version.licenseAll=Бессрочная авторизация +common.version.kodVersion=Версия программы +common.version.userLimitTitle=Номер пользователя +common.version.userUse=Используемый +common.version.userAllow=Количество поддерживаемых пользователей +common.version.userTo=Авторизованный объект +common.version.userTitle=Информация для авторизации +common.version.basicInfo=основная информация +common.version.appInfo=информация о продукте +common.version.tipsWarning=Внимание, пожалуйста, не изменяйте авторские права без разрешения, при необходимости, пожалуйста, свяжитесь с покупкой! +common.version.tipsCopyLink=Скопируйте успешно! Вставьте и сохраните в текстовый файл,
    Откройте эту ссылку на компьютере с сетью через USB-накопитель и т. Д. +common.version.tipsHistory=Бесплатная версия поддерживает только 5 версий истории, покупайте неограниченное количество лицензионных версий! +common.version.codeLink=Ссылка для запроса кода авторизации +common.version.codeLinkHelp=1. Скопируйте вышеуказанную ссылку и посетите другие компьютеры с доступом в Интернет.
    2. Заполните «Код авторизации авторизации», полученный выше, а затем активируйте и авторизуйте +common.copyright.logoTitle=Набор логотипов фирменного стиля +common.copyright.licenseInfo=Информация об авторизации +common.copyright.licenseReset=перераспределении полномочий +common.copyright.licenseResetTips=Активируйте для получения дополнительной информации! +common.copyright.formLogo=Тип логотипа страницы входа +common.copyright.formLogoTypeWord=Текстовый логотип +common.copyright.formLogoTypeImage=Изображение логотипа +common.copyright.formLogoDesc=Текстовый логотип использует название компании, а логотип изображения использует изображение, установленное следующим образом. +common.copyright.formLogoImage=Изображение логотипа страницы входа +common.copyright.formLogoImageDesc=Страница входа и фоновый логотип управления, рекомендуемый размер 250x100, полупрозрачный формат png +common.copyright.formLogoMain=Логотип главного интерфейса меню +common.copyright.formLogoMainDesc=Логотип управления файлами в левом верхнем углу, рекомендуемый размер 200x200, белый прозрачный формат png +common.copyright.formPowerByInfo=Настройки информации об авторских правах компании +common.copyright.formPowerBy=Название авторского права снизу +common.copyright.formHomePage=Нижняя ссылка на ссылку об авторских правах +common.copyright.formConcat=Всплывающий контакт +common.copyright.formDesc=Подробное описание всплывающего слоя продукта +common.copyright.formDescTips=После сохранения изменения страница обновления вступит в силу +common.copyright.formMetaKeywords=Ключевые слова сайта (используются поисковыми системами) +common.copyright.formMetaName=Название сайта (используется поисковыми системами) +common.copyright.downloadApp=Загрузка приложения +common.copyright.downloadLink= +common.copyright.about=на +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle= +common.copyright.nameDesc= +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=Автоматическая идентификация +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=арабский +common.charset.ISO_8859_6=арабский +common.charset.ISO_8859_10=Скандинавский язык +common.charset.CP1257=Языки вокруг Балтики +common.charset.ISO_8859_13=Языки вокруг Балтики +common.charset.ISO_8859_4=Языки вокруг Балтики +common.charset.BIG5_HKSCS=Традиционный-Гонконг +common.charset.BIG5=Традиционный - Тайвань +common.charset.Georgian_Academy=грузинский +common.charset.PT154=казах +common.charset.CP949=корейский +common.charset.EUC_KR=корейский +common.charset.GB18030=Упрощенный китайский +common.charset.GBK=Упрощенный китайский +common.charset.ISO_8859_14=кельтский +common.charset.CP1133=Лао +common.charset.ISO_8859_16=румынский +common.charset.ISO_8859_3=Южноевропейские языки +common.charset.EUC_JP=японский +common.charset.ISO_2022_JP=японский +common.charset.SHIFT_JIS=японский +common.charset.KOI8_T=Таджикский язык +common.charset.ISO_8859_11=тайский +common.charset.TIS_620=тайский +common.charset.CP1254=турецкий +common.charset.CP1251=кириллица +common.charset.ISO_8859_5=кириллица +common.charset.KOI8_R=кириллица +common.charset.KOI8_U=кириллица +common.charset.CP1252=Западноевропейские языки +common.charset.ISO_8859_1=Западноевропейские языки +common.charset.ISO_8859_15=Западноевропейские языки +common.charset.Macintosh=Западноевропейские языки +common.charset.CP1255=иврит +common.charset.ISO_8859_8=иврит +common.charset.CP1253=греческий +common.charset.ISO_8859_7=греческий +common.charset.ARMSCII_8=армянин +common.charset.CP1258=вьетнамский +common.charset.VISCII=вьетнамский +common.charset.CP1250=Центральноевропейские языки +common.charset.ISO_8859_2=Центральноевропейские языки +common.charset.defaultSet=Кодировка файла +common.charset.convertSave=Преобразовано в +common.date.near=Только сейчас +common.date.miniteBefore=Минут назад +common.date.today=сегодня +common.date.yestoday=вчера +common.date.before=до +common.faceDefault=Смайлик по умолчанию +common.loadMore=Загрузи больше +common.numberLimit=Количество превышает максимальный лимит! +common.lengthLimit=Длина превышает максимальный предел! +common.task.name=Диспетчер задач +common.task.title=название миссии +common.task.user=Исполнительный пользователь +common.task.porcess=график +common.task.start=Начать задание +common.task.useTime=Пройденное время +common.task.running=проведение +common.task.stoping=Приостановлено +common.task.killing=окончание +common.task.stop=Приостановленное задание +common.task.kill=Конечная задача +common.task.removeTips=Вы уверены, что закончите эту операцию? +common.task.killAll=Закончить все +common.task.killAllTips=Вы уверены, что завершите все задачи? +common.task.timeStart=Начать с +common.task.timeNeed=Оставаясь о +common.task.timeUse=Уже работает +ERROR_DB_PWD=Отказано в доступе к базе данных: неправильное имя пользователя или пароль. +ERROR_DB_TIMEOUT=Время ожидания подключения к базе данных истекло, проверьте правильность адреса. +ERROR_DB_CONN_RFS=Отказ в подключении к базе данных: неверная информация о конфигурации или служба не запущена. +ERROR_DB_ADR=Ошибка подключения к базе данных, проверьте правильность адреса. +ERROR_DB_NOT_SUPPORT=Неподдерживаемый тип базы данных. Проверьте, является ли соответствующий файл службы или конфигурации нормальным. +ERROR_DB_XS_DENNIED=Доступ к базе данных запрещен: недостаточно прав. +ERROR_DB_NOT_EXIST=База данных не существует, или было указано неправильное имя. +explorer.pathNotSupport=Этот тип каталога не поддерживает эту операцию! +explorer.pathIsRoot=Вы достигли корневого каталога! +explorer.pathNull=Папка пуста +explorer.zipFileLarge=Файл слишком велик, распакуйте его перед просмотром! +explorer.charNoSupport=Неподдерживаемые специальные символы: +explorer.moveError=Переместить не удалось +explorer.lockError=Произошла ошибка, время одновременной блокировки истекло +explorer.lockErrorDesc=Пожалуйста, уменьшите частоту запросов или оптимизируйте конфигурацию сервера, связанную с параллелизмом, или улучшите конфигурацию серверного оборудования; +explorer.moveSubPathError=Что-то пошло не так, родительский каталог нельзя переместить в дочерний каталог! +explorer.spaceIsFull=Недостаточно свободного места, пожалуйста, свяжитесь с администратором! +explorer.sessionSaveError=Запись сеанса не удалась! Проверьте, не заполнен ли диск, или обратитесь к поставщику услуг. +explorer.networkError=Ошибка сетевого подключения (net :: ERR_CONNECTION_RESET), соединение было сброшено.
    Пожалуйста, свяжитесь с хост-компанией или сетевым администратором, чтобы проверить конфигурацию брандмауэра! +explorer.folderManage=Директория управления +explorer.clickEdit=Нажмите, чтобы редактировать +explorer.shortLink=Ярлыки +explorer.upper=Верхний слой +explorer.historyNext=вперед +explorer.historyBack=отбой +explorer.loading=В работе ... +explorer.getting=Получение ... +explorer.sending=Отправка данных ... +explorer.pullTips=Потяните вниз, чтобы обновить страницу +explorer.pullDropTips=Бесплатно обновить страницу +explorer.getSuccess=Добейся успеха! +explorer.saveSuccess=Сохранено успешно! +explorer.saveError=Сохранить не удалось! +explorer.success=Операция прошла успешно +explorer.error=Операция не удалась +explorer.dataError=Данные ненормальные! +explorer.pathError=Ошибка пути к документу +explorer.repeatError=Операция не удалась, имя уже существует! +explorer.systemError=Системная ошибка +explorer.mistake=Что-то пошло не так! +explorer.recycleClear=Пустая корзина +explorer.recycleClearForce=В корзине слишком много содержимого, сначала очистите корзину! +explorer.recycleRestore=Восстановить корзину +explorer.recycleRestoreItem=снижение +explorer.recycleRestoreAll=Восстановить все +explorer.recycleClearInfo=Вы уверены, что хотите полностью очистить корзину? +explorer.zipDownloadReady=Загрузка автоматически после сжатия, пожалуйста, подождите ... +explorer.removeItem=Содержание элемента +explorer.uploading=Выгрузка +explorer.uploadTipsMore=Слишком много файлов, рекомендуется загрузить после сжатия, а затем распаковать онлайн! +explorer.uploadingMove=Слияние и передача ... +explorer.viewNewPage=Предварительный просмотр новой страницы +explorer.unknowFileTitle=Советы по открытию файлов! +explorer.unknowFileTips=Без приложения, которое поддерживает этот файл, вы можете: +explorer.unknowAppTips=Без приложения: +explorer.unknowFileTry=пробовать +explorer.unknowFileDown=Скачать файл +explorer.authFileDown=Загрузка файла +explorer.authShare=Общий +explorer.usersShare=Делиться +explorer.clipboard=Посмотреть буфер обмена +explorer.clipboardClear=Пустой буфер обмена +explorer.fullScreen=Полный экран +explorer.folderItem=Предметы +explorer.folderItemSelect=Выбранное +explorer.dbLoadAll=Дважды щелкните, чтобы загрузить все ... +explorer.ziping=Сжатие ... +explorer.unziping=Распаковка ... +explorer.zipingTips=Операция сжатия, пожалуйста, подождите ... +explorer.unzipingTips=Операция распаковки, пожалуйста, подождите ... +explorer.unzipRarTips=Содержимое файла повреждено или разбор файла не поддерживается.Рекомендуется использовать формат ZIP. +explorer.parsing=Получение ... +explorer.moving=Перемещение операции ... +explorer.copyMove=Скопировать ход +explorer.removeTitle=Удалить подтверждение +explorer.removeInfo=Вы уверены, что хотите удалить выбор? +explorer.removeTitleForce=Удалить навсегда +explorer.removeInfoForce=Вы уверены, что хотите удалить этот документ навсегда? +explorer.pathInRecycle=Папка находится в корзине, восстановите и попробуйте еще раз! +explorer.pathInRecycleFile=Файл находится в корзине, восстановите и попробуйте еще раз! +explorer.downOffline=Скачать в автономном режиме +explorer.savePath=Сохранить путь +explorer.uploadSelectMuti=Выберите несколько файлов для загрузки +explorer.goTo=Перейти к +explorer.selectFile=Выберите файл +explorer.selectFolder=Выберите папку +explorer.selectImage=Пожалуйста, выберите изображение ... +explorer.selectValidFolder=Пожалуйста, выберите папку, чтобы быть действительным! +explorer.selectFolderFile=Выберите файл или папку +explorer.selectMulti=Множественный выбор +explorer.notNull=Обязательные поля не могут быть пустыми! +explorer.picCannotNull=Адрес изображения не может быть пустым! +explorer.renameSuccess=Переименован успешно! +explorer.inputSearchWords=Пожалуйста, введите строку для поиска +explorer.search.optionContent=содержание документа +explorer.search.searchContentTips=Содержание файла поиска по ключевым словам, текстовый файл поддержки +explorer.search.optionMutil=Массовый поиск +explorer.search.optionMutilDesc=Один поисковый запрос в строке, результаты поиска сортируются в соответствии с поисковым запросом +explorer.removeSuccess=Удалено успешно! +explorer.removeFail=Удалить не удалось! +explorer.clipboardNull=Буфер обмена пуст! +explorer.createSuccess=Новый успех! +explorer.createError=Новое создание не удалось, пожалуйста, проверьте разрешения каталога! +explorer.copySuccess=[Копировать] - Перезаписать буфер обмена успешно! +explorer.cuteSuccess=[Вырезать] - Перезаписать буфер обмена успешно! +explorer.clipboardState=Состояние буфера обмена: +explorer.copyOK=Успешно скопировано! +explorer.copyNotExists=Источник не существует +explorer.currentHasParent=Папка назначения является подпапкой исходной папки! +explorer.pastSuccess=Операция вставки завершена +explorer.cutePastSuccess=Операция вырезания завершена +explorer.zipSuccess=Сжатие завершено +explorer.notZip=Не сжатый файл +explorer.zipNull=Не выбраны файлы или каталоги +explorer.unzipSuccess=Разархивировать завершено +explorer.pathIsCurrent=Открытый путь совпадает с текущим путем! +explorer.pathExists=Имя уже существует! +explorer.serverDownDesc=Задачи добавлены в список загрузки +explorer.parentPermission=Разрешения родительского каталога +explorer.confirm=Ты уверен? +explorer.ifSaveFileTips=Есть ли несохраненные файлы, вы уверены, что хотите закрыть окно? +explorer.ifSaveFile=Файл еще не сохранен. Сохранено? +explorer.ifStopUploadTips=Файл загружается, вы уверены, что закроете окно? +explorer.noPermissionRead=У вас нет разрешения на чтение! +explorer.noPermissionDownload=У вас нет разрешения на скачивание! +explorer.noPermissionWrite=Каталог не имеет разрешения на запись +explorer.noPermissionAction=У вас нет этого разрешения, пожалуйста, свяжитесь с администратором! +explorer.noPermissionWriteAll=Файл или каталог не имеет разрешения на запись +explorer.noPermissionWriteFile=Файл не имеет разрешения на запись +explorer.noPermissionReadAll=Файл или каталог не имеет разрешения на чтение +explorer.noPermission=Администратор отключил это разрешение! +explorer.noPermissionExt=Администратор отключил этот тип прав доступа к файлам. +explorer.noPermissionGroup=Вы не в этой группе пользователей! +explorer.pathNoWrite=Каталог не доступен для записи, пожалуйста, установите каталог и все подкаталоги для чтения и записи и попробуйте снова! +explorer.onlyReadDesc=Этот каталог не имеет разрешения на запись. Вы можете установить разрешения для этого каталога +explorer.settingSuccess=Модификация вступила в силу! +explorer.noRepeat=Дубликаты не допускаются +explorer.dataNotFull=Представление данных не завершено! +explorer.tooManyToView=Содержит слишком много контента (%s элементов), пожалуйста, откройте его локально для просмотра; +explorer.jumpAfterWhile=Автоматически прыгать после%ss, прыгать немедленно +explorer.retryTips=Пожалуйста, проверьте и попробуйте снова +explorer.selectObject=Выберите объекты +explorer.parentGroup=Начальник отдела +explorer.actionAuth=Операционный орган +explorer.notSelectDesc=Нет данных, пожалуйста, выберите! +explorer.groupAuthCopy=Скопируйте комбинацию +explorer.groupAuthCopyDesc=Скопируйте комбинацию разрешений +explorer.groupAuthPasteDesc=Вставьте скопированную комбинацию разрешений +explorer.groupAuthSave=Сохранить в избранное +explorer.groupAuthRecent=Недавно использованный +explorer.selectDesc=Выберите контент +explorer.cannotLoad=Невозможно загрузить результаты. +explorer.loadMore=Загрузить больше результатов ... +explorer.noSearchData=Результатов не найдено +explorer.delAllItem=Удалить все элементы +explorer.pleaseDel=Пожалуйста, удалите +explorer.pleaseInput=Пожалуйста, введите хотя бы +explorer.canChoose=Выберите только максимум +explorer.theChars=Персонажи +explorer.theItems=Предметы +explorer.noData=Нет данных +explorer.ifPathAuthClear=Все настройки разрешений для вложенных файлов и папок будут удалены. Вы уверены, что хотите продолжить? +explorer.fileDescAdd=Добавить описание документа +explorer.fileDesc=Описание документа +explorer.fileLog=Журнал документов +explorer.ifResetOpen=Вы уверены, что хотите сбросить все пользовательские методы открытия? +explorer.ResetOpen=Сброс всех пользовательских методов открытия +explorer.openWith=Открыть как ... +explorer.openWithAce=Редактор открывается +explorer.openWithLocal=Открыто локально +explorer.openWithLocalEdit=Локальное редактирование +explorer.editorSaveTips=Файл не был создан, пожалуйста, сначала сохраните новый файл +explorer.editor.fileTooBig=Файл слишком большой и не может быть больше 20M +explorer.errorFunctionTips=Этот тип файла не поддерживает списки функций! +explorer.errorFormatTips=Текущий тип файла не соответствует методу форматирования по умолчанию.
    Пожалуйста, выберите вручную +explorer.cuteToThe=Переместить в: +explorer.copyToThe=Скопировать в: +explorer.addToFav=Добавить в избранное +explorer.addFav=Добавить избранное +explorer.delFav=Отменить коллекцию +explorer.addFavSuccess=Добавить избранное успешно +explorer.pathHasFaved=Путь был одобрен +explorer.delFavSuccess=Отменить коллекцию успешно +explorer.fileLock=Изменить замок +explorer.fileLockNow=запирание +explorer.fileLockCancle=Разблокировать +explorer.fileLockTitle=заблокирован +explorer.fileLockTips=Заблокировано (другие не могут редактировать файл) +explorer.fileLockUser=Шкафчик +explorer.fileLockError=Текущий файл заблокирован, обратитесь в шкафчик, чтобы разблокировать его, и повторите попытку; +explorer.downloaded=Загрузка завершена +explorer.openAutoTips=Откроется автоматически +explorer.historyAutoTips=Автоматически генерировать исторические версии +explorer.saved=Сохранено успешно +explorer.opened=Открыть успешно! +explorer.openFail=Открыть не удалось! +explorer.openingWithLoc=Файл открыт локально ... +explorer.openOnlyView=Режим только для чтения включен +explorer.saving=Сохранение файла ... +explorer.notSupport=Что-то пошло не так, формат контента не поддерживается! +explorer.unzipErrorTips=Что-то пошло не так! Нераспознанный формат сжатого файла;
    Пожалуйста, проверьте, сжат ли файл или поврежден. +explorer.wordLoading=Загрузка ... +explorer.noFunction=Ни за что! +explorer.paramFormatError=Неверный формат параметра! +explorer.descTooLong=Описание слишком длинное +explorer.noMoreThan=Не более чем +explorer.desktopDelError=Извините, папка рабочего стола не поддерживает удаление! +explorer.copy=копия +explorer.past=ручка +explorer.clone=Создать копию +explorer.cute=ножницы +explorer.cuteTo=Переместить в ... +explorer.copyTo=Скопировать в ... +explorer.info=собственности +explorer.searchInPath=Поиск в папке +explorer.addToPlay=Добавить в плейлист +explorer.manageFav=Управление избранным +explorer.refreshTree=Обновить каталог дерева +explorer.zip=Создать сжатый пакет +explorer.unzip=Распакуйте в ... +explorer.unzipFolder=Извлечь в папку +explorer.unzipThis=Распаковать в текущий +explorer.unzipTo=Распакуйте в ... +explorer.openProject=Редактор открытого проекта +explorer.createLink=Создать ярлык +explorer.createLinkHome=Отправить на рабочий стол ярлык +explorer.setBackground=Установить как обои для рабочего стола +explorer.favRemove=Отменить эту коллекцию +explorer.openPath=Перейти в каталог +explorer.openPathFinished=Уже вошел в каталог +explorer.openIE=Браузер открывается +explorer.newFile=Новый файл +explorer.newFolder=Новая папка +explorer.fileSaveTo=Файл сохранен в +explorer.openFather=Отображение верхней папки +explorer.uploadFile=Загрузить файл +explorer.uploadFolder=Загрузить папку +explorer.appOpenDefault=Установить для открытия по умолчанию +explorer.appOpenAways=Откройте этот файл всегда с программой по вашему выбору +explorer.appSelectDesc=Выберите программу, которую вы хотите использовать, чтобы открыть этот файл +explorer.appSelectMenu=Установить как открытый режим по умолчанию +explorer.appSelectMenuCancel=Отменить открытие по умолчанию с помощью +explorer.appSelectWarning=Пожалуйста, выберите приложение! +explorer.appTypeSupport=Поддержка приложений +explorer.appTypeAll=Все приложения +explorer.appSearch=Поиск связанных установок приложений +explorer.recent.createTime=Создано на +explorer.recent.modifyTime=Изменено на +explorer.recent.viewTime=Открыть в +explorer.urlLink=Адрес внешней ссылки +explorer.downloading=Загрузка ... +explorer.downReady=Скоро +explorer.downError=Загрузка не удалась! +explorer.max=Максимизация +explorer.min=минимизировать +explorer.minAll=Свернуть все +explorer.displayAll=Показать все окна +explorer.closeAll=Закрыть все +explorer.authDtl=Нажмите, чтобы просмотреть свои разрешения в каталоге +explorer.authDialog=Внутренние члены, таблица разрешений уровня сотрудничества документов +explorer.authNote=Примечание. Функции управления включают настройку прав доступа для участников / управления комментариями и т. Д. Будьте осторожны! [Системный администратор] Роль не ограничена никакими разрешениями +explorer.auth.toOuter=Внешняя авторизация (другие отделы или пользователи) +explorer.auth.share=пайщик +explorer.auth.owner=владелец +explorer.auth.disableDeep=Только без разрешения +explorer.auth.disableDeepDesc=Каталог факторов имеет права на чтение и запись документов и установленный путь доступа. +explorer.auth.tips=Можете связаться с вышеупомянутыми пользователями, чтобы установить разрешения для вас +explorer.notSystemPath=Не системный путь к файлу +explorer.toolbar.rootPath=Личное пространство +explorer.toolbar.fav=Избранные +explorer.toolbar.desktop=рабочий стол +explorer.toolbar.client=Клиент +explorer.toolbar.myComputer=Мой компьютер +explorer.toolbar.recycle=Мусорная корзина +explorer.toolbar.myDocument=Мой документ +explorer.toolbar.myPicture=Мое фото +explorer.toolbar.myMusic=Моя музыка +explorer.toolbar.myMovie=Мое видео +explorer.toolbar.myDownload=Моя загрузка +explorer.toolbar.uiDesktop=рабочий стол +explorer.toolbar.uiExplorer=Управление файлами +explorer.toolbar.uiEditor=редактор +explorer.toolbar.uiProjectHome=Проект Home +explorer.toolbar.uiLogout=выход +explorer.toolbar.uiGroup=Организационная структура +explorer.toolbar.myGroup=Мой отдел +explorer.toolbar.publicPath=Публичный каталог +explorer.toolbar.recentDoc=Последние документы +explorer.toolbar.myShare=Моя доля +explorer.toolbar.shareToMe=Сотрудничать со мной +explorer.toolbar.shareTo=Мое сотрудничество +explorer.toolbar.shareLink=Обмен внешней ссылкой +explorer.toolbar.photo=Фотоальбом +explorer.photo.desc=Классификация альбомов пользователей +explorer.photo.group=Группировка альбомов +explorer.photo.setting=Настройки альбома +explorer.photo.pathRoot=Каталог сканирования альбомов +explorer.photo.pathRootSelect=Выберите папку в качестве корневого каталога для сканирования изображений альбома +explorer.photo.fileType=Укажите тип файла +explorer.photo.fileSize=фильтр размера файла +explorer.photo.fileSizeDesc=Фильтровать только файлы размером больше этого параметра, если он равен 0, ограничений нет. +explorer.toolbar.folder=каталог альбом +explorer.toolbar.folderSelect=Выберите папку для отображения в режиме альбома +explorer.pathDesc.fav=После того, как файл добавлен в коллекцию, к нему можно получить быстрый и прямой доступ. +explorer.pathDesc.home=Личное пространство - это ваше личное пространство для хранения, Видно только вам, а не другим пользователям +explorer.pathDesc.groupRoot=Это публичное пространство предприятия / подразделения, Все участники видны по умолчанию +explorer.pathDesc.myGroup=Управляйте документами своего отдела здесь, Документы отдела видны и доступны только членам этого отдела и не видны другим членам отдела. +explorer.pathDesc.group=Сетевой диск отдела, видимый только сотрудникам отдела, Полномочия на эксплуатацию назначаются и устанавливаются администратором отдела. +explorer.pathDesc.recentDoc=Недавно созданные, загруженные, измененные и открытые файлы +explorer.pathDesc.shareTo=Просматривайте и управляйте своими проектами [внутреннего сотрудничества], инициированными другими, здесь +explorer.pathDesc.shareLink=Здесь вы можете просматривать инициированный вами общий доступ к внешней сети и управлять им +explorer.pathDesc.recycle=Управляйте своими удаленными файлами (папками) здесь +explorer.pathDesc.fileType=Классифицируйте файлы по типу, только файлы в личном пространстве +explorer.pathDesc.tag=Добавляйте теги к файлам (папкам) для эффективной классификации и быстрого запроса +explorer.pathDesc.tagItem=Попробуйте добавить метку к файлу / папке! +explorer.pathDesc.mount=Здесь вы можете управлять несколькими внутренними хранилищами, а также дисками, установленными на сервере. +explorer.pathDesc.shareToMe=Плиточный дисплей - весь контент, с которым я работал +explorer.pathDesc.shareToMeUser=Показывать по авторам - контент, с которым я работал, классифицируется инициатором +explorer.pathDesc.shareToMeUserItem=Сотрудничество, инициированное этим пользователем +explorer.pathDesc.shareToMeGroup=Контент, с которым я сотрудничаю, классифицируется по отделам, в которых находится папка. +explorer.pathDesc.shareToMeGroupGroup=Совместное использование с сетевого диска отдела +explorer.pathDesc.search=Поддержка поиска файлов / тегов / заметок / содержимого; Поддержка пиньинь, нечеткое соответствие первой буквы +explorer.pathDesc.searchMore=Установите дополнительные условия поиска +explorer.pathDesc.shareFrom=Исходный путь +explorer.pathGroup.shareGroup=Ведомственное пространство +explorer.pathGroup.shareGroupDesc=Доступ, когда в отделе нижнего уровня есть контент +explorer.pathGroup.shareUser=Совместное использование личного пространства сотрудников отдела +explorer.pathGroup.shareUserDesc=Источник: совместное использование личного пространства пользователя, совместное использование документов внешним отделом по инициативе пользователя. +explorer.pathGroup.shareContent=Сотрудничество и совместное использование космоса отдела +explorer.pathGroup.group=отдел +explorer.pathGroup.groupContent=Ведомственный документ +explorer.pathGroup.shareUserOuter=Совместное использование внешнего сотрудничества +explorer.pathGroup.shareUserOuterDesc=Совместное использование внешних пользователей вне их собственной организационной структуры +explorer.pathGroup.shareSelf=личное пространство +explorer.toolbar.fileSizeTitle=Размер значка +explorer.toolbar.fileSizeSuper=Супер маленький +explorer.toolbar.fileSizeSmall=Маленькая иконка +explorer.toolbar.fileSizeDefault=Средний значок +explorer.toolbar.fileSizeBig=Большая иконка +explorer.toolbar.fileSizeBigSuper=Негабаритная иконка +explorer.toolbar.PagePC=Версия для ПК +explorer.toolbar.pagePhone=Мобильная версия +explorer.file.name=имя +explorer.file.type=тип +explorer.file.contain=содержать +explorer.file.address=расположение +explorer.file.detil=Описание Комментарии +explorer.file.linkCount=Цитирование +explorer.file.size=размер +explorer.file.count=Количество +explorer.file.byte=байт +explorer.file.path=путь +explorer.file.action=операционная +explorer.file.creator=творец +explorer.file.editor=Изменено +explorer.file.location=расположение +explorer.file.timeInfo=Информация о времени +explorer.file.createTime=Время создания +explorer.file.modifyTime=Время модификации +explorer.file.lastTime=Последнее посещение +explorer.file.sortType=Сортировать по +explorer.file.sortDisable=Контент не поддерживает указанную сортировку! +explorer.file.timeType=Г / м / д Ч: я: с +explorer.file.timeTypeInfo=Г / м / д Ч: я: с +explorer.file.listType=вид +explorer.file.listIcon=Расположение иконок +explorer.file.listList=Сортировка списка +explorer.file.listListSplit=Режим столбца +explorer.file.listTypeGroup=Режим отображения и метод сортировки +explorer.file.listTypeKeep=Режим отображения +explorer.file.listTypeKeepDesc=Выберите режим просмотра для каждой папки или используйте один и тот же режим просмотра для всех папок. +explorer.file.listSortKeep=Сортировать по +explorer.file.listSortKeepDesc=Настройте порядок сортировки столбцов для каждой папки или используйте один и тот же порядок для всех папок. +explorer.file.listViewKeep=Работает с одной папкой +explorer.file.listViewAll=применяется ко всем папкам +explorer.file.listViewReset=Восстановление значений по умолчанию +explorer.file.sortUp=инкремент +explorer.file.sortDown=убывающий +explorer.file.orderType=Сортировать по +explorer.file.orderDesc=По убыванию +explorer.file.orderAsc=По возрастанию +explorer.file.imageSize=Размер картинки +explorer.file.sharer=пайщик +explorer.file.shareTime=Поделись временем +explorer.file.viewCnt=мнения +explorer.file.downCnt=Загрузки +explorer.file.readWriteLock=Эта операция временно не поддерживается, обрабатываются другие задачи чтения и записи, повторите попытку позже! +explorer.app.app=Легкое приложение +explorer.app.createLink=Новый URL +explorer.app.create=Создать легкое приложение +explorer.app.edit=Редактировать легкое приложение +explorer.app.open=Приложение Open Light +explorer.app.groupGame=игры +explorer.app.groupTools=инструмент +explorer.app.groupReader=Читать +explorer.app.groupMovie=телевидение +explorer.app.groupMusic=музыка +explorer.app.groupLife=жизнь +explorer.app.desc=Описание приложения +explorer.app.icon=Значок приложения +explorer.app.iconShow=URL-адрес или каталог +explorer.app.group=Группировка приложений +explorer.app.type=тип +explorer.app.typeUrl=ссылка +explorer.app.typeCode=расширение JS +explorer.app.display=экстерьер +explorer.app.displayBorder=Без полей (выбран без полей) +explorer.app.displaySize=Изменить размер (выберите, чтобы настроить) +explorer.app.size=размер +explorer.app.url=Адрес ссылки +explorer.app.code=код JS +explorer.app.appType=Тип приложения +explorer.app.website=сайт +explorer.app.shortLink=Файловый ярлык +explorer.app.imgIcon=Значок изображения +explorer.app.imgIconUrl=Выберите изображение или вставьте URL-адрес веб-изображения. +explorer.app.path=путь +explorer.app.pathDesc=Не поддерживает ручную модификацию, вы можете щелкнуть правой кнопкой мыши, чтобы создать ярлык +explorer.app.link=URL ссылка +explorer.app.linkDesc=Пожалуйста, введите http / https ссылку +explorer.app.linkDragTips=Вы можете перетащить URL-ссылку в область файла, чтобы автоматически создать URL-ссылку! +explorer.app.openType=Открытый путь +explorer.app.openWindow=Новое окно +explorer.app.openDialog=Диалоговое окно +explorer.app.openCurrent=текущая страница +explorer.app.openInline=Вставить страницу +explorer.app.dialogSize=Размер диалога +explorer.app.with=ширина +explorer.app.height=высота +explorer.app.moreSet=Дополнительные настройки +explorer.app.canDiyWith=Разрешить регулировку ширины +explorer.app.miniBlock=Минималистская строка заголовка +explorer.app.runCode=Выполнить код JS +explorer.app.name=Название приложения +explorer.app.nameDesc=Пожалуйста, введите название приложения. +explorer.app.descDesc=Пожалуйста, введите описание приложения +explorer.embed.title=Встроенный файл +explorer.embed.desc=Вставьте файл на веб-страницу или в блог +explorer.embed.url=Встроить URL +explorer.embed.code=Код для вставки +explorer.upload.ready=В ожидании загрузки +explorer.upload.success=Загружен успешно +explorer.upload.secPassSuccess=Успех в секундах +explorer.upload.pathCurrent=Перейдите в текущий каталог +explorer.upload.select=Выберите файл +explorer.upload.maxSize=Максимально допустимый +explorer.upload.sizeInfo=Если вы хотите настроить больше, пожалуйста, измените максимально допустимую загрузку в php.ini. При выборе файла, те, которые больше этой конфигурации, будут автоматически отфильтрованы. +explorer.upload.error=Загрузка не удалась +explorer.upload.mergeError=Ошибка объединения файлов +explorer.upload.errorHttp=Ошибка сети или брандмауэра +explorer.upload.muti=Загрузка нескольких файлов +explorer.upload.drag=Перетащите загрузить +explorer.upload.dragFolder=Перетащите в папку для загрузки +explorer.upload.dragTips=Отпустите, чтобы загрузить! +explorer.upload.pathNotAllow=Имя файла не допускается +explorer.upload.errorNull=Нет документов! +explorer.upload.errorBig=Размер файла превышает лимит сервера +explorer.upload.errorMove=Не удалось переместить файлы! +explorer.upload.errorExists=Файл уже существует +explorer.upload.local=Загрузить локально +explorer.upload.tips=Используйте загрузку фрагментов, больше не ограниченную php.ini, рекомендуется перетаскивать и выгружать в папку Chrome Experience +explorer.upload.exist=Обработка файлов с тем же именем +explorer.upload.clearAll=Очистить все +explorer.upload.clear=Опорожнение завершено +explorer.upload.addMore=Добавить оптом +explorer.upload.errorEmpty=Не может быть пустым! +explorer.upload.errorExt=Расширения файлов не совпадают! +explorer.upload.fileSizeDisable=Слишком много файлов загружено / передано одновременно, обратитесь к администратору для корректировки! +explorer.upload.moreDesc=(Рекомендуется не более 2000), на данный момент всего: +explorer.upload.scan=сканирование +explorer.upload.merge=Проверка слияния +explorer.upload.needTime=Осталось ок. +explorer.upload.checkError=Ошибка при загрузке, попробуйте еще раз +explorer.upload.saveError=Не удалось сохранить информацию о загрузке файла +explorer.upload.downloadDesc=Поддерживает только сетевые ссылки http / https +explorer.table.first=дома +explorer.table.last=Последняя страница +explorer.table.prev=предыдущий +explorer.table.next=Следующая страница +explorer.table.one=Всего 1 страниц +explorer.table.page=страница +explorer.table.itemPage=/ страница +explorer.table.searchTotal=В общей сложности поиск +explorer.table.items=документация +explorer.table.list=Список данных +explorer.search.ing=Поиск ... +explorer.search.result=Результат поиска +explorer.search.resultTooMore=Слишком много результатов поиска, предложите другой каталог или слово +explorer.search.resultNull=Нет результатов поиска! +explorer.search.caseSensitive=Чувствителен к регистру +explorer.search.content=Поиск содержимого файла +explorer.search.extDesc=Введите расширения для фильтрации, разделенные пробелами. +explorer.search.byItems=Условная фильтрация +explorer.search.extNull=Неограниченный тип +explorer.search.extFile=Любой файл +explorer.search.extDiy=настроить +explorer.search.inputDesc=Пожалуйста, введите ключевые слова или укажите фильтры! +explorer.search.path=Поиск в каталоге: +explorer.search.rootPath=Поиск в корневом каталоге: +explorer.search.range=Диапазон поиска +explorer.search.allFolder=Все папки +explorer.search.currentFolder=Текущая папка +explorer.search.ext=Тип файла +explorer.search.timeRange=Временной диапазон +explorer.search.timeAll=Неограниченное время +explorer.search.lastDay=Почти 1 день +explorer.search.lastWeek=Последние 7 дней +explorer.search.lastMonth=Последние 30 дней +explorer.search.lastYear=В прошлом году +explorer.search.sizeAll=Неограниченный размер +explorer.search.inputNullDesc=Если не заполнено, это означает большее или меньшее определенного значения, которое может быть десятичным. +explorer.search.selectUser=Выберите пользователя ... +explorer.search.byUserDesc=Поиск по создателю / модификатору +explorer.search.total=В общей сложности поиск +explorer.search.noResult=Извините, результатов поиска нет, попробуйте другой запрос! +explorer.search.advance=Расширенный поиск +explorer.search.clear=Очистить содержание +explorer.history.list=История файла +explorer.history.lastModify=Последнее изменение +explorer.history.modifyUser=Изменено +explorer.history.noHistory=Нет исторической версии! +explorer.history.current=Текущая версия +explorer.history.detil=Описание Комментарии +explorer.history.detilAdd=Добавить отпечаток +explorer.history.uploadNew=Загрузить новую версию +explorer.history.diff=Сравнение исторических версий +explorer.history.setCurrent=Установить в качестве текущей версии +explorer.history.delCurrent=Удалить эту версию +explorer.history.delAll=Удалить всю историю версий +explorer.history.ifDelAll=Вы уверены, что хотите удалить всю историю? +explorer.history.ifDelCurrent=Удалить эту версию? +explorer.history.ifRollback=Вы уверены, что хотите вернуться к этой версии? +explorer.history.changeEvent=Переключение исторической версии +explorer.history.before=До +explorer.history.after=после +explorer.recycle.clearUser=Очистите корзину пользователя +explorer.recycle.restoreSelect=Восстановить этот контент +explorer.recycle.moveTo=Сдавать +explorer.recycle.config=Настройки корзины +explorer.recycle.configTitle=Настройки корзины системы +explorer.recycle.configOpen=Откройте системную корзину +explorer.recycle.configOpenDesc=Предлагаем открыть +explorer.recycle.configCloseInfo=При удалении контента он не попадет в корзину системы, а будет удален напрямую. +explorer.recycle.configOpenInfo=
  • Личные документы или документы отдела после полного удаления или опорожнения корзины попадают в корзину системы
  • Удаленный контент классифицируется в папке пользователя или отдела в соответствии с пользователем или отделом, в котором находится файл, и администратор может выбрать восстановление этих файлов;
  • Файлы до момента автоматического полного удаления будут регулярно автоматически очищаться;
  • Примечание. Удаленные здесь файлы не подлежат восстановлению.
  • +explorer.recycle.configClear=Удалить полностью автоматически +explorer.recycle.restoreConfirm=Вы уверены, что восстановите документ?
    После восстановления документ будет перемещен в целевой корневой каталог. +explorer.recycle.moveConfirm=Подтвердить передачу +explorer.recycle.moveSelectTarget=Выберите пользователя или отдел +explorer.recycle.moveDesc=
  • Передать назначенному пользователю или отделу; он переместится в корневой каталог объекта
  • После передачи описания документов, обмены и обсуждения, исторические версии и другая информация будут по-прежнему храниться; информация о совместной работе и разрешениях будет удалена.
  • +explorer.recycle.taskTitle=Система очистки корзины +explorer.recycle.taskDesc=Автоматически удалять содержимое корзины по истечении установленного времени, чтобы освободить место для хранения +explorer.share.add=Добавить долю +explorer.share.edit=Редактировать Поделиться +explorer.share.remove=Отмена обмена +explorer.share.path=Поделиться путем +explorer.share.source=Совместное использование ресурсов +explorer.share.name=Поделиться заголовком +explorer.share.nameDesc=Поделиться именем файла по умолчанию, можно настроить +explorer.share.time=Время истечения +explorer.share.timeLimit=Ограниченное время +explorer.share.timeLimitDesc=После включения и настройки общий доступ будет отключен автоматически по истечении времени +explorer.share.timeDesc=Не установлено, если пусто +explorer.share.pwd=Извлечь пароль +explorer.share.pwdDesc=Пароль не установлен +explorer.share.randomPwd=Случайно сгенерированный +explorer.share.randomPwdDesc=Его можно просмотреть только путем извлечения пароля, который является более приватным и безопасным. +explorer.share.cancel=Отмена обмена +explorer.share.create=Создать общедоступную ссылку +explorer.share.url=Общий адрес +explorer.share.noDown=Загрузка запрещена +explorer.share.codeRead=Чтение кода +explorer.share.configSave=Сохраните конфигурацию +explorer.share.errorParam=Ошибка параметра! +explorer.share.errorUser=Информация о пользователе неверна! +explorer.share.errorSid=Поделиться не существует! +explorer.share.errorTime=Вы опоздали, эта доля истекла! +explorer.share.errorPath=Общий файл не существует, он был удален или перемещен! +explorer.share.errorPwd=Пароль неверный! +explorer.share.errorShowTips=Этот тип файла не поддерживает предварительный просмотр! +explorer.share.expiredTips=Извините, срок действия этой доли истек, пожалуйста, свяжитесь с участником! +explorer.share.downExceedTips=Извините, доля загрузок превысила лимит, установленный участником +explorer.share.store=Сохранить в SkyDrive +explorer.share.loginTips=Извините, этот ресурс должен быть авторизован для доступа! +explorer.share.noDownTips=Извините, загрузчик отключил загрузку! +explorer.share.noViewTips=Извините, этот участник отключил предварительный просмотр! +explorer.share.noUploadTips=Извините, загрузка отключена этим участником! +explorer.share.needPwd=Эта доля требует пароль +explorer.share.notExist=Обмен не существует! +explorer.share.viewNum=Просмотров: +explorer.share.downNum=Загрузки +explorer.share.openPage=Открыть общую страницу +explorer.share.openLink=Открыть ссылку +explorer.share.copyLink=Копировать обмен информацией +explorer.share.link=Поделиться ссылкой: +explorer.share.accessPwd=Пароль доступа: +explorer.share.copied=скопированный +explorer.share.actionNotSupport=Поделиться контентом, эта операция не поддерживается +explorer.share.errorPathTips=Ссылка для обмена неверна или участник отменил внешнюю ссылку +explorer.share.shareTo=Совместный обмен +explorer.share.shareToTarget=Сотрудничающий член +explorer.share.innerTo=Внутреннее сотрудничество +explorer.share.linkTo=Обмен внешними ссылками +explorer.share.selectTarget=Выберите отдел или пользователя для совместного использования +explorer.share.afterShareDesc=После публикации другим лицам или отделу, к которому они принадлежат, пользователи могут видеть его в [Поделиться со мной]. +explorer.share.openOuterLink=Открытая внешняя цепочка обмена +explorer.share.openOuterLinkDesc=После создания внешней ссылки вы можете отправить ее другим пользователям по электронной почте или в QQ. +explorer.share.outerLink=Поделиться ссылкой +explorer.share.advanceSet=Расширенная конфигурация +explorer.share.loginLimit=Доступно только зарегистрированным пользователям +explorer.share.loginLimitDesc=После открытия доступ могут получить только внутренние участники. +explorer.share.authLimit=Права и ограничения +explorer.share.canUpload=Разрешить загрузку +explorer.share.notView=Отключить предварительный просмотр +explorer.share.notDown=Отключить загрузки +explorer.share.downNumLimit=Ограничение на скачивание +explorer.share.downNumLimitDesc=По истечении этого количества раз ссылка для обмена автоматически истекает. +explorer.share.learnAuth=Понимание разрешений на совместную работу с документами +explorer.share.shareToRemove=Вы действительно хотите отменить совместный доступ?
    Целевой пользователь, которому предоставлен доступ, больше не может видеть общий доступ для совместной работы! +explorer.share.shareLinkRemove=Вы действительно хотите отменить общий доступ по внешней ссылке?
    После отмены внешняя ссылка станет недействительной! +explorer.share.shareToCopy=Копировать путь доступа +explorer.share.shareToCopyDesc=Ссылку можно отправить сотруднику и быстро вступить в сотрудничество +explorer.share.specifyAuthTips=Помимо указанных выше пользователей +explorer.share.specifyAuthDesc=Полномочия назначенного пользователя> Полномочия отдела назначенного пользователя> Полномочия другого лица +explorer.share.selfAuthDesc=Невозможно изменить собственные разрешения, другие менеджеры могут установить +explorer.share.authTypeDesc=Наследовать разрешения из родительской папки по умолчанию +explorer.share.rootPathAuthDesc=Корневой отдел поддержки пользователей и выбор отдела +explorer.share.subPathAuthDesc=Подотдел, только избранные сотрудники отдела +explorer.share.myAuth=Мои разрешения +explorer.share.othersAuth=Другие разрешения +explorer.share.keepAuth=Сохранить оригинальные разрешения +explorer.share.specifyAuth=Укажите разрешения +explorer.share.userAuth=Права пользователя +explorer.share.specifyUserAuth=Указание пользовательских разрешений +explorer.share.rptTitle=Если вы обнаружите незаконную и вредоносную информацию, выберите причину ниже, чтобы отправить сообщение. +explorer.share.illegal=Незаконная информация +explorer.share.inputRptDesc=Пожалуйста, введите причину сообщения +explorer.share.rptSend=Отправка прошла успешно, администратор обработает ее вовремя +explorer.share.rptSended=Отчет отправлен, ожидает обработки администратором +explorer.auth.mutil=Устанавливайте разрешения партиями +explorer.auth.mutilTips=Примечание . Если у выбранного содержимого уже есть разрешение, оно будет перезаписано. +explorer.auth.mutilDesc=В то же время, что и последующие разрешения по умолчанию +explorer.auth.showMore=Сведения о разрешении +explorer.auth.tabUser=член отдела +explorer.auth.tabChildren=Разрешения для подпапок +explorer.auth.tabUserTips=Первоначальные разрешения членов отдела +explorer.auth.tabChildrenTips=Содержимое с установленными разрешениями в этой папке +explorer.auth.resetUser=Переопределить настройку этого разрешения пользователя +explorer.auth.resetUserBtn=Переопределить разрешения +explorer.auth.resetUserBtnTips=Переопределить права пользователя и всех подпапок (папок) в этой папке +explorer.auth.resetUserHeader=Папка нижнего уровня содержит содержимое, определяющее разрешения пользователя, и устанавливает все переопределения для указанных выше разрешений. +explorer.auth.resetUserContiner=Содержит содержимое разрешения пользователя +explorer.auth.resetUserEmpty1=Нет контента, для которого установлены разрешения для этого пользователя, не нужно переопределять +explorer.auth.resetUserEmpty2=Все дочернее содержимое наследует разрешения папки текущего уровня. +explorer.rename.mutil=Пакетное переименование +explorer.rename.nameBefore=Исходное имя файла +explorer.rename.nameTo=Rename +explorer.rename.start=Переименовать сейчас +explorer.rename.clearFinished=Опорожнение завершено +explorer.rename.clearAll=Очистить все +explorer.rename.typeReplaceAll=Заменить все +explorer.rename.typePrepend=Добавить до +explorer.rename.typeAppend=Добавить позже +explorer.rename.typeReplace=Найти и заменить +explorer.rename.typeChangeCase=Преобразование дела +explorer.rename.typeRemove=Удалить персонажей +explorer.rename.typeReplaceSet=Уточняйте замену партиями +explorer.rename.typeReplaceSetDesc=Замените, если они равны; каждая строка отделяется пробелом, а имя файла не допускает пробелов; например: +explorer.rename.numberStart=Offset +explorer.rename.appendContent=Дополнительный контент +explorer.rename.find=искать +explorer.rename.replaceTo=Заменено на +explorer.rename.caseUpperFirst=Начальный капитал +explorer.rename.caseUpper=Все шапки +explorer.rename.caseLower=Все строчные +explorer.rename.removeStart=Удалить с нуля +explorer.rename.removeEnd=Удалить из конца +explorer.rename.chars=характер +explorer.editor.beautifyCode=Форматирование кода +explorer.editor.convertCase=Преобразование дела +explorer.editor.convertUpperCase=Преобразовать в верхний регистр +explorer.editor.convertLowerCase=Преобразовать в нижний регистр +explorer.editor.currentTime=Текущее время +explorer.editor.md5=шифрование md5 +explorer.editor.qrcode=Строка QR-код +explorer.editor.regx=Тест регулярного выражения +explorer.editor.chinese=Упрощенное преобразование +explorer.editor.chineseSimple=Конвертировать в упрощенный китайский +explorer.editor.chineseTraditional=Преобразовать в традиционный китайский +explorer.editor.base64=кодек base64 +explorer.editor.base64Encode=кодировка base64 +explorer.editor.base64Decode=декодирование base64 +explorer.editor.url=URL-кодек +explorer.editor.urlEncode=Кодировка URL +explorer.editor.urlDecode=Декодирование URL +explorer.editor.unicode=Кодек Unicode +explorer.editor.unicodeEncode=Кодировка Юникод +explorer.editor.unicodeDecode=Unicode декодирование +explorer.editor.toolsSelectTips=Пожалуйста, выберите правильный контент для обработки! +explorer.editor.toolsRandString=Сгенерировать 32-битную случайную строку +explorer.editor.textEncode=Кодирование / декодирование текста +explorer.editor.textParse=Обработка текста +explorer.editor.timeShow=Отметка времени до времени +explorer.editor.timeInt=Время до отметки времени +explorer.editor.lineRemoveEmpty=Удалите пустые строки (включая пробелы) +explorer.editor.lineUnoin=Удалить повторяющиеся строки +explorer.editor.lineTrim=Удалите начальные и конечные пробелы +explorer.editor.lineSort=Сортировать по строке (в порядке возрастания) +explorer.editor.lineReverse=Поменять местами все строки вверх и вниз +explorer.editor.lineSum=Сумма +explorer.editor.lineAverage=Средняя стоимость +explorer.editor.calc=Бесплатный калькулятор +explorer.editor.goToLine=Перейти к строке +explorer.editor.keyboardType=Режим клавиатуры +explorer.editor.fontFamily=шрифты +explorer.editor.codeMode=Выделить синтаксис +explorer.editor.closeAll=Закрыть все +explorer.editor.closeLeft=Закрыть левую вкладку +explorer.editor.closeRight=Закрыть правую вкладку +explorer.editor.closeOthers=Закрыть другие +explorer.editor.wordwrap=Перенос слов +explorer.editor.showGutter=Показать номер строки +explorer.editor.charAllDisplay=Показать невидимых персонажей +explorer.editor.autoComplete=Автоматическая подсказка +explorer.editor.autoSave=Автоматическое сохранение +explorer.editor.functionList=Список функций +explorer.editor.codeTheme=Кодовый стиль +explorer.editor.fontSize=Размер шрифта +explorer.editor.completeCurrent=Автозаполнение тока +explorer.editor.createProject=Добавить в редактор проекта +explorer.editor.markdownContent=Каталог содержимого +explorer.editor.undo=Отменить +explorer.editor.redo=Анти отозвана +explorer.editor.shortcut=Ярлыки +explorer.editor.replace=замещать +explorer.editor.reload=Reload +explorer.editor.view=вид +explorer.editor.tools=инструмент +explorer.editor.help=Помощь +explorer.sync.data=Синхронизация данных +explorer.sync.openLoc=Открыть локальный каталог +explorer.sync.syncing=Syncing +explorer.sync.synced=Синхронизация завершена +explorer.sync.syncedError=Журнал ошибок +explorer.sync.syncStart=Начать синхронизацию +explorer.sync.syncStop=Остановить синхронизацию +explorer.sync.notOpenTips=Вы не включили локальную синхронизацию +explorer.sync.setNow=Настройте синхронизацию сейчас +explorer.sync.error=Загрузка не удалась +explorer.sync.success=Успешная синхронизация +explorer.sync.statusScan=сканирование +explorer.sync.statusNone=Синхронизация не настроена +explorer.sync.statusScanEnd=Сканирование завершено +explorer.sync.statusDoing=синхронизация +explorer.sync.statusDone=Синхронизация завершена +explorer.sync.statusStop=пауза +explorer.sync.clearCacheSuccess=Очистить кеш успешно! +explorer.sync.emptyTask=Нет задачи синхронизации +explorer.sync.openCloud=Открытое облачное местоположение +explorer.sync.openLocal=Открыто локально +explorer.sync.statusFiles=Ход выполнения документа +explorer.sync.statusLastTime=Время завершения +explorer.sync.configName=Настройки синхронизации +explorer.sync.configClient=Настройки клиента +explorer.sync.configAbout=на +explorer.sync.configSyncFrom=Локальный путь +explorer.sync.configSyncFromDesc=Выберите локальную папку для синхронизации +explorer.sync.configSyncTo=Синхронизировать с +explorer.sync.configSyncToDesc=Синхронизировать с местоположением сервера +explorer.sync.configIgnore=Игнорируемые типы файлов +explorer.sync.configIgnoreDesc=Файлы этого типа не синхронизированы +explorer.sync.autorun=Загрузка с начала +explorer.sync.configThread=Количество одновременных потоков +explorer.sync.configThreadDesc=Количество одновременно загруженных файлов +explorer.sync.configDownloadPath=Скачать путь +explorer.sync.configDownloadPathDesc=Путь загрузки по умолчанию при загрузке файловых папок +explorer.sync.configClearCacheAuto=Автоматически очищать кеш +explorer.sync.configClearCacheAutoDesc=Автоматически очищать файл кеша N дней назад +explorer.sync.configClearCache=Очистить кеш +explorer.sync.configChangeSite=Выход с текущего сайта +explorer.sync.configVersion=Текущая версия +explorer.sync.configUpdateDesc=Обновить инструкции +explorer.sync.configUpdateCheck=Обнаружение обновлений +explorer.sync.confirmReset=Синхронизируйте изменение каталога, информация о синхронизации будет сброшена. Вы уверены, что сохранили? +explorer.sync.listClearDone=Опорожнение завершено +explorer.sync.listClearError=Очистить список ошибок +explorer.sync.listRetryAll=Повторить все +explorer.async.tipsDisablePath=Не поддерживает выбор для синхронизации пути +explorer.async.tipsIsMoving=Обнаружено, что большой объем контента в настоящее время перемещается или копируется в синхронизированный каталог;
    Рекомендуется обновить страницу для синхронизации после локального завершения! +explorer.async.tipsStartUser=Запустите синхронизацию вручную +explorer.download.title=Управление загрузкой +explorer.download.waiting=Ожидающий +explorer.download.stop=Приостановить скачивание +explorer.download.start=начать загрузку +explorer.download.remove=Удалить задачу +explorer.download.stopAll=Приостановить все +explorer.download.startAll=Продолжить все +explorer.download.clearAll=Очистить все задачи +explorer.download.doing=обработка +explorer.download.done=Скачивание завершено +explorer.download.clearAllTips=Вы уверены, что удалите все задачи загрузки? +explorer.tag.name=Файловый тег +explorer.tag.edit=Управление этикетками +explorer.tag.add=Создать ярлык +explorer.tag.remove=Вы уверены, что хотите удалить этот тег? +explorer.tag.inputHolder=Пожалуйста, введите название ярлыка +explorer.tag.addTo=Установить метку +explorer.tag.default1=Учиться +explorer.tag.default2=Тестовые данные +explorer.tag.default3=контракт +explorer.tag.filter=Фильтр по ярлыку +explorer.groupTag.title=Публичный ярлык +explorer.groupTag.menuTtitle=Общественный лейбл отдела +explorer.groupTag.titleDesc=Публичный лейбл в отделе +explorer.groupTag.empty=После того, как администратор отдела устанавливает общедоступную метку, она автоматически включается. Когда нет содержимого метки, общедоступная метка автоматически отключается! +explorer.tag.pathDesc=Фильтр по личному ярлыку +explorer.groupTag.pathDesc=Фильтр по публичному ярлыку отдела +explorer.groupTag.removeTypeTips=Вы действительно хотите удалить эту группу? Все документы, связанные с ярлыком, будут удалены после удаления! +explorer.groupTag.removeTagTips=Вы действительно хотите удалить тег? Документ, связанный с тегом, будет удален после удаления! +explorer.groupTag.typeAdd=добавить категорию +explorer.groupTag.typeName=Название категории +explorer.groupTag.addDesc=После добавления тегов теги отделов включаются автоматически, максимальное количество тегов - 1000. +explorer.panel.info=Атрибуты +explorer.panel.version=версия +explorer.panel.chat=обсуждать +explorer.panel.log=динамический +explorer.panel.meta=Метаданные +explorer.panel.chatName=Обмен обсуждения +explorer.panel.chat.send=Отправить +explorer.panel.chat.noAuth=У вас нет разрешения комментировать этот документ! +explorer.panel.chat.placeholder=Введите здесь, [Enter] для отправки, [Ctrl + Enter] перевод строки +explorer.panel.chat.placeholderCtrl=Введите сюда, Ctrl + Enter, чтобы отправить, Enter, чтобы обернуть +explorer.panel.chat.reply=Ответить +explorer.panel.chat.empty=без комментариев +explorer.panel.chat.sendTo=Вперед +explorer.panel.metaName=Расширение метаданных +explorer.panel.metaDesc=Расширенные свойства поля документа +explorer.panel.thumbClear=очистить миниатюру +explorer.panel.thumbClearDesc=Очистите миниатюры файлов, обложку для восстановления. +explorer.panel.historyName=историческая версия +explorer.panel.historyDesc=Примечания к выпуску +explorer.panel.infoTips=Выберите файл (папку) для просмотра подробных свойств +explorer.panel.info.space=Космическая емкость +explorer.panel.info.groupAt=Расположение отдела +explorer.panel.info.tagEmpty=Нет тегов, нажмите настройки +explorer.panel.logName=Новости документа +explorer.panel.logEmpty=Нет активности +explorer.type.doc=доктор +explorer.type.image=образ +explorer.type.music=Музыка +explorer.type.movie=видео +explorer.type.zip=Архив +explorer.type.others=Другой +explorer.secret.title=Управление конфиденциальностью документов +explorer.secret.isOpen=Включить ли +explorer.secret.isOpenDesc=Включить и отключить управление уровнем безопасности +explorer.secret.setUser=секретный менеджер +explorer.secret.setUserDesc=Укажите пользователя, который может установить уровень конфиденциальности (должен быть одновременно владельцем в соответствующем отделе) +explorer.secret.type=Тип классификации +explorer.secret.add=Добавить уровень безопасности +explorer.secret.edit=изменить уровень безопасности +explorer.secret.name=Имя класса +explorer.secret.style=стиль +explorer.secret.auth=Разрешение секретного уровня +explorer.secret.authHas=Конфиденциальные разрешения включают +explorer.secret.createUser=сеттер +explorer.secret.folderAt=конфиденциальная папка +explorer.secret.tips=Разрешения контролируются секретным уровнем, а разрешения секретного уровня выше, чем разрешения документа. +explorer.secret.tips1=Только для содержимого на корпоративном сетевом диске указанный выше пользователь может установить уровень конфиденциальности (и должен быть одновременно владельцем папки) +explorer.secret.tips2=Все содержимое в нижнем слое папки с уровнем конфиденциальности установлено, и это полномочие является наивысшим. +explorer.secret.tips3=После установки разрешение секретного уровня выше, чем разрешение документа (документ также контролируется разрешением секретного уровня, системный суперадминистратор не подпадает под это ограничение, а установщик секретного уровня не подпадает под это ограничение) +explorer.secret.tips4=Разрешения на уровне конфиденциальности: можно добавить в «Управление отделами и участниками — Управление правами на документы» и установить как скрытые +user.displayHideFile=Показать скрытые файлы +user.displayHideFileDesc=Скрытые файлы: файлы, начинающиеся с., И скрытые имена файлов, заданные в фоновом режиме системы, скрытые файлы будут отображаться после открытия; +user.soundOpen=Включить звук +user.animateOpen=Запустить анимацию +user.recycleOpen=Открыть корзину +user.recycleDesc=После открытия delete переместится в корзину, рекомендуется открыть +user.animateDesc=Анимации, такие как открытие окна, можно рассмотреть закрытие, когда операция не является гладкой +user.soundDesc=Открывать файлы, удалять файлы, пустую корзину и т. Д. +user.thumbOpen=Открыть эскиз картинки +user.thumbDesc=Лучший опыт просмотра изображений после открытия +user.fileSelect=Значок открытого файла +user.fileSelectDesc=Щелкните левой кнопкой мыши значок файла, ярлык записи в меню правой кнопки мыши. +user.fileShowDesc=Показать введение папки +user.fileShowDescTips=режим только значок +user.fileOpenClick=Откройте файл (папку) следующим образом +user.fileOpenClick.dbclick=Открыть двойным кликом +user.fileOpenClick.click=Открыть, нажав +user.viewSetting=Показать параметры +user.thirdAccount=Сторонний аккаунт +user.bindAccount=Привязать аккаунт +user.thirdBindFirst=Учетная запись не была связана, пожалуйста, используйте после привязки +user.account=счета +user.bind=переплет +user.unbind=Разукрупнение +user.binded=Связанный +user.clickBind=Нажмите связать +user.clickToBind=Unbound, нажмите bind +user.clickEditPwd=Нажмите Изменить пароль +user.userAvatar=Картинка профиля +user.userNickName=Персональный ник +user.userAccount=Личный кабинет +user.uploadAvatar=Загрузить аватар +user.userAvatarCrop=Пожалуйста, выберите подходящую область в качестве аватара +user.userAvatarExt=Поддерживает только форматы изображений JPG, JPEG, PNG. +user.resetPwdDesc=Забыли пароль? Вы можете +user.inputEmailCode=Пожалуйста, введите код подтверждения вашей электронной почты +user.inputSmsCode=Пожалуйста, введите код подтверждения SMS +user.emailVerifyDesc=Некоторые предприятия требуют подтверждения по электронной почте +user.phoneVerifyDesc=Некоторые предприятия требуют проверки мобильного телефона +user.bindOthers=Уже привязан к другому аккаунту +user.notBind=Еще не связаны +user.regist=Регистрация пользователя +user.notRegist=Не зарегистрировано +user.registed=Уже зарегистрированы +user.signError=Подпись обратного вызова неверна +user.repeat=повторение +user.noRepeat=Не может повторить +user.newPwd=Новый пароль +user.unAuthFile=Несанкционированный доступ к файлам +user.unbindWarning=Пожалуйста, измените пароль перед отменой привязки, иначе учетная запись не будет работать должным образом +user.isLoginTips=Обнаружено, что вы в данный момент вошли в систему! +user.isLoginEnter=Введите сейчас +user.ifUnbind=Вы уверены, что хотите удалить? +user.bindFirst=Пожалуйста, сначала свяжите свой адрес электронной почты или номер мобильного телефона +user.inputNewPwd=Пожалуйста, введите новый пароль +user.inputNewValue=Пожалуйста, заполните новый контент +user.guestLogin=Туристический вход +user.name=Вход в систему +user.nickName=Ник пользователя +user.code=Код подтверждения +user.codeError=Ошибка кода подтверждения +user.imgCode=Капча +user.rootPwd=Установить пароль администратора +user.rootPwdRepeat=Подтвердите пароль еще раз +user.rootPwdEqual=Пароли не совпадают дважды! +user.rootPwdTips=Пожалуйста, установите пароль администратора! +user.pwdError=Неверное имя пользователя или пароль! +user.pwdNotNull=Пароль не может быть пустым! +user.oldPwdError=Оригинальный пароль неверен! +user.keepPwd=Запомнить пароль +user.forgetPwd=Забыли пароль +user.directLogin=Уже вошли в систему +user.moreLogin=Больше способов войти +user.loginNow=Войдите сейчас +user.registNow=Зарегистрируйтесь сейчас +user.backHome=Вернуться на главную +user.ifHasAccount=Уже есть аккаунт? +user.userEnabled=Аккаунт отключен или еще не включен! Пожалуйста, свяжитесь с администратором +user.roleError=Группа разрешений не существует, пожалуйста, свяжитесь с администратором +user.invalidEmail=У вас нет действующего адреса электронной почты, пожалуйста, свяжитесь с администратором, чтобы изменить +user.codeRefresh=Нажмите "Обновить" +user.emailVerify=Аутентификация почтового ящика +user.sendSuccess=Успешно отправлено +user.sendFail=Не удалось отправить +user.sendSuccessDesc=Код подтверждения отправлен успешно, перейдите к просмотру +user.sendFailDesc=Не удалось отправить код подтверждения, обратитесь к администратору +user.inputVerifyCode=Пожалуйста, введите проверочный код +user.getCode=Получить код подтверждения +user.inputPwd=Пожалуйста, введите пароль +user.inputPwdAgain=Пожалуйста, введите пароль еще раз +user.inputNickName=Пожалуйста, введите ник +user.inputEmail=Пожалуйста, введите ваш адрес электронной почты +user.inputPhone=Пожалуйста, введите ваш номер телефона +user.inputPhoneEmail=Пожалуйста, введите мобильный телефон / адрес электронной почты +user.invalidPhoneEmail=Неверный телефон / электронная почта +user.findPwd=Восстановить пароль +user.inputNotMatch=Введенный %s не соответствует границе +user.usingDesc=Вы используете +user.improveInfo=Пожалуйста, заполните информацию +user.codeExpired=Код подтверждения истек, пожалуйста, получите его снова +user.codeErrorTooMany=Слишком много ошибок кода подтверждения, пожалуйста, повторно +user.codeErrorFreq=Частота отправки слишком высока, повторите попытку позже! +user.codeErrorCnt=Количество отправлений превысило лимит и будет заблокировано на %s часов. +user.registSuccess=Успешно зарегистрирован +user.waitCheck=Ожидание отзыва администратора +user.nameHolder=Пожалуйста, введите свой номер телефона / электронную почту +user.loginNoPermission=К сожалению, у вас нет этого разрешения, пожалуйста, войдите в систему с учетной записью с этим разрешением! +user.loginFirst=Вы не авторизованы! Пожалуйста, войдите сначала +user.bindSignError=Подпись ненормальная, попробуйте еще раз! +user.bindUpdateError=Не удалось обновить информацию о пользователе, повторите попытку +user.bindTypeError=Неверный тип привязки +user.bindWxConfigError=Получить исключение информации о конфигурации +user.loginTimeout=Текущее время входа истекло, пожалуйста, войдите снова! +user.theme=Стиль темы +user.theme.desc=Автоматическая репрезентативная система слежения +user.theme.light=Светлый цвет +user.theme.dark=Темный цвет +user.theme.auto=автоматический +user.theme.title=Пользовательские настройки темы +user.theme.background=фон +user.theme.image=изображение +user.theme.colorBlur=Градиент цвета +user.theme.imageBlur=Обработка размытия изображения +user.theme.imageUrl=Адрес изображения +user.theme.colorStart=Начальный цвет +user.theme.colorEnd=Конечный цвет +user.theme.colorRadius=Угол градиента +user.theme.themeImage=Фоновое изображение +user.theme.themeImageDesc=Поддержка: URL-адрес изображения, цвет градиента css, следовать обоям +user.theme.imageWall=Следить за обоями +user.wall.random=Случайные обои +user.wall.paperDesktop=Обои для рабочего стола +user.wall.paperDeskMgt=Управление обоями рабочего стола +user.wall.paperLoginMgt=Управление обоями входа +user.wall.paperLoginTips=Когда имеется более одного изображения, фон интерфейса входа в систему будет вращаться случайным образом. +log-type-create-mkdir=новая папка +log-type-create-mkfile=создать новый файл +log-type-create-upload=загрузить файлы +log-type-create-copy=Вставить файл +log-type-edit=Обновить файл +log-type-move=Переместить файл +log-type-moveOut=Удалить файлы +log-type-share-shareLinkAdd=Создана внешняя ссылка +log-type-share-shareToAdd=Совместное совместное использование включено +log-type-share-shareLinkRemove=Закрытый обмен ссылками +log-type-share-shareToRemove=Отключить совместный доступ +log-type-share-shareEdit=Изменить общий доступ +log-type-rename=Rename +log-type-recycle-toRecycle=Переместить в корзину +log-type-recycle-restore=Восстановить из корзины +log-type-remove=Удалить +log-type-addDesc=Изменить описание +log-type-addComment=Оставить комментарий +log-event-create-mkdir=Создал эту папку +log-event-create-mkfile=Создал файл +log-event-create-upload=Загрузил файл +log-event-create-copy=Файл был создан путем вставки +log-event-create-mkdir-current=Здесь создана новая папка {0} +log-event-create-mkfile-current=Новый файл, созданный здесь {0} +log-event-create-upload-current=Выложено здесь {0} +log-event-create-copy-current=Вставил {0} сюда +log-event-create-mkdir-item=Создана новая папка в {0} {1} +log-event-create-mkfile-item=Новый файл создан в {0} {1} +log-event-create-upload-item=Загружено {1} в {0} +log-event-create-copy-item=Вставить {0} в {1} +log-event-create-mkdir-more=Здесь создано {0} папок +log-event-create-mkfile-more={0} новые файлы, созданные здесь +log-event-create-upload-more={0} файлы загружены здесь +log-event-create-copy-more=Вставил {0} файлы сюда +log-event-create-mkdir-more-at=Создано {1} новых папок в {0} +log-event-create-mkfile-more-at=Создано {1} новых файлов в {0} +log-event-create-upload-more-at={1} файлы загружены на {0} +log-event-create-copy-more-at=Вставил {0} документы в {1} +log-event-view-item=Просмотрено {0} +log-event-edit=обновил файл +log-event-edit-item=Правка обновлена {0} +log-event-edit-more=Редактировать обновленные {0} файлы +log-event-edit-more-user=Отредактировал и обновил файл {0} {1} раза +log-event-edit-more-at=Отредактировано и обновлено {1} файла в {0} +log-event-move=Переместите документ с {0} на {1} +log-event-move-item=Переместить {0} из {1} в [3] +log-event-move-current=Переместите {0} из {1} сюда +log-event-move-more={0} документ перемещен +log-event-move-more-desc=Переместите {0} из {1} в [3] +log-event-moveOut-more-desc=Удалено из {0} {1} +log-event-moveOut=Удалено отсюда {0} +log-event-moveOut-item=Удалено из {0} {1} +log-event-moveOut-more={0} документы удалены +log-event-share-shareLinkAdd=Создана внешняя ссылка, чтобы поделиться этим документом +log-event-share-shareLinkAdd-item={0} создал внешнюю ссылку, чтобы поделиться +log-event-share-shareLinkAdd-more=Создано {0} ссылок для обмена +log-event-share-shareToAdd=Включите совместный обмен этим документом +log-event-share-shareToAdd-item={0} включен совместный обмен +log-event-share-shareToAdd-more={0} созданы совместные акции +log-event-share-shareLinkRemove=Закрытый обмен ссылками документа +log-event-share-shareLinkRemove-item=Закрыто {0} обмен ссылками +log-event-share-shareLinkRemove-more=Закрыть {0} обмен внешними ссылками +log-event-share-shareToRemove=Отключить совместное использование этого документа +log-event-share-shareToRemove-item=Отключить совместное использование для {0} +log-event-share-shareToRemove-more=Закрыть {0} совместное использование +log-event-share-shareEdit=Отредактировал долю этого документа +log-event-share-shareEdit-item=Отредактировано {0} +log-event-share-shareEdit-more=Отредактировано {0} документов для обмена +log-event-rename=Переименовал документ +log-event-rename-item=Переименовано {0} +log-event-rename-more={0} документы переименованы +log-event-recycle-toRecycle=Переместил документ в корзину +log-event-recycle-toRecycle-current=Перемещено {0} в корзину здесь +log-event-recycle-toRecycle-item=Перемещено {1} в корзину на {0} +log-event-recycle-toRecycle-more={0} документы перемещены в корзину +log-event-recycle-toRecycle-more-at={1} документа перемещены в корзину {0} +log-event-recycle-restore=Восстановите документ из корзины +log-event-recycle-restore-item=Восстановить {0} из корзины +log-event-recycle-restore-more=Восстановить {0} документы из корзины +log-event-remove=Удалено {0} здесь +log-event-remove-current=Удалено {0} здесь +log-event-remove-item=Удалено {1} в {0} +log-event-remove-more={0} документы удалены здесь +log-event-remove-more-at=Удалено {1} документа по {0} +log-event-addDesc=Изменено описание документа +log-event-addDesc-item=Изменено {0} описание документа +log-event-addDesc-more=Модифицированные {0} описания документов +log-event-addComment=Прокомментировал этот документ +log-event-addComment-item=Прокомментировано {0} +log-event-addComment-more=Перечислено {1} комментариев в {0} +log-event-fav-fileAdd=В закладки {0} +log-event-fav-dirAdd=Папки с закладками {0} +log-event-down-item=Скачано {1} из {0} +log-event-down-items=Скачано из {0} +log-event-recycle-del-item=Удалить {0} файлы из корзины +log-event-recycle-rst-item=Восстановить {0} файлы из корзины +log-event-del-item={0} файлы удалены +log.file.move=Переместить / скопировать +log.file.fav=Избранные операции +log.file.shareLink=Обмен внешней ссылкой +log.file.shareTo=Совместное использование +log.user.edit=Изменить информацию об учетной записи +log.group.edit=Управление отделом +log.member.edit=Управление пользователями +log.role.edit=Управление ролями +log.auth.edit=Управление правами на документы +meta.user_sourceAlias=Связанные файлы (вложения) +meta.user_fileEncodeType=Конфиденциальность файла +meta.user_fileEncodeType.A=A-Совершенно секретно +meta.user_fileEncodeType.B=B конфиденциальный +meta.user_fileEncodeType.C=C-Secret +meta.user_sourceNumber=Номер тома +meta.user_sourceParticipant=участник +explorer.fileInfo.createTime=Дата создания +explorer.fileInfo.modifyTime=Дата изменения +explorer.fileInfo.softwareCreate=ПО для производства +explorer.fileInfo.software=Программное обеспечение для кодирования +explorer.fileInfo.playTime=Время игры +explorer.fileInfo.imageSize=размер картины +explorer.fileInfo.imageDpi=разрешение +explorer.fileInfo.imageBits=Битовая глубина +explorer.fileInfo.imageDesc=Аннотации +explorer.fileInfo.imageAuthor=создатель +explorer.fileInfo.imageColor=Цветовое пространство +explorer.fileInfo.cameraType=Модель устройства +explorer.fileInfo.cameraApertureFNumber=Номер апертуры +explorer.fileInfo.cameraApertureValue=Значение диафрагмы +explorer.fileInfo.cameraShutterSpeedValue=Скорость затвора +explorer.fileInfo.cameraExposureTime=Время воздействия +explorer.fileInfo.cameraFocalLength=фокусное расстояние +explorer.fileInfo.cameraFocusDistance=Расстояние фокусировки +explorer.fileInfo.cameraISOSpeedRatings=Чувствительность ISO +explorer.fileInfo.cameraWhiteBalance=баланс белого +explorer.fileInfo.cameraUser=Руководство по эксплуатации +explorer.fileInfo.cameraAuto=автоматический +explorer.fileInfo.cameraExposureMode=Режим экспозиции +explorer.fileInfo.cameraExposureBiasValue=Компенсация экспозиции +explorer.fileInfo.imageGps=Место съемки +explorer.fileInfo.imageCreateTime=Дата съемки +explorer.fileInfo.audioChannel=Аудио канал +explorer.fileInfo.audioChannel1=Мононуклеоз +explorer.fileInfo.audioChannel2=стерео +explorer.fileInfo.audioChannels=Многоканальный +explorer.fileInfo.audioRate=Частота дискретизации аудио +explorer.fileInfo.audioBits=Битовая глубина звука +explorer.fileInfo.audioBitrate=Битрейт аудио +explorer.fileInfo.vedioFormat=Кодирование видео +explorer.fileInfo.audioTitle=заглавие +explorer.fileInfo.audioAuthor=Автор +explorer.fileInfo.audioAlbum=Альбом +explorer.fileInfo.audioStyle=стиль +explorer.fileInfo.audioYear=Альбом год +explorer.fileInfo.vedioSize=Размер экрана +explorer.fileInfo.vedioFrame=Частота кадров видео +explorer.fileInfo.vedioBitrate=Битрейт видео +explorer.fileInfo.title=заглавие +explorer.fileInfo.author=Автор +explorer.fileInfo.pageTotal=всего страниц +explorer.fileInfo.pageSize=Размер страницы +explorer.fileInfo.pagePower=Создатель контента +explorer.fileInfo.pdfVersion=PDF версия +explorer.filter.shareCopyLimit=Количество файлов для дампа превышает лимит; максимальное количество файлов, которые вы можете сделать для дампа: +explorer.filter.shareSizeLimit=Размер общего файла превышает ограничение; максимальное количество файлов, которыми вы можете поделиться, составляет: +explorer.filter.unzipSizeLimit=Размер разархивированного файла превышает лимит; максимум, который вы можете разархивировать: +explorer.filter.zipSizeLimit=Размер сжатого файла превышает лимит; ваши максимально сжимаемые документы: +explorer.filter.uploadSizeLimit=Размер загружаемого файла превышает лимит; максимум, который вы можете загрузить, составляет: +explorer.fileEditError=Текущий файл %s редактируется, попробуйте позже  +explorer.groupDelError=Извините, но папка отдела не поддерживается для удаления.  +admin.info.typeDelError=Ошибка удаления, есть подкатегория или данные  +admin.info.domainIdentifyError=Сайт не распознается  +admin.info.articleIdentifyError=Статьи не распознаются  +admin.info.domainSupportError=Сайт пока не поддерживает сбор  +admin.info.fileTooLarge=Слишком большой файл  +explorer.toolbar.info=Информация +source.shareDisabled=Запрещается делиться ресурсами  +admin.exceeds.limit=Превышение ограничений  +admin.design.deleted=Невозможно удалить состояние активации  +admin.design.url.locked=Текущий URL заблокирован и временно недоступен  +explorer.SING_INVALID=Необычная подпись  +explorer.TEMP_AUTH_INVALID=Неправильный (недействительный) код временной лицензии  +explorer.QR_INVALID=QR - код не работает.  +explorer.toolbar.toolbox=Набор инструментов +explorer.toolbox.desc= +logs-detail-mkdir=Создана новая папка +logs-detail-mkfile=Создан новый документ +logs-detail-editFile=Редактирование обновлено. +logs-detail-upload=Загрузить файл +logs-detail-uploadNew=Изменить +logs-detail-file.upload= Загрузка. +logs-detail-file-copy=Вставить Создать файл +logs-detail-folder-copy=Вставить Создать папку +logs-detail-paste=Вставить +logs-detail-from= От +logs-detail-to= А +logs-detail-rename=Переименован. +logs-detail-rename-file=Переименовать файл +logs-detail-rename-folder=Переименовать папку +logs-detail-user=Пользователи: +logs-detail-moveFrom-restore=А +logs-detail-moveTo-restore=Восстановление со станции +logs-detail-move=А +logs-detail-moveTo=Перейти на +logs-detail-moveFrom-toRecycle=А +logs-detail-moveTo-toRecycle=Переехали на переработку. +logs-detail-file-toRecycle=Этот файл был перенесен в хранилище. +logs-detail-file-restore=Восстановление файла со станции +logs-detail-folder-toRecycle=Переместить папку в корзину +logs-detail-folder-restore=Восстановление папки из хранилища +logs-detail-favAdd=Коллекция. +logs-detail-favDel=Отмена коллекции. +logs-detail-unstar=Имя: +logs-detail-moveOut=Перенесено. +logs-detail-remove=Удалено +logs-detail-file.copy=Вставить +explorer.noPermissionAuthAll={0} ,Нет прав на эту операцию  \ No newline at end of file diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties new file mode 100644 index 0000000..d45bd61 --- /dev/null +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -0,0 +1,2566 @@ +admin.serverInfo=\u670d\u52a1\u5668\u4fe1\u606f +admin.today=\u4eca\u5929 +admin.yesterday=\u6628\u5929 +admin.weekDay=\u8fd17\u5929 +admin.monthDay=\u8fd130\u5929 +admin.ing=\u8fdb\u884c\u4e2d +admin.paused=\u5df2\u6682\u505c +admin.serverDownload=\u8fdc\u7a0b\u4e0b\u8f7d +admin.memberManage=\u7528\u6237\u7ba1\u7406 +admin.fileManage=\u6587\u4ef6\u7ba1\u7406 +admin.pwdEdit=\u4fee\u6539\u5bc6\u7801 +admin.fileEdit=\u7f16\u8f91\u4fdd\u5b58\u6587\u4ef6 +admin.list=\u5217\u8868\u67e5\u770b +admin.configError=\u914d\u7f6e\u4fdd\u5b58\u5931\u8d25\u7ba1\u7406\u5458\u7981\u6b62\u4e86\u6b64\u6743\u9650! +admin.userManage=\u4e2a\u4eba\u4e2d\u5fc3 +admin.manage=\u540e\u53f0\u7ba1\u7406 +admin.pluginManage=\u63d2\u4ef6\u7ba1\u7406 +admin.emailDear=%s,\u60a8\u597d, +admin.emailCodeText=\u60a8\u6b63\u5728\u8fdb\u884c\u90ae\u7bb1\u9a8c\u8bc1,\u672c\u6b21\u8bf7\u6c42\u7684\u9a8c\u8bc1\u7801\u5982\u4e0b,\u4e3a\u4e86\u4fdd\u969c\u60a8\u5e10\u53f7\u7684\u5b89\u5168\u6027,\u8bf7\u53ca\u65f6\u5b8c\u6210\u9a8c\u8bc1�� +admin.emailVerifyInTime=\u4e3a\u4e86\u4fdd\u969c\u60a8\u5e10\u53f7\u7684\u5b89\u5168\u6027,\u8bf7\u53ca\u65f6\u5b8c\u6210\u9a8c\u8bc1. +admin.dear=\u5c0a\u656c\u7684 +admin.dearUser=\u4eb2\u7231\u7684\u7528\u6237: +admin.emailResetLink=\u60a8\u6b63\u5728\u901a\u8fc7\u90ae\u7bb1\u91cd\u7f6e%s\u7684\u767b\u5f55\u5bc6\u7801,\u8bf7\u70b9\u51fb\u4e0b\u9762\u7684\u94fe\u63a5\u8fdb\u884c\u91cd\u7f6e��\u5982\u679c\u94fe\u63a5\u65e0\u6cd5\u8df3\u8f6c,\u8bf7\u5c06\u5176\u590d\u5236\u5230\u6d4f\u89c8\u5668\u7684\u5730\u5740\u680f\u8fdb\u884c\u8bbf\u95ee: +admin.emailExpireTime=\u8be5\u94fe\u63a520\u5206\u949f\u540e\u5931\u6548. +admin.jobName=\u5c97\u4f4d\u540d\u79f0 +admin.jobDesc=\u5c97\u4f4d\u8bf4\u660e +admin.jobNameInput=\u8bf7\u8f93\u5165\u5c97\u4f4d\u540d\u79f0 +admin.jobEdit=\u5c97\u4f4d\u7f16\u8f91 +admin.menu.home=\u9996\u9875 +admin.menu.dashboard=\u6982\u89c8 +admin.menu.dashboardTitle=\u6570\u636e\u7edf\u8ba1\u6982\u89c8 +admin.menu.notice=\u901a\u77e5\u7ba1\u7406 +admin.menu.groupMember=\u90e8\u95e8\u4e0e\u6210\u5458\u7ba1\u7406 +admin.menu.member=\u90e8\u95e8\u53ca\u7528\u6237 +admin.menu.role=\u89d2\u8272\u6743\u9650\u7ba1\u7406 +admin.menu.job=\u5c97\u4f4d\u7ba1\u7406 +admin.menu.auth=\u6587\u6863\u6743\u9650\u7ba1\u7406 +admin.menu.storage=\u5b58\u50a8/\u6587\u4ef6 +admin.menu.storageDriver=\u5b58\u50a8\u7ba1\u7406 +admin.menu.plugin=\u63d2\u4ef6\u4e2d\u5fc3 +admin.menu.tools=\u5b89\u5168\u7ba1\u63a7 +admin.menu.server=\u670d\u52a1\u5668\u7ba1\u7406 +admin.menu.backup=\u5907\u4efd\u7ba1\u7406 +admin.menu.share=\u5206\u4eab\u7ba1\u7406 +admin.menu.loginLog=\u767b\u5f55\u65e5\u5fd7 +admin.menu.log=\u64cd\u4f5c\u65e5\u5fd7 +admin.menu.task=\u8ba1\u5212\u4efb\u52a1 +admin.autoTask.restart=\u91cd\u542f\u8ba1\u5212\u4efb\u52a1 +admin.autoTask.restartEnd=\u8ba1\u5212\u4efb\u52a1\u5df2\u7ecf\u91cd\u542f +admin.index.userSpace=\u7528\u6237\u7a7a\u95f4 +admin.index.groupSpace=\u90e8\u95e8\u7a7a\u95f4 +admin.index.folderCount=\u6587\u4ef6\u5939\u6570: +admin.index.fileCount=\u6587\u4ef6\u6570: +admin.index.loginToday=\u4eca\u65e5\u767b\u5f55 +admin.index.useTotal=\u603b\u4f7f\u7528\u91cf: +admin.index.userLogin=\u7528\u6237\u767b\u5f55 +admin.index.spaceUsed=\u5360\u7528\u7a7a\u95f4 +admin.index.useSpace=\u4f7f\u7528\u7a7a\u95f4 +admin.index.usedSpace=\u5df2\u7528\u7a7a\u95f4 +admin.index.freeSpace=\u5269\u4f59\u7a7a\u95f4 +admin.index.sizeLimit=\u9650\u5b9a\u5927\u5c0f +admin.index.vipCount=\u6ce8\u518c\u7528\u6237 +admin.index.loginCurrent=\u5f53\u524d\u5728\u7ebf +admin.index.fileDel=\u6587\u4ef6\u5220\u9664 +admin.index.fileEdit=\u6587\u4ef6\u7f16\u8f91 +admin.index.fileUpload=\u6587\u4ef6\u4e0a\u4f20 +admin.index.fileDown=\u6587\u4ef6\u4e0b\u8f7d +admin.index.spaceUse=\u5b9e\u9645\u4f7f\u7528 +admin.index.spaceSave=\u8282\u7ea6\u7a7a\u95f4 +admin.index.spaceUser=\u7528\u6237\u4f7f\u7528 +admin.index.spaceGroup=\u90e8\u95e8\u4f7f\u7528 +admin.index.lastLogin=\u6700\u8fd1\u767b\u5f55\u65f6\u95f4 +admin.index.totalUsers=\u603b\u7528\u6237\u6570 +admin.index.loginUsers=\u767b\u5f55\u7528\u6237 +admin.index.spaceActUsed=\u5b9e\u9645\u5360\u7528 +admin.index.source=\u767b\u5f55\u6765\u6e90 +admin.index.address=\u767b\u5f55\u5730\u5740 +admin.index.userInfo=\u7528\u6237\u4fe1\u606f +admin.index.userValid=\u6fc0\u6d3b\u8d26\u53f7 +admin.index.userInvalid=\u7981\u7528\u8d26\u53f7 +admin.index.fileInfo=\u6587\u4ef6\u4fe1\u606f +admin.index.fileCnt=\u6587\u4ef6\u4e2a\u6570 +admin.index.fileAdd=\u4eca\u65e5\u65b0\u589e +admin.index.accInfo=\u8bbf\u95ee\u4fe1\u606f +admin.index.accCnt=\u8bf7\u6c42\u6b21\u6570 +admin.index.accUser=\u8bbf\u95ee\u7528\u6237 +admin.index.serverInfo=\u7cfb\u7edf\u4fe1\u606f +admin.index.serverDisk=\u7cfb\u7edf\u78c1\u76d8 +admin.index.serverStore=\u7f51\u76d8\u5b58\u50a8 +admin.index.serverName=\u670d\u52a1\u5668\u540d +admin.index.normal=\u6b63\u5e38 +admin.index.scoreDesc=\u4e0b\u5217\u56e0\u7d20\u5c06\u5f71\u54cd\u7cfb\u7edf\u8bc4\u5206,\u53ef\u81ea\u884c\u4f18\u5316,\u4ee5\u4fdd\u8bc1\u7cfb\u7edf\u826f\u597d\u8fd0\u884c:
    1.\u7cfb\u7edf\u78c1\u76d8,\u7f51\u76d8\u5b58\u50a8\u7684\u5269\u4f59\u7a7a\u95f4��
    2.\u6570\u636e\u7f13\u5b58\u65b9\u5f0f(\u63a8\u8350redis);
    3.php\u5e73\u53f0\u7248\u672c(\u63a8\u835064\u4f4dphp7+)�� +admin.index.fileRatio=\u6587\u4ef6\u4f7f\u7528\u5360\u6bd4 +admin.setting.system=\u7cfb\u7edf\u8bbe\u7f6e +admin.setting.account=\u8d26\u53f7\u8bbe\u7f6e +admin.setting.theme=\u4e3b\u9898\u8bbe\u7f6e +admin.setting.wall=\u58c1\u7eb8\u8bbe\u7f6e +admin.setting.stats=\u4f7f\u7528\u7edf\u8ba1 +admin.setting.safeMgt=\u5b89\u5168\u7ba1\u7406 +admin.setting.base=\u57fa\u7840\u8bbe\u7f6e +admin.setting.others=\u5176\u4ed6\u8bbe\u7f6e +admin.setting.sync=\u540c\u6b65\u8bbe\u7f6e +admin.setting.plugin=\u63d2\u4ef6\u8bbe\u7f6e +admin.setting.auth=\u6743\u9650\u8bbe\u7f6e +admin.setting.safe=\u5b89\u5168\u8bbe\u7f6e +admin.setting.loginLog=\u767b\u5f55\u65e5\u5fd7 +admin.setting.loginDevice=\u767b\u5f55\u8bbe\u5907 +admin.setting.deviceType=\u8bbe\u5907\u7c7b\u578b +admin.setting.lastLoginTime=\u6700\u8fd1\u767b\u5f55\u65f6\u95f4 +admin.setting.email=\u90ae\u7bb1\u8bbe\u7f6e +admin.setting.user=\u6ce8\u518c\u4e0e\u767b\u5f55 +admin.setting.pwdOld=\u539f\u5bc6\u7801 +admin.setting.pwdNew=\u4fee\u6539\u4e3a +admin.setting.wallDiy=\u81ea\u5b9a\u4e49\u58c1\u7eb8: +admin.setting.fav=\u6536\u85cf\u5939\u7ba1\u7406 +admin.setting.help=\u4f7f\u7528\u5e2e\u52a9 +admin.setting.about=\u5173\u4e8e\u4f5c\u54c1 +admin.setting.homePage=kodcloud \u4e3b\u9875 +admin.setting.subMenu=\u5b50\u83dc\u5355 +admin.setting.menuName=\u83dc\u5355\u540d +admin.setting.menuUrl=URL\u5730\u5740 +admin.setting.menuUrlDesc=url\u5730\u5740\u6216js\u4ee3\u7801 +admin.setting.safeAccount=\u8d26\u53f7\u53ca\u767b\u5f55\u5b89\u5168 +admin.setting.safeData=\u6570\u636e\u5b89\u5168/\u4f20\u8f93\u5b89\u5168 +admin.setting.passwordErrorLock=\u5bc6\u7801\u8f93\u5165\u9519\u8bef\u9501\u5b9a +admin.setting.passwordErrorLockDesc=\u8fde\u7eed5\u6b21\u5bc6\u7801\u9519\u8bef\u9501\u5b9a\u8be5\u8d26\u62371\u5206\u949f\u4e0d\u5141\u8bb8\u767b\u5f55\u5f00\u542f\u540e\u80fd\u6709\u6548\u9632\u6b62\u5bc6\u7801\u66b4\u529b\u7834\u89e3; +admin.setting.passwordRule=\u7528\u6237\u5bc6\u7801\u5f3a\u5ea6\u8bbe\u7f6e +admin.setting.passwordRuleDesc=\u6307\u5b9a\u5bc6\u7801\u5f3a\u5ea6\u540e\u53ef\u6709\u6548\u675c\u7edd\u5f31\u53e3\u4ee4 +admin.setting.passwordRuleNone=\u4e0d\u9650\u5236 +admin.setting.passwordRuleStrong=\u4e2d\u7b49\u5f3a\u5ea6 +admin.setting.passwordRuleStrongMore=\u9ad8\u5f3a\u5ea6 +admin.setting.passwordRuleNoneDesc=\u4e0d\u9650\u5236\u5bc6\u7801\u5f3a\u5ea6 +admin.setting.passwordRuleStrongDesc=\u957f\u5ea6\u5927\u4e8e6;\u5fc5\u987b\u540c\u65f6\u5305\u542b\u82f1\u6587\u548c\u6570\u5b57; +admin.setting.passwordRuleStrongMoreDesc=\u957f\u5ea6\u5927\u4e8e6;\u5fc5\u987b\u540c\u65f6\u5305\u542b\u6570\u5b57\u5927\u5199\u82f1\u6587\u5c0f\u5199\u82f1\u6587; +admin.setting.passwordRuleTips=\u60a8\u7684\u5f53\u524d\u5bc6\u7801\u5f3a\u5ea6\u4e0d\u8db3\u5efa\u8bae\u7acb\u5373\u4fee\u6539\u5bc6\u7801! +admin.loginCheck.menu=\u767b\u5f55\u7ba1\u63a7 +admin.loginCheck.ipCheck=IP\u9650\u5236 +admin.loginCheck.ipCheckNone=\u4e0d\u9650\u5236 +admin.loginCheck.ipCheckAllow=IP\u767d\u540d\u5355 +admin.loginCheck.ipCheckDisable=IP\u9ed1\u540d\u5355 +admin.loginCheck.loginIpAllowDesc=\u5f00\u542f\u540e\u53ea\u5141\u8bb8\u6307\u5b9aip\u7684\u7528\u6237\u624d\u80fd\u767b\u5f55\u8bf7\u8c28\u614e\u64cd\u4f5c +admin.loginCheck.ipAllow=\u5141\u8bb8\u7684IP +admin.loginCheck.ipAllowDesc=\u586b\u5199\u89c4\u5219\u5982\u4e0b (\u6bcf\u6761\u4e00\u884c\u9ed8\u8ba4\u5141\u8bb8\u670d\u52a1\u5668\u672c\u673aIP\u7cfb\u7edf\u7ba1\u7406\u5458\u5141\u8bb8\u5c40\u57df\u7f51IP) +admin.loginCheck.ipDisable=\u9ed1\u540d\u5355IP\u89c4\u5219 +admin.loginCheck.ipDisableDesc=\u5f00\u542f\u540e\u7b26\u5408ip\u6761\u4ef6\u7684\u7528\u6237\u5c06\u4e0d\u80fd\u505a\u4efb\u4f55\u64cd\u4f5c\u8bf7\u8c28\u614e\u5904\u7406!
    \u5982\u679c\u6307\u5b9a\u8bbe\u7f6e\u4e86\u6240\u6709\u4eba\u5219\u4f1a\u62e6\u622a\u6240\u6709\u8bf7\u6c42! +admin.loginCheck.ipDescTitle=\u586b\u5199\u89c4\u5219\u5982\u4e0b(\u6bcf\u6761\u4e00\u884c) +admin.loginCheck.ipDesc=
  • \u5b8c\u6574IP: \u76f8\u7b49\u5219\u5339\u914d \u4f8b\u5982:192.168.10.10
  • IP\u524d\u7f00: ip\u4ee5\u524d\u7f00\u4e3a\u5f00\u5934\u5219\u5339\u914d;\u4f8b\u5982:192.168
  • IP\u533a\u95f4\u6bb5: ip\u5728\u533a\u95f4\u5185\u5219\u5339\u914d;\u4f8b\u5982:192.168.1.1-192.168.200.255
  • +admin.loginCheck.sort=\u4f18\u5148\u7ea7 +admin.loginCheck.name=\u89c4\u5219\u540d\u79f0 +admin.loginCheck.user=\u6307\u5b9a\u7528\u6237 +admin.loginCheck.device=\u6307\u5b9a\u8bbe\u5907 +admin.loginCheck.deviceWeb=\u7f51\u9875\u7aef +admin.loginCheck.devicePc=PC\u7aef +admin.loginCheck.deviceAndroid=\u5b89\u5353 +admin.loginCheck.deviceIOS=\u82f9\u679c +admin.loginCheck.desc=
    \u5982\u679c\u60f3\u5f00\u542f\u6216\u5173\u95ed\u7ba1\u7406\u5458\u8bbf\u95ee\u5176\u4ed6\u76ee\u5f55\u53ef\u4ee5\u4fee\u6539php\u9632\u8de8\u7ad9open_basedir\u53c2\u6570\u5168\u90e8\u52a0\u5bc6: [\u9ed8\u8ba4\u63a8\u8350];\u5373\u4fbf\u62e5\u6709\u670d\u52a1\u5668\u6743\u9650\u4e5f\u65e0\u6cd5\u83b7\u77e5\u6587\u4ef6\u771f\u5b9e\u5185\u5bb9;\u80fd\u6709\u6548\u9632\u5fa1\u52d2\u7d22\u75c5\u6bd2\u7b49\u7834\u574f; +admin.setting.encodeNameDesc=\u4fdd\u7559\u6269\u5c55\u540d:\u6587\u4ef6\u540d\u52a0\u5bc6\u4fdd\u7559\u6269\u5c55\u540d +admin.setting.encodeNullDesc=\u4e0d\u52a0\u5bc6: \u4e0d\u5bf9\u6587\u4ef6\u540d\u8fdb\u884c\u52a0\u5bc6\u4fdd\u7559\u539f\u59cb\u6587\u4ef6\u540d;(\u4e3a\u786e\u4fdd\u5b89\u5168\u6027\u4e0a\u4f20\u6587\u4ef6\u5939\u540d\u4e3a\u52a0\u5bc6\u6784\u9020); +admin.setting.encodeTips1=\u4ec5\u5f71\u54cd\u8bbe\u7f6e\u66f4\u6539\u540e\u7684\u6587\u4ef6\u4e4b\u524d\u5df2\u5b58\u5728\u7684\u6587\u4ef6\u4e0d\u53d7\u5f71\u54cd; +admin.setting.encodeTips2=\u4e3a\u907f\u514d\u9519\u8bef\u8bf7\u52ff\u5bf9data/files\u4e2d\u7684\u6587\u4ef6\u8fdb\u884c\u5220\u9664\u6216\u91cd\u547d\u540d\u76f8\u5173\u64cd\u4f5c; +admin.setting.encodeTips3=\u4e3a\u652f\u6301\u5927\u89c4\u6a21\u5e76\u53d1\u79d2\u4f20\u96c6\u7fa4\u5206\u5e03\u5f0f\u81ea\u52a8\u6269\u5bb9\u7b49\u529f\u80fd;\u6587\u4ef6\u5939\u5c42\u7ea7\u7ed3\u6784\u8bb0\u5f55\u5728\u6570\u636e\u5e93\u4e2d;\u53ef\u4ee5\u901a\u8fc7\u590d\u5236\u7c98\u8d34\u5b9e\u73b0\u5bfc\u5165\u53ca\u8fd8\u539f\u6587\u4ef6\u5939\u7ed3\u6784; +admin.setting.thirdLogin=\u7b2c\u4e09\u65b9\u767b\u5f55 +admin.setting.thirdLoginDesc=\u5141\u8bb8\u901a\u8fc7\u7b2c\u4e09\u65b9\u8d26\u53f7\u8fdb\u884c\u6ce8\u518c,\u7ed1\u5b9a\u53ca\u767b\u5f55 +admin.setting.registOpen=\u5f00\u542f\u7528\u6237\u6ce8\u518c +admin.setting.registOpenDesc=\u4e3a\u907f\u514d\u6570\u636e\u51b2\u7a81,\u7b2c\u4e09\u65b9\u6570\u636e\u540c\u6b65\u548c\u7528\u6237\u6ce8\u518c\u4e0d\u80fd\u540c\u65f6\u542f\u7528 +admin.setting.registCheck=\u5f00\u542f\u6ce8\u518c\u5ba1\u6838 +admin.setting.registCheckDesc=\u5f00\u542f\u540e,\u9700\u8981\u7ba1\u7406\u5458\u5728[\u7528\u6237\u4e0e\u90e8\u95e8]\u4e2d\u5ba1\u6838\u5e76\u542f\u7528,\u6ce8\u518c\u7528\u6237\u624d\u80fd\u6b63\u5e38\u4f7f\u7528 +admin.setting.clearUserRecycle=\u6e05\u7a7a\u6240\u6709\u7528\u6237\u56de\u6536\u7ad9 +admin.setting.clearCache=\u6e05\u7a7a\u7f13\u5b58 +admin.setting.icp=\u7248\u6743\u6216\u5907\u6848\u53f7 +admin.setting.icpDesc=\u5982\u9700\u751f\u6210\u94fe\u63a5,\u53ef\u81ea\u884c\u6dfb\u52a0a\u6807\u7b7e +admin.setting.globalCss=\u81ea\u5b9a\u4e49\u5168\u5c40css +admin.setting.globalCssDesc=\u6240\u6709\u9875\u9762\u5c06\u4f1a\u63d2\u5165\u81ea\u5b9a\u4e49css +admin.setting.globalHtml=\u7edf\u8ba1\u4ee3\u7801 HTML +admin.setting.globalHtmlDesc=\u6240\u6709\u9875\u9762\u5c06\u63d2\u5165\u6b64\u6bb5html\u4ee3\u7801\u53ef\u4ee5\u653e\u7f6e\u7b2c\u4e09\u65b9\u7edf\u8ba1\u4ee3\u7801 +admin.setting.dateFormat=\u65e5\u671f\u683c\u5f0f +admin.setting.dateFormatDesc=\u5e74\u6708\u65e5\u65f6\u95f4\u683c\u5f0f\u663e\u793a\u6587\u4ef6\u4fee\u6539\u65f6\u95f4\u7b49\u5904\u4f53\u73b0 +admin.setting.menu=\u83dc\u5355\u7ba1\u7406 +admin.setting.systemName=\u516c\u53f8\u4ea7\u54c1\u540d +admin.setting.systemNameDesc=\u7528\u4e8e\u4ea7\u54c1logo\u6807\u9898 +admin.setting.systemDesc=\u4ea7\u54c1\u526f\u6807\u9898 +admin.setting.pathHidden=\u5217\u8868\u76ee\u5f55\u6392\u9664 +admin.setting.pathHiddenDesc=\u9ed8\u8ba4\u4e0d\u663e\u793a\u7684\u76ee\u5f55\u548c\u6587\u4ef6\u9017\u53f7\u9694\u5f00 +admin.setting.defaultFolder=\u65b0\u7528\u6237\u9ed8\u8ba4\u521b\u5efa\u76ee\u5f55 +admin.setting.defaultFolderDesc=\u7528\u9017\u53f7\u9694\u5f00 +admin.setting.defaultApp=\u65b0\u7528\u6237\u9ed8\u8ba4\u521b\u5efaapp +admin.setting.defaultAppDesc=\u5e94\u7528\u4e2d\u5fc3\u7684\u5e94\u7528,\u591a\u4e2a\u7528\u9017\u53f7\u9694\u5f00 +admin.setting.autoLogin=\u6e38\u5ba2\u81ea\u52a8\u767b\u5f55 +admin.setting.autoLoginDesc=\u9ed8\u8ba4\u767b\u5f55\u7528\u6237\u4e3aguest/guest\u7684\u7528\u6237��\u5f00\u542f\u540e\u786e\u4fdd\u8be5\u7528\u6237\u5b58\u5728 +admin.setting.firstIn=\u767b\u5f55\u540e\u9ed8\u8ba4\u8fdb\u5165 +admin.setting.registReviewOpen=\u5f00\u542f\u6ce8\u518c\u5ba1\u6838: +admin.setting.registRoleEmpty=\u89d2\u8272\u6743\u9650\u4e0d\u80fd\u4e3a\u7a7a +admin.setting.registNotSync=\u4e3a\u907f\u514d\u6570\u636e\u51b2\u7a81,\u7b2c\u4e09\u65b9\u6570\u636e\u540c\u6b65\u548c\u7528\u6237\u6ce8\u518c\u4e0d\u80fd\u540c\u65f6\u542f\u7528 +admin.setting.registNeedRewiew=\u5f00\u542f\u540e,\u9700\u8981\u7ba1\u7406\u5458\u5728\u7528\u6237\u4e0e\u90e8\u95e8\u4e2d\u5ba1\u6838\u5e76\u542f\u7528,\u6ce8\u518c\u7528\u6237\u624d\u80fd\u6b63\u5e38\u4f7f\u7528 +admin.setting.roleRight=\u89d2\u8272\u6743\u9650 +admin.setting.emailHost=\u90ae\u7bb1\u670d\u52a1\u5668 +admin.setting.emailHostInput=\u8bf7\u8f93\u5165\u90ae\u4ef6\u670d\u52a1\u5668\u5730\u5740 +admin.setting.emailHostTips=\u8bf7\u586b\u5199\u90ae\u4ef6\u670d\u52a1\u5668\u5730\u5740 +admin.setting.emailHostDesc=\u90ae\u7bb1\u670d\u52a1\u5668,\u5982:smtp.163.com,\u53ef\u81ea\u5b9a\u4e49\u7aef\u53e3(\u9ed8\u8ba4\u4e3a465) +admin.setting.emailSend=\u53d1\u4ef6\u90ae\u7bb1 +admin.setting.emailSendInput=\u8bf7\u8f93\u5165\u53d1\u9001\u90ae\u7bb1\u5730\u5740 +admin.setting.emailSendTips=\u8bf7\u586b\u5199\u53d1\u4ef6\u90ae\u7bb1\u5730\u5740 +admin.setting.emailSendDesc=\u7cfb\u7edf\u53d1\u4ef6\u90ae\u7bb1\u5730\u5740,\u9700\u5f00\u542fPOP3/SMTP\u670d\u52a1 +admin.setting.emailPwd=\u6388\u6743\u5bc6\u7801 +admin.setting.emailPwdTips=\u8bf7\u586b\u5199\u90ae\u7bb1\u6388\u6743\u5bc6\u7801 +admin.setting.secureType=\u52a0\u5bc6\u65b9\u5f0f +admin.setting.emailSendTest=\u53d1\u9001\u68c0\u6d4b +admin.setting.ensureEmailOk=\u8bf7\u786e\u4fdd\u90ae\u4ef6\u80fd\u6b63\u5e38\u53d1\u9001 +admin.setting.emailTo=\u6536\u4ef6\u90ae\u7bb1 +admin.setting.emailGoToTips=\u8bf7\u524d\u5f80\u90ae\u7bb1 +admin.setting.emailCheckTips=\u67e5\u770b +admin.setting.emailInputError=\u90ae\u7bb1\u8bbe\u7f6e\u586b\u5199\u6709\u8bef +admin.setting.emailPwdError=\u90ae\u7bb1\u8bbe\u7f6e\u5bc6\u7801\u586b\u5199\u6709\u8bef +admin.setting.emailDesc=\u8bbe\u7f6e\u90ae\u4ef6\u670d\u52a1\u5668,\u7528\u4e8e\u7528\u6237\u6ce8\u518c,\u5bc6\u7801\u627e\u56de\u90ae\u4ef6\u53d1\u9001 +admin.setting.sendEmail=\u53d1\u9001\u90ae\u4ef6 +admin.setting.sendEmailDesc=\u7cfb\u7edf\u9ed8\u8ba4:\u8c03\u7528\u53ef\u9053\u4e91\u90ae\u4ef6\u670d\u52a1\u5668\u53d1\u9001��\u81ea\u5b9a\u4e49:\u81ea\u884c\u914d\u7f6e\u90ae\u4ef6\u670d\u52a1\u5668 +admin.setting.systemBackup=\u7cfb\u7edf\u5907\u4efd +admin.setting.enableFunction=\u529f\u80fd\u53ca\u5f00\u5173 +admin.setting.treeOpen=\u6811\u76ee\u5f55\u529f\u80fd\u5f00\u5173 +admin.setting.treeOpenDesc=\u6587\u4ef6\u7ba1\u7406\u6811\u76ee\u5f55\u5bf9\u5e94\u529f\u80fd\u5168\u5c40\u5f00\u542f\u4e0e\u5173\u95ed +admin.setting.groupListChild=\u7f57\u5217\u5b50\u90e8\u95e8 +admin.setting.groupListChildDesc=\u90e8\u95e8\u6587\u4ef6\u5939\u662f\u5426\u663e\u793a\u5b50\u90e8\u95e8\u6743\u9650\u5411\u4e0a\u7ee7\u627f +admin.setting.groupRootListChild=\u4f01\u4e1a\u7f51\u76d8\u7f57\u5217\u5b50\u90e8\u95e8 +admin.setting.groupRootListChildDesc=\u4f01\u4e1a\u7f51\u76d8\u6587\u4ef6\u5939\u662f\u5426\u663e\u793a\u5b50\u90e8\u95e8\u6743\u9650\u5411\u4e0a\u7ee7\u627f +admin.setting.shareToMeAllowTree=\u4e0e\u6211\u534f\u4f5c-\u6309\u7ec4\u7ec7\u67b6\u6784\u663e\u793a +admin.setting.shareToMeAllowTreeTips=\u5f00\u542f\u540e\u4e0e\u6211\u534f\u4f5c\u7684\u5185\u5bb9\u652f\u6301\u6309\u90e8\u95e8\u7ec4\u7ec7\u67b6\u6784\u8fdb\u884c\u5206\u7c7b\u9002\u7528\u4e8e\u7ec4\u7ec7\u67b6\u6784\u6bd4\u8f83\u590d\u6742\u7684\u60c5\u51b5 +admin.setting.groupTagAllow=\u90e8\u95e8\u516c\u5171\u6807\u7b7e +admin.setting.groupTagAllowTips=\u542f\u7528\u540e\u90e8\u95e8\u5185\u6587\u4ef6\u8bbe\u7f6e\u516c\u5171\u6807\u7b7e\u540e\u6240\u6709\u90e8\u95e8\u6210\u5458\u53ef\u89c1. \u90e8\u95e8\u7ba1\u7406\u5458\u53ef\u4ee5\u7ef4\u62a4\u6807\u7b7e\u5185\u5bb9. +admin.setting.shareToMeList=\u5e73\u94fa\u663e\u793a +admin.setting.shareToMeGroup=\u6309\u7ec4\u7ec7\u67b6\u6784\u663e\u793a +admin.setting.shareToMeUser=\u6309\u5206\u4eab\u8005\u663e\u793a +admin.setting.sysSrvState=\u670d\u52a1\u5668\u72b6\u6001 +admin.setting.sysSrvInfo=\u670d\u52a1\u5668\u4fe1\u606f +admin.setting.sysPhpInfo=PHP\u4fe1\u606f +admin.setting.database=\u6570\u636e\u5e93 +admin.setting.cache=\u7f13\u5b58 +admin.setting.sysMyInfo=\u6211\u7684\u4fe1\u606f +admin.setting.srvStateCpu=CPU\u4f7f\u7528\u7387 +admin.setting.srvStateMem=\u5185\u5b58\u4f7f\u7528\u7387 +admin.setting.srvStateSrv=\u670d\u52a1\u5668\u7cfb\u7edf\u5b58\u50a8\u7a7a\u95f4 +admin.setting.srvStateDef=\u7f51\u76d8\u9ed8\u8ba4\u5b58\u50a8\u7a7a\u95f4 +admin.setting.srvInfoName=\u670d\u52a1\u5668\u540d +admin.setting.srvInfoIp=\u670d\u52a1\u5668IP +admin.setting.srvInfoTime=\u670d\u52a1\u5668\u65f6\u95f4 +admin.setting.srvInfoUpTime=\u6301\u7eed\u8fd0\u884c\u65f6\u95f4 +admin.setting.srvInfoWeb=\u670d\u52a1\u5668\u8f6f\u4ef6 +admin.setting.srvInfoPhpV=PHP\u7248\u672c +admin.setting.srvInfoSys=\u670d\u52a1\u5668\u7cfb\u7edf +admin.setting.srvInfoPath=\u7f51\u7ad9\u8def\u5f84 +admin.setting.srvPhpDtl=PHP\u8be6\u60c5 +admin.setting.memLimit=\u5185\u5b58\u9650\u5236 +admin.setting.postLimit=POST\u63d0\u4ea4\u9650\u5236 +admin.setting.uploadLimit=\u4e0a\u4f20\u6587\u4ef6\u9650\u5236 +admin.setting.execTime=\u6700\u5927\u6267\u884c\u65f6\u95f4 +admin.setting.inputTime=\u6700\u5927\u8bf7\u6c42\u65f6\u95f4 +admin.setting.disFunction=\u7981\u7528\u51fd\u6570 +admin.setting.phpExtSugst=\u63a8\u8350\u5b89\u88c5\u7684PHP\u6269\u5c55 +admin.setting.phpExtLoad=\u5df2\u52a0\u8f7d\u7684\u6269\u5c55 +admin.setting.myClientIp=\u6211\u7684IP +admin.setting.myClientUa=\u6211\u7684\u6d4f\u89c8\u5668UA +admin.setting.myClientLng=\u6211\u7684\u6d4f\u89c8\u5668\u8bed\u8a00 +admin.setting.disFuncDesc=\u7cfb\u7edf\u6240\u9700\u51fd\u6570,\u5efa\u8bae\u5f00\u542f +admin.setting.srvMemFree=\u5269\u4f59\u5185\u5b58 +admin.setting.srvMemUse=\u4f7f\u7528\u5185\u5b58 +admin.setting.srvCpuUse=\u5f53\u524d\u5360\u7528 +admin.setting.srvCpuFree=\u672a\u4f7f\u7528 +admin.setting.noLimit=\u65e0\u9650\u5236 +admin.setting.disFunNo=\u65e0 +admin.setting.systemCache=\u7cfb\u7edf\u7f13\u5b58 +admin.setting.systemDb=\u7cfb\u7edf\u6570\u636e\u5e93 +admin.setting.sysCacheTab=\u7f13\u5b58\u5207\u6362 +admin.setting.sysDbTab=\u6570\u636e\u5e93\u5207\u6362 +admin.setting.sysRecTab=\u6570\u636e\u5e93\u6062\u590d +admin.setting.cacheDesc=\u7f13\u5b58\u8bf4\u660e +admin.setting.fileCacheDesc=\u6587\u4ef6\u7f13\u5b58:\u5c06\u6570\u636e\u76f4\u63a5\u5199\u5165\u5230\u7f13\u5b58\u6587\u4ef6,\u9002\u7528\u4e8e\u6d4b\u8bd5\u6216\u5c0f\u89c4\u6a21\u4f7f\u7528�� +admin.setting.redisDesc=Redis:\u4e00\u4e2a\u9ad8\u6027\u80fd\u7684key-value\u975e\u5173\u7cfb\u578b\u6570\u636e\u5e93,\u9002\u7528\u4e8e\u9ad8\u5e76\u53d1\u8bfb\u5199\u7684\u60c5\u51b5��\u63a8\u8350\u4f7f\u7528�� +admin.setting.memcachedDesc=Memcached:\u4e00\u4e2a\u9ad8\u6027\u80fd\u7684\u5206\u5e03\u5f0f\u5185\u5b58\u5bf9\u8c61\u7f13\u5b58\u7cfb\u7edf,\u9002\u7528\u4e8e\u9ad8\u5e76\u53d1\u8bfb\u53d6\u7684\u60c5\u51b5�� +admin.setting.saveAfterTest=\u68c0\u6d4b\u901a\u8fc7\u540e,\u65b9\u53ef\u8fdb\u884c\u4fdd\u5b58 +admin.setting.checkPassed=\u68c0\u6d4b\u901a\u8fc7 +admin.setting.ifSaveCache=\u5207\u6362\u540e,\u7f13\u5b58\u6570\u636e\u5c06\u5168\u90e8\u88ab\u6e05\u9664!
    \u786e\u5b9a\u8981\u6267\u884c\u5417? +admin.setting.ifSaveDb=\u6570\u636e\u5e93\u5207\u6362,\u4f1a\u5c06\u7cfb\u7edf\u5f53\u524d\u7684\u6570\u636e\u5bfc\u5165\u81f3\u65b0\u7684\u6570\u636e\u5e93,\u5e76\u5c06\u5176\u8bbe\u4e3a\u9ed8\u8ba4��\u786e\u5b9a\u8981\u6267\u884c\u5417? +admin.setting.dbCurrent=\u5f53\u524d\u914d\u7f6e +admin.setting.dbType=\u6570\u636e\u5e93\u7c7b\u578b +admin.setting.dbName=\u6570\u636e\u5e93\u540d\u79f0 +admin.setting.dbInfo=\u6570\u636e\u5e93\u4fe1\u606f +admin.setting.dbSwitch=\u5f00\u542f\u5207\u6362 +admin.setting.dbSwitchDesc=\u5f00\u542f\u540e,\u53ef\u6839\u636e\u9700\u8981\u66f4\u6539\u6570\u636e\u5e93\u7c7b\u578b,\u8bf7\u8c28\u614e\u64cd\u4f5c�� +admin.setting.dbTable=\u6570\u636e\u8868 +admin.setting.dbCnt=\u603b\u8bb0\u5f55\u6570 +admin.setting.dbNeedNew=\u6570\u636e\u5e93\u5df2\u5b58\u5728,\u8bf7\u91cd\u65b0\u6307\u5b9a +admin.setting.dbInsertError=\u8868\u6570\u636e\u5199\u5165\u5931\u8d25 +admin.setting.dbNeedOthers=\u8bf7\u9009\u62e9\u5176\u4ed6\u6570\u636e\u5e93\u7c7b\u578b +admin.setting.dbNeedChange=\u8bf7\u4fee\u6539\u914d\u7f6e\u53c2\u6570 +admin.setting.dbCreateError=\u6570\u636e\u5e93\u6587\u4ef6\u521b\u5efa\u5931\u8d25,\u8bf7\u68c0\u67e5\u76ee\u5f55\u8bfb\u5199\u6743\u9650 +admin.setting.dbTaskProcess=\u6267\u884c\u8fdb\u5ea6 +admin.setting.dbTasking=\u6b63\u5728\u6267\u884c +admin.setting.dbTaskDesc=\u8bf7\u52ff\u5173\u95ed\u7a97\u53e3,\u6216\u5728\u7cfb\u7edf\u4e2d\u8fdb\u884c\u5176\u4ed6\u64cd\u4f5c,\u907f\u514d\u4ea7\u751f\u5dee\u5f02\u6027\u6570\u636e�� +admin.setting.recTaskDesc=\u8bf7\u52ff\u5173\u95ed\u7a97\u53e3,\u8bf7\u6c42\u4e2d\u65ad\u540e,\u540e\u53f0\u8fd8\u5c06\u7ee7\u7eed\u6267\u884c\u76f4\u81f3\u4efb\u52a1\u7ed3\u675f�� +admin.setting.dbCreate=\u65b0\u5efa\u6570\u636e\u5e93 +admin.setting.dbSelect=\u8bfb\u53d6\u6570\u636e\u5e93 +admin.setting.dbInsert=\u5199\u5165\u6570\u636e\u5e93 +admin.setting.dbSetSave=\u4fdd\u5b58\u914d\u7f6e\u4fe1\u606f +admin.setting.recDesc=\u4f7f\u7528\u8bf4\u660e +admin.setting.recDescInfo11=\u672c\u64cd\u4f5c\u5c06\u4f1a\u91cd\u7f6e\u7cfb\u7edf\u6570\u636e,\u975e\u8fd0\u7ef4\u6216\u76f8\u5173\u6280\u672f\u4eba\u5458\u8bf7\u52ff\u64cd\u4f5c! +admin.setting.recDescInfo21=\u901a\u8fc7\u5c06\u5907\u4efd\u6570\u636e\u5e93\u5199\u5165\u81f3\u65b0\u7684\u6570\u636e\u5e93,\u5e76\u5c06\u5176\u8bbe\u4e3a\u7cfb\u7edf\u9ed8\u8ba4,\u5b9e\u73b0\u6570\u636e\u7684\u6062\u590d�� +admin.setting.recDescInfo22= +admin.setting.recDescInfo23=\u672c\u529f\u80fd\u4ec5\u652f\u6301\u5904\u7406\u7531\u7cfb\u7edf\u5907\u4efd\u7ba1\u7406\u4ea7\u751f\u7684\u5907\u4efd\u6570\u636e,\u81ea\u884c\u5907\u4efd\u7684\u6570\u636e\u5e93\u8bf7\u901a\u8fc7\u5176\u4ed6\u65b9\u5f0f\u5904\u7406�� +admin.setting.recDescInfo31=\u6ce8\u610f:\u6570\u636e\u5e93\u7c7b\u578b\u4e3aMySQL\u65f6,\u4f1a\u6839\u636e\u5f53\u524d\u914d\u7f6e\u4fe1\u606f\u521b\u5efa\u65b0\u7684\u5e93(\u539f\u5e93\u540d_\u5f53\u524d\u65e5\u671f_rebuild),\u975eroot\u7528\u6237\u53ef\u80fd\u6743\u9650\u4e0d\u8db3,\u9700\u5148\u7ed9\u7528\u6237\u8bbe\u7f6e\u6743\u9650�� +admin.setting.recDescInfo32= +admin.setting.recDescInfo33=\u8bbe\u7f6e\u6743\u9650: +admin.setting.recDescInfo34=\u64a4\u9500\u6743\u9650: +admin.setting.recOpen=\u5f00\u542f\u6062\u590d +admin.setting.recOpenDesc=\u5f00\u542f\u540e,\u53ef\u6839\u636e\u9700\u8981\u9009\u62e9\u5907\u4efd\u7684\u6570\u636e\u5e93\u8fdb\u884c\u6062\u590d,\u8bf7\u8c28\u614e\u64cd\u4f5c�� +admin.setting.recTypeDesc=\u53d6\u51b3\u4e8e\u7cfb\u7edf\u5f53\u524d\u4f7f\u7528\u7684\u7c7b\u578b +admin.setting.recPath=\u6570\u636e\u5e93\u5907\u4efd\u76ee\u5f55 +admin.setting.recPathErr=\u65e0\u6548\u7684\u6570\u636e\u5e93\u5907\u4efd\u76ee\u5f55 +admin.setting.ifSaveRec=\u6570\u636e\u5e93\u6062\u590d,\u4f1a\u5c06\u5907\u4efd\u6570\u636e\u5bfc\u5165\u81f3\u65b0\u7684\u6570\u636e\u5e93,\u5e76\u5c06\u5176\u8bbe\u4e3a\u9ed8\u8ba4��
    \u786e\u5b9a\u8981\u6267\u884c\u5417? +admin.setting.recDiyPathErr=\u4f7f\u7528\u81ea\u884c\u5907\u4efd\u6062\u590d\u65f6,\u8bf7\u9009\u62e9\u5907\u4efd\u7684\u6570\u636e\u5e93\u6587\u4ef6 +admin.setting.recDiyFileNull=\u6570\u636e\u5e93\u6587\u4ef6\u4e3a\u7a7a +admin.setting.recDiyPhpErr= +admin.setting.recDiySqlErr=\u81ea\u884c\u5907\u4efd\u7684MySQL,\u8bf7\u9009\u62e9\u683c\u5f0f\u4e3asql\u7684\u6570\u636e\u5e93\u6587\u4ef6 +admin.setting.recSysPathErr=\u4f7f\u7528\u5907\u4efd\u7ba1\u7406\u6062\u590d\u65f6,\u8bf7\u9009\u62e9\u5907\u4efd\u7684\u6570\u636e\u5e93\u76ee\u5f55 +admin.setting.recSysTbErr=\u6570\u636e\u5e93\u5907\u4efd\u76ee\u5f55\u65e0\u6548,\u6216\u6570\u636e\u5e93\u7ed3\u6784\u6587\u4ef6\u7f3a\u5931 +admin.setting.recDbFileErr=\u9009\u62e9\u7684\u5e93\u6587\u4ef6\u4e0e\u7cfb\u7edf\u4e0d\u5339\u914d,\u6216\u7f3a\u5c11\u6709\u6548\u7684\u6570\u636e\u8868 +admin.setting.dbFileDown=\u8bfb\u53d6\u5e93\u6587\u4ef6 +admin.setting.dbFileDownErr=\u8bfb\u53d6\u5e93\u6587\u4ef6\u5931\u8d25 +admin.notice.waiting=\u7b49\u5f85\u63a8\u9001 +admin.notice.done=\u5df2\u63a8\u9001 +admin.notice.time=\u63a8\u9001\u65f6\u95f4 +admin.notice.target=\u63a8\u9001\u5bf9\u8c61 +admin.notice.level=\u63d0\u793a\u7ea7\u522b +admin.notice.level0=\u5f31\u63d0\u793a +admin.notice.level1=\u5f3a\u63d0\u793a +admin.notice.levelDesc=\u5f31\u63d0\u793a:\u5de6\u4e0b\u89d2\u901a\u77e5\u680f\u663e\u793a\u7ea2\u70b9��\u5f3a\u63d0\u793a:\u7528\u6237\u767b\u5f55\u540e\u76f4\u63a5\u5f39\u51fa\u901a\u77e5�� +admin.notice.targetAuth=\u9009\u62e9\u63a8\u9001\u7ed9\u6240\u6709\u4eba,\u6216\u63a8\u9001\u7ed9\u6307\u5b9a\u7528\u6237,\u7528\u6237\u7ec4,\u6743\u9650\u7ec4 +admin.notice.title=\u6d88\u606f\u6807\u9898 +admin.notice.content=\u6d88\u606f\u5185\u5bb9 +admin.notice.timeType=\u63a8\u9001\u65b9\u5f0f +admin.notice.timeNow=\u7acb\u5373\u63a8\u9001 +admin.notice.timePlan=\u8ba1\u5212\u63a8\u9001 +admin.notice.listTitle=\u7ad9\u5185\u6d88\u606f\u901a\u77e5 +admin.notice.clearAll=\u6e05\u7a7a\u5168\u90e8 +admin.notice.noMsg=\u6682\u65e0\u6d88\u606f +admin.notice.ifClearAll=\u786e\u5b9a\u8981\u6e05\u7a7a\u5168\u90e8\u6d88\u606f\u5417? +admin.group.role=\u89d2\u8272\u8eab\u4efd +admin.group.name=\u90e8\u95e8\u540d\u79f0 +admin.group.parent=\u4e0a\u7ea7\u90e8\u95e8 +admin.group.authShow=\u8be5\u90e8\u95e8\u6210\u5458\u53ef\u89c1\u7684\u7ec4\u7ec7\u67b6\u6784\u8303\u56f4 +admin.group.authShowAll=\u6240\u6709\u90e8\u95e8 +admin.group.authShowHide=\u4ec5\u672c\u90e8\u95e8\u53ca\u5b50\u90e8\u95e8 +admin.group.authShowSelect=\u6307\u5b9a\u90e8\u95e8 +admin.group.authShowAllTips=\u8be5\u90e8\u95e8\u6210\u5458\u534f\u4f5c\u5206\u4eab\u65f6\u53ef\u4ee5\u9009\u62e9\u5176\u4ed6\u6240\u6709\u90e8\u95e8(\u53ca\u7528\u6237) +admin.group.authShowHideTips=\u8be5\u90e8\u95e8\u6210\u5458\u534f\u4f5c\u5206\u4eab\u65f6\u4ec5\u652f\u6301\u9009\u62e9\u5f53\u524d\u90e8\u95e8\u53ca\u5b50\u90e8\u95e8(\u53ca\u7528\u6237) +admin.group.authShowSelectTips=\u8be5\u90e8\u95e8\u6210\u5458\u534f\u4f5c\u5206\u4eab\u65f6\u53ef\u4ee5\u9009\u62e9\u6307\u5b9a\u7684\u90e8\u95e8\u53ca\u5b50\u90e8\u95e8(\u53ca\u7528\u6237)\u5305\u542b\u5f53\u524d\u90e8\u95e8\u53ca\u5b50\u90e8\u95e8 +admin.group.addSub=\u6dfb\u52a0\u5b50\u90e8\u95e8 +admin.group.remove=\u5220\u9664\u90e8\u95e8 +admin.group.switch=\u8fc1\u79fb\u90e8\u95e8 +admin.group.swtichDesc=\u5c06\u6240\u9009\u90e8\u95e8(\u53ca\u5176\u5b50\u90e8\u95e8)\u4e0b\u7684\u7528\u6237\u548c\u6587\u4ef6,\u8fc1\u79fb\u81f3\u76ee\u6807\u90e8\u95e8�� +admin.group.switchSameError=\u76ee\u6807\u90e8\u95e8\u4e0d\u80fd\u4e0e\u5df2\u9009\u90e8\u95e8\u76f8\u540c +admin.group.switching=\u6b63\u5728\u8fc1\u79fb,\u8bf7\u7a0d\u5019... +admin.group.groupSwitching=\u6240\u9009\u90e8\u95e8\u6b63\u5728\u8fc1\u79fb\u4e2d +admin.group.parentNullError=\u4e0a\u7ea7\u90e8\u95e8\u4e0d\u80fd\u4e3a\u7a7a +admin.group.selected=\u5df2\u9009\u90e8\u95e8 +admin.group.setSizeBatch=\u6279\u91cf\u8bbe\u7f6e\u7a7a\u95f4\u5927\u5c0f +admin.group.multiSelect=\u53ef\u9009\u62e9\u591a\u4e2a\u90e8\u95e8\u8fdb\u884c\u6279\u91cf\u8bbe\u7f6e +admin.group.ifDisAll=\u6240\u6709\u5b50\u90e8\u95e8\u90fd\u5c06\u88ab\u7981\u7528,\u786e\u5b9a\u8981\u6267\u884c\u5417? +admin.member.manage=\u7528\u6237\u4e0e\u90e8\u95e8 +admin.member.add=\u65b0\u5efa\u7528\u6237 +admin.member.role=\u89d2\u8272\u6743\u9650 +admin.member.group=\u6240\u5728\u90e8\u95e8 +admin.member.groupAdd=\u6dfb\u52a0\u90e8\u95e8 +admin.member.groupEdit=\u7f16\u8f91\u90e8\u95e8 +admin.member.remove=\u5220\u9664\u7528\u6237 +admin.member.import=\u6279\u91cf\u6dfb\u52a0 +admin.member.enable=\u542f\u7528 +admin.member.batchSet=\u6279\u91cf\u64cd\u4f5c +admin.member.groupRemove=\u4ece\u90e8\u95e8\u79fb\u9664 +admin.member.groupInsert=\u6dfb\u52a0\u5230\u90e8\u95e8 +admin.member.groupSwitch=\u8fc1\u79fb\u5230\u90e8\u95e8 +admin.member.groupTarget=\u76ee\u6807\u90e8\u95e8 +admin.member.groupReset=\u91cd\u7f6e\u90e8\u95e8 +admin.member.groupSwtichDesc=\u5c06\u6240\u9009\u7528\u6237\u4ece\u5f53\u524d\u6240\u5728\u90e8\u95e8\u8fc1\u79fb\u81f3\u76ee\u6807\u90e8\u95e8 +admin.member.roleSet=\u89d2\u8272\u6743\u9650\u8bbe\u7f6e +admin.member.sizeSet=\u7a7a\u95f4\u5927\u5c0f\u8bbe\u7f6e +admin.member.name=\u767b\u5f55\u8d26\u53f7 +admin.member.nickName=\u7528\u6237\u6635\u79f0 +admin.member.userInfo=\u7528\u6237\u4fe1\u606f +admin.member.userImport=\u6279\u91cf\u5bfc\u5165\u7528\u6237 +admin.member.uploadFirst=\u8bf7\u5148\u4e0a\u4f20\u6587\u4ef6 +admin.member.downTpl=\u4e0b\u8f7d\u6a21\u677f +admin.member.downTplDesc=,\u8bf7\u6309\u7167\u6a21\u677f\u683c\u5f0f\u586b\u5199\u540e\u4e0a\u4f20�� +admin.member.uploadInvalid=\u4e0a\u4f20\u6587\u4ef6\u4e2d\u65e0\u6709\u6548\u6570\u636e,\u8bf7\u68c0\u67e5\u540e\u91cd\u65b0\u4e0a\u4f20 +admin.member.uploadDataInvalid=\u4e0a\u4f20\u6570\u636e\u65e0\u6548\u6216\u5df2\u8fc7\u671f,\u8bf7\u91cd\u65b0\u4e0a\u4f20 +admin.member.importSuccess=\u5bfc\u5165\u5b8c\u6210 +admin.member.importFail=\u5bfc\u5165\u5931\u8d25 +admin.member.importFailDesc=\u6210\u529f:{0} \u5931\u8d25: {1} +admin.member.importName=\u767b\u5f55\u8d26\u53f7(\u5fc5\u586b,\u552f\u4e00) +admin.member.importNickName=\u6635\u79f0(\u552f\u4e00) +admin.member.importPwd=\u5bc6\u7801(\u5fc5\u586b) +admin.member.importSex=\u6027\u522b(\u7537-1\u5973-0) +admin.member.importPhone=\u624b\u673a\u53f7(\u552f\u4e00) +admin.member.importEmail=\u90ae\u7bb1(\u552f\u4e00) +admin.member.groupRemoveTips=\u5220\u9664\u540e\u8be5\u7528\u6237\u7ec4\u7528\u6237\u65e0\u6cd5\u767b\u5f55
    (\u9700\u8981\u91cd\u65b0\u8bbe\u7f6e\u7528\u6237\u7ec4),\u786e\u5b9a\u8981\u7ee7\u7eed\u5417? +admin.member.memberRemoveTips=\u5220\u9664\u540e,\u7528\u6237\u76ee\u5f55\u5c06\u79fb\u81f3\u7cfb\u7edf\u56de\u6536\u7ad9,
    \u786e\u5b9a\u8981\u7ee7\u7eed\u5417? +admin.member.selectUserTips=\u8bf7\u9009\u62e9\u8981\u64cd\u4f5c\u7684\u8d26\u53f7 +admin.member.ifRemoveGroup=\u786e\u5b9a\u5c06\u6240\u9009\u7528\u6237\u4ece\u8be5\u7ec4\u79fb\u9664? +admin.member.importDesc=\u6bcf\u884c\u4e00\u4e2a\u7528\u6237
    \u5df2\u5b58\u5728\u5219\u81ea\u52a8\u5ffd\u7565 +admin.member.roleAdminTips=\u5907\u6ce8:\u7cfb\u7edf\u7ba1\u7406\u5458\u4e0d\u53d7\u6743\u9650\u63a7\u5236 +admin.member.space=\u8bbe\u7f6e\u7528\u6237\u7a7a\u95f4\u5927\u5c0f +admin.member.spaceTips=0\u5219\u4e0d\u9650\u5236 +admin.member.spaceTipsDefault=(GB) 0\u5219\u4e0d\u9650\u5236 +admin.member.spaceTipsFull=\u4e0d\u9650\u5236 +admin.member.spaceSize=\u7a7a\u95f4\u5927\u5c0f +admin.member.spaceSizeUse=\u7a7a\u95f4\u4f7f\u7528 +admin.member.memberAdd=\u6dfb\u52a0\u7528\u6237 +admin.member.allAdd=\u6dfb\u52a0\u7528\u6237\u6216\u90e8\u95e8 +admin.member.nullNotUpdate=\u4e0d\u586b\u5219\u4e0d\u4fee\u6539 +admin.member.search=\u641c\u7d22\u7528\u6237(\u8d26\u53f7/\u6635\u79f0/\u90ae\u7bb1/\u7535\u8bdd) +admin.member.searchUser=\u641c\u7d22\u7528\u6237(\u652f\u6301\u62fc\u97f3\u53ca\u6a21\u7cca\u5339\u914d) +admin.member.searchGroup=\u641c\u7d22\u90e8\u95e8(\u652f\u6301\u62fc\u97f3\u53ca\u6a21\u7cca\u5339\u914d) +admin.member.searchAll=\u641c\u7d22\u7528\u6237\u6216\u90e8\u95e8(\u652f\u6301\u62fc\u97f3\u53ca\u6a21\u7cca\u5339\u914d) +admin.member.editNoAuth=\u62b1\u6b49\u60a8\u6ca1\u6709\u8be5\u6743\u9650
    \u53ea\u6709\u7cfb\u7edf\u7ba1\u7406\u5458\u624d\u80fd\u6dfb\u52a0\u4fee\u6539\u7cfb\u7edf\u7ba1\u7406\u5458 +admin.member.disabledUsers=\u5df2\u7981\u7528\u8d26\u53f7 +admin.member.disabledTips=\u5207\u6362\u90e8\u95e8\u4ee5\u53d6\u6d88\u9009\u4e2d +admin.member.userGroup=\u7528\u6237\u90e8\u95e8 +admin.member.userRole=\u7528\u6237\u89d2\u8272 +admin.member.userSelected=\u5df2\u9009\u7528\u6237 +admin.member.authCopy=\u90e8\u95e8\u6743\u9650\u590d\u5236 +admin.member.authPaste=\u90e8\u95e8\u6743\u9650\u7c98\u8d34 +admin.member.ifAuthPaste=\u786e\u5b9a\u8981\u5c06\u5df2\u590d\u5236\u7684\u90e8\u95e8\u6743\u9650,\u8bbe\u7f6e\u7ed9\u5f53\u524d\u7528\u6237\u5417? +ERROR_USER_NOT_EXISTS=\u7528\u6237\u4e0d\u5b58\u5728 +ERROR_USER_PASSWORD_ERROR=\u5bc6\u7801\u9519\u8bef +ERROR_USER_EXIST_NAME=\u7528\u6237\u540d\u5df2\u5b58\u5728 +ERROR_USER_EXIST_PHONE=\u624b\u673a\u53f7\u5df2\u5b58\u5728 +ERROR_USER_EXIST_EMAIL=\u8be5\u90ae\u7bb1\u5df2\u5b58\u5728 +ERROR_USER_EXIST_NICKNAME=\u6635\u79f0\u5df2\u5b58\u5728 +ERROR_USER_LOGIN_LOCK=\u62b1\u6b49\u5bc6\u7801\u5c1d\u8bd5\u8f93\u5165\u9519\u8bef\u8fc7\u591a\u5f53\u524d\u8d26\u53f7\u5df2\u9501\u5b9a\u8bf71\u5206\u949f\u540e\u518d\u8bd5! +ERROR_IP_NOT_ALLOW=\u60a8\u5f53\u524dIP\u6216\u8bbf\u95ee\u8bbe\u5907\u4e0d\u5141\u8bb8\u767b\u5f55\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! +user.passwordCheckError=\u5bc6\u7801\u683c\u5f0f\u4e0d\u7b26\u5408\u5bc6\u7801\u5f3a\u5ea6\u89c4\u5219! +admin.role.administrator=\u7cfb\u7edf\u7ba1\u7406\u5458 +admin.role.group=\u90e8\u95e8\u7ba1\u7406\u5458 +admin.role.default=\u666e\u901a\u7528\u6237 +admin.role.ignoreExt=\u6269\u5c55\u540d\u9650\u5236 +admin.role.ignoreExtDesc=\u4e0d\u5141\u8bb8\u4e0a\u4f20\u7684\u6587\u4ef6\u7c7b\u578b\u4e3a\u7a7a\u5219\u4e0d\u9650\u5236 +admin.role.ignoreFileSize=\u4e0a\u4f20\u6587\u4ef6\u5927\u5c0f\u9650\u5236 +admin.role.ignoreFileSizeDesc=\u5141\u8bb8\u5355\u4e2a\u6587\u4ef6\u4e0a\u4f20\u6700\u5927\u503c0\u5219\u4e0d\u9650\u5236 +admin.role.ignoreExtTips=\u62b1\u6b49\u5f53\u524d\u7cfb\u7edf\u8bbe\u7f6e\u4e0d\u652f\u6301\u8be5\u7c7b\u578b\u6587\u4ef6\u4e0a\u4f20;\u5177\u4f53\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! +admin.role.ignoreFileSizeTips=\u62b1\u6b49\u5f53\u6587\u4ef6\u8d85\u51fa\u5927\u5c0f\u9650\u5236;\u5177\u4f53\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! +admin.role.desc=\u89d2\u8272\u63cf\u8ff0 +admin.role.adminDesc=\u8d85\u7ea7\u7ba1\u7406\u5458\u62e5\u6709\u670d\u52a1\u5668\u7ba1\u7406\u6743\u9650;\u6240\u6709\u6587\u4ef6\u6587\u4ef6\u5939\u8bbe\u7f6e\u6743\u9650\u5bf9\u8be5\u7528\u6237\u65e0\u6548! +admin.role.read=\u8bfb\u53d6 +admin.role.readList=\u6587\u4ef6\u5217\u8868 +admin.role.readInfo=\u6587\u4ef6(\u5939)\u5c5e\u6027\u67e5\u770b\u6587\u4ef6\u5939\u641c\u7d22 +admin.role.readCopy=\u6587\u4ef6\u590d\u5236 +admin.role.readPreview=\u6587\u4ef6\u9884\u89c8(\u56fe\u7247\u6587\u6863\u97f3\u89c6\u9891\u7b49) +admin.role.readDownload=\u6587\u4ef6(\u5939)\u4e0b\u8f7d +admin.role.write=\u5199\u5165 +admin.role.writeAdd=\u521b\u5efa\u6587\u4ef6(\u5939)\u538b\u7f29\u89e3\u538b\u6587\u4ef6 +admin.role.writeChange=\u91cd\u547d\u540d\u8c03\u6574\u76ee\u5f55\u7ed3\u6784 +admin.role.writeUpload=\u6587\u4ef6(\u5939)\u4e0a\u4f20\u8fdc\u7a0b\u4e0b\u8f7d +admin.role.writeRemove=\u6587\u4ef6(\u5939)\u5220\u9664\u526a\u5207 +admin.role.adminSetDesc=\u7cfb\u7edf\u7ba1\u7406\u5458\u62e5\u6709\u6240\u6709\u6743\u9650,\u65e0\u9700\u8bbe\u7f6e! +admin.role.displayDesc=\u8bbe\u7f6e\u7528\u6237\u89d2\u8272\u65f6\u662f\u5426\u663e\u793a +admin.role.defaultRoleDesc=\u63d0\u793a:\u7cfb\u7edf\u9ed8\u8ba4\u5185\u7f6e\u89d2\u8272,\u4e0d\u652f\u6301\u4fee\u6539\u6743\u9650��\u60a8\u53ef\u4ee5\u521b\u5efa\u65b0\u7684\u89d2\u8272 +admin.role.actionSetTitle=\u6587\u6863\u53ca\u914d\u7f6e +admin.role.userSetTitle=\u7528\u6237\u914d\u7f6e\u6570\u636e +admin.role.adminSetTitle=\u540e\u53f0\u529f\u80fd +admin.role.fileAdd=\u65b0\u5efa\u6587\u4ef6(\u5939) +admin.role.fileRemove=\u6587\u6863\u5220\u9664 +admin.role.fileMove=\u79fb\u52a8(\u590d\u5236/\u526a\u5207/\u7c98\u8d34/\u62d6\u62fd\u64cd\u4f5c) +admin.role.userConfig=\u914d\u7f6e\u4fee\u6539(\u8bbe\u7f6e\u5934\u50cf/\u4fee\u6539\u5bc6\u7801\u7b49) +admin.role.userEdit=\u7f16\u8f91\u7528\u6237(\u6dfb\u52a0/\u4fee\u6539/\u5220\u9664) +admin.role.userFav=\u6536\u85cf\u5939\u64cd\u4f5c +admin.role.itemEdit=\u6dfb\u52a0/\u4fee\u6539/\u5220\u9664 +admin.role.groupEdit=\u7f16\u8f91\u90e8\u95e8(\u6dfb\u52a0/\u4fee\u6539/\u5220\u9664) +admin.role.delErrTips=\u8be5\u89d2\u8272\u6b63\u5728\u88ab\u4f7f\u7528,\u65e0\u6cd5\u5220\u9664! +admin.authFrom.setUser=\u6307\u5b9a\u81ea\u5df1\u6743\u9650 +admin.authFrom.setGroup=\u6307\u5b9a\u90e8\u95e8\u6743\u9650 +admin.authFrom.setAll=\u5176\u4ed6\u7528\u6237\u6743\u9650 +admin.authFrom.groupAt=\u6240\u5728\u90e8\u95e8\u6743\u9650 +admin.authFrom.groupParent=\u4e0a\u5c42\u90e8\u95e8\u6743\u9650 +admin.authFrom.pathOnly=\u4ec5\u901a\u8def\u4e0b\u5c42\u6709\u5185\u5bb9\u6709\u6743\u9650 +admin.authFrom.groupRoot=\u90e8\u95e8\u6839\u76ee\u5f55 +admin.auth.owner=\u62e5\u6709\u8005 +admin.auth.editor=\u7f16\u8f91\u8005 +admin.auth.editUploader=\u7f16\u8f91/\u4e0a\u4f20\u8005 +admin.auth.viewer=\u67e5\u770b\u8005 +admin.auth.previewer=\u9884\u89c8\u8005 +admin.auth.uploader=\u4e0a\u4f20\u8005 +admin.auth.invisible=\u4e0d\u53ef\u89c1 +admin.auth.user=\u7528\u6237\u6570\u636e +admin.auth.pathDelete=\u6587\u4ef6\u5220\u9664 +admin.auth.pathInfo=\u6587\u4ef6\u5c5e\u6027 +admin.auth.pathMove=\u79fb\u52a8(\u590d\u5236/\u526a\u5207/\u7c98\u8d34/\u62d6\u62fd\u64cd\u4f5c) +admin.auth.canUpload=\u4e0a\u4f20\u4e0b\u8f7d +admin.auth.config=\u914d\u7f6e\u6570\u636e +admin.auth.fav=\u6536\u85cf\u5939\u64cd\u4f5c(\u6dfb\u52a0/\u7f16\u8f91/\u5220\u9664) +admin.auth.extWarning=\u4e0d\u5141\u8bb8\u6b64\u7c7b\u6587\u4ef6\u7684\u4e0a\u4f20
    \u91cd\u547d\u540d(\u91cd\u547d\u540d\u4e3a\u6307\u5b9a\u6269\u5c55\u540d)
    \u7f16\u8f91\u4fdd\u5b58\u8fdc\u7a0b\u4e0b\u8f7d\u89e3\u538b +admin.auth.error=\u89d2\u8272\u6743\u9650\u9519\u8bef(\u6ca1\u6709\u6743\u9650\u8bbe\u7f6e) +admin.auth.errorAdmin=\u6743\u9650\u4e0d\u8db3 +admin.auth.targetError=\u6743\u9650\u5bf9\u8c61\u7c7b\u578b\u9519\u8bef,\u5fc5\u987b\u4e3a\u7528\u6237\u6216\u90e8\u95e8 +admin.auth.errorAuthToGroup=\u975e\u6839\u90e8\u95e8,\u4e0d\u652f\u6301\u6388\u6743\u7ed9\u90e8\u95e8 +admin.auth.errorAuthToUsers=\u975e\u6839\u90e8\u95e8,\u4e0d\u652f\u6301\u6388\u6743\u7ed9\u8be5\u90e8\u95e8\u5916\u7684\u6210\u5458 +admin.auth.displayDesc=\u8bbe\u7f6e\u90e8\u95e8\u7528\u6237\u6743\u9650\u65f6\u662f\u5426\u663e\u793a +admin.auth.defaultAuthDesc=\u63d0\u793a:\u7cfb\u7edf\u9ed8\u8ba4\u5185\u7f6e\u6743\u9650\u7ec4,\u4e0d\u652f\u6301\u4fee\u6539\u6743\u9650��\u60a8\u53ef\u4ee5\u521b\u5efa\u65b0\u7684\u6743\u9650\u7ec4 +admin.auth.show=\u6587\u4ef6\u5217\u8868 +admin.auth.showAction=\u6587\u4ef6\u5217\u8868\u67e5\u770b +admin.auth.view=\u6587\u4ef6\u9884\u89c8 +admin.auth.viewAction=\u6587\u4ef6\u6253\u5f00\u9884\u89c8 +admin.auth.download=\u4e0b\u8f7d/\u590d\u5236 +admin.auth.downloadAction=\u4e0b\u8f7d/\u590d\u5236/\u6587\u4ef6\u9884\u89c8\u6253\u5370 +admin.auth.uploadAction=\u6587\u4ef6(\u5939)\u4e0a\u4f20/\u8fdc\u7a0b\u4e0b\u8f7d +admin.auth.edit=\u7f16\u8f91\u65b0\u5efa +admin.auth.editAction=\u65b0\u5efa\u6587\u4ef6(\u5939)/\u91cd\u547d\u540d/\u7c98\u8d34\u5230\u6587\u4ef6\u5939/\u7f16\u8f91\u6587\u4ef6/\u8bbe\u7f6e\u5907\u6ce8/\u521b\u5efa\u526f\u672c/\u89e3,\u538b\u7f29 +admin.auth.removeAction=\u526a\u5207/\u590d\u5236/\u79fb\u52a8 +admin.auth.shareAction=\u5916\u94fe\u5206\u4eab/\u4e0e\u4ed6\u4eba\u534f\u4f5c\u5206\u4eab +admin.auth.comment=\u6587\u6863\u8bc4\u8bba +admin.auth.commentAction=\u6587\u6863\u8bc4\u8bba\u67e5\u770b��\u6dfb\u52a0/\u5220\u9664\u81ea\u5df1\u7684\u8bc4\u8bba(\u9700\u7f16\u8f91\u6743\u9650) +admin.auth.event=\u6587\u6863\u52a8\u6001 +admin.auth.eventAction=\u6587\u6863\u52a8\u6001\u67e5\u770b,\u8ba2\u9605\u52a8\u6001 +admin.auth.root=\u7ba1\u7406\u6743\u9650 +admin.auth.rootAction=\u8bbe\u7f6e\u6210\u5458\u6743\u9650/\u8bc4\u8bba\u7ba1\u7406/\u5386\u53f2\u7248\u672c\u7ba1\u7406 +admin.auth.delErrTips=\u8be5\u6743\u9650\u6b63\u5728\u88ab\u4f7f\u7528,\u65e0\u6cd5\u5220\u9664! +admin.plugin.center=\u63d2\u4ef6\u4e2d\u5fc3 +admin.plugin.installed=\u5df2\u5b89\u88c5 +admin.plugin.type=\u5206\u7c7b +admin.plugin.typeFile=\u6587\u4ef6\u589e\u5f3a +admin.plugin.typeSafe=\u5b89\u5168\u5de5\u5177 +admin.plugin.typeTools=\u5b9e\u7528\u5de5\u5177 +admin.plugin.typeMedia=\u591a\u5a92\u4f53 +admin.plugin.typeCompany=\u4f01\u4e1a\u5e94\u7528 +admin.plugin.typeOem=\u4e13\u5c5e\u5b9a\u5236 +admin.plugin.needNetwork=\u9700\u8054\u5916\u7f51 +admin.plugin.install=\u5b89\u88c5\u63d2\u4ef6 +admin.plugin.enable=\u542f\u7528\u63d2\u4ef6 +admin.plugin.remove=\u5378\u8f7d\u63d2\u4ef6 +admin.plugin.config=\u914d\u7f6e\u63d2\u4ef6 +admin.plugin.statusEnabled=\u5df2\u542f\u7528 +admin.plugin.statusDisabled=\u672a\u542f\u7528 +admin.plugin.statusNotInstall=\u672a\u5b89\u88c5 +admin.plugin.installing=\u5b89\u88c5\u4e2d... +admin.plugin.hasUpdate=\u6709\u66f4\u65b0 +admin.plugin.updateStart=\u66f4\u65b0\u63d2\u4ef6 +admin.plugin.needConfig=\u9700\u8981\u521d\u59cb\u5316\u914d\u7f6e\u624d\u80fd\u542f\u7528 +admin.plugin.notNull=\u5fc5\u586b\u9879\u4e0d\u80fd\u4e3a\u7a7a! +admin.plugin.auther=\u4f5c\u8005 +admin.plugin.downloadNumber=\u5b89\u88c5\u6b21\u6570 +admin.plugin.back=\u8fd4\u56de +admin.plugin.detail=\u63cf\u8ff0 +admin.plugin.resetConfig=\u6062\u590d\u9ed8\u8ba4\u8bbe\u7f6e +admin.plugin.installSelf=\u624b\u52a8\u5b89\u88c5 +admin.plugin.updateSelf=\u624b\u52a8\u66f4\u65b0 +admin.plugin.updateAll=\u66f4\u65b0\u6240\u6709 +admin.plugin.installSelfDesc=
    \u9002\u7528\u60c5\u51b5:
  • 1. \u670d\u52a1\u5668\u4e0d\u652f\u6301\u8fde\u63a5\u5916\u7f51.
  • 2. \u865a\u62df\u4e3b\u673a\u5546\u7981\u7528\u4e86\u76f8\u5173\u529f\u80fd\u65f6(\u7f51\u7edc\u8bf7\u6c42https\u9a8c\u8bc1).

  • \u5b89\u88c5: \u4e0b\u8f7d\u540e\u4e0a\u4f20\u89e3\u538b\u5230plugins\u76ee\u5f55(\u9700\u8981\u4fdd\u7559\u63d2\u4ef6\u540d\u7684\u6587\u4ef6\u5939\u4e0d\u80fd\u4fee\u6539\u63d2\u4ef6\u540d);\u63d2\u4ef6\u4e2d\u5fc3\u542f\u7528\u5373\u53ef
  • \u66f4\u65b0: \u4e0b\u8f7d\u540e\u4e0a\u4f20\u89e3\u538b\u8986\u76d6\u5230\u5230\u5bf9\u5e94\u63d2\u4ef6\u540d\u6587\u4ef6\u5939;
  • +admin.plugin.installNetworkError=\u7f51\u7edc\u9519\u8bef,\u8bf7\u68c0\u67e5\u670d\u52a1\u5668\u80fd\u5426\u8bbf\u95ee\u5916\u7f51�� +admin.plugin.auth=\u4f7f\u7528\u6743\u9650 +admin.plugin.authDesc=\u8bbe\u7f6e\u6240\u6709\u4eba\u53ef\u7528,\u6216\u8005\u6307\u5b9a\u7528\u6237,\u7528\u6237\u7ec4,\u6743\u9650\u7ec4\u53ef\u4ee5\u4f7f\u7528 +admin.plugin.authOpen=\u5f00\u653e\u8bbf\u95ee +admin.plugin.authOpenDesc=\u65e0\u9700\u767b\u5f55\u7686\u53ef\u8bbf\u95ee\u53ef\u7528\u4e8e\u5bf9\u5916\u63a5\u53e3\u8c03\u7528 +admin.plugin.authAll=\u6240\u6709\u4eba +admin.plugin.authUser=\u6307\u5b9a\u7528\u6237 +admin.plugin.authGroup=\u6307\u5b9a\u90e8\u95e8 +admin.plugin.authRole=\u6307\u5b9a\u6743\u9650\u7ec4 +admin.plugin.openWith=\u6253\u5f00\u6837\u5f0f +admin.plugin.openWithDilog=\u5185\u90e8\u5bf9\u8bdd\u6846 +admin.plugin.openWithWindow=\u65b0\u9875\u9762\u6253\u5f00 +admin.plugin.fileSort=\u6269\u5c55\u540d\u5173\u8054\u4f18\u5148\u7ea7 +admin.plugin.fileSortDesc=\u8d8a\u5927\u6269\u5c55\u540d\u6253\u5f00\u4f18\u5148\u7ea7\u8d8a\u9ad8 +admin.plugin.fileExt=\u652f\u6301\u7684\u6587\u4ef6\u683c\u5f0f +admin.plugin.fileExtDesc=\u5173\u8054\u6269\u5c55\u540d\u5230\u8be5\u63d2\u4ef6 +admin.plugin.tabServer=\u670d\u52a1\u5668\u914d\u7f6e +admin.plugin.defaultAceEditor=Ace\u7f16\u8f91\u5668 +admin.plugin.defaultHtmlView=\u7f51\u9875\u9884\u89c8 +admin.plugin.defaultZipView=\u5728\u7ebf\u89e3\u538b\u7f29 +admin.plugin.authViewList=\u63d2\u4ef6\u5217\u8868 +admin.plugin.authStatus=\u5f00\u542f\u5173\u95ed +admin.plugin.authInstall=\u5b89\u88c5/\u5378\u8f7d +admin.plugin.disabled=\u63d2\u4ef6\u4e0d\u5b58\u5728\u6216\u5c1a\u672a\u5f00\u542f +admin.plugin.menuAdd=\u662f\u5426\u6dfb\u52a0\u5230\u4e3b\u83dc\u5355 +admin.plugin.menuAddDesc=\u4f5c\u4e3a\u5355\u72ec\u5e94\u7528\u4f7f\u7528 +admin.plugin.menuSubMenuDesc=\u6536\u7f29\u5728[\u66f4\u591a]\u83dc\u5355\u4e2d +admin.storage.type=\u5b58\u50a8\u7c7b\u578b +admin.storage.local=\u672c\u5730 +admin.storage.localStore=\u672c\u5730\u5b58\u50a8 +admin.storage.oss=\u963f\u91cc\u4e91OSS +admin.storage.cos=\u817e\u8baf\u4e91COS +admin.storage.qiniu=\u4e03\u725b\u4e91 +admin.storage.s3=\u4e9a\u9a6c\u900aS3 +admin.storage.ftp=FTP +admin.storage.oos=\u5929\u7ffc\u4e91OOS +admin.storage.moss=\u5b8f\u6749MOSS +admin.storage.eos=XSKY EOS +admin.storage.nos=\u524d\u4e91NOS +admin.storage.minio=MinIO +admin.storage.uss=\u53c8\u62cd\u4e91USS +admin.storage.eds=\u6df1\u4fe1\u670dEDS +admin.storage.driver=\u672c\u5730\u78c1\u76d8 +admin.storage.useage=\u7a7a\u95f4\u4f7f\u7528\u60c5\u51b5 +admin.storage.default=\u8bbe\u4e3a\u9ed8\u8ba4 +admin.storage.current=\u5f53\u524d\u9ed8\u8ba4 +admin.storage.edit=\u914d\u7f6e\u5b58\u50a8 +admin.storage.setConfig=\u4fee\u6539\u914d\u7f6e +admin.storage.moveData=\u8fc1\u79fb\u6570\u636e +admin.storage.delStore=\u5378\u8f7d\u5b58\u50a8 +admin.storage.ifMove=\u8be5\u5b58\u50a8\u4e2d\u5305\u542b{0}\u4e2a\u7f51\u76d8\u6587\u4ef6,\u5c06\u88ab\u8fc1\u79fb\u81f3\u5f53\u524d\u9ed8\u8ba4\u5b58\u50a8,\u662f\u5426\u7ee7\u7eed? +admin.storage.ifDel=\u786e\u5b9a\u8981\u5378\u8f7d\u5f53\u524d\u5b58\u50a8\u5417? +admin.storage.ifDelWithFile=\u8be5\u5b58\u50a8\u4e2d\u5305\u542b{0}\u4e2a\u7f51\u76d8\u6587\u4ef6,\u5220\u9664\u65f6\u5c06\u88ab\u8fc1\u79fb\u81f3\u5f53\u524d\u9ed8\u8ba4\u5b58\u50a8,\u662f\u5426\u7ee7\u7eed? +admin.storage.sysFile=\u7f51\u76d8\u6587\u4ef6:\u4e2a\u4eba\u7a7a\u95f4\u548c\u90e8\u95e8\u4e0b\u7684\u6587\u4ef6 +admin.storage.delErrTips=\u6210\u529f:%s;\u5931\u8d25:%s,\u8bf7\u91cd\u8bd5\u6216\u624b\u52a8\u8fc1\u79fb +admin.storage.delLocTips=\u8bf7\u81f3\u5c11\u4fdd\u7559\u4e00\u4e2a\u672c\u5730\u5b58\u50a8 +admin.storage.delStoreTips=\u8be5\u5b58\u50a8\u4e2d\u5305\u542b\u5907\u4efd\u6570\u636e,\u8bf7\u5904\u7406\u540e\u518d\u8fdb\u884c\u64cd\u4f5c! +admin.storage.nameDesc=\u5b58\u50a8\u540d\u79f0,\u7528\u4e8e\u533a\u5206\u4e0d\u540c\u5b58\u50a8 +admin.storage.path=\u5b58\u50a8\u76ee\u5f55 +admin.storage.pathLocDesc=\u6587\u4ef6\u5b58\u50a8\u76ee\u5f55,\u8bf7\u786e\u4fdd\u6240\u586b\u5199\u76ee\u5f55\u5177\u6709\u8bfb\u5199\u6743\u9650 +admin.storage.pathDesc=\u6587\u4ef6\u5b58\u50a8\u76ee\u5f55 +admin.storage.defaultDesc=\u9ed8\u8ba4\u9879\u4e3a\u552f\u4e00\u6709\u6548\u7684\u7cfb\u7edf\u5b58\u50a8,\u5982\u9009\u62e9\u5f00\u542f,\u5c06\u81ea\u52a8\u53d6\u6d88\u5176\u5b83\u9ed8\u8ba4\u5b58\u50a8\u65b9\u5f0f,\u8bf7\u8c28\u614e\u64cd\u4f5c�� +admin.storage.forceEdit=\u5f3a\u5236\u4fee\u6539 +admin.storage.editTips=\u5f00\u542f\u540e,\u53ef\u5bf9\u7981\u6b62\u4fee\u6539\u5b57\u6bb5\u8fdb\u884c\u7f16\u8f91��\u53ef\u80fd\u5bfc\u81f4\u8be5\u5b58\u50a8\u4e4b\u524d\u7684\u6587\u4ef6\u65e0\u6cd5\u8bbf\u95ee,\u8bf7\u8c28\u614e\u64cd\u4f5c�� +admin.storage.folderTips=\u5f53\u524d\u4e3a\u7cfb\u7edf\u6587\u4ef6\u5b58\u50a8\u4f4d\u7f6e\u8bf7\u8c28\u614e\u64cd\u4f5c +admin.storage.sizeTips=\u7a7a\u95f4\u5927\u5c0f\u9700\u5927\u4e8e0 +admin.storage.sizeDesc=(GB),\u8bf7\u6839\u636e\u6240\u9009\u5b58\u50a8\u76ee\u5f55\u7684\u5b9e\u9645\u53ef\u7528\u7a7a\u95f4\u5927\u5c0f\u586b\u5199 +admin.storage.region=\u5b58\u50a8\u533a\u57df +admin.storage.domain=\u7a7a\u95f4\u57df\u540d +admin.storage.bucket=Bucket\u540d\u79f0 +admin.storage.bucketDesc=\u521b\u5efa\u7a7a\u95f4\u65f6\u586b\u5199\u7684Bucket\u540d\u79f0 +admin.storage.userName=\u8d26\u53f7\u540d\u79f0 +admin.storage.userPwd=\u8d26\u53f7\u5bc6\u7801 +admin.storage.server=\u670d\u52a1\u5668\u5730\u5740 +admin.storage.serverDesc=ftp(s)://ip,\u4e0d\u52a0\u534f\u8bae\u9ed8\u8ba4\u4e3aftp +admin.storage.refer=\u53c2\u8003: +admin.storage.endpoint=\u5730\u57df\u8282\u70b9 +admin.storage.ossDomain=OSS\u7a7a\u95f4\u7ed1\u5b9a\u7684\u57df\u540d +admin.storage.ossKeyDesc=\u963f\u91cc\u4e91\u8d26\u53f7\u7684Access Key ID,\u8bf7\u5728��\u63a7\u5236\u53f0-Access Key\u7ba1\u7406��\u4e2d\u521b\u5efa\u6216\u67e5\u770b +admin.storage.ossSecretDesc=\u963f\u91cc\u4e91\u8d26\u53f7\u7684Access Key Secret,\u83b7\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.ossEndpoint=Endpoint,\u5982\u4f7f\u7528\u5185\u7f51\u8282\u70b9,\u9700\u5f00\u542f\u670d\u52a1\u5668\u4e2d\u8f6c +admin.storage.cosKeyDesc=\u817e\u8baf\u4e91\u8d26\u53f7\u7684Access Key ID,\u8bf7\u5728��\u63a7\u5236\u53f0-\u8bbf\u95ee\u7ba1\u7406-API\u79d8\u94a5\u7ba1\u7406��\u4e2d\u521b\u5efa\u6216\u67e5\u770b +admin.storage.cosSecretDesc=\u817e\u8baf\u4e91\u8d26\u53f7\u7684Access Key Secret,\u83b7\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.qiniuDomain=\u4e03\u725b\u7a7a\u95f4\u7ed1\u5b9a\u7684\u57df\u540d +admin.storage.qiniuKeyDesc=\u4e03\u725b\u8d26\u53f7\u7684Access Key,\u8bf7\u5728��\u63a7\u5236\u53f0-\u4e2a\u4eba\u4e2d\u5fc3-\u5bc6\u94a5\u7ba1\u7406��\u4e2d\u521b\u5efa\u6216\u67e5\u770b +admin.storage.qiniuSecretDesc=\u4e03\u725b\u8d26\u53f7\u7684Secret Key,\u83b7\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.qnz0=\u534e\u4e1c-\u6d59\u6c5f +admin.storage.qnz02=\u534e\u4e1c-\u6d59\u6c5f2 +admin.storage.qnz1=\u534e\u5317-\u6cb3\u5317 +admin.storage.qnz2=\u534e\u5357-\u5e7f\u4e1c +admin.storage.qnna0=\u5317\u7f8e-\u6d1b\u6749\u77f6 +admin.storage.qnas0=\u4e9a\u592a-\u65b0\u52a0\u5761 +admin.storage.qnas02=\u4e9a\u592a-\u9996\u5c14 +admin.storage.awsDomain=AWS\u7a7a\u95f4\u7ed1\u5b9a\u7684\u57df\u540d +admin.storage.awsKeyDesc=AWS\u8d26\u53f7\u7684Access Key ID,\u8bf7\u5728��\u63a7\u5236\u53f0-\u60a8\u7684\u5b89\u5168\u51ed\u8bc1��\u4e2d\u521b\u5efa +admin.storage.awsSecretDesc=AWS\u8d26\u53f7\u7684Access Key Secret,\u83b7\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.oosDomain=\u5929\u7ffc\u4e91\u7a7a\u95f4\u7ed1\u5b9a\u7684\u57df\u540d +admin.storage.oosKeyDesc=\u5929\u7ffc\u4e91\u8d26\u53f7\u7684Access Key ID,\u8bf7\u5728��\u63a7\u5236\u53f0-\u60a8\u7684\u5b89\u5168\u51ed\u8bc1��\u4e2d\u521b\u5efa +admin.storage.oosSecretDesc=\u5929\u7ffc\u4e91\u8d26\u53f7\u7684Access Key Secret,\u83b7\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.ftpDisabled=FTP\u4e0d\u53ef\u7528,\u8bf7\u5f00\u542fphp_ftp\u6269\u5c55 +admin.storage.ifDefaultTips=\u8be5\u64cd\u4f5c\u5c06\u53d6\u6d88\u5176\u5b83\u9ed8\u8ba4\u5b58\u50a8\u65b9\u5f0f,\u786e\u5b9a\u8981\u6267\u884c\u5417? +admin.storage.spaceUsed=\u5b9e\u9645\u4f7f\u7528 +admin.storage.spaceLave=\u5269\u4f59\u7528\u91cf +admin.storage.delError=\u8be5\u5b58\u50a8\u5df2\u6709\u6587\u4ef6\u5b58\u5728,\u4e0d\u53ef\u5220\u9664 +admin.storage.corsError=\u5982\u914d\u7f6e\u65e0\u8bef,\u8bf7\u6309��\u4f7f\u7528\u5e2e\u52a9��\u68c0\u67e5bucket\u8de8\u57df\u8bbe\u7f6e�� +admin.storage.saveError=\u65e0\u6cd5\u8fde\u63a5\u5230\u6307\u5b9a\u5b58\u50a8,\u8bf7\u68c0\u67e5\u914d\u7f6e\u4fe1\u606f\u662f\u5426\u6b63\u786e�� +admin.storage.ftpCharset=FTP\u670d\u52a1\u5668\u7f16\u7801 +admin.storage.ftpCharsetDesc=\u5982\u679c\u662fFTP\u670d\u52a1\u5668\u4e3awindows\u8be5\u5904\u6839\u636e\u60c5\u51b5\u53ef\u4ee5\u8bbe\u7f6e\u4e3aGBK; +admin.storage.ftpPasvOn=\u5f00\u542f +admin.storage.ftpPasvOff=\u5173\u95ed +admin.storage.ftpPasv=\u88ab\u52a8\u6a21\u5f0f +admin.storage.ftpPasvDesc=\u6570\u636e\u4f20\u8f93\u6a21\u5f0f +admin.storage.uploadSrv=\u670d\u52a1\u5668\u4e2d\u8f6c(\u4e0a\u4f20) +admin.storage.fileoutSrv=\u670d\u52a1\u5668\u4e2d\u8f6c(\u4e0b\u8f7d) +admin.storage.uploadSrvDesc=\u5f00\u542f\u540e,\u5c06\u901a\u8fc7\u670d\u52a1\u5668\u4e0a\u4f20\u6587\u4ef6\u81f3\u5bf9\u8c61\u5b58\u50a8��\u5426\u5219,\u5c06\u901a\u8fc7\u5ba2\u6237\u7aef\u76f4\u63a5\u4e0a\u4f20�� +admin.storage.fileoutSrvDesc=\u5f00\u542f\u540e,\u5c06\u901a\u8fc7\u670d\u52a1\u5668\u83b7\u53d6\u5b58\u50a8\u6587\u4ef6\u8fdb\u884c\u4e0b\u8f7d��\u5426\u5219,\u5c06\u83b7\u53d6\u6587\u4ef6\u76f4\u94fe\u4e0b\u8f7d�� +admin.storage.closeDefError=\u7981\u6b62\u5173\u95ed\u9ed8\u8ba4\u5b58\u50a8 +admin.storage.ussBucket=\u670d\u52a1\u540d\u79f0 +admin.storage.ussBucketDesc=\u4e91\u5b58\u50a8\u670d\u52a1\u540d\u79f0 +admin.storage.ussUser=\u64cd\u4f5c\u5458\u540d +admin.storage.ussUserDesc=\u64cd\u4f5c\u5458\u540d\u79f0 +admin.storage.ussUserPwd=\u64cd\u4f5c\u5458\u5bc6\u7801 +admin.storage.ussDomain=\u53c8\u62cd\u4e91\u7a7a\u95f4\u7ed1\u5b9a\u7684\u57df\u540d +admin.storage.ussToken=Token\u79d8\u94a5 +admin.storage.ussTokenDesc=Token\u9632\u76d7\u94fe\u79d8\u94a5(\u975e\u5fc5\u9700) +admin.storage.configError=\u914d\u7f6e\u53c2\u6570\u5f02\u5e38! +admin.storage.sizePercent=\u7cfb\u7edf\u6587\u4ef6\u5360\u6bd4: +admin.storage.fileCount=\u6587\u4ef6\u6570: +admin.storage.error=\u5b58\u50a8\u5f02\u5e38 +admin.task.name=\u4efb\u52a1\u540d\u79f0 +admin.task.edit=\u4efb\u52a1\u7f16\u8f91 +admin.task.type=\u4efb\u52a1\u7c7b\u578b +admin.task.method=\u5185\u7f6e\u65b9\u6cd5 +admin.task.methodName=\u65b9\u6cd5\u540d\u79f0 +admin.task.methodDesc=\u7531\u7cfb\u7edf\u6a21\u5757-\u63a7\u5236\u5668-\u65b9\u6cd5\u540d\u7ec4\u6210\u8c28\u614e\u586b\u5199. +admin.task.url=\u8bf7\u6c42URL +admin.task.urlDesc=\u81ea\u5b9a\u4e49URL\u5730\u5740,\u8ba1\u5212\u4efb\u52a1\u5b9a\u671f\u6267\u884c\u8bf7\u6c42�� +admin.task.cycle=\u6267\u884c\u5468\u671f +admin.task.desc=\u4efb\u52a1\u63cf\u8ff0 +admin.task.nMinutes=N\u5206\u949f +admin.task.default=\u7cfb\u7edf\u9ed8\u8ba4 +admin.task.timeInterval=\u95f4\u9694\u65f6\u95f4 +admin.task.timeStart=\u5f00\u59cb\u65f6\u95f4 +admin.task.timeStartRun=\u5f00\u59cb\u6267\u884c\u65f6\u95f4 +admin.task.timeLastRun=\u4e0a\u6b21\u6267\u884c\u65f6\u95f4 +admin.task.timeLastLogin=\u767b\u5f55\u65f6\u95f4 +admin.task.isOpen=\u662f\u5426\u542f\u7528 +admin.task.open=\u5f00\u542f +admin.task.content=\u6267\u884c\u5185\u5bb9 +admin.task.param=\u6267\u884c\u53c2\u6570 +admin.task.ifRun=\u786e\u5b9a\u8981\u8fd0\u884c\u8be5\u4efb\u52a1\u5417? +admin.task.backup=\u6570\u636e\u5907\u4efd +admin.task.backupDesc=\u6bcf\u592902:00\u5f00\u59cb\u5907\u4efd\u7cfb\u7edf\u6570\u636e�� +admin.install.install=\u7cfb\u7edf\u5b89\u88c5 +admin.install.databaseSet=\u6570\u636e\u5e93\u914d\u7f6e +admin.install.dataUpdate=\u6570\u636e\u8fc1\u79fb +admin.install.installSuccess=\u5b89\u88c5\u6210\u529f +admin.install.dbWasSet=\u60a8\u5df2\u914d\u7f6e\u6570\u636e\u5e93,\u5982\u9700\u91cd\u7f6e,\u53ef\u5728config/setting_user.php\u6587\u4ef6\u4e2d\u4fee\u6539\u914d\u7f6e\u540e\u91cd\u65b0\u5b89\u88c5! +admin.install.errorRequest=\u7cfb\u7edf\u5df2\u5b89\u88c5,\u7981\u6b62\u518d\u6b21\u8bf7\u6c42 +admin.install.databaseError=\u6570\u636e\u5e93\u8fde\u63a5\u9519\u8bef,\u8bf7\u68c0\u67e5\u914d\u7f6e +admin.install.cacheError=%s\u8fde\u63a5\u5931\u8d25,\u8bf7\u68c0\u67e5\u914d\u7f6e +admin.install.cacheConnectError=%s\u65e0\u6cd5\u8fde\u63a5\u5230\u670d\u52a1\u5668,\u8bf7\u68c0\u67e5\u914d\u7f6e +admin.install.dbSetError=\u6570\u636e\u5e93\u914d\u7f6e\u4fe1\u606f\u5199\u5165\u5931\u8d25 +admin.install.dbCreateTips=\u6570\u636e\u5e93\u4e0d\u5b58\u5728\u4e14\u81ea\u52a8\u521b\u5efa\u5931\u8d25,\u8bf7\u624b\u52a8\u521b\u5efa +admin.install.ifDelDb=\u6307\u5b9a\u7684\u6570\u636e\u5e93\u4e2d\u5df2\u5b58\u5728\u6570\u636e,\u70b9\u51fb[\u786e\u5b9a]\u540e\u5c06\u4f1a\u88ab\u5220\u9664��\u662f\u5426\u7ee7\u7eed? +admin.install.dbCreateError=\u6570\u636e\u8868\u521b\u5efa\u5f02\u5e38 +admin.install.dbFileError=\u6570\u636e\u5e93\u6587\u4ef6\u4e0d\u5b58\u5728 +admin.install.dbTypeError=\u6240\u9009\u6570\u636e\u5e93\u7c7b\u578b(%s)\u4e0d\u53ef\u7528,\u8bf7\u5b89\u88c5\u5bf9\u5e94\u670d\u52a1\u53ca\u6269\u5c55,\u6216\u9009\u62e9\u5176\u4ed6\u7c7b\u578b +admin.install.createSuccess=\u521b\u5efa\u6210\u529f +admin.install.defSetError=\u7cfb\u7edf\u9ed8\u8ba4\u914d\u7f6e\u6dfb\u52a0\u5931\u8d25 +admin.install.defStoreError=\u9ed8\u8ba4\u5b58\u50a8\u6dfb\u52a0\u5931\u8d25 +admin.install.defPathError=\u7cfb\u7edf\u76ee\u5f55\u6dfb\u52a0\u5931\u8d25 +admin.install.defAdminError=\u7ba1\u7406\u5458\u8d26\u53f7\u6dfb\u52a0\u5931\u8d25 +admin.install.defRoleError=\u9ed8\u8ba4\u89d2\u8272\u6dfb\u52a0\u5931\u8d25 +admin.install.defGroupError=\u7cfb\u7edf\u90e8\u95e8\u6dfb\u52a0\u5931\u8d25 +admin.install.dataPathNotExists=data\u76ee\u5f55\u4e0d\u5b58\u5728 +admin.install.defaultUpdate=\u7cfb\u7edf\u914d\u7f6e\u4fe1\u606f\u66f4\u65b0 +admin.install.pluginUpdated=\u63d2\u4ef6\u66f4\u65b0\u5b8c\u6210 +admin.install.defCacheError=\u521d\u59cb\u76ee\u5f55\u7f13\u5b58\u6570\u636e\u5f02\u5e38 +admin.install.serverDir=\u670d\u52a1\u5668\u5217\u76ee\u5f55 +admin.install.dirRight=\u76ee\u5f55\u6743\u9650 +admin.install.suggestOpen=\u5efa\u8bae\u5f00\u542f +admin.install.suggestClose=\u5efa\u8bae\u5173\u95ed +admin.install.phpVersionTips=PHP5.3\u53ca\u4ee5\u4e0a +admin.install.phpBitTips=\u5efa\u8bae64\u4f4d +admin.install.phpBitDesc=32\u4f4d\u4e0d\u652f\u63012G\u4ee5\u4e0a\u6587\u4ef6\u4e0a\u4f20\u4e0b\u8f7d +admin.install.pathNeedWirte=\u7a0b\u5e8f\u76ee\u5f55\u53ca\u6240\u6709\u5b50\u76ee\u5f55\u9700\u8981\u53ef\u8bfb\u5199 +admin.install.mustOpen=\u5fc5\u987b\u5f00\u542f +admin.install.setPathWrt=\u8bf7\u4e3a\u9879\u76ee\u76ee\u5f55\u8bbe\u7f6e\u8bfb\u5199\u6743\u9650 +admin.install.ensureNoError=\u8bf7\u786e\u4fdd\u4ee5\u4e0b\u5185\u5bb9\u65e0\u8bef: +admin.install.setAdminName=\u8bf7\u8bbe\u7f6e\u7ba1\u7406\u5458\u8d26\u53f7 +admin.install.setAdminPwd=\u8bf7\u8bbe\u7f6e\u7ba1\u7406\u5458\u5bc6\u7801 +admin.install.database=\u6570\u636e\u5e93 +admin.install.dbType=\u6570\u636e\u5e93\u7c7b\u578b +admin.install.dbName=\u6570\u636e\u5e93\u540d +admin.install.userName=\u7528\u6237\u540d +admin.install.dbPort=\u7aef\u53e3\u53f7 +admin.install.dbPortDesc=\u9ed8\u8ba4\u7aef\u53e33306,\u5982\u9700\u81ea\u5b9a\u4e49\u53ef\u5728\u540e\u9762\u8ffd\u52a0,\u5982:127.0.0.1:3307 +admin.install.dbEngine=\u5b58\u50a8\u5f15\u64ce +admin.install.sqliteDesc=php\u5185\u7f6e\u7eff\u8272\u8f7b\u91cf\u6570\u636e\u5e93(\u9002\u7528\u4e8e\u6d4b\u8bd5\u6216\u5c0f\u89c4\u6a21\u4f7f\u7528). +admin.install.mysqlDesc=\u652f\u6301\u96c6\u7fa4\u90e8\u7f72\u4e3b\u4ece\u591a\u6570\u636e\u5e93\u5206\u79bb. +admin.install.pdoDesc=\u66f4\u5b89\u5168\u7684\u6570\u636e\u5e93\u901a\u7528\u9a71\u52a8\u9700\u8981php\u5df2\u5b89\u88c5PDO\u6269\u5c55. +admin.install.cacheType=\u7cfb\u7edf\u7f13\u5b58\u7c7b\u578b +admin.install.cacheTypeDesc=\u7528\u4e8e\u7f13\u5b58\u901a\u7528\u6570\u636e\u53ca\u4f1a\u8bddsession,\u52a0\u5feb\u7cfb\u7edf\u8bbf\u95ee +admin.install.fileCache=\u6587\u4ef6\u7f13\u5b58 +admin.install.groupFile=\u90e8\u95e8\u6587\u6863 +admin.install.userFile=\u7528\u6237\u6587\u6863 +admin.install.role=\u89d2\u8272 +admin.install.fileAuth=\u6587\u6863\u6743\u9650 +admin.install.userList=\u7528\u6237\u5217\u8868 +admin.install.setInfo=\u7cfb\u7edf\u914d\u7f6e\u4fe1\u606f +admin.install.favShare=\u7528\u6237\u6536\u85cf\u53ca\u5206\u4eab +admin.install.waitUpdate=\u7b49\u5f85\u66f4\u65b0 +admin.install.updateSuccess=\u66f4\u65b0\u6210\u529f +admin.install.fileCount=\u6587\u4ef6\u6570 +admin.install.settingDesc=\u5931\u8d25\u9879\u53ef\u5728\u540e\u53f0\u7ba1\u7406\u8fdb\u884c\u624b\u52a8\u914d\u7f6e +admin.install.reInstallTips=\u8fd4\u56de\u7ed3\u679c\u5f02\u5e38,\u8bf7\u91cd\u65b0\u5b89\u88c5 +admin.log.accountEdit=\u4fee\u6539\u8d26\u53f7\u4fe1\u606f +admin.log.thirdBind=\u7ed1\u5b9a\u7b2c\u4e09\u65b9\u8d26\u53f7 +admin.log.delBind=\u53d6\u6d88\u7ed1\u5b9a +admin.log.viewFile=\u9884\u89c8\u6587\u4ef6 +admin.log.delFile=\u5220\u9664\u6587\u4ef6 +admin.log.editFile=\u7f16\u8f91\u6587\u4ef6 +admin.log.downFile=\u4e0b\u8f7d\u6587\u4ef6 +admin.log.downFolder=\u4e0b\u8f7d\u6587\u4ef6\u5939 +admin.log.moveFile=\u79fb\u52a8\u6587\u4ef6 +admin.log.addUser=\u65b0\u589e\u7528\u6237 +admin.log.editUser=\u7f16\u8f91\u7528\u6237 +admin.log.addUserTo=\u65b0\u589e\u7528\u6237\u5230\u90e8\u95e8 +admin.log.removeUserFrom=\u7528\u6237\u4ece\u90e8\u95e8\u79fb\u9664 +admin.log.switchUserGroup=\u8fc1\u79fb\u7528\u6237\u5230\u90e8\u95e8 +admin.log.stausUser=\u542f/\u7981\u7528\u7528\u6237 +admin.log.addRole=\u65b0\u5efa\u89d2\u8272 +admin.log.editRole=\u7f16\u8f91\u89d2\u8272 +admin.log.delRole=\u5220\u9664\u89d2\u8272 +admin.log.addAuth=\u65b0\u589e\u6743\u9650 +admin.log.editAuth=\u7f16\u8f91\u6743\u9650 +admin.log.delAuth=\u5220\u9664\u6743\u9650 +admin.log.editShare=\u7f16\u8f91\u5206\u4eab +admin.log.delLinkTo=\u53d6\u6d88\u5916\u94fe\u5206\u4eab +admin.log.delShareTo=\u53d6\u6d88\u534f\u4f5c\u5206\u4eab +admin.log.recycleTo=\u79fb\u5230\u56de\u6536\u7ad9 +admin.log.newName=\u65b0\u540d\u79f0 +admin.log.oldName=\u539f\u540d\u79f0 +admin.log.newPath=\u65b0\u76ee\u5f55 +admin.log.oldPath=\u539f\u76ee\u5f55 +admin.log.typeFile=\u6587\u4ef6\u64cd\u4f5c +admin.log.typeUser=\u7528\u6237\u914d\u7f6e +admin.log.queryByIp=\u70b9\u51fb\u6309\u94ae,\u6839\u636eIP\u67e5\u8be2\u5f53\u5929\u7684\u65e5\u5fd7\u8bb0\u5f55�� +admin.backup.setting=\u5907\u4efd\u8bbe\u7f6e +admin.backup.edit=\u5907\u4efd\u7f16\u8f91 +admin.backup.ing=\u5907\u4efd\u4e2d +admin.backup.success=\u5907\u4efd\u6210\u529f +admin.backup.fail=\u5907\u4efd\u5931\u8d25 +admin.backup.complete=\u5907\u4efd\u5b8c\u6210 +admin.backup.db=\u6570\u636e\u5e93 +admin.backup.dbFile=\u6570\u636e\u5e93\u6587\u4ef6 +admin.backup.fileError=\u90e8\u5206\u6587\u4ef6\u5907\u4efd\u5931\u8d25 +admin.backup.checkLog=\u8bf7\u67e5\u770b\u5907\u4efd\u65e5\u5fd7:data/temp/log/backup/\u5f53\u5929\u65e5\u671f__log.php +admin.backup.pathNoWrite=\u4e34\u65f6\u76ee\u5f55\u6ca1\u6709\u5199\u6743\u9650 +admin.backup.errorMsg=\u90e8\u5206\u6587\u4ef6\u5907\u4efd\u5931\u8d25,\u53ef\u6839\u636e\u65e5\u5fd7\u624b\u52a8\u590d\u5236,\u6216\u5220\u9664\u540e\u91cd\u65b0\u5907\u4efd�� +admin.backup.logFile=\u65e5\u5fd7\u6587\u4ef6 +admin.backup.manual=\u624b\u52a8\u5907\u4efd +admin.backup.continue=\u7ee7\u7eed\u5907\u4efd +admin.backup.start=\u5f00\u59cb\u5907\u4efd +admin.backup.open=\u5f00\u542f\u5907\u4efd +admin.backup.notOpen=\u5907\u4efd\u5c1a\u672a\u542f\u7528 +admin.backup.location=\u5907\u4efd\u4f4d\u7f6e +admin.backup.content=\u5907\u4efd\u5185\u5bb9 +admin.backup.dbOnly=\u4ec5\u6570\u636e\u5e93 +admin.backup.time=\u5907\u4efd\u65f6\u95f4 +admin.backup.notStart=\u672a\u5f00\u59cb +admin.backup.notEnabled=\u672a\u542f\u7528 +admin.backup.killed=\u5df2\u7ed3\u675f +admin.backup.ifKill=\u786e\u5b9a\u8981\u7ed3\u675f\u6b64\u6b21\u5907\u4efd\u5417? +admin.backup.kill=\u7ed3\u675f +admin.backup.error=\u5f02\u5e38\u4e2d\u6b62 +admin.backup.timeBeen=\u5df2\u8017\u65f6 +admin.backup.timeTotal=\u603b\u8017\u65f6 +admin.backup.backed=\u5df2\u5907\u4efd +admin.backup.storage=\u8bf7\u521b\u5efa\u4e00\u4e2a\u4e13\u95e8\u7528\u4e8e\u5907\u4efd\u7684\u5b58\u50a8�� +admin.backup.ifSave=\u5907\u4efd\u9700\u8981\u8f83\u957f\u65f6\u95f4,\u60a8\u786e\u5b9a\u8981\u8fdb\u884c\u5907\u4efd\u5417? +admin.backup.ifContinue=\u786e\u5b9a\u8981\u7ee7\u7eed\u5907\u4efd\u5417? +admin.backup.saveTips=\u5907\u4efd\u4efb\u52a1\u5df2\u63d0\u4ea4,\u8bf7\u8010\u5fc3\u7b49\u5f85 +admin.backup.fileSize=\u6587\u6863\u5927\u5c0f +admin.backup.dbSize=\u6570\u636e\u5e93\u5927\u5c0f +admin.backup.dbCnt=\u603b\u8bb0\u5f55\u6570 +admin.backup.notFinished=\u5c1a\u672a\u5b8c\u6210 +admin.backup.timeTaken=\u8017\u65f6 +admin.backup.node=\u8282\u70b9 +admin.backup.notYet=\u6682\u65e0 +admin.backup.storeNotExist=\u5907\u4efd\u5b58\u50a8\u4e0d\u5b58\u5728,\u8bf7\u91cd\u65b0\u8bbe\u7f6e +admin.backup.timeNote=\u8bf4\u660e:\u7cfb\u7edf\u4ec5\u4fdd\u7559\u6700\u8fd17\u5929,\u53ca\u6bcf\u67081\u53f7\u7684\u6570\u636e\u5e93\u5907\u4efd��\u5907\u4efd\u65f6\u95f4: +admin.backup.recover=\u6570\u636e\u6062\u590d\u8bf7\u8054\u7cfb\u670d\u52a1\u5546�� +admin.backup.optionTime=\u5907\u4efd\u6240\u9700\u65f6\u95f4\u8f83\u957f,\u8bf7\u5c3d\u91cf\u9009\u5728\u975e\u5de5\u4f5c\u65f6\u95f4\u6bb5\u8fdb\u884c +admin.backup.optionLocation=\u5982\u9700\u5907\u4efd\u6587\u4ef6,\u8bf7\u65b0\u521b\u5efa\u4e00\u4e2a\u4e13\u95e8\u7528\u4e8e\u5907\u4efd\u7684\u5b58\u50a8 +admin.backup.optionTips1=\u5907\u4efd\u5206\u4e3a\u6570\u636e\u5e93\u5907\u4efd\u548c\u6587\u4ef6\u5907\u4efd\u4e24\u90e8\u5206�� +admin.backup.optionTips2=\u6570\u636e\u5e93\u5907\u4efd:\u5c06\u6570\u636e\u5e93\u5185\u5bb9\u751f\u6210SQL\u6587\u4ef6,\u5907\u4efd\u81f3\u76ee\u6807\u5b58\u50a8database\u76ee\u5f55�� +admin.backup.optionTips3=\u6587\u4ef6\u5907\u4efd:\u5c06\u7cfb\u7edf\u5b58\u50a8\u6587\u4ef6,\u6309\u539f\u5b58\u50a8\u8def\u5f84\u589e\u91cf\u5907\u4efd\u81f3\u76ee\u6807\u5b58\u50a8�� +admin.backup.optionTips4=\u7cfb\u7edf\u4ec5\u4fdd\u7559\u6700\u8fd17\u5929,\u53ca\u6bcf\u67081\u53f7\u7684\u6570\u636e\u5e93\u5907\u4efd�� +admin.backup.needStorage=\u5907\u4efd\u5b58\u50a8\u4e0d\u80fd\u4e3a\u7a7a +admin.backup.needNoDefault=\u8bf7\u52ff\u9009\u62e9\u9ed8\u8ba4\u5b58\u50a8\u4f5c\u4e3a\u6587\u4ef6\u5907\u4efd\u4f4d\u7f6e +admin.backup.contentDesc=\u6388\u6743\u7248\u652f\u6301\u540c\u65f6\u5907\u4efd\u6570\u636e\u5e93\u548c\u6587\u4ef6 +admin.backup.action=\u64cd\u4f5c\u7ba1\u7406 +admin.backup.recovery=\u8fd8\u539f +admin.backup.sysRecovery=\u7cfb\u7edf\u8fd8\u539f +admin.backup.bakErr2Rec=\u6b64\u5907\u4efd\u672a\u5b8c\u6210,\u65e0\u6cd5\u8fd8\u539f +admin.recycle.menu=\u7cfb\u7edf\u56de\u6536\u7ad9 +admin.share.name=\u5206\u4eab\u540d\u79f0 +admin.share.type=\u5206\u4eab\u7c7b\u578b +admin.share.expiryTime=\u8fc7\u671f\u65f6\u95f4 +admin.share.expired=\u5df2\u8fc7\u671f +admin.share.link=\u5916\u94fe +admin.share.linkView=\u70b9\u51fb\u67e5\u770b\u5206\u4eab +admin.share.ifDel=\u786e\u5b9a\u8981\u53d6\u6d88\u8be5\u5206\u4eab\u5417? +admin.share.disFile=\u8be5\u6587\u4ef6\u906d\u5230\u7528\u6237\u4e3e\u62a5,\u5df2\u88ab\u7981\u6b62\u5206\u4eab +admin.share.disFolder=\u6b64\u76ee\u5f55\u4e0b\u542b\u6709\u88ab\u7981\u6b62\u5206\u4eab\u7684\u8fdd\u89c4\u6587\u4ef6 +admin.share.shareTab=\u5206\u4eab\u7ba1\u7406 +admin.share.reportTab=\u5206\u4eab\u4e3e\u62a5\u7ba1\u7406 +admin.share.rptType1=\u4fb5\u72af\u7248\u6743 +admin.share.rptType2=\u6deb\u79fd\u8272\u60c5 +admin.share.rptType3=\u8840\u8165\u66b4\u529b +admin.share.rptType4=\u653f\u6cbb\u6709\u5bb3 +admin.share.rptType5=\u5176\u4ed6\u539f\u56e0 +admin.share.doRptClose=\u5904\u7406\u5206\u4eab\u5185\u5bb9\u540e\u5173\u95ed\u8be5\u4e3e\u62a5,\u6216\u76f4\u63a5\u5173\u95ed +admin.share.doRptDisable=\u7981\u6b62/\u5141\u8bb8\u5206\u4eab\u540e,\u8be5\u6587\u4ef6\u5bf9\u5e94\u7684\u6240\u6709\u8d44\u6e90\u90fd\u5c06\u53d7\u5f71\u54cd��\u786e\u5b9a\u8981\u6267\u884c\u6b64\u64cd\u4f5c\u5417? +admin.share.rptUser=\u4e3e\u62a5\u8005 +admin.share.rptTitle=\u4e3e\u62a5\u5206\u4eab +admin.share.rptDesc=\u4e3e\u62a5\u539f\u56e0 +admin.share.rptTime=\u4e3e\u62a5\u65f6\u95f4 +admin.share.rptResult=\u5904\u7406\u7ed3\u679c +admin.share.rptDone=\u5df2\u5904\u7406 +admin.share.rptNoDone=\u672a\u5904\u7406 +admin.share.rptClose=\u5173\u95ed\u4e3e\u62a5 +admin.share.rptShareDel=\u53d6\u6d88\u5206\u4eab +admin.share.rptShareAllow=\u5141\u8bb8\u5206\u4eab +admin.share.rptShareDisable=\u7981\u6b62\u5206\u4eab +admin.share.rptDoDisable=\u7981\u6b62/\u5141\u8bb8\u5206\u4eab +admin.share.rptSelectTips=\u8bf7\u9009\u62e9\u5f85\u64cd\u4f5c\u9879! +admin.setting.transfer=\u4e0a\u4f20/\u4e0b\u8f7d +admin.setting.transferChunkSize=\u4e0a\u4f20\u5206\u7247\u5927\u5c0f +admin.setting.transferChunkSizeDesc=\u5927\u6587\u4ef6\u4e0a\u4f20\u65f6\u5207\u5206\u6210\u7247\u8fdb\u884c\u5e76\u53d1\u4e0a\u4f20\u4ece\u800c\u5b9e\u73b0\u52a0\u901f\u548c\u65ad\u70b9\u7eed\u4f20
    \u63a8\u83505M;\u6b64\u503c\u5fc5\u987b\u5c0f\u4e8e\u4e0b\u8ff0\u914d\u7f6e;\u5426\u5219\u4f1a\u5f15\u8d77\u4e0a\u4f20\u5f02\u5e38(\u4e0a\u4f20\u5931\u8d25\u8fdb\u5ea6\u56de\u9000) +admin.setting.transferChunkSizeDescError1=\u4e0a\u4f20\u5206\u7247\u5927\u5c0f\u4e0d\u80fd\u8d85\u8fc7php.ini\u4e2d\u7684\u8bbe\u7f6e +admin.setting.transferChunkSizeDescError2=\u5728php.ini\u4e2d\u4fee\u6539\u5927\u518d\u8bd5(\u4fee\u6539upload_max_filesize post_max_size\u9700\u8981\u91cd\u542f) +admin.setting.transferThreads=\u4e0a\u4f20\u5e76\u53d1\u7ebf\u7a0b +admin.setting.transferThreadsDesc=\u63a8\u8350 +admin.setting.transferIgnore=\u4e0a\u4f20\u5ffd\u7565\u6587\u4ef6 +admin.setting.transferIgnoreDesc=\u4e0a\u4f20\u81ea\u52a8\u5ffd\u7565\u7684\u6587\u4ef6\u540d\u53ef\u4ee5\u6392\u9664\u4e34\u65f6\u6587\u4ef6\u591a\u4e2a\u7528\u9017\u53f7\u9694\u5f00\u4f8b\u5982: .DS_storethumb.db +admin.setting.transferChunkRetry=\u4e0a\u4f20\u5931\u8d25\u81ea\u52a8\u91cd\u4f20 +admin.setting.transferChunkRetryDesc=\u63a8\u8350 +admin.setting.transferOsChunkSize=\u5bf9\u8c61\u5b58\u50a8\u5206\u7247\u5927\u5c0f +admin.setting.transferOsChunkSizeDesc=\u5bf9\u8c61\u5b58\u50a8\u4e0a\u4f20,\u5206\u7247\u5927\u5c0f\u8303\u56f4\u4e3a5MB~5GB,\u6700\u5927\u8bf7\u6c42\u6570\u4e3a1000,\u5373\u6700\u5927\u53ef\u652f\u63015TB\u7684\u6587\u4ef6\u4e0a\u4f20��
    \u63a8\u835010~20MB,\u6b64\u65f6\u652f\u6301\u6700\u5927\u6587\u4ef6\u5927\u5c0f\u4e3a9.7~19.5GB,\u7528\u6237\u53ef\u6839\u636e\u6240\u9700\u4e0a\u4f20\u6587\u4ef6\u5927\u5c0f\u81ea\u884c\u8c03\u6574�� +admin.setting.transferHttpSendFile=\u4e0b\u8f7dweb\u670d\u52a1\u5668\u52a0\u901f +admin.setting.transferHttpSendFileDesc=\u6587\u4ef6\u4e0b\u8f7d\u901a\u8fc7webserver\u76f4\u4f20;\u63d0\u5347\u4e0b\u8f7d\u901f\u5ea6;\u53ea\u9488\u5bf9\u9ed8\u8ba4\u5b58\u50a8\u914d\u7f6e\u4e3a\u672c\u5730\u5b58\u50a8\u7684\u60c5\u51b5\u6709\u6548. +admin.setting.downloadZipClient=\u5f00\u542f\u524d\u7aef\u6253\u5305\u538b\u7f29\u4e0b\u8f7d +admin.setting.downloadZipClientDesc=\u9700\u8981\u80fd\u591f\u94fe\u63a5\u5916\u7f51\u6216\u8005\u7ad9\u70b9\u4e3ahttps +admin.setting.downloadZipLimit=\u540e\u7aef\u6253\u5305\u538b\u7f29\u4e0b\u8f7d\u9650\u5236 +admin.setting.downloadZipLimitDesc=0\u4e3a\u4e0d\u9650\u5236;\u4e3a\u907f\u514d\u670d\u52a1\u5668\u6027\u80fd\u6d88\u8017\u8fc7\u5927 \u6587\u4ef6\u5939\u8fc7\u5927\u65f6\u9650\u5236\u6253\u5305\u4e0b\u8f7d\u63d0\u793a\u901a\u8fc7PC\u5ba2\u6237\u7aef\u53ef\u4ee5\u76f4\u63a5\u4e0b\u8f7d\u6587\u4ef6 +admin.setting.downloadZipLimitTips=\u538b\u7f29\u5185\u5bb9\u8d85\u51fa\u7cfb\u7edf\u9650\u5236\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! \u60a8\u53ef\u4ee5\u901a\u8fc7PC\u5ba2\u6237\u7aef\u76f4\u63a5\u4e0b\u8f7d\u6587\u4ef6\u5939\u65e0\u9700\u538b\u7f29. +admin.setting.dragDownload=\u62d6\u62fd\u5230\u684c\u9762\u4e0b\u8f7d +admin.setting.dragDownloadDesc=\u4ec5PC\u7aefChrome\u5185\u6838\u6d4f\u89c8\u5668\u652f\u6301(chrome edge 360\u6025\u901f\u7b49\u652f\u6301) +admin.setting.dragDownloadZip=\u591a\u9009\u62d6\u62fd\u538b\u7f29\u4e0b\u8f7d +admin.setting.dragDownloadZipDesc=\u591a\u9009\u6216\u6587\u4ef6\u5939\u62d6\u62fd\u4e0b\u8f7d\u652f\u6301\u987b\u5148\u670d\u52a1\u5668\u6253\u5305\u538b\u7f29\u540e\u4e0b\u8f7d +admin.setting.dragDownloadLimit=\u62d6\u62fd\u5185\u5bb9\u5927\u5c0f\u9650\u5236 +admin.setting.dragDownloadLimitDesc=0\u4e3a\u4e0d\u9650\u5236;\u62d6\u62fd\u5185\u5bb9\u5927\u5c0f\u4f1a\u53d7\u8be5\u9650\u5236. \u7531\u4e8e\u76ee\u524dChrome\u62d6\u62fd\u4e0b\u8f7d\u6ca1\u6709\u8fdb\u5ea6\u6761\u65e0\u6cd5\u53d6\u6d88\u63a8\u8350\u9650\u5236\u5927\u5c0f\u523020M. +admin.setting.dragDownloadUrlTips=url\u8fc7\u957f\u8bf7\u51cf\u5c11\u9009\u62e9\u5185\u5bb9\u540e\u518d\u8bd5! +admin.setting.dragDownloadOpenTips=\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u5728\u540e\u53f0\u8bbe\u7f6e\u4e2d\u5f00\u542f! +admin.setting.dragDownloadNotOpen=\u62d6\u62fd\u538b\u7f29\u4e0b\u8f7d\u672a\u5f00\u542f +admin.setting.dragDownloadSizeTips=\u62d6\u62fd\u5185\u5bb9\u5927\u5c0f\u8d85\u51fa\u9650\u5236 +admin.setting.showFileSafe=\u6587\u4ef6\u8bbf\u95ee\u5b89\u5168 +admin.setting.showFileLink=\u6587\u4ef6\u5916\u94fe\u5c55\u793a +admin.setting.showFileLinkDesc=\u5173\u95ed\u540e\u6587\u4ef6\u5c5e\u6027\u4e0d\u518d\u663e\u793a\u5916\u94fe\u8fde\u63a5 +admin.setting.showFileMd5=\u6587\u4ef6md5\u5c55\u793a +admin.setting.showFileMd5Desc=\u5173\u95ed\u540e\u6587\u4ef6\u5c5e\u6027\u4e0d\u518d\u663e\u793a\u6587\u4ef6md5 +admin.setting.shareLinkAllow=\u542f\u7528\u5916\u94fe\u5206\u4eab +admin.setting.shareLinkAllowDesc=\u5173\u95ed\u540e\u5c06\u4e0d\u518d\u652f\u6301\u5916\u94fe\u5206\u4eab\u5df2\u5206\u4eab\u7684\u5185\u5bb9\u4e0d\u53d7\u5f71\u54cd +admin.setting.shareLinkAllowTips=\u5f53\u524d\u7cfb\u7edf\u5df2\u7981\u7528\u4e86\u5916\u94fe\u5206\u4eab\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! +admin.setting.shareLinkPasswordAllowEmpty=\u5916\u94fe\u5206\u4eab\u5141\u8bb8\u5bc6\u7801\u4e3a\u7a7a +admin.setting.shareLinkPasswordAllowEmptyDesc=\u5173\u95ed\u540e\u5916\u94fe\u5206\u4eab\u5fc5\u987b\u8bbe\u7f6e\u5bc6\u7801;\u5df2\u5206\u4eab\u7684\u5185\u5bb9\u4e0d\u53d7\u5f71\u54cd +admin.setting.shareLinkAllowGuest=\u5916\u94fe\u5206\u4eab\u5141\u8bb8\u672a\u767b\u5f55\u6e38\u5ba2\u8bbf\u95ee +admin.setting.shareLinkAllowGuestDesc=\u5173\u95ed\u540e\u8bbf\u95ee\u5916\u94fe\u65f6\u5fc5\u987b\u767b\u5f55;\u5df2\u5206\u4eab\u7684\u5185\u5bb9\u4e0d\u53d7\u5f71\u54cd +admin.setting.shareLinkZip=\u5916\u94fe\u5206\u4eab\u6253\u5305\u4e0b\u8f7d +admin.setting.shareLinkZipDesc=\u5f00\u542f\u540e\u5916\u94fe\u5206\u4eab\u6587\u4ef6\u5939\u652f\u6301\u6253\u5305\u538b\u7f29\u4e0b\u8f7d\u5e76\u53d1\u5927\u7684\u8bdd\u4f1a\u8017\u8d39\u670d\u52a1\u5668\u6027\u80fd. +admin.setting.shareLinkZipTips=\u5916\u94fe\u5206\u4eab\u7981\u7528\u4e86\u6253\u5305\u4e0b\u8f7d\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u8fdb\u884c\u914d\u7f6e! +admin.setting.transferDownSpeed=\u4e0b\u8f7d\u9650\u901f +admin.setting.transferDownSpeedDesc=\u9650\u5236\u4e0b\u8f7d\u901f\u5ea6\u5bf9\u7f51\u7ad9\u5e76\u53d1\u5927\u7684\u60c5\u51b5\u8fdb\u884c\u7edf\u4e00\u9650\u901f +admin.setting.transferDownSpeedNum=\u4e0b\u8f7d\u9650\u901f\u901f\u5ea6 +admin.setting.transferDownSpeedNumDesc=\u9650\u5236\u4e0b\u8f7d\u901f\u5ea6\u5bf9\u7f51\u7ad9\u5e76\u53d1\u5927\u7684\u60c5\u51b5\u53ef\u4ee5\u8fdb\u884c\u7edf\u4e00\u9650\u901f.
    \u6ce8:\u6b64\u5904\u9650\u5236\u7684\u662f\u670d\u52a1\u5668\u901f\u5ea6,\u5177\u4f53\u4e0b\u8f7d\u901f\u5ea6\u8fd8\u53d7\u670d\u52a1\u5668\u5e26\u5bbd\u548c\u7528\u6237\u7f51\u7edc\u6709\u5173. +explorer.uploadSizeError=\u60a8\u670d\u52a1\u5668\u5f53\u524d\u4e0d\u652f\u63012G\u4ee5\u4e0a\u6587\u4ef6
    \u8bf7\u5347\u7ea7\u4e3a64\u4f4dphp;\u63a8\u835064\u4f4dphp7
    (\u6ce8:64\u4f4d\u64cd\u4f5c\u7cfb\u7edf\u624d\u80fd\u5b89\u88c564\u4f4dphp); +common.----=---- +common.width=\u5bbd +common.height=\u9ad8 +common.test=\u6d4b\u8bd5 +common.absolutePath=\u7edd\u5bf9\u5730\u5740 +common.qrcode=URL \u4e8c\u7ef4\u7801 +common.wechat=\u5fae\u4fe1 +common.group=\u90e8\u95e8 +common.user=\u7528\u6237 +common.online=\u5728\u7ebf +common.use=\u4f7f\u7528 +common.total=\u603b\u91cf +common.year=\u5e74 +common.month=\u6708 +common.week=\u5468 +common.daytime=\u65e5 +common.mon=\u5468\u4e00 +common.tue=\u5468\u4e8c +common.wed=\u5468\u4e09 +common.thu=\u5468\u56db +common.fri=\u5468\u4e94 +common.sat=\u5468\u516d +common.sun=\u5468\u65e5 +common.second=\u79d2 +common.minute=\u5206\u949f +common.hour=\u5c0f\u65f6 +common.day=\u5929 +common.every=\u6bcf +common.everyMonth=\u6bcf\u6708 +common.everyWeek=\u6bcf\u5468 +common.everyDay=\u6bcf\u5929 +common.language=\u591a\u8bed\u8a00 +common.all=\u5168\u90e8 +common.item=\u9879 +common.items=\u9879\u5185\u5bb9 +common.itemsEmpyt=\u65e0\u5185\u5bb9 +common.detail=\u8be6\u60c5 +common.me=\u6211\u81ea\u5df1 +common.others=\u5176\u4ed6 +common.guest=\u8bbf\u5ba2 +common.more=\u66f4\u591a +common.learnMore=\u4e86\u89e3\u66f4\u591a +common.yes=\u662f +common.no=\u5426 +common.omit=\u7565 +common.unknow=\u672a\u77e5 +common.title=\u6807\u9898 +common.time=\u65f6\u95f4 +common.scan=\u6d4f\u89c8 +common.report=\u4e3e\u62a5 +common.name=\u540d\u79f0 +common.nickName=\u6635\u79f0 +common.tools=\u5de5\u5177 +common.tag=\u6807\u7b7e +common.position=\u4f4d\u7f6e +common.mount=\u7f51\u7edc\u6302\u8f7d +common.type=\u7c7b\u578b +common.auth=\u6743\u9650 +common.status=\u72b6\u6001 +common.run=\u8fd0\u884c +common.file=\u6587\u4ef6 +common.folder=\u6587\u4ef6\u5939 +common.fileType=\u6587\u4ef6\u7c7b\u578b +common.fileSize=\u6587\u4ef6\u5927\u5c0f +common.attributeInfo=\u5c5e\u6027\u4fe1\u606f +common.actionType=\u64cd\u4f5c\u7c7b\u578b +common.isDisplay=\u662f\u5426\u663e\u793a +common.hide=\u9690\u85cf +common.isHide=\u5df2\u9690\u85cf +common.cancelHide=\u53d6\u6d88\u9690\u85cf +common.default=\u9ed8\u8ba4 +common.display=\u663e\u793a +common.moveDown=\u4e0b\u79fb +common.moveUp=\u4e0a\u79fb +common.drag=\u62d6\u62fd +common.dragSort=\u62d6\u62fd\u8c03\u6574\u987a\u5e8f +common.warning=\u8b66\u544a +common.tips=\u63d0\u793a +common.desc=\u8bf4\u660e +common.tipsDesc=\u63d0\u793a\u8bf4\u660e +common.tipsOthers=\u5176\u4ed6\u8bf4\u660e +common.view=\u67e5\u770b +common.log=\u65e5\u5fd7 +common.task=\u4efb\u52a1 +common.important=\u91cd\u8981 +common.icon=\u56fe\u6807 +common.menu=\u83dc\u5355 +common.system=\u7cfb\u7edf +common.basic=\u901a\u7528 +common.systemSet=\u7cfb\u7edf\u914d\u7f6e +common.systemDefault=\u7cfb\u7edf\u9ed8\u8ba4 +common.diy=\u81ea\u5b9a\u4e49 +common.input=\u8bf7\u8f93\u5165 +common.select=\u8bf7\u9009\u62e9 +common.add=\u65b0\u589e +common.edit=\u7f16\u8f91 +common.action=\u64cd\u4f5c +common.upload=\u4e0a\u4f20 +common.uploadTo=\u4e0a\u4f20\u5230 +common.download=\u4e0b\u8f7d +common.export=\u5bfc\u51fa +common.cover=\u8986\u76d6 +common.retry=\u91cd\u8bd5 +common.zip=\u538b\u7f29 +common.unzip=\u89e3\u538b +common.preview=\u9884\u89c8 +common.share=\u5206\u4eab +common.search=\u641c\u7d22 +common.query=\u67e5\u8be2 +common.delete=\u5220\u9664 +common.deleteForce=\u5f7b\u5e95\u5220\u9664 +common.deleteEnd=\u5df2\u5220\u9664 +common.refresh=\u5237\u65b0 +common.open=\u6253\u5f00 +common.close=\u5173\u95ed +common.from=\u6765\u6e90 +common.greater=\u5927\u4e8e +common.less=\u5c0f\u4e8e +common.print=\u6253\u5370 +common.selectInvert=\u53cd\u9009 +common.selectAll=\u5168\u9009/\u53cd\u9009 +common.selectAllItem=\u5168\u9009 +common.selectNum=\u5df2\u9009\u62e9 +common.selectNull=\u5168\u4e0d\u9009 +common.sizeMore=\u4ee5\u4e0a +common.showMore=\u5c55\u5f00 +common.showLess=\u6536\u8d77 +common.sizeSmall=\u5c0f +common.sizeMiddle=\u4e2d +common.sizeBig=\u5927 +common.rename=\u91cd\u547d\u540d +common.method=\u51fd\u6570 +common.extend=\u6269\u5c55 +common.fav=\u6536\u85cf +common.reset=\u91cd\u7f6e +common.testing=\u68c0\u6d4b +common.install=\u5b89\u88c5 +common.update=\u66f4\u65b0 +common.version=\u7248\u672c +common.sysVersion=\u5e73\u53f0\u7248\u672c +common.login=\u767b\u5f55 +common.regist=\u6ce8\u518c +common.password=\u5bc6\u7801 +common.operateTime=\u64cd\u4f5c\u65f6\u95f4 +common.createTime=\u521b\u5efa\u65f6\u95f4 +common.modifyTime=\u4fee\u6539\u65f6\u95f4 +common.activeTime=\u5f52\u6863\u65f6\u95f4 +common.startTime=\u5f00\u59cb\u65f6\u95f4 +common.endTime=\u7ed3\u675f\u65f6\u95f4 +common.finishTime=\u7ed3\u675f\u65f6\u95f4 +common.disable=\u7981\u7528 +common.goOn=\u7ee7\u7eed +common.ok=\u786e\u5b9a +common.startRun=\u5f00\u59cb\u6267\u884c +common.confirmTips=\u5371\u9669\u64cd\u4f5c\u8bf7\u518d\u6b21\u786e\u8ba4 +common.confirmAsk=\u786e\u8ba4\u8981\u8fdb\u884c\u8be5\u64cd\u4f5c\u5417? +common.submit=\u63d0\u4ea4 +common.skip=\u8df3\u8fc7 +common.nextStep=\u4e0b\u4e00\u6b65 +common.start=\u5f00\u59cb +common.stop=\u6682\u505c +common.set=\u8bbe\u7f6e +common.cancel=\u53d6\u6d88 +common.save=\u4fdd\u5b58 +common.empty=\u6ca1\u6709\u5185\u5bb9! +common.isOpen=\u5df2\u5f00\u542f +common.isClose=\u5df2\u5173\u95ed +common.apply=\u5e94\u7528 +common.saveAll=\u4fdd\u5b58\u5168\u90e8 +common.notSave=\u4e0d\u4fdd\u5b58 +common.appAdd=\u6dfb\u52a0 +common.backAdd=\u8fd4\u56de\u6dfb\u52a0 +common.saveEdit=\u4fdd\u5b58\u4fee\u6539 +common.saveSubmit=\u4fdd\u5b58\u63d0\u4ea4 +common.saveAndAdd=\u4fdd\u5b58\u5e76\u7ee7\u7eed\u6dfb\u52a0 +common.sex=\u6027\u522b +common.male=\u7537 +common.female=\u5973 +common.address=\u5730\u5740 +common.email=Email +common.phone=\u624b\u673a +common.sms=\u77ed\u4fe1 +common.phoneNumber=\u624b\u673a\u53f7 +common.server=\u670d\u52a1\u5668 +common.handheld=\u79fb\u52a8\u8bbe\u5907 +common.success=\u6210\u529f +common.fail=\u5931\u8d25 +common.error=\u9519\u8bef +common.result=\u7ed3\u679c +common.expired=\u5df2\u5931\u6548 +common.valid=\u6709\u6548 +common.inAll=\u603b\u8ba1 +common.allAndNull=\u5168\u9009/\u53d6\u6d88 +common.moveTop=\u7f6e\u9876 +common.moveBottom=\u7f6e\u5e95 +common.moveTopCancle=\u53d6\u6d88\u7f6e\u9876 +common.ECN=\u534e\u4e1c +common.NCN=\u534e\u5317 +common.SCN=\u534e\u5357 +common.USA=\u5317\u7f8e +common.SEA=\u4e1c\u5357\u4e9a +common.noLimit=\u4e0d\u9650\u5236 +common.notExists=\u4e0d\u5b58\u5728 +common.cannotWrite=\u53ea\u8bfb\u4e0d\u53ef\u5199 +common.readOnly=\u53ea\u8bfb +common.cannotRead=\u4e0d\u53ef\u8bfb +common.ifDel=\u786e\u5b9a\u8981\u5220\u9664\u5417? +common.pageNotExists=\u8be5\u9875\u9762\u4e0d\u5b58\u5728! +common.pathNotExists=\u8be5\u6587\u4ef6\u4e0d\u5b58\u5728 +common.fileShare=\u6587\u6863\u5206\u4eab +common.logining=\u767b\u5f55\u4e2d... +common.loginTokenError=\u767b\u5f55\u5df2\u5931\u6548,\u8bf7\u91cd\u65b0\u767b\u5f55! +common.loginSuccess=\u767b\u5f55\u6210\u529f! +common.loginError=\u767b\u5f55\u5931\u8d25 +common.connectSuccess=\u8fde\u63a5\u6210\u529f! +common.bindSuccess=\u7ed1\u5b9a\u6210\u529f! +common.bindError=\u7ed1\u5b9a\u5931\u8d25 +common.clear=\u6e05\u7a7a +common.congrats=\u606d\u559c, +common.sorry=\u62b1\u6b49, +common.invalid=\u65e0\u6548\u7684 +common.unavailable=\u4e0d\u53ef\u7528 +common.format=\u683c\u5f0f +common.noPermission=\u6ca1\u6709\u6743\u9650 +common.allPermission=\u6240\u6709\u6743\u9650 +common.invalidParam=\u65e0\u6548\u7684\u53c2\u6570 +common.invalidFormat=\u65e0\u6548\u7684\u683c\u5f0f +common.invalidRequest=\u4e0d\u5408\u6cd5\u7684\u8bf7\u6c42\u7c7b\u578b +common.illegalRequest=\u975e\u6cd5\u8bf7\u6c42 +common.expiredRequest=\u8bf7\u6c42\u5df2\u5931\u6548 +common.errorExpiredRequest=\u65e0\u6548\u7684\u8bf7\u6c42\u6216\u5df2\u7ecf\u5931\u6548 +common.migrating=\u6b63\u5728\u8fc1\u79fb +common.migrated=\u8fc1\u79fb\u5b8c\u6210 +common.maintenanceTips=\u7cfb\u7edf\u7ef4\u62a4\u4e2d,\u8bf7\u7a0d\u540e\u8bbf\u95ee���� +common.done=\u5df2\u5b8c\u6210 +common.disabled=\u5df2\u7981\u7528 +common.sizeTotal=\u603b\u5927\u5c0f +common.sqlStatement=[ SQL\u8bed\u53e5 ] : +common.env.check=\u73af\u5883\u68c0\u6d4b +common.env.errorLib=PHP\u5e93\u7f3a\u5931 +common.env.errorIgnore=\u5ffd\u7565\u5e76\u8fdb\u5165 +common.env.errorVersion=PHP\u7248\u672c\u4e0d\u80fd\u4f4e\u4e8e5.0 +common.env.errorPath=\u4e0d\u53ef\u5199 +common.env.errorListDir=\u60a8\u7684web\u670d\u52a1\u5668\u5f00\u542f\u4e86\u5217\u76ee\u5f55\u529f\u80fd,\u4e3a\u5b89\u5168\u8003\u8651\u8bf7\u7981\u7528\u8be5\u529f\u80fd!
    \u8bf7\u5173\u95ed\u7f13\u5b58,\u6216\u7a0d\u540e1\u5206\u949f\u5237\u65b0\u9875\u9762\u518d\u8bd5!
    (\u68c0\u67e5 DATA_PATH); +common.env.pathPermissionError=[Error Code:1002] \u76ee\u5f55\u6743\u9650\u9519\u8bef!\u8bf7\u8bbe\u7f6e\u7a0b\u5e8f\u76ee\u5f55\u53ca\u6240\u6709\u5b50\u76ee\u5f55\u4e3a\u8bfb\u5199\u72b6\u6001,
    linux \u8fd0\u884c\u5982\u4e0b\u6307\u4ee4:
    su -c 'setenforce 0'
    chmod -R 777 +common.version.free=\u514d\u8d39 +common.version.nameQ=\u4f01\u4e1a\u7248 +common.version.vipFree=\u514d\u8d39\u7248 +common.version.useFree=\u7ee7\u7eed\u4f7f\u7528\u514d\u8d39\u7248 +common.version.notSupport=\u60a8\u7684\u7248\u672c\u4e0d\u652f\u6301\u6b64\u64cd\u4f5c,\u8bf7\u5230\u5b98\u7f51\u8d2d\u4e70\u9ad8\u7ea7\u7248\u672c! +common.version.notSupportNumber=\u7531\u4e8e\u6570\u91cf\u9650\u5236\u4e0d\u652f\u6301\u6b64\u64cd\u4f5c,\u8bf7\u5230\u5b98\u7f51\u8d2d\u4e70\u9ad8\u7ea7\u7248\u672c! +common.version.toVip=\u5347\u7ea7\u4e3a\u5546\u4e1a\u7248 +common.version.license=\u8d2d\u4e70\u6388\u6743 +common.version.authCode=\u6388\u6743\u6fc0\u6d3b\u7801 +common.version.authActive=\u6fc0\u6d3b\u6388\u6743 +common.version.authorization=\u6ce8\u518c\u6388\u6743 +common.version.authorizeSuccess=\u606d\u559c\u60a8,\u5728\u7ebf\u5347\u7ea7\u6388\u6743\u6210\u529f! +common.version.networkError=\u8bf7\u6c42\u670d\u52a1\u5668\u5931\u8d25,\u68c0\u67e5\u670d\u52a1\u5668\u662f\u5426\u80fd\u8bbf\u95ee\u7f51\u7edc��
    \u6ce8:\u670d\u52a1\u5668\u4e0d\u80fd\u662f\u4ee3\u7406\u4e0a\u7f51 +common.version.authActiveOnline=\u5728\u7ebf\u6fc0\u6d3b +common.version.authActiveOffline=\u79bb\u7ebf\u6fc0\u6d3b +common.version.offlineTips=\u670d\u52a1\u5668\u4e0d\u80fd\u8bbf\u95ee\u5916\u7f51? +common.version.menuTitle=\u4f01\u4e1a\u4fe1\u606f\u8bbe\u7f6e +common.version.timeout=\u5df2\u8fc7\u671f +common.version.timeToService=\u670d\u52a1\u5230\u671f\u65f6\u95f4 +common.version.timeTo=\u6388\u6743\u5230\u671f\u65f6\u95f4 +common.version.licenseAll=\u6c38\u4e45\u6388\u6743 +common.version.kodVersion= +common.version.userLimitTitle=\u7528\u6237\u6570 +common.version.userUse=\u5df2\u6709\u7528\u6237\u6570 +common.version.userAllow=\u652f\u6301\u7528\u6237\u6570 +common.version.userTo=\u6388\u6743\u5bf9\u8c61 +common.version.userTitle=\u6388\u6743\u4fe1\u606f +common.version.basicInfo=\u57fa\u7840\u4fe1\u606f +common.version.appInfo=\u4ea7\u54c1\u4fe1\u606f +common.version.tipsWarning=\u8b66\u544a\u8bf7\u52ff\u64c5\u81ea\u4fee\u6539\u7248\u6743;\u5982\u6709\u9700\u8981\u8bf7\u8054\u7cfb\u8d2d\u4e70! +common.version.tipsCopyLink=\u590d\u5236\u6210\u529f!\u53ef\u7c98\u8d34\u4fdd\u5b58\u5230txt\u6587\u4ef6
    \u901a\u8fc7U\u76d8\u7b49\u65b9\u5f0f\u5728\u6709\u7f51\u7684\u7535\u8111\u6253\u5f00\u6b64\u94fe\u63a5 +common.version.tipsHistory=\u514d\u8d39\u7248\u53ea\u652f\u63015\u4e2a\u5386\u53f2\u8bb0\u5f55\u7248\u672c;\u8d2d\u4e70\u6388\u6743\u7248\u4e0d\u9650\u6570\u91cf! +common.version.codeLink=\u6388\u6743\u8ba4\u8bc1\u7801\u8bf7\u6c42\u94fe\u63a5 +common.version.codeLinkHelp=1. \u62f7\u8d1d\u4e0a\u9762\u94fe\u5230\u5176\u4ed6\u6709\u7f51\u7684\u7535\u8111\u8bbf\u95ee.
    2. \u5c06\u83b7\u5f97\u7684\\u6388\u6743\u8ba4\u8bc1\u7801\\u586b\u5199\u5230\u4e0a\u9762\u7136\u540e\u8fdb\u884c\u6fc0\u6d3b\u6388\u6743 +common.copyright.logoTitle=\u4f01\u4e1a\u5f62\u8c61logo\u8bbe\u7f6e +common.copyright.licenseInfo=\u6388\u6743\u4fe1\u606f +common.copyright.licenseReset=\u91cd\u65b0\u6388\u6743 +common.copyright.licenseResetTips=\u91cd\u65b0\u6fc0\u6d3b\u83b7\u53d6\u66f4\u591a\u4fe1\u606f! +common.copyright.formLogo=\u767b\u5f55\u9875logo\u7c7b\u578b +common.copyright.formLogoTypeWord=\u6587\u5b57logo +common.copyright.formLogoTypeImage=\u56fe\u7247logo +common.copyright.formLogoDesc=\u6587\u5b57logo\u5219\u4f7f\u7528\u516c\u53f8\u540d\u79f0\u56fe\u7247logo\u5219\u4f7f\u7528\u5982\u4e0b\u8bbe\u7f6e\u7684\u56fe\u7247. +common.copyright.formLogoImage=\u767b\u5f55\u9875\u9762logo\u56fe\u7247 +common.copyright.formLogoImageDesc=\u767b\u5f55\u9875\u9762\u548c\u7ba1\u7406\u540e\u53f0logo\u63a8\u8350\u5c3a\u5bf8250x100\u534a\u900f\u660epng\u683c\u5f0f +common.copyright.formLogoMain=\u4e3b\u754c\u9762\u83dc\u5355logo +common.copyright.formLogoMainDesc=\u6587\u4ef6\u7ba1\u7406\u5de6\u4e0a\u89d2logo\u63a8\u8350\u5c3a\u5bf8200x200\u767d\u8272\u534a\u900f\u660epng\u683c\u5f0f +common.copyright.formPowerByInfo=\u516c\u53f8\u7248\u6743\u4fe1\u606f\u8bbe\u7f6e +common.copyright.formPowerBy=\u5e95\u90e8\u7248\u6743\u516c\u53f8\u540d +common.copyright.formHomePage=\u5e95\u90e8\u7248\u6743\u94fe\u63a5\u8df3\u8f6c +common.copyright.formConcat=\u5f39\u51fa\u5c42\u8054\u7cfb\u65b9\u5f0f +common.copyright.formDesc=\u4ea7\u54c1\u5f39\u51fa\u5c42\u8be6\u7ec6\u8bf4\u660e +common.copyright.formDescTips=\u4fee\u6539\u4fdd\u5b58\u540e\u5237\u65b0\u9875\u9762\u751f\u6548 +common.copyright.formMetaKeywords=\u7ad9\u70b9\u5173\u952e\u8bcd(\u641c\u7d22\u5f15\u64ce\u4f7f\u7528) +common.copyright.formMetaName=\u7ad9\u70b9\u540d(\u641c\u7d22\u5f15\u64ce\u4f7f\u7528) +common.copyright.downloadApp=App\u4e0b\u8f7d +common.copyright.downloadLink= +common.copyright.about=\u5173\u4e8e +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle=\u53ef\u9053\u4e91 +common.copyright.nameDesc=\u53ef\u9053\u4e91?\u8d44\u6e90\u7ba1\u7406\u5668 +common.copyright.powerBy= +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=\u81ea\u52a8\u8bc6\u522b +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=\u963f\u62c9\u4f2f\u6587 +common.charset.ISO_8859_6=\u963f\u62c9\u4f2f\u6587 +common.charset.ISO_8859_10=\u5317\u6b27\u8bed\u8a00 +common.charset.CP1257=\u6ce2\u7f57\u7684\u6d77\u5468\u8fb9\u8bed\u8a00 +common.charset.ISO_8859_13=\u6ce2\u7f57\u7684\u6d77\u5468\u8fb9\u8bed\u8a00 +common.charset.ISO_8859_4=\u6ce2\u7f57\u7684\u6d77\u5468\u8fb9\u8bed\u8a00 +common.charset.BIG5_HKSCS=\u7e41\u4f53-\u9999\u6e2f +common.charset.BIG5=\u7e41\u4f53-\u53f0\u6e7e +common.charset.Georgian_Academy=\u683c\u9c81\u5409\u4e9a\u6587 +common.charset.PT154=\u54c8\u8428\u514b\u6587 +common.charset.CP949=\u97e9\u8bed +common.charset.EUC_KR=\u97e9\u8bed +common.charset.GB18030=\u7b80\u4f53\u4e2d\u6587 +common.charset.GBK=\u7b80\u4f53\u4e2d\u6587 +common.charset.ISO_8859_14=\u51ef\u5c14\u7279\u8bed +common.charset.CP1133=\u8001\u631d\u6587 +common.charset.ISO_8859_16=\u7f57\u9a6c\u5c3c\u4e9a\u6587 +common.charset.ISO_8859_3=\u5357\u6b27\u8bed\u8a00 +common.charset.EUC_JP=\u65e5\u6587 +common.charset.ISO_2022_JP=\u65e5\u6587 +common.charset.SHIFT_JIS=\u65e5\u6587 +common.charset.KOI8_T=\u5854\u5409\u514b\u8bed +common.charset.ISO_8859_11=\u6cf0\u6587 +common.charset.TIS_620=\u6cf0\u6587 +common.charset.CP1254=\u571f\u8033\u5176\u6587 +common.charset.CP1251=\u897f\u91cc\u5c14\u8bed +common.charset.ISO_8859_5=\u897f\u91cc\u5c14\u8bed +common.charset.KOI8_R=\u897f\u91cc\u5c14\u8bed +common.charset.KOI8_U=\u897f\u91cc\u5c14\u8bed +common.charset.CP1252=\u897f\u6b27\u8bed\u8a00 +common.charset.ISO_8859_1=\u897f\u6b27\u8bed\u8a00 +common.charset.ISO_8859_15=\u897f\u6b27\u8bed\u8a00 +common.charset.Macintosh=\u897f\u6b27\u8bed\u8a00 +common.charset.CP1255=\u5e0c\u4f2f\u6765\u6587 +common.charset.ISO_8859_8=\u5e0c\u4f2f\u6765\u6587 +common.charset.CP1253=\u5e0c\u814a\u6587 +common.charset.ISO_8859_7=\u5e0c\u814a\u6587 +common.charset.ARMSCII_8=\u4e9a\u7f8e\u5c3c\u4e9a\u6587 +common.charset.CP1258=\u8d8a\u5357\u6587 +common.charset.VISCII=\u8d8a\u5357\u6587 +common.charset.CP1250=\u4e2d\u6b27\u8bed\u8a00 +common.charset.ISO_8859_2=\u4e2d\u6b27\u8bed\u8a00 +common.charset.defaultSet=\u6587\u4ef6\u7f16\u7801 +common.charset.convertSave=\u8f6c\u6362\u7f16\u7801\u4e3a +common.date.near=\u521a\u521a +common.date.miniteBefore=\u5206\u949f\u524d +common.date.today=\u4eca\u5929 +common.date.yestoday=\u6628\u5929 +common.date.before=\u4ee5\u524d +common.faceDefault=\u9ed8\u8ba4\u8868\u60c5 +common.loadMore=\u52a0\u8f7d\u66f4\u591a +common.numberLimit=\u6570\u91cf\u8d85\u51fa\u6700\u5927\u9650\u5236! +common.lengthLimit=\u957f\u5ea6\u8d85\u51fa\u6700\u5927\u9650\u5236! +common.task.name=\u4efb\u52a1\u7ba1\u7406\u5668 +common.task.title=\u4efb\u52a1\u540d\u79f0 +common.task.user=\u6267\u884c\u7528\u6237 +common.task.porcess=\u8fdb\u5ea6 +common.task.start=\u5f00\u59cb\u4efb\u52a1 +common.task.useTime=\u5df2\u6267\u884c\u65f6\u95f4 +common.task.running=\u6267\u884c\u4e2d +common.task.stoping=\u6682\u505c\u4e2d +common.task.killing=\u6b63\u5728\u7ed3\u675f +common.task.stop=\u6682\u505c\u4efb\u52a1 +common.task.kill=\u7ed3\u675f\u4efb\u52a1 +common.task.removeTips=\u786e\u5b9a\u7ed3\u675f\u8be5\u64cd\u4f5c? +common.task.killAll=\u7ed3\u675f\u6240\u6709 +common.task.killAllTips=\u786e\u5b9a\u7ed3\u675f\u6240\u6709\u4efb\u52a1? +common.task.timeStart=\u5f00\u59cb\u4e8e +common.task.timeNeed=\u5269\u4f59\u7ea6 +common.task.timeUse=\u5df2\u8fd0\u884c +ERROR_DB_PWD=\u6570\u636e\u5e93\u8bbf\u95ee\u88ab\u62d2\u7edd:\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef�� +ERROR_DB_TIMEOUT=\u6570\u636e\u5e93\u8fde\u63a5\u8d85\u65f6,\u8bf7\u68c0\u67e5\u5730\u5740\u662f\u5426\u6b63\u786e�� +ERROR_DB_CONN_RFS=\u6570\u636e\u5e93\u8fde\u63a5\u88ab\u62d2\u7edd:\u914d\u7f6e\u4fe1\u606f\u6709\u8bef,\u6216\u670d\u52a1\u672a\u542f\u52a8�� +ERROR_DB_ADR=\u6570\u636e\u5e93\u8fde\u63a5\u9519\u8bef,\u8bf7\u68c0\u67e5\u5730\u5740\u662f\u5426\u6b63\u786e�� +ERROR_DB_NOT_SUPPORT=\u4e0d\u652f\u6301\u7684\u6570\u636e\u5e93\u7c7b\u578b,\u8bf7\u68c0\u67e5\u5bf9\u5e94\u670d\u52a1,\u6216\u914d\u7f6e\u6587\u4ef6\u662f\u5426\u6b63\u5e38�� +ERROR_DB_XS_DENNIED=\u6570\u636e\u5e93\u8bbf\u95ee\u88ab\u62d2\u7edd:\u6743\u9650\u4e0d\u8db3�� +ERROR_DB_NOT_EXIST=\u6570\u636e\u5e93\u4e0d\u5b58\u5728,\u6216\u6307\u5b9a\u540d\u79f0\u9519\u8bef�� +explorer.----=---- +explorer.pathNotSupport=\u6b64\u7c7b\u578b\u76ee\u5f55\u4e0d\u652f\u6301\u8be5\u64cd\u4f5c! +explorer.pathIsRoot=\u5df2\u7ecf\u5230\u6839\u76ee\u5f55\u4e86! +explorer.pathNull=\u6587\u4ef6\u5939\u4e3a\u7a7a +explorer.zipFileLarge=\u8be5\u6587\u4ef6\u592a\u5927,\u8bf7\u89e3\u538b\u540e\u518d\u8fdb\u884c\u9884\u89c8\u64cd\u4f5c! +explorer.charNoSupport=\u4e0d\u652f\u6301\u7684\u7279\u6b8a\u5b57\u7b26: +explorer.moveError=\u79fb\u52a8\u5931\u8d25 +explorer.lockError=\u51fa\u9519\u4e86\u5e76\u53d1\u9501\u5b9a\u8d85\u65f6 +explorer.lockErrorDesc=\u8bf7\u7a0d\u540e\u518d\u8bd5(\u53ef\u964d\u4f4e\u8bf7\u6c42\u9891\u7387\u4f18\u5316\u5e76\u53d1\u76f8\u5173\u914d\u7f6e). +explorer.moveSubPathError=\u51fa\u9519\u4e86,\u7236\u76ee\u5f55\u4e0d\u80fd\u79fb\u52a8\u5230\u5b50\u76ee\u5f55! +explorer.spaceIsFull=\u5269\u4f59\u7a7a\u95f4\u4e0d\u8db3\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! +explorer.sessionSaveError=session\u5199\u5165\u5931\u8d25!\u8bf7\u67e5\u770b\u78c1\u76d8\u662f\u5426\u5df2\u6ee1\u6216\u54a8\u8be2\u670d\u52a1\u5546�� +explorer.networkError=\u7f51\u7edc\u8fde\u63a5\u9519\u8bef (net::ERR_CONNECTION_RESET),\u8fde\u63a5\u5df2\u91cd\u7f6e.
    \u8bf7\u8054\u7cfb\u4e3b\u673a\u5546\u6216\u7f51\u7ba1,\u68c0\u67e5\u9632\u706b\u5899\u914d\u7f6e! +explorer.folderManage=\u7ba1\u7406\u76ee\u5f55 +explorer.clickEdit=\u70b9\u51fb\u8fdb\u5165\u7f16\u8f91\u72b6\u6001 +explorer.shortLink=\u5feb\u6377\u65b9\u5f0f +explorer.upper=\u4e0a\u5c42 +explorer.historyNext=\u524d\u8fdb +explorer.historyBack=\u540e\u9000 +explorer.loading=\u64cd\u4f5c\u4e2d... +explorer.getting=\u83b7\u53d6\u4e2d... +explorer.sending=\u6570\u636e\u53d1\u9001\u4e2d... +explorer.pullTips=\u4e0b\u62c9\u4ee5\u5237\u65b0\u9875\u9762 +explorer.pullDropTips=\u91ca\u653e\u4ee5\u5237\u65b0\u9875\u9762 +explorer.getSuccess=\u83b7\u53d6\u6210\u529f! +explorer.saveSuccess=\u4fdd\u5b58\u6210\u529f! +explorer.saveError=\u4fdd\u5b58\u5931\u8d25! +explorer.success=\u64cd\u4f5c\u6210\u529f +explorer.error=\u64cd\u4f5c\u5931\u8d25 +explorer.dataError=\u6570\u636e\u5f02\u5e38! +explorer.pathError=\u6587\u6863\u8def\u5f84\u9519\u8bef +explorer.repeatError=\u64cd\u4f5c\u5931\u8d25,\u8be5\u540d\u79f0\u5df2\u5b58\u5728! +explorer.systemError=\u7cfb\u7edf\u9519\u8bef +explorer.mistake=\u51fa\u9519\u4e86! +explorer.recycleClear=\u6e05\u7a7a\u56de\u6536\u7ad9 +explorer.recycleClearForce=\u56de\u6536\u7ad9\u5185\u5bb9\u8fc7\u591a\u8bf7\u5148\u6e05\u7a7a\u56de\u6536\u7ad9! +explorer.recycleRestore=\u8fd8\u539f\u56de\u6536\u7ad9 +explorer.recycleRestoreItem=\u8fd8\u539f +explorer.recycleRestoreAll=\u5168\u90e8\u8fd8\u539f +explorer.recycleClearInfo=\u60a8\u786e\u5b9a\u8981\u5f7b\u5e95\u6e05\u7a7a\u56de\u6536\u7ad9\u5417? +explorer.zipDownloadReady=\u538b\u7f29\u540e\u4f1a\u81ea\u52a8\u4e0b\u8f7d\u8bf7\u7a0d\u540e... +explorer.removeItem=\u9879\u5185\u5bb9 +explorer.uploading=\u4e0a\u4f20\u4e2d +explorer.uploadTipsMore=\u6587\u4ef6\u8fc7\u591a\u5efa\u8bae\u538b\u7f29\u540e\u4e0a\u4f20\u7136\u540e\u5728\u7ebf\u89e3\u538b! +explorer.uploadingMove=\u5408\u5e76\u8f6c\u5b58\u4e2d... +explorer.viewNewPage=\u65b0\u9875\u9762\u9884\u89c8 +explorer.unknowFileTitle=\u6587\u4ef6\u6253\u5f00\u63d0\u793a! +explorer.unknowFileTips=\u6ca1\u6709\u652f\u6301\u6b64\u6587\u4ef6\u7684\u5e94\u7528,\u60a8\u53ef\u4ee5: +explorer.unknowAppTips=\u6ca1\u6709\u8be5\u5e94\u7528: +explorer.unknowFileTry=\u5c1d\u8bd5 +explorer.unknowFileDown=\u4e0b\u8f7d\u8be5\u6587\u4ef6 +explorer.authFileDown=\u6587\u4ef6\u4e0b\u8f7d +explorer.authShare=\u5171\u4eab +explorer.usersShare=\u7684\u5171\u4eab +explorer.clipboard=\u67e5\u770b\u526a\u8d34\u677f +explorer.clipboardClear=\u6e05\u7a7a\u526a\u8d34\u677f +explorer.fullScreen=\u5168\u5c4f +explorer.folderItem=\u4e2a\u9879\u76ee +explorer.folderItemSelect=\u4e2a\u9009\u4e2d +explorer.dbLoadAll=\u53cc\u51fb\u52a0\u8f7d\u5168\u90e8���� +explorer.ziping=\u6b63\u5728\u538b\u7f29... +explorer.unziping=\u6b63\u5728\u89e3\u538b... +explorer.zipingTips=\u538b\u7f29\u64cd\u4f5c\u4e2d\u8bf7\u7a0d\u540e... +explorer.unzipingTips=\u89e3\u538b\u64cd\u4f5c\u4e2d\u8bf7\u7a0d\u540e... +explorer.unzipRarTips=\u6587\u4ef6\u5185\u5bb9\u635f\u574f\u6216\u4e0d\u652f\u6301\u8be5\u6587\u4ef6\u89e3\u6790,\u63a8\u8350\u4f7f\u7528ZIP\u683c\u5f0f�� +explorer.parsing=\u89e3\u6790\u83b7\u53d6\u4e2d... +explorer.moving=\u79fb\u52a8\u64cd\u4f5c\u4e2d... +explorer.copyMove=\u590d\u5236\u79fb\u52a8 +explorer.removeTitle=\u5220\u9664\u786e\u8ba4 +explorer.removeInfo=\u786e\u8ba4\u5220\u9664\u9009\u4e2d\u5185\u5bb9\u5417? +explorer.removeTitleForce=\u6c38\u4e45\u5220\u9664 +explorer.removeInfoForce=\u786e\u5b9a\u8981\u6c38\u4e45\u5220\u9664\u6b64\u6587\u6863\u5417? +explorer.pathInRecycle=\u8be5\u6587\u4ef6\u5939\u5728\u56de\u6536\u7ad9\u4e2d\u8bf7\u8fd8\u539f\u540e\u518d\u8bd5! +explorer.pathInRecycleFile=\u8be5\u6587\u4ef6\u5728\u56de\u6536\u7ad9\u4e2d\u8bf7\u8fd8\u539f\u540e\u518d\u8bd5! +explorer.downOffline=\u79bb\u7ebf\u4e0b\u8f7d +explorer.savePath=\u4fdd\u5b58\u8def\u5f84 +explorer.uploadSelectMuti=\u53ef\u9009\u62e9\u591a\u4e2a\u6587\u4ef6\u4e0a\u4f20 +explorer.goTo=\u8df3\u8f6c\u5230 +explorer.selectFile=\u9009\u62e9\u6587\u4ef6 +explorer.selectFolder=\u9009\u62e9\u6587\u4ef6\u5939 +explorer.selectImage=\u8bf7\u9009\u62e9\u56fe\u7247... +explorer.selectValidFolder=\u8bf7\u9009\u62e9\u8981\u6709\u6548\u7684\u6587\u4ef6\u5939! +explorer.selectFolderFile=\u9009\u62e9\u6587\u4ef6\u6216\u6587\u4ef6\u5939 +explorer.selectMulti=\u591a\u9009 +explorer.notNull=\u5fc5\u586b\u9879\u4e0d\u80fd\u4e3a\u7a7a! +explorer.picCannotNull=\u56fe\u7247\u5730\u5740\u4e0d\u80fd\u4e3a\u7a7a! +explorer.renameSuccess=\u91cd\u547d\u540d\u6210\u529f! +explorer.inputSearchWords=\u8bf7\u8f93\u5165\u8981\u641c\u7d22\u7684\u5b57\u7b26\u4e32 +explorer.search.optionContent=\u6587\u4ef6\u5185\u5bb9 +explorer.search.searchContentTips=\u5173\u952e\u5b57\u641c\u7d22\u6587\u4ef6\u5185\u5bb9\u652f\u6301\u6587\u672c\u6587\u4ef6 +explorer.search.optionMutil=\u6279\u91cf\u641c\u7d22 +explorer.search.optionMutilDesc=\u6bcf\u884c\u4e00\u4e2a\u641c\u7d22\u8bcd\u641c\u7d22\u7ed3\u679c\u6839\u636e\u641c\u7d22\u8bcd\u8fdb\u884c\u6392\u5e8f +explorer.removeSuccess=\u5220\u9664\u6210\u529f! +explorer.removeFail=\u5220\u9664\u5931\u8d25! +explorer.clipboardNull=\u526a\u8d34\u677f\u4e3a\u7a7a! +explorer.createSuccess=\u65b0\u5efa\u6210\u529f! +explorer.createError=\u65b0\u5efa\u5931\u8d25\u8bf7\u68c0\u67e5\u76ee\u5f55\u6743\u9650! +explorer.copySuccess=��\u590d\u5236������ \u8986\u76d6\u526a\u8d34\u677f\u6210\u529f! +explorer.cuteSuccess=��\u526a\u5207������ \u8986\u76d6\u526a\u8d34\u677f\u6210\u529f! +explorer.clipboardState=\u526a\u5207\u677f\u72b6\u6001: +explorer.copyOK=\u5df2\u590d\u5236\u6210\u529f! +explorer.copyNotExists=\u6765\u6e90\u4e0d\u5b58\u5728 +explorer.currentHasParent=\u76ee\u6807\u6587\u4ef6\u5939\u662f\u6e90\u6587\u4ef6\u5939\u7684\u5b50\u6587\u4ef6\u5939! +explorer.pastSuccess=\u7c98\u8d34\u64cd\u4f5c\u5b8c\u6210 +explorer.cutePastSuccess=\u526a\u5207\u64cd\u4f5c\u5b8c\u6210 +explorer.zipSuccess=\u538b\u7f29\u5b8c\u6210 +explorer.notZip=\u4e0d\u662f\u538b\u7f29\u6587\u4ef6 +explorer.zipNull=\u6ca1\u6709\u9009\u62e9\u7684\u6587\u4ef6\u6216\u76ee\u5f55 +explorer.unzipSuccess=\u89e3\u538b\u5b8c\u6210 +explorer.pathIsCurrent=\u6240\u6253\u5f00\u8def\u5f84\u548c\u5f53\u524d\u8def\u5f84\u4e00\u6837! +explorer.pathExists=\u8be5\u540d\u79f0\u5df2\u5b58\u5728! +explorer.serverDownDesc=\u4e2a\u4efb\u52a1\u52a0\u5165\u5230\u4e0b\u8f7d\u5217\u8868 +explorer.parentPermission=\u7236\u76ee\u5f55\u6743\u9650 +explorer.confirm=\u786e\u5b9a\u8fdb\u884c\u8be5\u64cd\u4f5c? +explorer.ifSaveFileTips=\u6709\u6587\u4ef6\u672a\u4fdd\u5b58\u786e\u5b9a\u5173\u95ed\u7a97\u53e3? +explorer.ifSaveFile=\u6587\u4ef6\u5c1a\u672a\u4fdd\u5b58\u662f\u5426\u4fdd\u5b58? +explorer.ifStopUploadTips=\u6709\u6587\u4ef6\u6b63\u5728\u4e0a\u4f20\u4e2d\u786e\u5b9a\u5173\u95ed\u7a97\u53e3? +explorer.noPermissionRead=\u60a8\u6ca1\u6709\u8bfb\u53d6\u6743\u9650! +explorer.noPermissionDownload=\u60a8\u6ca1\u6709\u4e0b\u8f7d\u6743\u9650! +explorer.noPermissionWrite=\u8be5\u76ee\u5f55\u6ca1\u6709\u5199\u6743\u9650 +explorer.noPermissionAction=\u60a8\u6ca1\u6709\u6b64\u6743\u9650,\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458! +explorer.noPermissionWriteAll=\u8be5\u6587\u4ef6\u6216\u76ee\u5f55\u6ca1\u6709\u5199\u6743\u9650 +explorer.noPermissionWriteFile=\u8be5\u6587\u4ef6\u6ca1\u6709\u5199\u6743\u9650 +explorer.noPermissionReadAll=\u8be5\u6587\u4ef6\u6216\u76ee\u5f55\u6ca1\u6709\u8bfb\u6743\u9650 +explorer.noPermission=\u7ba1\u7406\u5458\u7981\u6b62\u4e86\u6b64\u6743\u9650! +explorer.noPermissionExt=\u7ba1\u7406\u5458\u7981\u6b62\u4e86\u8be5\u7c7b\u578b\u6587\u4ef6\u6743\u9650 +explorer.noPermissionGroup=\u60a8\u4e0d\u5728\u8be5\u7528\u6237\u7ec4! +explorer.pathNoWrite=\u76ee\u5f55\u4e0d\u53ef\u5199\u8bf7\u5c06\u8be5\u76ee\u5f55\u53ca\u6240\u6709\u5b50\u76ee\u5f55\u8bbe\u7f6e\u4e3a\u53ef\u8bfb\u5199\u540e\u518d\u8bd5! +explorer.onlyReadDesc=\u8be5\u76ee\u5f55\u6ca1\u6709\u5199\u6743\u9650\u53ef\u4ee5\u5728\u670d\u52a1\u5668\u8bbe\u7f6e\u6b64\u76ee\u5f55\u7684\u6743\u9650 +explorer.settingSuccess=\u4fee\u6539\u5df2\u751f\u6548! +explorer.noRepeat=\u4e0d\u5141\u8bb8\u91cd\u590d +explorer.dataNotFull=\u6570\u636e\u63d0\u4ea4\u4e0d\u5b8c\u6574! +explorer.tooManyToView=\u5305\u542b\u5185\u5bb9\u592a\u591a(%s\u9879),\u8bf7\u5728\u672c\u5730\u6253\u5f00\u67e5\u770b; +explorer.jumpAfterWhile=%ss \u540e\u81ea\u52a8\u8df3\u8f6c
    \u8bf7\u624b\u52a8\u9009\u62e9 +explorer.cuteToThe=\u79fb\u52a8\u5230: +explorer.copyToThe=\u590d\u5236\u5230: +explorer.addToFav=\u6dfb\u52a0\u5230\u6536\u85cf\u5939 +explorer.addFav=\u6dfb\u52a0\u6536\u85cf +explorer.delFav=\u53d6\u6d88\u6536\u85cf +explorer.addFavSuccess=\u6dfb\u52a0\u6536\u85cf\u6210\u529f +explorer.pathHasFaved=\u8be5\u8def\u5f84\u5df2\u6536\u85cf +explorer.delFavSuccess=\u53d6\u6d88\u6536\u85cf\u6210\u529f +explorer.fileLock=\u7f16\u8f91\u9501\u5b9a +explorer.fileLockNow=\u9501\u5b9a +explorer.fileLockCancle=\u53d6\u6d88\u9501\u5b9a +explorer.fileLockTitle=\u5df2\u9501\u5b9a +explorer.fileLockTips=\u5df2\u9501\u5b9a(\u5176\u4ed6\u4eba\u4e0d\u80fd\u7f16\u8f91\u8be5\u6587\u4ef6) +explorer.fileLockUser=\u9501\u5b9a\u8005 +explorer.fileLockError=\u5f53\u524d\u6587\u4ef6\u4e3a\u9501\u5b9a\u72b6\u6001\u8bf7\u8054\u7cfb\u9501\u5b9a\u8005\u89e3\u9501\u540e\u518d\u8bd5; +explorer.downloaded=\u4e0b\u8f7d\u5b8c\u6210 +explorer.openAutoTips=\u5373\u5c06\u81ea\u52a8\u6253\u5f00 +explorer.historyAutoTips=\u81ea\u52a8\u751f\u6210\u5386\u53f2\u7248\u672c +explorer.saved=\u4fdd\u5b58\u6210\u529f +explorer.opened=\u6253\u5f00\u6210\u529f! +explorer.openFail=\u6253\u5f00\u5931\u8d25! +explorer.openingWithLoc=\u6587\u4ef6\u672c\u5730\u6253\u5f00\u4e2d... +explorer.openOnlyView=\u53ea\u8bfb\u6a21\u5f0f\u6253\u5f00 +explorer.saving=\u6587\u4ef6\u4fdd\u5b58\u4e2d... +explorer.notSupport=\u51fa\u9519\u4e86 \u4e0d\u652f\u6301\u8be5\u5185\u5bb9\u683c\u5f0f! +explorer.unzipErrorTips=\u51fa\u9519\u4e86!\u672a\u8bc6\u522b\u7684\u538b\u7f29\u6587\u4ef6\u683c\u5f0f��
    \u8bf7\u68c0\u67e5\u8be5\u6587\u4ef6\u662f\u5426\u4e3a\u538b\u7f29\u6587\u4ef6\u6216\u8005\u662f\u5426\u635f\u574f�� +explorer.wordLoading=\u52a0\u8f7d\u4e2d... +explorer.noFunction=\u6ca1\u6709\u8be5\u65b9\u6cd5! +explorer.paramFormatError=\u53c2\u6570\u683c\u5f0f\u9519\u8bef! +explorer.descTooLong=\u63cf\u8ff0\u957f\u5ea6\u8fc7\u957f +explorer.noMoreThan=\u4e0d\u8d85\u8fc7 +explorer.desktopDelError=\u62b1\u6b49\u684c\u9762\u6587\u4ef6\u5939\u4e0d\u652f\u6301\u5220\u9664! +explorer.copy=\u590d\u5236 +explorer.past=\u7c98\u8d34 +explorer.clone=\u521b\u5efa\u526f\u672c +explorer.cute=\u526a\u5207 +explorer.cuteTo=\u79fb\u52a8\u5230... +explorer.copyTo=\u590d\u5236\u5230... +explorer.info=\u5c5e\u6027 +explorer.searchInPath=\u6587\u4ef6\u5939\u4e2d\u641c\u7d22 +explorer.addToPlay=\u6dfb\u52a0\u5230\u64ad\u653e\u5217\u8868 +explorer.manageFav=\u7ba1\u7406\u6536\u85cf\u5939 +explorer.refreshTree=\u5237\u65b0\u6811\u76ee\u5f55 +explorer.zip=\u521b\u5efa\u538b\u7f29\u5305 +explorer.unzip=\u89e3\u538b\u5230... +explorer.unzipFolder=\u89e3\u538b\u5230\u6587\u4ef6\u5939 +explorer.unzipThis=\u89e3\u538b\u5230\u5f53\u524d +explorer.unzipTo=\u89e3\u538b\u5230... +explorer.openProject=\u7f16\u8f91\u5668\u6253\u5f00\u9879\u76ee +explorer.createLink=\u521b\u5efa\u5feb\u6377\u65b9\u5f0f +explorer.createLinkHome=\u53d1\u9001\u5230\u684c\u9762\u5feb\u6377\u65b9\u5f0f +explorer.setBackground=\u8bbe\u7f6e\u4e3a\u684c\u9762\u58c1\u7eb8 +explorer.favRemove=\u53d6\u6d88\u8be5\u6536\u85cf +explorer.openPath=\u8fdb\u5165\u6240\u5728\u76ee\u5f55 +explorer.openPathFinished=\u5df2\u7ecf\u8fdb\u5165\u6240\u5728\u76ee\u5f55 +explorer.openIE=\u6d4f\u89c8\u5668\u6253\u5f00 +explorer.newFile=\u65b0\u5efa\u6587\u4ef6 +explorer.newFolder=\u65b0\u5efa\u6587\u4ef6\u5939 +explorer.fileSaveTo=\u6587\u4ef6\u4fdd\u5b58\u5230 +explorer.openFather=\u4e0a\u5c42\u6587\u4ef6\u5939\u663e\u793a +explorer.uploadFile=\u4e0a\u4f20\u6587\u4ef6 +explorer.uploadFolder=\u4e0a\u4f20\u6587\u4ef6\u5939 +explorer.appOpenDefault=\u8bbe\u7f6e\u9ed8\u8ba4\u6253\u5f00 +explorer.appOpenAways=\u59cb\u7ec8\u4f7f\u7528\u9009\u62e9\u7684\u7a0b\u5e8f\u6253\u5f00\u8fd9\u79cd\u6587\u4ef6 +explorer.appSelectDesc=\u9009\u62e9\u60a8\u60f3\u7528\u6765\u6253\u5f00\u6b64\u6587\u4ef6\u7684\u7a0b\u5e8f +explorer.appSelectMenu=\u8bbe\u7f6e\u4e3a\u9ed8\u8ba4\u6253\u5f00\u65b9\u5f0f +explorer.appSelectMenuCancel=\u53d6\u6d88\u8bbe\u7f6e\u4e3a\u9ed8\u8ba4\u6253\u5f00\u65b9\u5f0f +explorer.appSelectWarning=\u8bf7\u9009\u62e9\u5e94\u7528! +explorer.appTypeSupport=\u652f\u6301\u5e94\u7528 +explorer.appTypeAll=\u6240\u6709\u5e94\u7528 +explorer.appSearch=\u641c\u7d22\u76f8\u5173\u7684\u5e94\u7528\u5b89\u88c5 +explorer.recent.createTime=\u521b\u5efa\u4e8e +explorer.recent.modifyTime=\u4fee\u6539\u4e8e +explorer.recent.viewTime=\u6253\u5f00\u4e8e +explorer.urlLink=\u5916\u94fe\u5730\u5740 +explorer.downloading=\u4e0b\u8f7d\u4e2d... +explorer.downReady=\u5373\u5c06\u4e0b\u8f7d +explorer.downError=\u4e0b\u8f7d\u5931\u8d25! +explorer.max=\u6700\u5927\u5316 +explorer.min=\u6700\u5c0f\u5316 +explorer.minAll=\u6700\u5c0f\u5316\u6240\u6709 +explorer.displayAll=\u663e\u793a\u6240\u6709\u7a97\u53e3 +explorer.closeAll=\u5173\u95ed\u6240\u6709 +explorer.authDtl=\u70b9\u51fb\u67e5\u770b\u60a8\u5728\u8be5\u76ee\u5f55\u7684\u6743\u9650 +explorer.authDialog=\u5185\u90e8\u6210\u5458,\u6587\u6863\u534f\u4f5c\u7ea7\u522b\u6743\u9650\u8868 +explorer.authNote=\u6ce8: \u7ba1\u7406\u529f\u80fd\u5305\u542b\u8bbe\u7f6e\u6210\u5458\u6743\u9650/\u8bc4\u8bba\u7ba1\u7406\u7b49\u8c28\u614e\u64cd\u4f5c![\u7cfb\u7edf\u7ba1\u7406\u5458]\u89d2\u8272\u4e0d\u53d7\u4efb\u4f55\u6743\u9650\u9650\u5236 +explorer.auth.toOuter=\u5bf9\u5916\u6388\u6743 (\u5176\u4ed6\u90e8\u95e8\u6216\u7528\u6237) +explorer.auth.share=\u5206\u4eab\u8005 +explorer.auth.owner=\u62e5\u6709\u8005 +explorer.auth.disableDeep=\u65e0\u6743\u9650-\u4ec5\u901a\u8def +explorer.auth.disableDeepDesc=\u56e0\u5b50\u76ee\u5f55\u6709\u6587\u6863\u8bfb\u5199\u6743\u9650\u800c\u5efa\u7acb\u7684\u8bbf\u95ee\u901a\u8def. +explorer.auth.tips=\u53ef\u8054\u7cfb\u4e0a\u8ff0\u7528\u6237\u7ed9\u60a8\u8bbe\u7f6e\u6743\u9650 +explorer.notSystemPath=\u4e0d\u662f\u7cfb\u7edf\u6587\u4ef6\u8def\u5f84 +explorer.toolbar.rootPath=\u4e2a\u4eba\u7a7a\u95f4 +explorer.toolbar.fav=\u6536\u85cf\u5939 +explorer.toolbar.desktop=\u684c\u9762 +explorer.toolbar.client=\u5ba2\u6237\u7aef +explorer.toolbar.myComputer=\u6211\u7684\u7535\u8111 +explorer.toolbar.recycle=\u56de\u6536\u7ad9 +explorer.toolbar.myDocument=\u4e2a\u4eba\u7a7a\u95f4 +explorer.toolbar.myPicture=\u6211\u7684\u7167\u7247 +explorer.toolbar.myMusic=\u6211\u7684\u97f3\u4e50 +explorer.toolbar.myMovie=\u6211\u7684\u89c6\u9891 +explorer.toolbar.myDownload=\u6211\u7684\u4e0b\u8f7d +explorer.toolbar.uiDesktop=\u684c\u9762 +explorer.toolbar.uiExplorer=\u6587\u4ef6\u7ba1\u7406 +explorer.toolbar.uiEditor=\u7f16\u8f91\u5668 +explorer.toolbar.uiProjectHome=\u9879\u76ee\u4e3b\u9875 +explorer.toolbar.uiLogout=\u9000\u51fa +explorer.toolbar.uiGroup=\u7ec4\u7ec7\u67b6\u6784 +explorer.toolbar.myGroup=\u6211\u5728\u7684\u90e8\u95e8 +explorer.toolbar.publicPath=\u516c\u5171\u76ee\u5f55 +explorer.toolbar.recentDoc=\u6700\u8fd1\u6587\u6863 +explorer.toolbar.myShare=\u6211\u7684\u5206\u4eab +explorer.toolbar.shareToMe=\u4e0e\u6211\u534f\u4f5c +explorer.toolbar.shareTo=\u6211\u7684\u534f\u4f5c +explorer.toolbar.shareLink=\u5916\u94fe\u5206\u4eab +explorer.toolbar.photo=\u6211\u7684\u76f8\u518c +explorer.photo.desc=\u7528\u6237\u76f8\u518c\u5f52\u7c7b +explorer.photo.group=\u76f8\u518c\u5206\u7ec4 +explorer.photo.setting=\u76f8\u518c\u8bbe\u7f6e +explorer.photo.pathRoot=\u76f8\u518c\u626b\u63cf\u76ee\u5f55 +explorer.photo.pathRootSelect=\u9009\u62e9\u6587\u4ef6\u5939\u4f5c\u4e3a\u76f8\u518c\u56fe\u7247\u626b\u63cf\u7684\u6839\u76ee\u5f55 +explorer.photo.fileType=\u6307\u5b9a\u6587\u4ef6\u7c7b\u578b +explorer.photo.fileSize=\u6587\u4ef6\u5927\u5c0f\u7b5b\u9009 +explorer.photo.fileSizeDesc=\u4ec5\u7b5b\u9009\u5927\u4e8e\u8be5\u8bbe\u7f6e\u7684\u6587\u4ef6\u4e3a0\u5219\u4e0d\u9650\u5236 +explorer.toolbar.folder=\u76ee\u5f55\u76f8\u518c +explorer.toolbar.folderSelect=\u9009\u62e9\u6587\u4ef6\u5939\u4ee5\u76f8\u518c\u6a21\u5f0f\u5c55\u793a +explorer.pathDesc.fav=\u6587\u4ef6\u6dfb\u52a0\u6536\u85cf\u540e\u53ef\u4ee5\u5b9e\u73b0\u5feb\u901f\u8bbf\u95ee,\u4e00\u70b9\u76f4\u8fbe +explorer.pathDesc.home=\u4e2a\u4eba\u7a7a\u95f4\u662f\u60a8\u7684\u79c1\u6709\u5b58\u50a8\u7a7a\u95f4\u4ec5\u81ea\u5df1\u53ef\u89c1,\u5176\u4ed6\u7528\u6237\u4e0d\u53ef\u89c1 +explorer.pathDesc.groupRoot=\u8fd9\u91cc\u662f\u4f01\u4e1a/\u5355\u4f4d\u7684\u516c\u5171\u7a7a\u95f4,\u9ed8\u8ba4\u6240\u6709\u6210\u5458\u53ef\u89c1 +explorer.pathDesc.myGroup=\u5728\u8fd9\u91cc\u7ba1\u7406\u60a8\u7684\u6240\u5728\u90e8\u95e8\u7684\u6587\u6863\u90e8\u95e8\u6587\u6863\u4ec5\u672c\u90e8\u95e8\u6210\u5458\u53ef\u89c1,\u53ef\u64cd\u4f5c,\u5176\u4ed6\u90e8\u95e8\u6210\u5458\u4e0d\u53ef\u89c1 +explorer.pathDesc.group=\u90e8\u95e8\u7f51\u76d8\u4ec5\u8be5\u90e8\u95e8\u6210\u5458\u53ef\u89c1\u64cd\u4f5c\u6743\u9650\u7531\u90e8\u95e8\u7ba1\u7406\u5458\u5206\u914d\u8bbe\u5b9a. +explorer.pathDesc.recentDoc=\u6700\u8fd1\u65b0\u5efa/\u4e0a\u4f20/\u4fee\u6539/\u6253\u5f00\u7684\u6587\u4ef6 +explorer.pathDesc.shareTo=\u5728\u8fd9\u91cc\u67e5\u770b\u548c\u7ba1\u7406\u60a8\u5411\u4ed6\u4eba\u53d1\u8d77\u7684[\u5185\u90e8\u534f\u4f5c]\u9879\u76ee +explorer.pathDesc.shareLink=\u5728\u8fd9\u91cc\u67e5\u770b\u548c\u7ba1\u7406\u60a8\u53d1\u8d77\u7684\u5916\u94fe\u5206\u4eab +explorer.pathDesc.recycle=\u5728\u8fd9\u91cc\u7ba1\u7406\u60a8\u5220\u9664\u7684\u6587\u4ef6(\u5939) +explorer.pathDesc.fileType=\u6309\u7c7b\u578b\u5bf9\u6587\u4ef6\u8fdb\u884c\u5206\u7c7b\u4ec5\u4e2a\u4eba\u7a7a\u95f4\u5185\u6587\u4ef6 +explorer.pathDesc.tag=\u7ed9\u6587\u4ef6(\u5939)\u6dfb\u52a0\u6807\u7b7e,\u5b9e\u73b0\u9ad8\u6548\u5206\u7c7b\u548c\u5feb\u901f\u67e5\u8be2 +explorer.pathDesc.tagItem=\u8bd5\u8bd5\u7ed9\u6587\u4ef6/\u6587\u4ef6\u5939\u6dfb\u52a0\u4e2a\u6807\u7b7e\u5427! +explorer.pathDesc.mount=\u5728\u8fd9\u91cc\u60a8\u53ef\u4ee5\u7ba1\u7406\u591a\u4e2a\u540e\u53f0\u5b58\u50a8\u4ee5\u53ca\u8be5\u670d\u52a1\u5668\u4e0a\u6302\u8f7d\u7684\u78c1\u76d8 +explorer.pathDesc.shareToMe=\u6240\u6709\u4e0e\u6211\u534f\u4f5c\u7684\u5185\u5bb9\u5305\u542b\u90e8\u95e8\u7a7a\u95f4\u534f\u4f5c\u5185\u5bb9\u53ca\u4e2a\u4eba\u7a7a\u95f4\u534f\u4f5c\u5185\u5bb9 +explorer.pathDesc.shareToMeUser=\u4e0e\u6211\u534f\u4f5c\u7684\u5185\u5bb9\u6309\u53d1\u8d77\u8005\u8fdb\u884c\u5206\u7c7b +explorer.pathDesc.shareToMeUserItem=\u8be5\u7528\u6237\u53d1\u8d77\u7684\u534f\u4f5c +explorer.pathDesc.shareToMeGroup=\u4e0e\u6211\u534f\u4f5c\u7684\u5185\u5bb9\u6309\u6587\u4ef6\u5939\u6240\u5728\u90e8\u95e8\u8fdb\u884c\u5206\u7c7b +explorer.pathDesc.shareToMeGroupGroup=\u6765\u81ea\u4e8e\u8be5\u90e8\u95e8\u7a7a\u95f4\u4e0b\u7684\u534f\u4f5c\u5206\u4eab +explorer.pathDesc.search=\u652f\u6301\u641c\u7d22\u6587\u4ef6/\u6807\u7b7e/\u5907\u6ce8/\u5185\u5bb9;\u652f\u6301\u62fc\u97f3,\u9996\u5b57\u6bcd\u6a21\u7cca\u5339\u914d +explorer.pathDesc.searchMore=\u8bbe\u7f6e\u66f4\u591a\u68c0\u7d22\u6761\u4ef6 +explorer.pathDesc.shareFrom=\u534f\u4f5c\u6765\u6e90 +explorer.pathGroup.shareGroup=\u90e8\u95e8\u7a7a\u95f4 +explorer.pathGroup.shareGroupDesc=\u4e0b\u7ea7\u90e8\u95e8\u4e2d\u6709\u5185\u5bb9\u65f6\u901a\u8def +explorer.pathGroup.shareUser=\u90e8\u95e8\u6210\u5458\u7684\u4e2a\u4eba\u7a7a\u95f4\u5206\u4eab +explorer.pathGroup.shareUserDesc=\u6765\u6e90: \u7528\u6237\u4e2a\u4eba\u7a7a\u95f4\u5206\u4eab \u8be5\u7528\u6237\u53d1\u8d77\u7684\u5916\u90e8\u90e8\u95e8\u6587\u6863\u5206\u4eab. +explorer.pathGroup.shareContent=\u8be5\u90e8\u95e8\u7a7a\u95f4\u534f\u4f5c\u5206\u4eab +explorer.pathGroup.group=\u5b50\u90e8\u95e8 +explorer.pathGroup.groupContent=\u90e8\u95e8\u6587\u6863 +explorer.pathGroup.shareUserOuter=\u5916\u90e8\u534f\u4f5c\u5206\u4eab +explorer.pathGroup.shareUserOuterDesc=\u4e0d\u5728\u81ea\u5df1\u7ec4\u7ec7\u67b6\u6784\u4e0b\u7684\u5916\u90e8\u7528\u6237\u7684\u534f\u4f5c\u5206\u4eab +explorer.pathGroup.shareSelf=\u4e2a\u4eba\u7a7a\u95f4 +explorer.toolbar.fileSizeTitle=\u56fe\u6807\u5927\u5c0f +explorer.toolbar.fileSizeSuper=\u8d85\u5c0f +explorer.toolbar.fileSizeSmall=\u5c0f\u56fe\u6807 +explorer.toolbar.fileSizeDefault=\u4e2d\u56fe\u6807 +explorer.toolbar.fileSizeBig=\u5927\u56fe\u6807 +explorer.toolbar.fileSizeBigSuper=\u8d85\u5927\u56fe\u6807 +explorer.toolbar.PagePC=\u7535\u8111\u7248 +explorer.toolbar.pagePhone=\u624b\u673a\u7248 +explorer.file.name=\u540d\u79f0 +explorer.file.type=\u7c7b\u578b +explorer.file.contain=\u5305\u542b +explorer.file.address=\u4f4d\u7f6e +explorer.file.detil=\u63cf\u8ff0\u8bf4\u660e +explorer.file.linkCount=\u5f15\u7528\u6570 +explorer.file.size=\u5927\u5c0f +explorer.file.count=\u6570\u91cf +explorer.file.byte=\u5b57\u8282 +explorer.file.path=\u8def\u5f84 +explorer.file.action=\u64cd\u4f5c +explorer.file.creator=\u521b\u5efa\u8005 +explorer.file.editor=\u4fee\u6539\u8005 +explorer.file.location=\u6240\u5728\u4f4d\u7f6e +explorer.file.timeInfo=\u65f6\u95f4\u4fe1\u606f +explorer.file.createTime=\u521b\u5efa\u65f6\u95f4 +explorer.file.modifyTime=\u4fee\u6539\u65f6\u95f4 +explorer.file.lastTime=\u6700\u540e\u8bbf\u95ee +explorer.file.sortType=\u6392\u5e8f\u65b9\u5f0f +explorer.file.sortDisable=\u8be5\u5185\u5bb9\u4e0d\u652f\u6301\u6307\u5b9a\u6392\u5e8f! +explorer.file.timeType=Y/m/d H:i:s +explorer.file.timeTypeInfo=Y/m/d H:i:s +explorer.file.listType=\u67e5\u770b +explorer.file.listIcon=\u56fe\u6807\u6392\u5217 +explorer.file.listList=\u5217\u8868\u6392\u5217 +explorer.file.listListSplit=\u5206\u680f\u6a21\u5f0f +explorer.file.listTypeGroup=\u663e\u793a\u6a21\u5f0f\u53ca\u6392\u5e8f\u65b9\u5f0f +explorer.file.listTypeKeep=\u663e\u793a\u6a21\u5f0f +explorer.file.listTypeKeepDesc=\u4e3a\u6bcf\u4e2a\u6587\u4ef6\u5939\u9009\u62e9\u89c6\u56fe\u6a21\u5f0f,\u6216\u5bf9\u6240\u6709\u6587\u4ef6\u5939\u4f7f\u7528\u76f8\u540c\u7684\u89c6\u56fe\u6a21\u5f0f +explorer.file.listSortKeep=\u6392\u5e8f\u65b9\u5f0f +explorer.file.listSortKeepDesc=\u4e3a\u6bcf\u4e2a\u6587\u4ef6\u5939\u914d\u7f6e\u5217\u6392\u5e8f\u987a\u5e8f,\u6216\u5bf9\u6240\u6709\u6587\u4ef6\u5939\u4f7f\u7528\u76f8\u540c\u7684\u987a\u5e8f +explorer.file.listViewKeep=\u9002\u7528\u4e8e\u5355\u4e2a\u6587\u4ef6\u5939 +explorer.file.listViewAll=\u9002\u7528\u4e8e\u6240\u6709\u6587\u4ef6\u5939 +explorer.file.listViewReset=\u91cd\u7f6e\u5230\u9ed8\u8ba4 +explorer.file.sortUp=\u9012\u589e +explorer.file.sortDown=\u9012\u51cf +explorer.file.orderType=\u6392\u5e8f\u65b9\u5f0f +explorer.file.orderDesc=\u964d\u5e8f +explorer.file.orderAsc=\u5347\u5e8f +explorer.file.imageSize=\u56fe\u7247\u5c3a\u5bf8 +explorer.file.sharer=\u5206\u4eab\u8005 +explorer.file.shareTime=\u5206\u4eab\u65f6\u95f4 +explorer.file.viewCnt=\u6d4f\u89c8\u6570 +explorer.file.downCnt=\u4e0b\u8f7d\u6570 +explorer.file.readWriteLock=\u6682\u4e0d\u652f\u6301\u8be5\u64cd\u4f5c\u6709\u5176\u4ed6\u8bfb\u5199\u4efb\u52a1\u6b63\u5728\u5904\u7406\u4e2d\u8bf7\u7a0d\u540e\u518d\u8bd5! +explorer.app.app=\u8f7b\u5e94\u7528 +explorer.app.createLink=\u65b0\u5efa\u7f51\u5740 +explorer.app.create=\u521b\u5efa\u8f7b\u5e94\u7528 +explorer.app.edit=\u7f16\u8f91\u8f7b\u5e94\u7528 +explorer.app.open=\u6253\u5f00\u8f7b\u5e94\u7528 +explorer.app.groupGame=\u6e38\u620f +explorer.app.groupTools=\u5de5\u5177 +explorer.app.groupReader=\u9605\u8bfb +explorer.app.groupMovie=\u5f71\u89c6 +explorer.app.groupMusic=\u97f3\u4e50 +explorer.app.groupLife=\u751f\u6d3b +explorer.app.desc=\u5e94\u7528\u63cf\u8ff0 +explorer.app.icon=\u5e94\u7528\u56fe\u6807 +explorer.app.iconShow=url\u5730\u5740\u6216\u8be5\u76ee\u5f55 +explorer.app.group=\u5e94\u7528\u5206\u7ec4 +explorer.app.type=\u7c7b\u578b +explorer.app.typeUrl=\u94fe\u63a5 +explorer.app.typeCode=js\u6269\u5c55 +explorer.app.display=\u5916\u89c2 +explorer.app.displayBorder=\u65e0\u8fb9\u6846(\u9009\u4e2d\u5373\u65e0\u8fb9\u6846) +explorer.app.displaySize=\u8c03\u6574\u5927\u5c0f(\u9009\u4e2d\u5373\u53ef\u8c03\u6574) +explorer.app.size=\u5c3a\u5bf8 +explorer.app.url=\u94fe\u63a5\u5730\u5740 +explorer.app.code=js\u4ee3\u7801 +explorer.app.appType=\u5e94\u7528\u7c7b\u578b +explorer.app.website=\u7f51\u5740 +explorer.app.shortLink=\u6587\u4ef6\u5feb\u6377\u65b9\u5f0f +explorer.app.imgIcon=\u56fe\u7247\u56fe\u6807 +explorer.app.imgIconUrl=\u9009\u62e9\u56fe\u7247\u6216\u5219\u7c98\u8d34\u7f51\u7edc\u56fe\u7247url. +explorer.app.path=\u8def\u5f84 +explorer.app.pathDesc=\u4e0d\u652f\u6301\u624b\u52a8\u4fee\u6539,\u53ef\u4ee5\u6587\u4ef6\u53f3\u952e\u521b\u5efa\u5feb\u6377\u65b9\u5f0f +explorer.app.link=\u7f51\u5740\u94fe\u63a5 +explorer.app.linkDesc=\u8bf7\u8f93\u5165http/https\u94fe\u63a5 +explorer.app.linkDragTips=\u53ef\u4ee5\u5c06url\u94fe\u63a5\u62d6\u5165\u5230\u6587\u4ef6\u533a\u57df\u81ea\u52a8\u521b\u5efa\u7f51\u5740\u94fe\u63a5! +explorer.app.openType=\u6253\u5f00\u65b9\u5f0f +explorer.app.openWindow=\u65b0\u7a97\u53e3 +explorer.app.openDialog=\u5bf9\u8bdd\u6846 +explorer.app.openCurrent=\u5f53\u524d\u9875 +explorer.app.openInline=\u5d4c\u5165\u9875\u9762 +explorer.app.dialogSize=\u5bf9\u8bdd\u6846\u5c3a\u5bf8 +explorer.app.with=\u5bbd\u5ea6 +explorer.app.height=\u9ad8\u5ea6 +explorer.app.moreSet=\u66f4\u591a\u8bbe\u7f6e +explorer.app.canDiyWith=\u5141\u8bb8\u8c03\u6574\u5bbd\u5ea6 +explorer.app.miniBlock=\u6781\u7b80\u6807\u9898\u680f +explorer.app.runCode=\u6267\u884cjs\u4ee3\u7801 +explorer.app.name=\u5e94\u7528\u540d +explorer.app.nameDesc=\u8bf7\u8f93\u5165\u5e94\u7528\u540d. +explorer.app.descDesc=\u8bf7\u8f93\u5165\u5e94\u7528\u63cf\u8ff0 +explorer.embed.title=\u5d4c\u5165\u6587\u4ef6 +explorer.embed.desc=\u5c06\u8be5\u6587\u4ef6\u5d4c\u5165\u5230\u7f51\u9875\u6216\u535a\u5ba2\u4e2d +explorer.embed.url=\u5d4c\u5165URL +explorer.embed.code=\u5d4c\u5165\u4ee3\u7801 +explorer.upload.ready=\u7b49\u5f85\u4e0a\u4f20 +explorer.upload.success=\u4e0a\u4f20\u6210\u529f +explorer.upload.secPassSuccess=\u79d2\u4f20\u6210\u529f +explorer.upload.pathCurrent=\u5207\u6362\u5230\u5f53\u524d\u76ee\u5f55 +explorer.upload.select=\u9009\u62e9\u6587\u4ef6 +explorer.upload.maxSize=\u6700\u5927\u5141\u8bb8 +explorer.upload.sizeInfo=\u5982\u679c\u60f3\u914d\u7f6e\u66f4\u5927,\u8bf7\u4fee\u6539php.ini\u4e2d\u5141\u8bb8\u4e0a\u4f20\u7684\u6700\u5927\u503c��\u9009\u62e9\u6587\u4ef6\u65f6\u5927\u4e8e\u8be5\u914d\u7f6e\u7684\u5c06\u81ea\u52a8\u8fc7\u6ee4\u6389�� +explorer.upload.error=\u4e0a\u4f20\u5931\u8d25 +explorer.upload.mergeError=\u5408\u5e76\u6587\u4ef6\u5931\u8d25 +explorer.upload.errorHttp=\u7f51\u7edc\u6216\u9632\u706b\u5899\u9519\u8bef +explorer.upload.muti=\u591a\u6587\u4ef6\u4e0a\u4f20 +explorer.upload.drag=\u62d6\u62fd\u4e0a\u4f20 +explorer.upload.dragFolder=\u62d6\u62fd\u5230\u6587\u4ef6\u5939\u4e0a\u4f20 +explorer.upload.dragTips=\u677e\u5f00\u5373\u53ef\u4e0a\u4f20! +explorer.upload.pathNotAllow=\u6587\u4ef6\u540d\u4e0d\u5141\u8bb8\u51fa\u73b0 +explorer.upload.errorNull=\u6ca1\u6709\u6587\u4ef6! +explorer.upload.errorBig=\u6587\u4ef6\u5927\u5c0f\u8d85\u8fc7\u670d\u52a1\u5668\u9650\u5236 +explorer.upload.errorMove=\u79fb\u52a8\u6587\u4ef6\u5931\u8d25! +explorer.upload.errorExists=\u8be5\u6587\u4ef6\u5df2\u5b58\u5728 +explorer.upload.local=\u672c\u5730\u4e0a\u4f20 +explorer.upload.tips=\u91c7\u7528\u5206\u7247\u4e0a\u4f20\u4e0d\u518d\u53d7php.ini\u9650\u5236;\u63a8\u8350chrome\u4f53\u9a8c\u6587\u4ef6\u5939\u62d6\u62fd\u4e0a\u4f20 +explorer.upload.exist=\u540c\u540d\u6587\u4ef6\u5904\u7406 +explorer.upload.clearAll=\u6e05\u7a7a\u6240\u6709 +explorer.upload.clear=\u6e05\u7a7a\u5df2\u5b8c\u6210 +explorer.upload.addMore=\u6279\u91cf\u6dfb\u52a0 +explorer.upload.errorEmpty=\u4e0d\u80fd\u4e3a\u7a7a\u6587\u4ef6! +explorer.upload.errorExt=\u6587\u4ef6\u6269\u5c55\u540d\u4e0d\u5339\u914d! +explorer.upload.fileSizeDisable=\u540c\u65f6\u4e0a\u4f20/\u8f6c\u5b58\u6587\u4ef6\u6570\u8fc7\u591a\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u8fdb\u884c\u8c03\u6574! +explorer.upload.moreDesc=(\u5efa\u8bae\u4e0d\u5927\u4e8e2000)\u5f53\u524d\u603b\u5171: +explorer.upload.scan=\u626b\u63cf\u4e2d +explorer.upload.merge=\u6821\u9a8c\u5408\u5e76\u4e2d +explorer.upload.needTime=\u5269\u4f59\u7ea6 +explorer.upload.checkError=\u4e0a\u4f20\u6821\u9a8c\u5931\u8d25\u8bf7\u91cd\u8bd5 +explorer.upload.saveError=\u4e0a\u4f20\u6587\u4ef6\u4fe1\u606f\u4fdd\u5b58\u5931\u8d25 +explorer.upload.downloadDesc=\u4ec5\u652f\u6301http/https\u7f51\u7edc\u94fe\u63a5 +explorer.table.first=\u9996\u9875 +explorer.table.last=\u5c3e\u9875 +explorer.table.prev=\u4e0a\u4e00\u9875 +explorer.table.next=\u4e0b\u4e00\u9875 +explorer.table.one=\u51711\u9875 +explorer.table.page=\u9875 +explorer.table.itemPage=\u6761/\u9875 +explorer.table.searchTotal=\u5171\u641c\u7d22\u5230 +explorer.table.items=\u6761\u8bb0\u5f55 +explorer.table.list=\u6570\u636e\u5217\u8868 +explorer.search.ing=\u641c\u7d22\u4e2d... +explorer.search.result=\u641c\u7d22\u7ed3\u679c +explorer.search.resultTooMore=\u641c\u7d22\u7ed3\u679c\u592a\u591a,\u5efa\u8bae\u6362\u4e00\u4e2a\u76ee\u5f55\u6216\u8bcd\u8bed +explorer.search.resultNull=\u6ca1\u6709\u641c\u7d22\u7ed3\u679c! +explorer.search.caseSensitive=\u533a\u5206\u5927\u5c0f\u5199 +explorer.search.content=\u641c\u7d22\u6587\u4ef6\u5185\u5bb9 +explorer.search.extDesc=\u8f93\u5165\u9700\u8981\u7b5b\u9009\u7684\u6269\u5c55\u540d,\u7528\u7a7a\u683c\u9694\u5f00. +explorer.search.byItems=\u4e2a\u6761\u4ef6\u7b5b\u9009 +explorer.search.extNull=\u4e0d\u9650\u7c7b\u578b +explorer.search.extFile=\u4efb\u610f\u6587\u4ef6 +explorer.search.extDiy=\u81ea\u5b9a\u4e49 +explorer.search.inputDesc=\u8bf7\u8f93\u5165\u5173\u952e\u5b57\u6216\u7ed9\u51fa\u7b5b\u9009\u6761\u4ef6! +explorer.search.path=\u641c\u7d22\u76ee\u5f55: +explorer.search.rootPath=\u641c\u7d22\u6839\u76ee\u5f55: +explorer.search.range=\u641c\u7d22\u8303\u56f4 +explorer.search.allFolder=\u5168\u90e8\u6587\u4ef6\u5939 +explorer.search.currentFolder=\u5f53\u524d\u6587\u4ef6\u5939 +explorer.search.ext=\u6587\u4ef6\u7c7b\u578b +explorer.search.timeRange=\u65f6\u95f4\u8303\u56f4 +explorer.search.timeAll=\u4e0d\u9650\u65f6\u95f4 +explorer.search.lastDay=\u8fd11\u5929 +explorer.search.lastWeek=\u6700\u8fd17\u5929 +explorer.search.lastMonth=\u6700\u8fd130\u5929 +explorer.search.lastYear=\u6700\u8fd1\u4e00\u5e74 +explorer.search.sizeAll=\u4e0d\u9650\u5927\u5c0f +explorer.search.inputNullDesc=\u4e0d\u586b\u5219\u4ee3\u8868\u5927\u4e8e\u6216\u5c0f\u4e8e\u67d0\u4e2a\u503c\u53ef\u4ee5\u4e3a\u5c0f\u6570. +explorer.search.selectUser=\u9009\u62e9\u7528\u6237... +explorer.search.byUserDesc=\u6309\u521b\u5efa\u8005/\u4fee\u6539\u8005\u641c\u7d22 +explorer.search.total=\u5171\u641c\u7d22\u5230 +explorer.search.noResult=\u62b1\u6b49,\u6ca1\u6709\u641c\u7d22\u7ed3\u679c,\u8bf7\u6362\u4e2a\u641c\u7d22\u8bcd\u518d\u8bd5\u5427! +explorer.search.advance=\u9ad8\u7ea7\u641c\u7d22 +explorer.search.clear=\u6e05\u7a7a\u5185\u5bb9 +explorer.history.list=\u6587\u4ef6\u5386\u53f2\u8bb0\u5f55 +explorer.history.lastModify=\u6700\u540e\u4fee\u6539\u65f6\u95f4 +explorer.history.modifyUser=\u7248\u672c\u4fee\u6539\u8005 +explorer.history.noHistory=\u6ca1\u6709\u5386\u53f2\u7248\u672c! +explorer.history.current=\u5f53\u524d\u7248\u672c +explorer.history.detil=\u63cf\u8ff0\u8bf4\u660e +explorer.history.detilAdd=\u6dfb\u52a0\u7248\u672c\u8bf4\u660e +explorer.history.uploadNew=\u4e0a\u4f20\u65b0\u7248\u672c +explorer.history.diff=\u5386\u53f2\u7248\u672c\u5bf9\u6bd4 +explorer.history.setCurrent=\u8fd9\u662f\u56de\u6eda\u524d\u7684\u7248\u672c +explorer.history.delCurrent=\u5220\u9664\u8be5\u7248\u672c +explorer.history.delAll=\u5220\u9664\u6240\u6709\u7248\u672c\u8bb0\u5f55 +explorer.history.ifDelAll=\u786e\u5b9a\u5220\u9664\u6240\u6709\u5386\u53f2\u8bb0\u5f55? +explorer.history.ifDelCurrent=\u5220\u9664\u8be5\u7248\u672c? +explorer.history.ifRollback=\u786e\u5b9a\u8981\u56de\u6eda\u5230\u8be5\u7248\u672c? +explorer.history.changeEvent=\u5386\u53f2\u7248\u672c\u5207\u6362 +explorer.history.before=\u4fee\u6539\u524d +explorer.history.after=\u4fee\u6539\u540e +explorer.recycle.clearUser=\u6e05\u7a7a\u8be5\u7528\u6237\u56de\u6536\u7ad9 +explorer.recycle.restoreSelect=\u8fd8\u539f\u8be5\u5185\u5bb9 +explorer.recycle.moveTo=\u79fb\u4ea4\u7ed9 +explorer.recycle.config=\u56de\u6536\u7ad9\u8bbe\u7f6e +explorer.recycle.configTitle=\u7cfb\u7edf\u56de\u6536\u7ad9\u8bbe\u7f6e +explorer.recycle.configOpen=\u5f00\u542f\u7cfb\u7edf\u56de\u6536\u7ad9 +explorer.recycle.configOpenDesc=\u5efa\u8bae\u5f00\u542f +explorer.recycle.configCloseInfo=\u5220\u9664\u5185\u5bb9\u65f6\u4e0d\u4f1a\u8fdb\u5165\u7cfb\u7edf\u56de\u6536\u7ad9;\u76f4\u63a5\u5f7b\u5e95\u5220\u9664. +explorer.recycle.configOpenInfo=
  • \u4e2a\u4eba\u6587\u6863\u6216\u90e8\u95e8\u6587\u4ef6\u5728\u5f7b\u5e95\u5220\u9664\u6216\u6e05\u7a7a\u56de\u6536\u7ad9\u540e\u8fdb\u5165\u7cfb\u7edf\u56de\u6536\u7ad9
  • \u5220\u9664\u5185\u5bb9\u6309\u6587\u4ef6\u6240\u5728\u7528\u6237\u6216\u90e8\u95e8\u5f52\u7c7b\u5728\u7528\u6237\u6216\u90e8\u95e8\u6587\u4ef6\u5939\u4e2d\u7ba1\u7406\u5458\u53ef\u4ee5\u9009\u62e9\u8fd8\u539f\u8fd9\u4e9b\u6587\u4ef6;
  • \u8d85\u8fc7\u81ea\u52a8\u5f7b\u5e95\u5220\u9664\u65f6\u95f4\u4e4b\u524d\u7684\u6587\u4ef6\u5c06\u5b9a\u671f\u81ea\u52a8\u6e05\u7a7a;
  • \u6ce8\u610f: \u5728\u6b64\u5904\u5220\u9664\u7684\u6587\u4ef6\u4e0d\u80fd\u518d\u6062\u590d.
  • +explorer.recycle.configClear=\u81ea\u52a8\u5f7b\u5e95\u5220\u9664 +explorer.recycle.restoreConfirm=\u786e\u5b9a\u8fd8\u539f\u6587\u6863?
    \u8fd8\u539f\u540e\u6587\u6863\u5c06\u79fb\u52a8\u5230\u76ee\u6807\u6839\u76ee\u5f55 +explorer.recycle.moveConfirm=\u786e\u8ba4\u79fb\u4ea4 +explorer.recycle.moveSelectTarget=\u9009\u62e9\u7528\u6237\u6216\u90e8\u95e8 +explorer.recycle.moveDesc=
  • \u79fb\u4ea4\u7ed9\u6307\u5b9a\u7528\u6237\u6216\u8005\u90e8\u95e8;\u4f1a\u8fc1\u79fb\u5bf9\u8c61\u6839\u76ee\u5f55\u4e0b
  • \u79fb\u4ea4\u540e\u6587\u6863\u8bf4\u660e\u4ea4\u6d41\u8ba8\u8bba\u5386\u53f2\u7248\u672c\u7b49\u4fe1\u606f\u5c06\u4f1a\u7ee7\u7eed\u4fdd\u7559;\u5206\u4eab\u534f\u4f5c\u53ca\u6743\u9650\u4fe1\u606f\u4f1a\u79fb\u9664
  • +explorer.recycle.taskTitle=\u7cfb\u7edf\u56de\u6536\u7ad9\u6e05\u7406 +explorer.recycle.taskDesc=\u81ea\u52a8\u5220\u9664\u8d85\u8fc7\u8bbe\u7f6e\u65f6\u95f4\u7684\u56de\u6536\u7ad9\u5185\u5bb9\u91ca\u653e\u5b58\u50a8\u7a7a\u95f4 +explorer.share.add=\u6dfb\u52a0\u5206\u4eab +explorer.share.edit=\u7f16\u8f91\u5206\u4eab +explorer.share.remove=\u53d6\u6d88\u5206\u4eab +explorer.share.path=\u5206\u4eab\u8def\u5f84 +explorer.share.source=\u8d44\u6e90\u5206\u4eab +explorer.share.name=\u5206\u4eab\u6807\u9898 +explorer.share.nameDesc=\u9ed8\u8ba4\u4e3a\u5206\u4eab\u6587\u6863\u540d,\u53ef\u81ea\u5b9a\u4e49\u540d\u79f0 +explorer.share.time=\u5230\u671f\u65f6\u95f4 +explorer.share.timeLimit=\u9650\u5b9a\u65f6\u95f4 +explorer.share.timeLimitDesc=\u5f00\u542f\u5e76\u8bbe\u7f6e\u540e\u8d85\u8fc7\u65f6\u95f4\u5206\u4eab\u81ea\u52a8\u5931\u6548 +explorer.share.timeDesc=\u4e3a\u7a7a\u5219\u4e0d\u8bbe\u7f6e +explorer.share.pwd=\u63d0\u53d6\u5bc6\u7801 +explorer.share.pwdDesc=\u4e3a\u7a7a\u5219\u4e0d\u8bbe\u7f6e\u5bc6\u7801 +explorer.share.randomPwd=\u968f\u673a\u751f\u6210 +explorer.share.randomPwdDesc=\u4ec5\u9650\u63d0\u53d6\u5bc6\u7801\u624d\u80fd\u67e5\u770b,\u66f4\u52a0\u9690\u79c1\u5b89\u5168. +explorer.share.cancel=\u53d6\u6d88\u5171\u4eab +explorer.share.create=\u521b\u5efa\u516c\u5f00\u94fe\u63a5 +explorer.share.url=\u5171\u4eab\u5730\u5740 +explorer.share.noDown=\u7981\u6b62\u4e0b\u8f7d +explorer.share.codeRead=\u4ee3\u7801\u9605\u8bfb +explorer.share.configSave=\u4fdd\u5b58\u914d\u7f6e +explorer.share.errorParam=\u53c2\u6570\u9519\u8bef! +explorer.share.errorUser=\u7528\u6237\u4fe1\u606f\u9519\u8bef! +explorer.share.errorSid=\u5171\u4eab\u4e0d\u5b58\u5728! +explorer.share.errorTime=\u60a8\u6765\u665a\u4e86\u8be5\u5171\u4eab\u5df2\u7ecf\u8fc7\u671f! +explorer.share.errorPath=\u5171\u4eab\u6587\u4ef6\u4e0d\u5b58\u5728\u88ab\u5220\u9664\u6216\u8005\u79fb\u8d70\u4e86! +explorer.share.errorPwd=\u5bc6\u7801\u9519\u8bef! +explorer.share.errorShowTips=\u8be5\u7c7b\u578b\u6587\u4ef6\u6682\u4e0d\u652f\u6301\u9884\u89c8! +explorer.share.expiredTips=\u62b1\u6b49,\u8be5\u5206\u4eab\u5df2\u8fc7\u671f\u8bf7\u8054\u7cfb\u5206\u4eab\u8005! +explorer.share.downExceedTips=\u62b1\u6b49,\u8be5\u5206\u4eab\u4e0b\u8f7d\u6b21\u6570\u8d85\u8fc7\u5206\u4eab\u8005\u8bbe\u7f6e\u7684\u4e0a\u9650 +explorer.share.store=\u4fdd\u5b58\u5230\u7f51\u76d8 +explorer.share.loginTips=\u62b1\u6b49,\u8be5\u5206\u4eab\u5fc5\u987b\u767b\u5f55\u7528\u6237\u624d\u80fd\u8bbf\u95ee! +explorer.share.noDownTips=\u62b1\u6b49,\u8be5\u5206\u4eab\u8005\u7981\u7528\u4e86\u4e0b\u8f7d! +explorer.share.noViewTips=\u62b1\u6b49,\u8be5\u5206\u4eab\u8005\u7981\u7528\u4e86\u9884\u89c8! +explorer.share.noUploadTips=\u62b1\u6b49,\u8be5\u5206\u4eab\u8005\u7981\u7528\u4e86\u4e0a\u4f20! +explorer.share.needPwd=\u8be5\u5206\u4eab\u9700\u8981\u5bc6\u7801 +explorer.share.notExist=\u5206\u4eab\u4e0d\u5b58\u5728! +explorer.share.viewNum=\u6d4f\u89c8: +explorer.share.downNum=\u4e0b\u8f7d\u6b21\u6570 +explorer.share.openPage=\u6253\u5f00\u5171\u4eab\u9875\u9762 +explorer.share.openLink=\u6253\u5f00\u5206\u4eab\u94fe\u63a5 +explorer.share.copyLink=\u590d\u5236\u5206\u4eab\u4fe1\u606f +explorer.share.link=\u5206\u4eab\u94fe\u63a5: +explorer.share.accessPwd=\u8bbf\u95ee\u5bc6\u7801: +explorer.share.copied=\u5df2\u590d\u5236 +explorer.share.actionNotSupport=\u5206\u4eab\u5185\u5bb9\u4e0d\u652f\u6301\u8be5\u64cd\u4f5c +explorer.share.errorPathTips=\u5206\u4eab\u94fe\u63a5\u9519\u8bef\u6216\u5206\u4eab\u8005\u5df2\u7ecf\u53d6\u6d88\u4e86\u8be5\u5916\u94fe\u5206\u4eab +explorer.share.shareTo=\u534f\u4f5c\u5206\u4eab +explorer.share.shareToTarget=\u534f\u4f5c\u6210\u5458 +explorer.share.innerTo=\u5185\u90e8\u534f\u4f5c +explorer.share.linkTo=\u5916\u94fe\u5206\u4eab +explorer.share.selectTarget=\u9009\u62e9\u534f\u4f5c\u5206\u4eab\u7684\u90e8\u95e8\u6216\u7528\u6237 +explorer.share.afterShareDesc=\u5206\u4eab\u7ed9\u5bf9\u65b9\u6216\u5bf9\u65b9\u6240\u5728\u90e8\u95e8\u540e,\u7528\u6237\u53ef\u4ee5\u5728[\u5206\u4eab\u7ed9\u6211\u7684]\u4e2d\u770b\u5230�� +explorer.share.openOuterLink=\u5f00\u653e\u5916\u94fe\u5206\u4eab +explorer.share.openOuterLinkDesc=\u521b\u5efa\u5916\u94fe\u540e,\u53ef\u4ee5\u901a\u8fc7\u90ae\u4ef6\u6216QQ\u53d1\u9001\u7ed9\u5176\u4ed6\u4eba�� +explorer.share.outerLink=\u5206\u4eab\u94fe\u63a5 +explorer.share.advanceSet=\u9ad8\u7ea7\u914d\u7f6e +explorer.share.loginLimit=\u4ec5\u767b\u5f55\u7528\u6237\u53ef\u7528 +explorer.share.loginLimitDesc=\u5f00\u542f\u540e\u4ec5\u5185\u90e8\u6210\u5458\u53ef\u8bbf\u95ee. +explorer.share.authLimit=\u6743\u9650\u53ca\u9650\u5236 +explorer.share.canUpload=\u5141\u8bb8\u4e0a\u4f20 +explorer.share.notView=\u7981\u7528\u9884\u89c8 +explorer.share.notDown=\u7981\u7528\u4e0b\u8f7d +explorer.share.downNumLimit=\u4e0b\u8f7d\u6b21\u6570\u9650\u5236 +explorer.share.downNumLimitDesc=\u8d85\u8fc7\u8be5\u6b21\u6570,\u5206\u4eab\u94fe\u63a5\u81ea\u52a8\u5931\u6548. +explorer.share.learnAuth=\u4e86\u89e3\u6587\u6863\u534f\u4f5c\u6743\u9650 +explorer.share.shareToRemove=\u786e\u5b9a\u53d6\u6d88\u8be5\u534f\u4f5c\u5206\u4eab?
    \u5206\u4eab\u7ed9\u7684\u76ee\u6807\u7528\u6237\u4e0d\u518d\u80fd\u770b\u5230\u8be5\u534f\u4f5c\u5206\u4eab! +explorer.share.shareLinkRemove=\u786e\u5b9a\u53d6\u6d88\u8be5\u5916\u94fe\u5206\u4eab?
    \u53d6\u6d88\u540e\u5916\u94fe\u5c06\u5931\u6548! +explorer.share.shareToCopy=\u590d\u5236\u8bbf\u95ee\u8def\u5f84 +explorer.share.shareToCopyDesc=\u53ef\u5c06\u8be5\u94fe\u63a5\u53d1\u9001\u7ed9\u534f\u4f5c\u7684\u4eba\u5feb\u6377\u8fdb\u5165\u534f\u4f5c +explorer.share.specifyAuthTips=\u9664\u4e0a\u8ff0\u6307\u5b9a\u7528\u6237 +explorer.share.specifyAuthDesc=\u6307\u5b9a\u7528\u6237\u6743\u9650 > \u6307\u5b9a\u7528\u6237\u6240\u5728\u90e8\u95e8\u6743\u9650 > \u5176\u4ed6\u4eba\u6743\u9650 +explorer.share.selfAuthDesc=\u4e0d\u80fd\u4fee\u6539\u81ea\u5df1\u7684\u6743\u9650,\u5176\u4ed6\u7ba1\u7406\u8005\u53ef\u4ee5\u8bbe\u7f6e +explorer.share.authTypeDesc=\u9ed8\u8ba4\u7ee7\u627f\u4e0a\u7ea7\u6587\u4ef6\u5939\u6743\u9650 +explorer.share.rootPathAuthDesc=\u6839\u90e8\u95e8\u652f\u6301\u9009\u62e9\u7528\u6237\u548c\u90e8\u95e8 +explorer.share.subPathAuthDesc=\u5b50\u90e8\u95e8,\u4ec5\u652f\u6301\u9009\u62e9\u8be5\u90e8\u95e8\u7684\u6210\u5458\u7528\u6237 +explorer.share.myAuth=\u6211\u7684\u6743\u9650 +explorer.share.othersAuth=\u5176\u4ed6\u4eba\u6743\u9650 +explorer.share.keepAuth=\u4fdd\u6301\u539f\u6765\u6743\u9650 +explorer.share.specifyAuth=\u6307\u5b9a\u6743\u9650 +explorer.share.userAuth=\u7528\u6237\u6743\u9650 +explorer.share.specifyUserAuth=\u6307\u5b9a\u7528\u6237\u6743\u9650 +explorer.share.rptTitle=\u5982\u6709\u53d1\u73b0\u8fdd\u6cd5\u6709\u5bb3\u4fe1\u606f,\u8bf7\u5728\u4e0b\u65b9\u9009\u62e9\u539f\u56e0\u63d0\u4ea4\u4e3e\u62a5�� +explorer.share.illegal=\u8fdd\u6cd5\u4fe1\u606f +explorer.share.inputRptDesc=\u8bf7\u8f93\u5165\u4e3e\u62a5\u539f\u56e0 +explorer.share.rptSend=\u63d0\u4ea4\u6210\u529f,\u7ba1\u7406\u5458\u5c06\u4f1a\u53ca\u65f6\u5904\u7406 +explorer.share.rptSended=\u4e3e\u62a5\u5df2\u63d0\u4ea4,\u7b49\u5f85\u7ba1\u7406\u5458\u5904\u7406 +explorer.auth.mutil=\u6279\u91cf\u8bbe\u7f6e\u6743\u9650 +explorer.auth.mutilTips=\u6ce8\u610f:\u5982\u679c\u6240\u9009\u5185\u5bb9\u5df2\u7ecf\u6709\u6743\u9650 \u5219\u4f1a\u88ab\u8986\u76d6. +explorer.auth.mutilDesc=\u540c\u65f6\u4f5c\u4e3a\u540e\u7eed\u9ed8\u8ba4\u6743\u9650 +explorer.auth.showMore=\u6743\u9650\u8be6\u60c5 +explorer.auth.tabUser=\u90e8\u95e8\u6210\u5458 +explorer.auth.tabChildren=\u5b50\u6587\u4ef6\u5939\u6743\u9650 +explorer.auth.tabUserTips=\u90e8\u95e8\u6210\u5458\u521d\u59cb\u6743\u9650 +explorer.auth.tabChildrenTips=\u8be5\u6587\u4ef6\u5939\u4e0b\u8bbe\u7f6e\u8fc7\u6743\u9650\u7684\u5185\u5bb9 +explorer.auth.resetUser=\u8986\u76d6\u8bbe\u7f6e\u8be5\u7528\u6237\u6743\u9650 +explorer.auth.resetUserBtn=\u8986\u76d6\u6743\u9650 +explorer.auth.resetUserBtnTips=\u8986\u76d6\u8be5\u7528\u6237\u5728\u8be5\u6587\u4ef6\u5939\u6240\u6709\u5b50\u6587\u4ef6(\u5939)\u6743\u9650 +explorer.auth.resetUserHeader=\u4e0b\u7ea7\u6587\u4ef6\u5939\u4e2d\u5305\u542b\u6307\u5b9a\u8be5\u7528\u6237\u6743\u9650\u7684\u5185\u5bb9\u5c06\u5168\u90e8\u8986\u76d6\u8bbe\u7f6e\u4e3a\u4e0a\u8ff0\u6743\u9650 +explorer.auth.resetUserContiner=\u5305\u542b\u8be5\u7528\u6237\u6743\u9650\u5185\u5bb9 +explorer.auth.resetUserEmpty1=\u6ca1\u6709\u9488\u5bf9\u8be5\u7528\u6237\u8bbe\u7f6e\u6743\u9650\u7684\u5185\u5bb9\u65e0\u9700\u8986\u76d6 +explorer.auth.resetUserEmpty2=\u6240\u6709\u5b50\u5185\u5bb9\u90fd\u7ee7\u627f\u5f53\u524d\u5c42\u7ea7\u6587\u4ef6\u5939\u6743\u9650 +explorer.rename.mutil=\u6279\u91cf\u91cd\u547d\u540d +explorer.rename.nameBefore=\u539f\u6587\u4ef6\u540d +explorer.rename.nameTo=\u91cd\u547d\u540d\u4e3a +explorer.rename.start=\u7acb\u5373\u91cd\u547d\u540d +explorer.rename.clearFinished=\u6e05\u7a7a\u5df2\u5b8c\u6210 +explorer.rename.clearAll=\u6e05\u7a7a\u6240\u6709 +explorer.rename.typeReplaceAll=\u5168\u90e8\u66ff\u6362 +explorer.rename.typePrepend=\u524d\u9762\u8ffd\u52a0 +explorer.rename.typeAppend=\u540e\u9762\u8ffd\u52a0 +explorer.rename.typeReplace=\u67e5\u627e\u66ff\u6362 +explorer.rename.typeChangeCase=\u5927\u5c0f\u5199\u8f6c\u6362 +explorer.rename.typeRemove=\u5220\u9664\u5b57\u7b26 +explorer.rename.typeReplaceSet=\u6279\u91cf\u6307\u5b9a\u66ff\u6362 +explorer.rename.typeReplaceSetDesc=\u76f8\u7b49\u65f6\u5219\u66ff\u6362;\u6bcf\u884c\u4e00\u9879\u7a7a\u683c\u9694\u5f00\u6587\u4ef6\u540d\u4e0d\u5141\u8bb8\u7a7a\u683c;\u4f8b\u5982: +explorer.rename.numberStart=\u8ba1\u6570\u5f00\u59cb +explorer.rename.appendContent=\u8ffd\u52a0\u5185\u5bb9 +explorer.rename.find=\u67e5\u627e +explorer.rename.replaceTo=\u66ff\u6362\u4e3a +explorer.rename.caseUpperFirst=\u9996\u5b57\u6bcd\u5927\u5199 +explorer.rename.caseUpper=\u5168\u5927\u5199 +explorer.rename.caseLower=\u5168\u5c0f\u5199 +explorer.rename.removeStart=\u4ece\u5934\u5220\u9664 +explorer.rename.removeEnd=\u4ece\u7ed3\u5c3e\u5220\u9664 +explorer.rename.chars=\u5b57\u7b26 +explorer.editor.beautifyCode=\u4ee3\u7801\u683c\u5f0f\u5316 +explorer.editor.convertCase=\u5927\u5c0f\u5199\u8f6c\u6362 +explorer.editor.convertUpperCase=\u8f6c\u6362\u4e3a\u5927\u5199 +explorer.editor.convertLowerCase=\u8f6c\u6362\u4e3a\u5c0f\u5199 +explorer.editor.currentTime=\u5f53\u524d\u65f6\u95f4 +explorer.editor.md5=md5\u52a0\u5bc6 +explorer.editor.qrcode=\u5b57\u7b26\u4e32\u4e8c\u7ef4\u7801 +explorer.editor.regx=\u6b63\u5219\u8868\u8fbe\u5f0f\u6d4b\u8bd5 +explorer.editor.chinese=\u7e41\u7b80\u8f6c\u6362 +explorer.editor.chineseSimple=\u8f6c\u6362\u4e3a\u7b80\u4f53\u4e2d\u6587 +explorer.editor.chineseTraditional=\u8f6c\u6362\u4e3a\u7e41\u4f53\u4e2d\u6587 +explorer.editor.base64=base64\u7f16\u89e3\u7801 +explorer.editor.base64Encode=base64 \u7f16\u7801 +explorer.editor.base64Decode=base64 \u89e3\u7801 +explorer.editor.url=URL\u7f16\u89e3\u7801 +explorer.editor.urlEncode=URL \u7f16\u7801 +explorer.editor.urlDecode=URL \u89e3\u7801 +explorer.editor.unicode=Unicode\u7f16\u89e3\u7801 +explorer.editor.unicodeEncode=Unicode \u7f16\u7801 +explorer.editor.unicodeDecode=Unicode \u89e3\u7801 +explorer.editor.toolsSelectTips=\u8bf7\u9009\u4e2d\u6b63\u786e\u7684\u5f85\u5904\u7406\u5185\u5bb9! +explorer.editor.toolsRandString=\u751f\u621032\u4f4d\u968f\u673a\u5b57\u7b26\u4e32 +explorer.editor.textEncode=\u6587\u672c\u7f16\u7801/\u89e3\u7801 +explorer.editor.textParse=\u6587\u672c\u5904\u7406 +explorer.editor.timeShow=\u65f6\u95f4\u6233\u8f6c\u65f6\u95f4 +explorer.editor.timeInt=\u65f6\u95f4\u8f6c\u65f6\u95f4\u6233 +explorer.editor.lineRemoveEmpty=\u79fb\u9664\u7a7a\u884c(\u542b\u7a7a\u683c) +explorer.editor.lineUnoin=\u79fb\u9664\u91cd\u590d\u884c +explorer.editor.lineTrim=\u79fb\u9664\u9996\u5c3e\u7a7a\u683c +explorer.editor.lineSort=\u6309\u884c\u6392\u5e8f(\u5347\u5e8f) +explorer.editor.lineReverse=\u4e0a\u4e0b\u8c03\u6362\u6240\u6709\u884c +explorer.editor.lineSum=\u6c42\u548c +explorer.editor.lineAverage=\u5e73\u5747\u503c +explorer.editor.calc=\u81ea\u7531\u8ba1\u7b97\u5668 +explorer.editor.goToLine=\u8df3\u8f6c\u5230\u884c +explorer.editor.keyboardType=\u952e\u76d8\u6a21\u5f0f +explorer.editor.fontFamily=\u5b57\u4f53 +explorer.editor.codeMode=\u9ad8\u4eae\u8bed\u6cd5 +explorer.editor.closeAll=\u5173\u95ed\u5168\u90e8 +explorer.editor.closeLeft=\u5173\u95ed\u5de6\u4fa7\u6807\u7b7e +explorer.editor.closeRight=\u5173\u95ed\u53f3\u4fa7\u6807\u7b7e +explorer.editor.closeOthers=\u5173\u95ed\u5176\u4ed6 +explorer.editor.wordwrap=\u81ea\u52a8\u6362\u884c +explorer.editor.showGutter=\u663e\u793a\u884c\u53f7 +explorer.editor.charAllDisplay=\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26 +explorer.editor.autoComplete=\u81ea\u52a8\u63d0\u793a +explorer.editor.autoSave=\u81ea\u52a8\u4fdd\u5b58 +explorer.editor.functionList=\u51fd\u6570\u5217\u8868 +explorer.editor.codeTheme=\u4ee3\u7801\u98ce\u683c +explorer.editor.fontSize=\u5b57\u4f53\u5927\u5c0f +explorer.editor.completeCurrent=\u81ea\u52a8\u8865\u5168\u5f53\u524d +explorer.editor.createProject=\u6dfb\u52a0\u5230\u7f16\u8f91\u5668\u5de5\u7a0b +explorer.editor.markdownContent=\u5185\u5bb9\u76ee\u5f55 +explorer.editor.undo=\u64a4\u9500 +explorer.editor.redo=\u53cd\u64a4\u9500 +explorer.editor.shortcut=\u5feb\u6377\u952e +explorer.editor.replace=\u66ff\u6362 +explorer.editor.reload=\u91cd\u65b0\u8f7d\u5165 +explorer.editor.view=\u89c6\u56fe +explorer.editor.tools=\u5de5\u5177 +explorer.editor.help=\u5e2e\u52a9 +explorer.sync.data=\u6570\u636e\u540c\u6b65 +explorer.sync.openLoc=\u6253\u5f00\u672c\u5730\u76ee\u5f55 +explorer.sync.syncing=\u6b63\u5728\u540c\u6b65 +explorer.sync.synced=\u540c\u6b65\u5b8c\u6210 +explorer.sync.syncedError=\u9519\u8bef\u8bb0\u5f55 +explorer.sync.syncStart=\u5f00\u59cb\u540c\u6b65 +explorer.sync.syncStop=\u505c\u6b62\u540c\u6b65 +explorer.sync.notOpenTips=\u60a8\u672a\u5f00\u542f\u672c\u5730\u540c\u6b65 +explorer.sync.setNow=\u7acb\u5373\u8bbe\u7f6e\u540c\u6b65 +explorer.sync.error=\u4e0a\u4f20\u5931\u8d25 +explorer.sync.success=\u540c\u6b65\u6210\u529f +explorer.sync.statusScan=\u626b\u63cf\u4e2d +explorer.sync.statusNone=\u540c\u6b65\u672a\u914d\u7f6e +explorer.sync.statusScanEnd=\u626b\u63cf\u5b8c\u6210 +explorer.sync.statusDoing=\u540c\u6b65\u4e2d +explorer.sync.statusDone=\u540c\u6b65\u5b8c\u6210 +explorer.sync.statusStop=\u6682\u505c\u4e2d +explorer.sync.clearCacheSuccess=\u6e05\u9664\u7f13\u5b58\u6210\u529f! +explorer.sync.emptyTask=\u6682\u65e0\u540c\u6b65\u4efb\u52a1 +explorer.sync.openCloud=\u6253\u5f00\u4e91\u7aef\u6240\u5728\u4f4d\u7f6e +explorer.sync.openLocal=\u672c\u5730\u6253\u5f00 +explorer.sync.statusFiles=\u6587\u4ef6\u8fdb\u5ea6 +explorer.sync.statusLastTime=\u5b8c\u6210\u65f6\u95f4 +explorer.sync.configName=\u540c\u6b65\u8bbe\u7f6e +explorer.sync.configClient=\u5ba2\u6237\u7aef\u8bbe\u7f6e +explorer.sync.configAbout=\u5173\u4e8e +explorer.sync.configSyncFrom=\u672c\u5730\u8def\u5f84 +explorer.sync.configSyncFromDesc=\u9009\u62e9\u8981\u540c\u6b65\u7684\u672c\u5730\u6587\u4ef6\u5939 +explorer.sync.configSyncTo=\u540c\u6b65\u5230 +explorer.sync.configSyncToDesc=\u540c\u6b65\u5230\u670d\u52a1\u5668\u4f4d\u7f6e +explorer.sync.configIgnore=\u5ffd\u7565\u7684\u6587\u4ef6\u7c7b\u578b +explorer.sync.configIgnoreDesc=\u8be5\u7c7b\u578b\u6587\u4ef6\u4e0d\u8fdb\u884c\u540c\u6b65 +explorer.sync.autorun=\u5f00\u673a\u81ea\u542f\u52a8 +explorer.sync.configThread=\u5e76\u53d1\u7ebf\u7a0b\u6570 +explorer.sync.configThreadDesc=\u540c\u65f6\u4e0a\u4f20\u6587\u4ef6\u6570\u91cf +explorer.sync.configDownloadPath=\u4e0b\u8f7d\u8def\u5f84 +explorer.sync.configDownloadPathDesc=\u4e0b\u8f7d\u6587\u4ef6\u6587\u4ef6\u5939\u65f6\u9ed8\u8ba4\u4e0b\u8f7d\u8def\u5f84 +explorer.sync.configClearCacheAuto=\u81ea\u52a8\u6e05\u7a7a\u7f13\u5b58 +explorer.sync.configClearCacheAutoDesc=\u81ea\u52a8\u6e05\u7a7aN\u5929\u524d\u7f13\u5b58\u6587\u4ef6 +explorer.sync.configClearCache=\u6e05\u7a7a\u7f13\u5b58 +explorer.sync.configChangeSite=\u9000\u51fa\u5f53\u524d\u7ad9\u70b9 +explorer.sync.configVersion=\u5f53\u524d\u7248\u672c +explorer.sync.configUpdateDesc=\u66f4\u65b0\u8bf4\u660e +explorer.sync.configUpdateCheck=\u68c0\u6d4b\u66f4\u65b0 +explorer.sync.confirmReset=\u540c\u6b65\u76ee\u5f55\u4fee\u6539\u540c\u6b65\u4fe1\u606f\u5c06\u91cd\u7f6e\u786e\u5b9a\u4fdd\u5b58? +explorer.sync.listClearDone=\u6e05\u7a7a\u5df2\u5b8c\u6210 +explorer.sync.listClearError=\u6e05\u7a7a\u9519\u8bef\u5217\u8868 +explorer.sync.listRetryAll=\u5168\u90e8\u91cd\u8bd5 +explorer.async.tipsDisablePath=\u4e0d\u652f\u6301\u9009\u62e9\u540c\u6b65\u8be5\u8def\u5f84 +explorer.async.tipsIsMoving=\u68c0\u6d4b\u5230\u5f53\u524d\u5927\u91cf\u5185\u5bb9\u6b63\u5728\u79fb\u52a8\u6216\u590d\u5236\u5230\u540c\u6b65\u76ee\u5f55;
    \u5efa\u8bae\u672c\u5730\u5b8c\u6210\u540e\u5237\u65b0\u9875\u9762\u8fdb\u884c\u540c\u6b65! +explorer.async.tipsStartUser=\u624b\u52a8\u5f00\u59cb\u540c\u6b65 +explorer.download.title=\u4e0b\u8f7d\u7ba1\u7406 +explorer.download.waiting=\u7b49\u5f85\u4e2d +explorer.download.stop=\u6682\u505c\u4e0b\u8f7d +explorer.download.start=\u5f00\u59cb\u4e0b\u8f7d +explorer.download.remove=\u79fb\u9664\u4efb\u52a1 +explorer.download.stopAll=\u5168\u90e8\u6682\u505c +explorer.download.startAll=\u5168\u90e8\u7ee7\u7eed +explorer.download.clearAll=\u6e05\u7a7a\u6240\u6709\u4efb\u52a1 +explorer.download.doing=\u8fdb\u884c\u4e2d +explorer.download.done=\u4e0b\u8f7d\u5b8c\u6210 +explorer.download.clearAllTips=\u786e\u5b9a\u5220\u9664\u6240\u6709\u4e0b\u8f7d\u4efb\u52a1\u5417? +explorer.tag.name=\u6807\u7b7e +explorer.tag.edit=\u6807\u7b7e\u7ba1\u7406 +explorer.tag.add=\u521b\u5efa\u6807\u7b7e +explorer.tag.remove=\u786e\u5b9a\u5220\u9664\u8be5\u6807\u7b7e\u5417? +explorer.tag.inputHolder=\u8bf7\u8f93\u5165\u6807\u7b7e\u540d\u79f0 +explorer.tag.addTo=\u8bbe\u7f6e\u6807\u7b7e +explorer.tag.default1=\u5b66\u4e60\u8d44\u6599 +explorer.tag.default2=\u6d4b\u8bd5\u6570\u636e +explorer.tag.default3=\u5408\u540c +explorer.tag.filter=\u6309\u6807\u7b7e\u7b5b\u9009 +explorer.groupTag.title=\u516c\u5171\u6807\u7b7e +explorer.groupTag.menuTtitle=\u90e8\u95e8\u516c\u5171\u6807\u7b7e +explorer.groupTag.titleDesc=\u90e8\u95e8\u5185\u516c\u5171\u6807\u7b7e +explorer.groupTag.empty=\u90e8\u95e8\u7ba1\u7406\u5458\u8bbe\u7f6e\u516c\u5171\u6807\u7b7e\u540e\u81ea\u52a8\u542f\u7528. \u6ca1\u6709\u6807\u7b7e\u5185\u5bb9\u65f6\u81ea\u52a8\u5173\u95ed\u516c\u5171\u6807\u7b7e! +explorer.tag.pathDesc=\u6309\u4e2a\u4eba\u6807\u7b7e\u7b5b\u9009 +explorer.groupTag.pathDesc=\u6309\u90e8\u95e8\u516c\u5171\u6807\u7b7e\u7b5b\u9009 +explorer.groupTag.removeTypeTips=\u786e\u8ba4\u5220\u9664\u8be5\u5206\u7ec4\u5417? \u5220\u9664\u540e\u6240\u6709\u6240\u5c5e\u6807\u7b7e\u5173\u8054\u7684\u6587\u6863\u90fd\u4f1a\u8fdb\u884c\u89e3\u9664! +explorer.groupTag.removeTagTips=\u786e\u8ba4\u5220\u9664\u8be5\u6807\u7b7e\u5417? \u5220\u9664\u540e\u6807\u7b7e\u5173\u8054\u7684\u6587\u6863\u4f1a\u8fdb\u884c\u89e3\u9664! +explorer.groupTag.typeAdd=\u6dfb\u52a0\u5206\u7c7b +explorer.groupTag.typeName=\u5206\u7c7b\u540d\u79f0 +explorer.groupTag.addDesc=\u6dfb\u52a0\u6807\u7b7e\u540e\u81ea\u52a8\u542f\u7528\u90e8\u95e8\u6807\u7b7e\u6807\u7b7e\u4e0a\u96501000\u4e2a +explorer.panel.info=\u5c5e\u6027 +explorer.panel.version=\u7248\u672c +explorer.panel.chat=\u8ba8\u8bba +explorer.panel.log=\u52a8\u6001 +explorer.panel.meta=\u5173\u8054\u4fe1\u606f +explorer.panel.chatName=\u4ea4\u6d41\u8ba8\u8bba +explorer.panel.chat.send=\u53d1\u9001 +explorer.panel.chat.noAuth=\u8be5\u6587\u6863\u60a8\u6ca1\u6709\u8bc4\u8bba\u6743\u9650! +explorer.panel.chat.placeholder=\u5728\u8fd9\u91cc\u8f93\u5165Enter\u53d1\u9001Ctrl+Enter\u6362\u884c +explorer.panel.chat.placeholderCtrl=\u5728\u8fd9\u91cc\u8f93\u5165Ctrl+Enter\u53d1\u9001Enter\u6362\u884c +explorer.panel.chat.reply=\u56de\u590d +explorer.panel.chat.empty=\u6ca1\u6709\u8bc4\u8bba +explorer.panel.chat.sendTo=\u8f6c\u53d1 +explorer.panel.metaName=\u5173\u8054\u6570\u636e\u6269\u5c55 +explorer.panel.metaDesc=\u6269\u5c55\u6587\u6863\u5b57\u6bb5\u5c5e\u6027 +explorer.panel.thumbClear=\u6e05\u9664\u7f29\u7565\u56fe +explorer.panel.thumbClearDesc=\u6e05\u9664\u6587\u4ef6\u7f29\u7565\u56fe,\u5c01\u9762\u56fe,\u4ee5\u91cd\u65b0\u751f\u6210�� +explorer.panel.historyName=\u5386\u53f2\u7248\u672c +explorer.panel.historyDesc=\u7248\u672c\u8bf4\u660e +explorer.panel.infoTips=\u9009\u4e2d\u6587\u4ef6(\u5939)\u67e5\u770b\u8be6\u7ec6\u5c5e\u6027 +explorer.panel.info.space=\u7a7a\u95f4\u5bb9\u91cf +explorer.panel.info.groupAt=\u90e8\u95e8\u4f4d\u7f6e +explorer.panel.info.tagEmpty=\u6682\u65e0\u6807\u7b7e\u70b9\u51fb\u8bbe\u7f6e +explorer.panel.logName=\u6587\u6863\u52a8\u6001 +explorer.panel.logEmpty=\u6ca1\u6709\u52a8\u6001 +explorer.type.doc=\u6587\u6863 +explorer.type.image=\u56fe\u7247 +explorer.type.music=\u97f3\u4e50 +explorer.type.movie=\u89c6\u9891 +explorer.type.zip=\u538b\u7f29\u5305 +explorer.type.others=\u5176\u4ed6 +explorer.secret.title=\u6587\u6863\u5bc6\u7ea7\u7ba1\u7406 +explorer.secret.isOpen=\u662f\u5426\u542f\u7528 +explorer.secret.isOpenDesc=\u5f00\u542f\u5173\u95ed\u5bc6\u7ea7\u7ba1\u7406 +explorer.secret.setUser=\u5bc6\u7ea7\u7ba1\u7406\u8005 +explorer.secret.setUserDesc=\u6307\u5b9a\u53ef\u4ee5\u8bbe\u7f6e\u5bc6\u7ea7\u7684\u7528\u6237(\u5fc5\u987b\u5728\u5bf9\u5e94\u90e8\u95e8\u540c\u65f6\u4e3a\u62e5\u6709\u8005) +explorer.secret.type=\u5bc6\u7ea7\u7c7b\u578b +explorer.secret.add=\u6dfb\u52a0\u5bc6\u7ea7 +explorer.secret.edit=\u7f16\u8f91\u5bc6\u7ea7 +explorer.secret.name=\u5bc6\u7ea7\u540d\u79f0 +explorer.secret.style=\u6837\u5f0f +explorer.secret.auth=\u5bc6\u7ea7\u6743\u9650 +explorer.secret.authHas=\u5bc6\u7ea7\u6743\u9650\u5305\u542b +explorer.secret.createUser=\u8bbe\u7f6e\u8005 +explorer.secret.folderAt=\u5bc6\u7ea7\u6587\u4ef6\u5939 +explorer.secret.tips=\u6743\u9650\u53d7\u5bc6\u7ea7\u63a7\u5236\u5bc6\u7ea7\u6743\u9650\u9ad8\u4e8e\u6587\u6863\u6743\u9650 +explorer.secret.tips1=\u4ec5\u9650\u90e8\u95e8\u7f51\u76d8\u4e0b\u5185\u5bb9\u4e0a\u8ff0\u6307\u5b9a\u7528\u6237\u624d\u80fd\u8bbe\u7f6e\u5bc6\u7ea7(\u540c\u65f6\u5fc5\u987b\u4e3a\u6587\u4ef6\u5939\u62e5\u6709\u8005) +explorer.secret.tips2=\u8bbe\u7f6e\u5bc6\u7ea7\u7684\u6587\u4ef6\u5939\u4e0b\u5c42\u6240\u6709\u5185\u5bb9\u90fd\u4ee5\u6b64\u6743\u9650\u4e3a\u6700\u9ad8\u6743\u9650 +explorer.secret.tips3=\u8bbe\u7f6e\u540e\u5bc6\u7ea7\u6743\u9650\u9ad8\u4e8e\u6587\u6863\u6743\u9650(\u6587\u6863\u62e5\u4e5f\u53d7\u5bc6\u7ea7\u6743\u9650\u63a7\u5236\u7cfb\u7edf\u8d85\u7ea7\u7ba1\u7406\u5458\u4e0d\u53d7\u8be5\u9650\u5236\u5bc6\u7ea7\u8bbe\u7f6e\u8005\u81ea\u5df1\u4e0d\u53d7\u8be5\u9650\u5236) +explorer.secret.tips4=\u5bc6\u7ea7\u6743\u9650: \u53ef\u4ee5\u5728\\u90e8\u95e8\u4e0e\u6210\u5458\u7ba1\u7406--\u6587\u6863\u6743\u9650\u7ba1\u7406\\u4e2d\u6dfb\u52a0\u5e76\u8bbe\u7f6e\u4e3a\u9690\u85cf +user.----=---- +user.displayHideFile=\u663e\u793a\u9690\u85cf\u6587\u4ef6 +user.displayHideFileDesc=\u9690\u85cf\u6587\u4ef6:\u4ee5.\u5f00\u5934\u7684\u6587\u4ef6\u53ca\u7cfb\u7edf\u540e\u53f0\u8bbe\u7f6e\u7684\u9690\u85cf\u6587\u4ef6\u540d;\u5f00\u542f\u540e\u9690\u85cf\u6587\u4ef6\u4f1a\u663e\u793a; +user.soundOpen=\u5f00\u542f\u97f3\u6548 +user.animateOpen=\u5f00\u542f\u52a8\u753b +user.recycleOpen=\u5f00\u542f\u56de\u6536\u7ad9 +user.recycleDesc=\u5f00\u542f\u540e\u5220\u9664\u4f1a\u79fb\u5230\u56de\u6536\u7ad9\u5efa\u8bae\u5f00\u542f +user.animateDesc=\u7a97\u53e3\u6253\u5f00\u7b49\u52a8\u753b\u64cd\u4f5c\u4e0d\u6d41\u7545\u65f6\u53ef\u4ee5\u8003\u8651\u5173\u95ed +user.soundDesc=\u6253\u5f00\u6587\u4ef6,\u5220\u9664\u6587\u4ef6,\u6e05\u7a7a\u56de\u6536\u7ad9\u7b49\u64cd\u4f5c\u97f3\u6548 +user.thumbOpen=\u5f00\u542f\u56fe\u7247\u7f29\u7565\u56fe +user.thumbDesc=\u5f00\u542f\u540e\u56fe\u7247\u6d4f\u89c8\u4f53\u9a8c\u66f4\u4f73 +user.fileSelect=\u5f00\u542f\u6587\u4ef6\u56fe\u6807\u52fe\u9009 +user.fileSelectDesc=\u6587\u4ef6\u56fe\u6807\u7684\u5de6\u952e\u52fe\u9009,\u53f3\u952e\u83dc\u5355\u7684\u5feb\u6377\u5165\u53e3 +user.fileShowDesc=\u663e\u793a\u6587\u4ef6\u5939\u7b80\u4ecb +user.fileShowDescTips=\u4ec5\u56fe\u6807\u6a21\u5f0f +user.fileOpenClick=\u6309\u5982\u4e0b\u65b9\u5f0f\u6253\u5f00\u6587\u4ef6(\u5939) +user.fileOpenClick.dbclick=\u901a\u8fc7\u53cc\u51fb\u6253\u5f00 +user.fileOpenClick.click=\u901a\u8fc7\u5355\u51fb\u6253\u5f00 +user.viewSetting=\u663e\u793a\u9009\u9879 +user.thirdAccount=\u7b2c\u4e09\u65b9\u8d26\u53f7 +user.bindAccount=\u7ed1\u5b9a\u8d26\u53f7 +user.thirdBindFirst=\u8d26\u53f7\u5c1a\u672a\u7ed1\u5b9a,\u8bf7\u7ed1\u5b9a\u540e\u4f7f\u7528 +user.account=\u8d26\u53f7 +user.bind=\u7ed1\u5b9a +user.unbind=\u89e3\u7ed1 +user.binded=\u5df2\u7ed1\u5b9a +user.clickBind=\u70b9\u51fb\u7ed1\u5b9a +user.clickToBind=\u672a\u7ed1\u5b9a\u70b9\u51fb\u7ed1\u5b9a +user.clickEditPwd=\u70b9\u51fb\u4fee\u6539\u5bc6\u7801 +user.userAvatar=\u4e2a\u4eba\u5934\u50cf +user.userNickName=\u4e2a\u4eba\u6635\u79f0 +user.userAccount=\u4e2a\u4eba\u8d26\u53f7 +user.uploadAvatar=\u4e0a\u4f20\u5934\u50cf +user.userAvatarCrop=\u8bf7\u9009\u62e9\u5408\u9002\u7684\u533a\u57df\u4f5c\u4e3a\u5934\u50cf +user.userAvatarExt=\u4ec5\u652f\u6301 JPG,JPEG,PNG \u7684\u56fe\u7247\u683c\u5f0f +user.resetPwdDesc=\u5fd8\u8bb0\u5bc6\u7801? \u60a8\u53ef\u4ee5\u8fdb\u884c +user.inputEmailCode=\u8bf7\u8f93\u5165\u90ae\u7bb1\u9a8c\u8bc1\u7801 +user.inputSmsCode=\u8bf7\u8f93\u5165\u77ed\u4fe1\u9a8c\u8bc1\u7801 +user.emailVerifyDesc=\u90e8\u5206\u4e1a\u52a1\u9700\u8981\u7528\u90ae\u7bb1\u9a8c\u8bc1 +user.phoneVerifyDesc=\u90e8\u5206\u4e1a\u52a1\u9700\u8981\u7528\u624b\u673a\u9a8c\u8bc1 +user.bindOthers=\u5df2\u7ed1\u5b9a\u5176\u4ed6\u8d26\u53f7 +user.notBind=\u5c1a\u672a\u7ed1\u5b9a +user.regist=\u7528\u6237\u6ce8\u518c +user.notRegist=\u5c1a\u672a\u6ce8\u518c +user.registed=\u5df2\u88ab\u6ce8\u518c +user.signError=\u56de\u8c03\u7b7e\u540d\u6709\u8bef +user.repeat=\u91cd\u590d +user.noRepeat=\u4e0d\u80fd\u91cd\u590d +user.newPwd=\u65b0\u5bc6\u7801 +user.unAuthFile=\u672a\u6388\u6743\u7684\u6587\u4ef6\u8bbf\u95ee +user.unbindWarning=\u89e3\u7ed1\u524d\u8bf7\u5148\u4fee\u6539\u5bc6\u7801,\u5426\u5219\u5c06\u5bfc\u81f4\u8be5\u8d26\u53f7\u65e0\u6cd5\u6b63\u5e38\u4f7f\u7528 +user.isLoginTips=\u68c0\u6d4b\u5230\u60a8\u5f53\u524d\u5df2\u767b\u5f55! +user.isLoginEnter=\u7acb\u5373\u8fdb\u5165 +user.ifUnbind=\u786e\u5b9a\u8981\u89e3\u9664\u7ed1\u5b9a\u5417? +user.bindFirst=\u8bf7\u5148\u7ed1\u5b9a\u90ae\u7bb1\u6216\u624b\u673a\u53f7 +user.inputNewPwd=\u8bf7\u8f93\u5165\u65b0\u7684\u5bc6\u7801 +user.inputNewValue=\u8bf7\u586b\u5199\u65b0\u7684\u5185\u5bb9 +user.guestLogin=\u6e38\u5ba2\u767b\u5f55 +user.name=\u767b\u5f55\u8d26\u53f7 +user.nickName=\u7528\u6237\u6635\u79f0 +user.code=\u9a8c\u8bc1\u7801 +user.codeError=\u9a8c\u8bc1\u7801\u9519\u8bef +user.imgCode=\u56fe\u5f62\u9a8c\u8bc1\u7801 +user.rootPwd=\u8bbe\u7f6e\u7ba1\u7406\u5458\u5bc6\u7801 +user.rootPwdRepeat=\u518d\u6b21\u786e\u8ba4\u5bc6\u7801 +user.rootPwdEqual=\u4e24\u6b21\u5bc6\u7801\u4e0d\u4e00\u81f4! +user.rootPwdTips=\u8bf7\u8bbe\u7f6e\u7ba1\u7406\u5458\u5bc6\u7801! +user.pwdError=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef! +user.pwdNotNull=\u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a! +user.oldPwdError=\u539f\u5bc6\u7801\u9519\u8bef! +user.keepPwd=\u8bb0\u4f4f\u5bc6\u7801 +user.forgetPwd=\u5fd8\u8bb0\u5bc6\u7801 +user.directLogin=\u5df2\u6709\u8d26\u53f7\u767b\u5f55 +user.moreLogin=\u66f4\u591a\u767b\u5f55\u65b9\u5f0f +user.loginNow=\u7acb\u5373\u767b\u5f55 +user.registNow=\u7acb\u5373\u6ce8\u518c +user.backHome=\u8fd4\u56de\u9996\u9875 +user.ifHasAccount=\u5df2\u6709\u8d26\u53f7? +user.userEnabled=\u8d26\u53f7\u88ab\u7981\u7528\u6216\u5c1a\u672a\u542f\u7528!\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458 +user.roleError=\u6240\u5c5e\u6743\u9650\u7ec4\u4e0d\u5b58\u5728,\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458 +user.invalidEmail=\u60a8\u6ca1\u6709\u6709\u6548\u7684\u90ae\u7bb1\u5730\u5740\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u4fee\u6539 +user.codeRefresh=\u70b9\u51fb\u5237\u65b0 +user.emailVerify=\u90ae\u7bb1\u8eab\u4efd\u9a8c\u8bc1 +user.sendSuccess=\u53d1\u9001\u6210\u529f +user.sendFail=\u53d1\u9001\u5931\u8d25 +user.sendSuccessDesc=\u9a8c\u8bc1\u7801\u53d1\u9001\u6210\u529f\u8bf7\u524d\u5f80\u67e5\u770b +user.sendFailDesc=\u9a8c\u8bc1\u7801\u53d1\u9001\u5931\u8d25\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458 +user.inputVerifyCode=\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801 +user.getCode=\u83b7\u53d6\u9a8c\u8bc1\u7801 +user.inputPwd=\u8bf7\u8f93\u5165\u5bc6\u7801 +user.inputPwdAgain=\u8bf7\u518d\u6b21\u8f93\u5165\u5bc6\u7801 +user.inputNickName=\u8bf7\u8f93\u5165\u6635\u79f0 +user.inputEmail=\u8bf7\u8f93\u5165\u90ae\u7bb1\u5730\u5740 +user.inputPhone=\u8bf7\u8f93\u5165\u624b\u673a\u53f7 +user.inputPhoneEmail=\u8bf7\u8f93\u5165\u624b\u673a/Email +user.invalidPhoneEmail=\u65e0\u6548\u7684\u624b\u673a/Email +user.findPwd=\u627e\u56de\u5bc6\u7801 +user.inputNotMatch=\u8f93\u5165\u7684%s\u4e0e\u5df2\u7ed1\u5b9a\u7684\u4e0d\u76f8\u7b26 +user.usingDesc=\u60a8\u6b63\u5728\u4f7f\u7528 +user.improveInfo=\u8bf7\u5b8c\u5584\u4fe1\u606f +user.codeExpired=\u9a8c\u8bc1\u7801\u5df2\u8fc7\u671f\u8bf7\u91cd\u65b0\u83b7\u53d6 +user.codeErrorTooMany=\u9a8c\u8bc1\u7801\u9519\u8bef\u6b21\u6570\u8fc7\u591a\u8bf7\u91cd\u65b0\u83b7\u53d6 +user.codeErrorFreq=\u53d1\u9001\u9891\u7387\u8fc7\u9ad8,\u8bf7\u7a0d\u540e\u518d\u8bd5! +user.codeErrorCnt=\u53d1\u9001\u6b21\u6570\u5df2\u8d85\u9650\u5236,\u5c06\u88ab\u9501\u5b9a%s\u5c0f\u65f6�� +user.registSuccess=\u6ce8\u518c\u6210\u529f +user.waitCheck=\u7b49\u5f85\u7ba1\u7406\u5458\u5ba1\u6838 +user.nameHolder=\u8bf7\u8f93\u5165\u624b\u673a\u53f7/Email +user.loginNoPermission=\u62b1\u6b49\u60a8\u6ca1\u6709\u8be5\u6743\u9650\u8bf7\u4f7f\u7528\u6709\u6b64\u6743\u9650\u7684\u8d26\u53f7\u767b\u5f55! +user.loginFirst=\u60a8\u5c1a\u672a\u767b\u5f55!\u8bf7\u5148\u767b\u5f55 +user.bindSignError=\u7b7e\u540d\u5f02\u5e38\uff0c\u8bf7\u91cd\u65b0\u64cd\u4f5c\u4e00\u6b21\uff01 +user.bindUpdateError=\u7528\u6237\u4fe1\u606f\u66f4\u65b0\u5931\u8d25,\u8bf7\u91cd\u8bd5 +user.bindTypeError=\u65e0\u6548\u7684\u7ed1\u5b9a\u7c7b\u578b +user.bindWxConfigError=\u83b7\u53d6\u914d\u7f6e\u4fe1\u606f\u5f02\u5e38 +user.loginTimeout=\u5f53\u524d\u767b\u5f55\u5df2\u8d85\u65f6,\u8bf7\u91cd\u65b0\u767b\u5f55! +user.theme=\u4e3b\u9898\u6837\u5f0f +user.theme.desc=\u81ea\u52a8\u4ee3\u8868\u8ddf\u968f\u7cfb\u7edf +user.theme.light=\u6d45\u8272 +user.theme.dark=\u6df1\u8272 +user.theme.auto=\u81ea\u52a8 +user.theme.title=\u81ea\u5b9a\u4e49\u4e3b\u9898\u8bbe\u7f6e +user.theme.background=\u80cc\u666f +user.theme.image=\u56fe\u7247 +user.theme.colorBlur=\u6e10\u53d8\u989c\u8272 +user.theme.imageBlur=\u56fe\u7247\u6a21\u7cca\u5904\u7406 +user.theme.imageUrl=\u56fe\u7247\u5730\u5740 +user.theme.colorStart=\u5f00\u59cb\u989c\u8272 +user.theme.colorEnd=\u7ed3\u675f\u989c\u8272 +user.theme.colorRadius=\u6e10\u53d8\u89d2\u5ea6 +user.theme.themeImage=\u80cc\u666f\u56fe\u7247 +user.theme.themeImageDesc=\u652f\u6301: \u56fe\u7247urlcss\u6e10\u53d8\u8272\u8ddf\u968f\u58c1\u7eb8 +user.theme.imageWall=\u8ddf\u968f\u58c1\u7eb8 +user.wall.random=\u968f\u673a\u58c1\u7eb8 +user.wall.paperDesktop=\u684c\u9762\u58c1\u7eb8 +user.wall.paperDeskMgt=\u684c\u9762\u58c1\u7eb8\u7ba1\u7406 +user.wall.paperLoginMgt=\u767b\u5f55\u58c1\u7eb8\u7ba1\u7406 +user.wall.paperLoginTips=\u56fe\u7247\u591a\u4e8e1\u5f20\u65f6,\u767b\u5f55\u754c\u9762\u80cc\u666f\u5c06\u968f\u673a\u8f6e\u6362 +log-type-create-mkdir=\u65b0\u5efa\u6587\u4ef6\u5939 +log-type-create-mkfile=\u65b0\u5efa\u6587\u4ef6 +log-type-create-upload=\u4e0a\u4f20\u6587\u4ef6 +log-type-create-copy=\u7c98\u8d34\u6587\u4ef6 +log-type-edit=\u66f4\u65b0\u6587\u4ef6 +log-type-move=\u79fb\u52a8\u6587\u4ef6 +log-type-moveOut=\u79fb\u8d70\u6587\u4ef6 +log-type-share-shareLinkAdd=\u521b\u5efa\u4e86\u5916\u94fe\u5206\u4eab +log-type-share-shareToAdd=\u5f00\u542f\u4e86\u534f\u4f5c\u5206\u4eab +log-type-share-shareLinkRemove=\u5173\u95ed\u7684\u5916\u94fe\u5206\u4eab +log-type-share-shareToRemove=\u5173\u95ed\u534f\u4f5c\u5206\u4eab +log-type-share-shareEdit=\u7f16\u8f91\u5206\u4eab +log-type-rename=\u91cd\u547d\u540d +log-type-recycle-toRecycle=\u79fb\u5230\u56de\u6536\u7ad9 +log-type-recycle-restore=\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +log-type-remove=\u5220\u9664 +log-type-addDesc=\u4fee\u6539\u63cf\u8ff0 +log-type-addComment=\u53d1\u8868\u8bc4\u8bba +log-event-create-mkdir=\u65b0\u5efa\u4e86\u8be5\u6587\u4ef6\u5939 +log-event-create-mkfile=\u65b0\u5efa\u4e86\u8be5\u6587\u4ef6 +log-event-create-upload=\u4e0a\u4f20\u4e86\u8be5\u6587\u4ef6 +log-event-create-copy=\u7c98\u8d34\u521b\u5efa\u4e86\u8be5\u6587\u4ef6 +log-event-create-mkdir-current=\u5728\u6b64\u65b0\u5efa\u4e86\u6587\u4ef6\u5939{0} +log-event-create-mkfile-current=\u5728\u6b64\u65b0\u5efa\u4e86\u6587\u4ef6{0} +log-event-create-upload-current=\u5728\u6b64\u4e0a\u4f20\u4e86{0} +log-event-create-copy-current=\u7c98\u8d34\u4e86{0}\u5230\u6b64\u5904 +log-event-create-mkdir-item=\u5728{0}\u65b0\u5efa\u4e86\u6587\u4ef6\u5939{1} +log-event-create-mkfile-item=\u5728{0}\u65b0\u5efa\u4e86\u6587\u4ef6{1} +log-event-create-upload-item=\u5728{0}\u4e0a\u4f20\u4e86{1} +log-event-create-copy-item=\u7c98\u8d34{0}\u5230{1} +log-event-create-mkdir-more=\u5728\u6b64\u65b0\u5efa\u4e86{0}\u4e2a\u6587\u4ef6\u5939 +log-event-create-mkfile-more=\u5728\u6b64\u65b0\u5efa\u4e86{0}\u4e2a\u6587\u4ef6 +log-event-create-upload-more=\u5728\u6b64\u4e0a\u4f20\u4e86{0}\u4e2a\u6587\u4ef6 +log-event-create-copy-more=\u7c98\u8d34\u4e86{0}\u4e2a\u6587\u4ef6\u5230\u6b64\u5904 +log-event-create-mkdir-more-at=\u5728{0}\u65b0\u5efa\u4e86{1}\u4e2a\u6587\u4ef6\u5939 +log-event-create-mkfile-more-at=\u5728{0}\u65b0\u5efa\u4e86{1}\u4e2a\u6587\u4ef6 +log-event-create-upload-more-at=\u5728{0}\u4e0a\u4f20\u4e86{1}\u4e2a\u6587\u4ef6 +log-event-create-copy-more-at=\u7c98\u8d34\u4e86{0}\u4e2a\u6587\u6863\u5230{1} +log-event-view-item=\u67e5\u770b\u4e86{0} +log-event-edit=\u66f4\u65b0\u4e86\u8be5\u6587\u4ef6 +log-event-edit-item=\u7f16\u8f91\u66f4\u65b0\u4e86{0} +log-event-edit-more=\u7f16\u8f91\u66f4\u65b0\u4e86{0}\u4e2a\u6587\u4ef6 +log-event-edit-more-user=\u7f16\u8f91\u66f4\u65b0\u4e86\u6587\u4ef6{0} {1}\u6b21 +log-event-edit-more-at=\u5728{0}\u7f16\u8f91\u66f4\u65b0\u4e86{1}\u4e2a\u6587\u4ef6 +log-event-move=\u5c06\u8be5\u6587\u6863\u4ece{0}\u79fb\u52a8\u5230{1} +log-event-move-item=\u5c06{0}\u4ece{1}\u79fb\u52a8\u5230[3] +log-event-move-current=\u5c06{0}\u4ece{1}\u79fb\u52a8\u5230\u6b64\u5904 +log-event-move-more=\u79fb\u52a8\u4e86{0}\u4e2a\u6587\u6863 +log-event-move-more-desc=\u5c06{0}\u4ece{1}\u79fb\u52a8\u5230[3] +log-event-moveOut-more-desc=\u4ece{0}\u79fb\u8d70\u4e86{1} +log-event-moveOut=\u4ece\u6b64\u5904\u79fb\u8d70\u4e86{0} +log-event-moveOut-item=\u4ece{0}\u79fb\u8d70\u4e86{1} +log-event-moveOut-more=\u79fb\u8d70\u4e86{0}\u4e2a\u6587\u6863 +log-event-share-shareLinkAdd=\u5c06\u8be5\u6587\u6863\u521b\u5efa\u4e86\u5916\u94fe\u5206\u4eab +log-event-share-shareLinkAdd-item=\u5c06{0}\u521b\u5efa\u4e86\u5916\u94fe\u5206\u4eab +log-event-share-shareLinkAdd-more=\u521b\u5efa\u4e86{0}\u4e2a\u5916\u94fe\u5206\u4eab +log-event-share-shareToAdd=\u5c06\u8be5\u6587\u6863\u5f00\u542f\u4e86\u534f\u4f5c\u5206\u4eab +log-event-share-shareToAdd-item=\u5c06{0}\u5f00\u542f\u4e86\u534f\u4f5c\u5206\u4eab +log-event-share-shareToAdd-more=\u521b\u5efa\u4e86{0}\u4e2a\u534f\u4f5c\u5206\u4eab +log-event-share-shareLinkRemove=\u5173\u95ed\u4e86\u8be5\u6587\u6863\u7684\u5916\u94fe\u5206\u4eab +log-event-share-shareLinkRemove-item=\u5173\u95ed\u4e86{0}\u7684\u5916\u94fe\u5206\u4eab +log-event-share-shareLinkRemove-more=\u5173\u95ed{0}\u4e2a\u5916\u94fe\u5206\u4eab +log-event-share-shareToRemove=\u5173\u95ed\u4e86\u8be5\u6587\u6863\u7684\u534f\u4f5c\u5206\u4eab +log-event-share-shareToRemove-item=\u5173\u95ed\u4e86{0}\u7684\u534f\u4f5c\u5206\u4eab +log-event-share-shareToRemove-more=\u5173\u95ed{0}\u4e2a\u534f\u4f5c\u5206\u4eab +log-event-share-shareEdit=\u7f16\u8f91\u4e86\u8be5\u6587\u6863\u7684\u5206\u4eab +log-event-share-shareEdit-item=\u7f16\u8f91\u4e86{0}\u7684\u5206\u4eab +log-event-share-shareEdit-more=\u7f16\u8f91\u4e86{0}\u4e2a\u6587\u6863\u5206\u4eab +log-event-rename=\u91cd\u547d\u540d\u4e86\u8be5\u6587\u6863 +log-event-rename-item=\u91cd\u547d\u540d\u4e86{0} +log-event-rename-more=\u91cd\u547d\u540d\u4e86{0}\u4e2a\u6587\u6863 +log-event-recycle-toRecycle=\u5c06\u8be5\u6587\u6863\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-current=\u5728\u6b64\u5904\u5c06{0}\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-item=\u5728{0}\u5c06{1}\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-more=\u5c06{0}\u4e2a\u6587\u6863\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-more-at=\u5728{0}\u5c06{1}\u4e2a\u6587\u6863\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-restore=\u5c06\u8be5\u6587\u6863\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +log-event-recycle-restore-item=\u5c06{0}\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +log-event-recycle-restore-more=\u5c06{0}\u4e2a\u6587\u6863\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +log-event-remove=\u5728\u6b64\u5904\u5220\u9664\u4e86{0} +log-event-remove-current=\u5728\u6b64\u5904\u5220\u9664\u4e86{0} +log-event-remove-item=\u5728{0}\u5220\u9664\u4e86{1} +log-event-remove-more=\u5728\u6b64\u5904\u5220\u9664\u4e86{0}\u4e2a\u6587\u6863 +log-event-remove-more-at=\u5728{0}\u5220\u9664\u4e86{1}\u4e2a\u6587\u6863 +log-event-addDesc=\u4fee\u6539\u4e86\u8be5\u6587\u6863\u63cf\u8ff0 +log-event-addDesc-item=\u4fee\u6539\u4e86{0}\u6587\u6863\u63cf\u8ff0 +log-event-addDesc-more=\u4fee\u6539\u4e86{0}\u4e2a\u6587\u6863\u63cf\u8ff0 +log-event-addComment=\u5728\u8be5\u6587\u6863\u53d1\u8868\u4e86\u8bc4\u8bba +log-event-addComment-item=\u5728{0}\u8868\u4e86\u8bc4\u8bba +log-event-addComment-more=\u5728{0}\u8868\u4e86{1}\u6761\u8bc4\u8bba +log-event-fav-fileAdd=\u6536\u85cf\u4e86\u6587\u4ef6{0} +log-event-fav-dirAdd=\u6536\u85cf\u4e86\u6587\u4ef6\u5939{0} +log-event-down-item=\u4ece{0}\u4e0b\u8f7d\u4e86{1} +log-event-down-items=\u4ece{0}\u4e0b\u8f7d\u4e86 +log-event-recycle-del-item=\u4ece\u56de\u6536\u7ad9\u5220\u9664{0}\u4e2a\u6587\u4ef6 +log-event-recycle-rst-item=\u4ece\u56de\u6536\u7ad9\u8fd8\u539f{0}\u4e2a\u6587\u4ef6 +log-event-del-item=\u5220\u9664\u4e86{0}\u4e2a\u6587\u4ef6 +log.file.move=\u79fb\u52a8/\u590d\u5236 +log.file.fav=\u6536\u85cf\u5939\u64cd\u4f5c +log.file.shareLink=\u5916\u94fe\u5206\u4eab +log.file.shareTo=\u534f\u4f5c\u5206\u4eab +log.user.edit=\u4fee\u6539\u8d26\u53f7\u4fe1\u606f +log.group.edit=\u90e8\u95e8\u7ba1\u7406 +log.member.edit=\u7528\u6237\u7ba1\u7406 +log.role.edit=\u89d2\u8272\u6743\u9650\u7ba1\u7406 +log.auth.edit=\u6587\u6863\u6743\u9650\u7ba1\u7406 +meta.user_sourceAlias=\u5173\u8054\u6587\u4ef6(\u9644\u4ef6) +meta.user_fileEncodeType=\u6587\u4ef6\u5bc6\u7ea7 +meta.user_fileEncodeType.A=A-\u7edd\u5bc6 +meta.user_fileEncodeType.B=B-\u673a\u5bc6 +meta.user_fileEncodeType.C=C-\u79d8\u5bc6 +meta.user_sourceNumber=\u5b97\u5377\u7f16\u53f7 +meta.user_sourceParticipant=\u53c2\u4e0e\u8005 +explorer.fileInfo.createTime=\u521b\u5efa\u65e5\u671f +explorer.fileInfo.modifyTime=\u4fee\u6539\u65e5\u671f +explorer.fileInfo.softwareCreate=\u5236\u4f5c\u8f6f\u4ef6 +explorer.fileInfo.software=\u7f16\u7801\u8f6f\u4ef6 +explorer.fileInfo.playTime=\u64ad\u653e\u65f6\u957f +explorer.fileInfo.imageSize=\u56fe\u7247\u5c3a\u5bf8 +explorer.fileInfo.imageDpi=\u5206\u8fa8\u7387 +explorer.fileInfo.imageBits=\u4f4d\u6df1\u5ea6 +explorer.fileInfo.imageDesc=\u6807\u6ce8\u8bf4\u660e +explorer.fileInfo.imageAuthor=\u521b\u4f5c\u8005 +explorer.fileInfo.imageColor=\u8272\u5f69\u7a7a\u95f4 +explorer.fileInfo.cameraType=\u8bbe\u5907\u578b\u53f7 +explorer.fileInfo.cameraApertureFNumber=\u5149\u5708\u6570 +explorer.fileInfo.cameraApertureValue=\u5149\u5708\u503c +explorer.fileInfo.cameraShutterSpeedValue=\u5feb\u95e8\u901f\u5ea6 +explorer.fileInfo.cameraExposureTime=\u66dd\u5149\u65f6\u95f4 +explorer.fileInfo.cameraFocalLength=\u7126\u8ddd +explorer.fileInfo.cameraFocusDistance=\u5bf9\u7126\u8ddd\u79bb +explorer.fileInfo.cameraISOSpeedRatings=ISO\u611f\u5149\u5ea6 +explorer.fileInfo.cameraWhiteBalance=\u767d\u5e73\u8861 +explorer.fileInfo.cameraUser=\u624b\u52a8 +explorer.fileInfo.cameraAuto=\u81ea\u52a8 +explorer.fileInfo.cameraExposureMode=\u66dd\u5149\u6a21\u5f0f +explorer.fileInfo.cameraExposureBiasValue=\u66dd\u5149\u8865\u507f +explorer.fileInfo.imageGps=\u62cd\u6444\u4f4d\u7f6e +explorer.fileInfo.imageCreateTime=\u62cd\u6444\u65e5\u671f +explorer.fileInfo.audioChannel=\u97f3\u9891\u58f0\u9053 +explorer.fileInfo.audioChannel1=\u5355\u58f0\u9053 +explorer.fileInfo.audioChannel2=\u7acb\u4f53\u58f0 +explorer.fileInfo.audioChannels=\u591a\u58f0\u9053 +explorer.fileInfo.audioRate=\u97f3\u9891\u91c7\u6837\u7387 +explorer.fileInfo.audioBits=\u97f3\u9891\u4f4d\u6df1\u5ea6 +explorer.fileInfo.audioBitrate=\u97f3\u9891\u6bd4\u7279\u7387 +explorer.fileInfo.vedioFormat=\u89c6\u9891\u7f16\u7801 +explorer.fileInfo.audioTitle=\u6807\u9898 +explorer.fileInfo.audioAuthor=\u4f5c\u8005 +explorer.fileInfo.audioAlbum=\u4e13\u8f91 +explorer.fileInfo.audioStyle=\u98ce\u683c +explorer.fileInfo.audioYear=\u4e13\u8f91\u5e74\u4ee3 +explorer.fileInfo.vedioSize=\u753b\u9762\u5c3a\u5bf8 +explorer.fileInfo.vedioFrame=\u89c6\u9891\u5e27\u7387 +explorer.fileInfo.vedioBitrate=\u89c6\u9891\u6bd4\u7279\u7387 +explorer.fileInfo.title=\u6807\u9898 +explorer.fileInfo.author=\u4f5c\u8005 +explorer.fileInfo.pageTotal=\u603b\u9875\u6570 +explorer.fileInfo.pageSize=\u9875\u9762\u5c3a\u5bf8 +explorer.fileInfo.pagePower=\u5185\u5bb9\u521b\u4f5c\u8005 +explorer.fileInfo.pdfVersion=PDF\u7248\u672c +explorer.filter.shareCopyLimit=\u8f6c\u5b58\u6587\u4ef6\u4e2a\u6570\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u8f6c\u5b58\u6587\u4ef6\u4e2a\u6570\u4e3a: +explorer.filter.shareSizeLimit=\u5206\u4eab\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u5206\u4eab\u6587\u6863: +explorer.filter.unzipSizeLimit=\u89e3\u538b\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u89e3\u538b\u6587\u6863: +explorer.filter.zipSizeLimit=\u538b\u7f29\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u538b\u7f29\u6587\u6863: +explorer.filter.uploadSizeLimit=\u4e0a\u4f20\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u4e0a\u4f20\u6587\u6863: +explorer.fileEditError=\u5f53\u524d\u6587\u4ef6 %s \u6b63\u5728\u7f16\u8f91,\u8bf7\u7a0d\u540e\u518d\u8bd5 +explorer.groupDelError=\u62b1\u6b49\u90e8\u95e8\u6587\u4ef6\u5939\u4e0d\u652f\u6301\u5220\u9664 +admin.info.typeDelError=\u5220\u9664\u5931\u8d25, \u6709\u5b50\u5206\u7c7b\u6216\u6570\u636e +admin.info.domainIdentifyError=\u7f51\u7ad9\u65e0\u6cd5\u8bc6\u522b +admin.info.articleIdentifyError=\u6587\u7ae0\u65e0\u6cd5\u8bc6\u522b +admin.info.domainSupportError=\u8be5\u7f51\u7ad9\u6682\u4e0d\u652f\u6301\u91c7\u96c6 +admin.info.fileTooLarge=\u6587\u4ef6\u8fc7\u5927 +explorer.toolbar.info=\u8d44\u8baf +source.shareDisabled=\u5f53\u524d\u8d44\u6e90\u7981\u6b62\u5206\u4eab +admin.exceeds.limit=\u8d85\u51fa\u9650\u5236 +admin.design.deleted=\u542f\u7528\u72b6\u6001\u65e0\u6cd5\u5220\u9664 +admin.design.url.locked=\u88ab\u9501\u5b9a\u002c\u0020\u6682\u65f6\u4e0d\u80fd\u4f7f\u7528 +explorer.SING_INVALID=\u7b7e\u540d\u5f02\u5e38 +explorer.TEMP_AUTH_INVALID=\u4e34\u65f6\u6388\u6743\u7801\u65e0\u6548\uff08\u5931\u6548\uff09 +explorer.QR_INVALID=\u4e8c\u7ef4\u7801\u5df2\u5931\u6548 +explorer.toolbar.toolbox=\u5de5\u5177\u7bb1 +explorer.toolbox.desc= +logs-detail-mkdir=\u65b0\u5efa\u4e86\u6587\u4ef6\u5939 +logs-detail-mkfile=\u65b0\u5efa\u4e86\u6587\u4ef6 +logs-detail-editFile=\u7f16\u8f91\u66f4\u65b0\u4e86 +logs-detail-upload=\u4e0a\u4f20\u4e86\u6587\u4ef6 +logs-detail-uploadNew=\u7f16\u8f91\u4e86 +logs-detail-file.upload=\u4e0a\u4f20\u4e86 +logs-detail-file-copy=\u7c98\u8d34\u521b\u5efa\u4e86\u6587\u4ef6 +logs-detail-folder-copy=\u7c98\u8d34\u521b\u5efa\u4e86\u6587\u4ef6\u5939 +logs-detail-paste=\u7c98\u8d34 +logs-detail-from=\u4ece +logs-detail-to=\u5230 +logs-detail-rename=\u91cd\u547d\u540d\u4e86 +logs-detail-rename-file=\u91cd\u547d\u540d\u4e86\u8be5\u6587\u4ef6 +logs-detail-rename-folder=\u91cd\u547d\u540d\u4e86\u8be5\u6587\u4ef6\u5939 +logs-detail-user=\u7528\u6237: +logs-detail-moveFrom-restore=\u5c06 +logs-detail-moveTo-restore=\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +logs-detail-move=\u5c06 +logs-detail-moveTo=\u79fb\u52a8\u5230 +logs-detail-moveFrom-toRecycle=\u5c06 +logs-detail-moveTo-toRecycle=\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +logs-detail-file-toRecycle=\u5c06\u8be5\u6587\u4ef6\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +logs-detail-file-restore=\u5c06\u8be5\u6587\u4ef6\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +logs-detail-folder-toRecycle=\u5c06\u8be5\u6587\u4ef6\u5939\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +logs-detail-folder-restore=\u5c06\u8be5\u6587\u4ef6\u5939\u4ece\u56de\u6536\u7ad9\u8fd8\u539f +logs-detail-favAdd=\u6536\u85cf\u4e86 +logs-detail-favDel=\u53d6\u6d88\u4e86\u6536\u85cf +logs-detail-unstar=\u540d\u79f0: +logs-detail-moveOut=\u79fb\u8d70\u4e86 +logs-detail-remove=\u5220\u9664\u4e86 +logs-detail-file.copy=\u7c98\u8d34\u4e86 +explorer.noPermissionAuthAll={0} ,\u6c92\u6709\u6b64\u64cd\u4f5c\u6743\u9650 \ No newline at end of file diff --git a/src/main/resources/i18n/messages_zh_TW.properties b/src/main/resources/i18n/messages_zh_TW.properties new file mode 100644 index 0000000..df091be --- /dev/null +++ b/src/main/resources/i18n/messages_zh_TW.properties @@ -0,0 +1,2566 @@ +admin.serverInfo=\u670d\u52d9\u5668\u4fe1\u606f +admin.today=\u4eca\u5929 +admin.yesterday=\u6628\u5929 +admin.weekDay=\u8fd17\u5929 +admin.monthDay=\u8fd130\u5929 +admin.ing=\u9032\u884c\u4e2d +admin.paused=\u5df2\u66ab\u505c +admin.serverDownload=\u9060\u7a0b\u4e0b\u8f09 +admin.memberManage=\u7528\u6236\u7ba1\u7406 +admin.fileManage=\u6587\u4ef6\u7ba1\u7406 +admin.pwdEdit=\u4fee\u6539\u5bc6\u78bc +admin.fileEdit=\u7de8\u8f2f\u4fdd\u5b58\u6587\u4ef6 +admin.list=\u5217\u8868\u67e5\u770b +admin.configError=\u914d\u7f6e\u4fdd\u5b58\u5931\u6557\u7ba1\u7406\u54e1\u7981\u6b62\u4e86\u6b64\u6b0a\u9650! +admin.userManage=\u500b\u4eba\u4e2d\u5fc3 +admin.manage=\u5f8c\u53f0\u7ba1\u7406 +admin.pluginManage=\u63d2\u4ef6\u7ba1\u7406 +admin.emailDear=%s��\u60a8\u597d�� +admin.emailCodeText=\u60a8\u6b63\u5728\u9032\u884c\u90f5\u7bb1\u9a57\u8b49��\u672c\u6b21\u8acb\u6c42\u7684\u9a57\u8b49\u78bc\u5982\u4e0b��\u70ba\u4e86\u4fdd\u969c\u60a8\u5e33\u865f\u7684\u5b89\u5168\u6027��\u8acb\u53ca\u6642\u5b8c\u6210\u9a57\u8b49�� +admin.emailVerifyInTime=\u70ba\u4e86\u4fdd\u969c\u60a8\u5e33\u865f\u7684\u5b89\u5168\u6027��\u8acb\u53ca\u6642\u5b8c\u6210\u9a57\u8b49. +admin.dear=\u5c0a\u656c\u7684 +admin.dearUser=\u89aa\u611b\u7684\u7528\u6236�� +admin.emailResetLink=\u60a8\u6b63\u5728\u901a\u904e\u90f5\u7bb1\u91cd\u7f6e%s\u7684\u767b\u9304\u5bc6\u78bc��\u8acb\u9ede\u64ca\u4e0b\u9762\u7684\u93c8\u63a5\u9032\u884c\u91cd\u7f6e��\u5982\u679c\u93c8\u63a5\u7121\u6cd5\u8df3\u8f49��\u8acb\u5c07\u5176\u8907\u88fd\u5230\u700f\u89bd\u5668\u7684\u5730\u5740\u6b04\u9032\u884c\u8a2a\u554f�� +admin.emailExpireTime=\u8a72\u93c8\u63a520\u5206\u9418\u5f8c\u5931\u6548. +admin.jobName=\u5d17\u4f4d\u540d\u7a31 +admin.jobDesc=\u5d17\u4f4d\u8aaa\u660e +admin.jobNameInput=\u8acb\u8f38\u5165\u5d17\u4f4d\u540d\u7a31 +admin.jobEdit=\u5d17\u4f4d\u7de8\u8f2f +admin.menu.home=\u9996\u9801 +admin.menu.dashboard=\u6982\u89bd +admin.menu.dashboardTitle=\u6578\u64da\u7d71\u8a08\u6982\u89bd +admin.menu.notice=\u901a\u77e5\u7ba1\u7406 +admin.menu.groupMember=\u90e8\u9580\u8207\u6210\u54e1\u7ba1\u7406 +admin.menu.member=\u90e8\u9580\u53ca\u7528\u6236 +admin.menu.role=\u89d2\u8272\u6743\u9650\u7ba1\u7406 +admin.menu.job=\u5d17\u4f4d\u7ba1\u7406 +admin.menu.auth=\u6587\u6a94\u6b0a\u9650\u7ba1\u7406 +admin.menu.storage=\u5b58\u5132/\u6587\u4ef6 +admin.menu.storageDriver=\u5b58\u5132\u7ba1\u7406 +admin.menu.plugin=\u63d2\u4ef6\u4e2d\u5fc3 +admin.menu.tools=\u5b89\u5168\u7ba1\u63a7 +admin.menu.server=\u670d\u52d9\u5668\u7ba1\u7406 +admin.menu.backup=\u5099\u4efd\u7ba1\u7406 +admin.menu.share=\u5206\u4eab\u7ba1\u7406 +admin.menu.loginLog=\u767b\u9304\u65e5\u8a8c +admin.menu.log=\u64cd\u4f5c\u65e5\u8a8c +admin.menu.task=\u8a08\u5283\u4efb\u52d9 +admin.autoTask.restart=\u91cd\u555f\u8a08\u5283\u4efb\u52d9 +admin.autoTask.restartEnd=\u8a08\u5283\u4efb\u52d9\u5df2\u7d93\u91cd\u555f +admin.index.userSpace=\u7528\u6236\u7a7a\u9593 +admin.index.groupSpace=\u90e8\u9580\u7a7a\u9593 +admin.index.folderCount=\u6587\u4ef6\u593e\u6578�� +admin.index.fileCount=\u6587\u4ef6\u6578�� +admin.index.loginToday=\u4eca\u65e5\u767b\u9304 +admin.index.useTotal=\u7e3d\u4f7f\u7528\u91cf�� +admin.index.userLogin=\u7528\u6236\u767b\u9304 +admin.index.spaceUsed=\u4f54\u7528\u7a7a\u9593 +admin.index.useSpace=\u4f7f\u7528\u7a7a\u9593 +admin.index.usedSpace=\u5df2\u7528\u7a7a\u9593 +admin.index.freeSpace=\u5269\u9918\u7a7a\u9593 +admin.index.sizeLimit=\u9650\u5b9a\u5927\u5c0f +admin.index.vipCount=\u8a3b\u518a\u7528\u6236 +admin.index.loginCurrent=\u7576\u524d\u5728\u7dda +admin.index.fileDel=\u6587\u4ef6\u522a\u9664 +admin.index.fileEdit=\u6587\u4ef6\u7de8\u8f2f +admin.index.fileUpload=\u6587\u4ef6\u4e0a\u50b3 +admin.index.fileDown=\u6587\u4ef6\u4e0b\u8f09 +admin.index.spaceUse=\u5be6\u969b\u4f7f\u7528 +admin.index.spaceSave=\u7bc0\u7d04\u7a7a\u9593 +admin.index.spaceUser=\u7528\u6236\u4f7f\u7528 +admin.index.spaceGroup=\u90e8\u9580\u4f7f\u7528 +admin.index.lastLogin=\u6700\u8fd1\u767b\u9304\u6642\u9593 +admin.index.totalUsers=\u7e3d\u7528\u6236\u6578 +admin.index.loginUsers=\u767b\u9304\u7528\u6236 +admin.index.spaceActUsed=\u5be6\u969b\u4f54\u7528 +admin.index.source=\u767b\u9304\u4f86\u6e90 +admin.index.address=\u767b\u9304\u5730\u5740 +admin.index.userInfo=\u7528\u6236\u4fe1\u606f +admin.index.userValid=\u6709\u6548\u8cec\u865f +admin.index.userInvalid=\u7121\u6548\u8cec\u865f +admin.index.fileInfo=\u6587\u4ef6\u4fe1\u606f +admin.index.fileCnt=\u6587\u4ef6\u500b\u6578 +admin.index.fileAdd=\u4eca\u65e5\u65b0\u589e +admin.index.accInfo=\u8a2a\u554f\u4fe1\u606f +admin.index.accCnt=\u8acb\u6c42\u6b21\u6578 +admin.index.accUser=\u8a2a\u554f\u7528\u6236 +admin.index.serverInfo=\u7cfb\u7d71\u4fe1\u606f +admin.index.serverDisk=\u7cfb\u7d71\u78c1\u76e4 +admin.index.serverStore=\u7db2\u76e4\u5b58\u5132 +admin.index.serverName=\u670d\u52d9\u5668\u540d +admin.index.normal=\u6b63\u5e38 +admin.index.scoreDesc=\u4e0b\u5217\u56e0\u7d20\u5c07\u5f71\u97ff\u7cfb\u7d71\u8a55\u5206��\u53ef\u81ea\u884c\u512a\u5316��\u4ee5\u4fdd\u8b49\u7cfb\u7d71\u826f\u597d\u904b\u884c��
    1.\u7cfb\u7d71\u78c1\u76e4��\u7db2\u76e4\u5b58\u5132\u7684\u5269\u9918\u7a7a\u9593��
    2.\u6578\u64da\u7de9\u5b58\u65b9\u5f0f��\u63a8\u85a6redis��;
    3.php\u5e73\u53f0\u7248\u672c��\u63a8\u85a664\u4f4dphp7+���� +admin.index.fileRatio=\u6587\u4ef6\u4f7f\u7528\u4f54\u6bd4 +admin.setting.system=\u7cfb\u7d71\u8a2d\u7f6e +admin.setting.account=\u8cec\u865f\u8a2d\u7f6e +admin.setting.theme=\u4e3b\u984c\u8a2d\u7f6e +admin.setting.wall=\u58c1\u7d19\u8a2d\u7f6e +admin.setting.stats=\u4f7f\u7528\u7d71\u8a08 +admin.setting.safeMgt=\u5b89\u5168\u7ba1\u7406 +admin.setting.base=\u57fa\u790e\u8a2d\u7f6e +admin.setting.others=\u5176\u4ed6\u8a2d\u7f6e +admin.setting.sync=\u540c\u6b65\u8a2d\u7f6e +admin.setting.plugin=\u63d2\u4ef6\u8a2d\u7f6e +admin.setting.auth=\u6b0a\u9650\u8a2d\u7f6e +admin.setting.safe=\u5b89\u5168\u8a2d\u7f6e +admin.setting.loginLog=\u767b\u9304\u65e5\u8a8c +admin.setting.loginDevice=\u767b\u9304\u8a2d\u5099 +admin.setting.deviceType=\u8a2d\u5099\u985e\u578b +admin.setting.lastLoginTime=\u6700\u8fd1\u767b\u9304\u6642\u9593 +admin.setting.email=\u90f5\u7bb1\u8a2d\u7f6e +admin.setting.user=\u8a3b\u518a\u8207\u767b\u9304 +admin.setting.pwdOld=\u539f\u5bc6\u78bc +admin.setting.pwdNew=\u4fee\u6539\u70ba +admin.setting.wallDiy=\u81ea\u5b9a\u7fa9\u58c1\u7d19�� +admin.setting.fav=\u6536\u85cf\u593e\u7ba1\u7406 +admin.setting.help=\u4f7f\u7528\u5e6b\u52a9 +admin.setting.about=\u95dc\u65bc\u4f5c\u54c1 +admin.setting.homePage= +admin.setting.subMenu=\u5b50\u83dc\u55ae +admin.setting.menuName=\u83dc\u55ae\u540d +admin.setting.menuUrl=URL\u5730\u5740 +admin.setting.menuUrlDesc=url\u5730\u5740\u6216js\u4ee3\u78bc +admin.setting.safeAccount=\u8cec\u865f\u53ca\u767b\u9304\u5b89\u5168 +admin.setting.safeData=\u6578\u64da\u5b89\u5168/\u50b3\u8f38\u5b89\u5168 +admin.setting.passwordErrorLock=\u5bc6\u78bc\u8f38\u5165\u932f\u8aa4\u9396\u5b9a +admin.setting.passwordErrorLockDesc=\u9023\u7e8c5\u6b21\u5bc6\u78bc\u932f\u8aa4\u9396\u5b9a\u8a72\u8cec\u62361\u5206\u9418\u4e0d\u5141\u8a31\u767b\u9304\u958b\u555f\u5f8c\u80fd\u6709\u6548\u9632\u6b62\u5bc6\u78bc\u66b4\u529b\u7834\u89e3; +admin.setting.passwordRule=\u7528\u6236\u5bc6\u78bc\u5f37\u5ea6\u8a2d\u7f6e +admin.setting.passwordRuleDesc=\u6307\u5b9a\u5bc6\u78bc\u5f37\u5ea6\u5f8c\u53ef\u6709\u6548\u675c\u7d55\u5f31\u53e3\u4ee4 +admin.setting.passwordRuleNone=\u4e0d\u9650\u5236 +admin.setting.passwordRuleStrong=\u4e2d\u7b49\u5f37\u5ea6 +admin.setting.passwordRuleStrongMore=\u9ad8\u5f37\u5ea6 +admin.setting.passwordRuleNoneDesc=\u4e0d\u9650\u5236\u5bc6\u78bc\u5f37\u5ea6 +admin.setting.passwordRuleStrongDesc=\u9577\u5ea6\u5927\u65bc6;\u5fc5\u9808\u540c\u6642\u5305\u542b\u82f1\u6587\u548c\u6578\u5b57; +admin.setting.passwordRuleStrongMoreDesc=\u9577\u5ea6\u5927\u65bc6;\u5fc5\u9808\u540c\u6642\u5305\u542b\u6578\u5b57\u5927\u5beb\u82f1\u6587\u5c0f\u5beb\u82f1\u6587; +admin.setting.passwordRuleTips=\u60a8\u7684\u7576\u524d\u5bc6\u78bc\u5f37\u5ea6\u4e0d\u8db3\u5efa\u8b70\u7acb\u5373\u4fee\u6539\u5bc6\u78bc! +admin.loginCheck.menu=\u767b\u9304\u7ba1\u63a7 +admin.loginCheck.ipCheck=IP\u9650\u5236 +admin.loginCheck.ipCheckNone=\u4e0d\u9650\u5236 +admin.loginCheck.ipCheckAllow=IP\u767d\u540d\u55ae +admin.loginCheck.ipCheckDisable=IP\u9ed1\u540d\u55ae +admin.loginCheck.loginIpAllowDesc=\u958b\u555f\u5f8c\u53ea\u5141\u8a31\u6307\u5b9aip\u7684\u7528\u6236\u624d\u80fd\u767b\u9304\u8acb\u8b39\u614e\u64cd\u4f5c +admin.loginCheck.ipAllow=\u5141\u8a31\u7684IP +admin.loginCheck.ipAllowDesc=\u586b\u5beb\u898f\u5247\u5982\u4e0b(\u6bcf\u689d\u4e00\u884c\u9ed8\u8a8d\u5141\u8a31\u670d\u52d9\u5668\u672c\u6a5fIP\u7cfb\u7d71\u7ba1\u7406\u54e1\u5141\u8a31\u5c40\u57df\u7db2IP) +admin.loginCheck.ipDisable=\u9ed1\u540d\u55aeIP\u898f\u5247 +admin.loginCheck.ipDisableDesc=\u958b\u555f\u5f8c\u7b26\u5408ip\u689d\u4ef6\u7684\u7528\u6236\u5c07\u4e0d\u80fd\u505a\u4efb\u4f55\u64cd\u4f5c\u8acb\u8b39\u614e\u8655\u7406!
    \u5982\u679c\u6307\u5b9a\u8a2d\u7f6e\u4e86\u6240\u6709\u4eba\u5247\u6703\u6514\u622a\u6240\u6709\u8acb\u6c42! +admin.loginCheck.ipDescTitle=\u586b\u5beb\u898f\u5247\u5982\u4e0b(\u6bcf\u689d\u4e00\u884c) +admin.loginCheck.ipDesc=
  • \u5b8c\u6574IP:\u76f8\u7b49\u5247\u5339\u914d\u4f8b\u5982:192.168.10.10
  • IP\u524d\u7db4:ip\u4ee5\u524d\u7db4\u70ba\u958b\u982d\u5247\u5339\u914d;\u4f8b\u5982:192.168
  • IP\u5340\u9593\u6bb5:ip\u5728\u5340\u9593\u5167\u5247\u5339\u914d;\u4f8b\u5982:192.168.1.1-192.168.200.255
  • +admin.loginCheck.sort=\u512a\u5148\u7d1a +admin.loginCheck.name=\u898f\u5247\u540d\u7a31 +admin.loginCheck.user=\u6307\u5b9a\u7528\u6236 +admin.loginCheck.device=\u6307\u5b9a\u8a2d\u5099 +admin.loginCheck.deviceWeb=\u7db2\u9801\u7aef +admin.loginCheck.devicePc=PC\u7aef +admin.loginCheck.deviceAndroid=\u5b89\u5353 +admin.loginCheck.deviceIOS=iOS +admin.loginCheck.desc=\u5982\u679c\u60f3\u958b\u555f\u6216\u95dc\u9589\u7ba1\u7406\u54e1\u8a2a\u554f\u5176\u4ed6\u76ee\u9304\u53ef\u4ee5\u4fee\u6539php\u9632\u8de8\u7ad9open_basedir\u53c3\u6578\u5168\u90e8\u52a0\u5bc6:[\u9ed8\u8a8d\u63a8\u85a6];\u5373\u4fbf\u64c1\u6709\u670d\u52d9\u5668\u6b0a\u9650\u4e5f\u7121\u6cd5\u7372\u77e5\u6587\u4ef6\u771f\u5be6\u5167\u5bb9;\u80fd\u6709\u6548\u9632\u79a6\u52d2\u7d22\u75c5\u6bd2\u7b49\u7834\u58de; +admin.setting.encodeNameDesc=\u4fdd\u7559\u64f4\u5c55\u540d:\u6587\u4ef6\u540d\u52a0\u5bc6\u4fdd\u7559\u64f4\u5c55\u540d +admin.setting.encodeNullDesc=\u4e0d\u52a0\u5bc6:\u4e0d\u5c0d\u6587\u4ef6\u540d\u9032\u884c\u52a0\u5bc6\u4fdd\u7559\u539f\u59cb\u6587\u4ef6\u540d;(\u70ba\u78ba\u4fdd\u5b89\u5168\u6027\u4e0a\u50b3\u6587\u4ef6\u593e\u540d\u70ba\u52a0\u5bc6\u69cb\u9020); +admin.setting.encodeTips1=\u50c5\u5f71\u97ff\u8a2d\u7f6e\u66f4\u6539\u5f8c\u7684\u6587\u4ef6\u4e4b\u524d\u5df2\u5b58\u5728\u7684\u6587\u4ef6\u4e0d\u53d7\u5f71\u97ff; +admin.setting.encodeTips2=\u70ba\u907f\u514d\u932f\u8aa4\u8acb\u52ff\u5c0ddata/files\u4e2d\u7684\u6587\u4ef6\u9032\u884c\u522a\u9664\u6216\u91cd\u547d\u540d\u76f8\u95dc\u64cd\u4f5c; +admin.setting.encodeTips3=\u70ba\u652f\u6301\u5927\u898f\u6a21\u4e26\u767c\u79d2\u50b3\u96c6\u7fa4\u5206\u4f48\u5f0f\u81ea\u52d5\u64f4\u5bb9\u7b49\u529f\u80fd;\u6587\u4ef6\u593e\u5c64\u7d1a\u7d50\u69cb\u8a18\u9304\u5728\u6578\u64da\u5eab\u4e2d;\u53ef\u4ee5\u901a\u904e\u8907\u88fd\u7c98\u8cbc\u5be6\u73fe\u5c0e\u5165\u53ca\u9084\u539f\u6587\u4ef6\u593e\u7d50\u69cb; +admin.setting.thirdLogin=\u7b2c\u4e09\u65b9\u767b\u9304 +admin.setting.thirdLoginDesc=\u5141\u8a31\u901a\u904e\u7b2c\u4e09\u65b9\u8cec\u865f\u9032\u884c\u8a3b\u518a��\u7d81\u5b9a\u53ca\u767b\u9304 +admin.setting.registOpen=\u958b\u555f\u7528\u6236\u8a3b\u518a +admin.setting.registOpenDesc=\u70ba\u907f\u514d\u6578\u64da\u885d\u7a81��\u7b2c\u4e09\u65b9\u6578\u64da\u540c\u6b65\u548c\u7528\u6236\u8a3b\u518a\u4e0d\u80fd\u540c\u6642\u555f\u7528 +admin.setting.registCheck=\u958b\u555f\u8a3b\u518a\u5be9\u6838 +admin.setting.registCheckDesc=\u958b\u555f\u5f8c��\u9700\u8981\u7ba1\u7406\u54e1\u5728[\u7528\u6236\u8207\u90e8\u9580]\u4e2d\u5be9\u6838\u4e26\u555f\u7528��\u8a3b\u518a\u7528\u6236\u624d\u80fd\u6b63\u5e38\u4f7f\u7528 +admin.setting.clearUserRecycle=\u6e05\u7a7a\u6240\u6709\u7528\u6236\u56de\u6536\u7ad9 +admin.setting.clearCache=\u6e05\u7a7a\u7de9\u5b58 +admin.setting.icp=\u7248\u6b0a\u6216\u5099\u6848\u865f +admin.setting.icpDesc=\u5982\u9700\u751f\u6210\u93c8\u63a5��\u53ef\u81ea\u884c\u6dfb\u52a0a\u6a19\u7c64 +admin.setting.globalCss=\u81ea\u5b9a\u7fa9\u5168\u5c40css +admin.setting.globalCssDesc=\u6240\u6709\u9801\u9762\u5c07\u6703\u63d2\u5165\u81ea\u5b9a\u7fa9css +admin.setting.globalHtml=\u7d71\u8a08\u4ee3\u78bcHTML +admin.setting.globalHtmlDesc=\u6240\u6709\u9801\u9762\u5c07\u63d2\u5165\u6b64\u6bb5html\u4ee3\u78bc\u53ef\u4ee5\u653e\u7f6e\u7b2c\u4e09\u65b9\u7d71\u8a08\u4ee3\u78bc +admin.setting.dateFormat=\u65e5\u671f\u683c\u5f0f +admin.setting.dateFormatDesc=\u5e74\u6708\u65e5\u6642\u9593\u683c\u5f0f\u986f\u793a\u6587\u4ef6\u4fee\u6539\u6642\u9593\u7b49\u8655\u9ad4\u73fe +admin.setting.menu=\u83dc\u55ae\u7ba1\u7406 +admin.setting.systemName=\u516c\u53f8\u7522\u54c1\u540d +admin.setting.systemNameDesc=\u7528\u65bc\u7522\u54c1logo\u6a19\u984c +admin.setting.systemDesc=\u7522\u54c1\u526f\u6a19\u984c +admin.setting.pathHidden=\u76ee\u9304\u6392\u9664 +admin.setting.pathHiddenDesc=\u9ed8\u8a8d\u4e0d\u986f\u793a\u7684\u76ee\u9304\u548c\u6587\u4ef6\u9017\u865f\u9694\u958b +admin.setting.defaultFolder=\u65b0\u7528\u6236\u9ed8\u8a8d\u5275\u5efa\u76ee\u9304 +admin.setting.defaultFolderDesc=\u7528\u9017\u865f\u9694\u958b +admin.setting.defaultApp=\u65b0\u7528\u6236\u9ed8\u8a8d\u5275\u5efaapp +admin.setting.defaultAppDesc=\u61c9\u7528\u4e2d\u5fc3\u7684\u61c9\u7528��\u591a\u500b\u7528\u9017\u865f\u9694\u958b +admin.setting.autoLogin=\u904a\u5ba2\u81ea\u52d5\u767b\u9304 +admin.setting.autoLoginDesc=\u9ed8\u8a8d\u767b\u9304\u7528\u6236\u70baguest/guest\u7684\u7528\u6236��\u958b\u555f\u5f8c\u78ba\u4fdd\u8a72\u7528\u6236\u5b58\u5728 +admin.setting.firstIn=\u767b\u9304\u5f8c\u9ed8\u8a8d\u9032\u5165 +admin.setting.registReviewOpen=\u958b\u555f\u8a3b\u518a\u5be9\u6838: +admin.setting.registRoleEmpty=\u89d2\u8272\u6b0a\u9650\u4e0d\u80fd\u70ba\u7a7a +admin.setting.registNotSync=\u70ba\u907f\u514d\u6578\u64da\u885d\u7a81��\u7b2c\u4e09\u65b9\u6578\u64da\u540c\u6b65\u548c\u7528\u6236\u8a3b\u518a\u4e0d\u80fd\u540c\u6642\u555f\u7528 +admin.setting.registNeedRewiew=\u958b\u555f\u5f8c��\u9700\u8981\u7ba1\u7406\u54e1\u5728\u7528\u6236\u8207\u90e8\u9580\u4e2d\u5be9\u6838\u4e26\u555f\u7528��\u8a3b\u518a\u7528\u6236\u624d\u80fd\u6b63\u5e38\u4f7f\u7528 +admin.setting.roleRight=\u89d2\u8272\u6b0a\u9650 +admin.setting.emailHost=\u90f5\u7bb1\u670d\u52d9\u5668 +admin.setting.emailHostInput=\u8acb\u8f38\u5165\u90f5\u4ef6\u670d\u52d9\u5668\u5730\u5740 +admin.setting.emailHostTips=\u8acb\u586b\u5beb\u90f5\u4ef6\u670d\u52d9\u5668\u5730\u5740 +admin.setting.emailHostDesc=\u90f5\u7bb1\u670d\u52d9\u5668��\u5982��smtp.163.com��\u53ef\u81ea\u5b9a\u7fa9\u7aef\u53e3��\u9ed8\u8a8d\u70ba465�� +admin.setting.emailSend=\u767c\u4ef6\u90f5\u7bb1 +admin.setting.emailSendInput=\u8acb\u8f38\u5165\u767c\u9001\u90f5\u7bb1\u5730\u5740 +admin.setting.emailSendTips=\u8acb\u586b\u5beb\u767c\u4ef6\u90f5\u7bb1\u5730\u5740 +admin.setting.emailSendDesc=\u7cfb\u7d71\u767c\u4ef6\u90f5\u7bb1\u5730\u5740��\u9700\u958b\u555fPOP3/SMTP\u670d\u52d9 +admin.setting.emailPwd=\u6388\u6b0a\u5bc6\u78bc +admin.setting.emailPwdTips=\u8acb\u586b\u5beb\u90f5\u7bb1\u6388\u6b0a\u5bc6\u78bc +admin.setting.secureType=\u52a0\u5bc6\u65b9\u5f0f +admin.setting.emailSendTest=\u767c\u9001\u6aa2\u6e2c +admin.setting.ensureEmailOk=\u8acb\u78ba\u4fdd\u90f5\u4ef6\u80fd\u6b63\u5e38\u767c\u9001 +admin.setting.emailTo=\u6536\u4ef6\u90f5\u7bb1 +admin.setting.emailGoToTips=\u8acb\u524d\u5f80\u90f5\u7bb1 +admin.setting.emailCheckTips=\u67e5\u770b +admin.setting.emailInputError=\u90f5\u7bb1\u8a2d\u7f6e\u586b\u5beb\u6709\u8aa4 +admin.setting.emailPwdError=\u90f5\u7bb1\u8a2d\u7f6e\u5bc6\u78bc\u586b\u5beb\u6709\u8aa4 +admin.setting.emailDesc=\u8a2d\u7f6e\u90f5\u4ef6\u670d\u52d9\u5668��\u7528\u65bc\u7528\u6236\u8a3b\u518a��\u5bc6\u78bc\u627e\u56de\u90f5\u4ef6\u767c\u9001 +admin.setting.sendEmail=\u767c\u9001\u90f5\u4ef6 +admin.setting.sendEmailDesc=\u7cfb\u7d71\u9ed8\u8a8d��\u8abf\u7528\u53ef\u9053\u4e91\u90f5\u4ef6\u670d\u52d9\u5668\u767c\u9001��\u81ea\u5b9a\u7fa9��\u81ea\u884c\u914d\u7f6e\u90f5\u4ef6\u670d\u52d9\u5668 +admin.setting.systemBackup=\u7cfb\u7d71\u5099\u4efd +admin.setting.enableFunction=\u529f\u80fd\u53ca\u958b\u95dc +admin.setting.treeOpen=\u6a39\u76ee\u9304\u529f\u80fd\u958b\u95dc +admin.setting.treeOpenDesc=\u6587\u4ef6\u7ba1\u7406\u6a39\u76ee\u9304\u5c0d\u61c9\u529f\u80fd\u5168\u5c40\u958b\u555f\u8207\u95dc\u9589 +admin.setting.groupListChild=\u7f85\u5217\u5b50\u90e8\u9580 +admin.setting.groupListChildDesc=\u90e8\u9580\u6587\u4ef6\u593e\u662f\u5426\u986f\u793a\u5b50\u90e8\u9580\u6b0a\u9650\u5411\u4e0a\u7e7c\u627f +admin.setting.groupRootListChild=\u4f01\u696d\u7db2\u76e4\u7f85\u5217\u5b50\u90e8\u9580 +admin.setting.groupRootListChildDesc=\u4f01\u696d\u7db2\u76e4\u6587\u4ef6\u593e\u662f\u5426\u986f\u793a\u5b50\u90e8\u9580\u6b0a\u9650\u5411\u4e0a\u7e7c\u627f +admin.setting.shareToMeAllowTree=\u8207\u6211\u5354\u4f5c-\u6309\u7d44\u7e54\u67b6\u69cb\u986f\u793a +admin.setting.shareToMeAllowTreeTips=\u958b\u555f\u5f8c\u8207\u6211\u5354\u4f5c\u7684\u5167\u5bb9\u652f\u6301\u6309\u90e8\u9580\u7d44\u7e54\u67b6\u69cb\u9032\u884c\u5206\u985e\u9069\u7528\u65bc\u7d44\u7e54\u67b6\u69cb\u6bd4\u8f03\u8907\u96dc\u7684\u60c5\u6cc1 +admin.setting.groupTagAllow=\u90e8\u9580\u516c\u5171\u6a19\u7c64 +admin.setting.groupTagAllowTips=\u555f\u7528\u5f8c\u90e8\u9580\u5167\u6587\u4ef6\u8a2d\u7f6e\u516c\u5171\u6a19\u7c64\u5f8c\u6240\u6709\u90e8\u9580\u6210\u54e1\u53ef\u898b.\u90e8\u9580\u7ba1\u7406\u54e1\u53ef\u4ee5\u7dad\u8b77\u6a19\u7c64\u5167\u5bb9. +admin.setting.shareToMeList=\u5e73\u92ea\u986f\u793a +admin.setting.shareToMeGroup=\u6309\u7d44\u7e54\u67b6\u69cb\u986f\u793a +admin.setting.shareToMeUser=\u6309\u5206\u4eab\u8005\u986f\u793a +admin.setting.sysSrvState=\u670d\u52d9\u5668\u72c0\u614b +admin.setting.sysSrvInfo=\u670d\u52d9\u5668\u4fe1\u606f +admin.setting.sysPhpInfo=PHP\u4fe1\u606f +admin.setting.database=\u6578\u64da\u5eab +admin.setting.cache=\u7de9\u5b58 +admin.setting.sysMyInfo=\u6211\u7684\u4fe1\u606f +admin.setting.srvStateCpu=CPU\u4f7f\u7528\u7387 +admin.setting.srvStateMem=\u5167\u5b58\u4f7f\u7528\u7387 +admin.setting.srvStateSrv=\u670d\u52d9\u5668\u7cfb\u7d71\u5b58\u5132\u7a7a\u9593 +admin.setting.srvStateDef=\u7db2\u76e4\u9ed8\u8a8d\u5b58\u5132\u7a7a\u9593 +admin.setting.srvInfoName=\u670d\u52d9\u5668\u540d +admin.setting.srvInfoIp=\u670d\u52d9\u5668IP +admin.setting.srvInfoTime=\u670d\u52d9\u5668\u6642\u9593 +admin.setting.srvInfoUpTime=\u6301\u7e8c\u904b\u884c\u6642\u9593 +admin.setting.srvInfoWeb=\u670d\u52d9\u5668\u8edf\u4ef6 +admin.setting.srvInfoPhpV=PHP\u7248\u672c +admin.setting.srvInfoSys=\u670d\u52d9\u5668\u7cfb\u7d71 +admin.setting.srvInfoPath=\u7db2\u7ad9\u8def\u5f91 +admin.setting.srvPhpDtl=PHP\u8a73\u60c5 +admin.setting.memLimit=\u5167\u5b58\u9650\u5236 +admin.setting.postLimit=POST\u63d0\u4ea4\u9650\u5236 +admin.setting.uploadLimit=\u4e0a\u50b3\u6587\u4ef6\u9650\u5236 +admin.setting.execTime=\u6700\u5927\u57f7\u884c\u6642\u9593 +admin.setting.inputTime=\u6700\u5927\u8acb\u6c42\u6642\u9593 +admin.setting.disFunction=\u7981\u7528\u51fd\u6578 +admin.setting.phpExtSugst=\u63a8\u85a6\u5b89\u88dd\u7684PHP\u64f4\u5c55 +admin.setting.phpExtLoad=\u5df2\u52a0\u8f09\u7684\u64f4\u5c55 +admin.setting.myClientIp=\u6211\u7684IP +admin.setting.myClientUa=\u6211\u7684\u700f\u89bd\u5668UA +admin.setting.myClientLng=\u6211\u7684\u700f\u89bd\u5668\u8a9e\u8a00 +admin.setting.disFuncDesc=\u7cfb\u7d71\u6240\u9700\u51fd\u6578��\u5efa\u8b70\u958b\u555f +admin.setting.srvMemFree=\u5269\u9918\u5167\u5b58 +admin.setting.srvMemUse=\u4f7f\u7528\u5167\u5b58 +admin.setting.srvCpuUse=\u7576\u524d\u4f54\u7528 +admin.setting.srvCpuFree=\u672a\u4f7f\u7528 +admin.setting.noLimit=\u7121\u9650\u5236 +admin.setting.disFunNo=\u7121 +admin.setting.systemCache=\u7cfb\u7d71\u7de9\u5b58 +admin.setting.systemDb=\u7cfb\u7d71\u6578\u64da\u5eab +admin.setting.sysCacheTab=\u7de9\u5b58\u5207\u63db +admin.setting.sysDbTab=\u6578\u64da\u5eab\u5207\u63db +admin.setting.sysRecTab=\u6578\u64da\u5eab\u6062\u5fa9 +admin.setting.cacheDesc=\u7de9\u5b58\u8aaa\u660e +admin.setting.fileCacheDesc=\u6587\u4ef6\u7de9\u5b58��\u5c07\u6578\u64da\u76f4\u63a5\u5beb\u5165\u5230\u7de9\u5b58\u6587\u4ef6��\u9069\u7528\u65bc\u6e2c\u8a66\u6216\u5c0f\u898f\u6a21\u4f7f\u7528�� +admin.setting.redisDesc=Redis��\u4e00\u500b\u9ad8\u6027\u80fd\u7684key-value\u975e\u95dc\u4fc2\u578b\u6578\u64da\u5eab��\u9069\u7528\u65bc\u9ad8\u4e26\u767c\u8b80\u5beb\u7684\u60c5\u6cc1��\u63a8\u85a6\u4f7f\u7528�� +admin.setting.memcachedDesc=Memcached��\u4e00\u500b\u9ad8\u6027\u80fd\u7684\u5206\u4f48\u5f0f\u5167\u5b58\u5c0d\u8c61\u7de9\u5b58\u7cfb\u7d71��\u9069\u7528\u65bc\u9ad8\u4e26\u767c\u8b80\u53d6\u7684\u60c5\u6cc1�� +admin.setting.saveAfterTest=\u6aa2\u6e2c\u901a\u904e\u5f8c��\u65b9\u53ef\u9032\u884c\u4fdd\u5b58 +admin.setting.checkPassed=\u6aa2\u6e2c\u901a\u904e +admin.setting.ifSaveCache=\u5207\u63db\u5f8c��\u7de9\u5b58\u6578\u64da\u5c07\u5168\u90e8\u88ab\u6e05\u9664��
    \u78ba\u5b9a\u8981\u57f7\u884c\u55ce�� +admin.setting.ifSaveDb=\u6578\u64da\u5eab\u5207\u63db��\u6703\u5c07\u7cfb\u7d71\u7576\u524d\u7684\u6578\u64da\u5c0e\u5165\u81f3\u65b0\u7684\u6578\u64da\u5eab��\u4e26\u5c07\u5176\u8a2d\u70ba\u9ed8\u8a8d��\u78ba\u5b9a\u8981\u57f7\u884c\u55ce�� +admin.setting.dbCurrent=\u7576\u524d\u914d\u7f6e +admin.setting.dbType=\u6578\u64da\u5eab\u985e\u578b +admin.setting.dbName=\u6578\u64da\u5eab\u540d\u7a31 +admin.setting.dbInfo=\u6578\u64da\u5eab\u4fe1\u606f +admin.setting.dbSwitch=\u958b\u555f\u5207\u63db +admin.setting.dbSwitchDesc=\u958b\u555f\u5f8c��\u53ef\u6839\u64da\u9700\u8981\u66f4\u6539\u6578\u64da\u5eab\u985e\u578b��\u8acb\u8b39\u614e\u64cd\u4f5c�� +admin.setting.dbTable=\u6578\u64da\u8868 +admin.setting.dbCnt=\u7e3d\u8a18\u9304\u6578 +admin.setting.dbNeedNew=\u6578\u64da\u5eab\u5df2\u5b58\u5728��\u8acb\u91cd\u65b0\u6307\u5b9a +admin.setting.dbInsertError=\u8868\u6578\u64da\u5beb\u5165\u5931\u6557 +admin.setting.dbNeedOthers=\u8acb\u9078\u64c7\u5176\u4ed6\u6578\u64da\u5eab\u985e\u578b +admin.setting.dbNeedChange=\u8acb\u4fee\u6539\u914d\u7f6e\u53c3\u6578 +admin.setting.dbCreateError=\u6578\u64da\u5eab\u6587\u4ef6\u5275\u5efa\u5931\u6557��\u8acb\u6aa2\u67e5\u76ee\u9304\u8b80\u5beb\u6b0a\u9650 +admin.setting.dbTaskProcess=\u57f7\u884c\u9032\u5ea6 +admin.setting.dbTasking=\u6b63\u5728\u57f7\u884c +admin.setting.dbTaskDesc=\u8acb\u52ff\u95dc\u9589\u7a97\u53e3��\u6216\u5728\u7cfb\u7d71\u4e2d\u9032\u884c\u5176\u4ed6\u64cd\u4f5c��\u907f\u514d\u7522\u751f\u5dee\u7570\u6027\u6578\u64da�� +admin.setting.recTaskDesc=\u8acb\u52ff\u95dc\u9589\u7a97\u53e3��\u8acb\u6c42\u4e2d\u65b7\u5f8c��\u5f8c\u53f0\u9084\u5c07\u7e7c\u7e8c\u57f7\u884c\u76f4\u81f3\u4efb\u52d9\u7d50\u675f�� +admin.setting.dbCreate=\u65b0\u5efa\u6578\u64da\u5eab +admin.setting.dbSelect=\u8b80\u53d6\u6578\u64da\u5eab +admin.setting.dbInsert=\u5beb\u5165\u6578\u64da\u5eab +admin.setting.dbSetSave=\u4fdd\u5b58\u914d\u7f6e\u4fe1\u606f +admin.setting.recDesc=\u4f7f\u7528\u8aaa\u660e +admin.setting.recDescInfo11=\u672c\u64cd\u4f5c\u5c07\u6703\u91cd\u7f6e\u7cfb\u7d71\u6578\u64da��\u975e\u904b\u7dad\u6216\u76f8\u95dc\u6280\u8853\u4eba\u54e1\u8acb\u52ff\u64cd\u4f5c�� +admin.setting.recDescInfo21=\u901a\u904e\u5c07\u5099\u4efd\u6578\u64da\u5eab\u5beb\u5165\u81f3\u65b0\u7684\u6578\u64da\u5eab��\u4e26\u5c07\u5176\u8a2d\u70ba\u7cfb\u7d71\u9ed8\u8a8d��\u5be6\u73fe\u6578\u64da\u7684\u6062\u5fa9�� +admin.setting.recDescInfo22= +admin.setting.recDescInfo23=\u672c\u529f\u80fd\u50c5\u652f\u6301\u8655\u7406\u7531\u7cfb\u7d71\u5099\u4efd\u7ba1\u7406\u7522\u751f\u7684\u5099\u4efd\u6578\u64da��\u81ea\u884c\u5099\u4efd\u7684\u6578\u64da\u5eab\u8acb\u901a\u904e\u5176\u4ed6\u65b9\u5f0f\u8655\u7406�� +admin.setting.recDescInfo31= +admin.setting.recDescInfo32= +admin.setting.recDescInfo33=\u8a2d\u7f6e\u6b0a\u9650�� +admin.setting.recDescInfo34=\u64a4\u92b7\u6b0a\u9650�� +admin.setting.recOpen=\u958b\u555f\u6062\u5fa9 +admin.setting.recOpenDesc=\u958b\u555f\u5f8c��\u53ef\u6839\u64da\u9700\u8981\u9078\u64c7\u5099\u4efd\u7684\u6578\u64da\u5eab\u9032\u884c\u6062\u5fa9��\u8acb\u8b39\u614e\u64cd\u4f5c�� +admin.setting.recTypeDesc=\u53d6\u6c7a\u65bc\u7cfb\u7d71\u7576\u524d\u4f7f\u7528\u7684\u985e\u578b +admin.setting.recPath=\u6578\u64da\u5eab\u5099\u4efd\u76ee\u9304 +admin.setting.recPathErr=\u7121\u6548\u7684\u6578\u64da\u5eab\u5099\u4efd\u76ee\u9304 +admin.setting.ifSaveRec=\u6578\u64da\u5eab\u6062\u5fa9��\u6703\u5c07\u5099\u4efd\u6578\u64da\u5c0e\u5165\u81f3\u65b0\u7684\u6578\u64da\u5eab��\u4e26\u5c07\u5176\u8a2d\u70ba\u9ed8\u8a8d��
    \u78ba\u5b9a\u8981\u57f7\u884c\u55ce�� +admin.setting.recDiyPathErr=\u4f7f\u7528\u81ea\u884c\u5099\u4efd\u6062\u5fa9\u6642��\u8acb\u9078\u64c7\u5099\u4efd\u7684\u6578\u64da\u5eab\u6587\u4ef6 +admin.setting.recDiyFileNull=\u6578\u64da\u5eab\u6587\u4ef6\u70ba\u7a7a +admin.setting.recDiyPhpErr=\u81ea\u884c\u5099\u4efd\u7684SQLite��\u8acb\u9078\u64c7\u683c\u5f0f\u70baphp\u7684\u6578\u64da\u5eab\u6587\u4ef6 +admin.setting.recDiySqlErr=\u81ea\u884c\u5099\u4efd\u7684MySQL��\u8acb\u9078\u64c7\u683c\u5f0f\u70basql\u7684\u6578\u64da\u5eab\u6587\u4ef6 +admin.setting.recSysPathErr=\u4f7f\u7528\u5099\u4efd\u7ba1\u7406\u6062\u5fa9\u6642��\u8acb\u9078\u64c7\u5099\u4efd\u7684\u6578\u64da\u5eab\u76ee\u9304 +admin.setting.recSysTbErr=\u6578\u64da\u5eab\u5099\u4efd\u76ee\u9304\u7121\u6548��\u6216\u6578\u64da\u5eab\u7d50\u69cb\u6587\u4ef6\u7f3a\u5931 +admin.setting.recDbFileErr=\u9078\u64c7\u7684\u5eab\u6587\u4ef6\u8207\u7cfb\u7d71\u4e0d\u5339\u914d��\u6216\u7f3a\u5c11\u6709\u6548\u7684\u6578\u64da\u8868 +admin.setting.dbFileDown=\u8b80\u53d6\u5eab\u6587\u4ef6 +admin.setting.dbFileDownErr=\u8b80\u53d6\u5eab\u6587\u4ef6\u5931\u6557 +admin.notice.waiting=\u7b49\u5f85\u63a8\u9001 +admin.notice.done=\u5df2\u63a8\u9001 +admin.notice.time=\u63a8\u9001\u6642\u9593 +admin.notice.target=\u63a8\u9001\u5c0d\u8c61 +admin.notice.level=\u63d0\u793a\u7d1a\u5225 +admin.notice.level0=\u5f31\u63d0\u793a +admin.notice.level1=\u5f37\u63d0\u793a +admin.notice.levelDesc=\u5f31\u63d0\u793a��\u5de6\u4e0b\u89d2\u901a\u77e5\u6b04\u986f\u793a\u7d05\u9ede��\u5f37\u63d0\u793a��\u7528\u6236\u767b\u9304\u5f8c\u76f4\u63a5\u5f48\u51fa\u901a\u77e5�� +admin.notice.targetAuth=\u9078\u64c7\u63a8\u9001\u7d66\u6240\u6709\u4eba��\u6216\u63a8\u9001\u7d66\u6307\u5b9a\u7528\u6236��\u7528\u6236\u7d44��\u6b0a\u9650\u7d44 +admin.notice.title=\u6d88\u606f\u6a19\u984c +admin.notice.content=\u6d88\u606f\u5167\u5bb9 +admin.notice.timeType=\u63a8\u9001\u65b9\u5f0f +admin.notice.timeNow=\u7acb\u5373\u63a8\u9001 +admin.notice.timePlan=\u8a08\u5283\u63a8\u9001 +admin.notice.listTitle=\u7ad9\u5167\u6d88\u606f\u901a\u77e5 +admin.notice.clearAll=\u6e05\u7a7a\u5168\u90e8 +admin.notice.noMsg=\u66ab\u7121\u6d88\u606f +admin.notice.ifClearAll=\u78ba\u5b9a\u8981\u6e05\u7a7a\u5168\u90e8\u6d88\u606f\u55ce�� +admin.group.role=\u89d2\u8272\u8eab\u4efd +admin.group.name=\u90e8\u9580\u540d\u7a31 +admin.group.parent=\u4e0a\u7d1a\u90e8\u9580 +admin.group.authShow=\u8a72\u90e8\u9580\u6210\u54e1\u53ef\u898b\u7684\u7d44\u7e54\u67b6\u69cb\u7bc4\u570d +admin.group.authShowAll=\u6240\u6709\u90e8\u9580 +admin.group.authShowHide=\u50c5\u672c\u90e8\u9580\u53ca\u5b50\u90e8\u9580 +admin.group.authShowSelect=\u6307\u5b9a\u90e8\u9580 +admin.group.authShowAllTips=\u8a72\u90e8\u9580\u6210\u54e1\u5354\u4f5c\u5206\u4eab\u6642\u53ef\u4ee5\u9078\u64c7\u5176\u4ed6\u6240\u6709\u90e8\u9580(\u53ca\u7528\u6236) +admin.group.authShowHideTips=\u8a72\u90e8\u9580\u6210\u54e1\u5354\u4f5c\u5206\u4eab\u6642\u50c5\u652f\u6301\u9078\u64c7\u7576\u524d\u90e8\u9580\u53ca\u5b50\u90e8\u9580(\u53ca\u7528\u6236) +admin.group.authShowSelectTips=\u8a72\u90e8\u9580\u6210\u54e1\u5354\u4f5c\u5206\u4eab\u6642\u53ef\u4ee5\u9078\u64c7\u6307\u5b9a\u7684\u90e8\u9580\u53ca\u5b50\u90e8\u9580(\u53ca\u7528\u6236)\u5305\u542b\u7576\u524d\u90e8\u9580\u53ca\u5b50\u90e8\u9580 +admin.group.addSub=\u6dfb\u52a0\u5b50\u90e8\u9580 +admin.group.remove=\u522a\u9664\u90e8\u9580 +admin.group.switch=\u9077\u79fb\u90e8\u9580 +admin.group.swtichDesc=\u5c07\u6240\u9078\u90e8\u9580��\u53ca\u5176\u5b50\u90e8\u9580��\u4e0b\u7684\u7528\u6236\u548c\u6587\u4ef6��\u9077\u79fb\u81f3\u76ee\u6a19\u90e8\u9580�� +admin.group.switchSameError=\u76ee\u6a19\u90e8\u9580\u4e0d\u80fd\u8207\u5df2\u9078\u90e8\u9580\u76f8\u540c +admin.group.switching=\u6b63\u5728\u9077\u79fb��\u8acb\u7a0d\u5019... +admin.group.groupSwitching=\u6240\u9078\u90e8\u9580\u6b63\u5728\u9077\u79fb\u4e2d +admin.group.parentNullError=\u4e0a\u7d1a\u90e8\u9580\u4e0d\u80fd\u70ba\u7a7a +admin.group.selected=\u5df2\u9078\u90e8\u9580 +admin.group.setSizeBatch=\u6279\u91cf\u8a2d\u7f6e\u7a7a\u9593\u5927\u5c0f +admin.group.multiSelect=\u53ef\u9078\u64c7\u591a\u500b\u90e8\u9580\u9032\u884c\u6279\u91cf\u8a2d\u7f6e +admin.group.ifDisAll=\u6240\u6709\u5b50\u90e8\u9580\u90fd\u5c07\u88ab\u7981\u7528��\u78ba\u5b9a\u8981\u57f7\u884c\u55ce�� +admin.member.manage=\u7528\u6236\u8207\u90e8\u9580 +admin.member.add=\u65b0\u5efa\u7528\u6236 +admin.member.role=\u89d2\u8272\u6b0a\u9650 +admin.member.group=\u6240\u5728\u90e8\u9580 +admin.member.groupAdd=\u6dfb\u52a0\u90e8\u9580 +admin.member.groupEdit=\u7de8\u8f2f\u90e8\u9580 +admin.member.remove=\u522a\u9664\u7528\u6236 +admin.member.import=\u6279\u91cf\u6dfb\u52a0 +admin.member.enable=\u555f\u7528 +admin.member.batchSet=\u6279\u91cf\u64cd\u4f5c +admin.member.groupRemove=\u5f9e\u90e8\u9580\u79fb\u9664 +admin.member.groupInsert=\u6dfb\u52a0\u5230\u90e8\u9580 +admin.member.groupSwitch=\u9077\u79fb\u5230\u90e8\u9580 +admin.member.groupTarget=\u76ee\u6a19\u90e8\u9580 +admin.member.groupReset=\u91cd\u7f6e\u90e8\u9580 +admin.member.groupSwtichDesc=\u5c07\u6240\u9078\u7528\u6236\u5f9e\u7576\u524d\u6240\u5728\u90e8\u9580\u9077\u79fb\u81f3\u76ee\u6a19\u90e8\u9580 +admin.member.roleSet=\u89d2\u8272\u6b0a\u9650\u8a2d\u7f6e +admin.member.sizeSet=\u7a7a\u9593\u5927\u5c0f\u8a2d\u7f6e +admin.member.name=\u767b\u9304\u8cec\u865f +admin.member.nickName=\u7528\u6236\u66b1\u7a31 +admin.member.userInfo=\u7528\u6236\u4fe1\u606f +admin.member.userImport=\u6279\u91cf\u5c0e\u5165\u7528\u6236 +admin.member.uploadFirst=\u8acb\u5148\u4e0a\u50b3\u6587\u4ef6 +admin.member.downTpl=\u4e0b\u8f09\u6a21\u677f +admin.member.downTplDesc=��\u8acb\u6309\u7167\u6a21\u677f\u683c\u5f0f\u586b\u5beb\u5f8c\u4e0a\u50b3�� +admin.member.uploadInvalid=\u4e0a\u50b3\u6587\u4ef6\u4e2d\u7121\u6709\u6548\u6578\u64da��\u8acb\u6aa2\u67e5\u5f8c\u91cd\u65b0\u4e0a\u50b3 +admin.member.uploadDataInvalid=\u4e0a\u50b3\u6578\u64da\u7121\u6548\u6216\u5df2\u904e\u671f��\u8acb\u91cd\u65b0\u4e0a\u50b3 +admin.member.importSuccess=\u5c0e\u5165\u5b8c\u6210 +admin.member.importFail=\u5c0e\u5165\u5931\u6557 +admin.member.importFailDesc=\u6210\u529f:{0}\u5931\u6557:{1} +admin.member.importName=\u767b\u9304\u8cec\u865f(\u5fc5\u586b��\u552f\u4e00) +admin.member.importNickName=\u66b1\u7a31(\u552f\u4e00) +admin.member.importPwd=\u5bc6\u78bc(\u5fc5\u586b) +admin.member.importSex=\u6027\u5225(\u7537-1\u5973-0) +admin.member.importPhone=\u624b\u6a5f\u865f(\u552f\u4e00) +admin.member.importEmail=\u90f5\u7bb1(\u552f\u4e00) +admin.member.groupRemoveTips=\u522a\u9664\u5f8c\u8a72\u7528\u6236\u7d44\u7528\u6236\u7121\u6cd5\u767b\u9304
    (\u9700\u8981\u91cd\u65b0\u8a2d\u7f6e\u7528\u6236\u7d44)��\u78ba\u5b9a\u8981\u7e7c\u7e8c\u55ce�� +admin.member.memberRemoveTips=\u522a\u9664\u5f8c��\u7528\u6236\u76ee\u9304\u5c07\u79fb\u81f3\u7cfb\u7d71\u56de\u6536\u7ad9��
    \u78ba\u5b9a\u8981\u7e7c\u7e8c\u55ce�� +admin.member.selectUserTips=\u8acb\u9078\u64c7\u8981\u64cd\u4f5c\u7684\u8cec\u865f +admin.member.ifRemoveGroup=\u78ba\u5b9a\u5c07\u6240\u9078\u7528\u6236\u5f9e\u8a72\u7d44\u79fb\u9664�� +admin.member.importDesc=\u6bcf\u884c\u4e00\u500b\u7528\u6236
    \u5df2\u5b58\u5728\u5247\u81ea\u52d5\u5ffd\u7565 +admin.member.roleAdminTips=\u5099\u8a3b��\u7cfb\u7d71\u7ba1\u7406\u54e1\u4e0d\u53d7\u6b0a\u9650\u63a7\u5236 +admin.member.space=\u8a2d\u7f6e\u7528\u6236\u7a7a\u9593\u5927\u5c0f +admin.member.spaceTips=0\u5247\u4e0d\u9650\u5236 +admin.member.spaceTipsDefault=(GB)0\u5247\u4e0d\u9650\u5236 +admin.member.spaceTipsFull=\u4e0d\u9650\u5236 +admin.member.spaceSize=\u7a7a\u9593\u5927\u5c0f +admin.member.spaceSizeUse=\u7a7a\u9593\u4f7f\u7528 +admin.member.memberAdd=\u6dfb\u52a0\u7528\u6236 +admin.member.allAdd=\u6dfb\u52a0\u7528\u6236\u6216\u90e8\u9580 +admin.member.nullNotUpdate=\u4e0d\u586b\u5247\u4e0d\u4fee\u6539 +admin.member.search=\u641c\u7d22\u7528\u6236(\u8cec\u865f/\u66b1\u7a31/\u90f5\u7bb1/\u96fb\u8a71) +admin.member.searchUser=\u641c\u7d22\u7528\u6236(\u652f\u6301\u62fc\u97f3\u53ca\u6a21\u7cca\u5339\u914d) +admin.member.searchGroup=\u641c\u7d22\u90e8\u9580(\u652f\u6301\u62fc\u97f3\u53ca\u6a21\u7cca\u5339\u914d) +admin.member.searchAll=\u641c\u7d22\u7528\u6236\u6216\u90e8\u9580(\u652f\u6301\u62fc\u97f3\u53ca\u6a21\u7cca\u5339\u914d) +admin.member.editNoAuth=\u62b1\u6b49\u60a8\u6c92\u6709\u8a72\u6b0a\u9650
    \u53ea\u6709\u7cfb\u7d71\u7ba1\u7406\u54e1\u624d\u80fd\u6dfb\u52a0\u4fee\u6539\u7cfb\u7d71\u7ba1\u7406\u54e1 +admin.member.disabledUsers=\u5df2\u7981\u7528\u8cec\u865f +admin.member.disabledTips=\u5207\u63db\u90e8\u9580\u4ee5\u53d6\u6d88\u9078\u4e2d +admin.member.userGroup=\u7528\u6236\u90e8\u9580 +admin.member.userRole=\u7528\u6236\u89d2\u8272 +admin.member.userSelected=\u5df2\u9078\u7528\u6236 +admin.member.authCopy=\u90e8\u9580\u6b0a\u9650\u8907\u88fd +admin.member.authPaste=\u90e8\u9580\u6b0a\u9650\u7c98\u8cbc +admin.member.ifAuthPaste=\u78ba\u5b9a\u8981\u5c07\u5df2\u5fa9\u5236\u7684\u90e8\u9580\u6b0a\u9650��\u8a2d\u7f6e\u7d66\u7576\u524d\u7528\u6236\u55ce�� +ERROR_USER_NOT_EXISTS=\u7528\u6236\u4e0d\u5b58\u5728 +ERROR_USER_PASSWORD_ERROR=\u5bc6\u78bc\u932f\u8aa4 +ERROR_USER_EXIST_NAME=\u7528\u6236\u540d\u5df2\u5b58\u5728 +ERROR_USER_EXIST_PHONE=\u624b\u6a5f\u865f\u5df2\u5b58\u5728 +ERROR_USER_EXIST_EMAIL=\u8a72\u90f5\u7bb1\u5df2\u5b58\u5728 +ERROR_USER_EXIST_NICKNAME=\u66b1\u7a31\u5df2\u5b58\u5728 +ERROR_USER_LOGIN_LOCK=\u62b1\u6b49\u5bc6\u78bc\u5617\u8a66\u8f38\u5165\u932f\u8aa4\u904e\u591a\u7576\u524d\u8cec\u865f\u5df2\u9396\u5b9a\u8acb1\u5206\u9418\u5f8c\u518d\u8a66! +ERROR_IP_NOT_ALLOW=\u60a8\u7576\u524dIP\u6216\u8a2a\u554f\u8a2d\u5099\u4e0d\u5141\u8a31\u767b\u9304\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1! +user.passwordCheckError=\u5bc6\u78bc\u683c\u5f0f\u4e0d\u7b26\u5408\u5bc6\u78bc\u5f37\u5ea6\u898f\u5247! +admin.role.administrator=\u7cfb\u7d71\u7ba1\u7406\u54e1 +admin.role.group=\u90e8\u9580\u7ba1\u7406\u54e1 +admin.role.default=\u666e\u901a\u7528\u6236 +admin.role.ignoreExt=\u64f4\u5c55\u540d\u9650\u5236 +admin.role.ignoreExtDesc=\u4e0d\u5141\u8a31\u4e0a\u50b3\u7684\u6587\u4ef6\u985e\u578b\u70ba\u7a7a\u5247\u4e0d\u9650\u5236 +admin.role.ignoreFileSize=\u4e0a\u50b3\u6587\u4ef6\u5927\u5c0f\u9650\u5236 +admin.role.ignoreFileSizeDesc=\u5141\u8a31\u55ae\u500b\u6587\u4ef6\u4e0a\u50b3\u6700\u5927\u503c0\u5247\u4e0d\u9650\u5236 +admin.role.ignoreExtTips=\u62b1\u6b49\u7576\u524d\u7cfb\u7d71\u8a2d\u7f6e\u4e0d\u652f\u6301\u8a72\u985e\u578b\u6587\u4ef6\u4e0a\u50b3;\u5177\u9ad4\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1! +admin.role.ignoreFileSizeTips=\u62b1\u6b49\u7576\u6587\u4ef6\u8d85\u51fa\u5927\u5c0f\u9650\u5236;\u5177\u9ad4\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1! +admin.role.desc=\u89d2\u8272\u63cf\u8ff0 +admin.role.adminDesc=\u8d85\u7d1a\u7ba1\u7406\u54e1\u64c1\u6709\u670d\u52d9\u5668\u7ba1\u7406\u6b0a\u9650;\u6240\u6709\u6587\u4ef6\u6587\u4ef6\u593e\u8a2d\u7f6e\u6b0a\u9650\u5c0d\u8a72\u7528\u6236\u7121\u6548! +admin.role.read=\u8b80\u53d6 +admin.role.readList=\u6587\u4ef6\u5217\u8868 +admin.role.readInfo=\u6587\u4ef6(\u593e)\u5c6c\u6027\u67e5\u770b\u6587\u4ef6\u593e\u641c\u7d22 +admin.role.readCopy=\u6587\u4ef6\u8907\u88fd +admin.role.readPreview=\u6587\u4ef6\u9810\u89bd(\u5716\u7247\u6587\u6a94\u97f3\u8996\u983b\u7b49) +admin.role.readDownload=\u6587\u4ef6(\u593e)\u4e0b\u8f09 +admin.role.write=\u5beb\u5165 +admin.role.writeAdd=\u5275\u5efa\u6587\u4ef6(\u593e)\u58d3\u7e2e\u89e3\u58d3\u6587\u4ef6 +admin.role.writeChange=\u91cd\u547d\u540d\u8abf\u6574\u76ee\u9304\u7d50\u69cb +admin.role.writeUpload=\u6587\u4ef6(\u593e)\u4e0a\u50b3\u9060\u7a0b\u4e0b\u8f09 +admin.role.writeRemove=\u6587\u4ef6(\u593e)\u522a\u9664\u526a\u5207 +admin.role.adminSetDesc=\u7cfb\u7d71\u7ba1\u7406\u54e1\u64c1\u6709\u6240\u6709\u6b0a\u9650��\u7121\u9700\u8a2d\u7f6e! +admin.role.displayDesc=\u8a2d\u7f6e\u7528\u6236\u89d2\u8272\u6642\u662f\u5426\u986f\u793a +admin.role.defaultRoleDesc=\u63d0\u793a��\u7cfb\u7d71\u9ed8\u8a8d\u5167\u7f6e\u89d2\u8272��\u4e0d\u652f\u6301\u4fee\u6539\u6b0a\u9650��\u60a8\u53ef\u4ee5\u5275\u5efa\u65b0\u7684\u89d2\u8272 +admin.role.actionSetTitle=\u6587\u6a94\u53ca\u914d\u7f6e +admin.role.userSetTitle=\u7528\u6236\u914d\u7f6e\u6578\u64da +admin.role.adminSetTitle=\u5f8c\u53f0\u529f\u80fd +admin.role.fileAdd=\u65b0\u5efa\u6587\u4ef6��\u593e�� +admin.role.fileRemove=\u6587\u6a94\u522a\u9664 +admin.role.fileMove=\u79fb\u52d5��\u8907\u88fd/\u526a\u5207/\u7c98\u8cbc/\u62d6\u62fd\u64cd\u4f5c�� +admin.role.userConfig=\u914d\u7f6e\u4fee\u6539��\u8a2d\u7f6e\u982d\u50cf/\u4fee\u6539\u5bc6\u78bc\u7b49�� +admin.role.userEdit=\u7de8\u8f2f\u7528\u6236��\u6dfb\u52a0/\u4fee\u6539/\u522a\u9664�� +admin.role.userFav=\u6536\u85cf\u593e\u64cd\u4f5c +admin.role.itemEdit=\u6dfb\u52a0/\u4fee\u6539/\u522a\u9664 +admin.role.groupEdit=\u7de8\u8f2f\u90e8\u9580��\u6dfb\u52a0/\u4fee\u6539/\u522a\u9664�� +admin.role.delErrTips=\u8a72\u89d2\u8272\u6b63\u5728\u88ab\u4f7f\u7528��\u7121\u6cd5\u522a\u9664�� +admin.authFrom.setUser=\u6307\u5b9a\u81ea\u5df1\u6b0a\u9650 +admin.authFrom.setGroup=\u6307\u5b9a\u90e8\u9580\u6b0a\u9650 +admin.authFrom.setAll=\u5176\u4ed6\u7528\u6236\u6b0a\u9650 +admin.authFrom.groupAt=\u6240\u5728\u90e8\u9580\u6b0a\u9650 +admin.authFrom.groupParent=\u4e0a\u5c64\u90e8\u9580\u6b0a\u9650 +admin.authFrom.pathOnly=\u50c5\u901a\u8def\u4e0b\u5c64\u6709\u5167\u5bb9\u6709\u6b0a\u9650 +admin.authFrom.groupRoot=\u90e8\u9580\u6839\u76ee\u9304 +admin.auth.owner=\u64c1\u6709\u8005 +admin.auth.editor=\u7de8\u8f2f\u8005 +admin.auth.editUploader=\u7de8\u8f2f/\u4e0a\u50b3\u8005 +admin.auth.viewer=\u67e5\u770b\u8005 +admin.auth.previewer=\u9810\u89bd\u8005 +admin.auth.uploader=\u4e0a\u50b3\u8005 +admin.auth.invisible=\u4e0d\u53ef\u898b +admin.auth.user=\u7528\u6236\u6578\u64da +admin.auth.pathDelete=\u6587\u4ef6\u522a\u9664 +admin.auth.pathInfo=\u6587\u4ef6\u5c6c\u6027 +admin.auth.pathMove=\u79fb\u52d5(\u8907\u88fd/\u526a\u5207/\u7c98\u8cbc/\u62d6\u62fd\u64cd\u4f5c) +admin.auth.canUpload=\u4e0a\u50b3\u4e0b\u8f09 +admin.auth.config=\u914d\u7f6e\u6578\u64da +admin.auth.fav=\u6536\u85cf\u593e\u64cd\u4f5c(\u6dfb\u52a0/\u7de8\u8f2f/\u522a\u9664) +admin.auth.extWarning=\u4e0d\u5141\u8a31\u6b64\u985e\u6587\u4ef6\u7684\u4e0a\u50b3
    \u91cd\u547d\u540d(\u91cd\u547d\u540d\u70ba\u6307\u5b9a\u64f4\u5c55\u540d)
    \u7de8\u8f2f\u4fdd\u5b58\u9060\u7a0b\u4e0b\u8f09\u89e3\u58d3 +admin.auth.error=\u89d2\u8272\u6b0a\u9650\u932f\u8aa4(\u6c92\u6709\u6b0a\u9650\u8a2d\u7f6e) +admin.auth.errorAdmin=\u6b0a\u9650\u4e0d\u8db3 +admin.auth.targetError=\u6b0a\u9650\u5c0d\u50cf\u985e\u578b\u932f\u8aa4��\u5fc5\u9808\u70ba\u7528\u6236\u6216\u90e8\u9580 +admin.auth.errorAuthToGroup=\u975e\u6839\u90e8\u9580��\u4e0d\u652f\u6301\u6388\u6b0a\u7d66\u90e8\u9580 +admin.auth.errorAuthToUsers=\u975e\u6839\u90e8\u9580��\u4e0d\u652f\u6301\u6388\u6b0a\u7d66\u8a72\u90e8\u9580\u5916\u7684\u6210\u54e1 +admin.auth.displayDesc=\u8a2d\u7f6e\u90e8\u9580\u7528\u6236\u6b0a\u9650\u6642\u662f\u5426\u986f\u793a +admin.auth.defaultAuthDesc=\u63d0\u793a��\u7cfb\u7d71\u9ed8\u8a8d\u5167\u7f6e\u6b0a\u9650\u7d44��\u4e0d\u652f\u6301\u4fee\u6539\u6b0a\u9650��\u60a8\u53ef\u4ee5\u5275\u5efa\u65b0\u7684\u6b0a\u9650\u7d44 +admin.auth.show=\u6587\u4ef6\u5217\u8868 +admin.auth.showAction=\u6587\u4ef6\u5217\u8868\u67e5\u770b +admin.auth.view=\u6587\u4ef6\u9810\u89bd +admin.auth.viewAction=\u6587\u4ef6\u6253\u958b\u9810\u89bd +admin.auth.download=\u4e0b\u8f09/\u8907\u88fd +admin.auth.downloadAction=\u4e0b\u8f09/\u8907\u88fd/\u6587\u4ef6\u9810\u89bd\u6253\u5370 +admin.auth.uploadAction=\u6587\u4ef6(\u593e)\u4e0a\u50b3/\u9060\u7a0b\u4e0b\u8f09 +admin.auth.edit=\u7de8\u8f2f\u65b0\u5efa +admin.auth.editAction=\u65b0\u5efa\u6587\u4ef6(\u593e)/\u91cd\u547d\u540d/\u7c98\u8cbc\u5230\u6587\u4ef6\u593e/\u7de8\u8f2f\u6587\u4ef6/\u8a2d\u7f6e\u5099\u8a3b/\u5275\u5efa\u526f\u672c/\u89e3��\u58d3\u7e2e +admin.auth.removeAction=\u526a\u5207/\u8907\u88fd/\u79fb\u52d5 +admin.auth.shareAction=\u5916\u93c8\u5206\u4eab/\u8207\u4ed6\u4eba\u5354\u4f5c\u5206\u4eab +admin.auth.comment=\u6587\u6a94\u8a55\u8ad6 +admin.auth.commentAction=\u6587\u6a94\u8a55\u8ad6\u67e5\u770b��\u6dfb\u52a0/\u522a\u9664\u81ea\u5df1\u7684\u8a55\u8ad6(\u9700\u7de8\u8f2f\u6b0a\u9650) +admin.auth.event=\u6587\u6a94\u52d5\u614b +admin.auth.eventAction=\u6587\u6a94\u52d5\u614b\u67e5\u770b��\u8a02\u95b1\u52d5\u614b +admin.auth.root=\u7ba1\u7406\u6b0a\u9650 +admin.auth.rootAction=\u8a2d\u7f6e\u6210\u54e1\u6b0a\u9650/\u8a55\u8ad6\u7ba1\u7406/\u6b77\u53f2\u7248\u672c\u7ba1\u7406 +admin.auth.delErrTips=\u8a72\u6b0a\u9650\u6b63\u5728\u88ab\u4f7f\u7528��\u7121\u6cd5\u522a\u9664�� +admin.plugin.center=\u63d2\u4ef6\u4e2d\u5fc3 +admin.plugin.installed=\u5df2\u5b89\u88dd +admin.plugin.type=\u5206\u985e +admin.plugin.typeFile=\u6587\u4ef6\u589e\u5f37 +admin.plugin.typeSafe=\u5b89\u5168\u5de5\u5177 +admin.plugin.typeTools=\u5be6\u7528\u5de5\u5177 +admin.plugin.typeMedia=\u591a\u5a92\u9ad4 +admin.plugin.typeCompany=\u4f01\u696d\u61c9\u7528 +admin.plugin.typeOem=\u5c08\u5c6c\u5b9a\u5236 +admin.plugin.needNetwork=\u9700\u806f\u5916\u7db2 +admin.plugin.install=\u5b89\u88dd\u63d2\u4ef6 +admin.plugin.enable=\u555f\u7528\u63d2\u4ef6 +admin.plugin.remove=\u5378\u8f09\u63d2\u4ef6 +admin.plugin.config=\u914d\u7f6e\u63d2\u4ef6 +admin.plugin.statusEnabled=\u5df2\u555f\u7528 +admin.plugin.statusDisabled=\u672a\u555f\u7528 +admin.plugin.statusNotInstall=\u672a\u5b89\u88dd +admin.plugin.installing=\u5b89\u88dd\u4e2d... +admin.plugin.hasUpdate=\u6709\u66f4\u65b0 +admin.plugin.updateStart=\u66f4\u65b0\u63d2\u4ef6 +admin.plugin.needConfig=\u9700\u8981\u521d\u59cb\u5316\u914d\u7f6e\u624d\u80fd\u555f\u7528 +admin.plugin.notNull=\u5fc5\u586b\u9805\u4e0d\u80fd\u70ba\u7a7a! +admin.plugin.auther=\u4f5c\u8005 +admin.plugin.downloadNumber=\u5b89\u88dd\u6b21\u6578 +admin.plugin.back=\u8fd4\u56de +admin.plugin.detail=\u63cf\u8ff0 +admin.plugin.resetConfig=\u6062\u5fa9\u9ed8\u8a8d\u8a2d\u7f6e +admin.plugin.installSelf=\u624b\u52d5\u5b89\u88dd +admin.plugin.updateSelf=\u624b\u52d5\u66f4\u65b0 +admin.plugin.updateAll=\u66f4\u65b0\u6240\u6709 +admin.plugin.installSelfDesc=
    \u9069\u7528\u60c5\u6cc1:
  • 1.\u670d\u52d9\u5668\u4e0d\u652f\u6301\u9023\u63a5\u5916\u7db2.
  • 2.\u865b\u64ec\u4e3b\u6a5f\u5546\u7981\u7528\u4e86\u76f8\u95dc\u529f\u80fd\u6642(\u7db2\u7d61\u8acb\u6c42https\u9a57\u8b49).

  • \u5b89\u88dd:\u4e0b\u8f09\u5f8c\u4e0a\u50b3\u89e3\u58d3\u5230plugins\u76ee\u9304(\u9700\u8981\u4fdd\u7559\u63d2\u4ef6\u540d\u7684\u6587\u4ef6\u593e\u4e0d\u80fd\u4fee\u6539\u63d2\u4ef6\u540d);\u63d2\u4ef6\u4e2d\u5fc3\u555f\u7528\u5373\u53ef
  • \u66f4\u65b0:\u4e0b\u8f09\u5f8c\u4e0a\u50b3\u89e3\u58d3\u8986\u84cb\u5230\u5230\u5c0d\u61c9\u63d2\u4ef6\u540d\u6587\u4ef6\u593e;
  • +admin.plugin.installNetworkError=\u7db2\u7d61\u932f\u8aa4��\u8acb\u6aa2\u67e5\u670d\u52d9\u5668\u80fd\u5426\u8a2a\u554f\u5916\u7db2�� +admin.plugin.auth=\u4f7f\u7528\u6b0a\u9650 +admin.plugin.authDesc=\u8a2d\u7f6e\u6240\u6709\u4eba\u53ef\u7528��\u6216\u8005\u6307\u5b9a\u7528\u6236��\u7528\u6236\u7d44��\u6b0a\u9650\u7d44\u53ef\u4ee5\u4f7f\u7528 +admin.plugin.authOpen=\u958b\u653e\u8a2a\u554f +admin.plugin.authOpenDesc=\u7121\u9700\u767b\u9304\u7686\u53ef\u8a2a\u554f\u53ef\u7528\u65bc\u5c0d\u5916\u63a5\u53e3\u8abf\u7528 +admin.plugin.authAll=\u6240\u6709\u4eba +admin.plugin.authUser=\u6307\u5b9a\u7528\u6236 +admin.plugin.authGroup=\u6307\u5b9a\u90e8\u9580 +admin.plugin.authRole=\u6307\u5b9a\u6b0a\u9650\u7d44 +admin.plugin.openWith=\u6253\u958b\u6a23\u5f0f +admin.plugin.openWithDilog=\u5167\u90e8\u5c0d\u8a71\u6846 +admin.plugin.openWithWindow=\u65b0\u9801\u9762\u6253\u958b +admin.plugin.fileSort=\u64f4\u5c55\u540d\u95dc\u806f\u512a\u5148\u7d1a +admin.plugin.fileSortDesc=\u8d8a\u5927\u64f4\u5c55\u540d\u6253\u958b\u512a\u5148\u7d1a\u8d8a\u9ad8 +admin.plugin.fileExt=\u652f\u6301\u7684\u6587\u4ef6\u683c\u5f0f +admin.plugin.fileExtDesc=\u95dc\u806f\u64f4\u5c55\u540d\u5230\u8a72\u63d2\u4ef6 +admin.plugin.tabServer=\u670d\u52d9\u5668\u914d\u7f6e +admin.plugin.defaultAceEditor=Ace\u7de8\u8f2f\u5668 +admin.plugin.defaultHtmlView=\u7db2\u9801\u9810\u89bd +admin.plugin.defaultZipView=\u5728\u7dda\u89e3\u58d3\u7e2e +admin.plugin.authViewList=\u63d2\u4ef6\u5217\u8868 +admin.plugin.authStatus=\u958b\u555f\u95dc\u9589 +admin.plugin.authInstall=\u5b89\u88dd/\u5378\u8f09 +admin.plugin.disabled=\u63d2\u4ef6\u4e0d\u5b58\u5728\u6216\u5c1a\u672a\u958b\u555f +admin.plugin.menuAdd=\u662f\u5426\u6dfb\u52a0\u5230\u4e3b\u83dc\u55ae +admin.plugin.menuAddDesc=\u4f5c\u70ba\u55ae\u7368\u61c9\u7528\u4f7f\u7528 +admin.plugin.menuSubMenuDesc=\u6536\u7e2e\u5728[\u66f4\u591a]\u83dc\u55ae\u4e2d +admin.storage.type=\u5b58\u5132\u985e\u578b +admin.storage.local=\u672c\u5730 +admin.storage.localStore=\u672c\u5730\u5b58\u5132 +admin.storage.oss=\u963f\u91cc\u96f2OSS +admin.storage.cos=\u9a30\u8a0a\u96f2COS +admin.storage.qiniu=\u4e03\u725b\u96f2 +admin.storage.s3=\u4e9e\u99ac\u905cS3 +admin.storage.ftp=FTP +admin.storage.oos=\u5929\u7ffc\u96f2OOS +admin.storage.moss=\u5b8f\u6749MOSS +admin.storage.eos=XSKYEOS +admin.storage.nos=\u524d\u4e91NOS +admin.storage.minio=MinIO +admin.storage.uss=\u53c8\u62cd\u96f2USS +admin.storage.eds=\u6df1\u4fe1\u670dEDS +admin.storage.driver=\u672c\u5730\u78c1\u76e4 +admin.storage.useage=\u7a7a\u9593\u4f7f\u7528\u60c5\u6cc1 +admin.storage.default=\u8a2d\u70ba\u9ed8\u8a8d +admin.storage.current=\u7576\u524d\u9ed8\u8a8d +admin.storage.edit=\u914d\u7f6e\u5b58\u5132 +admin.storage.setConfig=\u4fee\u6539\u914d\u7f6e +admin.storage.moveData=\u9077\u79fb\u6578\u64da +admin.storage.delStore=\u5378\u8f09\u5b58\u5132 +admin.storage.ifMove=\u8a72\u5b58\u5132\u4e2d\u5305\u542b{0}\u500b\u7db2\u76e4\u6587\u4ef6��\u5c07\u88ab\u9077\u79fb\u81f3\u7576\u524d\u9ed8\u8a8d\u5b58\u5132��\u662f\u5426\u7e7c\u7e8c�� +admin.storage.ifDel=\u78ba\u5b9a\u8981\u5378\u8f09\u7576\u524d\u5b58\u5132\u55ce�� +admin.storage.ifDelWithFile=\u8a72\u5b58\u5132\u4e2d\u5305\u542b{0}\u500b\u7db2\u76e4\u6587\u4ef6��\u522a\u9664\u6642\u5c07\u88ab\u9077\u79fb\u81f3\u7576\u524d\u9ed8\u8a8d\u5b58\u5132��\u662f\u5426\u7e7c\u7e8c�� +admin.storage.sysFile=\u7db2\u76e4\u6587\u4ef6��\u500b\u4eba\u7a7a\u9593\u548c\u90e8\u9580\u4e0b\u7684\u6587\u4ef6 +admin.storage.delErrTips=\u6210\u529f:%s;\u5931\u6557:%s��\u8acb\u91cd\u8a66\u6216\u624b\u52d5\u9077\u79fb +admin.storage.delLocTips=\u8acb\u81f3\u5c11\u4fdd\u7559\u4e00\u500b\u672c\u5730\u5b58\u5132 +admin.storage.delStoreTips=\u8a72\u5b58\u5132\u4e2d\u5305\u542b\u5099\u4efd\u6578\u64da��\u8acb\u8655\u7406\u5f8c\u518d\u9032\u884c\u64cd\u4f5c�� +admin.storage.nameDesc=\u5b58\u5132\u540d\u7a31��\u7528\u65bc\u5340\u5206\u4e0d\u540c\u5b58\u5132 +admin.storage.path=\u5b58\u5132\u76ee\u9304 +admin.storage.pathLocDesc=\u6587\u4ef6\u5b58\u5132\u76ee\u9304��\u8acb\u78ba\u4fdd\u6240\u586b\u5beb\u76ee\u9304\u5177\u6709\u8b80\u5beb\u6b0a\u9650 +admin.storage.pathDesc=\u6587\u4ef6\u5b58\u5132\u76ee\u9304 +admin.storage.defaultDesc=\u9ed8\u8a8d\u9805\u70ba\u552f\u4e00\u6709\u6548\u7684\u7cfb\u7d71\u5b58\u5132��\u5982\u9078\u64c7\u958b\u555f��\u5c07\u81ea\u52d5\u53d6\u6d88\u5176\u5b83\u9ed8\u8a8d\u5b58\u5132\u65b9\u5f0f��\u8acb\u8b39\u614e\u64cd\u4f5c�� +admin.storage.forceEdit=\u5f37\u5236\u4fee\u6539 +admin.storage.editTips=\u958b\u555f\u5f8c��\u53ef\u5c0d\u7981\u6b62\u4fee\u6539\u5b57\u6bb5\u9032\u884c\u7de8\u8f2f��\u53ef\u80fd\u5c0e\u81f4\u8a72\u5b58\u5132\u4e4b\u524d\u7684\u6587\u4ef6\u7121\u6cd5\u8a2a\u554f��\u8acb\u8b39\u614e\u64cd\u4f5c�� +admin.storage.folderTips=\u7576\u524d\u70ba\u7cfb\u7d71\u6587\u4ef6\u5b58\u5132\u4f4d\u7f6e\u8acb\u8b39\u614e\u64cd\u4f5c +admin.storage.sizeTips=\u7a7a\u9593\u5927\u5c0f\u9700\u5927\u65bc0 +admin.storage.sizeDesc=(GB)��\u8acb\u6839\u64da\u6240\u9078\u5b58\u5132\u76ee\u9304\u7684\u5be6\u969b\u53ef\u7528\u7a7a\u9593\u5927\u5c0f\u586b\u5beb +admin.storage.region=\u5b58\u5132\u5340\u57df +admin.storage.domain=\u7a7a\u9593\u57df\u540d +admin.storage.bucket=Bucket\u540d\u7a31 +admin.storage.bucketDesc=\u5275\u5efa\u7a7a\u9593\u6642\u586b\u5beb\u7684Bucket\u540d\u7a31 +admin.storage.userName=\u8cec\u865f\u540d\u7a31 +admin.storage.userPwd=\u8cec\u865f\u5bc6\u78bc +admin.storage.server=\u670d\u52d9\u5668\u5730\u5740 +admin.storage.serverDesc=ftp(s)://ip��\u4e0d\u52a0\u5354\u8b70\u9ed8\u8a8d\u70baftp +admin.storage.refer=\u53c3\u8003�� +admin.storage.endpoint=\u5730\u57df\u7bc0\u9ede +admin.storage.ossDomain=OSS\u7a7a\u9593\u7d81\u5b9a\u7684\u57df\u540d +admin.storage.ossKeyDesc=\u963f\u91cc\u96f2\u8cec\u865f\u7684AccessKeyID��\u8acb\u5728��\u63a7\u5236\u53f0-AccessKey\u7ba1\u7406��\u4e2d\u5275\u5efa\u6216\u67e5\u770b +admin.storage.ossSecretDesc=\u963f\u91cc\u96f2\u8cec\u865f\u7684AccessKeySecret��\u7372\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.ossEndpoint=Endpoint��\u5982\u4f7f\u7528\u5167\u7db2\u7bc0\u9ede��\u9700\u958b\u555f\u670d\u52d9\u5668\u4e2d\u8f49 +admin.storage.cosKeyDesc=\u9a30\u8a0a\u96f2\u8cec\u865f\u7684AccessKeyID��\u8acb\u5728��\u63a7\u5236\u53f0-\u8a2a\u554f\u7ba1\u7406-API\u79d8\u9470\u7ba1\u7406��\u4e2d\u5275\u5efa\u6216\u67e5\u770b +admin.storage.cosSecretDesc=\u9a30\u8a0a\u96f2\u8cec\u865f\u7684AccessKeySecret��\u7372\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.qiniuDomain=\u4e03\u725b\u7a7a\u9593\u7d81\u5b9a\u7684\u57df\u540d +admin.storage.qiniuKeyDesc=\u4e03\u725b\u8cec\u865f\u7684AccessKey��\u8acb\u5728��\u63a7\u5236\u53f0-\u500b\u4eba\u4e2d\u5fc3-\u5bc6\u9470\u7ba1\u7406��\u4e2d\u5275\u5efa\u6216\u67e5\u770b +admin.storage.qiniuSecretDesc=\u4e03\u725b\u8cec\u865f\u7684SecretKey��\u7372\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.qnz0=\u83ef\u6771-\u6d59\u6c5f +admin.storage.qnz02=\u83ef\u6771-\u6d59\u6c5f2 +admin.storage.qnz1=\u83ef\u5317-\u6cb3\u5317 +admin.storage.qnz2=\u83ef\u5357-\u5ee3\u6771 +admin.storage.qnna0=\u5317\u7f8e-\u6d1b\u6749\u78ef +admin.storage.qnas0=\u4e9e\u592a-\u65b0\u52a0\u5761 +admin.storage.qnas02=\u4e9e\u592a-\u9996\u723e +admin.storage.awsDomain=AWS\u7a7a\u9593\u7d81\u5b9a\u7684\u57df\u540d +admin.storage.awsKeyDesc=AWS\u8cec\u865f\u7684AccessKeyID��\u8acb\u5728��\u63a7\u5236\u53f0-\u60a8\u7684\u5b89\u5168\u6191\u8b49��\u4e2d\u5275\u5efa +admin.storage.awsSecretDesc=AWS\u8cec\u865f\u7684AccessKeySecret��\u7372\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.oosDomain=\u5929\u7ffc\u96f2\u7a7a\u9593\u7d81\u5b9a\u7684\u57df\u540d +admin.storage.oosKeyDesc=\u5929\u7ffc\u96f2\u8cec\u865f\u7684AccessKeyID��\u8acb\u5728��\u63a7\u5236\u53f0-\u60a8\u7684\u5b89\u5168\u6191\u8b49��\u4e2d\u5275\u5efa +admin.storage.oosSecretDesc=\u5929\u7ffc\u96f2\u8cec\u865f\u7684AccessKeySecret��\u7372\u53d6\u65b9\u6cd5\u540c\u4e0a +admin.storage.ftpDisabled=FTP\u4e0d\u53ef\u7528��\u8acb\u958b\u555fphp_ftp\u64f4\u5c55 +admin.storage.ifDefaultTips=\u8a72\u64cd\u4f5c\u5c07\u53d6\u6d88\u5176\u5b83\u9ed8\u8a8d\u5b58\u5132\u65b9\u5f0f��\u78ba\u5b9a\u8981\u57f7\u884c\u55ce�� +admin.storage.spaceUsed=\u5be6\u969b\u4f7f\u7528 +admin.storage.spaceLave=\u5269\u9918\u7528\u91cf +admin.storage.delError=\u8a72\u5b58\u5132\u5df2\u6709\u6587\u4ef6\u5b58\u5728��\u4e0d\u53ef\u522a\u9664 +admin.storage.corsError=\u5982\u914d\u7f6e\u7121\u8aa4��\u8acb\u6309��\u4f7f\u7528\u5e6b\u52a9��\u6aa2\u67e5bucket\u8de8\u57df\u8a2d\u7f6e�� +admin.storage.saveError=\u7121\u6cd5\u9023\u63a5\u5230\u6307\u5b9a\u5b58\u5132��\u8acb\u6aa2\u67e5\u914d\u7f6e\u4fe1\u606f\u662f\u5426\u6b63\u78ba�� +admin.storage.ftpCharset=FTP\u670d\u52d9\u5668\u7de8\u78bc +admin.storage.ftpCharsetDesc=\u5982\u679c\u662fFTP\u670d\u52d9\u5668\u70bawindows\u8a72\u8655\u6839\u64da\u60c5\u6cc1\u53ef\u4ee5\u8a2d\u7f6e\u70baGBK; +admin.storage.ftpPasvOn=\u958b\u555f +admin.storage.ftpPasvOff=\u95dc\u9589 +admin.storage.ftpPasv=\u88ab\u52d5\u6a21\u5f0f +admin.storage.ftpPasvDesc=\u6578\u64da\u50b3\u8f38\u6a21\u5f0f +admin.storage.uploadSrv=\u670d\u52d9\u5668\u4e2d\u8f49��\u4e0a\u50b3�� +admin.storage.fileoutSrv=\u670d\u52d9\u5668\u4e2d\u8f49��\u4e0b\u8f09�� +admin.storage.uploadSrvDesc=\u958b\u555f\u5f8c��\u5c07\u901a\u904e\u670d\u52d9\u5668\u4e0a\u50b3\u6587\u4ef6\u81f3\u5c0d\u8c61\u5b58\u5132��\u5426\u5247��\u5c07\u901a\u904e\u5ba2\u6236\u7aef\u76f4\u63a5\u4e0a\u50b3�� +admin.storage.fileoutSrvDesc=\u958b\u555f\u5f8c��\u5c07\u901a\u904e\u670d\u52d9\u5668\u7372\u53d6\u5b58\u5132\u6587\u4ef6\u9032\u884c\u4e0b\u8f09��\u5426\u5247��\u5c07\u7372\u53d6\u6587\u4ef6\u76f4\u93c8\u4e0b\u8f09�� +admin.storage.closeDefError=\u7981\u6b62\u95dc\u9589\u9ed8\u8a8d\u5b58\u5132 +admin.storage.ussBucket=\u670d\u52d9\u540d\u7a31 +admin.storage.ussBucketDesc=\u96f2\u5b58\u5132\u670d\u52d9\u540d\u7a31 +admin.storage.ussUser=\u64cd\u4f5c\u54e1\u540d +admin.storage.ussUserDesc=\u64cd\u4f5c\u54e1\u540d\u7a31 +admin.storage.ussUserPwd=\u64cd\u4f5c\u54e1\u5bc6\u78bc +admin.storage.ussDomain=\u53c8\u62cd\u96f2\u7a7a\u9593\u7d81\u5b9a\u7684\u57df\u540d +admin.storage.ussToken=\u9632\u76dc\u93c8Token +admin.storage.ussTokenDesc=Token\u9632\u76dc\u93c8\u79d8\u9470��\u975e\u5fc5\u9700�� +admin.storage.configError=\u914d\u7f6e\u53c3\u6578\u7570\u5e38�� +admin.storage.sizePercent=\u7cfb\u7d71\u6587\u4ef6\u4f54\u6bd4�� +admin.storage.fileCount=\u6587\u4ef6\u6578�� +admin.storage.error=\u5b58\u5132\u7570\u5e38 +admin.task.name=\u4efb\u52d9\u540d\u7a31 +admin.task.edit=\u4efb\u52d9\u7de8\u8f2f +admin.task.type=\u4efb\u52d9\u985e\u578b +admin.task.method=\u5167\u7f6e\u65b9\u6cd5 +admin.task.methodName=\u65b9\u6cd5\u540d\u7a31 +admin.task.methodDesc=\u7531\u7cfb\u7d71\u6a21\u584a-\u63a7\u5236\u5668-\u65b9\u6cd5\u540d\u7d44\u6210\u8b39\u614e\u586b\u5beb. +admin.task.url=\u8acb\u6c42URL +admin.task.urlDesc=\u81ea\u5b9a\u7fa9URL\u5730\u5740��\u8a08\u5283\u4efb\u52d9\u5b9a\u671f\u57f7\u884c\u8acb\u6c42�� +admin.task.cycle=\u57f7\u884c\u9031\u671f +admin.task.desc=\u4efb\u52d9\u63cf\u8ff0 +admin.task.nMinutes=N\u5206\u9418 +admin.task.default=\u7cfb\u7d71\u9ed8\u8a8d +admin.task.timeInterval=\u9593\u9694\u6642\u9593 +admin.task.timeStart=\u958b\u59cb\u6642\u9593 +admin.task.timeStartRun=\u958b\u59cb\u57f7\u884c\u6642\u9593 +admin.task.timeLastRun=\u4e0a\u6b21\u57f7\u884c\u6642\u9593 +admin.task.timeLastLogin=\u767b\u9304\u6642\u9593 +admin.task.isOpen=\u662f\u5426\u555f\u7528 +admin.task.open=\u958b\u555f +admin.task.content=\u57f7\u884c\u5167\u5bb9 +admin.task.param=\u57f7\u884c\u53c3\u6578 +admin.task.ifRun=\u78ba\u5b9a\u8981\u904b\u884c\u8a72\u4efb\u52d9\u55ce�� +admin.task.backup=\u6578\u64da\u5099\u4efd +admin.task.backupDesc=\u6bcf\u592902:00\u958b\u59cb\u5099\u4efd\u7cfb\u7d71\u6578\u64da�� +admin.install.install=\u7cfb\u7d71\u5b89\u88dd +admin.install.databaseSet=\u6578\u64da\u5eab\u914d\u7f6e +admin.install.dataUpdate=\u6578\u64da\u9077\u79fb +admin.install.installSuccess=\u5b89\u88dd\u6210\u529f +admin.install.dbWasSet=\u60a8\u5df2\u914d\u7f6e\u6578\u64da\u5eab��\u5982\u9700\u91cd\u7f6e��\u53ef\u5728config/setting_user.php\u6587\u4ef6\u4e2d\u4fee\u6539\u914d\u7f6e\u5f8c\u91cd\u65b0\u5b89\u88dd�� +admin.install.errorRequest=\u7cfb\u7d71\u5df2\u5b89\u88dd��\u7981\u6b62\u518d\u6b21\u8acb\u6c42 +admin.install.databaseError=\u6578\u64da\u5eab\u9023\u63a5\u932f\u8aa4��\u8acb\u6aa2\u67e5\u914d\u7f6e +admin.install.cacheError=%s\u9023\u63a5\u5931\u6557��\u8acb\u6aa2\u67e5\u914d\u7f6e +admin.install.cacheConnectError=%s\u7121\u6cd5\u9023\u63a5\u5230\u670d\u52d9\u5668��\u8acb\u6aa2\u67e5\u914d\u7f6e +admin.install.dbSetError=\u6578\u64da\u5eab\u914d\u7f6e\u4fe1\u606f\u5beb\u5165\u5931\u6557 +admin.install.dbCreateTips=\u6578\u64da\u5eab\u4e0d\u5b58\u5728\u4e14\u81ea\u52d5\u5275\u5efa\u5931\u6557��\u8acb\u624b\u52d5\u5275\u5efa +admin.install.ifDelDb=\u6307\u5b9a\u7684\u6578\u64da\u5eab\u4e2d\u5df2\u5b58\u5728\u6578\u64da��\u9ede\u64ca[\u78ba\u5b9a]\u5f8c\u5c07\u6703\u88ab\u522a\u9664��\u662f\u5426\u7e7c\u7e8c�� +admin.install.dbCreateError=\u6578\u64da\u8868\u5275\u5efa\u7570\u5e38 +admin.install.dbFileError=\u6578\u64da\u5eab\u6587\u4ef6\u4e0d\u5b58\u5728 +admin.install.dbTypeError=\u6240\u9078\u6578\u64da\u5eab\u985e\u578b(%s)\u4e0d\u53ef\u7528��\u8acb\u5b89\u88dd\u5c0d\u61c9\u670d\u52d9\u53ca\u64f4\u5c55��\u6216\u9078\u64c7\u5176\u4ed6\u985e\u578b +admin.install.createSuccess=\u5275\u5efa\u6210\u529f +admin.install.defSetError=\u7cfb\u7d71\u9ed8\u8a8d\u914d\u7f6e\u6dfb\u52a0\u5931\u6557 +admin.install.defStoreError=\u9ed8\u8a8d\u5b58\u5132\u6dfb\u52a0\u5931\u6557 +admin.install.defPathError=\u7cfb\u7d71\u76ee\u9304\u6dfb\u52a0\u5931\u6557 +admin.install.defAdminError=\u7ba1\u7406\u54e1\u8cec\u865f\u6dfb\u52a0\u5931\u6557 +admin.install.defRoleError=\u9ed8\u8a8d\u89d2\u8272\u6dfb\u52a0\u5931\u6557 +admin.install.defGroupError=\u7cfb\u7d71\u90e8\u9580\u6dfb\u52a0\u5931\u6557 +admin.install.dataPathNotExists=data\u76ee\u9304\u4e0d\u5b58\u5728 +admin.install.defaultUpdate=\u7cfb\u7d71\u914d\u7f6e\u4fe1\u606f\u66f4\u65b0 +admin.install.pluginUpdated=\u63d2\u4ef6\u66f4\u65b0\u5b8c\u6210 +admin.install.defCacheError=\u521d\u59cb\u76ee\u9304\u7de9\u5b58\u6578\u64da\u7570\u5e38 +admin.install.serverDir=\u670d\u52d9\u5668\u5217\u76ee\u9304 +admin.install.dirRight=\u76ee\u9304\u6b0a\u9650 +admin.install.suggestOpen=\u5efa\u8b70\u958b\u555f +admin.install.suggestClose=\u5efa\u8b70\u95dc\u9589 +admin.install.phpVersionTips=PHP5.3\u53ca\u4ee5\u4e0a +admin.install.phpBitTips=\u5efa\u8b7064\u4f4d +admin.install.phpBitDesc=32\u4f4d\u4e0d\u652f\u63012G\u4ee5\u4e0a\u6587\u4ef6\u4e0a\u50b3\u4e0b\u8f09 +admin.install.pathNeedWirte=\u7a0b\u5e8f\u76ee\u9304\u53ca\u6240\u6709\u5b50\u76ee\u9304\u9700\u8981\u53ef\u8b80\u5beb +admin.install.mustOpen=\u5fc5\u9808\u958b\u555f +admin.install.setPathWrt=\u8acb\u70ba\u9805\u76ee\u76ee\u9304\u8a2d\u7f6e\u8b80\u5beb\u6b0a\u9650 +admin.install.ensureNoError=\u8acb\u78ba\u4fdd\u4ee5\u4e0b\u5167\u5bb9\u7121\u8aa4�� +admin.install.setAdminName=\u8acb\u8a2d\u7f6e\u7ba1\u7406\u54e1\u8cec\u865f +admin.install.setAdminPwd=\u8acb\u8a2d\u7f6e\u7ba1\u7406\u54e1\u5bc6\u78bc +admin.install.database=\u6578\u64da\u5eab +admin.install.dbType=\u6578\u64da\u5eab\u985e\u578b +admin.install.dbName=\u6578\u64da\u5eab\u540d +admin.install.userName=\u7528\u6236\u540d +admin.install.dbPort=\u7aef\u53e3\u865f +admin.install.dbPortDesc=\u9ed8\u8a8d\u7aef\u53e33306��\u5982\u9700\u81ea\u5b9a\u7fa9\u53ef\u5728\u5f8c\u9762\u8ffd\u52a0��\u5982��127.0.0.1:3307 +admin.install.dbEngine=\u5b58\u5132\u5f15\u64ce +admin.install.sqliteDesc=php\u5167\u7f6e\u7da0\u8272\u8f15\u91cf\u6578\u64da\u5eab(\u9069\u7528\u65bc\u6e2c\u8a66\u6216\u5c0f\u898f\u6a21\u4f7f\u7528). +admin.install.mysqlDesc=\u652f\u6301\u96c6\u7fa4\u90e8\u7f72\u4e3b\u5f9e\u591a\u6578\u64da\u5eab\u5206\u96e2. +admin.install.pdoDesc=\u66f4\u5b89\u5168\u7684\u6578\u64da\u5eab\u901a\u7528\u9a45\u52d5\u9700\u8981php\u5df2\u5b89\u88ddPDO\u64f4\u5c55. +admin.install.cacheType=\u7cfb\u7d71\u7de9\u5b58\u985e\u578b +admin.install.cacheTypeDesc=\u7528\u65bc\u7de9\u5b58\u901a\u7528\u6578\u64da\u53ca\u6703\u8a71session��\u52a0\u5feb\u7cfb\u7d71\u8a2a\u554f +admin.install.fileCache=\u6587\u4ef6\u7de9\u5b58 +admin.install.groupFile=\u90e8\u9580\u6587\u6a94 +admin.install.userFile=\u7528\u6236\u6587\u6a94 +admin.install.role=\u89d2\u8272 +admin.install.fileAuth=\u6587\u6a94\u6b0a\u9650 +admin.install.userList=\u7528\u6236\u5217\u8868 +admin.install.setInfo=\u7cfb\u7d71\u914d\u7f6e\u4fe1\u606f +admin.install.favShare=\u7528\u6236\u6536\u85cf\u53ca\u5206\u4eab +admin.install.waitUpdate=\u7b49\u5f85\u66f4\u65b0 +admin.install.updateSuccess=\u66f4\u65b0\u6210\u529f +admin.install.fileCount=\u6587\u4ef6\u6578 +admin.install.settingDesc=\u5931\u6557\u9805\u53ef\u5728\u5f8c\u53f0\u7ba1\u7406\u9032\u884c\u624b\u52d5\u914d\u7f6e +admin.install.reInstallTips=\u8fd4\u56de\u7d50\u679c\u7570\u5e38��\u8acb\u91cd\u65b0\u5b89\u88dd +admin.log.accountEdit=\u4fee\u6539\u8cec\u865f\u4fe1\u606f +admin.log.thirdBind=\u7d81\u5b9a\u7b2c\u4e09\u65b9\u8cec\u865f +admin.log.delBind=\u53d6\u6d88\u7d81\u5b9a +admin.log.viewFile=\u9810\u89bd\u6587\u4ef6 +admin.log.delFile=\u522a\u9664\u6587\u4ef6 +admin.log.editFile=\u7de8\u8f2f\u6587\u4ef6 +admin.log.downFile=\u4e0b\u8f09\u6587\u4ef6 +admin.log.downFolder=\u4e0b\u8f09\u6587\u4ef6\u593e +admin.log.moveFile=\u79fb\u52d5\u6587\u4ef6 +admin.log.addUser=\u65b0\u589e\u7528\u6236 +admin.log.editUser=\u7de8\u8f2f\u7528\u6236 +admin.log.addUserTo=\u65b0\u589e\u7528\u6236\u5230\u90e8\u9580 +admin.log.removeUserFrom=\u7528\u6236\u5f9e\u90e8\u9580\u79fb\u9664 +admin.log.switchUserGroup=\u9077\u79fb\u7528\u6236\u5230\u90e8\u9580 +admin.log.stausUser=\u555f/\u7981\u7528\u7528\u6236 +admin.log.addRole=\u65b0\u5efa\u89d2\u8272 +admin.log.editRole=\u7de8\u8f2f\u89d2\u8272 +admin.log.delRole=\u522a\u9664\u89d2\u8272 +admin.log.addAuth=\u65b0\u589e\u6b0a\u9650 +admin.log.editAuth=\u7de8\u8f2f\u6b0a\u9650 +admin.log.delAuth=\u522a\u9664\u6b0a\u9650 +admin.log.editShare=\u7de8\u8f2f\u5206\u4eab +admin.log.delLinkTo=\u53d6\u6d88\u5916\u93c8\u5206\u4eab +admin.log.delShareTo=\u53d6\u6d88\u5354\u4f5c\u5206\u4eab +admin.log.recycleTo=\u79fb\u5230\u56de\u6536\u7ad9 +admin.log.newName=\u65b0\u540d\u7a31 +admin.log.oldName=\u539f\u540d\u7a31 +admin.log.newPath=\u65b0\u76ee\u9304 +admin.log.oldPath=\u539f\u76ee\u9304 +admin.log.typeFile=\u6587\u4ef6\u64cd\u4f5c +admin.log.typeUser=\u7528\u6236\u914d\u7f6e +admin.log.queryByIp=\u9ede\u64ca\u6309\u9215��\u6839\u64daIP\u67e5\u8a62\u7576\u5929\u7684\u65e5\u8a8c\u8a18\u9304�� +admin.backup.setting=\u5099\u4efd\u8a2d\u7f6e +admin.backup.edit=\u5099\u4efd\u7de8\u8f2f +admin.backup.ing=\u5099\u4efd\u4e2d +admin.backup.success=\u5099\u4efd\u6210\u529f +admin.backup.fail=\u5099\u4efd\u5931\u6557 +admin.backup.complete=\u5099\u4efd\u5b8c\u6210 +admin.backup.db=\u6578\u64da\u5eab +admin.backup.dbFile=\u6578\u64da\u5eab\u6587\u4ef6 +admin.backup.fileError=\u90e8\u5206\u6587\u4ef6\u5099\u4efd\u5931\u6557 +admin.backup.checkLog=\u8acb\u67e5\u770b\u5099\u4efd\u65e5\u8a8c��data/temp/log/backup/\u7576\u5929\u65e5\u671f__log.php +admin.backup.pathNoWrite=\u81e8\u6642\u76ee\u9304\u6c92\u6709\u5beb\u6b0a\u9650 +admin.backup.errorMsg=\u90e8\u5206\u6587\u4ef6\u5099\u4efd\u5931\u6557��\u53ef\u6839\u64da\u65e5\u8a8c\u624b\u52d5\u8907\u88fd��\u6216\u522a\u9664\u5f8c\u91cd\u65b0\u5099\u4efd�� +admin.backup.logFile=\u65e5\u8a8c\u6587\u4ef6 +admin.backup.manual=\u624b\u52d5\u5099\u4efd +admin.backup.continue=\u7e7c\u7e8c\u5099\u4efd +admin.backup.start=\u958b\u59cb\u5099\u4efd +admin.backup.open=\u958b\u555f\u5099\u4efd +admin.backup.notOpen=\u5099\u4efd\u5c1a\u672a\u555f\u7528 +admin.backup.location=\u5099\u4efd\u4f4d\u7f6e +admin.backup.content=\u5099\u4efd\u5167\u5bb9 +admin.backup.dbOnly=\u50c5\u6578\u64da\u5eab +admin.backup.time=\u5099\u4efd\u6642\u9593 +admin.backup.notStart=\u672a\u958b\u59cb +admin.backup.notEnabled=\u672a\u555f\u7528 +admin.backup.killed=\u5df2\u7d50\u675f +admin.backup.ifKill=\u78ba\u5b9a\u8981\u7d50\u675f\u6b64\u6b21\u5099\u4efd\u55ce�� +admin.backup.kill=\u7d50\u675f +admin.backup.error=\u7570\u5e38\u4e2d\u6b62 +admin.backup.timeBeen=\u5df2\u8017\u6642 +admin.backup.timeTotal=\u7e3d\u8017\u6642 +admin.backup.backed=\u5df2\u5099\u4efd +admin.backup.storage=\u8acb\u5275\u5efa\u4e00\u500b\u5c08\u9580\u7528\u65bc\u5099\u4efd\u7684\u5b58\u5132�� +admin.backup.ifSave=\u5099\u4efd\u9700\u8981\u8f03\u9577\u6642\u9593��\u60a8\u78ba\u5b9a\u8981\u9032\u884c\u5099\u4efd\u55ce�� +admin.backup.ifContinue=\u78ba\u5b9a\u8981\u7e7c\u7e8c\u5099\u4efd\u55ce�� +admin.backup.saveTips=\u5099\u4efd\u4efb\u52d9\u5df2\u63d0\u4ea4��\u8acb\u8010\u5fc3\u7b49\u5f85 +admin.backup.fileSize=\u6587\u6a94\u5927\u5c0f +admin.backup.dbSize=\u6578\u64da\u5eab\u5927\u5c0f +admin.backup.dbCnt=\u7e3d\u8a18\u9304\u6578 +admin.backup.notFinished=\u5c1a\u672a\u5b8c\u6210 +admin.backup.timeTaken=\u8017\u6642 +admin.backup.node=\u7bc0\u9ede +admin.backup.notYet=\u66ab\u7121 +admin.backup.storeNotExist=\u5099\u4efd\u5b58\u5132\u4e0d\u5b58\u5728��\u8acb\u91cd\u65b0\u8a2d\u7f6e +admin.backup.timeNote=\u8aaa\u660e��\u7cfb\u7d71\u50c5\u4fdd\u7559\u6700\u8fd17\u5929��\u53ca\u6bcf\u67081\u865f\u7684\u6578\u64da\u5eab\u5099\u4efd��\u5099\u4efd\u6642\u9593�� +admin.backup.recover=\u6578\u64da\u6062\u5fa9\u8acb\u806f\u7e6b\u670d\u52d9\u5546�� +admin.backup.optionTime=\u5099\u4efd\u6240\u9700\u6642\u9593\u8f03\u9577��\u8acb\u76e1\u91cf\u9078\u5728\u975e\u5de5\u4f5c\u6642\u9593\u6bb5\u9032\u884c +admin.backup.optionLocation=\u5982\u9700\u5099\u4efd\u6587\u4ef6��\u8acb\u65b0\u5275\u5efa\u4e00\u500b\u5c08\u9580\u7528\u65bc\u5099\u4efd\u7684\u5b58\u5132 +admin.backup.optionTips1=\u5099\u4efd\u5206\u70ba\u6578\u64da\u5eab\u5099\u4efd\u548c\u6587\u4ef6\u5099\u4efd\u5169\u90e8\u5206�� +admin.backup.optionTips2=\u6578\u64da\u5eab\u5099\u4efd��\u5c07\u6578\u64da\u5eab\u5167\u5bb9\u751f\u6210SQL\u6587\u4ef6��\u5099\u4efd\u81f3\u76ee\u6a19\u5b58\u5132database\u76ee\u9304�� +admin.backup.optionTips3=\u6587\u4ef6\u5099\u4efd��\u5c07\u7cfb\u7d71\u5b58\u5132\u6587\u4ef6��\u6309\u539f\u5b58\u5132\u8def\u5f91\u589e\u91cf\u5099\u4efd\u81f3\u76ee\u6a19\u5b58\u5132�� +admin.backup.optionTips4=\u7cfb\u7d71\u50c5\u4fdd\u7559\u6700\u8fd17\u5929��\u53ca\u6bcf\u67081\u865f\u7684\u6578\u64da\u5eab\u5099\u4efd�� +admin.backup.needStorage=\u5099\u4efd\u5b58\u5132\u4e0d\u80fd\u70ba\u7a7a +admin.backup.needNoDefault=\u8acb\u52ff\u9078\u64c7\u9ed8\u8a8d\u5b58\u5132\u4f5c\u70ba\u6587\u4ef6\u5099\u4efd\u4f4d\u7f6e +admin.backup.contentDesc=\u6388\u6b0a\u7248\u652f\u6301\u540c\u6642\u5099\u4efd\u6578\u64da\u5eab\u548c\u6587\u4ef6 +admin.backup.action=\u64cd\u4f5c\u7ba1\u7406 +admin.backup.recovery=\u9084\u539f +admin.backup.sysRecovery=\u7cfb\u7d71\u9084\u539f +admin.backup.bakErr2Rec=\u6b64\u5099\u4efd\u672a\u5b8c\u6210��\u7121\u6cd5\u9084\u539f +admin.recycle.menu=\u7cfb\u7d71\u56de\u6536\u7ad9 +admin.share.name=\u5206\u4eab\u540d\u7a31 +admin.share.type=\u5206\u4eab\u985e\u578b +admin.share.expiryTime=\u904e\u671f\u6642\u9593 +admin.share.expired=\u5df2\u904e\u671f +admin.share.link=\u5916\u93c8 +admin.share.linkView=\u9ede\u64ca\u67e5\u770b\u5206\u4eab +admin.share.ifDel=\u78ba\u5b9a\u8981\u53d6\u6d88\u8a72\u5206\u4eab\u55ce�� +admin.share.disFile=\u8a72\u6587\u4ef6\u906d\u5230\u7528\u6236\u8209\u5831��\u5df2\u88ab\u7981\u6b62\u5206\u4eab +admin.share.disFolder=\u6b64\u76ee\u9304\u4e0b\u542b\u6709\u88ab\u7981\u6b62\u5206\u4eab\u7684\u9055\u898f\u6587\u4ef6 +admin.share.shareTab=\u5206\u4eab\u7ba1\u7406 +admin.share.reportTab=\u5206\u4eab\u8209\u5831\u7ba1\u7406 +admin.share.rptType1=\u4fb5\u72af\u7248\u6b0a +admin.share.rptType2=\u6deb\u7a62\u8272\u60c5 +admin.share.rptType3=\u8840\u8165\u66b4\u529b +admin.share.rptType4=\u653f\u6cbb\u6709\u5bb3 +admin.share.rptType5=\u5176\u4ed6\u539f\u56e0 +admin.share.doRptClose=\u8655\u7406\u5206\u4eab\u5167\u5bb9\u5f8c\u95dc\u9589\u8a72\u8209\u5831��\u6216\u76f4\u63a5\u95dc\u9589 +admin.share.doRptDisable=\u7981\u6b62/\u5141\u8a31\u5206\u4eab\u5f8c��\u8a72\u6587\u4ef6\u5c0d\u61c9\u7684\u6240\u6709\u8cc7\u6e90\u90fd\u5c07\u53d7\u5f71\u97ff��\u78ba\u5b9a\u8981\u57f7\u884c\u6b64\u64cd\u4f5c\u55ce�� +admin.share.rptUser=\u8209\u5831\u8005 +admin.share.rptTitle=\u8209\u5831\u5206\u4eab +admin.share.rptDesc=\u8209\u5831\u539f\u56e0 +admin.share.rptTime=\u8209\u5831\u6642\u9593 +admin.share.rptResult=\u8655\u7406\u7d50\u679c +admin.share.rptDone=\u5df2\u8655\u7406 +admin.share.rptNoDone=\u672a\u8655\u7406 +admin.share.rptClose=\u95dc\u9589\u8209\u5831 +admin.share.rptShareDel=\u53d6\u6d88\u5206\u4eab +admin.share.rptShareAllow=\u5141\u8a31\u5206\u4eab +admin.share.rptShareDisable=\u7981\u6b62\u5206\u4eab +admin.share.rptDoDisable=\u7981\u6b62/\u5141\u8a31\u5206\u4eab +admin.share.rptSelectTips=\u8acb\u9078\u64c7\u5f85\u64cd\u4f5c\u9805�� +admin.setting.transfer=\u4e0a\u50b3/\u4e0b\u8f09 +admin.setting.transferChunkSize=\u4e0a\u50b3\u5206\u7247\u5927\u5c0f +admin.setting.transferChunkSizeDesc=\u5927\u6587\u4ef6\u4e0a\u50b3\u6642\u5207\u5206\u6210\u7247\u9032\u884c\u4e26\u767c\u4e0a\u50b3\u5f9e\u800c\u5be6\u73fe\u52a0\u901f\u548c\u65b7\u9ede\u7e8c\u50b3
    \u63a8\u85a65M;\u6b64\u503c\u5fc5\u9808\u5c0f\u65bc\u4e0b\u8ff0\u914d\u7f6e;\u5426\u5247\u6703\u5f15\u8d77\u4e0a\u50b3\u7570\u5e38(\u4e0a\u50b3\u5931\u6557\u9032\u5ea6\u56de\u9000) +admin.setting.transferChunkSizeDescError1=\u4e0a\u50b3\u5206\u7247\u5927\u5c0f\u4e0d\u80fd\u8d85\u904ephp.ini\u4e2d\u7684\u8a2d\u7f6e +admin.setting.transferChunkSizeDescError2=\u5728php.ini\u4e2d\u4fee\u6539\u5927\u518d\u8a66(\u4fee\u6539upload_max_filesize��post_max_size\u9700\u8981\u91cd\u555f) +admin.setting.transferThreads=\u4e0a\u50b3\u4e26\u767c\u7dda\u7a0b +admin.setting.transferThreadsDesc=\u63a8\u85a6 +admin.setting.transferIgnore=\u4e0a\u50b3\u5ffd\u7565\u6587\u4ef6 +admin.setting.transferIgnoreDesc=\u4e0a\u50b3\u81ea\u52d5\u5ffd\u7565\u7684\u6587\u4ef6\u540d\u53ef\u4ee5\u6392\u9664\u81e8\u6642\u6587\u4ef6\u591a\u500b\u7528\u9017\u865f\u9694\u958b\u4f8b\u5982:.DS_storethumb.db +admin.setting.transferChunkRetry=\u4e0a\u50b3\u5931\u6557\u81ea\u52d5\u91cd\u50b3 +admin.setting.transferChunkRetryDesc=\u63a8\u85a6 +admin.setting.transferOsChunkSize=\u5c0d\u8c61\u5b58\u5132\u5206\u7247\u5927\u5c0f +admin.setting.transferOsChunkSizeDesc=\u5c0d\u8c61\u5b58\u5132\u4e0a\u50b3��\u5206\u7247\u5927\u5c0f\u7bc4\u570d\u70ba5MB~5GB��\u6700\u5927\u8acb\u6c42\u6578\u70ba1000��\u5373\u6700\u5927\u53ef\u652f\u63015TB\u7684\u6587\u4ef6\u4e0a\u50b3��
    \u63a8\u85a610~20MB��\u6b64\u6642\u652f\u6301\u6700\u5927\u6587\u4ef6\u5927\u5c0f\u70ba9.7~19.5GB��\u7528\u6236\u53ef\u6839\u64da\u6240\u9700\u4e0a\u50b3\u6587\u4ef6\u5927\u5c0f\u81ea\u884c\u8abf\u6574�� +admin.setting.transferHttpSendFile=\u4e0b\u8f09web\u670d\u52d9\u5668\u52a0\u901f +admin.setting.transferHttpSendFileDesc=\u6587\u4ef6\u4e0b\u8f09\u901a\u904ewebserver\u76f4\u50b3;\u63d0\u5347\u4e0b\u8f09\u901f\u5ea6;\u53ea\u91dd\u5c0d\u9ed8\u8a8d\u5b58\u5132\u914d\u7f6e\u70ba\u672c\u5730\u5b58\u5132\u7684\u60c5\u6cc1\u6709\u6548. +admin.setting.downloadZipClient=\u958b\u555f\u524d\u7aef\u6253\u5305\u58d3\u7e2e\u4e0b\u8f09 +admin.setting.downloadZipClientDesc=\u9700\u8981\u80fd\u5920\u93c8\u63a5\u5916\u7db2\u6216\u8005\u7ad9\u9ede\u70bahttps +admin.setting.downloadZipLimit=\u5f8c\u7aef\u6253\u5305\u58d3\u7e2e\u4e0b\u8f09\u9650\u5236 +admin.setting.downloadZipLimitDesc=0\u70ba\u4e0d\u9650\u5236;\u70ba\u907f\u514d\u670d\u52d9\u5668\u6027\u80fd\u6d88\u8017\u904e\u5927\u6587\u4ef6\u593e\u904e\u5927\u6642\u9650\u5236\u6253\u5305\u4e0b\u8f09\u63d0\u793a\u901a\u904ePC\u5ba2\u6236\u7aef\u53ef\u4ee5\u76f4\u63a5\u4e0b\u8f09\u6587\u4ef6 +admin.setting.downloadZipLimitTips=\u58d3\u7e2e\u5167\u5bb9\u8d85\u51fa\u7cfb\u7d71\u9650\u5236\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1!\u60a8\u53ef\u4ee5\u901a\u904ePC\u5ba2\u6236\u7aef\u76f4\u63a5\u4e0b\u8f09\u6587\u4ef6\u593e\u7121\u9700\u58d3\u7e2e. +admin.setting.dragDownload=\u62d6\u62fd\u5230\u684c\u9762\u4e0b\u8f09 +admin.setting.dragDownloadDesc=\u50c5PC\u7aefChrome\u5167\u6838\u700f\u89bd\u5668\u652f\u6301(chromeedge360\u6025\u901f\u7b49\u652f\u6301) +admin.setting.dragDownloadZip=\u591a\u9078\u62d6\u62fd\u58d3\u7e2e\u4e0b\u8f09 +admin.setting.dragDownloadZipDesc=\u591a\u9078\u6216\u6587\u4ef6\u593e\u62d6\u62fd\u4e0b\u8f09\u652f\u6301\u9808\u5148\u670d\u52d9\u5668\u6253\u5305\u58d3\u7e2e\u5f8c\u4e0b\u8f09 +admin.setting.dragDownloadLimit=\u62d6\u62fd\u5167\u5bb9\u5927\u5c0f\u9650\u5236 +admin.setting.dragDownloadLimitDesc=0\u70ba\u4e0d\u9650\u5236;\u62d6\u62fd\u5167\u5bb9\u5927\u5c0f\u6703\u53d7\u8a72\u9650\u5236.\u7531\u65bc\u76ee\u524dChrome\u62d6\u62fd\u4e0b\u8f09\u6c92\u6709\u9032\u5ea6\u689d\u7121\u6cd5\u53d6\u6d88\u63a8\u85a6\u9650\u5236\u5927\u5c0f\u523020M. +admin.setting.dragDownloadUrlTips=url\u904e\u9577\u8acb\u6e1b\u5c11\u9078\u64c7\u5167\u5bb9\u5f8c\u518d\u8a66! +admin.setting.dragDownloadOpenTips=\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1\u5728\u5f8c\u53f0\u8a2d\u7f6e\u4e2d\u958b\u555f! +admin.setting.dragDownloadNotOpen=\u62d6\u62fd\u58d3\u7e2e\u4e0b\u8f09\u672a\u958b\u555f +admin.setting.dragDownloadSizeTips=\u62d6\u62fd\u5167\u5bb9\u5927\u5c0f\u8d85\u51fa\u9650\u5236 +admin.setting.showFileSafe=\u6587\u4ef6\u8a2a\u554f\u5b89\u5168 +admin.setting.showFileLink=\u6587\u4ef6\u5916\u93c8\u5c55\u793a +admin.setting.showFileLinkDesc=\u95dc\u9589\u5f8c\u6587\u4ef6\u5c6c\u6027\u4e0d\u518d\u986f\u793a\u5916\u93c8\u9023\u63a5 +admin.setting.showFileMd5=\u6587\u4ef6md5\u5c55\u793a +admin.setting.showFileMd5Desc=\u95dc\u9589\u5f8c\u6587\u4ef6\u5c6c\u6027\u4e0d\u518d\u986f\u793a\u6587\u4ef6md5 +admin.setting.shareLinkAllow=\u555f\u7528\u5916\u93c8\u5206\u4eab +admin.setting.shareLinkAllowDesc=\u95dc\u9589\u5f8c\u5c07\u4e0d\u518d\u652f\u6301\u5916\u93c8\u5206\u4eab\u5df2\u5206\u4eab\u7684\u5167\u5bb9\u4e0d\u53d7\u5f71\u97ff +admin.setting.shareLinkAllowTips=\u7576\u524d\u7cfb\u7d71\u5df2\u7981\u7528\u4e86\u5916\u93c8\u5206\u4eab\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1! +admin.setting.shareLinkPasswordAllowEmpty=\u5916\u93c8\u5206\u4eab\u5141\u8a31\u5bc6\u78bc\u70ba\u7a7a +admin.setting.shareLinkPasswordAllowEmptyDesc=\u95dc\u9589\u5f8c\u5916\u93c8\u5206\u4eab\u5fc5\u9808\u8a2d\u7f6e\u5bc6\u78bc;\u5df2\u5206\u4eab\u7684\u5167\u5bb9\u4e0d\u53d7\u5f71\u97ff +admin.setting.shareLinkAllowGuest=\u5916\u93c8\u5206\u4eab\u5141\u8a31\u672a\u767b\u9304\u904a\u5ba2\u8a2a\u554f +admin.setting.shareLinkAllowGuestDesc=\u95dc\u9589\u5f8c\u8a2a\u554f\u5916\u93c8\u6642\u5fc5\u9808\u767b\u9304;\u5df2\u5206\u4eab\u7684\u5167\u5bb9\u4e0d\u53d7\u5f71\u97ff +admin.setting.shareLinkZip=\u5916\u93c8\u5206\u4eab\u6253\u5305\u4e0b\u8f09 +admin.setting.shareLinkZipDesc=\u958b\u555f\u5f8c\u5916\u93c8\u5206\u4eab\u6587\u4ef6\u593e\u652f\u6301\u6253\u5305\u58d3\u7e2e\u4e0b\u8f09\u4e26\u767c\u5927\u7684\u8a71\u6703\u8017\u8cbb\u670d\u52d9\u5668\u6027\u80fd. +admin.setting.shareLinkZipTips=\u5916\u93c8\u5206\u4eab\u7981\u7528\u4e86\u6253\u5305\u4e0b\u8f09\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1\u9032\u884c\u914d\u7f6e! +admin.setting.transferDownSpeed=\u4e0b\u8f09\u9650\u901f +admin.setting.transferDownSpeedDesc=\u9650\u5236\u4e0b\u8f09\u901f\u5ea6\u5c0d\u7db2\u7ad9\u4e26\u767c\u5927\u7684\u60c5\u6cc1\u9032\u884c\u7d71\u4e00\u9650\u901f +admin.setting.transferDownSpeedNum=\u4e0b\u8f09\u9650\u901f\u901f\u5ea6 +admin.setting.transferDownSpeedNumDesc=\u9650\u5236\u4e0b\u8f09\u901f\u5ea6\u5c0d\u7db2\u7ad9\u4e26\u767c\u5927\u7684\u60c5\u6cc1\u53ef\u4ee5\u9032\u884c\u7d71\u4e00\u9650\u901f.
    \u6ce8��\u6b64\u8655\u9650\u5236\u7684\u662f\u670d\u52d9\u5668\u901f\u5ea6��\u5177\u9ad4\u4e0b\u8f09\u901f\u5ea6\u9084\u53d7\u670d\u52d9\u5668\u5e36\u5bec\u548c\u7528\u6236\u7db2\u7d61\u6709\u95dc. +explorer.uploadSizeError=\u60a8\u670d\u52d9\u5668\u7576\u524d\u4e0d\u652f\u63012G\u4ee5\u4e0a\u6587\u4ef6
    \u8acb\u5347\u7d1a\u70ba64\u4f4dphp;\u63a8\u85a664\u4f4dphp7
    (\u6ce8:64\u4f4d\u64cd\u4f5c\u7cfb\u7d71\u624d\u80fd\u5b89\u88dd64\u4f4dphp); +common.----=---- +common.width=\u5bec +common.height=\u9ad8 +common.test=\u6e2c\u8a66 +common.absolutePath=\u7d55\u5c0d\u5730\u5740 +common.qrcode=URL\u4e8c\u7dad\u78bc +common.wechat=\u5fae\u4fe1 +common.group=\u90e8\u9580 +common.user=\u7528\u6236 +common.online=\u5728\u7dda +common.use=\u4f7f\u7528 +common.total=\u7e3d\u91cf +common.year=\u5e74 +common.month=\u6708 +common.week=\u9031 +common.daytime=\u65e5 +common.mon=\u9031\u4e00 +common.tue=\u9031\u4e8c +common.wed=\u9031\u4e09 +common.thu=\u9031\u56db +common.fri=\u9031\u4e94 +common.sat=\u9031\u516d +common.sun=\u9031\u65e5 +common.second=\u79d2 +common.minute=\u5206\u9418 +common.hour=\u5c0f\u6642 +common.day=\u5929 +common.every=\u6bcf +common.everyMonth=\u6bcf\u6708 +common.everyWeek=\u6bcf\u9031 +common.everyDay=\u6bcf\u5929 +common.language=\u591a\u8a9e\u8a00 +common.all=\u5168\u90e8 +common.item=\u9805 +common.items=\u9805\u5167\u5bb9 +common.itemsEmpyt=\u7121\u5167\u5bb9 +common.detail=\u8a73\u60c5 +common.me=\u6211\u81ea\u5df1 +common.others=\u5176\u4ed6 +common.guest=\u8a2a\u5ba2 +common.more=\u66f4\u591a +common.learnMore=\u4e86\u89e3\u66f4\u591a +common.yes=\u662f +common.no=\u5426 +common.omit=\u7565 +common.unknow=\u672a\u77e5 +common.title=\u6a19\u984c +common.time=\u6642\u9593 +common.scan=\u700f\u89bd +common.report=\u8209\u5831 +common.name=\u540d\u7a31 +common.nickName=\u66b1\u7a31 +common.tools=\u5de5\u5177 +common.tag=\u6a19\u7c64 +common.position=\u4f4d\u7f6e +common.mount=\u7db2\u7d61\u639b\u8f09 +common.type=\u985e\u578b +common.auth=\u6b0a\u9650 +common.status=\u72c0\u614b +common.run=\u904b\u884c +common.file=\u6587\u4ef6 +common.folder=\u6587\u4ef6\u593e +common.fileType=\u6587\u4ef6\u985e\u578b +common.fileSize=\u6587\u4ef6\u5927\u5c0f +common.attributeInfo=\u5c6c\u6027\u4fe1\u606f +common.actionType=\u64cd\u4f5c\u985e\u578b +common.isDisplay=\u662f\u5426\u986f\u793a +common.hide=\u96b1\u85cf +common.isHide=\u5df2\u96b1\u85cf +common.cancelHide=\u53d6\u6d88\u96b1\u85cf +common.default=\u9ed8\u8a8d +common.display=\u986f\u793a +common.moveDown=\u4e0b\u79fb +common.moveUp=\u4e0a\u79fb +common.drag=\u62d6\u62fd +common.dragSort=\u62d6\u62fd\u8abf\u6574\u9806\u5e8f +common.warning=\u8b66\u544a +common.tips=\u63d0\u793a +common.desc=\u8aaa\u660e +common.tipsDesc=\u63d0\u793a\u8aaa\u660e +common.tipsOthers=\u5176\u4ed6\u8aaa\u660e +common.view=\u67e5\u770b +common.log=\u65e5\u8a8c +common.task=\u4efb\u52d9 +common.important=\u91cd\u8981 +common.icon=\u5716\u6a19 +common.menu=\u83dc\u55ae +common.system=\u7cfb\u7d71 +common.basic=\u901a\u7528 +common.systemSet=\u7cfb\u7d71\u914d\u7f6e +common.systemDefault=\u7cfb\u7d71\u9ed8\u8a8d +common.diy=\u81ea\u5b9a\u7fa9 +common.input=\u8acb\u8f38\u5165 +common.select=\u8acb\u9078\u64c7 +common.add=\u65b0\u589e +common.edit=\u7de8\u8f2f +common.action=\u64cd\u4f5c +common.upload=\u4e0a\u50b3 +common.uploadTo=\u4e0a\u50b3\u5230 +common.download=\u4e0b\u8f09 +common.export=\u5c0e\u51fa +common.cover=\u8986\u84cb +common.retry=\u91cd\u8a66 +common.zip=\u58d3\u7e2e +common.unzip=\u89e3\u58d3 +common.preview=\u9810\u89bd +common.share=\u5206\u4eab +common.search=\u641c\u7d22 +common.query=\u67e5\u8a62 +common.delete=\u522a\u9664 +common.deleteForce=\u5fb9\u5e95\u522a\u9664 +common.deleteEnd=\u5df2\u522a\u9664 +common.refresh=\u5237\u65b0 +common.open=\u6253\u958b +common.close=\u95dc\u9589 +common.from=\u4f86\u6e90 +common.greater=\u5927\u65bc +common.less=\u5c0f\u65bc +common.print=\u6253\u5370 +common.selectInvert=\u53cd\u9078 +common.selectAll=\u5168\u9078/\u53cd\u9078 +common.selectAllItem=\u5168\u9078 +common.selectNum=\u5df2\u9078\u64c7 +common.selectNull=\u5168\u4e0d\u9078 +common.sizeMore=\u4ee5\u4e0a +common.showMore=\u5c55\u958b +common.showLess=\u6536\u8d77 +common.sizeSmall=\u5c0f +common.sizeMiddle=\u4e2d +common.sizeBig=\u5927 +common.rename=\u91cd\u547d\u540d +common.method=\u51fd\u6578 +common.extend=\u64f4\u5c55 +common.fav=\u6536\u85cf +common.reset=\u91cd\u7f6e +common.testing=\u6aa2\u6e2c +common.install=\u5b89\u88dd +common.update=\u66f4\u65b0 +common.version=\u7248\u672c +common.sysVersion=\u5e73\u53f0\u7248\u672c +common.login=\u767b\u9304 +common.regist=\u8a3b\u518a +common.password=\u5bc6\u78bc +common.operateTime=\u64cd\u4f5c\u6642\u9593 +common.createTime=\u5275\u5efa\u6642\u9593 +common.modifyTime=\u4fee\u6539\u6642\u9593 +common.activeTime=\u6b78\u6a94\u6642\u9593 +common.startTime=\u958b\u59cb\u6642\u9593 +common.endTime=\u7d50\u675f\u6642\u9593 +common.finishTime=\u7d50\u675f\u6642\u9593 +common.disable=\u7981\u7528 +common.goOn=\u7e7c\u7e8c +common.ok=\u78ba\u5b9a +common.startRun=\u5f00\u59cb\u6267\u884c +common.confirmTips=\u5371\u96aa\u64cd\u4f5c\u8acb\u518d\u6b21\u78ba\u8a8d +common.confirmAsk=\u78ba\u8a8d\u8981\u9032\u884c\u8a72\u64cd\u4f5c\u55ce? +common.submit=\u63d0\u4ea4 +common.skip=\u8df3\u904e +common.nextStep=\u4e0b\u4e00\u6b65 +common.start=\u958b\u59cb +common.stop=\u66ab\u505c +common.set=\u8a2d\u7f6e +common.cancel=\u53d6\u6d88 +common.save=\u4fdd\u5b58 +common.empty=\u6c92\u6709\u5167\u5bb9! +common.isOpen=\u5df2\u958b\u555f +common.isClose=\u5df2\u95dc\u9589 +common.apply=\u61c9\u7528 +common.saveAll=\u4fdd\u5b58\u5168\u90e8 +common.notSave=\u4e0d\u4fdd\u5b58 +common.appAdd=\u6dfb\u52a0 +common.backAdd=\u8fd4\u56de\u6dfb\u52a0 +common.saveEdit=\u4fdd\u5b58\u4fee\u6539 +common.saveSubmit=\u4fdd\u5b58\u63d0\u4ea4 +common.saveAndAdd=\u4fdd\u5b58\u4e26\u7e7c\u7e8c\u6dfb\u52a0 +common.sex=\u6027\u5225 +common.male=\u7537 +common.female=\u5973 +common.address=\u5730\u5740 +common.email=Email +common.phone=\u624b\u6a5f +common.sms=\u77ed\u4fe1 +common.phoneNumber=\u624b\u6a5f\u865f +common.server=\u670d\u52d9\u5668 +common.handheld=\u79fb\u52d5\u8a2d\u5099 +common.success=\u6210\u529f +common.fail=\u5931\u6557 +common.error=\u932f\u8aa4 +common.result=\u7d50\u679c +common.expired=\u5df2\u5931\u6548 +common.valid=\u6709\u6548 +common.inAll=\u7e3d\u8a08 +common.allAndNull=\u5168\u9078/\u53d6\u6d88 +common.moveTop=\u7f6e\u9802 +common.moveBottom=\u7f6e\u5e95 +common.moveTopCancle=\u53d6\u6d88\u7f6e\u9802 +common.ECN=\u83ef\u6771 +common.NCN=\u83ef\u5317 +common.SCN=\u83ef\u5357 +common.USA=\u5317\u7f8e +common.SEA=\u6771\u5357\u4e9e +common.noLimit=\u4e0d\u9650\u5236 +common.notExists=\u4e0d\u5b58\u5728 +common.cannotWrite=\u53ea\u8b80\u4e0d\u53ef\u5beb +common.readOnly=\u53ea\u8b80 +common.cannotRead=\u4e0d\u53ef\u8b80 +common.ifDel=\u78ba\u5b9a\u8981\u522a\u9664\u55ce�� +common.pageNotExists=\u8a72\u9801\u9762\u4e0d\u5b58\u5728! +common.pathNotExists=\u8a72\u6587\u4ef6\u4e0d\u5b58\u5728 +common.fileShare=\u6587\u6a94\u5206\u4eab +common.logining=\u767b\u9304\u4e2d... +common.loginTokenError=\u767b\u9304\u5df2\u5931\u6548��\u8acb\u91cd\u65b0\u767b\u9304! +common.loginSuccess=\u767b\u9304\u6210\u529f�� +common.loginError=\u767b\u9304\u5931\u6557 +common.connectSuccess=\u9023\u63a5\u6210\u529f�� +common.bindSuccess=\u7d81\u5b9a\u6210\u529f�� +common.bindError=\u7d81\u5b9a\u5931\u6557 +common.clear=\u6e05\u7a7a +common.congrats=\u606d\u559c�� +common.sorry=\u62b1\u6b49�� +common.invalid=\u7121\u6548\u7684 +common.unavailable=\u4e0d\u53ef\u7528 +common.format=\u683c\u5f0f +common.noPermission=\u6c92\u6709\u6b0a\u9650 +common.allPermission=\u6240\u6709\u6b0a\u9650 +common.invalidParam=\u7121\u6548\u7684\u53c3\u6578 +common.invalidFormat=\u7121\u6548\u7684\u683c\u5f0f +common.invalidRequest=\u4e0d\u5408\u6cd5\u7684\u8acb\u6c42\u985e\u578b +common.illegalRequest=\u975e\u6cd5\u8acb\u6c42 +common.expiredRequest=\u8acb\u6c42\u5df2\u5931\u6548 +common.errorExpiredRequest=\u7121\u6548\u7684\u8acb\u6c42\u6216\u5df2\u7d93\u5931\u6548 +common.migrating=\u6b63\u5728\u9077\u79fb +common.migrated=\u9077\u79fb\u5b8c\u6210 +common.maintenanceTips=\u7cfb\u7d71\u7dad\u8b77\u4e2d��\u8acb\u7a0d\u5f8c\u8a2a\u554f���� +common.done=\u5df2\u5b8c\u6210 +common.disabled=\u5df2\u7981\u7528 +common.sizeTotal=\u7e3d\u5927\u5c0f +common.sqlStatement=[SQL\u8a9e\u53e5]: +common.env.check=\u74b0\u5883\u6aa2\u6e2c +common.env.errorLib=PHP\u5eab\u7f3a\u5931 +common.env.errorIgnore=\u5ffd\u7565\u4e26\u9032\u5165 +common.env.errorVersion=PHP\u7248\u672c\u4e0d\u80fd\u4f4e\u65bc5.0 +common.env.errorPath=\u4e0d\u53ef\u5beb +common.env.errorListDir=\u60a8\u7684web\u670d\u52d9\u5668\u958b\u555f\u4e86\u5217\u76ee\u9304\u529f\u80fd��\u70ba\u5b89\u5168\u8003\u616e\u8acb\u7981\u7528\u8a72\u529f\u80fd��\u8acb\u95dc\u9589\u7de9\u5b58��\u6216\u7a0d\u5f8c1\u5206\u9418\u5237\u65b0\u9801\u9762\u518d\u8a66��
    (\u6aa2\u67e5DATA_PATH); +common.env.pathPermissionError=[ErrorCode:1002]\u76ee\u9304\u6b0a\u9650\u932f\u8aa4��\u8acb\u8a2d\u7f6e\u7a0b\u5e8f\u76ee\u9304\u53ca\u6240\u6709\u5b50\u76ee\u9304\u70ba\u8b80\u5beb\u72c0\u614b��
    linux\u904b\u884c\u5982\u4e0b\u6307\u4ee4��
    su-c'setenforce0'
    chmod-R777 +common.version.free=\u514d\u8cbb +common.version.nameQ=\u4f01\u696d\u7248 +common.version.vipFree=\u514d\u8cbb\u7248 +common.version.useFree=\u7e7c\u7e8c\u4f7f\u7528\u514d\u8cbb\u7248 +common.version.notSupport=\u60a8\u7684\u7248\u672c\u4e0d\u652f\u6301\u6b64\u64cd\u4f5c��\u8acb\u5230\u5b98\u7db2\u8cfc\u8cb7\u9ad8\u7d1a\u7248\u672c�� +common.version.notSupportNumber=\u7531\u65bc\u6578\u91cf\u9650\u5236\u4e0d\u652f\u6301\u6b64\u64cd\u4f5c��\u8acb\u5230\u5b98\u7db2\u8cfc\u8cb7\u9ad8\u7d1a\u7248\u672c�� +common.version.toVip=\u5347\u7d1a\u70ba\u5546\u696d\u7248 +common.version.license=\u8cfc\u8cb7\u6388\u6b0a +common.version.authCode=\u6388\u6b0a\u6fc0\u6d3b\u78bc +common.version.authActive=\u6fc0\u6d3b\u6388\u6b0a +common.version.authorization=\u8a3b\u518a\u6388\u6b0a +common.version.authorizeSuccess=\u606d\u559c\u60a8��\u5728\u7dda\u5347\u7d1a\u6388\u6b0a\u6210\u529f�� +common.version.networkError=\u8acb\u6c42\u670d\u52d9\u5668\u5931\u6557��\u6aa2\u67e5\u670d\u52d9\u5668\u662f\u5426\u80fd\u8a2a\u554f\u7db2\u7d61��
    \u6ce8:\u670d\u52d9\u5668\u4e0d\u80fd\u662f\u4ee3\u7406\u4e0a\u7db2 +common.version.authActiveOnline=\u5728\u7dda\u6fc0\u6d3b +common.version.authActiveOffline=\u96e2\u7dda\u6fc0\u6d3b +common.version.offlineTips=\u670d\u52d9\u5668\u4e0d\u80fd\u8a2a\u554f\u5916\u7db2? +common.version.menuTitle=\u4f01\u696d\u4fe1\u606f\u8a2d\u7f6e +common.version.timeout=\u5df2\u904e\u671f +common.version.timeToService=\u670d\u52d9\u5230\u671f\u6642\u9593 +common.version.timeTo=\u6388\u6b0a\u5230\u671f\u6642\u9593 +common.version.licenseAll=\u6c38\u4e45\u6388\u6b0a +common.version.kodVersion=\u7a0b\u5e8f\u7248\u672c +common.version.userLimitTitle=\u7528\u6236\u6578 +common.version.userUse=\u5df2\u6709\u7528\u6237\u6570 +common.version.userAllow=\u652f\u6301\u7528\u6236\u6578 +common.version.userTo=\u6388\u6b0a\u5c0d\u8c61 +common.version.userTitle=\u6388\u6b0a\u4fe1\u606f +common.version.basicInfo=\u57fa\u790e\u4fe1\u606f +common.version.appInfo=\u7522\u54c1\u4fe1\u606f +common.version.tipsWarning=\u8b66\u544a\u8acb\u52ff\u64c5\u81ea\u4fee\u6539\u7248\u6b0a;\u5982\u6709\u9700\u8981\u8acb\u806f\u7e6b\u8cfc\u8cb7�� +common.version.tipsCopyLink=\u8907\u88fd\u6210\u529f!\u53ef\u7c98\u8cbc\u4fdd\u5b58\u5230txt\u6587\u4ef6
    \u901a\u904eU\u76e4\u7b49\u65b9\u5f0f\u5728\u6709\u7db2\u7684\u96fb\u8166\u6253\u958b\u6b64\u93c8\u63a5 +common.version.tipsHistory=\u514d\u8cbb\u7248\u53ea\u652f\u63015\u500b\u6b77\u53f2\u8a18\u9304\u7248\u672c;\u8cfc\u8cb7\u6388\u6b0a\u7248\u4e0d\u9650\u6578\u91cf! +common.version.codeLink=\u6388\u6b0a\u8a8d\u8b49\u78bc\u8acb\u6c42\u93c8\u63a5 +common.version.codeLinkHelp=1.\u62f7\u8c9d\u4e0a\u9762\u93c8\u5230\u5176\u4ed6\u6709\u7db2\u7684\u96fb\u8166\u8a2a\u554f.
    2.\u5c07\u7372\u5f97\u7684"\u6388\u6b0a\u8a8d\u8b49\u78bc"\u586b\u5beb\u5230\u4e0a\u9762\u7136\u5f8c\u9032\u884c\u6fc0\u6d3b\u6388\u6b0a +common.copyright.logoTitle=\u4f01\u696d\u5f62\u8c61logo\u8a2d\u7f6e +common.copyright.licenseInfo=\u6388\u6b0a\u4fe1\u606f +common.copyright.licenseReset=\u91cd\u65b0\u6388\u6b0a +common.copyright.licenseResetTips=\u91cd\u65b0\u6fc0\u6d3b\u7372\u53d6\u66f4\u591a\u4fe1\u606f! +common.copyright.formLogo=\u767b\u9304\u9801logo\u985e\u578b +common.copyright.formLogoTypeWord=\u6587\u5b57logo +common.copyright.formLogoTypeImage=\u5716\u7247logo +common.copyright.formLogoDesc=\u6587\u5b57logo\u5247\u4f7f\u7528\u516c\u53f8\u540d\u7a31\u5716\u7247logo\u5247\u4f7f\u7528\u5982\u4e0b\u8a2d\u7f6e\u7684\u5716\u7247. +common.copyright.formLogoImage=\u767b\u9304\u9801\u9762logo\u5716\u7247 +common.copyright.formLogoImageDesc=\u767b\u9304\u9801\u9762\u548c\u7ba1\u7406\u5f8c\u53f0logo\u63a8\u85a6\u5c3a\u5bf8250x100\u534a\u900f\u660epng\u683c\u5f0f +common.copyright.formLogoMain=\u4e3b\u754c\u9762\u83dc\u55aelogo +common.copyright.formLogoMainDesc=\u6587\u4ef6\u7ba1\u7406\u5de6\u4e0a\u89d2logo\u63a8\u85a6\u5c3a\u5bf8200x200\u767d\u8272\u534a\u900f\u660epng\u683c\u5f0f +common.copyright.formPowerByInfo=\u516c\u53f8\u7248\u6b0a\u4fe1\u606f\u8a2d\u7f6e +common.copyright.formPowerBy=\u5e95\u90e8\u7248\u6b0a\u516c\u53f8\u540d +common.copyright.formHomePage=\u5e95\u90e8\u7248\u6b0a\u93c8\u63a5\u8df3\u8f49 +common.copyright.formConcat=\u5f48\u51fa\u5c64\u806f\u7e6b\u65b9\u5f0f +common.copyright.formDesc=\u7522\u54c1\u5f48\u51fa\u5c64\u8a73\u7d30\u8aaa\u660e +common.copyright.formDescTips=\u4fee\u6539\u4fdd\u5b58\u5f8c\u5237\u65b0\u9801\u9762\u751f\u6548 +common.copyright.formMetaKeywords=\u7ad9\u9ede\u95dc\u9375\u8a5e(\u641c\u7d22\u5f15\u64ce\u4f7f\u7528) +common.copyright.formMetaName=\u7ad9\u9ede\u540d(\u641c\u7d22\u5f15\u64ce\u4f7f\u7528) +common.copyright.downloadApp=App\u4e0b\u8f09 +common.copyright.downloadLink= +common.copyright.about=\u95dc\u65bc +common.copyright.desc= +common.copyright.contact= +common.copyright.homepage= +common.copyright.name= +common.copyright.nameTitle=\u53ef\u9053\u4e91 +common.copyright.nameDesc=\u53ef\u9053\u4e91?\u8cc7\u6e90\u7ba1\u7406\u5668 +common.copyright.powerBy=- +common.copyright.metaKeywords= +common.copyright.metaName= +common.charset.AUTO=\u81ea\u52d5\u8b58\u5225 +common.charset.UTF_8=Unicode +common.charset.UTF_16=Unicode +common.charset.CP1256=\u963f\u62c9\u4f2f\u6587 +common.charset.ISO_8859_6=\u963f\u62c9\u4f2f\u6587 +common.charset.ISO_8859_10=\u5317\u6b50\u8a9e\u8a00 +common.charset.CP1257=\u6ce2\u7f85\u7684\u6d77\u5468\u908a\u8a9e\u8a00 +common.charset.ISO_8859_13=\u6ce2\u7f85\u7684\u6d77\u5468\u908a\u8a9e\u8a00 +common.charset.ISO_8859_4=\u6ce2\u7f85\u7684\u6d77\u5468\u908a\u8a9e\u8a00 +common.charset.BIG5_HKSCS=\u7e41\u9ad4-\u9999\u6e2f +common.charset.BIG5=\u7e41\u9ad4-\u53f0\u7063 +common.charset.Georgian_Academy=\u683c\u9b6f\u5409\u4e9e\u6587 +common.charset.PT154=\u54c8\u85a9\u514b\u6587 +common.charset.CP949=\u97d3\u8a9e +common.charset.EUC_KR=\u97d3\u8a9e +common.charset.GB18030=\u7c21\u9ad4\u4e2d\u6587 +common.charset.GBK=\u7c21\u9ad4\u4e2d\u6587 +common.charset.ISO_8859_14=\u51f1\u723e\u7279\u8a9e +common.charset.CP1133=\u8001\u64be\u6587 +common.charset.ISO_8859_16=\u7f85\u99ac\u5c3c\u4e9e\u6587 +common.charset.ISO_8859_3=\u5357\u6b50\u8a9e\u8a00 +common.charset.EUC_JP=\u65e5\u6587 +common.charset.ISO_2022_JP=\u65e5\u6587 +common.charset.SHIFT_JIS=\u65e5\u6587 +common.charset.KOI8_T=\u5854\u5409\u514b\u8a9e +common.charset.ISO_8859_11=\u6cf0\u6587 +common.charset.TIS_620=\u6cf0\u6587 +common.charset.CP1254=\u571f\u8033\u5176\u6587 +common.charset.CP1251=\u897f\u91cc\u723e\u8a9e +common.charset.ISO_8859_5=\u897f\u91cc\u723e\u8a9e +common.charset.KOI8_R=\u897f\u91cc\u723e\u8a9e +common.charset.KOI8_U=\u897f\u91cc\u723e\u8a9e +common.charset.CP1252=\u897f\u6b50\u8a9e\u8a00 +common.charset.ISO_8859_1=\u897f\u6b50\u8a9e\u8a00 +common.charset.ISO_8859_15=\u897f\u6b50\u8a9e\u8a00 +common.charset.Macintosh=\u897f\u6b50\u8a9e\u8a00 +common.charset.CP1255=\u5e0c\u4f2f\u4f86\u6587 +common.charset.ISO_8859_8=\u5e0c\u4f2f\u4f86\u6587 +common.charset.CP1253=\u5e0c\u81d8\u6587 +common.charset.ISO_8859_7=\u5e0c\u81d8\u6587 +common.charset.ARMSCII_8=\u4e9e\u7f8e\u5c3c\u4e9e\u6587 +common.charset.CP1258=\u8d8a\u5357\u6587 +common.charset.VISCII=\u8d8a\u5357\u6587 +common.charset.CP1250=\u4e2d\u6b50\u8a9e\u8a00 +common.charset.ISO_8859_2=\u4e2d\u6b50\u8a9e\u8a00 +common.charset.defaultSet=\u6587\u4ef6\u7de8\u78bc +common.charset.convertSave=\u8f49\u63db\u7de8\u78bc\u70ba +common.date.near=\u525b\u525b +common.date.miniteBefore=\u5206\u9418\u524d +common.date.today=\u4eca\u5929 +common.date.yestoday=\u6628\u5929 +common.date.before=\u4ee5\u524d +common.faceDefault=\u9ed8\u8a8d\u8868\u60c5 +common.loadMore=\u52a0\u8f09\u66f4\u591a +common.numberLimit=\u6570\u91cf\u8d85\u51fa\u6700\u5927\u9650\u5236! +common.lengthLimit=\u957f\u5ea6\u8d85\u51fa\u6700\u5927\u9650\u5236! +common.task.name=\u4efb\u52d9\u7ba1\u7406\u5668 +common.task.title=\u4efb\u52d9\u540d\u7a31 +common.task.user=\u57f7\u884c\u7528\u6236 +common.task.porcess=\u9032\u5ea6 +common.task.start=\u958b\u59cb\u4efb\u52d9 +common.task.useTime=\u5df2\u57f7\u884c\u6642\u9593 +common.task.running=\u57f7\u884c\u4e2d +common.task.stoping=\u66ab\u505c\u4e2d +common.task.killing=\u6b63\u5728\u7d50\u675f +common.task.stop=\u66ab\u505c\u4efb\u52d9 +common.task.kill=\u7d50\u675f\u4efb\u52d9 +common.task.removeTips=\u78ba\u5b9a\u7d50\u675f\u8a72\u64cd\u4f5c? +common.task.killAll=\u7d50\u675f\u6240\u6709 +common.task.killAllTips=\u78ba\u5b9a\u7d50\u675f\u6240\u6709\u4efb\u52d9? +common.task.timeStart=\u958b\u59cb\u65bc +common.task.timeNeed=\u5269\u9918\u7d04 +common.task.timeUse=\u5df2\u904b\u884c +ERROR_DB_PWD=\u6578\u64da\u5eab\u8a2a\u554f\u88ab\u62d2\u7d55��\u7528\u6236\u540d\u6216\u5bc6\u78bc\u932f\u8aa4�� +ERROR_DB_TIMEOUT=\u6578\u64da\u5eab\u9023\u63a5\u8d85\u6642��\u8acb\u6aa2\u67e5\u5730\u5740\u662f\u5426\u6b63\u78ba�� +ERROR_DB_CONN_RFS=\u6578\u64da\u5eab\u9023\u63a5\u88ab\u62d2\u7d55��\u914d\u7f6e\u4fe1\u606f\u6709\u8aa4��\u6216\u670d\u52d9\u672a\u555f\u52d5�� +ERROR_DB_ADR=\u6578\u64da\u5eab\u9023\u63a5\u932f\u8aa4��\u8acb\u6aa2\u67e5\u5730\u5740\u662f\u5426\u6b63\u78ba�� +ERROR_DB_NOT_SUPPORT=\u4e0d\u652f\u6301\u7684\u6578\u64da\u5eab\u985e\u578b��\u8acb\u6aa2\u67e5\u5c0d\u61c9\u670d\u52d9��\u6216\u914d\u7f6e\u6587\u4ef6\u662f\u5426\u6b63\u5e38�� +ERROR_DB_XS_DENNIED=\u6578\u64da\u5eab\u8a2a\u554f\u88ab\u62d2\u7d55��\u6b0a\u9650\u4e0d\u8db3�� +ERROR_DB_NOT_EXIST=\u6578\u64da\u5eab\u4e0d\u5b58\u5728��\u6216\u6307\u5b9a\u540d\u7a31\u932f\u8aa4�� +explorer.----=---- +explorer.pathNotSupport=\u6b64\u985e\u578b\u76ee\u9304\u4e0d\u652f\u6301\u8a72\u64cd\u4f5c! +explorer.pathIsRoot=\u5df2\u7d93\u5230\u6839\u76ee\u9304\u4e86! +explorer.pathNull=\u6587\u4ef6\u593e\u70ba\u7a7a +explorer.zipFileLarge=\u8a72\u6587\u4ef6\u592a\u5927��\u8acb\u89e3\u58d3\u5f8c\u518d\u9032\u884c\u9810\u89bd\u64cd\u4f5c�� +explorer.charNoSupport=\u4e0d\u652f\u6301\u7684\u7279\u6b8a\u5b57\u7b26: +explorer.moveError=\u79fb\u52d5\u5931\u6557 +explorer.lockError=\u51fa\u932f\u4e86\u4e26\u767c\u9396\u5b9a\u8d85\u6642 +explorer.lockErrorDesc=\u8bf7\u7a0d\u540e\u518d\u8bd5(\u53ef\u964d\u4f4e\u8bf7\u6c42\u9891\u7387\u4f18\u5316\u5e76\u53d1\u76f8\u5173\u914d\u7f6e). +explorer.moveSubPathError=\u51fa\u932f\u4e86��\u7236\u76ee\u9304\u4e0d\u80fd\u79fb\u52d5\u5230\u5b50\u76ee\u9304�� +explorer.spaceIsFull=\u5269\u9918\u7a7a\u9593\u4e0d\u8db3\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1! +explorer.sessionSaveError=session\u5beb\u5165\u5931\u6557!\u8acb\u67e5\u770b\u78c1\u76e4\u662f\u5426\u5df2\u6eff\u6216\u8aee\u8a62\u670d\u52d9\u5546�� +explorer.networkError=\u7db2\u7d61\u9023\u63a5\u932f\u8aa4(net::ERR_CONNECTION_RESET)��\u9023\u63a5\u5df2\u91cd\u7f6e.
    \u8acb\u806f\u7e6b\u4e3b\u6a5f\u5546\u6216\u7db2\u7ba1��\u6aa2\u67e5\u9632\u706b\u7246\u914d\u7f6e�� +explorer.folderManage=\u7ba1\u7406\u76ee\u9304 +explorer.clickEdit=\u9ede\u64ca\u9032\u5165\u7de8\u8f2f\u72c0\u614b +explorer.shortLink=\u5feb\u6377\u65b9\u5f0f +explorer.upper=\u4e0a\u5c64 +explorer.historyNext=\u524d\u9032 +explorer.historyBack=\u5f8c\u9000 +explorer.loading=\u64cd\u4f5c\u4e2d... +explorer.getting=\u7372\u53d6\u4e2d... +explorer.sending=\u6578\u64da\u767c\u9001\u4e2d... +explorer.pullTips=\u4e0b\u62c9\u4ee5\u5237\u65b0\u9801\u9762 +explorer.pullDropTips=\u91cb\u653e\u4ee5\u5237\u65b0\u9801\u9762 +explorer.getSuccess=\u7372\u53d6\u6210\u529f! +explorer.saveSuccess=\u4fdd\u5b58\u6210\u529f! +explorer.saveError=\u4fdd\u5b58\u5931\u6557�� +explorer.success=\u64cd\u4f5c\u6210\u529f +explorer.error=\u64cd\u4f5c\u5931\u6557 +explorer.dataError=\u6578\u64da\u7570\u5e38�� +explorer.pathError=\u6587\u6a94\u8def\u5f91\u932f\u8aa4 +explorer.repeatError=\u64cd\u4f5c\u5931\u6557��\u8a72\u540d\u7a31\u5df2\u5b58\u5728�� +explorer.systemError=\u7cfb\u7d71\u932f\u8aa4 +explorer.mistake=\u51fa\u932f\u4e86�� +explorer.recycleClear=\u6e05\u7a7a\u56de\u6536\u7ad9 +explorer.recycleClearForce=\u56de\u6536\u7ad9\u5167\u5bb9\u904e\u591a\u8acb\u5148\u6e05\u7a7a\u56de\u6536\u7ad9! +explorer.recycleRestore=\u9084\u539f\u56de\u6536\u7ad9 +explorer.recycleRestoreItem=\u9084\u539f +explorer.recycleRestoreAll=\u5168\u90e8\u9084\u539f +explorer.recycleClearInfo=\u60a8\u78ba\u5b9a\u8981\u5fb9\u5e95\u6e05\u7a7a\u56de\u6536\u7ad9\u55ce�� +explorer.zipDownloadReady=\u58d3\u7e2e\u5f8c\u6703\u81ea\u52d5\u4e0b\u8f09\u8acb\u7a0d\u5f8c... +explorer.removeItem=\u9805\u5167\u5bb9 +explorer.uploading=\u4e0a\u50b3\u4e2d +explorer.uploadTipsMore=\u6587\u4ef6\u904e\u591a\u5efa\u8b70\u58d3\u7e2e\u5f8c\u4e0a\u50b3\u7136\u5f8c\u5728\u7dda\u89e3\u58d3�� +explorer.uploadingMove=\u5408\u4f75\u8f49\u5b58\u4e2d... +explorer.viewNewPage=\u65b0\u9801\u9762\u9810\u89bd +explorer.unknowFileTitle=\u6587\u4ef6\u6253\u958b\u63d0\u793a! +explorer.unknowFileTips=\u6c92\u6709\u652f\u6301\u6b64\u6587\u4ef6\u7684\u61c9\u7528��\u60a8\u53ef\u4ee5�� +explorer.unknowAppTips=\u6c92\u6709\u8a72\u61c9\u7528: +explorer.unknowFileTry=\u5617\u8a66 +explorer.unknowFileDown=\u4e0b\u8f09\u8a72\u6587\u4ef6 +explorer.authFileDown=\u6587\u4ef6\u4e0b\u8f09 +explorer.authShare=\u5171\u4eab +explorer.usersShare=\u7684\u5171\u4eab +explorer.clipboard=\u67e5\u770b\u526a\u8cbc\u677f +explorer.clipboardClear=\u6e05\u7a7a\u526a\u8cbc\u677f +explorer.fullScreen=\u5168\u5c4f +explorer.folderItem=\u500b\u9805\u76ee +explorer.folderItemSelect=\u500b\u9078\u4e2d +explorer.dbLoadAll=\u96d9\u64ca\u52a0\u8f09\u5168\u90e8���� +explorer.ziping=\u6b63\u5728\u58d3\u7e2e... +explorer.unziping=\u6b63\u5728\u89e3\u58d3... +explorer.zipingTips=\u58d3\u7e2e\u64cd\u4f5c\u4e2d\u8acb\u7a0d\u5f8c... +explorer.unzipingTips=\u89e3\u58d3\u64cd\u4f5c\u4e2d\u8acb\u7a0d\u5f8c... +explorer.unzipRarTips=\u6587\u4ef6\u5167\u5bb9\u640d\u58de\u6216\u4e0d\u652f\u6301\u8a72\u6587\u4ef6\u89e3\u6790��\u63a8\u85a6\u4f7f\u7528ZIP\u683c\u5f0f�� +explorer.parsing=\u89e3\u6790\u7372\u53d6\u4e2d... +explorer.moving=\u79fb\u52d5\u64cd\u4f5c\u4e2d... +explorer.copyMove=\u8907\u88fd\u79fb\u52d5 +explorer.removeTitle=\u522a\u9664\u78ba\u8a8d +explorer.removeInfo=\u78ba\u8a8d\u522a\u9664\u9078\u4e2d\u5167\u5bb9\u55ce�� +explorer.removeTitleForce=\u6c38\u4e45\u522a\u9664 +explorer.removeInfoForce=\u78ba\u5b9a\u8981\u6c38\u4e45\u522a\u9664\u6b64\u6587\u6a94\u55ce�� +explorer.pathInRecycle=\u8a72\u6587\u4ef6\u593e\u5728\u56de\u6536\u7ad9\u4e2d\u8acb\u9084\u539f\u5f8c\u518d\u8a66! +explorer.pathInRecycleFile=\u8a72\u6587\u4ef6\u5728\u56de\u6536\u7ad9\u4e2d\u8acb\u9084\u539f\u5f8c\u518d\u8a66! +explorer.downOffline=\u96e2\u7dda\u4e0b\u8f09 +explorer.savePath=\u4fdd\u5b58\u8def\u5f91 +explorer.uploadSelectMuti=\u53ef\u9078\u64c7\u591a\u500b\u6587\u4ef6\u4e0a\u50b3 +explorer.goTo=\u8df3\u8f49\u5230 +explorer.selectFile=\u9078\u64c7\u6587\u4ef6 +explorer.selectFolder=\u9078\u64c7\u6587\u4ef6\u593e +explorer.selectImage=\u8acb\u9078\u64c7\u5716\u7247... +explorer.selectValidFolder=\u8acb\u9078\u64c7\u8981\u6709\u6548\u7684\u6587\u4ef6\u593e! +explorer.selectFolderFile=\u9078\u64c7\u6587\u4ef6\u6216\u6587\u4ef6\u593e +explorer.selectMulti=\u591a\u9078 +explorer.notNull=\u5fc5\u586b\u9805\u4e0d\u80fd\u70ba\u7a7a! +explorer.picCannotNull=\u5716\u7247\u5730\u5740\u4e0d\u80fd\u70ba\u7a7a! +explorer.renameSuccess=\u91cd\u547d\u540d\u6210\u529f�� +explorer.inputSearchWords=\u8acb\u8f38\u5165\u8981\u641c\u7d22\u7684\u5b57\u7b26\u4e32 +explorer.search.optionContent=\u6587\u4ef6\u5167\u5bb9 +explorer.search.searchContentTips=\u95dc\u9375\u5b57\u641c\u7d22\u6587\u4ef6\u5167\u5bb9\u652f\u6301\u6587\u672c\u6587\u4ef6 +explorer.search.optionMutil=\u6279\u91cf\u641c\u7d22 +explorer.search.optionMutilDesc=\u6bcf\u884c\u4e00\u500b\u641c\u7d22\u8a5e\u641c\u7d22\u7d50\u679c\u6839\u64da\u641c\u7d22\u8a5e\u9032\u884c\u6392\u5e8f +explorer.removeSuccess=\u522a\u9664\u6210\u529f�� +explorer.removeFail=\u522a\u9664\u5931\u6557! +explorer.clipboardNull=\u526a\u8cbc\u677f\u70ba\u7a7a�� +explorer.createSuccess=\u65b0\u5efa\u6210\u529f�� +explorer.createError=\u65b0\u5efa\u5931\u6557\u8acb\u6aa2\u67e5\u76ee\u9304\u6b0a\u9650�� +explorer.copySuccess=��\u8907\u88fd������\u8986\u84cb\u526a\u8cbc\u677f\u6210\u529f! +explorer.cuteSuccess=��\u526a\u5207������\u8986\u84cb\u526a\u8cbc\u677f\u6210\u529f! +explorer.clipboardState=\u526a\u5207\u677f\u72c0\u614b: +explorer.copyOK=\u5df2\u5fa9\u88fd\u6210\u529f! +explorer.copyNotExists=\u4f86\u6e90\u4e0d\u5b58\u5728 +explorer.currentHasParent=\u76ee\u6a19\u6587\u4ef6\u593e\u662f\u6e90\u6587\u4ef6\u593e\u7684\u5b50\u6587\u4ef6\u593e! +explorer.pastSuccess=\u7c98\u8cbc\u64cd\u4f5c\u5b8c\u6210 +explorer.cutePastSuccess=\u526a\u5207\u64cd\u4f5c\u5b8c\u6210 +explorer.zipSuccess=\u58d3\u7e2e\u5b8c\u6210 +explorer.notZip=\u4e0d\u662f\u58d3\u7e2e\u6587\u4ef6 +explorer.zipNull=\u6c92\u6709\u9078\u64c7\u7684\u6587\u4ef6\u6216\u76ee\u9304 +explorer.unzipSuccess=\u89e3\u58d3\u5b8c\u6210 +explorer.pathIsCurrent=\u6240\u6253\u958b\u8def\u5f91\u548c\u7576\u524d\u8def\u5f91\u4e00\u6a23�� +explorer.pathExists=\u8a72\u540d\u7a31\u5df2\u5b58\u5728�� +explorer.serverDownDesc=\u500b\u4efb\u52d9\u52a0\u5165\u5230\u4e0b\u8f09\u5217\u8868 +explorer.parentPermission=\u7236\u76ee\u9304\u6b0a\u9650 +explorer.confirm=\u78ba\u5b9a\u9032\u884c\u8a72\u64cd\u4f5c�� +explorer.ifSaveFileTips=\u6709\u6587\u4ef6\u672a\u4fdd\u5b58\u78ba\u5b9a\u95dc\u9589\u7a97\u53e3�� +explorer.ifSaveFile=\u6587\u4ef6\u5c1a\u672a\u4fdd\u5b58\u662f\u5426\u4fdd\u5b58�� +explorer.ifStopUploadTips=\u6709\u6587\u4ef6\u6b63\u5728\u4e0a\u50b3\u4e2d\u78ba\u5b9a\u95dc\u9589\u7a97\u53e3�� +explorer.noPermissionRead=\u60a8\u6c92\u6709\u8b80\u53d6\u6b0a\u9650�� +explorer.noPermissionDownload=\u60a8\u6c92\u6709\u4e0b\u8f09\u6b0a\u9650�� +explorer.noPermissionWrite=\u8a72\u76ee\u9304\u6c92\u6709\u5beb\u6b0a\u9650 +explorer.noPermissionAction=\u60a8\u6c92\u6709\u6b64\u6b0a\u9650��\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1! +explorer.noPermissionWriteAll=\u8a72\u6587\u4ef6\u6216\u76ee\u9304\u6c92\u6709\u5beb\u6b0a\u9650 +explorer.noPermissionWriteFile=\u8a72\u6587\u4ef6\u6c92\u6709\u5beb\u6b0a\u9650 +explorer.noPermissionReadAll=\u8a72\u6587\u4ef6\u6216\u76ee\u9304\u6c92\u6709\u8b80\u6b0a\u9650 +explorer.noPermission=\u7ba1\u7406\u54e1\u7981\u6b62\u4e86\u6b64\u6b0a\u9650! +explorer.noPermissionExt=\u7ba1\u7406\u54e1\u7981\u6b62\u4e86\u8a72\u985e\u578b\u6587\u4ef6\u6b0a\u9650 +explorer.noPermissionGroup=\u60a8\u4e0d\u5728\u8a72\u7528\u6236\u7d44! +explorer.pathNoWrite=\u76ee\u9304\u4e0d\u53ef\u5beb\u8acb\u5c07\u8a72\u76ee\u9304\u53ca\u6240\u6709\u5b50\u76ee\u9304\u8a2d\u7f6e\u70ba\u53ef\u8b80\u5beb\u5f8c\u518d\u8a66�� +explorer.onlyReadDesc=\u8a72\u76ee\u9304\u6c92\u6709\u5beb\u6b0a\u9650\u53ef\u4ee5\u5728\u670d\u52d9\u5668\u8a2d\u7f6e\u6b64\u76ee\u9304\u7684\u6b0a\u9650 +explorer.settingSuccess=\u4fee\u6539\u5df2\u751f\u6548�� +explorer.noRepeat=\u4e0d\u5141\u8a31\u91cd\u8907 +explorer.dataNotFull=\u6578\u64da\u63d0\u4ea4\u4e0d\u5b8c\u6574�� +explorer.tooManyToView=\u5305\u542b\u5167\u5bb9\u592a\u591a(%s\u9805)��\u8acb\u5728\u672c\u5730\u6253\u958b\u67e5\u770b; +explorer.jumpAfterWhile=%ss\u5f8c\u81ea\u52d5\u8df3\u8f49\u8acb\u624b\u52d5\u9078\u64c7 +explorer.cuteToThe=\u79fb\u52d5\u5230�� +explorer.copyToThe=\u8907\u88fd\u5230�� +explorer.addToFav=\u6dfb\u52a0\u5230\u6536\u85cf\u593e +explorer.addFav=\u6dfb\u52a0\u6536\u85cf +explorer.delFav=\u53d6\u6d88\u6536\u85cf +explorer.addFavSuccess=\u6dfb\u52a0\u6536\u85cf\u6210\u529f +explorer.pathHasFaved=\u8a72\u8def\u5f91\u5df2\u6536\u85cf +explorer.delFavSuccess=\u53d6\u6d88\u6536\u85cf\u6210\u529f +explorer.fileLock=\u7de8\u8f2f\u9396\u5b9a +explorer.fileLockNow=\u9396\u5b9a +explorer.fileLockCancle=\u53d6\u6d88\u9396\u5b9a +explorer.fileLockTitle=\u5df2\u9396\u5b9a +explorer.fileLockTips=\u5df2\u9396\u5b9a(\u5176\u4ed6\u4eba\u4e0d\u80fd\u7de8\u8f2f\u8a72\u6587\u4ef6) +explorer.fileLockUser=\u9396\u5b9a\u8005 +explorer.fileLockError=\u7576\u524d\u6587\u4ef6\u70ba\u9396\u5b9a\u72c0\u614b\u8acb\u806f\u7e6b\u9396\u5b9a\u8005\u89e3\u9396\u5f8c\u518d\u8a66; +explorer.downloaded=\u4e0b\u8f09\u5b8c\u6210 +explorer.openAutoTips=\u5373\u5c07\u81ea\u52d5\u6253\u958b +explorer.historyAutoTips=\u81ea\u52d5\u751f\u6210\u6b77\u53f2\u7248\u672c +explorer.saved=\u4fdd\u5b58\u6210\u529f +explorer.opened=\u6253\u958b\u6210\u529f�� +explorer.openFail=\u6253\u958b\u5931\u6557�� +explorer.openingWithLoc=\u6587\u4ef6\u672c\u5730\u6253\u958b\u4e2d... +explorer.openOnlyView=\u53ea\u8b80\u6a21\u5f0f\u6253\u958b +explorer.saving=\u6587\u4ef6\u4fdd\u5b58\u4e2d... +explorer.notSupport=\u51fa\u932f\u4e86\u4e0d\u652f\u6301\u8a72\u5167\u5bb9\u683c\u5f0f! +explorer.unzipErrorTips=\u51fa\u932f\u4e86��\u672a\u8b58\u5225\u7684\u58d3\u7e2e\u6587\u4ef6\u683c\u5f0f��
    \u8acb\u6aa2\u67e5\u8a72\u6587\u4ef6\u662f\u5426\u70ba\u58d3\u7e2e\u6587\u4ef6\u6216\u8005\u662f\u5426\u640d\u58de�� +explorer.wordLoading=\u52a0\u8f09\u4e2d... +explorer.noFunction=\u6c92\u6709\u8a72\u65b9\u6cd5�� +explorer.paramFormatError=\u53c3\u6578\u683c\u5f0f\u932f\u8aa4�� +explorer.descTooLong=\u63cf\u8ff0\u9577\u5ea6\u904e\u9577 +explorer.noMoreThan=\u4e0d\u8d85\u904e +explorer.desktopDelError=\u62b1\u6b49\u684c\u9762\u6587\u4ef6\u593e\u4e0d\u652f\u6301\u522a\u9664�� +explorer.copy=\u8907\u88fd +explorer.past=\u7c98\u8cbc +explorer.clone=\u5275\u5efa\u526f\u672c +explorer.cute=\u526a\u5207 +explorer.cuteTo=\u79fb\u52d5\u5230... +explorer.copyTo=\u8907\u88fd\u5230... +explorer.info=\u5c6c\u6027 +explorer.searchInPath=\u6587\u4ef6\u593e\u4e2d\u641c\u7d22 +explorer.addToPlay=\u6dfb\u52a0\u5230\u64ad\u653e\u5217\u8868 +explorer.manageFav=\u7ba1\u7406\u6536\u85cf\u593e +explorer.refreshTree=\u5237\u65b0\u6a39\u76ee\u9304 +explorer.zip=\u5275\u5efa\u58d3\u7e2e\u5305 +explorer.unzip=\u89e3\u58d3\u5230... +explorer.unzipFolder=\u89e3\u58d3\u5230\u6587\u4ef6\u593e +explorer.unzipThis=\u89e3\u58d3\u5230\u7576\u524d +explorer.unzipTo=\u89e3\u58d3\u5230... +explorer.openProject=\u7de8\u8f2f\u5668\u6253\u958b\u9805\u76ee +explorer.createLink=\u5275\u5efa\u5feb\u6377\u65b9\u5f0f +explorer.createLinkHome=\u767c\u9001\u5230\u684c\u9762\u5feb\u6377\u65b9\u5f0f +explorer.setBackground=\u8a2d\u7f6e\u70ba\u684c\u9762\u58c1\u7d19 +explorer.favRemove=\u53d6\u6d88\u8a72\u6536\u85cf +explorer.openPath=\u9032\u5165\u6240\u5728\u76ee\u9304 +explorer.openPathFinished=\u5df2\u7d93\u9032\u5165\u6240\u5728\u76ee\u9304 +explorer.openIE=\u700f\u89bd\u5668\u6253\u958b +explorer.newFile=\u65b0\u5efa\u6587\u4ef6 +explorer.newFolder=\u65b0\u5efa\u6587\u4ef6\u593e +explorer.fileSaveTo=\u6587\u4ef6\u4fdd\u5b58\u5230 +explorer.openFather=\u4e0a\u5c64\u6587\u4ef6\u593e\u986f\u793a +explorer.uploadFile=\u4e0a\u50b3\u6587\u4ef6 +explorer.uploadFolder=\u4e0a\u50b3\u6587\u4ef6\u593e +explorer.appOpenDefault=\u8a2d\u7f6e\u9ed8\u8a8d\u6253\u958b +explorer.appOpenAways=\u59cb\u7d42\u4f7f\u7528\u9078\u64c7\u7684\u7a0b\u5e8f\u6253\u958b\u9019\u7a2e\u6587\u4ef6 +explorer.appSelectDesc=\u9078\u64c7\u60a8\u60f3\u7528\u4f86\u6253\u958b\u6b64\u6587\u4ef6\u7684\u7a0b\u5e8f +explorer.appSelectMenu=\u8a2d\u7f6e\u70ba\u9ed8\u8a8d\u6253\u958b\u65b9\u5f0f +explorer.appSelectMenuCancel=\u53d6\u6d88\u8a2d\u7f6e\u70ba\u9ed8\u8a8d\u6253\u958b\u65b9\u5f0f +explorer.appSelectWarning=\u8acb\u9078\u64c7\u61c9\u7528! +explorer.appTypeSupport=\u652f\u6301\u61c9\u7528 +explorer.appTypeAll=\u6240\u6709\u61c9\u7528 +explorer.appSearch=\u641c\u7d22\u76f8\u95dc\u7684\u61c9\u7528\u5b89\u88dd +explorer.recent.createTime=\u5275\u5efa\u65bc +explorer.recent.modifyTime=\u4fee\u6539\u65bc +explorer.recent.viewTime=\u6253\u958b\u65bc +explorer.urlLink=\u5916\u93c8\u5730\u5740 +explorer.downloading=\u4e0b\u8f09\u4e2d... +explorer.downReady=\u5373\u5c07\u4e0b\u8f09 +explorer.downError=\u4e0b\u8f09\u5931\u6557�� +explorer.max=\u6700\u5927\u5316 +explorer.min=\u6700\u5c0f\u5316 +explorer.minAll=\u6700\u5c0f\u5316\u6240\u6709 +explorer.displayAll=\u986f\u793a\u6240\u6709\u7a97\u53e3 +explorer.closeAll=\u95dc\u9589\u6240\u6709 +explorer.authDtl=\u9ede\u64ca\u67e5\u770b\u60a8\u5728\u8a72\u76ee\u9304\u7684\u6b0a\u9650 +explorer.authDialog=\u5167\u90e8\u6210\u54e1��\u6587\u6a94\u5354\u4f5c\u7d1a\u5225\u6b0a\u9650\u8868 +explorer.authNote=\u6ce8:\u7ba1\u7406\u529f\u80fd\u5305\u542b\u8a2d\u7f6e\u6210\u54e1\u6b0a\u9650/\u8a55\u8ad6\u7ba1\u7406\u7b49\u8b39\u614e\u64cd\u4f5c��[\u7cfb\u7d71\u7ba1\u7406\u54e1]\u89d2\u8272\u4e0d\u53d7\u4efb\u4f55\u6b0a\u9650\u9650\u5236 +explorer.auth.toOuter=\u5c0d\u5916\u6388\u6b0a(\u5176\u4ed6\u90e8\u9580\u6216\u7528\u6236) +explorer.auth.share=\u5206\u4eab\u8005 +explorer.auth.owner=\u64c1\u6709\u8005 +explorer.auth.disableDeep=\u7121\u6b0a\u9650-\u50c5\u901a\u8def +explorer.auth.disableDeepDesc=\u56e0\u5b50\u76ee\u9304\u6709\u6587\u6a94\u8b80\u5beb\u6b0a\u9650\u800c\u5efa\u7acb\u7684\u8a2a\u554f\u901a\u8def. +explorer.auth.tips=\u53ef\u806f\u7e6b\u4e0a\u8ff0\u7528\u6236\u7d66\u60a8\u8a2d\u7f6e\u6b0a\u9650 +explorer.notSystemPath=\u4e0d\u662f\u7cfb\u7d71\u6587\u4ef6\u8def\u5f91 +explorer.toolbar.rootPath=\u500b\u4eba\u7a7a\u9593 +explorer.toolbar.fav=\u6536\u85cf\u593e +explorer.toolbar.desktop=\u684c\u9762 +explorer.toolbar.client=\u5ba2\u6236\u7aef +explorer.toolbar.myComputer=\u6211\u7684\u96fb\u8166 +explorer.toolbar.recycle=\u56de\u6536\u7ad9 +explorer.toolbar.myDocument=\u6211\u7684\u6587\u6a94 +explorer.toolbar.myPicture=\u6211\u7684\u7167\u7247 +explorer.toolbar.myMusic=\u6211\u7684\u97f3\u6a02 +explorer.toolbar.myMovie=\u6211\u7684\u8996\u983b +explorer.toolbar.myDownload=\u6211\u7684\u4e0b\u8f09 +explorer.toolbar.uiDesktop=\u684c\u9762 +explorer.toolbar.uiExplorer=\u6587\u4ef6\u7ba1\u7406 +explorer.toolbar.uiEditor=\u7de8\u8f2f\u5668 +explorer.toolbar.uiProjectHome=\u9805\u76ee\u4e3b\u9801 +explorer.toolbar.uiLogout=\u9000\u51fa +explorer.toolbar.uiGroup=\u7d44\u7e54\u67b6\u69cb +explorer.toolbar.myGroup=\u6211\u5728\u7684\u90e8\u9580 +explorer.toolbar.publicPath=\u516c\u5171\u76ee\u9304 +explorer.toolbar.recentDoc=\u6700\u8fd1\u6587\u6a94 +explorer.toolbar.myShare=\u6211\u7684\u5206\u4eab +explorer.toolbar.shareToMe=\u8207\u6211\u5354\u4f5c +explorer.toolbar.shareTo=\u6211\u7684\u5354\u4f5c +explorer.toolbar.shareLink=\u5916\u93c8\u5206\u4eab +explorer.toolbar.photo=\u6211\u7684\u76f8\u518c +explorer.photo.desc=\u7528\u6236\u76f8\u518a\u6b78\u985e +explorer.photo.group=\u76f8\u518a\u5206\u7d44 +explorer.photo.setting=\u76f8\u518c\u8a2d\u7f6e +explorer.photo.pathRoot=\u76f8\u518c\u6383\u63cf\u76ee\u9304 +explorer.photo.pathRootSelect=\u9078\u64c7\u6587\u4ef6\u593e\u4f5c\u70ba\u76f8\u518c\u5716\u7247\u6383\u63cf\u7684\u6839\u76ee\u9304 +explorer.photo.fileType=\u6307\u5b9a\u6587\u4ef6\u985e\u578b +explorer.photo.fileSize=\u6587\u4ef6\u5927\u5c0f\u7be9\u9078 +explorer.photo.fileSizeDesc=\u50c5\u7be9\u9078\u5927\u65bc\u8a72\u8a2d\u7f6e\u7684\u6587\u4ef6\u70ba0\u5247\u4e0d\u9650\u5236 +explorer.toolbar.folder=\u76ee\u9304\u76f8\u518c +explorer.toolbar.folderSelect=\u9078\u64c7\u6587\u4ef6\u593e\u4ee5\u76f8\u518a\u6a21\u5f0f\u5c55\u793a +explorer.pathDesc.fav=\u6587\u4ef6\u6dfb\u52a0\u6536\u85cf\u5f8c\u53ef\u4ee5\u5be6\u73fe\u5feb\u901f\u8a2a\u554f��\u4e00\u9ede\u76f4\u9054 +explorer.pathDesc.home=\u500b\u4eba\u7a7a\u9593\u662f\u60a8\u7684\u79c1\u6709\u5b58\u5132\u7a7a\u9593\u50c5\u81ea\u5df1\u53ef\u898b��\u5176\u4ed6\u7528\u6236\u4e0d\u53ef\u898b +explorer.pathDesc.groupRoot=\u9019\u88e1\u662f\u4f01\u696d/\u55ae\u4f4d\u7684\u516c\u5171\u7a7a\u9593��\u9ed8\u8a8d\u6240\u6709\u6210\u54e1\u53ef\u898b +explorer.pathDesc.myGroup=\u5728\u9019\u88e1\u7ba1\u7406\u60a8\u7684\u6240\u5728\u90e8\u9580\u7684\u6587\u6a94\u90e8\u9580\u6587\u6a94\u50c5\u672c\u90e8\u9580\u6210\u54e1\u53ef\u898b��\u53ef\u64cd\u4f5c��\u5176\u4ed6\u90e8\u9580\u6210\u54e1\u4e0d\u53ef\u898b +explorer.pathDesc.group=\u90e8\u9580\u7db2\u76e4\u50c5\u8a72\u90e8\u9580\u6210\u54e1\u53ef\u898b\u64cd\u4f5c\u6b0a\u9650\u7531\u90e8\u9580\u7ba1\u7406\u54e1\u5206\u914d\u8a2d\u5b9a. +explorer.pathDesc.recentDoc=\u6700\u8fd1\u65b0\u5efa��\u4e0a\u50b3��\u4fee\u6539��\u6253\u958b\u7684\u6587\u4ef6 +explorer.pathDesc.shareTo=\u5728\u9019\u88e1\u67e5\u770b\u548c\u7ba1\u7406\u60a8\u5411\u4ed6\u4eba\u767c\u8d77\u7684[\u5167\u90e8\u5354\u4f5c]\u9805\u76ee +explorer.pathDesc.shareLink=\u5728\u9019\u88e1\u67e5\u770b\u548c\u7ba1\u7406\u60a8\u767c\u8d77\u7684\u5916\u93c8\u5206\u4eab +explorer.pathDesc.recycle=\u5728\u9019\u88e1\u7ba1\u7406\u60a8\u522a\u9664\u7684\u6587\u4ef6��\u593e�� +explorer.pathDesc.fileType=\u6309\u985e\u578b\u5c0d\u6587\u4ef6\u9032\u884c\u5206\u985e\u50c5\u500b\u4eba\u7a7a\u9593\u5167\u6587\u4ef6 +explorer.pathDesc.tag=\u7d66\u6587\u4ef6��\u593e��\u6dfb\u52a0\u6a19\u7c64��\u5be6\u73fe\u9ad8\u6548\u5206\u985e\u548c\u5feb\u901f\u67e5\u8a62 +explorer.pathDesc.tagItem=\u8a66\u8a66\u7d66\u6587\u4ef6/\u6587\u4ef6\u593e\u6dfb\u52a0\u500b\u6a19\u7c64\u5427! +explorer.pathDesc.mount=\u5728\u9019\u88e1\u60a8\u53ef\u4ee5\u7ba1\u7406\u591a\u500b\u5f8c\u53f0\u5b58\u5132\u4ee5\u53ca\u8a72\u670d\u52d9\u5668\u4e0a\u639b\u8f09\u7684\u78c1\u76e4 +explorer.pathDesc.shareToMe=\u5e73\u92ea\u986f\u793a--\u6240\u6709\u8207\u6211\u5354\u4f5c\u7684\u5167\u5bb9 +explorer.pathDesc.shareToMeUser=\u6309\u5206\u4eab\u8005\u986f\u793a--\u8207\u6211\u5354\u4f5c\u7684\u5167\u5bb9\u6309\u767c\u8d77\u8005\u9032\u884c\u5206\u985e +explorer.pathDesc.shareToMeUserItem=\u8a72\u7528\u6236\u767c\u8d77\u7684\u5354\u4f5c +explorer.pathDesc.shareToMeGroup=\u8207\u6211\u5354\u4f5c\u7684\u5167\u5bb9\u6309\u6587\u4ef6\u593e\u6240\u5728\u90e8\u9580\u9032\u884c\u5206\u985e +explorer.pathDesc.shareToMeGroupGroup=\u4f86\u81ea\u65bc\u8a72\u90e8\u9580\u7db2\u76e4\u4e0b\u7684\u5354\u4f5c\u5206\u4eab +explorer.pathDesc.search=\u652f\u6301\u641c\u7d22\u6587\u4ef6/\u6a19\u7c64/\u5099\u8a3b/\u5167\u5bb9;\u652f\u6301\u62fc\u97f3��\u9996\u5b57\u6bcd\u6a21\u7cca\u5339\u914d +explorer.pathDesc.searchMore=\u8a2d\u7f6e\u66f4\u591a\u6aa2\u7d22\u689d\u4ef6 +explorer.pathDesc.shareFrom=\u534f\u4f5c\u4f86\u6e90 +explorer.pathGroup.shareGroup=\u90e8\u9580\u7a7a\u9593 +explorer.pathGroup.shareGroupDesc=\u4e0b\u7d1a\u90e8\u9580\u4e2d\u6709\u5167\u5bb9\u6642\u901a\u8def +explorer.pathGroup.shareUser=\u90e8\u9580\u6210\u54e1\u7684\u500b\u4eba\u7a7a\u9593\u5206\u4eab +explorer.pathGroup.shareUserDesc=\u4f86\u6e90:\u7528\u6236\u500b\u4eba\u7a7a\u9593\u5206\u4eab\u8a72\u7528\u6236\u767c\u8d77\u7684\u5916\u90e8\u90e8\u9580\u6587\u6a94\u5206\u4eab. +explorer.pathGroup.shareContent=\u8a72\u90e8\u9580\u7a7a\u9593\u5354\u4f5c\u5206\u4eab +explorer.pathGroup.group=\u5b50\u90e8\u9580 +explorer.pathGroup.groupContent=\u90e8\u9580\u6587\u6a94 +explorer.pathGroup.shareUserOuter=\u5916\u90e8\u5354\u4f5c\u5206\u4eab +explorer.pathGroup.shareUserOuterDesc=\u4e0d\u5728\u81ea\u5df1\u7d44\u7e54\u67b6\u69cb\u4e0b\u7684\u5916\u90e8\u7528\u6236\u7684\u5354\u4f5c\u5206\u4eab +explorer.pathGroup.shareSelf=\u500b\u4eba\u7a7a\u9593 +explorer.toolbar.fileSizeTitle=\u5716\u6a19\u5927\u5c0f +explorer.toolbar.fileSizeSuper=\u8d85\u5c0f +explorer.toolbar.fileSizeSmall=\u5c0f\u5716\u6a19 +explorer.toolbar.fileSizeDefault=\u4e2d\u5716\u6a19 +explorer.toolbar.fileSizeBig=\u5927\u5716\u6a19 +explorer.toolbar.fileSizeBigSuper=\u8d85\u5927\u5716\u6a19 +explorer.toolbar.PagePC=\u96fb\u8166\u7248 +explorer.toolbar.pagePhone=\u624b\u6a5f\u7248 +explorer.file.name=\u540d\u7a31 +explorer.file.type=\u985e\u578b +explorer.file.contain=\u5305\u542b +explorer.file.address=\u4f4d\u7f6e +explorer.file.detil=\u63cf\u8ff0\u8aaa\u660e +explorer.file.linkCount=\u5f15\u7528\u6578 +explorer.file.size=\u5927\u5c0f +explorer.file.count=\u6578\u91cf +explorer.file.byte=\u5b57\u7bc0 +explorer.file.path=\u8def\u5f91 +explorer.file.action=\u64cd\u4f5c +explorer.file.creator=\u5275\u5efa\u8005 +explorer.file.editor=\u4fee\u6539\u8005 +explorer.file.location=\u6240\u5728\u4f4d\u7f6e +explorer.file.timeInfo=\u6642\u9593\u4fe1\u606f +explorer.file.createTime=\u5275\u5efa\u6642\u9593 +explorer.file.modifyTime=\u4fee\u6539\u6642\u9593 +explorer.file.lastTime=\u6700\u5f8c\u8a2a\u554f +explorer.file.sortType=\u6392\u5e8f\u65b9\u5f0f +explorer.file.sortDisable=\u8a72\u5167\u5bb9\u4e0d\u652f\u6301\u6307\u5b9a\u6392\u5e8f! +explorer.file.timeType=Y/m/dH:i:s +explorer.file.timeTypeInfo=Y/m/dH:i:s +explorer.file.listType=\u67e5\u770b +explorer.file.listIcon=\u5716\u6a19\u6392\u5217 +explorer.file.listList=\u5217\u8868\u6392\u5217 +explorer.file.listListSplit=\u5206\u6b04\u6a21\u5f0f +explorer.file.listTypeGroup=\u986f\u793a\u6a21\u5f0f\u53ca\u6392\u5e8f\u65b9\u5f0f +explorer.file.listTypeKeep=\u986f\u793a\u6a21\u5f0f +explorer.file.listTypeKeepDesc=\u70ba\u6bcf\u500b\u6587\u4ef6\u593e\u9078\u64c7\u8996\u5716\u6a21\u5f0f��\u6216\u5c0d\u6240\u6709\u6587\u4ef6\u593e\u4f7f\u7528\u76f8\u540c\u7684\u8996\u5716\u6a21\u5f0f +explorer.file.listSortKeep=\u6392\u5e8f\u65b9\u5f0f +explorer.file.listSortKeepDesc=\u70ba\u6bcf\u500b\u6587\u4ef6\u593e\u914d\u7f6e\u5217\u6392\u5e8f\u9806\u5e8f��\u6216\u5c0d\u6240\u6709\u6587\u4ef6\u593e\u4f7f\u7528\u76f8\u540c\u7684\u9806\u5e8f +explorer.file.listViewKeep=\u9069\u7528\u65bc\u55ae\u500b\u6587\u4ef6\u593e +explorer.file.listViewAll=\u9069\u7528\u65bc\u6240\u6709\u6587\u4ef6\u593e +explorer.file.listViewReset=\u91cd\u7f6e\u5230\u9ed8\u8a8d +explorer.file.sortUp=\u905e\u589e +explorer.file.sortDown=\u905e\u6e1b +explorer.file.orderType=\u6392\u5e8f\u65b9\u5f0f +explorer.file.orderDesc=\u964d\u5e8f +explorer.file.orderAsc=\u5347\u5e8f +explorer.file.imageSize=\u5716\u7247\u5c3a\u5bf8 +explorer.file.sharer=\u5206\u4eab\u8005 +explorer.file.shareTime=\u5206\u4eab\u6642\u9593 +explorer.file.viewCnt=\u700f\u89bd\u6578 +explorer.file.downCnt=\u4e0b\u8f09\u6578 +explorer.file.readWriteLock=\u66ab\u4e0d\u652f\u6301\u8a72\u64cd\u4f5c\u6709\u5176\u4ed6\u8b80\u5beb\u4efb\u52d9\u6b63\u5728\u8655\u7406\u4e2d\u8acb\u7a0d\u5f8c\u518d\u8a66! +explorer.app.app=\u8f15\u61c9\u7528 +explorer.app.createLink=\u65b0\u5efa\u7db2\u5740 +explorer.app.create=\u5275\u5efa\u8f15\u61c9\u7528 +explorer.app.edit=\u7de8\u8f2f\u8f15\u61c9\u7528 +explorer.app.open=\u6253\u958b\u8f15\u61c9\u7528 +explorer.app.groupGame=\u904a\u6232 +explorer.app.groupTools=\u5de5\u5177 +explorer.app.groupReader=\u95b1\u8b80 +explorer.app.groupMovie=\u5f71\u8996 +explorer.app.groupMusic=\u97f3\u6a02 +explorer.app.groupLife=\u751f\u6d3b +explorer.app.desc=\u61c9\u7528\u63cf\u8ff0 +explorer.app.icon=\u61c9\u7528\u5716\u6a19 +explorer.app.iconShow=url\u5730\u5740\u6216\u8a72\u76ee\u9304 +explorer.app.group=\u61c9\u7528\u5206\u7d44 +explorer.app.type=\u985e\u578b +explorer.app.typeUrl=\u93c8\u63a5 +explorer.app.typeCode=js\u64f4\u5c55 +explorer.app.display=\u5916\u89c0 +explorer.app.displayBorder=\u7121\u908a\u6846(\u9078\u4e2d\u5373\u7121\u908a\u6846) +explorer.app.displaySize=\u8abf\u6574\u5927\u5c0f(\u9078\u4e2d\u5373\u53ef\u8abf\u6574) +explorer.app.size=\u5c3a\u5bf8 +explorer.app.url=\u93c8\u63a5\u5730\u5740 +explorer.app.code=js\u4ee3\u78bc +explorer.app.appType=\u61c9\u7528\u985e\u578b +explorer.app.website=\u7db2\u5740 +explorer.app.shortLink=\u6587\u4ef6\u5feb\u6377\u65b9\u5f0f +explorer.app.imgIcon=\u5716\u7247\u5716\u6a19 +explorer.app.imgIconUrl=\u9078\u64c7\u5716\u7247\u6216\u5247\u7c98\u8cbc\u7db2\u7d61\u5716\u7247url. +explorer.app.path=\u8def\u5f91 +explorer.app.pathDesc=\u4e0d\u652f\u6301\u624b\u52d5\u4fee\u6539��\u53ef\u4ee5\u6587\u4ef6\u53f3\u9375\u5275\u5efa\u5feb\u6377\u65b9\u5f0f +explorer.app.link=\u7db2\u5740\u93c8\u63a5 +explorer.app.linkDesc=\u8acb\u8f38\u5165http/https\u93c8\u63a5 +explorer.app.linkDragTips=\u53ef\u4ee5\u5c07url\u93c8\u63a5\u62d6\u5165\u5230\u6587\u4ef6\u5340\u57df\u81ea\u52d5\u5275\u5efa\u7db2\u5740\u93c8\u63a5! +explorer.app.openType=\u6253\u958b\u65b9\u5f0f +explorer.app.openWindow=\u65b0\u7a97\u53e3 +explorer.app.openDialog=\u5c0d\u8a71\u6846 +explorer.app.openCurrent=\u7576\u524d\u9801 +explorer.app.openInline=\u5d4c\u5165\u9801\u9762 +explorer.app.dialogSize=\u5c0d\u8a71\u6846\u5c3a\u5bf8 +explorer.app.with=\u5bec\u5ea6 +explorer.app.height=\u9ad8\u5ea6 +explorer.app.moreSet=\u66f4\u591a\u8a2d\u7f6e +explorer.app.canDiyWith=\u5141\u8a31\u8abf\u6574\u5bec\u5ea6 +explorer.app.miniBlock=\u6975\u7c21\u6a19\u984c\u6b04 +explorer.app.runCode=\u57f7\u884cjs\u4ee3\u78bc +explorer.app.name=\u61c9\u7528\u540d +explorer.app.nameDesc=\u8acb\u8f38\u5165\u61c9\u7528\u540d. +explorer.app.descDesc=\u8acb\u8f38\u5165\u61c9\u7528\u63cf\u8ff0 +explorer.embed.title=\u5d4c\u5165\u6587\u4ef6 +explorer.embed.desc=\u5c07\u8a72\u6587\u4ef6\u5d4c\u5165\u5230\u7db2\u9801\u6216\u535a\u5ba2\u4e2d +explorer.embed.url=\u5d4c\u5165URL +explorer.embed.code=\u5d4c\u5165\u4ee3\u78bc +explorer.upload.ready=\u7b49\u5f85\u4e0a\u50b3 +explorer.upload.success=\u4e0a\u50b3\u6210\u529f +explorer.upload.secPassSuccess=\u79d2\u50b3\u6210\u529f +explorer.upload.pathCurrent=\u5207\u63db\u5230\u7576\u524d\u76ee\u9304 +explorer.upload.select=\u9078\u64c7\u6587\u4ef6 +explorer.upload.maxSize=\u6700\u5927\u5141\u8a31 +explorer.upload.sizeInfo=\u5982\u679c\u60f3\u914d\u7f6e\u66f4\u5927��\u8acb\u4fee\u6539php.ini\u4e2d\u5141\u8a31\u4e0a\u50b3\u7684\u6700\u5927\u503c��\u9078\u64c7\u6587\u4ef6\u6642\u5927\u65bc\u8a72\u914d\u7f6e\u7684\u5c07\u81ea\u52d5\u904e\u6ffe\u6389�� +explorer.upload.error=\u4e0a\u50b3\u5931\u6557 +explorer.upload.mergeError=\u5408\u4f75\u6587\u4ef6\u5931\u6557 +explorer.upload.errorHttp=\u7db2\u7d61\u6216\u9632\u706b\u7246\u932f\u8aa4 +explorer.upload.muti=\u591a\u6587\u4ef6\u4e0a\u50b3 +explorer.upload.drag=\u62d6\u62fd\u4e0a\u50b3 +explorer.upload.dragFolder=\u62d6\u62fd\u5230\u6587\u4ef6\u593e\u4e0a\u50b3 +explorer.upload.dragTips=\u9b06\u958b\u5373\u53ef\u4e0a\u50b3! +explorer.upload.pathNotAllow=\u6587\u4ef6\u540d\u4e0d\u5141\u8a31\u51fa\u73fe +explorer.upload.errorNull=\u6c92\u6709\u6587\u4ef6�� +explorer.upload.errorBig=\u6587\u4ef6\u5927\u5c0f\u8d85\u904e\u670d\u52d9\u5668\u9650\u5236 +explorer.upload.errorMove=\u79fb\u52d5\u6587\u4ef6\u5931\u6557�� +explorer.upload.errorExists=\u8a72\u6587\u4ef6\u5df2\u5b58\u5728 +explorer.upload.local=\u672c\u5730\u4e0a\u50b3 +explorer.upload.tips=\u63a1\u7528\u5206\u7247\u4e0a\u50b3\u4e0d\u518d\u53d7php.ini\u9650\u5236;\u63a8\u85a6chrome\u9ad4\u9a57\u6587\u4ef6\u593e\u62d6\u62fd\u4e0a\u50b3 +explorer.upload.exist=\u540c\u540d\u6587\u4ef6\u8655\u7406 +explorer.upload.clearAll=\u6e05\u7a7a\u6240\u6709 +explorer.upload.clear=\u6e05\u7a7a\u5df2\u5b8c\u6210 +explorer.upload.addMore=\u6279\u91cf\u6dfb\u52a0 +explorer.upload.errorEmpty=\u4e0d\u80fd\u70ba\u7a7a\u6587\u4ef6! +explorer.upload.errorExt=\u6587\u4ef6\u64f4\u5c55\u540d\u4e0d\u5339\u914d! +explorer.upload.fileSizeDisable=\u540c\u6642\u4e0a\u50b3/\u8f49\u5b58\u6587\u4ef6\u6578\u904e\u591a\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1\u9032\u884c\u8abf\u6574! +explorer.upload.moreDesc=(\u5efa\u8b70\u4e0d\u5927\u65bc2000)\u7576\u524d\u7e3d\u5171: +explorer.upload.scan=\u6383\u63cf\u4e2d +explorer.upload.merge=\u6821\u9a57\u5408\u4f75\u4e2d +explorer.upload.needTime=\u5269\u9918\u7d04 +explorer.upload.checkError=\u4e0a\u50b3\u6821\u9a57\u5931\u6557\u8acb\u91cd\u8a66 +explorer.upload.saveError=\u4e0a\u50b3\u6587\u4ef6\u4fe1\u606f\u4fdd\u5b58\u5931\u6557 +explorer.upload.downloadDesc=\u50c5\u652f\u6301http/https\u7db2\u7d61\u93c8\u63a5 +explorer.table.first=\u9996\u9801 +explorer.table.last=\u5c3e\u9801 +explorer.table.prev=\u4e0a\u4e00\u9801 +explorer.table.next=\u4e0b\u4e00\u9801 +explorer.table.one=\u51711\u9801 +explorer.table.page=\u9801 +explorer.table.itemPage=\u6761/\u9801 +explorer.table.searchTotal=\u5171\u641c\u7d22\u5230 +explorer.table.items=\u689d\u8a18\u9304 +explorer.table.list=\u6578\u64da\u5217\u8868 +explorer.search.ing=\u641c\u7d22\u4e2d... +explorer.search.result=\u641c\u7d22\u7d50\u679c +explorer.search.resultTooMore=\u641c\u7d22\u7d50\u679c\u592a\u591a��\u5efa\u8b70\u63db\u4e00\u500b\u76ee\u9304\u6216\u8a5e\u8a9e +explorer.search.resultNull=\u6c92\u6709\u641c\u7d22\u7d50\u679c! +explorer.search.caseSensitive=\u5340\u5206\u5927\u5c0f\u5beb +explorer.search.content=\u641c\u7d22\u6587\u4ef6\u5167\u5bb9 +explorer.search.extDesc=\u8f38\u5165\u9700\u8981\u7be9\u9078\u7684\u64f4\u5c55\u540d��\u7528\u7a7a\u683c\u9694\u958b. +explorer.search.byItems=\u500b\u689d\u4ef6\u7be9\u9078 +explorer.search.extNull=\u4e0d\u9650\u985e\u578b +explorer.search.extFile=\u4efb\u610f\u6587\u4ef6 +explorer.search.extDiy=\u81ea\u5b9a\u7fa9 +explorer.search.inputDesc=\u8acb\u8f38\u5165\u95dc\u9375\u5b57\u6216\u7d66\u51fa\u7be9\u9078\u689d\u4ef6�� +explorer.search.path=\u641c\u7d22\u76ee\u9304�� +explorer.search.rootPath=\u641c\u7d22\u6839\u76ee\u9304�� +explorer.search.range=\u641c\u7d22\u7bc4\u570d +explorer.search.allFolder=\u5168\u90e8\u6587\u4ef6\u593e +explorer.search.currentFolder=\u7576\u524d\u6587\u4ef6\u593e +explorer.search.ext=\u6587\u4ef6\u985e\u578b +explorer.search.timeRange=\u6642\u9593\u7bc4\u570d +explorer.search.timeAll=\u4e0d\u9650\u6642\u9593 +explorer.search.lastDay=\u8fd11\u5929 +explorer.search.lastWeek=\u6700\u8fd17\u5929 +explorer.search.lastMonth=\u6700\u8fd130\u5929 +explorer.search.lastYear=\u6700\u8fd1\u4e00\u5e74 +explorer.search.sizeAll=\u4e0d\u9650\u5927\u5c0f +explorer.search.inputNullDesc=\u4e0d\u586b\u5247\u4ee3\u8868\u5927\u65bc\u6216\u5c0f\u65bc\u67d0\u500b\u503c\u53ef\u4ee5\u70ba\u5c0f\u6578. +explorer.search.selectUser=\u9078\u64c7\u7528\u6236... +explorer.search.byUserDesc=\u6309\u5275\u5efa\u8005/\u4fee\u6539\u8005\u641c\u7d22 +explorer.search.total=\u5171\u641c\u7d22\u5230 +explorer.search.noResult=\u62b1\u6b49��\u6c92\u6709\u641c\u7d22\u7d50\u679c��\u8acb\u63db\u500b\u641c\u7d22\u8a5e\u518d\u8a66\u5427�� +explorer.search.advance=\u9ad8\u7d1a\u641c\u7d22 +explorer.search.clear=\u6e05\u7a7a\u5167\u5bb9 +explorer.history.list=\u6587\u4ef6\u6b77\u53f2\u8a18\u9304 +explorer.history.lastModify=\u6700\u5f8c\u4fee\u6539\u6642\u9593 +explorer.history.modifyUser=\u7248\u672c\u4fee\u6539\u8005 +explorer.history.noHistory=\u6c92\u6709\u6b77\u53f2\u7248\u672c! +explorer.history.current=\u7576\u524d\u7248\u672c +explorer.history.detil=\u63cf\u8ff0\u8aaa\u660e +explorer.history.detilAdd=\u6dfb\u52a0\u7248\u672c\u8aaa\u660e +explorer.history.uploadNew=\u4e0a\u50b3\u65b0\u7248\u672c +explorer.history.diff=\u6b77\u53f2\u7248\u672c\u5c0d\u6bd4 +explorer.history.setCurrent=\u9019\u662f\u56de\u6efe\u524d\u7684\u7248\u672c +explorer.history.delCurrent=\u522a\u9664\u8a72\u7248\u672c +explorer.history.delAll=\u522a\u9664\u6240\u6709\u7248\u672c\u8a18\u9304 +explorer.history.ifDelAll=\u78ba\u5b9a\u522a\u9664\u6240\u6709\u6b77\u53f2\u8a18\u9304�� +explorer.history.ifDelCurrent=\u522a\u9664\u8a72\u7248\u672c�� +explorer.history.ifRollback=\u78ba\u5b9a\u8981\u56de\u6efe\u5230\u8a72\u7248\u672c�� +explorer.history.changeEvent=\u6b77\u53f2\u7248\u672c\u5207\u63db +explorer.history.before=\u4fee\u6539\u524d +explorer.history.after=\u4fee\u6539\u5f8c +explorer.recycle.clearUser=\u6e05\u7a7a\u8a72\u7528\u6236\u56de\u6536\u7ad9 +explorer.recycle.restoreSelect=\u9084\u539f\u8a72\u5167\u5bb9 +explorer.recycle.moveTo=\u79fb\u4ea4\u7d66 +explorer.recycle.config=\u56de\u6536\u7ad9\u8a2d\u7f6e +explorer.recycle.configTitle=\u7cfb\u7d71\u56de\u6536\u7ad9\u8a2d\u7f6e +explorer.recycle.configOpen=\u958b\u555f\u7cfb\u7d71\u56de\u6536\u7ad9 +explorer.recycle.configOpenDesc=\u5efa\u8b70\u958b\u555f +explorer.recycle.configCloseInfo=\u522a\u9664\u5167\u5bb9\u6642\u4e0d\u6703\u9032\u5165\u7cfb\u7d71\u56de\u6536\u7ad9;\u76f4\u63a5\u5fb9\u5e95\u522a\u9664. +explorer.recycle.configOpenInfo=
  • \u500b\u4eba\u6587\u6a94\u6216\u90e8\u9580\u6587\u4ef6\u5728\u5fb9\u5e95\u522a\u9664\u6216\u6e05\u7a7a\u56de\u6536\u7ad9\u5f8c\u9032\u5165\u7cfb\u7d71\u56de\u6536\u7ad9
  • \u522a\u9664\u5167\u5bb9\u6309\u6587\u4ef6\u6240\u5728\u7528\u6236\u6216\u90e8\u9580\u6b78\u985e\u5728\u7528\u6236\u6216\u90e8\u9580\u6587\u4ef6\u593e\u4e2d\u7ba1\u7406\u54e1\u53ef\u4ee5\u9078\u64c7\u9084\u539f\u9019\u4e9b\u6587\u4ef6;
  • \u8d85\u904e\u81ea\u52d5\u5fb9\u5e95\u522a\u9664\u6642\u9593\u4e4b\u524d\u7684\u6587\u4ef6\u5c07\u5b9a\u671f\u81ea\u52d5\u6e05\u7a7a;
  • \u6ce8\u610f:\u5728\u6b64\u8655\u522a\u9664\u7684\u6587\u4ef6\u4e0d\u80fd\u518d\u6062\u5fa9.
  • +explorer.recycle.configClear=\u81ea\u52d5\u5fb9\u5e95\u522a\u9664 +explorer.recycle.restoreConfirm=\u78ba\u5b9a\u9084\u539f\u6587\u6a94?
    \u9084\u539f\u5f8c\u6587\u6a94\u5c07\u79fb\u52d5\u5230\u76ee\u6a19\u6839\u76ee\u9304 +explorer.recycle.moveConfirm=\u78ba\u8a8d\u79fb\u4ea4 +explorer.recycle.moveSelectTarget=\u9078\u64c7\u7528\u6236\u6216\u90e8\u9580 +explorer.recycle.moveDesc=
  • \u79fb\u4ea4\u7d66\u6307\u5b9a\u7528\u6236\u6216\u8005\u90e8\u9580;\u6703\u9077\u79fb\u5c0d\u50cf\u6839\u76ee\u9304\u4e0b
  • \u79fb\u4ea4\u5f8c\u6587\u6a94\u8aaa\u660e\u4ea4\u6d41\u8a0e\u8ad6\u6b77\u53f2\u7248\u672c\u7b49\u4fe1\u606f\u5c07\u6703\u7e7c\u7e8c\u4fdd\u7559;\u5206\u4eab\u5354\u4f5c\u53ca\u6b0a\u9650\u4fe1\u606f\u6703\u79fb\u9664
  • +explorer.recycle.taskTitle=\u7cfb\u7d71\u56de\u6536\u7ad9\u6e05\u7406 +explorer.recycle.taskDesc=\u81ea\u52d5\u522a\u9664\u8d85\u904e\u8a2d\u7f6e\u6642\u9593\u7684\u56de\u6536\u7ad9\u5167\u5bb9\u91cb\u653e\u5b58\u5132\u7a7a\u9593 +explorer.share.add=\u6dfb\u52a0\u5206\u4eab +explorer.share.edit=\u7de8\u8f2f\u5206\u4eab +explorer.share.remove=\u53d6\u6d88\u5206\u4eab +explorer.share.path=\u5206\u4eab\u8def\u5f91 +explorer.share.source=\u8cc7\u6e90\u5206\u4eab +explorer.share.name=\u5206\u4eab\u6a19\u984c +explorer.share.nameDesc=\u9ed8\u8a8d\u70ba\u5206\u4eab\u6587\u6a94\u540d��\u53ef\u81ea\u5b9a\u7fa9\u540d\u7a31 +explorer.share.time=\u5230\u671f\u6642\u9593 +explorer.share.timeLimit=\u9650\u5b9a\u6642\u9593 +explorer.share.timeLimitDesc=\u958b\u555f\u4e26\u8a2d\u7f6e\u5f8c\u8d85\u904e\u6642\u9593\u5206\u4eab\u81ea\u52d5\u5931\u6548 +explorer.share.timeDesc=\u70ba\u7a7a\u5247\u4e0d\u8a2d\u7f6e +explorer.share.pwd=\u63d0\u53d6\u5bc6\u78bc +explorer.share.pwdDesc=\u70ba\u7a7a\u5247\u4e0d\u8a2d\u7f6e\u5bc6\u78bc +explorer.share.randomPwd=\u96a8\u6a5f\u751f\u6210 +explorer.share.randomPwdDesc=\u50c5\u9650\u63d0\u53d6\u5bc6\u78bc\u624d\u80fd\u67e5\u770b��\u66f4\u52a0\u96b1\u79c1\u5b89\u5168. +explorer.share.cancel=\u53d6\u6d88\u5171\u4eab +explorer.share.create=\u5275\u5efa\u516c\u958b\u93c8\u63a5 +explorer.share.url=\u5171\u4eab\u5730\u5740 +explorer.share.noDown=\u7981\u6b62\u4e0b\u8f09 +explorer.share.codeRead=\u4ee3\u78bc\u95b1\u8b80 +explorer.share.configSave=\u4fdd\u5b58\u914d\u7f6e +explorer.share.errorParam=\u53c3\u6578\u932f\u8aa4! +explorer.share.errorUser=\u7528\u6236\u4fe1\u606f\u932f\u8aa4�� +explorer.share.errorSid=\u5171\u4eab\u4e0d\u5b58\u5728�� +explorer.share.errorTime=\u60a8\u4f86\u665a\u4e86\u8a72\u5171\u4eab\u5df2\u7d93\u904e\u671f! +explorer.share.errorPath=\u5171\u4eab\u6587\u4ef6\u4e0d\u5b58\u5728\u88ab\u522a\u9664\u6216\u8005\u79fb\u8d70\u4e86! +explorer.share.errorPwd=\u5bc6\u78bc\u932f\u8aa4! +explorer.share.errorShowTips=\u8a72\u985e\u578b\u6587\u4ef6\u66ab\u4e0d\u652f\u6301\u9810\u89bd! +explorer.share.expiredTips=\u62b1\u6b49��\u8a72\u5206\u4eab\u5df2\u904e\u671f\u8acb\u806f\u7e6b\u5206\u4eab\u8005�� +explorer.share.downExceedTips=\u62b1\u6b49��\u8a72\u5206\u4eab\u4e0b\u8f09\u6b21\u6578\u8d85\u904e\u5206\u4eab\u8005\u8a2d\u7f6e\u7684\u4e0a\u9650 +explorer.share.store=\u4fdd\u5b58\u5230\u7db2\u76e4 +explorer.share.loginTips=\u62b1\u6b49��\u8a72\u5206\u4eab\u5fc5\u9808\u767b\u9304\u7528\u6236\u624d\u80fd\u8a2a\u554f�� +explorer.share.noDownTips=\u62b1\u6b49��\u8a72\u5206\u4eab\u8005\u7981\u7528\u4e86\u4e0b\u8f09�� +explorer.share.noViewTips=\u62b1\u6b49��\u8a72\u5206\u4eab\u8005\u7981\u7528\u4e86\u9810\u89bd�� +explorer.share.noUploadTips=\u62b1\u6b49��\u8a72\u5206\u4eab\u8005\u7981\u7528\u4e86\u4e0a\u50b3�� +explorer.share.needPwd=\u8a72\u5206\u4eab\u9700\u8981\u5bc6\u78bc +explorer.share.notExist=\u5206\u4eab\u4e0d\u5b58\u5728�� +explorer.share.viewNum=\u700f\u89bd: +explorer.share.downNum=\u4e0b\u8f09\u6b21\u6578 +explorer.share.openPage=\u6253\u958b\u5171\u4eab\u9801\u9762 +explorer.share.openLink=\u6253\u958b\u5206\u4eab\u93c8\u63a5 +explorer.share.copyLink=\u8907\u88fd\u5206\u4eab\u4fe1\u606f +explorer.share.link=\u5206\u4eab\u93c8\u63a5�� +explorer.share.accessPwd=\u8a2a\u554f\u5bc6\u78bc�� +explorer.share.copied=\u5df2\u5fa9\u5236 +explorer.share.actionNotSupport=\u5206\u4eab\u5167\u5bb9\u4e0d\u652f\u6301\u8a72\u64cd\u4f5c +explorer.share.errorPathTips=\u5206\u4eab\u93c8\u63a5\u932f\u8aa4\u6216\u5206\u4eab\u8005\u5df2\u7d93\u53d6\u6d88\u4e86\u8a72\u5916\u93c8\u5206\u4eab +explorer.share.shareTo=\u5354\u4f5c\u5206\u4eab +explorer.share.shareToTarget=\u5354\u4f5c\u6210\u54e1 +explorer.share.innerTo=\u5167\u90e8\u5354\u4f5c +explorer.share.linkTo=\u5916\u93c8\u5206\u4eab +explorer.share.selectTarget=\u9078\u64c7\u5354\u4f5c\u5206\u4eab\u7684\u90e8\u9580\u6216\u7528\u6236 +explorer.share.afterShareDesc=\u5206\u4eab\u7d66\u5c0d\u65b9\u6216\u5c0d\u65b9\u6240\u5728\u90e8\u9580\u5f8c��\u7528\u6236\u53ef\u4ee5\u5728[\u5206\u4eab\u7d66\u6211\u7684]\u4e2d\u770b\u5230�� +explorer.share.openOuterLink=\u958b\u653e\u5916\u93c8\u5206\u4eab +explorer.share.openOuterLinkDesc=\u5275\u5efa\u5916\u93c8\u5f8c��\u53ef\u4ee5\u901a\u904e\u90f5\u4ef6\u6216QQ\u767c\u9001\u7d66\u5176\u4ed6\u4eba�� +explorer.share.outerLink=\u5206\u4eab\u93c8\u63a5 +explorer.share.advanceSet=\u9ad8\u7d1a\u914d\u7f6e +explorer.share.loginLimit=\u50c5\u767b\u9304\u7528\u6236\u53ef\u7528 +explorer.share.loginLimitDesc=\u958b\u555f\u5f8c\u50c5\u5167\u90e8\u6210\u54e1\u53ef\u8a2a\u554f. +explorer.share.authLimit=\u6b0a\u9650\u53ca\u9650\u5236 +explorer.share.canUpload=\u5141\u8a31\u4e0a\u50b3 +explorer.share.notView=\u7981\u7528\u9810\u89bd +explorer.share.notDown=\u7981\u7528\u4e0b\u8f09 +explorer.share.downNumLimit=\u4e0b\u8f09\u6b21\u6578\u9650\u5236 +explorer.share.downNumLimitDesc=\u8d85\u904e\u8a72\u6b21\u6578��\u5206\u4eab\u93c8\u63a5\u81ea\u52d5\u5931\u6548. +explorer.share.learnAuth=\u4e86\u89e3\u6587\u6a94\u5354\u4f5c\u6b0a\u9650 +explorer.share.shareToRemove=\u78ba\u5b9a\u53d6\u6d88\u8a72\u5354\u4f5c\u5206\u4eab��
    \u5206\u4eab\u7d66\u7684\u76ee\u6a19\u7528\u6236\u4e0d\u518d\u80fd\u770b\u5230\u8a72\u5354\u4f5c\u5206\u4eab�� +explorer.share.shareLinkRemove=\u78ba\u5b9a\u53d6\u6d88\u8a72\u5916\u93c8\u5206\u4eab��
    \u53d6\u6d88\u5f8c\u5916\u93c8\u5c07\u5931\u6548�� +explorer.share.shareToCopy=\u8907\u88fd\u8a2a\u554f\u8def\u5f91 +explorer.share.shareToCopyDesc=\u53ef\u5c07\u8a72\u93c8\u63a5\u767c\u9001\u7d66\u5354\u4f5c\u7684\u4eba\u5feb\u6377\u9032\u5165\u5354\u4f5c +explorer.share.specifyAuthTips=\u9664\u4e0a\u8ff0\u6307\u5b9a\u7528\u6236 +explorer.share.specifyAuthDesc=\u6307\u5b9a\u7528\u6236\u6b0a\u9650>\u6307\u5b9a\u7528\u6236\u6240\u5728\u90e8\u9580\u6b0a\u9650>\u5176\u4ed6\u4eba\u6b0a\u9650 +explorer.share.selfAuthDesc=\u4e0d\u80fd\u4fee\u6539\u81ea\u5df1\u7684\u6b0a\u9650��\u5176\u4ed6\u7ba1\u7406\u8005\u53ef\u4ee5\u8a2d\u7f6e +explorer.share.authTypeDesc=\u9ed8\u8a8d\u7e7c\u627f\u4e0a\u7d1a\u6587\u4ef6\u593e\u6b0a\u9650 +explorer.share.rootPathAuthDesc=\u6839\u90e8\u9580\u652f\u6301\u9078\u64c7\u7528\u6236\u548c\u90e8\u9580 +explorer.share.subPathAuthDesc=\u5b50\u90e8\u9580��\u50c5\u652f\u6301\u9078\u64c7\u8a72\u90e8\u9580\u7684\u6210\u54e1\u7528\u6236 +explorer.share.myAuth=\u6211\u7684\u6b0a\u9650 +explorer.share.othersAuth=\u5176\u4ed6\u4eba\u6b0a\u9650 +explorer.share.keepAuth=\u4fdd\u6301\u539f\u4f86\u6b0a\u9650 +explorer.share.specifyAuth=\u6307\u5b9a\u6b0a\u9650 +explorer.share.userAuth=\u7528\u6236\u6b0a\u9650 +explorer.share.specifyUserAuth=\u6307\u5b9a\u7528\u6236\u6b0a\u9650 +explorer.share.rptTitle=\u5982\u6709\u767c\u73fe\u9055\u6cd5\u6709\u5bb3\u4fe1\u606f��\u8acb\u5728\u4e0b\u65b9\u9078\u64c7\u539f\u56e0\u63d0\u4ea4\u8209\u5831�� +explorer.share.illegal=\u9055\u6cd5\u4fe1\u606f +explorer.share.inputRptDesc=\u8acb\u8f38\u5165\u8209\u5831\u539f\u56e0 +explorer.share.rptSend=\u63d0\u4ea4\u6210\u529f��\u7ba1\u7406\u54e1\u5c07\u6703\u53ca\u6642\u8655\u7406 +explorer.share.rptSended=\u8209\u5831\u5df2\u63d0\u4ea4��\u7b49\u5f85\u7ba1\u7406\u54e1\u8655\u7406 +explorer.auth.mutil=\u6279\u91cf\u8a2d\u7f6e\u6b0a\u9650 +explorer.auth.mutilTips=\u6ce8\u610f:\u5982\u679c\u6240\u9078\u5167\u5bb9\u5df2\u7d93\u6709\u6b0a\u9650\u5247\u6703\u88ab\u8986\u84cb. +explorer.auth.mutilDesc=\u540c\u6642\u4f5c\u70ba\u5f8c\u7e8c\u9ed8\u8a8d\u6b0a\u9650 +explorer.auth.showMore=\u6b0a\u9650\u8a73\u60c5 +explorer.auth.tabUser=\u90e8\u9580\u6210\u54e1 +explorer.auth.tabChildren=\u5b50\u6587\u4ef6\u593e\u6b0a\u9650 +explorer.auth.tabUserTips=\u90e8\u9580\u6210\u54e1\u521d\u59cb\u6b0a\u9650 +explorer.auth.tabChildrenTips=\u8a72\u6587\u4ef6\u593e\u4e0b\u8a2d\u7f6e\u904e\u6b0a\u9650\u7684\u5167\u5bb9 +explorer.auth.resetUser=\u8986\u84cb\u8a2d\u7f6e\u8a72\u7528\u6236\u6b0a\u9650 +explorer.auth.resetUserBtn=\u8986\u84cb\u6b0a\u9650 +explorer.auth.resetUserBtnTips=\u8986\u84cb\u8a72\u7528\u6236\u5728\u8a72\u6587\u4ef6\u593e\u6240\u6709\u5b50\u6587\u4ef6(\u593e)\u6b0a\u9650 +explorer.auth.resetUserHeader=\u4e0b\u7d1a\u6587\u4ef6\u593e\u4e2d\u5305\u542b\u6307\u5b9a\u8a72\u7528\u6236\u6b0a\u9650\u7684\u5167\u5bb9\u5c07\u5168\u90e8\u8986\u84cb\u8a2d\u7f6e\u70ba\u4e0a\u8ff0\u6b0a\u9650 +explorer.auth.resetUserContiner=\u5305\u542b\u8a72\u7528\u6236\u6b0a\u9650\u5167\u5bb9 +explorer.auth.resetUserEmpty1=\u6c92\u6709\u91dd\u5c0d\u8a72\u7528\u6236\u8a2d\u7f6e\u6b0a\u9650\u7684\u5167\u5bb9\u7121\u9700\u8986\u84cb +explorer.auth.resetUserEmpty2=\u6240\u6709\u5b50\u5167\u5bb9\u90fd\u7e7c\u627f\u7576\u524d\u5c64\u7d1a\u6587\u4ef6\u593e\u6b0a\u9650 +explorer.rename.mutil=\u6279\u91cf\u91cd\u547d\u540d +explorer.rename.nameBefore=\u539f\u6587\u4ef6\u540d +explorer.rename.nameTo=\u91cd\u547d\u540d\u70ba +explorer.rename.start=\u7acb\u5373\u91cd\u547d\u540d +explorer.rename.clearFinished=\u6e05\u7a7a\u5df2\u5b8c\u6210 +explorer.rename.clearAll=\u6e05\u7a7a\u6240\u6709 +explorer.rename.typeReplaceAll=\u5168\u90e8\u66ff\u63db +explorer.rename.typePrepend=\u524d\u9762\u8ffd\u52a0 +explorer.rename.typeAppend=\u5f8c\u9762\u8ffd\u52a0 +explorer.rename.typeReplace=\u67e5\u627e\u66ff\u63db +explorer.rename.typeChangeCase=\u5927\u5c0f\u5beb\u8f49\u63db +explorer.rename.typeRemove=\u522a\u9664\u5b57\u7b26 +explorer.rename.typeReplaceSet=\u6279\u91cf\u6307\u5b9a\u66ff\u63db +explorer.rename.typeReplaceSetDesc=\u76f8\u7b49\u6642\u5247\u66ff\u63db;\u6bcf\u884c\u4e00\u9805\u7a7a\u683c\u9694\u958b\u6587\u4ef6\u540d\u4e0d\u5141\u8a31\u7a7a\u683c;\u4f8b\u5982: +explorer.rename.numberStart=\u8ba1\u6570\u5f00\u59cb +explorer.rename.appendContent=\u8ffd\u52a0\u5167\u5bb9 +explorer.rename.find=\u67e5\u627e +explorer.rename.replaceTo=\u66ff\u63db\u70ba +explorer.rename.caseUpperFirst=\u9996\u5b57\u6bcd\u5927\u5beb +explorer.rename.caseUpper=\u5168\u5927\u5beb +explorer.rename.caseLower=\u5168\u5c0f\u5beb +explorer.rename.removeStart=\u5f9e\u982d\u522a\u9664 +explorer.rename.removeEnd=\u5f9e\u7d50\u5c3e\u522a\u9664 +explorer.rename.chars=\u5b57\u7b26 +explorer.editor.beautifyCode=\u4ee3\u78bc\u683c\u5f0f\u5316 +explorer.editor.convertCase=\u5927\u5c0f\u5beb\u8f49\u63db +explorer.editor.convertUpperCase=\u8f49\u63db\u70ba\u5927\u5beb +explorer.editor.convertLowerCase=\u8f49\u63db\u70ba\u5c0f\u5beb +explorer.editor.currentTime=\u7576\u524d\u6642\u9593 +explorer.editor.md5=md5\u52a0\u5bc6 +explorer.editor.qrcode=\u5b57\u7b26\u4e32\u4e8c\u7dad\u78bc +explorer.editor.regx=\u6b63\u5247\u8868\u9054\u5f0f\u6e2c\u8a66 +explorer.editor.chinese=\u7e41\u7c21\u8f49\u63db +explorer.editor.chineseSimple=\u8f49\u63db\u70ba\u7c21\u9ad4\u4e2d\u6587 +explorer.editor.chineseTraditional=\u8f49\u63db\u70ba\u7e41\u9ad4\u4e2d\u6587 +explorer.editor.base64=base64\u7de8\u89e3\u78bc +explorer.editor.base64Encode=base64\u7de8\u78bc +explorer.editor.base64Decode=base64\u89e3\u78bc +explorer.editor.url=URL\u7de8\u89e3\u78bc +explorer.editor.urlEncode=URL\u7de8\u78bc +explorer.editor.urlDecode=URL\u89e3\u78bc +explorer.editor.unicode=Unicode\u7de8\u89e3\u78bc +explorer.editor.unicodeEncode=Unicode\u7de8\u78bc +explorer.editor.unicodeDecode=Unicode\u89e3\u78bc +explorer.editor.toolsSelectTips=\u8acb\u9078\u4e2d\u6b63\u78ba\u7684\u5f85\u8655\u7406\u5167\u5bb9! +explorer.editor.toolsRandString=\u751f\u621032\u4f4d\u96a8\u6a5f\u5b57\u7b26\u4e32 +explorer.editor.textEncode=\u6587\u672c\u7de8\u78bc/\u89e3\u78bc +explorer.editor.textParse=\u6587\u672c\u8655\u7406 +explorer.editor.timeShow=\u6642\u9593\u6233\u8f49\u6642\u9593 +explorer.editor.timeInt=\u6642\u9593\u8f49\u6642\u9593\u6233 +explorer.editor.lineRemoveEmpty=\u79fb\u9664\u7a7a\u884c(\u542b\u7a7a\u683c) +explorer.editor.lineUnoin=\u79fb\u9664\u91cd\u8907\u884c +explorer.editor.lineTrim=\u79fb\u9664\u9996\u5c3e\u7a7a\u683c +explorer.editor.lineSort=\u6309\u884c\u6392\u5e8f(\u5347\u5e8f) +explorer.editor.lineReverse=\u4e0a\u4e0b\u8abf\u63db\u6240\u6709\u884c +explorer.editor.lineSum=\u6c42\u548c +explorer.editor.lineAverage=\u5e73\u5747\u503c +explorer.editor.calc=\u81ea\u7531\u8a08\u7b97\u5668 +explorer.editor.goToLine=\u8df3\u8f49\u5230\u884c +explorer.editor.keyboardType=\u9375\u76e4\u6a21\u5f0f +explorer.editor.fontFamily=\u5b57\u9ad4 +explorer.editor.codeMode=\u9ad8\u4eae\u8a9e\u6cd5 +explorer.editor.closeAll=\u95dc\u9589\u5168\u90e8 +explorer.editor.closeLeft=\u95dc\u9589\u5de6\u5074\u6a19\u7c64 +explorer.editor.closeRight=\u95dc\u9589\u53f3\u5074\u6a19\u7c64 +explorer.editor.closeOthers=\u95dc\u9589\u5176\u4ed6 +explorer.editor.wordwrap=\u81ea\u52d5\u63db\u884c +explorer.editor.showGutter=\u986f\u793a\u884c\u865f +explorer.editor.charAllDisplay=\u986f\u793a\u4e0d\u53ef\u898b\u5b57\u7b26 +explorer.editor.autoComplete=\u81ea\u52d5\u63d0\u793a +explorer.editor.autoSave=\u81ea\u52d5\u4fdd\u5b58 +explorer.editor.functionList=\u51fd\u6578\u5217\u8868 +explorer.editor.codeTheme=\u4ee3\u78bc\u98a8\u683c +explorer.editor.fontSize=\u5b57\u9ad4\u5927\u5c0f +explorer.editor.completeCurrent=\u81ea\u52d5\u88dc\u5168\u7576\u524d +explorer.editor.createProject=\u6dfb\u52a0\u5230\u7de8\u8f2f\u5668\u5de5\u7a0b +explorer.editor.markdownContent=\u5167\u5bb9\u76ee\u9304 +explorer.editor.undo=\u64a4\u92b7 +explorer.editor.redo=\u53cd\u64a4\u92b7 +explorer.editor.shortcut=\u5feb\u6377\u9375 +explorer.editor.replace=\u66ff\u63db +explorer.editor.reload=\u91cd\u65b0\u8f09\u5165 +explorer.editor.view=\u8996\u5716 +explorer.editor.tools=\u5de5\u5177 +explorer.editor.help=\u5e6b\u52a9 +explorer.sync.data=\u6578\u64da\u540c\u6b65 +explorer.sync.openLoc=\u6253\u958b\u672c\u5730\u76ee\u9304 +explorer.sync.syncing=\u6b63\u5728\u540c\u6b65 +explorer.sync.synced=\u540c\u6b65\u5b8c\u6210 +explorer.sync.syncedError=\u932f\u8aa4\u8a18\u9304 +explorer.sync.syncStart=\u958b\u59cb\u540c\u6b65 +explorer.sync.syncStop=\u505c\u6b62\u540c\u6b65 +explorer.sync.notOpenTips=\u60a8\u672a\u958b\u555f\u672c\u5730\u540c\u6b65 +explorer.sync.setNow=\u7acb\u5373\u8a2d\u7f6e\u540c\u6b65 +explorer.sync.error=\u4e0a\u50b3\u5931\u6557 +explorer.sync.success=\u540c\u6b65\u6210\u529f +explorer.sync.statusScan=\u6383\u63cf\u4e2d +explorer.sync.statusNone=\u540c\u6b65\u672a\u914d\u7f6e +explorer.sync.statusScanEnd=\u6383\u63cf\u5b8c\u6210 +explorer.sync.statusDoing=\u540c\u6b65\u4e2d +explorer.sync.statusDone=\u540c\u6b65\u5b8c\u6210 +explorer.sync.statusStop=\u66ab\u505c\u4e2d +explorer.sync.clearCacheSuccess=\u6e05\u9664\u7de9\u5b58\u6210\u529f! +explorer.sync.emptyTask=\u66ab\u7121\u540c\u6b65\u4efb\u52d9 +explorer.sync.openCloud=\u6253\u958b\u96f2\u7aef\u6240\u5728\u4f4d\u7f6e +explorer.sync.openLocal=\u672c\u5730\u6253\u958b +explorer.sync.statusFiles=\u6587\u4ef6\u9032\u5ea6 +explorer.sync.statusLastTime=\u5b8c\u6210\u6642\u9593 +explorer.sync.configName=\u540c\u6b65\u8a2d\u7f6e +explorer.sync.configClient=\u5ba2\u6236\u7aef\u8a2d\u7f6e +explorer.sync.configAbout=\u95dc\u65bc +explorer.sync.configSyncFrom=\u672c\u5730\u8def\u5f91 +explorer.sync.configSyncFromDesc=\u9078\u64c7\u8981\u540c\u6b65\u7684\u672c\u5730\u6587\u4ef6\u593e +explorer.sync.configSyncTo=\u540c\u6b65\u5230 +explorer.sync.configSyncToDesc=\u540c\u6b65\u5230\u670d\u52d9\u5668\u4f4d\u7f6e +explorer.sync.configIgnore=\u5ffd\u7565\u7684\u6587\u4ef6\u985e\u578b +explorer.sync.configIgnoreDesc=\u8a72\u985e\u578b\u6587\u4ef6\u4e0d\u9032\u884c\u540c\u6b65 +explorer.sync.autorun=\u958b\u6a5f\u81ea\u555f\u52d5 +explorer.sync.configThread=\u4e26\u767c\u7dda\u7a0b\u6578 +explorer.sync.configThreadDesc=\u540c\u6642\u4e0a\u50b3\u6587\u4ef6\u6578\u91cf +explorer.sync.configDownloadPath=\u4e0b\u8f09\u8def\u5f91 +explorer.sync.configDownloadPathDesc=\u4e0b\u8f09\u6587\u4ef6\u6587\u4ef6\u593e\u6642\u9ed8\u8a8d\u4e0b\u8f09\u8def\u5f91 +explorer.sync.configClearCacheAuto=\u81ea\u52d5\u6e05\u7a7a\u7de9\u5b58 +explorer.sync.configClearCacheAutoDesc=\u81ea\u52d5\u6e05\u7a7aN\u5929\u524d\u7de9\u5b58\u6587\u4ef6 +explorer.sync.configClearCache=\u6e05\u7a7a\u7de9\u5b58 +explorer.sync.configChangeSite=\u9000\u51fa\u7576\u524d\u7ad9\u9ede +explorer.sync.configVersion=\u7576\u524d\u7248\u672c +explorer.sync.configUpdateDesc=\u66f4\u65b0\u8aaa\u660e +explorer.sync.configUpdateCheck=\u6aa2\u6e2c\u66f4\u65b0 +explorer.sync.confirmReset=\u540c\u6b65\u76ee\u9304\u4fee\u6539\u540c\u6b65\u4fe1\u606f\u5c07\u91cd\u7f6e\u78ba\u5b9a\u4fdd\u5b58? +explorer.sync.listClearDone=\u6e05\u7a7a\u5df2\u5b8c\u6210 +explorer.sync.listClearError=\u6e05\u7a7a\u932f\u8aa4\u5217\u8868 +explorer.sync.listRetryAll=\u5168\u90e8\u91cd\u8a66 +explorer.async.tipsDisablePath=\u4e0d\u652f\u6301\u9078\u64c7\u540c\u6b65\u8a72\u8def\u5f91 +explorer.async.tipsIsMoving=\u6aa2\u6e2c\u5230\u7576\u524d\u5927\u91cf\u5167\u5bb9\u6b63\u5728\u79fb\u52d5\u6216\u8907\u88fd\u5230\u540c\u6b65\u76ee\u9304;
    \u5efa\u8b70\u672c\u5730\u5b8c\u6210\u5f8c\u5237\u65b0\u9801\u9762\u9032\u884c\u540c\u6b65! +explorer.async.tipsStartUser=\u624b\u52d5\u958b\u59cb\u540c\u6b65 +explorer.download.title=\u4e0b\u8f09\u7ba1\u7406 +explorer.download.waiting=\u7b49\u5f85\u4e2d +explorer.download.stop=\u66ab\u505c\u4e0b\u8f09 +explorer.download.start=\u958b\u59cb\u4e0b\u8f09 +explorer.download.remove=\u79fb\u9664\u4efb\u52d9 +explorer.download.stopAll=\u5168\u90e8\u66ab\u505c +explorer.download.startAll=\u5168\u90e8\u7e7c\u7e8c +explorer.download.clearAll=\u6e05\u7a7a\u6240\u6709\u4efb\u52d9 +explorer.download.doing=\u9032\u884c\u4e2d +explorer.download.done=\u4e0b\u8f09\u5b8c\u6210 +explorer.download.clearAllTips=\u78ba\u5b9a\u522a\u9664\u6240\u6709\u4e0b\u8f09\u4efb\u52d9\u55ce? +explorer.tag.name=\u6a19\u7c64 +explorer.tag.edit=\u6a19\u7c64\u7ba1\u7406 +explorer.tag.add=\u5275\u5efa\u6a19\u7c64 +explorer.tag.remove=\u78ba\u5b9a\u522a\u9664\u8a72\u6a19\u7c64\u55ce? +explorer.tag.inputHolder=\u8acb\u8f38\u5165\u6a19\u7c64\u540d\u7a31 +explorer.tag.addTo=\u8a2d\u7f6e\u6a19\u7c64 +explorer.tag.default1=\u5b78\u7fd2\u8cc7\u6599 +explorer.tag.default2=\u6e2c\u8a66\u6578\u64da +explorer.tag.default3=\u5408\u540c +explorer.tag.filter=\u6309\u6a19\u7c64\u7be9\u9078 +explorer.groupTag.title=\u516c\u5171\u6a19\u7c64 +explorer.groupTag.menuTtitle=\u90e8\u9580\u516c\u5171\u6a19\u7c64 +explorer.groupTag.titleDesc=\u90e8\u9580\u5167\u516c\u5171\u6a19\u7c64 +explorer.groupTag.empty=\u90e8\u9580\u7ba1\u7406\u54e1\u8a2d\u7f6e\u516c\u5171\u6a19\u7c64\u5f8c\u81ea\u52d5\u555f\u7528.\u6c92\u6709\u6a19\u7c64\u5167\u5bb9\u6642\u81ea\u52d5\u95dc\u9589\u516c\u5171\u6a19\u7c64! +explorer.tag.pathDesc=\u6309\u500b\u4eba\u6a19\u7c64\u7be9\u9078 +explorer.groupTag.pathDesc=\u6309\u90e8\u9580\u516c\u5171\u6a19\u7c64\u7be9\u9078 +explorer.groupTag.removeTypeTips=\u78ba\u8a8d\u522a\u9664\u8a72\u5206\u7d44\u55ce?\u522a\u9664\u5f8c\u6240\u6709\u6240\u5c6c\u6a19\u7c64\u95dc\u806f\u7684\u6587\u6a94\u90fd\u6703\u9032\u884c\u89e3\u9664! +explorer.groupTag.removeTagTips=\u78ba\u8a8d\u522a\u9664\u8a72\u6a19\u7c64\u55ce?\u522a\u9664\u5f8c\u6a19\u7c64\u95dc\u806f\u7684\u6587\u6a94\u6703\u9032\u884c\u89e3\u9664! +explorer.groupTag.typeAdd=\u6dfb\u52a0\u5206\u985e +explorer.groupTag.typeName=\u5206\u985e\u540d\u7a31 +explorer.groupTag.addDesc=\u6dfb\u52a0\u6a19\u7c64\u5f8c\u81ea\u52d5\u555f\u7528\u90e8\u9580\u6a19\u7c64\u6a19\u7c64\u4e0a\u96501000\u500b +explorer.panel.info=\u5c6c\u6027 +explorer.panel.version=\u7248\u672c +explorer.panel.chat=\u8a0e\u8ad6 +explorer.panel.log=\u52d5\u614b +explorer.panel.meta=\u95dc\u806f\u4fe1\u606f +explorer.panel.chatName=\u4ea4\u6d41\u8a0e\u8ad6 +explorer.panel.chat.send=\u767c\u9001 +explorer.panel.chat.noAuth=\u8a72\u6587\u6a94\u60a8\u6c92\u6709\u8a55\u8ad6\u6b0a\u9650! +explorer.panel.chat.placeholder=\u5728\u9019\u88e1\u8f38\u5165Enter\u767c\u9001Ctrl+Enter\u63db\u884c +explorer.panel.chat.placeholderCtrl=\u5728\u9019\u88e1\u8f38\u5165Ctrl+Enter\u767c\u9001Enter\u63db\u884c +explorer.panel.chat.reply=\u56de\u590d +explorer.panel.chat.empty=\u6c92\u6709\u8a55\u8ad6 +explorer.panel.chat.sendTo=\u8f49\u767c +explorer.panel.metaName=\u95dc\u806f\u6578\u64da\u64f4\u5c55 +explorer.panel.metaDesc=\u64f4\u5c55\u6587\u6a94\u5b57\u6bb5\u5c6c\u6027 +explorer.panel.thumbClear=\u6e05\u9664\u7e2e\u7565\u5716 +explorer.panel.thumbClearDesc=\u6e05\u9664\u6587\u4ef6\u7e2e\u7565\u5716��\u5c01\u9762\u5716��\u4ee5\u91cd\u65b0\u751f\u6210�� +explorer.panel.historyName=\u6b77\u53f2\u7248\u672c +explorer.panel.historyDesc=\u7248\u672c\u8aaa\u660e +explorer.panel.infoTips=\u9078\u4e2d\u6587\u4ef6(\u593e)\u67e5\u770b\u8a73\u7d30\u5c6c\u6027 +explorer.panel.info.space=\u7a7a\u9593\u5bb9\u91cf +explorer.panel.info.groupAt=\u90e8\u9580\u4f4d\u7f6e +explorer.panel.info.tagEmpty=\u66ab\u7121\u6a19\u7c64\u9ede\u64ca\u8a2d\u7f6e +explorer.panel.logName=\u6587\u6a94\u52d5\u614b +explorer.panel.logEmpty=\u6c92\u6709\u52d5\u614b +explorer.type.doc=\u6587\u6a94 +explorer.type.image=\u5716\u7247 +explorer.type.music=\u97f3\u6a02 +explorer.type.movie=\u8996\u983b +explorer.type.zip=\u58d3\u7e2e\u5305 +explorer.type.others=\u5176\u4ed6 +explorer.secret.title=\u6587\u6a94\u5bc6\u7d1a\u7ba1\u7406 +explorer.secret.isOpen=\u662f\u5426\u555f\u7528 +explorer.secret.isOpenDesc=\u958b\u555f\u95dc\u9589\u5bc6\u7d1a\u7ba1\u7406 +explorer.secret.setUser=\u5bc6\u7d1a\u7ba1\u7406\u8005 +explorer.secret.setUserDesc=\u6307\u5b9a\u53ef\u4ee5\u8a2d\u7f6e\u5bc6\u7d1a\u7684\u7528\u6236(\u5fc5\u9808\u5728\u5c0d\u61c9\u90e8\u9580\u540c\u6642\u70ba\u64c1\u6709\u8005) +explorer.secret.type=\u5bc6\u7d1a\u985e\u578b +explorer.secret.add=\u6dfb\u52a0\u5bc6\u7d1a +explorer.secret.edit=\u7de8\u8f2f\u5bc6\u7d1a +explorer.secret.name=\u5bc6\u7d1a\u540d\u7a31 +explorer.secret.style=\u6a23\u5f0f +explorer.secret.auth=\u5bc6\u7d1a\u6b0a\u9650 +explorer.secret.authHas=\u5bc6\u7d1a\u6b0a\u9650\u5305\u542b +explorer.secret.createUser=\u8a2d\u7f6e\u8005 +explorer.secret.folderAt=\u5bc6\u7d1a\u6587\u4ef6\u593e +explorer.secret.tips=\u6b0a\u9650\u53d7\u5bc6\u7d1a\u63a7\u5236\u5bc6\u7d1a\u6b0a\u9650\u9ad8\u65bc\u6587\u6a94\u6b0a\u9650 +explorer.secret.tips1=\u50c5\u9650\u90e8\u9580\u7db2\u76e4\u4e0b\u5167\u5bb9\u4e0a\u8ff0\u6307\u5b9a\u7528\u6236\u624d\u80fd\u8a2d\u7f6e\u5bc6\u7d1a(\u540c\u6642\u5fc5\u9808\u70ba\u6587\u4ef6\u593e\u64c1\u6709\u8005) +explorer.secret.tips2=\u8a2d\u7f6e\u5bc6\u7d1a\u7684\u6587\u4ef6\u593e\u4e0b\u5c64\u6240\u6709\u5167\u5bb9\u90fd\u4ee5\u6b64\u6b0a\u9650\u70ba\u6700\u9ad8\u6b0a\u9650 +explorer.secret.tips3=\u8a2d\u7f6e\u5f8c\u5bc6\u7d1a\u6b0a\u9650\u9ad8\u65bc\u6587\u6a94\u6b0a\u9650(\u6587\u6a94\u64c1\u4e5f\u53d7\u5bc6\u7d1a\u6b0a\u9650\u63a7\u5236\u7cfb\u7d71\u8d85\u7d1a\u7ba1\u7406\u54e1\u4e0d\u53d7\u8a72\u9650\u5236\u5bc6\u7d1a\u8a2d\u7f6e\u8005\u81ea\u5df1\u4e0d\u53d7\u8a72\u9650\u5236) +explorer.secret.tips4=\u5bc6\u7d1a\u6b0a\u9650:\u53ef\u4ee5\u5728\\u90e8\u9580\u8207\u6210\u54e1\u7ba1\u7406--\u6587\u6a94\u6b0a\u9650\u7ba1\u7406\\u4e2d\u6dfb\u52a0\u4e26\u8a2d\u7f6e\u70ba\u96b1\u85cf +user.----=---- +user.displayHideFile=\u986f\u793a\u96b1\u85cf\u6587\u4ef6 +user.displayHideFileDesc=\u96b1\u85cf\u6587\u4ef6:\u4ee5.\u958b\u982d\u7684\u6587\u4ef6\u53ca\u7cfb\u7d71\u5f8c\u53f0\u8a2d\u7f6e\u7684\u96b1\u85cf\u6587\u4ef6\u540d;\u958b\u555f\u5f8c\u96b1\u85cf\u6587\u4ef6\u6703\u986f\u793a; +user.soundOpen=\u958b\u555f\u97f3\u6548 +user.animateOpen=\u958b\u555f\u52d5\u756b +user.recycleOpen=\u958b\u555f\u56de\u6536\u7ad9 +user.recycleDesc=\u958b\u555f\u5f8c\u522a\u9664\u6703\u79fb\u5230\u56de\u6536\u7ad9\u5efa\u8b70\u958b\u555f +user.animateDesc=\u7a97\u53e3\u6253\u958b\u7b49\u52d5\u756b\u64cd\u4f5c\u4e0d\u6d41\u66a2\u6642\u53ef\u4ee5\u8003\u616e\u95dc\u9589 +user.soundDesc=\u6253\u958b\u6587\u4ef6��\u522a\u9664\u6587\u4ef6��\u6e05\u7a7a\u56de\u6536\u7ad9\u7b49\u64cd\u4f5c\u97f3\u6548 +user.thumbOpen=\u958b\u555f\u5716\u7247\u7e2e\u7565\u5716 +user.thumbDesc=\u958b\u555f\u5f8c\u5716\u7247\u700f\u89bd\u9ad4\u9a57\u66f4\u4f73 +user.fileSelect=\u958b\u555f\u6587\u4ef6\u5716\u6a19\u52fe\u9078 +user.fileSelectDesc=\u6587\u4ef6\u5716\u6a19\u7684\u5de6\u9375\u52fe\u9078��\u53f3\u9375\u83dc\u55ae\u7684\u5feb\u6377\u5165\u53e3 +user.fileShowDesc=\u986f\u793a\u6587\u4ef6\u593e\u7c21\u4ecb +user.fileShowDescTips=\u50c5\u5716\u6a19\u6a21\u5f0f +user.fileOpenClick=\u6309\u5982\u4e0b\u65b9\u5f0f\u6253\u958b\u6587\u4ef6(\u593e) +user.fileOpenClick.dbclick=\u901a\u904e\u96d9\u64ca\u6253\u958b +user.fileOpenClick.click=\u901a\u904e\u55ae\u64ca\u6253\u958b +user.viewSetting=\u986f\u793a\u9078\u9805 +user.thirdAccount=\u7b2c\u4e09\u65b9\u8cec\u865f +user.bindAccount=\u7d81\u5b9a\u8cec\u865f +user.thirdBindFirst=\u8cec\u865f\u5c1a\u672a\u7d81\u5b9a��\u8acb\u7d81\u5b9a\u5f8c\u4f7f\u7528 +user.account=\u8cec\u865f +user.bind=\u7d81\u5b9a +user.unbind=\u89e3\u7d81 +user.binded=\u5df2\u7d81\u5b9a +user.clickBind=\u9ede\u64ca\u7d81\u5b9a +user.clickToBind=\u672a\u7d81\u5b9a\u9ede\u64ca\u7d81\u5b9a +user.clickEditPwd=\u9ede\u64ca\u4fee\u6539\u5bc6\u78bc +user.userAvatar=\u500b\u4eba\u982d\u50cf +user.userNickName=\u500b\u4eba\u66b1\u7a31 +user.userAccount=\u500b\u4eba\u8cec\u865f +user.uploadAvatar=\u4e0a\u50b3\u982d\u50cf +user.userAvatarCrop=\u8acb\u9078\u64c7\u5408\u9069\u7684\u5340\u57df\u4f5c\u70ba\u982d\u50cf +user.userAvatarExt=\u50c5\u652f\u6301JPG��JPEG��PNG\u7684\u5716\u7247\u683c\u5f0f +user.resetPwdDesc=\u5fd8\u8a18\u5bc6\u78bc?\u60a8\u53ef\u4ee5\u9032\u884c +user.inputEmailCode=\u8acb\u8f38\u5165\u90f5\u7bb1\u9a57\u8b49\u78bc +user.inputSmsCode=\u8acb\u8f38\u5165\u77ed\u4fe1\u9a57\u8b49\u78bc +user.emailVerifyDesc=\u90e8\u5206\u696d\u52d9\u9700\u8981\u7528\u90f5\u7bb1\u9a57\u8b49 +user.phoneVerifyDesc=\u90e8\u5206\u696d\u52d9\u9700\u8981\u7528\u624b\u6a5f\u9a57\u8b49 +user.bindOthers=\u5df2\u7d81\u5b9a\u5176\u4ed6\u8cec\u865f +user.notBind=\u5c1a\u672a\u7d81\u5b9a +user.regist=\u7528\u6236\u8a3b\u518a +user.notRegist=\u5c1a\u672a\u8a3b\u518a +user.registed=\u5df2\u88ab\u8a3b\u518a +user.signError=\u56de\u8abf\u7c3d\u540d\u6709\u8aa4 +user.repeat=\u91cd\u8907 +user.noRepeat=\u4e0d\u80fd\u91cd\u8907 +user.newPwd=\u65b0\u5bc6\u78bc +user.unAuthFile=\u672a\u6388\u6b0a\u7684\u6587\u4ef6\u8a2a\u554f +user.unbindWarning=\u89e3\u7d81\u524d\u8acb\u5148\u4fee\u6539\u5bc6\u78bc��\u5426\u5247\u5c07\u5c0e\u81f4\u8a72\u8cec\u865f\u7121\u6cd5\u6b63\u5e38\u4f7f\u7528 +user.isLoginTips=\u6aa2\u6e2c\u5230\u60a8\u7576\u524d\u5df2\u767b\u9304! +user.isLoginEnter=\u7acb\u5373\u9032\u5165 +user.ifUnbind=\u78ba\u5b9a\u8981\u89e3\u9664\u7d81\u5b9a\u55ce? +user.bindFirst=\u8acb\u5148\u7d81\u5b9a\u90f5\u7bb1\u6216\u624b\u6a5f\u865f +user.inputNewPwd=\u8acb\u8f38\u5165\u65b0\u7684\u5bc6\u78bc +user.inputNewValue=\u8acb\u586b\u5beb\u65b0\u7684\u5167\u5bb9 +user.guestLogin=\u904a\u5ba2\u767b\u9304 +user.name=\u767b\u9304\u8cec\u865f +user.nickName=\u7528\u6236\u66b1\u7a31 +user.code=\u9a57\u8b49\u78bc +user.codeError=\u9a57\u8b49\u78bc\u932f\u8aa4 +user.imgCode=\u5716\u5f62\u9a57\u8b49\u78bc +user.rootPwd=\u8a2d\u7f6e\u7ba1\u7406\u54e1\u5bc6\u78bc +user.rootPwdRepeat=\u518d\u6b21\u78ba\u8a8d\u5bc6\u78bc +user.rootPwdEqual=\u5169\u6b21\u5bc6\u78bc\u4e0d\u4e00\u81f4�� +user.rootPwdTips=\u8acb\u8a2d\u7f6e\u7ba1\u7406\u54e1\u5bc6\u78bc�� +user.pwdError=\u7528\u6236\u540d\u6216\u5bc6\u78bc\u932f\u8aa4! +user.pwdNotNull=\u5bc6\u78bc\u4e0d\u80fd\u70ba\u7a7a! +user.oldPwdError=\u539f\u5bc6\u78bc\u932f\u8aa4! +user.keepPwd=\u8a18\u4f4f\u5bc6\u78bc +user.forgetPwd=\u5fd8\u8a18\u5bc6\u78bc +user.directLogin=\u5df2\u6709\u8cec\u865f\u767b\u9304 +user.moreLogin=\u66f4\u591a\u767b\u9304\u65b9\u5f0f +user.loginNow=\u7acb\u5373\u767b\u9304 +user.registNow=\u7acb\u5373\u8a3b\u518a +user.backHome=\u8fd4\u56de\u9996\u9801 +user.ifHasAccount=\u5df2\u6709\u8cec\u865f�� +user.userEnabled=\u8cec\u865f\u88ab\u7981\u7528\u6216\u5c1a\u672a\u555f\u7528��\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1 +user.roleError=\u6240\u5c6c\u6b0a\u9650\u7d44\u4e0d\u5b58\u5728��\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1 +user.invalidEmail=\u60a8\u6c92\u6709\u6709\u6548\u7684\u90f5\u7bb1\u5730\u5740\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1\u4fee\u6539 +user.codeRefresh=\u9ede\u64ca\u5237\u65b0 +user.emailVerify=\u90f5\u7bb1\u8eab\u4efd\u9a57\u8b49 +user.sendSuccess=\u767c\u9001\u6210\u529f +user.sendFail=\u767c\u9001\u5931\u6557 +user.sendSuccessDesc=\u9a57\u8b49\u78bc\u767c\u9001\u6210\u529f\u8acb\u524d\u5f80\u67e5\u770b +user.sendFailDesc=\u9a57\u8b49\u78bc\u767c\u9001\u5931\u6557\u8acb\u806f\u7e6b\u7ba1\u7406\u54e1 +user.inputVerifyCode=\u8acb\u8f38\u5165\u9a57\u8b49\u78bc +user.getCode=\u7372\u53d6\u9a57\u8b49\u78bc +user.inputPwd=\u8acb\u8f38\u5165\u5bc6\u78bc +user.inputPwdAgain=\u8acb\u518d\u6b21\u8f38\u5165\u5bc6\u78bc +user.inputNickName=\u8acb\u8f38\u5165\u66b1\u7a31 +user.inputEmail=\u8acb\u8f38\u5165\u90f5\u7bb1\u5730\u5740 +user.inputPhone=\u8acb\u8f38\u5165\u624b\u6a5f\u865f +user.inputPhoneEmail=\u8acb\u8f38\u5165\u624b\u6a5f/Email +user.invalidPhoneEmail=\u7121\u6548\u7684\u624b\u6a5f/Email +user.findPwd=\u627e\u56de\u5bc6\u78bc +user.inputNotMatch=\u8f38\u5165\u7684%s\u8207\u5df2\u7d81\u5b9a\u7684\u4e0d\u76f8\u7b26 +user.usingDesc=\u60a8\u6b63\u5728\u4f7f\u7528 +user.improveInfo=\u8acb\u5b8c\u5584\u4fe1\u606f +user.codeExpired=\u9a57\u8b49\u78bc\u5df2\u904e\u671f\u8acb\u91cd\u65b0\u7372\u53d6 +user.codeErrorTooMany=\u9a57\u8b49\u78bc\u932f\u8aa4\u6b21\u6578\u904e\u591a\u8acb\u91cd\u65b0\u7372\u53d6 +user.codeErrorFreq=\u767c\u9001\u983b\u7387\u904e\u9ad8��\u8acb\u7a0d\u5f8c\u518d\u8a66�� +user.codeErrorCnt=\u767c\u9001\u6b21\u6578\u5df2\u8d85\u9650\u5236��\u5c07\u88ab\u9396\u5b9a%s\u5c0f\u6642�� +user.registSuccess=\u8a3b\u518a\u6210\u529f +user.waitCheck=\u7b49\u5f85\u7ba1\u7406\u54e1\u5be9\u6838 +user.nameHolder=\u8acb\u8f38\u5165\u624b\u6a5f\u865f/Email +user.loginNoPermission=\u62b1\u6b49\u60a8\u6c92\u6709\u8a72\u6b0a\u9650\u8acb\u4f7f\u7528\u6709\u6b64\u6b0a\u9650\u7684\u8cec\u865f\u767b\u9304! +user.loginFirst=\u60a8\u5c1a\u672a\u767b\u9304!\u8acb\u5148\u767b\u9304 +user.bindSignError=\u7c3d\u540d\u7570\u5e38��\u8acb\u91cd\u65b0\u64cd\u4f5c\u4e00\u6b21�� +user.bindUpdateError=\u7528\u6236\u4fe1\u606f\u66f4\u65b0\u5931\u6557��\u8acb\u91cd\u8a66 +user.bindTypeError=\u7121\u6548\u7684\u7d81\u5b9a\u985e\u578b +user.bindWxConfigError=\u7372\u53d6\u914d\u7f6e\u4fe1\u606f\u7570\u5e38 +user.loginTimeout=\u7576\u524d\u767b\u9304\u5df2\u8d85\u6642��\u8acb\u91cd\u65b0\u767b\u9304�� +user.theme=\u4e3b\u984c\u6a23\u5f0f +user.theme.desc=\u81ea\u52d5\u4ee3\u8868\u8ddf\u96a8\u7cfb\u7d71 +user.theme.light=\u6dfa\u8272 +user.theme.dark=\u6df1\u8272 +user.theme.auto=\u81ea\u52d5 +user.theme.title=\u81ea\u5b9a\u7fa9\u4e3b\u984c\u8a2d\u7f6e +user.theme.background=\u80cc\u666f +user.theme.image=\u5716\u7247 +user.theme.colorBlur=\u6f38\u8b8a\u984f\u8272 +user.theme.imageBlur=\u5716\u7247\u6a21\u7cca\u8655\u7406 +user.theme.imageUrl=\u5716\u7247\u5730\u5740 +user.theme.colorStart=\u958b\u59cb\u984f\u8272 +user.theme.colorEnd=\u7d50\u675f\u984f\u8272 +user.theme.colorRadius=\u6f38\u8b8a\u89d2\u5ea6 +user.theme.themeImage=\u80cc\u666f\u5716\u7247 +user.theme.themeImageDesc=\u652f\u6301:\u5716\u7247urlcss\u6f38\u8b8a\u8272\u8ddf\u96a8\u58c1\u7d19 +user.theme.imageWall=\u8ddf\u96a8\u58c1\u7d19 +user.wall.random=\u96a8\u6a5f\u58c1\u7d19 +user.wall.paperDesktop=\u684c\u9762\u58c1\u7d19 +user.wall.paperDeskMgt=\u684c\u9762\u58c1\u7d19\u7ba1\u7406 +user.wall.paperLoginMgt=\u767b\u9304\u58c1\u7d19\u7ba1\u7406 +user.wall.paperLoginTips=\u5716\u7247\u591a\u65bc1\u5f35\u6642��\u767b\u9304\u754c\u9762\u80cc\u666f\u5c07\u96a8\u6a5f\u8f2a\u63db +log-type-create-mkdir=\u65b0\u5efa\u6587\u4ef6\u593e +log-type-create-mkfile=\u65b0\u5efa\u6587\u4ef6 +log-type-create-upload=\u4e0a\u50b3\u6587\u4ef6 +log-type-create-copy=\u7c98\u8cbc\u6587\u4ef6 +log-type-edit=\u66f4\u65b0\u6587\u4ef6 +log-type-move=\u79fb\u52d5\u6587\u4ef6 +log-type-moveOut=\u79fb\u8d70\u6587\u4ef6 +log-type-share-shareLinkAdd=\u5275\u5efa\u4e86\u5916\u93c8\u5206\u4eab +log-type-share-shareToAdd=\u958b\u555f\u4e86\u5354\u4f5c\u5206\u4eab +log-type-share-shareLinkRemove=\u95dc\u9589\u7684\u5916\u93c8\u5206\u4eab +log-type-share-shareToRemove=\u95dc\u9589\u5354\u4f5c\u5206\u4eab +log-type-share-shareEdit=\u7de8\u8f2f\u5206\u4eab +log-type-rename=\u91cd\u547d\u540d +log-type-recycle-toRecycle=\u79fb\u5230\u56de\u6536\u7ad9 +log-type-recycle-restore=\u5f9e\u56de\u6536\u7ad9\u9084\u539f +log-type-remove=\u522a\u9664 +log-type-addDesc=\u4fee\u6539\u63cf\u8ff0 +log-type-addComment=\u767c\u8868\u8a55\u8ad6 +log-event-create-mkdir=\u65b0\u5efa\u4e86\u8a72\u6587\u4ef6\u593e +log-event-create-mkfile=\u65b0\u5efa\u4e86\u8a72\u6587\u4ef6 +log-event-create-upload=\u4e0a\u50b3\u4e86\u8a72\u6587\u4ef6 +log-event-create-copy=\u7c98\u8cbc\u5275\u5efa\u4e86\u8a72\u6587\u4ef6 +log-event-create-mkdir-current=\u5728\u6b64\u65b0\u5efa\u4e86\u6587\u4ef6\u593e{0} +log-event-create-mkfile-current=\u5728\u6b64\u65b0\u5efa\u4e86\u6587\u4ef6{0} +log-event-create-upload-current=\u5728\u6b64\u4e0a\u50b3\u4e86{0} +log-event-create-copy-current=\u7c98\u8cbc\u4e86{0}\u5230\u6b64\u8655 +log-event-create-mkdir-item=\u5728{0}\u65b0\u5efa\u4e86\u6587\u4ef6\u593e{1} +log-event-create-mkfile-item=\u5728{0}\u65b0\u5efa\u4e86\u6587\u4ef6{1} +log-event-create-upload-item=\u5728{0}\u4e0a\u50b3\u4e86{1} +log-event-create-copy-item=\u7c98\u8cbc{0}\u5230{1} +log-event-create-mkdir-more=\u5728\u6b64\u65b0\u5efa\u4e86{0}\u500b\u6587\u4ef6\u593e +log-event-create-mkfile-more=\u5728\u6b64\u65b0\u5efa\u4e86{0}\u500b\u6587\u4ef6 +log-event-create-upload-more=\u5728\u6b64\u4e0a\u50b3\u4e86{0}\u500b\u6587\u4ef6 +log-event-create-copy-more=\u7c98\u8cbc\u4e86{0}\u500b\u6587\u4ef6\u5230\u6b64\u8655 +log-event-create-mkdir-more-at=\u5728{0}\u65b0\u5efa\u4e86{1}\u500b\u6587\u4ef6\u593e +log-event-create-mkfile-more-at=\u5728{0}\u65b0\u5efa\u4e86{1}\u500b\u6587\u4ef6 +log-event-create-upload-more-at=\u5728{0}\u4e0a\u50b3\u4e86{1}\u500b\u6587\u4ef6 +log-event-create-copy-more-at=\u7c98\u8cbc\u4e86{0}\u500b\u6587\u6a94\u5230{1} +log-event-view-item=\u67e5\u770b\u4e86{0} +log-event-edit=\u66f4\u65b0\u4e86\u8a72\u6587\u4ef6 +log-event-edit-item=\u7de8\u8f2f\u66f4\u65b0\u4e86{0} +log-event-edit-more=\u7de8\u8f2f\u66f4\u65b0\u4e86{0}\u500b\u6587\u4ef6 +log-event-edit-more-user=\u7de8\u8f2f\u66f4\u65b0\u4e86\u6587\u4ef6{0}{1}\u6b21 +log-event-edit-more-at=\u5728{0}\u7de8\u8f2f\u66f4\u65b0\u4e86{1}\u500b\u6587\u4ef6 +log-event-move=\u5c07\u8a72\u6587\u6a94\u5f9e{0}\u79fb\u52d5\u5230{1} +log-event-move-item=\u5c07{0}\u5f9e{1}\u79fb\u52d5\u5230[3] +log-event-move-current=\u5c07{0}\u5f9e{1}\u79fb\u52d5\u5230\u6b64\u8655 +log-event-move-more=\u79fb\u52d5\u4e86{0}\u500b\u6587\u6a94 +log-event-move-more-desc=\u5c07{0}\u5f9e{1}\u79fb\u52d5\u5230[3] +log-event-moveOut-more-desc=\u5f9e{0}\u79fb\u8d70\u4e86{1} +log-event-moveOut=\u5f9e\u6b64\u8655\u79fb\u8d70\u4e86{0} +log-event-moveOut-item=\u5f9e{0}\u79fb\u8d70\u4e86{1} +log-event-moveOut-more=\u79fb\u8d70\u4e86{0}\u500b\u6587\u6a94 +log-event-share-shareLinkAdd=\u5c07\u8a72\u6587\u6a94\u5275\u5efa\u4e86\u5916\u93c8\u5206\u4eab +log-event-share-shareLinkAdd-item=\u5c07{0}\u5275\u5efa\u4e86\u5916\u93c8\u5206\u4eab +log-event-share-shareLinkAdd-more=\u5275\u5efa\u4e86{0}\u500b\u5916\u93c8\u5206\u4eab +log-event-share-shareToAdd=\u5c07\u8a72\u6587\u6a94\u958b\u555f\u4e86\u5354\u4f5c\u5206\u4eab +log-event-share-shareToAdd-item=\u5c07{0}\u958b\u555f\u4e86\u5354\u4f5c\u5206\u4eab +log-event-share-shareToAdd-more=\u5275\u5efa\u4e86{0}\u500b\u5354\u4f5c\u5206\u4eab +log-event-share-shareLinkRemove=\u95dc\u9589\u4e86\u8a72\u6587\u6a94\u7684\u5916\u93c8\u5206\u4eab +log-event-share-shareLinkRemove-item=\u95dc\u9589\u4e86{0}\u7684\u5916\u93c8\u5206\u4eab +log-event-share-shareLinkRemove-more=\u95dc\u9589{0}\u500b\u5916\u93c8\u5206\u4eab +log-event-share-shareToRemove=\u95dc\u9589\u4e86\u8a72\u6587\u6a94\u7684\u5354\u4f5c\u5206\u4eab +log-event-share-shareToRemove-item=\u95dc\u9589\u4e86{0}\u7684\u5354\u4f5c\u5206\u4eab +log-event-share-shareToRemove-more=\u95dc\u9589{0}\u500b\u5354\u4f5c\u5206\u4eab +log-event-share-shareEdit=\u7de8\u8f2f\u4e86\u8a72\u6587\u6a94\u7684\u5206\u4eab +log-event-share-shareEdit-item=\u7de8\u8f2f\u4e86{0}\u7684\u5206\u4eab +log-event-share-shareEdit-more=\u7de8\u8f2f\u4e86{0}\u500b\u6587\u6a94\u5206\u4eab +log-event-rename=\u91cd\u547d\u540d\u4e86\u8a72\u6587\u6a94 +log-event-rename-item=\u91cd\u547d\u540d\u4e86{0} +log-event-rename-more=\u91cd\u547d\u540d\u4e86{0}\u500b\u6587\u6a94 +log-event-recycle-toRecycle=\u5c07\u8a72\u6587\u6a94\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-current=\u5728\u6b64\u8655\u5c07{0}\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-item=\u5728{0}\u5c07{1}\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-more=\u5c07{0}\u500b\u6587\u6a94\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-toRecycle-more-at=\u5728{0}\u5c07{1}\u500b\u6587\u6a94\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +log-event-recycle-restore=\u5c07\u8a72\u6587\u6a94\u5f9e\u56de\u6536\u7ad9\u9084\u539f +log-event-recycle-restore-item=\u5c07{0}\u5f9e\u56de\u6536\u7ad9\u9084\u539f +log-event-recycle-restore-more=\u5c07{0}\u500b\u6587\u6a94\u5f9e\u56de\u6536\u7ad9\u9084\u539f +log-event-remove=\u5728\u6b64\u8655\u522a\u9664\u4e86{0} +log-event-remove-current=\u5728\u6b64\u8655\u522a\u9664\u4e86{0} +log-event-remove-item=\u5728{0}\u522a\u9664\u4e86{1} +log-event-remove-more=\u5728\u6b64\u8655\u522a\u9664\u4e86{0}\u500b\u6587\u6a94 +log-event-remove-more-at=\u5728{0}\u522a\u9664\u4e86{1}\u500b\u6587\u6a94 +log-event-addDesc=\u4fee\u6539\u4e86\u8a72\u6587\u6a94\u63cf\u8ff0 +log-event-addDesc-item=\u4fee\u6539\u4e86{0}\u6587\u6a94\u63cf\u8ff0 +log-event-addDesc-more=\u4fee\u6539\u4e86{0}\u500b\u6587\u6a94\u63cf\u8ff0 +log-event-addComment=\u5728\u8a72\u6587\u6a94\u767c\u8868\u4e86\u8a55\u8ad6 +log-event-addComment-item=\u5728{0}\u8868\u4e86\u8a55\u8ad6 +log-event-addComment-more=\u5728{0}\u8868\u4e86{1}\u689d\u8a55\u8ad6 +log-event-fav-fileAdd=\u6536\u85cf\u4e86\u6587\u4ef6{0} +log-event-fav-dirAdd=\u6536\u85cf\u4e86\u6587\u4ef6\u593e{0} +log-event-down-item=\u5f9e{0}\u4e0b\u8f09\u4e86{1} +log-event-down-items=\u5f9e{0}\u4e0b\u8f09\u4e86 +log-event-recycle-del-item=\u5f9e\u56de\u6536\u7ad9\u522a\u9664{0}\u500b\u6587\u4ef6 +log-event-recycle-rst-item=\u5f9e\u56de\u6536\u7ad9\u9084\u539f{0}\u500b\u6587\u4ef6 +log-event-del-item=\u522a\u9664\u4e86{0}\u500b\u6587\u4ef6 +log.file.move=\u79fb\u52d5/\u8907\u88fd +log.file.fav=\u6536\u85cf\u593e\u64cd\u4f5c +log.file.shareLink=\u5916\u93c8\u5206\u4eab +log.file.shareTo=\u5354\u4f5c\u5206\u4eab +log.user.edit=\u4fee\u6539\u8cec\u865f\u4fe1\u606f +log.group.edit=\u90e8\u9580\u7ba1\u7406 +log.member.edit=\u7528\u6236\u7ba1\u7406 +log.role.edit=\u89d2\u8272\u6743\u9650\u7ba1\u7406 +log.auth.edit=\u6587\u6a94\u6b0a\u9650\u7ba1\u7406 +meta.user_sourceAlias=\u95dc\u806f\u6587\u4ef6(\u9644\u4ef6) +meta.user_fileEncodeType=\u6587\u4ef6\u5bc6\u7d1a +meta.user_fileEncodeType.A=A-\u7d55\u5bc6 +meta.user_fileEncodeType.B=B-\u6a5f\u5bc6 +meta.user_fileEncodeType.C=C-\u79d8\u5bc6 +meta.user_sourceNumber=\u5b97\u5377\u7de8\u865f +meta.user_sourceParticipant=\u53c3\u8207\u8005 +explorer.fileInfo.createTime=\u5275\u5efa\u65e5\u671f +explorer.fileInfo.modifyTime=\u4fee\u6539\u65e5\u671f +explorer.fileInfo.softwareCreate=\u88fd\u4f5c\u8edf\u4ef6 +explorer.fileInfo.software=\u7de8\u78bc\u8edf\u4ef6 +explorer.fileInfo.playTime=\u64ad\u653e\u6642\u9577 +explorer.fileInfo.imageSize=\u5716\u7247\u5c3a\u5bf8 +explorer.fileInfo.imageDpi=\u5206\u8fa8\u7387 +explorer.fileInfo.imageBits=\u4f4d\u6df1\u5ea6 +explorer.fileInfo.imageDesc=\u6a19\u8a3b\u8aaa\u660e +explorer.fileInfo.imageAuthor=\u5275\u4f5c\u8005 +explorer.fileInfo.imageColor=\u8272\u5f69\u7a7a\u9593 +explorer.fileInfo.cameraType=\u8a2d\u5099\u578b\u865f +explorer.fileInfo.cameraApertureFNumber=\u5149\u5708\u6578 +explorer.fileInfo.cameraApertureValue=\u5149\u5708\u503c +explorer.fileInfo.cameraShutterSpeedValue=\u5feb\u9580\u901f\u5ea6 +explorer.fileInfo.cameraExposureTime=\u66dd\u5149\u6642\u9593 +explorer.fileInfo.cameraFocalLength=\u7126\u8ddd +explorer.fileInfo.cameraFocusDistance=\u5c0d\u7126\u8ddd\u96e2 +explorer.fileInfo.cameraISOSpeedRatings=ISO\u611f\u5149\u5ea6 +explorer.fileInfo.cameraWhiteBalance=\u767d\u5e73\u8861 +explorer.fileInfo.cameraUser=\u624b\u52d5 +explorer.fileInfo.cameraAuto=\u81ea\u52d5 +explorer.fileInfo.cameraExposureMode=\u66dd\u5149\u6a21\u5f0f +explorer.fileInfo.cameraExposureBiasValue=\u66dd\u5149\u88dc\u511f +explorer.fileInfo.imageGps=\u62cd\u651d\u4f4d\u7f6e +explorer.fileInfo.imageCreateTime=\u62cd\u651d\u65e5\u671f +explorer.fileInfo.audioChannel=\u97f3\u983b\u8072\u9053 +explorer.fileInfo.audioChannel1=\u55ae\u8072\u9053 +explorer.fileInfo.audioChannel2=\u7acb\u9ad4\u8072 +explorer.fileInfo.audioChannels=\u591a\u8072\u9053 +explorer.fileInfo.audioRate=\u97f3\u983b\u63a1\u6a23\u7387 +explorer.fileInfo.audioBits=\u97f3\u983b\u4f4d\u6df1\u5ea6 +explorer.fileInfo.audioBitrate=\u97f3\u983b\u6bd4\u7279\u7387 +explorer.fileInfo.vedioFormat=\u8996\u983b\u7de8\u78bc +explorer.fileInfo.audioTitle=\u6a19\u984c +explorer.fileInfo.audioAuthor=\u4f5c\u8005 +explorer.fileInfo.audioAlbum=\u5c08\u8f2f +explorer.fileInfo.audioStyle=\u98a8\u683c +explorer.fileInfo.audioYear=\u5c08\u8f2f\u5e74\u4ee3 +explorer.fileInfo.vedioSize=\u756b\u9762\u5c3a\u5bf8 +explorer.fileInfo.vedioFrame=\u8996\u983b\u5e40\u7387 +explorer.fileInfo.vedioBitrate=\u8996\u983b\u6bd4\u7279\u7387 +explorer.fileInfo.title=\u6a19\u984c +explorer.fileInfo.author=\u4f5c\u8005 +explorer.fileInfo.pageTotal=\u7e3d\u9801\u6578 +explorer.fileInfo.pageSize=\u9801\u9762\u5c3a\u5bf8 +explorer.fileInfo.pagePower=\u5167\u5bb9\u5275\u4f5c\u8005 +explorer.fileInfo.pdfVersion=PDF\u7248\u672c +explorer.filter.shareCopyLimit=\u8f49\u5b58\u6587\u4ef6\u500b\u6578\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u8f49\u5b58\u6587\u4ef6\u500b\u6578\u70ba: +explorer.filter.shareSizeLimit=\u5206\u4eab\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u5206\u4eab\u6587\u6a94: +explorer.filter.unzipSizeLimit=\u89e3\u58d3\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u89e3\u58d3\u6587\u6a94: +explorer.filter.zipSizeLimit=\u58d3\u7e2e\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u58d3\u7e2e\u6587\u6a94: +explorer.filter.uploadSizeLimit=\u4e0a\u50b3\u5927\u5c0f\u8d85\u51fa\u9650\u5236;\u60a8\u6700\u5927\u53ef\u4e0a\u50b3\u6587\u6a94: +explorer.fileEditError=\u7576\u524d\u6587\u4ef6 %s \u6b63\u5728\u7de8\u8f2f, \u8acb\u7a0d\u5f8c\u518d\u8a66 +explorer.groupDelError=\u62b1\u6b49\u90e8\u9580\u6587\u4ef6\u593e\u4e0d\u652f\u6301\u522a\u9664 +admin.info.typeDelError=\u522a\u9664\u5931\u6557, \u6709\u5b50\u5206\u985e\u6216\u6578\u64da +admin.info.domainIdentifyError=\u7db2\u7ad9\u7121\u6cd5\u8b58\u5225 +admin.info.articleIdentifyError=\u6587\u7ae0\u7121\u6cd5\u8b58\u5225 +admin.info.domainSupportError=\u8a72\u7db2\u7ad9\u66ab\u4e0d\u652f\u6301\u91c7\u96c6 +admin.info.fileTooLarge=\u6587\u4ef6\u904e\u5927 +explorer.toolbar.info=\u8cc7\u8a0a +source.shareDisabled=\u7576\u524d\u8cc7\u6e90\u7981\u6b62\u5206\u4eab +admin.exceeds.limit=\u8d85\u51fa\u9650\u88fd +admin.design.deleted=\u555f\u7528\u72c0\u614b\u7121\u6cd5\u522a\u9664 +admin.design.url.locked=\u88ab\u9396\u5b9a\u002c\u0020\u66ab\u6642\u4e0d\u80fd\u4f7f\u7528 +explorer.SING_INVALID=\u7c3d\u540d\u7570\u5e38 +explorer.TEMP_AUTH_INVALID=\u81e8\u6642\u6388\u6b0a\u78bc\u7121\u6548\uff08\u5931\u6548\uff09 +explorer.QR_INVALID=\u4e8c\u7dad\u78bc\u5df2\u5931\u6548 +explorer.toolbar.toolbox=\u5de5\u5177\u7bb1 +explorer.toolbox.desc= +logs-detail-mkdir=\u65b0\u5efa\u4e86\u6587\u4ef6\u5939 +logs-detail-mkfile=\u65b0\u5efa\u4e86\u6587\u4ef6 +logs-detail-editFile=\u7de8\u8f2f\u66f4\u65b0\u4e86 +logs-detail-upload=\u4e0a\u50b3\u4e86\u6587\u4ef6 +logs-detail-uploadNew=\u7de8\u8f2f\u4e86 +logs-detail-file.upload=\u4e0a\u50b3\u4e86 +logs-detail-file-copy=\u7c98\u8cbc\u5275\u5efa\u4e86\u6587\u4ef6 +logs-detail-folder-copy=\u7c98\u8cbc\u5275\u5efa\u4e86\u6587\u4ef6\u5939 +logs-detail-paste=\u7c98\u8cbc +logs-detail-from=\u5f9e +logs-detail-to=\u5230 +logs-detail-rename=\u91cd\u547d\u540d\u4e86 +logs-detail-rename-file=\u91cd\u547d\u540d\u4e86\u8a72\u6587\u4ef6 +logs-detail-rename-folder=\u91cd\u547d\u540d\u4e86\u8a72\u6587\u4ef6\u5939 +logs-detail-user=\u7528\u6236: +logs-detail-moveFrom-restore=\u5c07 +logs-detail-moveTo-restore=\u5f9e\u56de\u6536\u7ad9\u9084\u539f +logs-detail-move=\u5c07 +logs-detail-moveTo=\u79fb\u52d5\u5230 +logs-detail-moveFrom-toRecycle=\u5c07 +logs-detail-moveTo-toRecycle=\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +logs-detail-file-toRecycle=\u5c07\u8a72\u6587\u4ef6\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +logs-detail-file-restore=\u5c07\u8a72\u6587\u4ef6\u5f9e\u56de\u6536\u7ad9\u9084\u539f +logs-detail-folder-toRecycle=\u5c07\u8a72\u6587\u4ef6\u593e\u79fb\u5230\u4e86\u56de\u6536\u7ad9 +logs-detail-folder-restore=\u5c07\u8a72\u6587\u4ef6\u593e\u5f9e\u56de\u6536\u7ad9\u9084\u539f +logs-detail-favAdd=\u6536\u85cf\u4e86 +logs-detail-favDel=\u53d6\u6d88\u4e86\u6536\u85cf +logs-detail-unstar=\u540d\u7a31: +logs-detail-moveOut=\u79fb\u8d70\u4e86 +logs-detail-remove=\u522a\u9664\u4e86 +logs-detail-file.copy=\u7c98\u8cbc\u4e86 +explorer.noPermissionAuthAll={0} ,\u6c92\u6709\u6b64\u64cd\u4f5c\u6b0a\u9650 \ No newline at end of file diff --git a/src/main/resources/itest/agent.config b/src/main/resources/itest/agent.config new file mode 100644 index 0000000..a0f1826 --- /dev/null +++ b/src/main/resources/itest/agent.config @@ -0,0 +1,114 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The agent namespace +agent.namespace=itest + +# The service name in UI +agent.service_name=itest:disk + +# The number of sampled traces per 3 seconds +# Negative or zero means off, by default +# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1} + +# Authentication active is based on backend setting, see application.yml for more details. +# agent.authentication = ${SW_AGENT_AUTHENTICATION:xxxx} + +# The max amount of spans in a single segment. +# Through this config item, SkyWalking keep your application memory cost estimated. +# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:150} + +# If the operation name of the first span is included in this set, this segment should be ignored. Multiple values should be separated by `,`. +# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg} + +# If true, SkyWalking agent will save all instrumented classes files in `/debugging` folder. +# SkyWalking team may ask for these files in order to resolve compatible problem. +# agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true} + +# If true, SkyWalking agent will cache all instrumented classes files to memory or disk files (decided by class cache mode), +# allow other javaagent to enhance those classes that enhanced by SkyWalking agent. +# agent.is_cache_enhanced_class = ${SW_AGENT_CACHE_CLASS:false} + +# The instrumented classes cache mode: MEMORY or FILE +# MEMORY: cache class bytes to memory, if instrumented classes is too many or too large, it may take up more memory +# FILE: cache class bytes in `/class-cache` folder, automatically clean up cached class files when the application exits +# agent.class_cache_mode = ${SW_AGENT_CLASS_CACHE_MODE:MEMORY} + +# The operationName max length +# Notice, in the current practice, we don't recommend the length over 190. +# agent.operation_name_threshold=${SW_AGENT_OPERATION_NAME_THRESHOLD:150} + +# The agent use gRPC plain text in default. +# If true, SkyWalking agent uses TLS even no CA file detected. +# agent.force_tls=${SW_AGENT_FORCE_TLS:false} + +# If true, skywalking agent will enable profile when user create a new profile task. Otherwise disable profile. +# profile.active=${SW_AGENT_PROFILE_ACTIVE:true} + +# Parallel monitor segment count +# profile.max_parallel=${SW_AGENT_PROFILE_MAX_PARALLEL:5} + +# Max monitor segment time(minutes), if current segment monitor time out of limit, then stop it. +# profile.duration=${SW_AGENT_PROFILE_DURATION:10} + +# Max dump thread stack depth +# profile.dump_max_stack_depth=${SW_AGENT_PROFILE_DUMP_MAX_STACK_DEPTH:500} + +# Snapshot transport to backend buffer size +# profile.snapshot_transport_buffer_size=${SW_AGENT_PROFILE_SNAPSHOT_TRANSPORT_BUFFER_SIZE:50} + +# Backend service addresses. +collector.backend_service=192.168.110.98:11800 + +# Logging file_name +logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log} + +# Logging level +logging.level=${SW_LOGGING_LEVEL:INFO} + +# Logging dir +# logging.dir=${SW_LOGGING_DIR:""} + +# Logging max_file_size, default: 300 * 1024 * 1024 = 314572800 +# logging.max_file_size=${SW_LOGGING_MAX_FILE_SIZE:314572800} + +# The max history log files. When rollover happened, if log files exceed this number, +# then the oldest file will be delete. Negative or zero means off, by default. +# logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:-1} + +# Listed exceptions would not be treated as an error. Because in some codes, the exception is being used as a way of controlling business flow. +# Besides, the annotation named IgnoredException in the trace toolkit is another way to configure ignored exceptions. +# statuscheck.ignored_exceptions=${SW_STATUSCHECK_IGNORED_EXCEPTIONS:} + +# The max recursive depth when checking the exception traced by the agent. Typically, we don't recommend setting this more than 10, which could cause a performance issue. Negative value and 0 would be ignored, which means all exceptions would make the span tagged in error status. +# statuscheck.max_recursive_depth=${SW_STATUSCHECK_MAX_RECURSIVE_DEPTH:1} + +# Mount the specific folders of the plugins. Plugins in mounted folders would work. +plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations} + +# Exclude activated plugins +# plugin.exclude_plugins=${SW_EXCLUDE_PLUGINS:} + +# If set to true, the parameters of the sql (typically java.sql.PreparedStatement) would be collected. +plugin.jdbc.trace_sql_parameters=true + +# Kafka producer configuration +plugin.kafka.bootstrap_servers=192.168.110.68:9092 +# if you want to set namespace. please make sure the OAP server has set it in Kafka fetcher module +# plugin.kafka.namespace=${SW_KAFKA_NAMESPACE:""} + +# Match spring bean with regex expression for classname +# plugin.springannotation.classname_match_regex=${SW_SPRINGANNOTATION_CLASSNAME_MATCH_REGEX:} diff --git a/src/main/resources/itest/application.properties b/src/main/resources/itest/application.properties new file mode 100644 index 0000000..9cd87f5 --- /dev/null +++ b/src/main/resources/itest/application.properties @@ -0,0 +1,161 @@ +server.port=80 +spring.application.name=disk +spring.profiles.active=test + +instance.id=5 +spring.main.allow-bean-definition-overriding=true + +spring.datasource.url=jdbc:mysql://192.168.110.98:8066/cloud_disk?useUnicode=true&characterEncoding=utf8&useSSL=false&queryTimeout=6000 +spring.datasource.username=root +spring.datasource.password=ENC(gmEtTGXR9cvB/sLYMdkAMDLPPD2XkJRv) +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.initialization-mode=always +spring.datasource.continue-on-error=true +spring.datasource.testOnBorrow=true +spring.mvc.async.request-timeout=20000 +spring.datasource.hikari.read-only=false +spring.datasource.hikari.connection-timeout=60000 +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.validation-timeout=30000 +spring.datasource.hikari.max-lifetime=60000 +spring.datasource.hikari.login-timeout=5 +spring.datasource.hikari.maximum-pool-size=200 +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.connection-test-query=SELECT 1 +#????? +server.tomcat.max-connections=2000 +#????? +server.tomcat.max-threads=1000 +## Mybatis ??==================================== +mybatis.mapperLocations=classpath:mapper/*.xml +user.default.lady=/static/common/image/head/lady.png +user.default.boy=/static/common/image/head/boy.png +user.default.girl=/static/common/image/head/girl.png +user.default.sir=/static/common/image/head/sir.png +user.default.headPic=/static/common/image/head/girl.png +loginLimit.level1.count=5 +loginLimit.level1.interval=300 +loginLimit.level2.count=10 +loginLimit.level2.interval=300 +loginLimit.level2.denyInterval=600 + +spring.messages.basename=i18n.messages +spring.messages.encoding=utf-8 + + +## Redis \uFFFD\uFFFD\uFFFD\uFFFD +spring.redis.database=7 +## Redis????? +spring.redis.cluster.nodes=192.168.110.148:18111,192.168.110.148:18222,192.168.110.148:18333,192.168.110.98:16111,192.168.110.98:16222,192.168.110.98:16333 + +## Redis??????? +##spring.redis.port=8379 +## Redis????????????? +spring.redis.password=123456 +## ???????????????????? +spring.redis.jedis.pool.max-active=300 +## ??????????????????????? +spring.redis.jedis.pool.max-wait=-1 +## ??????????? +spring.redis.jedis.pool.max-idle=300 +## ??????????? +spring.redis.jedis.pool.min-idle=0 +## ?????????? +spring.redis.timeout=300 + +#buildkey +m3u8.buildkey=buildkey +m3u8.buildkey2=buildkey2 +schedule.video_convert_time=0 0/30 * * * ? + +verification.expiried=5 + + +h5doc.apiUrl=http://p2.ebh.net/i2.aspx?from=wuji +h5doc.appId=ebhapp1008 +h5doc.appKey=89327008 +swfdoc.apiUrl=http://p1.ebh.net/i.aspx?from=wuji +swfdoc.appId=ebhapp1005 +swfdoc.appKey=89327005 +swfdoc.callback.ipWhiteList=101.71.142.135 + + +spring.mail.host=smtp.qq.com +spring.mail.username=system@wxbig.cn +#\u6388\u6743\u7801g\uFF0C\u5728QQ\u90AE\u7BB1\u5BA2\u6237\u7AEF\u751F\u6210 \u4FEE\u6539\u6210\u81EA\u5DF1\u7684 \u8BBE\u7F6E-\u8D26\u6237-\u5F00\u542F\u670D\u52A1-\u83B7\u53D6\u6388\u6743\u7801 +spring.mail.password=ENC(AvNBF7xFcdy8792rgQOD2Ad0VhtF7ojqYrI2VJofsHs=) +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true +logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG +# Max file size??10M +spring.servlet.multipart.max-file-size=10485760 +# Max request size??10M +spring.servlet.multipart.max-request-size=10485760 + + +ppt.des.key= +ppt.des.vi= +ppt.server.url=https://weboffice.filesbox.cn/ +ppt.replace.need=0 +ppt.ip.whitelist= +cdn.domain=test-cdn.filesbox.cn + +mail.encode.fail = 414667543@qq.com +environment.type=itest +disk.default.size=1024 + +dingding.token=eGN4zltmKYsEfnmxLkWJigTFsv +dingding.corpId=ding1f566670a125f1e7 +dingding.aes.key=gQg2uPqSEfduMkHMKBVfHcFC7kkKw0u6A9CMwfDD14w +dingding.app.key=dinguom4izrf3j7vy58k +dingding.app.secret=oy9btsUAr_WtuLBzJnbwcsz5h193_EgRwdKn-c4Nti5FAsRITFh7yZmg3LW_Lp-r + + +yz.view.convert.url=https://demo.filesbox.cn/fcscloud/composite/httpfile +yz.edit.convert.url=https://demo.filesbox.cn/plugin/yzwo +yz.edit.post.url=https://demo.filesbox.cn/plugin/yzwo/api.do +yz.fileId.prefix=i_ + +schedule.deleteCloudDownload=0 0 1 * * ? +webdav.host=https://test.filesbox.cn + +enWechat.corpId=ww2d1e9bafb529c21f +enWechat.AgentId=100009 +enWechat.Secret=r1V4SE4ZNZRWRMrlAK-be4qDs40OCvYpJ48tvXleghc + +wechat.web.wx_appid=wxeed6a7666ad6b030 +wechat.web.wx_appSecret=3a2d4d810360ac367c3fe64d73af2e0f +wechat.app.wx_appid=wx283aec18f2335a85 +wechat.app.wx_appSecret=b10e94cd00d0aeb6c67fdb5c43449423 + +mybatis-plus.mapper-locations=classpath*:mapper/*.xml +info.common.htmlPath.name=filesbox + +#libreoffice\u914D\u7F6E\u4FE1\u606F +office.libreOfficeVersion=libreoffice6.3 +office.shellFileName=docx.sh +office.shellFileDirectory=/ +design.subPage.limitCount=512 +schedule.msgWarning=*/20 * * * * ? + +#\u626B\u7801\u767B\u5F55\u4E8C\u7EF4\u7801\u6709\u6548\u671F\u3002\u5355\u4F4D\uFF1A\u5206\u949F +scan.login.code.expire=3 + +webdav.rootContext[0]=/webdav/private +webdav.rootContext[1]=/webdav/favor +webdav.license=D:/License.lic +# Whether to print exception stacktrace in the response. +webdav.showExceptions=true +# Here you map you filesystem folder to be root for WebDAV. If not provided default structure will be created for the testing. +webdav.rootFolder=/ +# WebSockets are available at this endpoint. WebSockets are used in the default GET page. +webdav.rootWebSocket=/ + +logging.level.com.svnlan.user.dao=debug +logging.level.com.svnlan.home.dao=debug +logging.level.com.svnlan.manage.dao=debug +logging.level.com.svnlan.webdav.WebdavEndpoint=debug +jasypt.encryptor.bean=encryptorBean + + diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..f23b2fb --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,134 @@ + + + + monitor + + + + + log/${HOSTNAME}.log + + + + log/${HOSTNAME}-%d{yyyy-MM-dd}.%i.log + + 10MB + + + 30 + + true + + + + +    ${consoleLayoutPattern} + + UTF-8 + + + + + INFO + + ACCEPT + + DENY + + + + + + + + + + log/error/${HOSTNAME}.log + + + + log/error/${HOSTNAME}-%d{yyyy-MM-dd}.%i.log + + 10MB + + + 30 + + true + + + + +    ${consoleLayoutPattern} + + UTF-8 + + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + +    ${consoleLayoutPattern} + + UTF-8 + + + + + + + + + + + + + log/debug/${HOSTNAME}.log + + + + log/debug/${HOSTNAME}-%d{yyyy-MM-dd}.%i.log + + 10MB + + + 30 + + true + + + + +    ${consoleLayoutPattern} + + UTF-8 + + + + + DEBUG + + ACCEPT + + DENY + + + + + + + diff --git a/src/main/resources/mapper/AdminShareMapper.xml b/src/main/resources/mapper/AdminShareMapper.xml new file mode 100644 index 0000000..8011161 --- /dev/null +++ b/src/main/resources/mapper/AdminShareMapper.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + shareID,title,shareHash, + userID,sourceID,sourcePath, + url,isLink,isShareTo, + password,timeTo,numView, + numDownload,options,createTime, + modifyTime + + + DELETE + FROM share + WHERE shareID = #{id} + + + UPDATE share SET `status` = 4 + WHERE shareID IN + + #{_id} + + + + + + + + diff --git a/src/main/resources/mapper/CommentMapper.xml b/src/main/resources/mapper/CommentMapper.xml new file mode 100644 index 0000000..f60f2ce --- /dev/null +++ b/src/main/resources/mapper/CommentMapper.xml @@ -0,0 +1,61 @@ + + + + + + c.commentID, c.`pid` , c.userID, c.targetType, c.targetID, c.content, c.createTime , c.`status` + + + + INSERT INTO `comment` ( `pid`, `userID`, `targetType`, `targetID`, `content`, `praiseCount`, `commentCount`, `status`, `modifyTime`, `createTime`) + VALUES + ( #{pid}, #{userID}, #{targetType}, #{targetID}, IFNULL(#{content}, ''), IFNULL(#{praiseCount}, 0), IFNULL(#{commentCount}, 0), IFNULL(#{status}, 1), unix_timestamp(now()), unix_timestamp(now()) + ); + + + update `comment` + set `commentCount` = commentCount + #{commentCount}, + modifyTime = unix_timestamp(now()) + where commentID = #{commentID} + + + + delete from `comment` + where commentID = #{commentID} or pid = #{commentID} + + + + + + c.targetID = #{targetID} and c.status = 1 + and c.targetType = #{targetType} + and c.commentID > #{idFrom} + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonConvertMapper.xml b/src/main/resources/mapper/CommonConvertMapper.xml new file mode 100644 index 0000000..4768bf4 --- /dev/null +++ b/src/main/resources/mapper/CommonConvertMapper.xml @@ -0,0 +1,111 @@ + + + + + + insert into common_convert (sourceID, `fileID`,`userID`,`name`,`state`,`frequencyCount`,`remark`, createTime, modifyTime, scheduleFrequencyCount,scheduleTime) + values ( + #{sourceID}, #{fileID}, #{userID}, #{name}, #{state}, #{frequencyCount}, #{remark}, unix_timestamp(now()), 0, 0, 0 + ) + + + + update common_convert + set state = #{state}, + modifyTime = unix_timestamp() + where convertID = #{convertID} + + + update common_convert + set state = #{state}, + frequencyCount = frequencyCount + 1, + userID = #{userID}, + remark = #{remark}, + modifyTime = unix_timestamp() + where convertID = #{convertID} + + + update common_convert + set state = #{state}, + scheduleFrequencyCount = scheduleFrequencyCount + 1, + modifyTime = unix_timestamp() + where convertID = #{convertID} + + + + + + + + and (cc.userID = #{userID}) + + + and io.sourceID = #{sourceID} + + + and cc.state = #{state} + + + and io.fileType in + + #{item} + + + + and ( io.name like concat('%', #{keyword}, '%') OR io.`name_pinyin` LIKE CONCAT('%',#{keyword}, '%') + OR io.`name_pinyin_simple` LIKE CONCAT('%',#{keyword}, '%') + ) + + + + + + and (io.createTime between #{minDate} and #{maxDate}) + + + and (io.createTime >= #{minDate}) + + + + + + and ( #{maxDate} >=io.createTime) + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonDesignClassifyMapper.xml b/src/main/resources/mapper/CommonDesignClassifyMapper.xml new file mode 100644 index 0000000..2420cdd --- /dev/null +++ b/src/main/resources/mapper/CommonDesignClassifyMapper.xml @@ -0,0 +1,144 @@ + + + + + + delete from common_design_classify where designClassifyID = #{designClassifyID} + + + insert into common_design_classify (typeName, parentID, parentLevel, status, sort, namePinyin, namePinyinSimple, createTime, modifyTime, createUser) + values (#{typeName}, #{parentID}, #{parentLevel}, #{status}, #{sort}, #{namePinyin}, #{namePinyinSimple},unix_timestamp(now()), unix_timestamp(now()) + , #{createUser} + ) + + + insert into common_design_classify (typeName, parentID, parentLevel, status, sort, namePinyin, namePinyinSimple, createTime, modifyTime, createUser) + values + + (#{item.typeName}, #{item.parentID}, #{item.parentLevel}, #{item.status}, #{item.sort}, #{item.namePinyin}, #{item.namePinyinSimple} + ,unix_timestamp(now()), unix_timestamp(now()), #{item.createUser} + ) + + + + + update common_design_classify + set typeName = #{typeName}, + parentID = #{parentID}, + parentLevel = #{parentLevel}, + status = #{status}, + namePinyin = #{namePinyin}, + namePinyinSimple = #{namePinyinSimple}, + modifyTime = unix_timestamp(now()) + where designClassifyID = #{designClassifyID} + + + + + + + update common_design_classify + set status = #{status}, modifyTime = unix_timestamp(now()) + where designClassifyID = #{designClassifyID} + + + update common_design_classify + set status = 0 , modifyTime = unix_timestamp(now()) + where designClassifyID in + + #{item} + + + + + + + + update common_design_classify set sort = #{item.sort} where designClassifyID = #{item.designClassifyID} + + + + + update common_design_classify + + + + when designClassifyID=#{item.designClassifyID} then #{item.parentLevel} + + + ,modifyTime=unix_timestamp() + + where designClassifyID in + + #{item.designClassifyID} + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonDesignMapper.xml b/src/main/resources/mapper/CommonDesignMapper.xml new file mode 100644 index 0000000..e4e6010 --- /dev/null +++ b/src/main/resources/mapper/CommonDesignMapper.xml @@ -0,0 +1,235 @@ + + + + + + + insert into common_design (title, offset, `size`, pic, gmt_create, gmt_modified,detail, + design_type, client_type, is_used, url, file_url, fk_common_design_id, foot, head, setting, applet, + source_design_id, approval_state, approval_detail,gmt_approval, `sort`,`state`,`is_paste`,seo, mb_design_id, designClassifyID, pathPre) + values (#{title}, #{offset}, #{size}, #{pic}, now(),now(), #{detail}, + #{designType}, #{clientType}, #{isUsed},#{url}, + #{fileUrl}, #{fkCommonDesignId}, #{foot}, #{head}, #{setting}, #{applet}, + #{sourceDesignId}, '1','',now(), #{sort},#{state},0,#{seo},#{mbDesignId},IFNULL(#{designClassifyID},0),#{pathPre} + ) + + + + + + + + + + + + + 0 + 1 + + update common_design + set is_used = , + gmt_modified = #{gmtModified} + where client_type = #{clientType} + and design_type = #{designType} + and is_used = + and state = '1' + + + update common_design + set is_used = , + gmt_modified = now() + where common_design_id = #{designId} + + + 1 + + update common_design + set state = '3' + where common_design_id = #{commonDesignId} + and (is_used = or design_type != ) + + + + + update common_design + + gmt_modified = #{gmtModified}, + + detail = #{detail}, + + + head = #{head}, + + + foot = #{foot}, + + + pic = #{pic}, + + + setting = #{setting}, + + + title = #{title}, + + + is_used = #{isUsed}, + + + `size` = #{size}, + + + url = #{url}, + + + applet = #{applet}, + + + seo = #{seo}, + + + pathPre = #{pathPre}, + + + designClassifyID = #{designClassifyID}, + + + where common_design_id = #{commonDesignId} + and source_design_id = 0 + and state in ('0', '1') + + + '1' + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonInfoMapper.xml b/src/main/resources/mapper/CommonInfoMapper.xml new file mode 100644 index 0000000..d50e77e --- /dev/null +++ b/src/main/resources/mapper/CommonInfoMapper.xml @@ -0,0 +1,260 @@ + + + + + + i.infoID,i.title,i.computerPicPath,i.mobilePicPath,i.status,i.detail,i.fileDetail,i.createTime,i.modifyTime,i.createUser,i.userIp,i.infoTypeID,i.sort,i.introduce + ,i.isTop,i.topTime,i.seo,i.infoSource,i.isApplyOriginal,i.videoID,i.thumb,i.previewUrl,i.infoType,i.isVertical,i.thumbVertical,i.computerPicPathVertical,i.isVideoExists + ,i.gmtPage,i.userAgent,i.isUrlInfo,i.infoUrl,i.attachmentCount,i.showAttachment,i.remark,i.isTransport,i.rightFlag,i.sourceID,i.isHide,i.viewCount,i.likeCount,i.isLogin + ,i.pathPre + + + insert into common_info (title,computerPicPath,mobilePicPath,status,detail,fileDetail,createTime,modifyTime,createUser,modifyUser,userIp,infoTypeID,sort,introduce + ,isTop,topTime,seo,infoSource,isApplyOriginal,videoID,thumb,previewUrl,infoType,isVertical,thumbVertical,computerPicPathVertical,isVideoExists + ,gmtPage,userAgent,isUrlInfo,infoUrl,attachmentCount,showAttachment,remark,isTransport,rightFlag,sourceID,isHide,isLogin,actualViewCount,viewCount + ,namePinyin,namePinyinSimple,pathPre) + values (#{title}, #{computerPicPath}, #{mobilePicPath}, #{status}, #{detail}, #{fileDetail}, unix_timestamp(now()), unix_timestamp(now()) + , #{createUser}, #{modifyUser}, #{userIp}, #{infoTypeID}, #{sort}, #{introduce}, 0, 0 , #{seo}, #{infoSource}, #{isApplyOriginal}, #{videoID} + , #{thumb}, #{previewUrl}, #{infoType} , #{isVertical}, #{thumbVertical}, #{computerPicPathVertical}, #{isVideoExists}, #{gmtPage} + , #{userAgent}, #{isUrlInfo}, #{infoUrl}, #{attachmentCount}, #{showAttachment}, #{remark}, #{isTransport}, #{rightFlag}, #{sourceID} + , #{isHide},#{isLogin}, 0, 0, #{namePinyin}, #{namePinyinSimple}, #{pathPre} + ) + + + + update common_info + set + title = #{title}, + computerPicPath = #{computerPicPath}, + mobilePicPath = #{mobilePicPath}, + detail = #{detail}, + fileDetail = #{fileDetail}, + infoTypeID = #{infoTypeID}, + introduce = #{introduce}, + seo = #{seo}, + infoSource = #{infoSource}, + isApplyOriginal = #{isApplyOriginal}, + videoID = #{videoID}, + thumb = #{thumb}, + previewUrl = #{previewUrl}, + infoType = #{infoType}, + isVertical = #{isVertical}, + thumbVertical = #{thumbVertical}, + computerPicPathVertical = #{computerPicPathVertical}, + isVideoExists = #{isVideoExists}, + isUrlInfo = #{isUrlInfo}, + infoUrl = #{infoUrl}, + attachmentCount = #{attachmentCount}, + showAttachment = #{showAttachment}, + remark = #{remark}, + isTransport = #{isTransport}, + rightFlag = #{rightFlag}, + sourceID = #{sourceID}, + isHide = #{isHide}, + isLogin = #{isLogin}, + viewCount = #{viewCount}, + namePinyin = #{namePinyin}, + namePinyinSimple = #{namePinyinSimple}, + pathPre = #{pathPre}, + modifyTime = unix_timestamp(now()) + where infoID = #{infoID} + + + + update common_info + set status = 2, modifyUser = #{modifyUser} , modifyTime = unix_timestamp(now()) + where infoID in + + #{item} + + + + update common_info + set status = 2 , modifyUser = #{modifyUser}, modifyTime = unix_timestamp(now()) + where infoID = #{infoID} + + + + + + + + + + i.status = #{status} + + + i.status in (0,1) + + + + and i.infoType = #{infoType} + + + and uf.tagID = #{tagID} + + + + and (i.infoTypeID = #{infoTypeID} or cit.parentLevel like concat(#{infoTypeLevel}, '%') ) + + + and i.infoTypeID = #{infoTypeID} + + + and cit.parentLevel like concat(#{infoTypeLevel}, '%') + + + + and ( i.title like concat('%', #{keyword}, '%') + ) + + + + order by i.topTime desc, i.sort desc , i.createTime desc + + + + + + + + + + update common_info + set gmtPage = unix_timestamp(now()) + where infoID in + + #{item.id} + + + + + update common_info + set isTop = #{isTop}, + + + topTime = 0 + + + topTime = unix_timestamp(now()) + + + where infoID = #{infoID} + + + + + update common_info + set sort = #{item.sort} + where infoID = #{item.infoID} + + + + + update common_info + set status = #{updateState}, + + remark=#{remark}, + + modifyTime = unix_timestamp(now()) + where infoID = #{infoID} and status = #{conditionState} + + + UPDATE common_info + + + likeCount = likeCount + 1 + + + likeCount = likeCount - 1 + + + WHERE infoID = #{id} + + AND likeCount > 0 + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonInfoTypeMapper.xml b/src/main/resources/mapper/CommonInfoTypeMapper.xml new file mode 100644 index 0000000..5ce9f34 --- /dev/null +++ b/src/main/resources/mapper/CommonInfoTypeMapper.xml @@ -0,0 +1,144 @@ + + + + + + delete from common_info_type where infoTypeID = #{infoTypeID} + + + insert into common_info_type (typeName, parentID, parentLevel, status, sort, namePinyin, namePinyinSimple, createTime, modifyTime, createUser) + values (#{typeName}, #{parentID}, #{parentLevel}, #{status}, #{sort}, #{namePinyin}, #{namePinyinSimple},unix_timestamp(now()), unix_timestamp(now()) + , #{createUser} + ) + + + insert into common_info_type (typeName, parentID, parentLevel, status, sort, namePinyin, namePinyinSimple, createTime, modifyTime, createUser) + values + + (#{item.typeName}, #{item.parentID}, #{item.parentLevel}, #{item.status}, #{item.sort}, #{item.namePinyin}, #{item.namePinyinSimple} + ,unix_timestamp(now()), unix_timestamp(now()), #{item.createUser} + ) + + + + + update common_info_type + set typeName = #{typeName}, + parentID = #{parentID}, + parentLevel = #{parentLevel}, + status = #{status}, + namePinyin = #{namePinyin}, + namePinyinSimple = #{namePinyinSimple}, + modifyTime = unix_timestamp(now()) + where infoTypeID = #{infoTypeID} + + + + + + + update common_info_type + set status = #{status}, modifyTime = unix_timestamp(now()) + where infoTypeID = #{infoTypeID} + + + update common_info_type + set status = 0 , modifyTime = unix_timestamp(now()) + where infoTypeID in + + #{item} + + + + + + + + update common_info_type set sort = #{item.sort} where infoTypeID = #{item.infoTypeID} + + + + + update common_info_type + + + + when infoTypeID=#{item.infoTypeID} then #{item.parentLevel} + + + ,modifyTime=unix_timestamp() + + where infoTypeID in + + #{item.infoTypeID} + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonLabelMapper.xml b/src/main/resources/mapper/CommonLabelMapper.xml new file mode 100644 index 0000000..ef2c7fa --- /dev/null +++ b/src/main/resources/mapper/CommonLabelMapper.xml @@ -0,0 +1,67 @@ + + + + + + insert into common_label (userID, `label_name`,`label_en_name`,`en_name_simple`,`status`, createTime, modifyTime,`style`,`sort`, `tagType`) + values ( + #{userID}, #{labelName}, #{labelEnName}, #{enNameSimple}, 1, unix_timestamp(now()), unix_timestamp(now()), #{style}, #{sort}, IFNULL(#{tagType}, 1) + ) + + + + + + update common_label + set label_name = #{labelName}, + label_en_name = #{labelEnName}, + en_name_simple = #{enNameSimple}, + style = #{style}, + modifyTime = unix_timestamp() + where label_id = #{labelId} + + + + delete from common_label where label_id = #{labelId} + + + + update common_label + set status = #{status}, + modifyTime = unix_timestamp() + where label_id = #{labelId} + + + update common_label + set sort = #{sort}, + modifyTime = unix_timestamp() + where label_id = #{labelId} + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/CommonScheduleMapper.xml b/src/main/resources/mapper/CommonScheduleMapper.xml new file mode 100644 index 0000000..da697d0 --- /dev/null +++ b/src/main/resources/mapper/CommonScheduleMapper.xml @@ -0,0 +1,93 @@ + + + + + + + + + + common_schedule_id, schedule_name, gmt_modified + + + + insert into common_schedule (common_schedule_id, schedule_name, gmt_modified, frequency + ) + values (#{commonScheduleId,jdbcType=VARCHAR}, #{scheduleName,jdbcType=VARCHAR} + , #{gmtModified,jdbcType=DATE} ,#{frequency} ) + + + insert into common_schedule + + + common_schedule_id, + + + schedule_name, + + + gmt_modified, + + + + + #{commonScheduleId,jdbcType=VARCHAR}, + + + #{scheduleName,jdbcType=VARCHAR}, + + + #{gmtModified,jdbcType=DATE}, + + + + + update common_schedule + + + schedule_name = #{scheduleName,jdbcType=VARCHAR}, + + + gmt_modified = #{gmtModified,jdbcType=DATE}, + + + where common_schedule_id = #{commonScheduleId,jdbcType=VARCHAR} + + + + update common_schedule + set schedule_name = #{scheduleName,jdbcType=VARCHAR}, + gmt_modified = #{gmtModified,jdbcType=DATE} + where common_schedule_id = #{commonScheduleId,jdbcType=VARCHAR} + + + update common_schedule set gmt_modified=now() where common_schedule_id=#{commonScheduleId} and gmt_modified <=date_add(now(),interval -frequency second) + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/ExplorerOperationMapper.xml b/src/main/resources/mapper/ExplorerOperationMapper.xml new file mode 100644 index 0000000..46465d0 --- /dev/null +++ b/src/main/resources/mapper/ExplorerOperationMapper.xml @@ -0,0 +1,55 @@ + + + + + + + + update `io_source` + + + + + when `sourceID` = #{item.sourceID} then #{item.parentLevel} + + + + + where `sourceID` in + + #{item.sourceID} + + + + + + + update `io_source` + + + + + when `sourceID` = #{item.sourceID} then #{item.size} + + + + + where `sourceID` in + + #{item.sourceID} + + + \ No newline at end of file diff --git a/src/main/resources/mapper/FileMapper.xml b/src/main/resources/mapper/FileMapper.xml new file mode 100644 index 0000000..8dfd056 --- /dev/null +++ b/src/main/resources/mapper/FileMapper.xml @@ -0,0 +1,272 @@ + + + + + + + + insert into io_file(`name`, `size`, ioType, path, hashSimple, hashMd5, linkCount, createTime, modifyTime,is_preview,app_preview,is_h264_preview,is_m3u8,fileName + ,convertSize,thumbSize) + values (#{name}, #{size}, #{ioType}, #{path}, #{hashSimple}, #{hashMd5}, 0, unix_timestamp(), unix_timestamp(), IFNULL(#{isPreview}, 0 ), IFNULL(#{appPreview}, 0 ), IFNULL(#{isH264Preview}, 0 ) + , IFNULL(#{isM3u8}, 0 ), IFNULL(#{fileName}, ''), IFNULL(#{convertSize}, 0 ), IFNULL(#{thumbSize}, 0 ) + ) + + + insert into io_file(`name`, `size`, ioType, path, hashSimple, hashMd5, linkCount, createTime, modifyTime,is_preview,app_preview,is_h264_preview,is_m3u8,fileName + ,convertSize,thumbSize) + values + + (#{item.name}, #{item.size}, #{item.ioType}, #{item.path}, #{item.hashSimple}, #{item.hashMd5}, 0, unix_timestamp(), unix_timestamp() + , IFNULL(#{item.isPreview}, 0 ), IFNULL(#{item.appPreview}, 0 ), IFNULL(#{item.isH264Preview}, 0 ), IFNULL(#{item.isM3u8}, 0 ) + , IFNULL(#{item.fileName}, ''), IFNULL(#{item.convertSize}, 0 ), IFNULL(#{item.thumbSize}, 0 ) + ) + + + + insert into io_file_meta(`fileID`, `key`, `value`, createTime, modifyTime) + values (#{fileID}, #{key}, #{value}, unix_timestamp(), unix_timestamp() + ) + + + + insert into io_file_meta(`fileID`, `key`, `value`, createTime, modifyTime) + values + + (#{item.fileID}, #{item.key}, #{item.value}, unix_timestamp(), unix_timestamp() + ) + + + + + + + update io_file + set is_m3u8 = #{isM3u8}, + is_preview = #{isPreview}, + convertSize = #{convertSize}, + modifyTime = unix_timestamp() + where fileID = #{fileID} + + + update io_file + set is_m3u8 = #{commonSource.isM3u8}, + is_preview = #{commonSource.isPreview}, + convertSize = #{commonSource.convertSize}, + modifyTime = unix_timestamp() + where fileID in + + #{item} + + and is_m3u8 = 0 + + + update io_file + set app_preview = #{appPreview}, + is_preview = #{isPreview}, + modifyTime = unix_timestamp() + where fileID = #{fileID} + + + update io_file + set is_m3u8 = 1, + modifyTime = unix_timestamp() + where fileID in + + #{item} + + and is_m3u8 = 0 + + + update io_file + set app_preview = 1, + is_preview = 1, + modifyTime = unix_timestamp() + where fileID in + + #{item} + + and app_preview = 0 + + + + + + delete from io_file + where `fileID` in + + #{item} + + + + delete from io_file_meta + where `fileID` in + + #{item} + + + + delete from io_file_contents + where `fileID` in + + #{item} + + + + + + update `io_file_meta` + + + + + when `fileID` = #{item.fileID} then #{item.value} + + + + + where `fileID` in + + #{item.fileID} + + and `key` = 'fileInfoMore' + + + update `io_file_meta` set `value` = #{value} + where `fileID` = #{fileID} and `key` = 'fileInfoMore' + + + + + + + update io_file + set isExistFile = 0, + modifyTime = unix_timestamp() + where fileID = #{fileID} + + + update io_file + set is_h264_preview = #{isH264Preview}, + convertSize = convertSize + #{convertSize}, + modifyTime = unix_timestamp() + where fileID = #{fileID} + + + + update io_file + set is_h264_preview = #{isH264Preview}, + thumbSize = thumbSize + #{thumbSize}, + modifyTime = unix_timestamp() + where fileID = #{fileID} + + + + update `io_file` set `hashMd5` = #{hashMd5} + where `path` = #{path} + + + + + + update `io_file` set `hashMd5` = #{hashMd5}, `size` = #{size} + where `fileID` = #{fileID} + + + + update io_file set path = #{path} where fileID = #{fileID} and path = '' + + + + UPDATE io_file cs + SET cs.is_h264_preview = #{isH264Preview}, cs.modifyTime = unix_timestamp() + WHERE cs.fileID = #{fileID} + + + \ No newline at end of file diff --git a/src/main/resources/mapper/GroupMapper.xml b/src/main/resources/mapper/GroupMapper.xml new file mode 100644 index 0000000..78d7172 --- /dev/null +++ b/src/main/resources/mapper/GroupMapper.xml @@ -0,0 +1,252 @@ + + + + + + g.groupID, g.`name` , g.parentID, g.parentLevel, g.sort, g.sizeMax, g.sizeUse , g.`status` + + + + INSERT INTO `group` ( `name`, `parentID`, `parentLevel`, `extraField`, `sort`, `sizeMax`, `sizeUse`, `modifyTime`, `createTime`, `status`) + VALUES + ( #{name}, #{parentID}, #{parentLevel}, IFNULL(#{extraField}, ''), #{sort}, #{sizeMax}, 0, unix_timestamp(now()), unix_timestamp(now()), 1 + ); + + + update `group` + set `name` = #{name}, + `parentID` = #{parentID}, + `parentLevel` = #{parentLevel}, + `sizeMax` = #{sizeMax}, + modifyTime = unix_timestamp(now()) + where groupID = #{groupID} + + + + + + update `group` + set `status` = #{status}, modifyTime = unix_timestamp(now()) + where groupID = #{groupID} + + + + update `group` + + + + + when `groupID` = #{item.groupID} then #{item.sort} + + + + + where `groupID` in + + #{item.groupID} + + + + + + + update `io_source` + set `name` = #{name}, + parentID = #{parentID}, + parentLevel = #{parentLevel}, + modifyTime = unix_timestamp(now()) + where targetType = 2 + and sourceID = #{sourceID} + and isFolder = 1 + and isDelete = 0 + + + + + + + + + + + + + + + + + + + + + update `group` + + + + when groupID=#{item.groupID} then #{item.sizeUse} + + + + where groupID in + + #{item.groupID} + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/GroupMetaMapper.xml b/src/main/resources/mapper/GroupMetaMapper.xml new file mode 100644 index 0000000..f389dc4 --- /dev/null +++ b/src/main/resources/mapper/GroupMetaMapper.xml @@ -0,0 +1,40 @@ + + + + + + delete from group_meta + where groupID = #{groupID} + and `key` in + + #{item} + + + + + insert into group_meta (groupID, `key`,`value`, createTime, modifyTime) + values + + ( + #{item.groupID}, #{item.key}, #{item.value}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/GroupSourceMapper.xml b/src/main/resources/mapper/GroupSourceMapper.xml new file mode 100644 index 0000000..c95b33b --- /dev/null +++ b/src/main/resources/mapper/GroupSourceMapper.xml @@ -0,0 +1,44 @@ + + + + + + insert into group_source (groupID, sourceID, createTime) + values + ( + #{groupID}, #{sourceID}, unix_timestamp(now()) + ) + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/HomeExplorerMapper.xml b/src/main/resources/mapper/HomeExplorerMapper.xml new file mode 100644 index 0000000..092f26b --- /dev/null +++ b/src/main/resources/mapper/HomeExplorerMapper.xml @@ -0,0 +1,442 @@ + + + + + + + + + + + + and io.parentID = #{sourceID} + + + and io.sourceID = #{thisSourceID} + + + and io.targetType = #{targetType} + + + and io.parentLevel = #{parentLevel} + + + and uf.tagID = #{tagID} + + + and io.isFolder = #{isFolder} + + + and f.hashMd5 = #{repeatHashMd5} + + + and io.name = #{repeatName} + + + and ( + + io.parentLevel like concat('%', #{pLe}, '%') + + ) + + + and ( io.name like concat('%', #{keyword}, '%') OR io.`name_pinyin` LIKE CONCAT('%',#{keyword}, '%') + OR io.`name_pinyin_simple` LIKE CONCAT('%',#{keyword}, '%') + ) + + + + + and (io.createUser = #{userID} or io.modifyUser = #{userID}) + + + and (io.createUser = #{userID}) + + + + + + + and io.`type` = #{documentType} + + + and io.fileType in + + #{fileTypeItem} + + + + + + + + and (io.size between #{minSize} and #{maxSize}) + + + and (io.size >= #{minSize}) + + + + + + and ( #{maxSize} >=io.size) + + + + + + + + and (io.createTime between #{minDate} and #{maxDate}) + + + and (io.createTime >= #{minDate}) + + + + + + and ( #{maxDate} >=io.createTime) + + + + + and not exists (select sourceID from group_source gs where io.sourceID = gs.sourceID ) + + + + + + + insert into io_source(sourceHash, targetType, targetID, createUser, modifyUser, isFolder, + `name`, fileType, parentID, parentLevel, fileID, isDelete, `size`, createTime, modifyTime, + viewTime,storageID,name_pinyin,name_pinyin_simple) + values ('', #{targetType}, #{targetID}, #{createUser}, #{modifyUser}, #{isFolder}, #{name}, #{fileType}, #{parentID}, #{parentLevel}, #{fileID}, 0, 0, unix_timestamp(), unix_timestamp(), + unix_timestamp(), IFNULL(#{storageID},0), #{namePinyin}, #{namePinyinSimple} + ) + + + + + + + + + + update `group` + set sizeUse = sizeUse + #{memory} + where groupID = #{groupID} + + + update `group` + set sizeUse = sizeUse + #{memory} + where groupID in + + #{item} + + + + update `user` + set sizeUse = sizeUse + #{memory} + where userID = #{userID} + + + update `user` + set sizeUse = sizeUse - #{memory} + where userID = #{userID} + + + update `group` + + + + when groupID=#{item.groupID} then `sizeUse` - #{item.sizeUse} + + + + where groupID in + + #{item.groupID} + + + + + + + + + + + + + + + + + + + + + + insert into io_source(sourceHash, targetType, targetID, createUser, modifyUser, isFolder, + `name`, fileType, parentID, parentLevel, fileID, isDelete, `size`, createTime, modifyTime, + viewTime, storageID,name_pinyin,name_pinyin_simple) + values ('', #{targetType}, #{targetID}, #{createUser}, #{modifyUser}, #{isFolder}, #{name}, #{fileType}, #{parentID}, #{parentLevel}, #{fileID}, 0, 0, unix_timestamp(), unix_timestamp(), + unix_timestamp(), IFNULL(#{storageID},0), #{namePinyin}, #{namePinyinSimple} + ) + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/IoSourceAuthMapper.xml b/src/main/resources/mapper/IoSourceAuthMapper.xml new file mode 100644 index 0000000..ffdcc7d --- /dev/null +++ b/src/main/resources/mapper/IoSourceAuthMapper.xml @@ -0,0 +1,79 @@ + + + + + + insert into io_source_auth (sourceID, `targetType`,`targetID`, `authID`, `authDefine`, createTime, modifyTime) + values ( + #{sourceID}, #{targetType}, #{targetID}, #{authID}, #{authDefine}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + insert into io_source_auth (sourceID, `targetType`,`targetID`, `authID`, `authDefine`, createTime, modifyTime) + values + + ( + #{item.sourceID}, #{item.targetType}, #{item.targetID}, #{item.authID}, #{item.authDefine}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + + delete from io_source_auth where sourceID = #{sourceID} + + + + + + + + + diff --git a/src/main/resources/mapper/IoSourceEventMapper.xml b/src/main/resources/mapper/IoSourceEventMapper.xml new file mode 100644 index 0000000..ee69937 --- /dev/null +++ b/src/main/resources/mapper/IoSourceEventMapper.xml @@ -0,0 +1,51 @@ + + + + + + insert into io_source_event (sourceID, `sourceParent`,`userID`, `type`, `desc`, createTime) + values ( + #{sourceID}, #{sourceParent}, #{userID}, #{type}, #{desc}, unix_timestamp(now()) + ) + + + insert into io_source_event (sourceID, `sourceParent`,`userID`, `type`, `desc`, createTime) + values + + ( + #{item.sourceID}, #{item.sourceParent}, #{item.userID}, #{item.type}, #{item.desc}, unix_timestamp(now()) + ) + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/IoSourceHistoryMapper.xml b/src/main/resources/mapper/IoSourceHistoryMapper.xml new file mode 100644 index 0000000..5c67383 --- /dev/null +++ b/src/main/resources/mapper/IoSourceHistoryMapper.xml @@ -0,0 +1,101 @@ + + + + + + insert into io_source_history (sourceID, `userID`,`fileID`, `size`, `detail`, createTime, modifyTime) + values ( + #{sourceID}, #{userID}, #{fileID}, #{size}, #{detail}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + insert into io_source_history (sourceID, `userID`,`fileID`, `size`, `detail`, createTime, modifyTime) + values + + ( + #{item.sourceID}, #{item.userID}, #{item.fileID}, #{item.size}, #{item.detail}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + + + + + + update `io_source_history` + set `detail` = #{detail}, + modifyTime = unix_timestamp(now()) + where id = #{id} + + + update `io_source_history` + set `detail` = #{detail}, + `fileID` = #{fileID}, + `userID` = #{userID}, + `size` = #{size}, + modifyTime = unix_timestamp(now()) + where id = #{id} + + + update `io_source` + set `fileID` = #{fileID}, + `size` = #{size}, + `modifyUser` = #{userID}, + modifyTime = unix_timestamp(now()) + where sourceID = #{sourceID} + + + + + delete from io_source_history where id = #{id} + + + delete from io_source_history where sourceID = #{sourceID} + + + + + + + update `io_source_history` + set `size` = #{size}, + `detail` = #{detail}, + modifyTime = unix_timestamp(now()) + where id = #{id} + + \ No newline at end of file diff --git a/src/main/resources/mapper/IoSourceMapper.xml b/src/main/resources/mapper/IoSourceMapper.xml new file mode 100644 index 0000000..2060fc3 --- /dev/null +++ b/src/main/resources/mapper/IoSourceMapper.xml @@ -0,0 +1,501 @@ + + + + + + insert into io_source(sourceHash,`type`, targetType, targetID, createUser, modifyUser, isFolder, + `name`, fileType, parentID, parentLevel, fileID, isDelete, `size`, createTime, modifyTime, + viewTime,convertSize,thumbSize, storageID,name_pinyin,name_pinyin_simple) + values (IFNULL(#{sourceHash},''), IFNULL(#{type},0), #{targetType}, #{targetID}, #{createUser}, #{modifyUser}, #{isFolder}, #{name}, #{fileType}, #{parentID}, #{parentLevel}, #{fileID}, 0, IFNULL(#{size},0), unix_timestamp(), unix_timestamp(), + unix_timestamp(), IFNULL(#{convertSize},0), IFNULL(#{thumbSize},0), IFNULL(#{storageID},0), #{namePinyin}, #{namePinyinSimple} + ) + + + insert into io_source(sourceHash,`type`, targetType, targetID, createUser, modifyUser, isFolder, + `name`, fileType, parentID, parentLevel, fileID, isDelete, `size`, createTime, modifyTime, + viewTime,convertSize,thumbSize, storageID,name_pinyin,name_pinyin_simple) + values + + (IFNULL(#{item.sourceHash},'') , IFNULL(#{item.type}, 0), #{item.targetType}, #{item.targetID}, #{item.createUser}, #{item.modifyUser}, #{item.isFolder}, #{item.name}, #{item.fileType}, #{item.parentID} + , #{item.parentLevel}, #{item.fileID}, 0, IFNULL(#{item.size},0), unix_timestamp(), unix_timestamp(), unix_timestamp(), IFNULL(#{item.convertSize},0), IFNULL(#{item.thumbSize},0) + , IFNULL(#{item.storageID},0), #{item.namePinyin}, #{item.namePinyinSimple} + ) + + + + + update io_source + set isDelete = 1, modifyTime = unix_timestamp() + where isDelete = 0 and sourceID in + + #{item} + + + + + update io_source + set isDelete = 1 , modifyTime = unix_timestamp() + where isDelete = 0 + and ( + + ( parentLevel like concat(#{item},'%')) + + ) + + + + + + + + + + + update io_source + + + + when sourceID=#{item.sourceID} then #{item.name} + + + + + when sourceID=#{item.sourceID} then #{item.namePinyin} + + + + + when sourceID=#{item.sourceID} then #{item.namePinyinSimple} + + + ,modifyUser=#{userID} + ,modifyTime=unix_timestamp() + + where sourceID in + + #{item.sourceID} + + + + + update io_source + + + + when sourceID=#{item.sourceID} then #{item.parentID} + + + + + when sourceID=#{item.sourceID} then #{item.targetType} + + + + + when sourceID=#{item.sourceID} then #{item.parentLevel} + + + ,modifyTime=unix_timestamp() + + where sourceID in + + #{item.sourceID} + + + + update io_source + set isDelete = 0 + , modifyTime = unix_timestamp() + ,modifyUser=#{userID} + where isDelete = 1 and sourceID in + + #{item} + + + + update io_source + set isDelete = 0 , modifyTime = unix_timestamp(),modifyUser=#{userID} + where isDelete = 1 + and ( + + ( parentLevel like concat(#{item},'%')) + + ) + + + delete from io_source + where isDelete = 1 and `sourceID` in + + #{item} + + + + delete from io_source + where isDelete = 1 + and ( + + ( parentLevel like concat(#{item},'%')) + + ) + + + + + + + update `io_source` + set `size` = `size` + #{memory} + where sourceID in + + #{item} + + + + + update io_source + + + + when sourceID=#{item.sourceID} then `size` + #{item.size} + + + + where sourceID in + + #{item.sourceID} + + + + + update `io_source` + set `size` = `size` - #{memory} + where sourceID in + + #{item} + + + + + update io_source + + + + when sourceID=#{item.sourceID} then `size` - #{item.size} + + + + where sourceID in + + #{item.sourceID} + + + + + + update `io_source` + set sort = #{sort} + where sourceID = #{sourceID} + + + + update `io_source` + set modifyUser = #{modifyUser}, + `size` = #{size}, + `fileID` = #{fileID}, + modifyTime = unix_timestamp() + where sourceID = #{sourceID} + + + + + + + + + update `io_source` + set modifyUser = #{modifyUser}, + `size` = #{size}, + modifyTime = unix_timestamp() + where sourceID = #{sourceID} + + + update `io_file` + set `size` = #{size}, + `hashMd5` = #{hashMd5}, + modifyTime = unix_timestamp() + where fileID = #{fileID} + + + + + + + + + + + + + update io_source + + + + when sourceID=#{item.sourceID} then #{item.parentID} + + + + + when sourceID=#{item.sourceID} then #{item.targetType} + + + + + when sourceID=#{item.sourceID} then #{item.name} + + + + + when sourceID=#{item.sourceID} then #{item.parentLevel} + + + ,isDelete=0 + ,modifyTime=unix_timestamp() + + where sourceID in + + #{item.sourceID} + + + + + + + + + + + update `io_source` + set modifyUser = #{modifyUser}, + `size` = `size` + #{size}, + `fileID` = #{fileID}, + thumbSize = thumbSize + #{thumbSize}, + convertSize = convertSize + #{convertSize}, + modifyTime = unix_timestamp() + where sourceID = #{sourceID} + + + + update `io_source` + set convertSize = convertSize + #{convertSize} + where sourceID = #{sourceID} + + + + update `io_source` + set thumbSize = thumbSize + #{thumbSize} + where sourceID = #{sourceID} + + + + + + update `io_source` + set `size` = #{size} + where sourceID = #{sourceID} + + + + + update `io_source` + set description = #{description} + where sourceID = #{sourceID} + + \ No newline at end of file diff --git a/src/main/resources/mapper/IoSourceMetaMapper.xml b/src/main/resources/mapper/IoSourceMetaMapper.xml new file mode 100644 index 0000000..4443818 --- /dev/null +++ b/src/main/resources/mapper/IoSourceMetaMapper.xml @@ -0,0 +1,87 @@ + + + + + + delete from io_source_meta + where sourceID = #{sourceID} + and `key` in + + #{item} + + + + delete from io_source_meta + where sourceID in + + #{sourceId} + + and `key` in + + #{item} + + + + insert into io_source_meta (sourceID, `key`,`value`, createTime, modifyTime) + values + + ( + #{item.sourceID}, #{item.key}, #{item.value}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + insert into io_source_meta (sourceID, `key`,`value`, createTime, modifyTime) + values + ( + #{sourceID}, #{key}, #{value}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + + + + update io_source_meta set `value` = #{desc} + where sourceID = #{sourceID} + and `key` = #{key} + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/IoSourceRecycleMapper.xml b/src/main/resources/mapper/IoSourceRecycleMapper.xml new file mode 100644 index 0000000..e3d5733 --- /dev/null +++ b/src/main/resources/mapper/IoSourceRecycleMapper.xml @@ -0,0 +1,41 @@ + + + + + + insert into io_source_recycle (targetType, `targetID`,`sourceID`, userID, parentLevel, createTime) + values + + ( + #{targetType}, #{targetID}, #{sourceID}, #{userID}, #{parentLevel}, unix_timestamp(now()) + ) + + + + + insert into io_source_recycle (targetType, `targetID`,`sourceID`, userID, parentLevel, createTime) + values + + ( + #{item.targetType}, #{item.targetID}, #{item.sourceID}, #{item.userID}, #{item.parentLevel}, unix_timestamp(now()) + ) + + + + + delete from io_source_recycle + where userID = #{userID} and targetType = #{targetType} + and `sourceID` in + + #{item} + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/LogScheduleMapper.xml b/src/main/resources/mapper/LogScheduleMapper.xml new file mode 100644 index 0000000..4f9b574 --- /dev/null +++ b/src/main/resources/mapper/LogScheduleMapper.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + log_schedule_id, common_schedule_id, gmt_start, gmt_end, state, remark + + + insert into log_schedule (log_schedule_id, common_schedule_id, gmt_start, + gmt_end, state, remark + ) + values (#{logScheduleId,jdbcType=BIGINT}, #{commonScheduleId,jdbcType=VARCHAR}, now(), + now(), #{state,jdbcType=CHAR}, #{remark,jdbcType=VARCHAR} + ) + + + update log_schedule + set common_schedule_id = #{commonScheduleId,jdbcType=VARCHAR}, + gmt_start = #{gmtStart,jdbcType=TIMESTAMP}, + gmt_end = #{gmtEnd,jdbcType=TIMESTAMP}, + state = #{state,jdbcType=CHAR}, + remark = #{remark,jdbcType=VARCHAR} + where log_schedule_id = #{logScheduleId,jdbcType=BIGINT} + + + UPDATE log_schedule + set + state = #{state}, + gmt_end = #{gmtEnd}, + remark = concat(#{remark}, ',定时任务执行时间:', TIMESTAMPDIFF(SECOND, gmt_start, #{gmtEnd})) + where log_schedule_id = #{logScheduleId} + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/NoticeDao.xml b/src/main/resources/mapper/NoticeDao.xml new file mode 100644 index 0000000..7945895 --- /dev/null +++ b/src/main/resources/mapper/NoticeDao.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + id,title,level, + status,enable,send_time, + sender_id,sender_ip,notice_type, + create_time,modify_time + + + diff --git a/src/main/resources/mapper/NoticeDetailDao.xml b/src/main/resources/mapper/NoticeDetailDao.xml new file mode 100644 index 0000000..468658a --- /dev/null +++ b/src/main/resources/mapper/NoticeDetailDao.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/src/main/resources/mapper/NoticeUserDao.xml b/src/main/resources/mapper/NoticeUserDao.xml new file mode 100644 index 0000000..b6f693e --- /dev/null +++ b/src/main/resources/mapper/NoticeUserDao.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + id,notice_id,user_id, + is_read,year,create_time, + modify_time + + diff --git a/src/main/resources/mapper/RoleMapper.xml b/src/main/resources/mapper/RoleMapper.xml new file mode 100644 index 0000000..7d4c48c --- /dev/null +++ b/src/main/resources/mapper/RoleMapper.xml @@ -0,0 +1,88 @@ + + + + + + r.roleID, r.role_name roleName, r.description, r.label, r.auth, r.enable, r.is_system isSystem, r.administrator, r.ignoreFileSize, r.sort, r.role_type roleType,r.modifyTime + + + + INSERT INTO `role` ( `role_name`, `code`, `description`, `label`, `auth`, `createTime`, `modifyTime`, `deleteTime`, `status`, `enable` + , `is_system`, `administrator`, `ignoreFileSize`, `ignoreExt`, `sort`, role_type) + VALUES + ( #{roleName}, #{code}, IFNULL(#{description}, ''), IFNULL(#{label}, ''), IFNULL(#{auth}, ''), unix_timestamp(now()), unix_timestamp(now()), unix_timestamp(now()), #{status} + , #{enable}, IFNULL(#{isSystem}, 0), IFNULL(#{administrator}, 0), #{ignoreFileSize}, IFNULL(#{ignoreExt}, ''), #{sort}, #{roleType} + ); + + + + update `role` + set `role_name` = #{roleName}, + `description` = #{description}, + `label` = #{label}, + `auth` = #{auth}, + `enable` = #{enable}, + `ignoreFileSize` = #{ignoreFileSize}, + modifyTime = unix_timestamp(now()) + where roleID = #{roleID} + + + + + update `role` + set `status` = #{status}, modifyTime = unix_timestamp(now()) + where roleID = #{roleID} and is_system = 0 and role_type = #{roleType} + + + + + + update `role` + + + + + when `roleID` = #{item.roleID} then #{item.sort} + + + + + where role_type = #{roleType} + and `roleID` in + + #{item.roleID} + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/ShareMapper.xml b/src/main/resources/mapper/ShareMapper.xml new file mode 100644 index 0000000..7fd4739 --- /dev/null +++ b/src/main/resources/mapper/ShareMapper.xml @@ -0,0 +1,201 @@ + + + + + + insert into share (title, shareHash, `userID`, `sourceID`, `sourcePath` , url, isLink, isShareTo, password, timeTo, numView, numDownload, options + , createTime, modifyTime ) + values (#{title}, #{shareHash}, #{userID}, #{sourceID}, #{sourcePath}, #{url}, #{isLink}, #{isShareTo}, #{password}, #{timeTo}, #{numView}, #{numDownload} + , #{options} , unix_timestamp(now()), unix_timestamp(now())) + + + update `share` + set `title` = #{title}, + `password` = #{password}, + `options` = #{options}, + `timeTo` = #{timeTo}, + `status` = #{status}, + modifyTime = unix_timestamp(now()) + where shareID = #{shareID} + + + + + + delete from share where shareID = #{shareID} + + + delete from share where shareID in + + #{item} + + + + + update `share` set `numView` = numView + 1 where shareID = #{shareID} + + + update `share` set `numDownload` = numDownload + 1 where shareID = #{shareID} + + + update `share` set status = #{operateType} + WHERE shareID IN + + #{_id} + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/ShareReportMapper.xml b/src/main/resources/mapper/ShareReportMapper.xml new file mode 100644 index 0000000..082b7d0 --- /dev/null +++ b/src/main/resources/mapper/ShareReportMapper.xml @@ -0,0 +1,53 @@ + + + + + + SELECT sr.id, sr.share_id shareId, sr.reason,sr.create_time createTime, sr.title, sr.user_id userId, + sr.status, s.status shareStatus, sr.reason, sr.report_type, sr.source_id sourceId, s.shareHash + FROM share_report sr INNER JOIN share s ON s.shareID = sr.share_id + + + + + + + + AND sr.create_time = ]]> #{dto.timeFrom} + + + AND sr.create_time #{dto.timeTo} + + + AND sr.report_type = #{dto.reportType} + + + + AND sr.status = #{dto.status} + + + AND sr.status = 1 AND s.status = #{dto.status} + + + + + ORDER BY sr.create_time DESC + + + + + + + diff --git a/src/main/resources/mapper/ShareToMapper.xml b/src/main/resources/mapper/ShareToMapper.xml new file mode 100644 index 0000000..b6b01ff --- /dev/null +++ b/src/main/resources/mapper/ShareToMapper.xml @@ -0,0 +1,28 @@ + + + + + + insert into share_to (shareID, `targetType`, `targetID`,`authID`,`authDefine`, createTime, modifyTime) + values + + ( + #{item.shareID}, #{item.targetType}, #{item.targetID}, #{item.authID}, #{item.authDefine}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + delete from share_to where shareID = #{shareID} + + + delete from share_to where shareID in + + #{item} + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/SystemLogMapper.xml b/src/main/resources/mapper/SystemLogMapper.xml new file mode 100644 index 0000000..cdd737a --- /dev/null +++ b/src/main/resources/mapper/SystemLogMapper.xml @@ -0,0 +1,76 @@ + + + + + + insert into system_log (sessionID, userID, `type`, `desc`, `createTime` , visit_date, client_type, osName ) + values (#{sessionID}, #{userID}, #{type}, #{desc}, unix_timestamp(now()), #{visitDate}, IFNULL(#{clientType}, '1'), #{osName}) + + + insert into system_log (sessionID, userID, `type`, `desc`, `createTime` , visit_date, client_type, osName ) + values + + (#{item.sessionID}, #{item.userID}, #{item.type}, #{item.desc}, unix_timestamp(now()), #{item.visitDate}, IFNULL(#{item.clientType}, '1'), #{item.osName}) + + + + + + + and log.userID = #{userID} + + + and log.`type` = #{type} + + + and log.`type` in + + #{item} + + + + + + + and (log.createTime between #{minDate} and #{maxDate}) + + + and (log.createTime >= #{minDate}) + + + + + + and ( #{maxDate} >=log.createTime) + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/SystemOptionMapper.xml b/src/main/resources/mapper/SystemOptionMapper.xml new file mode 100644 index 0000000..1993823 --- /dev/null +++ b/src/main/resources/mapper/SystemOptionMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + update `system_option` + + + + + when `key` = #{item.key} then #{item.value} + + + + + where `type` = #{type} + and `key` in + + #{item.key} + + + + + + + + update `system_option` + set `value` = #{value} + where `id` = #{id} + + + INSERT INTO `system_option` (`type`, `key`, `value`, `createTime`, `modifyTime`) + values + + ( + '', #{item.key}, #{item.value}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserCommonInfoMapper.xml b/src/main/resources/mapper/UserCommonInfoMapper.xml new file mode 100644 index 0000000..fd85d23 --- /dev/null +++ b/src/main/resources/mapper/UserCommonInfoMapper.xml @@ -0,0 +1,21 @@ + + + + + + UPDATE user_common_info + SET view_count = view_count + 1 + WHERE info_id = #{id} + + + AND user_id = #{userId} + + + AND ip = #{ip} + + + + + diff --git a/src/main/resources/mapper/UserFavMapper.xml b/src/main/resources/mapper/UserFavMapper.xml new file mode 100644 index 0000000..dfd74f4 --- /dev/null +++ b/src/main/resources/mapper/UserFavMapper.xml @@ -0,0 +1,182 @@ + + + + + + insert into user_fav (userID, `tagID`,`name`, path, `type`, `sort`, modifyTime, createTime) + values ( + #{userID}, #{tagID}, #{name}, #{path}, #{type}, #{sort}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + insert into user_fav (userID, `tagID`,`name`, path, `type`, `sort`, modifyTime, createTime) + values + + ( + #{item.userID}, #{item.tagID}, #{item.name}, #{item.path}, #{item.type}, #{item.sort}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + + + + delete from user_fav + where userID = #{userID} and tagID = 0 and `type` = 'source' and `path` in + + #{item} + + + + + delete from user_fav + where userID = #{userID} and tagID = 0 and id in + + #{item} + + + + + + + + delete from user_fav + where tagID = #{tagID} and `type` = 'source' + and `path` in + + #{item} + + + + + + + + + + + + + + + + + + delete from user_fav + where tagID = #{tagID} and userID = #{userID} and `type` = 'source' + + + + update `user_fav` + set sort = sort + 1 + where userID = #{userID} and tagID = 0 and `type` = 'source' + + + update `user_fav` + set sort = sort - 1 + where userID = #{userID} and tagID = 0 and `type` = 'source' and sort > 0 + + + update `user_fav` + set sort = #{sort} + where userID = #{userID} and tagID = 0 and `type` = 'source' and path = #{path} + + + + + + update `user_fav` + set sort = sort + 1 + where userID = #{userID} and tagID > 0 and `type` = 'source' + + + update `user_fav` + set sort = sort - 1 + where userID = #{userID} and tagID > 0 and `type` = 'source' and sort > 0 + + + update `user_fav` + set sort = #{sort} + where userID = #{userID} and tagID > 0 and `type` = 'source' and path = #{path} + + + update `user_fav` + set `name` = #{name} + where id = #{id} + + + + delete from user_fav + where tagID = #{tagID} and userID = 0 and `type` = 'info' + + + delete from user_fav + where path = #{path} and userID = 0 and `type` = 'info' + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserGroupMapper.xml b/src/main/resources/mapper/UserGroupMapper.xml new file mode 100644 index 0000000..9395f44 --- /dev/null +++ b/src/main/resources/mapper/UserGroupMapper.xml @@ -0,0 +1,66 @@ + + + + + + + + + delete from user_group where userID = #{userID} + + + delete from user_group where groupID = #{groupID} + + + insert into user_group (userID, groupID, authID,sort, createTime, modifyTime) + values + + ( + #{item.userID}, #{item.groupID}, #{item.authID},#{item.sort} + , unix_timestamp(now()), unix_timestamp(now()) + ) + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserJwtMapper.xml b/src/main/resources/mapper/UserJwtMapper.xml new file mode 100644 index 0000000..085a9b2 --- /dev/null +++ b/src/main/resources/mapper/UserJwtMapper.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + u.userID, u.name, u.nickname, u.password, u.lastLogin, u.phone, u.email, u.status, u.sex, u.avatar, u.roleID + + + + + + + + update `user` set lastLogin = #{lastLogin} where userID = #{userID} + + + + UPDATE `user` u + SET + gmt_modified = now() + + ,u.avatar = #{avatar} + + WHERE u.userID = #{userID} + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserMapper.xml b/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..fd27afa --- /dev/null +++ b/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + u.userID, u.`name`, u.nickname, u.lastLogin, u.phone, u.email, u.`status`, u.sex, u.avatar, u.roleID, u.dingOpenId, u.wechatOpenId, u.alipayOpenId, u.enWechatOpenId + + + + INSERT INTO `user` ( `name`, `roleID`, `email`, `phone`, `nickname`, `avatar`, `sex`, `password`, `sizeMax`, `sizeUse`, `status`, `lastLogin` + , `modifyTime`, `createTime`, `dingOpenId`, wechatOpenId, alipayOpenId) VALUES + (#{name}, #{roleID}, IFNULL(#{email}, ''), IFNULL(#{phone}, ''), IFNULL(#{nickname}, ''), IFNULL(#{avatar}, ''), #{sex}, #{password}, #{sizeMax}, IFNULL(#{sizeUse}, 0), IFNULL(#{status}, 1) + , unix_timestamp(now()), unix_timestamp(now()), unix_timestamp(now()), #{dingOpenId}, #{wechatOpenId}, #{alipayOpenId}); + + + + update `user` + set + + `name` = #{name}, + + + `roleID` = #{roleID}, + + + `sizeMax` = #{sizeMax}, + + + `email` = #{email}, + + + `avatar` = #{avatar}, + + + `phone` = #{phone}, + + + `nickname` = #{nickname}, + + + `sex` = #{sex}, + + + dingOpenId = #{dingOpenId}, + + + enWechatOpenId = #{enWechatOpenId}, + + + wechatOpenId = #{wechatOpenId}, + + + alipayOpenId = #{alipayOpenId}, + + + `password` = #{password}, + + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + + + + + + update `user` + set `status` = #{status}, modifyTime = unix_timestamp(now()) + where userID in + + #{item} + + + + update `user` + set `nickname` = #{nickname}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + update `user` + set `email` = #{email}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + update `user` + set `password` = #{password}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + + + + + + + + + + + + update `user` + set `sex` = #{sex}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + update `user` + set `avatar` = #{avatar}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + update `user` + set `avatar` = #{avatar}, + modifyTime = unix_timestamp(now()) + where userID in + + #{item} + + + + + + update `user` + set `phone` = #{phone}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserMetaMapper.xml b/src/main/resources/mapper/UserMetaMapper.xml new file mode 100644 index 0000000..494bbf9 --- /dev/null +++ b/src/main/resources/mapper/UserMetaMapper.xml @@ -0,0 +1,24 @@ + + + + + + delete from user_meta + where userID = #{userID} + and `key` in + + #{item} + + + + + insert into user_meta (userID, `key`,`value`, createTime, modifyTime) + values + + ( + #{item.userID}, #{item.key}, #{item.value}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserOptionMapper.xml b/src/main/resources/mapper/UserOptionMapper.xml new file mode 100644 index 0000000..e9d3c7c --- /dev/null +++ b/src/main/resources/mapper/UserOptionMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + insert into user_option (userID, `type`, `key`,`value`, createTime, modifyTime) + values + + ( + #{item.userID}, #{item.type}, #{item.key}, #{item.value}, unix_timestamp(now()), unix_timestamp(now()) + ) + + + + update `user_option` + set `value` = #{value}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} and `key` = #{key} and `type` = #{type} + + + update `user_option` + set `value` = #{value}, + modifyTime = unix_timestamp(now()) + where userID = #{userID} and `key` = #{key} and `type` = '' + + + + + + + + delete from user_option + where userID = #{userID} and `key` in + + #{item} + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/VisitCountRecordMapper.xml b/src/main/resources/mapper/VisitCountRecordMapper.xml new file mode 100644 index 0000000..4969777 --- /dev/null +++ b/src/main/resources/mapper/VisitCountRecordMapper.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + id,visitCount,deviceType,osName,type, + visitDay,modifyTime,createTime + + + + + + + + + delete from visit_count_record + where id = #{id,jdbcType=BIGINT} + + + insert into visit_count_record + ( id,visitCount,deviceType + ,visitDay,modifyTime,createTime + ) + values (#{id,jdbcType=BIGINT},#{visitCount,jdbcType=BIGINT},#{deviceType,jdbcType=TINYINT} + ,#{visitDay,jdbcType=DATE},#{modifyTime,jdbcType=BIGINT},#{createTime,jdbcType=BIGINT} + ) + + + insert into visit_count_record + + id, + visitCount, + deviceType, + visitDay, + modifyTime, + createTime, + + + #{id,jdbcType=BIGINT}, + #{visitCount,jdbcType=BIGINT}, + #{deviceType,jdbcType=TINYINT}, + #{visitDay,jdbcType=DATE}, + #{modifyTime,jdbcType=BIGINT}, + #{createTime,jdbcType=BIGINT}, + + + + insert into visit_count_record(visitCount,deviceType,osName,type,visitDay,modifyTime,createTime) + VALUES + + ( + #{_records.visitCount,jdbcType=BIGINT}, + #{_records.deviceType,jdbcType=TINYINT}, + #{_records.osName,jdbcType=VARCHAR}, + #{_records.type,jdbcType=TINYINT}, + #{_records.visitDay,jdbcType=DATE}, + #{_records.modifyTime,jdbcType=BIGINT}, + #{_records.createTime,jdbcType=BIGINT} + ) + + + + update visit_count_record + + + + + visitCount = visitCount + #{record.visitCount,jdbcType=BIGINT}, + + + + + visitCount = #{record.visitCount,jdbcType=BIGINT}, + + + + + + deviceType = #{record.deviceType,jdbcType=TINYINT}, + + + visitDay = #{record.visitDay,jdbcType=DATE}, + + + `type` = #{record.type,jdbcType=TINYINT}, + + + osName = #{record.osName,jdbcType=VARCHAR}, + + + modifyTime = #{record.modifyTime,jdbcType=BIGINT}, + + + createTime = #{record.createTime,jdbcType=BIGINT}, + + + where id = #{record.id,jdbcType=BIGINT} + + + update visit_count_record + set + visitCount = #{visitCount,jdbcType=BIGINT}, + deviceType = #{deviceType,jdbcType=TINYINT}, + visitDay = #{visitday,jdbcType=DATE}, + modifyTime = #{modifyTime,jdbcType=BIGINT}, + createTime = #{createTime,jdbcType=BIGINT} + where id = #{id,jdbcType=BIGINT} + + diff --git a/src/main/resources/pre/agent.config b/src/main/resources/pre/agent.config new file mode 100644 index 0000000..84e4d83 --- /dev/null +++ b/src/main/resources/pre/agent.config @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The agent namespace +agent.namespace=${SW_AGENT_NAMESPACE:pre} + +# The service name in UI +agent.service_name=${SW_AGENT_NAME:disk} + +# The number of sampled traces per 3 seconds +# Negative number means sample traces as many as possible, most likely 100% +# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1} + +# Authentication active is based on backend setting, see application.yml for more details. +# agent.authentication = ${SW_AGENT_AUTHENTICATION:xxxx} + +# The max amount of spans in a single segment. +# Through this config item, skywalking keep your application memory cost estimated. +# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300} + +# Ignore the segments if their operation names start with these suffix. +# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg} + +# If true, skywalking agent will save all instrumented classes files in `/debugging` folder. +# Skywalking team may ask for these files in order to resolve compatible problem. +# agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true} + +# Backend service addresses. +collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.101.31:11800} + +# Logging level +logging.level=${SW_LOGGING_LEVEL:DEBUG} diff --git a/src/main/resources/pre/application.properties b/src/main/resources/pre/application.properties new file mode 100644 index 0000000..882712e --- /dev/null +++ b/src/main/resources/pre/application.properties @@ -0,0 +1,158 @@ +server.port=80 +spring.application.name=disk +spring.profiles.active=pre + +instance.id=5 +spring.main.allow-bean-definition-overriding=true + +spring.datasource.url=jdbc:mysql://101.71.142.95:16033/cloud_disk_pre?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true +spring.datasource.username=dev +spring.datasource.password=dev123456 +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.initialization-mode=always +spring.datasource.continue-on-error=true +spring.datasource.testOnBorrow=true +spring.mvc.async.request-timeout=20000 +spring.datasource.hikari.read-only=false +spring.datasource.hikari.connection-timeout=60000 +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.validation-timeout=30000 +spring.datasource.hikari.max-lifetime=60000 +spring.datasource.hikari.login-timeout=5 +spring.datasource.hikari.maximum-pool-size=200 +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL +#????? +server.tomcat.max-connections=2000 +#????? +server.tomcat.max-threads=1000 +## Mybatis ??==================================== +mybatis.mapperLocations=classpath:mapper/*.xml +user.default.lady=/static/common/image/head/lady.png +user.default.boy=/static/common/image/head/boy.png +user.default.girl=/static/common/image/head/girl.png +user.default.sir=/static/common/image/head/sir.png +user.default.headPic=/static/common/image/head/girl.png +loginLimit.level1.count=5 +loginLimit.level1.interval=300 +loginLimit.level2.count=10 +loginLimit.level2.interval=300 +loginLimit.level2.denyInterval=600 + +spring.messages.basename=i18n.messages +spring.messages.encoding=utf-8 + +## Redis ???? +spring.redis.database=7 +## Redis????? +spring.redis.cluster.nodes=192.168.110.148:19111,192.168.110.148:19222,192.168.110.148:19333 + +## Redis??????? +##spring.redis.port=8379 +## Redis????????????? +spring.redis.password=123456 +## ???????????????????? +spring.redis.jedis.pool.max-active=8 +## ??????????????????????? +spring.redis.jedis.pool.max-wait=-1 +## ??????????? +spring.redis.jedis.pool.max-idle=8 +## ??????????? +spring.redis.jedis.pool.min-idle=0 +## ?????????? +spring.redis.timeout=300 + +#buildkey +m3u8.buildkey=buildkey +m3u8.buildkey2=buildkey2 +schedule.video_convert_time=0 0/30 * * * ? + +verification.expiried=5 + + +h5doc.apiUrl=http://p2.ebh.net/i2.aspx?from=wuji +h5doc.appId=ebhapp1008 +h5doc.appKey=89327008 +swfdoc.apiUrl=http://p1.ebh.net/i.aspx?from=wuji +swfdoc.appId=ebhapp1005 +swfdoc.appKey=89327005 +swfdoc.callback.ipWhiteList=101.71.142.135 + + +spring.mail.host=smtp.qq.com +spring.mail.username=system@wxbig.cn +#\u6388\u6743\u7801g\uFF0C\u5728QQ\u90AE\u7BB1\u5BA2\u6237\u7AEF\u751F\u6210 \u4FEE\u6539\u6210\u81EA\u5DF1\u7684 \u8BBE\u7F6E-\u8D26\u6237-\u5F00\u542F\u670D\u52A1-\u83B7\u53D6\u6388\u6743\u7801 +spring.mail.password=ENC(AvNBF7xFcdy8792rgQOD2Ad0VhtF7ojqYrI2VJofsHs=) +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true +logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG +# Max file size??10M +spring.servlet.multipart.max-file-size=10485760 +# Max request size??10M +spring.servlet.multipart.max-request-size=10485760 + + +ppt.des.key= +ppt.des.vi= +ppt.server.url=https://weboffice.filesbox.cn/ +ppt.replace.need=0 +ppt.ip.whitelist= +cdn.domain= + +mail.encode.fail = 414667543@qq.com +environment.type=pre +disk.default.size=1024 + +dingding.token=Fl7pOJfYHvnKRHh9fIDUHbWx6cQpxv3Hn8wPiY2rHvbOGrWN +dingding.corpId=ding1f566670a125f1e7 +dingding.aes.key=NRhboNOBa8zsIg5zWpcCTzMrUqLVEvRHS2yDaElPcwa +dingding.app.key=dinglf3c9hvwae9azs2h +dingding.app.secret=oy9btsUAr_WtuLBzJnbwcsz5h193_EgRwdKn-c4Nti5FAsRITFh7yZmg3LW_Lp-r + +yz.view.convert.url=https://demo.filesbox.cn/fcscloud/composite/httpfile +yz.edit.convert.url=https://demo.filesbox.cn/plugin/yzwo +yz.edit.post.url=https://demo.filesbox.cn/plugin/yzwo/api.do +yz.fileId.prefix=p_ + +schedule.deleteCloudDownload=0 0 1 * * ? +webdav.host=https://pre.filesbox.cn + +enWechat.corpId=ww2d1e9bafb529c21f +enWechat.AgentId=100009 +enWechat.Secret=r1V4SE4ZNZRWRMrlAK-be4qDs40OCvYpJ48tvXleghc + +wechat.web.wx_appid=wxeed6a7666ad6b030 +wechat.web.wx_appSecret=3a2d4d810360ac367c3fe64d73af2e0f +wechat.app.wx_appid=wx283aec18f2335a85 +wechat.app.wx_appSecret=b10e94cd00d0aeb6c67fdb5c43449423 + +mybatis-plus.mapper-locations=classpath*:mapper/*.xml +info.common.htmlPath.name=filesbox + +#libreoffice\u914D\u7F6E\u4FE1\u606F +office.libreOfficeVersion=libreoffice6.3 +office.shellFileName=docx.sh +office.shellFileDirectory=/ +design.subPage.limitCount=512 +schedule.msgWarning=*/20 * * * * ? + +#\u626B\u7801\u767B\u5F55\u4E8C\u7EF4\u7801\u6709\u6548\u671F\u3002\u5355\u4F4D\uFF1A\u5206\u949F +scan.login.code.expire=3 + +webdav.rootContext[0]=/webdav/private +webdav.rootContext[1]=/webdav/favor +webdav.license=D:/License.lic +# Whether to print exception stacktrace in the response. +webdav.showExceptions=true +# Here you map you filesystem folder to be root for WebDAV. If not provided default structure will be created for the testing. +webdav.rootFolder=/uploads +# WebSockets are available at this endpoint. WebSockets are used in the default GET page. +webdav.rootWebSocket=/ +logging.level.root=info +logging.level.com.svnlan.user.dao=debug +logging.level.com.svnlan.home.dao=debug +logging.level.com.svnlan.manage.dao=debug +logging.level.com.svnlan.webdav=debug +logging.level.org.jooq=debug +jasypt.encryptor.bean=encryptorBean \ No newline at end of file diff --git a/src/main/resources/pro/agent.config b/src/main/resources/pro/agent.config new file mode 100644 index 0000000..7ef109c --- /dev/null +++ b/src/main/resources/pro/agent.config @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The agent namespace +agent.namespace=pro + +# The service name in UI +agent.service_name=disk + +# The number of sampled traces per 3 seconds +# Negative or zero means off, by default +# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1} + +# Authentication active is based on backend setting, see application.yml for more details. +# agent.authentication = ${SW_AGENT_AUTHENTICATION:xxxx} + +# The max amount of spans in a single segment. +# Through this config item, SkyWalking keep your application memory cost estimated. +# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300} + +# Ignore the segments if their operation names end with these suffix. +# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg} + +# If true, SkyWalking agent will save all instrumented classes files in `/debugging` folder. +# SkyWalking team may ask for these files in order to resolve compatible problem. +# agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true} + +# The operationName max length +# agent.operation_name_threshold=${SW_AGENT_OPERATION_NAME_THRESHOLD:500} + +# If true, skywalking agent will enable profile when user create a new profile task. Otherwise disable profile. +# profile.active=${SW_AGENT_PROFILE_ACTIVE:true} + +# Parallel monitor segment count +# profile.max_parallel=${SW_AGENT_PROFILE_MAX_PARALLEL:5} + +# Max monitor segment time(minutes), if current segment monitor time out of limit, then stop it. +# profile.duration=${SW_AGENT_PROFILE_DURATION:10} + +# Max dump thread stack depth +# profile.dump_max_stack_depth=${SW_AGENT_PROFILE_DUMP_MAX_STACK_DEPTH:500} + +# Snapshot transport to backend buffer size +# profile.snapshot_transport_buffer_size=${SW_AGENT_PROFILE_SNAPSHOT_TRANSPORT_BUFFER_SIZE:50} + +# Backend service addresses. +collector.backend_service=192.168.0.20:11800 + +# Logging file_name +logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log} + +# Logging level +logging.level=${SW_LOGGING_LEVEL:INFO} + +# Logging dir +# logging.dir=${SW_LOGGING_DIR:""} + +# Logging max_file_size, default: 300 * 1024 * 1024 = 314572800 +# logging.max_file_size=${SW_LOGGING_MAX_FILE_SIZE:314572800} + +# The max history log files. When rollover happened, if log files exceed this number, +# then the oldest file will be delete. Negative or zero means off, by default. +# logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:-1} + +# Listed exceptions would not be treated as an error. Because in some codes, the exception is being used as a way of controlling business flow. +# Besides, the annotation named IgnoredException in the trace toolkit is another way to configure ignored exceptions. +# statuscheck.ignored_exceptions=${SW_STATUSCHECK_IGNORED_EXCEPTIONS:} + +# The max recursive depth when checking the exception traced by the agent. Typically, we don't recommend setting this more than 10, which could cause a performance issue. Negative value and 0 would be ignored, which means all exceptions would make the span tagged in error status. +# statuscheck.max_recursive_depth=${SW_STATUSCHECK_MAX_RECURSIVE_DEPTH:1} + +# Mount the specific folders of the plugins. Plugins in mounted folders would work. +plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations} + +# Exclude activated plugins +# plugin.exclude_plugins=${SW_EXCLUDE_PLUGINS:} + +# mysql plugin configuration +plugin.jdbc.trace_sql_parameters=true + +# Kafka producer configuration +plugin.kafka.bootstrap_servers=node1.kafka.mw.pro:9092,node2.kafka.mw.pro:9092,node3.kafka.mw.pro:9092 + +# Match spring bean with regex expression for classname +# plugin.springannotation.classname_match_regex=${SW_SPRINGANNOTATION_CLASSNAME_MATCH_REGEX:} \ No newline at end of file diff --git a/src/main/resources/pro/application.properties b/src/main/resources/pro/application.properties new file mode 100644 index 0000000..3126ab7 --- /dev/null +++ b/src/main/resources/pro/application.properties @@ -0,0 +1,153 @@ +server.port=80 +spring.application.name=disk +spring.profiles.active=pro + +instance.id=5 +spring.main.allow-bean-definition-overriding=true +logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG +spring.datasource.url=jdbc:mysql://tidb.db.pro:3306/cloud_disk?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true +spring.datasource.username=web +spring.datasource.password=ENC(h01nogcIQ6VuVs2i3P+Zr4pSDnnicYp7) +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.initialization-mode=always +spring.datasource.continue-on-error=true +spring.datasource.testOnBorrow=true + +spring.datasource.hikari.read-only=false +spring.datasource.hikari.connection-timeout=60000 +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.validation-timeout=30000 +spring.datasource.hikari.max-lifetime=60000 +spring.datasource.hikari.login-timeout=5 +spring.datasource.hikari.maximum-pool-size=200 +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL +#????? +server.tomcat.max-connections=2000 +#????? +server.tomcat.max-threads=1000 +## Mybatis ??==================================== +mybatis.mapperLocations=classpath:mapper/*.xml +user.default.lady=/static/common/image/head/lady.png +user.default.boy=/static/common/image/head/boy.png +user.default.girl=/static/common/image/head/girl.png +user.default.sir=/static/common/image/head/sir.png +user.default.headPic=/static/common/image/head/girl.png +loginLimit.level1.count=5 +loginLimit.level1.interval=300 +loginLimit.level2.count=10 +loginLimit.level2.interval=300 +loginLimit.level2.denyInterval=600 + +spring.messages.basename=i18n.messages +spring.messages.encoding=utf-8 + +## Redis ??==================================== +## Redis?????????0? +spring.redis.database=0 +## Redis????? +spring.redis.host=redis + +spring.redis.port=6379 +## Redis????????????? +spring.redis.password= +## ???????????????????? +spring.redis.jedis.pool.max-active=200 +## ??????????????????????? +spring.redis.jedis.pool.max-wait=-1 +## ??????????? +spring.redis.jedis.pool.max-idle=200 +## ??????????? +spring.redis.jedis.pool.min-idle=0 +## ?????????? +spring.redis.timeout=300 + +#buildkey +m3u8.buildkey=buildkey +m3u8.buildkey2=buildkey2 +schedule.video_convert_time=0 0/30 * * * ? + +verification.expiried=5 + + +h5doc.apiUrl=http://p2.ebh.net/i2.aspx?from=wuji +h5doc.appId=ebhapp1008 +h5doc.appKey=89327008 +swfdoc.apiUrl=http://p1.ebh.net/i.aspx?from=wuji +swfdoc.appId=ebhapp1005 +swfdoc.appKey=89327005 +swfdoc.callback.ipWhiteList=101.71.142.135 + + +spring.mail.host=smtp.qq.com +spring.mail.username=system@wxbig.cn +#\u6388\u6743\u7801g\uFF0C\u5728QQ\u90AE\u7BB1\u5BA2\u6237\u7AEF\u751F\u6210 \u4FEE\u6539\u6210\u81EA\u5DF1\u7684 \u8BBE\u7F6E-\u8D26\u6237-\u5F00\u542F\u670D\u52A1-\u83B7\u53D6\u6388\u6743\u7801 +spring.mail.password=ENC(AvNBF7xFcdy8792rgQOD2Ad0VhtF7ojqYrI2VJofsHs=) +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true + + +# Max file size??10M +spring.servlet.multipart.max-file-size=10485760 +# Max request size??10M +spring.servlet.multipart.max-request-size=10485760 + + +ppt.des.key= +ppt.des.vi= +ppt.server.url=https://demo.filesbox.cn/plugin/wo365/ +ppt.replace.need=0 +ppt.ip.whitelist= +cdn.domain=cdn.filesbox.cn + +mail.encode.fail = 414667543@qq.com +environment.type=pro +disk.default.size=1024 + +dingding.token=IHQCLrVBXNzB179pwdarwG +dingding.corpId=ding1f566670a125f1e7 +dingding.aes.key=Fl7pOJfYHvnKRHh9fIDUHbWx6cQpxv3Hn8wPiY2rHvbOGrWN +dingding.app.key=dingyw0a2j25u6cjqifl +dingding.app.secret=lZdcpljJWmtFK1DqhEtVftYuqLfNeKUfTJeFfPhtvgRHWvzAw5tUyRuIvzFe4hlH + +yz.view.convert.url=https://demo.filesbox.cn/fcscloud/composite/httpfile +yz.edit.convert.url=https://demo.filesbox.cn/plugin/yzwo +yz.edit.post.url=https://demo.filesbox.cn/plugin/yzwo/api.do +yz.fileId.prefix=o_ + +schedule.deleteCloudDownload=0 0 1 * * ? +webdav.host=https://demo.filesbox.cn + + +enWechat.corpId=ww2d1e9bafb529c21f +enWechat.AgentId=100008 +enWechat.Secret=Vy2WaVIblMP57pjmpon_bVGTqmbU2ls7STAgWXSPvak + +wechat.web.wx_appid=wxeed6a7666ad6b030 +wechat.web.wx_appSecret=3a2d4d810360ac367c3fe64d73af2e0f +wechat.app.wx_appid=wx283aec18f2335a85 +wechat.app.wx_appSecret=b10e94cd00d0aeb6c67fdb5c43449423 + +mybatis-plus.mapper-locations=classpath*:mapper/*.xml +info.common.htmlPath.name=filesbox + +#libreoffice\u914D\u7F6E\u4FE1\u606F +office.libreOfficeVersion=libreoffice6.3 +office.shellFileName=docx.sh +office.shellFileDirectory=/ +design.subPage.limitCount=512 +schedule.msgWarning=*/20 * * * * ? + +#\u626B\u7801\u767B\u5F55\u4E8C\u7EF4\u7801\u6709\u6548\u671F\u3002\u5355\u4F4D\uFF1A\u5206\u949F +scan.login.code.expire=3 + +webdav.rootContext[0]=/webdav/private +webdav.rootContext[1]=/webdav/favor +# Whether to print exception stacktrace in the response. +webdav.showExceptions=false +# Here you map you filesystem folder to be root for WebDAV. If not provided default structure will be created for the testing. +webdav.rootFolder=/ +# WebSockets are available at this endpoint. WebSockets are used in the default GET page. +webdav.rootWebSocket=/ +jasypt.encryptor.bean=encryptorBean \ No newline at end of file diff --git a/src/main/resources/pufay/agent.config b/src/main/resources/pufay/agent.config new file mode 100644 index 0000000..59e7a37 --- /dev/null +++ b/src/main/resources/pufay/agent.config @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# The agent namespace +agent.namespace=pufay + +# The service name in UI +agent.service_name=disk + +# The number of sampled traces per 3 seconds +# Negative or zero means off, by default +# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1} + +# Authentication active is based on backend setting, see application.yml for more details. +# agent.authentication = ${SW_AGENT_AUTHENTICATION:xxxx} + +# The max amount of spans in a single segment. +# Through this config item, SkyWalking keep your application memory cost estimated. +# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300} + +# Ignore the segments if their operation names end with these suffix. +# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg} + +# If true, SkyWalking agent will save all instrumented classes files in `/debugging` folder. +# SkyWalking team may ask for these files in order to resolve compatible problem. +# agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true} + +# The operationName max length +# agent.operation_name_threshold=${SW_AGENT_OPERATION_NAME_THRESHOLD:500} + +# If true, skywalking agent will enable profile when user create a new profile task. Otherwise disable profile. +# profile.active=${SW_AGENT_PROFILE_ACTIVE:true} + +# Parallel monitor segment count +# profile.max_parallel=${SW_AGENT_PROFILE_MAX_PARALLEL:5} + +# Max monitor segment time(minutes), if current segment monitor time out of limit, then stop it. +# profile.duration=${SW_AGENT_PROFILE_DURATION:10} + +# Max dump thread stack depth +# profile.dump_max_stack_depth=${SW_AGENT_PROFILE_DUMP_MAX_STACK_DEPTH:500} + +# Snapshot transport to backend buffer size +# profile.snapshot_transport_buffer_size=${SW_AGENT_PROFILE_SNAPSHOT_TRANSPORT_BUFFER_SIZE:50} + +# Backend service addresses. +collector.backend_service=192.168.0.20:11800 + +# Logging file_name +logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log} + +# Logging level +logging.level=${SW_LOGGING_LEVEL:INFO} + +# Logging dir +# logging.dir=${SW_LOGGING_DIR:""} + +# Logging max_file_size, default: 300 * 1024 * 1024 = 314572800 +# logging.max_file_size=${SW_LOGGING_MAX_FILE_SIZE:314572800} + +# The max history log files. When rollover happened, if log files exceed this number, +# then the oldest file will be delete. Negative or zero means off, by default. +# logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:-1} + +# Listed exceptions would not be treated as an error. Because in some codes, the exception is being used as a way of controlling business flow. +# Besides, the annotation named IgnoredException in the trace toolkit is another way to configure ignored exceptions. +# statuscheck.ignored_exceptions=${SW_STATUSCHECK_IGNORED_EXCEPTIONS:} + +# The max recursive depth when checking the exception traced by the agent. Typically, we don't recommend setting this more than 10, which could cause a performance issue. Negative value and 0 would be ignored, which means all exceptions would make the span tagged in error status. +# statuscheck.max_recursive_depth=${SW_STATUSCHECK_MAX_RECURSIVE_DEPTH:1} + +# Mount the specific folders of the plugins. Plugins in mounted folders would work. +plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations} + +# Exclude activated plugins +# plugin.exclude_plugins=${SW_EXCLUDE_PLUGINS:} + +# mysql plugin configuration +plugin.jdbc.trace_sql_parameters=true + +# Kafka producer configuration +plugin.kafka.bootstrap_servers=node1.kafka.mw.pro:9092,node2.kafka.mw.pro:9092,node3.kafka.mw.pro:9092 + +# Match spring bean with regex expression for classname +# plugin.springannotation.classname_match_regex=${SW_SPRINGANNOTATION_CLASSNAME_MATCH_REGEX:} \ No newline at end of file diff --git a/src/main/resources/pufay/application.properties b/src/main/resources/pufay/application.properties new file mode 100644 index 0000000..c9a8fb1 --- /dev/null +++ b/src/main/resources/pufay/application.properties @@ -0,0 +1,152 @@ +server.port=80 +spring.application.name=disk +spring.profiles.active=pufay + +instance.id=5 +spring.main.allow-bean-definition-overriding=true +logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG +spring.datasource.url=jdbc:mysql://tidb.db.pro:3306/cloud_disk_pufay?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true +spring.datasource.username=web +spring.datasource.password=ENC(h01nogcIQ6VuVs2i3P+Zr4pSDnnicYp7) +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.initialization-mode=always +spring.datasource.continue-on-error=true +spring.datasource.testOnBorrow=true + +spring.datasource.hikari.read-only=false +spring.datasource.hikari.connection-timeout=60000 +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.validation-timeout=30000 +spring.datasource.hikari.max-lifetime=60000 +spring.datasource.hikari.login-timeout=5 +spring.datasource.hikari.maximum-pool-size=200 +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL +#????? +server.tomcat.max-connections=2000 +#????? +server.tomcat.max-threads=1000 +## Mybatis ??==================================== +mybatis.mapperLocations=classpath:mapper/*.xml +user.default.lady=/static/common/image/head/lady.png +user.default.boy=/static/common/image/head/boy.png +user.default.girl=/static/common/image/head/girl.png +user.default.sir=/static/common/image/head/sir.png +user.default.headPic=/static/common/image/head/girl.png +loginLimit.level1.count=5 +loginLimit.level1.interval=300 +loginLimit.level2.count=10 +loginLimit.level2.interval=300 +loginLimit.level2.denyInterval=600 + +spring.messages.basename=i18n.messages +spring.messages.encoding=utf-8 + +## Redis ??==================================== +## Redis?????????0? +spring.redis.database=0 +## Redis????? +spring.redis.host=redis + +spring.redis.port=6379 +## Redis????????????? +spring.redis.password= +## ???????????????????? +spring.redis.jedis.pool.max-active=200 +## ??????????????????????? +spring.redis.jedis.pool.max-wait=-1 +## ??????????? +spring.redis.jedis.pool.max-idle=200 +## ??????????? +spring.redis.jedis.pool.min-idle=0 +## ?????????? +spring.redis.timeout=300 + +#buildkey +m3u8.buildkey=buildkey +m3u8.buildkey2=buildkey2 +schedule.video_convert_time=0 0/30 * * * ? + +verification.expiried=5 + + +h5doc.apiUrl=http://p2.ebh.net/i2.aspx?from=wuji +h5doc.appId=ebhapp1008 +h5doc.appKey=89327008 +swfdoc.apiUrl=http://p1.ebh.net/i.aspx?from=wuji +swfdoc.appId=ebhapp1005 +swfdoc.appKey=89327005 +swfdoc.callback.ipWhiteList=101.71.142.135 + + +spring.mail.host=smtp.qq.com +spring.mail.username=system@wxbig.cn +#\u6388\u6743\u7801g\uFF0C\u5728QQ\u90AE\u7BB1\u5BA2\u6237\u7AEF\u751F\u6210 \u4FEE\u6539\u6210\u81EA\u5DF1\u7684 \u8BBE\u7F6E-\u8D26\u6237-\u5F00\u542F\u670D\u52A1-\u83B7\u53D6\u6388\u6743\u7801 +spring.mail.password=ENC(AvNBF7xFcdy8792rgQOD2Ad0VhtF7ojqYrI2VJofsHs=) +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true + + +# Max file size??10M +spring.servlet.multipart.max-file-size=10485760 +# Max request size??10M +spring.servlet.multipart.max-request-size=10485760 + + +ppt.des.key= +ppt.des.vi= +ppt.server.url=https://demo.filesbox.cn/plugin/wo365/ +ppt.replace.need=0 +ppt.ip.whitelist= +cdn.domain=pufay-cdn.filesbox.cn + +mail.encode.fail = 414667543@qq.com +environment.type=pufay +disk.default.size=1024 + +dingding.token=IHQCLrVBXNzB179pwdarwG +dingding.aes.key=B1Jsb68yUw4PzOQZbugNAGo8DbAJuWhRbvlKUAH7QUV +dingding.app.key=dingyw0a2j25u6cjqifl +dingding.app.secret=lZdcpljJWmtFK1DqhEtVftYuqLfNeKUfTJeFfPhtvgRHWvzAw5tUyRuIvzFe4hlH + +yz.view.convert.url=https://demo.filesbox.cn/fcscloud/composite/httpfile +yz.edit.convert.url=https://demo.filesbox.cn/plugin/yzwo +yz.edit.post.url=https://demo.filesbox.cn/plugin/yzwo/api.do +yz.fileId.prefix=o_ + +schedule.deleteCloudDownload=0 0 1 * * ? +webdav.host=https://my.pufay.cn + + +enWechat.corpId=ww2d1e9bafb529c21f +enWechat.AgentId=100008 +enWechat.Secret=Vy2WaVIblMP57pjmpon_bVGTqmbU2ls7STAgWXSPvak + +wechat.web.wx_appid=wxeed6a7666ad6b030 +wechat.web.wx_appSecret=3a2d4d810360ac367c3fe64d73af2e0f +wechat.app.wx_appid=wx283aec18f2335a85 +wechat.app.wx_appSecret=b10e94cd00d0aeb6c67fdb5c43449423 + +mybatis-plus.mapper-locations=classpath*:mapper/*.xml +info.common.htmlPath.name=pufay + +#libreoffice\u914D\u7F6E\u4FE1\u606F +office.libreOfficeVersion=libreoffice6.3 +office.shellFileName=docx.sh +office.shellFileDirectory=/ +design.subPage.limitCount=512 +schedule.msgWarning=*/20 * * * * ? + +#\u626B\u7801\u767B\u5F55\u4E8C\u7EF4\u7801\u6709\u6548\u671F\u3002\u5355\u4F4D\uFF1A\u5206\u949F +scan.login.code.expire=3 + +webdav.rootContext[0]=/webdav/private/ +webdav.rootContext[1]=/webdav/favor/ +# Whether to print exception stacktrace in the response. +webdav.showExceptions=true +# Here you map you filesystem folder to be root for WebDAV. If not provided default structure will be created for the testing. +webdav.rootFolder=/ +# WebSockets are available at this endpoint. WebSockets are used in the default GET page. +webdav.rootWebSocket=/ +jasypt.encryptor.bean=encryptorBean \ No newline at end of file diff --git a/src/main/resources/qqwry.dat b/src/main/resources/qqwry.dat new file mode 100644 index 0000000..e03d642 Binary files /dev/null and b/src/main/resources/qqwry.dat differ diff --git a/src/main/resources/static/border/1.png b/src/main/resources/static/border/1.png new file mode 100644 index 0000000..35f23b5 Binary files /dev/null and b/src/main/resources/static/border/1.png differ diff --git a/src/main/resources/static/border/2.png b/src/main/resources/static/border/2.png new file mode 100644 index 0000000..cc0fc2f Binary files /dev/null and b/src/main/resources/static/border/2.png differ diff --git a/src/main/resources/static/img/1.png b/src/main/resources/static/img/1.png new file mode 100644 index 0000000..7c661ba Binary files /dev/null and b/src/main/resources/static/img/1.png differ diff --git a/src/main/resources/static/img/2.png b/src/main/resources/static/img/2.png new file mode 100644 index 0000000..8cd637d Binary files /dev/null and b/src/main/resources/static/img/2.png differ diff --git a/src/main/resources/static/img/3.png b/src/main/resources/static/img/3.png new file mode 100644 index 0000000..33579f4 Binary files /dev/null and b/src/main/resources/static/img/3.png differ diff --git a/src/main/resources/static/img/4.png b/src/main/resources/static/img/4.png new file mode 100644 index 0000000..8d51e19 Binary files /dev/null and b/src/main/resources/static/img/4.png differ diff --git a/src/main/resources/static/img/5.png b/src/main/resources/static/img/5.png new file mode 100644 index 0000000..c01d1e9 Binary files /dev/null and b/src/main/resources/static/img/5.png differ diff --git a/src/main/resources/static/img/refresh.jpg b/src/main/resources/static/img/refresh.jpg new file mode 100644 index 0000000..040d6eb Binary files /dev/null and b/src/main/resources/static/img/refresh.jpg differ diff --git a/src/main/resources/static/js/layer.css b/src/main/resources/static/js/layer.css new file mode 100644 index 0000000..b9dbf20 --- /dev/null +++ b/src/main/resources/static/js/layer.css @@ -0,0 +1 @@ +.layui-m-layer{position:relative;z-index:19891014}.layui-m-layer *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.layui-m-layermain,.layui-m-layershade{position:fixed;left:0;top:0;width:100%;height:100%}.layui-m-layershade{background-color:rgba(0,0,0,.7);pointer-events:auto}.layui-m-layermain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layui-m-layermain .layui-m-layersection{display:table-cell;vertical-align:middle;text-align:center}.layui-m-layerchild{position:relative;display:inline-block;text-align:left;background-color:#fff;font-size:14px;border-radius:5px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-overflow-scrolling:touch;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layui-m-anim-scale{animation-name:layui-m-anim-scale;-webkit-animation-name:layui-m-anim-scale}@-webkit-keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}.layui-m-anim-up{-webkit-animation-name:layui-m-anim-up;animation-name:layui-m-anim-up}.layui-m-layer0 .layui-m-layerchild{width:90%;max-width:640px}.layui-m-layer1 .layui-m-layerchild{border:none;border-radius:0}.layui-m-layer2 .layui-m-layerchild{width:auto;max-width:260px;min-width:40px;border:none;background:0 0;box-shadow:none;color:#fff}.layui-m-layerchild h3{padding:0 10px;height:60px;line-height:60px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;text-align:center}.layui-m-layerbtn span,.layui-m-layerchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-m-layercont{padding:50px 30px;line-height:22px;text-align:center}.layui-m-layer1 .layui-m-layercont{padding:0;text-align:left}.layui-m-layer2 .layui-m-layercont{text-align:center;padding:0;line-height:0}.layui-m-layer2 .layui-m-layercont i{width:25px;height:25px;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:layui-m-anim-loading 1.4s infinite ease-in-out;animation:layui-m-anim-loading 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-m-layerbtn,.layui-m-layerbtn span{position:relative;text-align:center;border-radius:0 0 5px 5px}.layui-m-layer2 .layui-m-layercont p{margin-top:20px}@-webkit-keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layui-m-layer2 .layui-m-layercont>div{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/src/main/resources/static/js/layer.js b/src/main/resources/static/js/layer.js new file mode 100644 index 0000000..7097a64 --- /dev/null +++ b/src/main/resources/static/js/layer.js @@ -0,0 +1,2 @@ +/** layer-v3.2.0 Web 弹层组件 MIT License */ + ;!function(e,t){"use strict";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,i=t.length-1,n=i;n>0;n--)if("interactive"===t[n].readyState){e=t[n].src;break}return e||t[i].src}();return e.substring(0,e.lastIndexOf("/")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:["确定","取消"],type:["dialog","page","iframe","loading","tips"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName("head")[0],s=document.createElement("link");"string"==typeof i&&(n=i);var l=(n||t).replace(/\.|\//g,""),f="layuicss-"+l,c=0;s.rel="stylesheet",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),"function"==typeof i&&!function u(){return++c>80?e.console&&console.error("layer.css: Invalid"):void(1989===parseInt(o.getStyle(document.getElementById(f),"width"))?i():setTimeout(u,100))}()}}},r={v:"3.2.0",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||"ActiveXObject"in e)&&((t.match(/msie\s(\d+)/)||[])[1]||"11")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,"string"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss("modules/layer/"+e.extend):o.link("theme/"+e.extend),this):this},ready:function(e){var t="layer",i="",n=(a?"modules/layer/":"theme/")+"default/layer.css?v="+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a="function"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s="function"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s="function"==typeof n,f=o.config.skin,c=(f?f+" "+f+"-msg":"")||"layui-layer-msg",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+" layui-layer-hui",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+" "+(n.skin||"layui-layer-hui")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];l.anim=["layer-anim-00","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:"信息",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f="object"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'
    '+(f?r.title[0]:r.title)+"
    ":"";return r.zIndex=s,t([r.shade?'
    ':"",'
    '+(e&&2!=r.type?"":u)+'
    '+(0==r.type&&r.icon!==-1?'':"")+(1==r.type&&e?"":r.content||"")+'
    '+function(){var e=c?'
    ':"";return r.closeBtn&&(e+=''),e}()+""+(r.btn?function(){var e="";"string"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t'+r.btn[t]+"";return'
    '+e+"
    "}():"")+(r.resize?'':"")+"
    "],u,i('
    ')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f="object"==typeof s,c=i("body");if(!t.id||!i("#"+t.id)[0]){switch("string"==typeof t.area&&(t.area="auto"===t.area?["",""]:[t.area,""]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn="btn"in t?t.btn:o.btn[0],r.closeAll("dialog");break;case 2:var s=t.content=f?t.content:[t.content||"http://layer.layui.com","auto"];t.content='';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;af&&(a=f),ou&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'":function(){return''}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["确定","取消"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a=''+t[0].title+"";i"+t[i].title+"";return a}(),content:'
      '+function(){var e=t.length,i=1,a="";if(e>0)for(a='
    • '+(t[0].content||"no content")+"
    • ";i'+(t[i].content||"no content")+"";return a}()+"
    ",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("没有图片")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(u[d].alt||
    '+(u.length>1?'':"")+'
    '+(u[d].alt||"")+""+s.imgIndex+"/"+u.length+"
    ",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("当前图片地址异常
    是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/src/main/resources/static/js/theme/default/icon-ext.png b/src/main/resources/static/js/theme/default/icon-ext.png new file mode 100644 index 0000000..bbbb669 Binary files /dev/null and b/src/main/resources/static/js/theme/default/icon-ext.png differ diff --git a/src/main/resources/static/js/theme/default/icon.png b/src/main/resources/static/js/theme/default/icon.png new file mode 100644 index 0000000..3e17da8 Binary files /dev/null and b/src/main/resources/static/js/theme/default/icon.png differ diff --git a/src/main/resources/static/js/theme/default/layer.css b/src/main/resources/static/js/theme/default/layer.css new file mode 100644 index 0000000..820b4a9 --- /dev/null +++ b/src/main/resources/static/js/theme/default/layer.css @@ -0,0 +1 @@ +.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/src/main/resources/static/js/theme/default/loading-0.gif b/src/main/resources/static/js/theme/default/loading-0.gif new file mode 100644 index 0000000..6f3c953 Binary files /dev/null and b/src/main/resources/static/js/theme/default/loading-0.gif differ diff --git a/src/main/resources/static/js/theme/default/loading-1.gif b/src/main/resources/static/js/theme/default/loading-1.gif new file mode 100644 index 0000000..db3a483 Binary files /dev/null and b/src/main/resources/static/js/theme/default/loading-1.gif differ diff --git a/src/main/resources/static/js/theme/default/loading-2.gif b/src/main/resources/static/js/theme/default/loading-2.gif new file mode 100644 index 0000000..5bb90fd Binary files /dev/null and b/src/main/resources/static/js/theme/default/loading-2.gif differ diff --git a/src/main/resources/static/material/border1.png b/src/main/resources/static/material/border1.png new file mode 100644 index 0000000..35f23b5 Binary files /dev/null and b/src/main/resources/static/material/border1.png differ diff --git a/src/main/resources/static/material/border2.png b/src/main/resources/static/material/border2.png new file mode 100644 index 0000000..cc0fc2f Binary files /dev/null and b/src/main/resources/static/material/border2.png differ diff --git a/src/main/resources/static/material/template1.png b/src/main/resources/static/material/template1.png new file mode 100644 index 0000000..a939908 Binary files /dev/null and b/src/main/resources/static/material/template1.png differ diff --git a/src/main/resources/static/material/template2.png b/src/main/resources/static/material/template2.png new file mode 100644 index 0000000..19cf4f3 Binary files /dev/null and b/src/main/resources/static/material/template2.png differ diff --git a/src/main/resources/static/material/template3.png b/src/main/resources/static/material/template3.png new file mode 100644 index 0000000..2aa45b6 Binary files /dev/null and b/src/main/resources/static/material/template3.png differ diff --git a/src/main/resources/static/material/template4.png b/src/main/resources/static/material/template4.png new file mode 100644 index 0000000..bb47a0c Binary files /dev/null and b/src/main/resources/static/material/template4.png differ diff --git a/src/main/resources/static/targets/1.jpg b/src/main/resources/static/targets/1.jpg new file mode 100644 index 0000000..05c4091 Binary files /dev/null and b/src/main/resources/static/targets/1.jpg differ diff --git a/src/main/resources/static/targets/4.jpg b/src/main/resources/static/targets/4.jpg new file mode 100644 index 0000000..e8e465f Binary files /dev/null and b/src/main/resources/static/targets/4.jpg differ diff --git a/src/main/resources/static/targets/7.jpg b/src/main/resources/static/targets/7.jpg new file mode 100644 index 0000000..90f425c Binary files /dev/null and b/src/main/resources/static/targets/7.jpg differ diff --git a/src/main/resources/static/targets/8.jpg b/src/main/resources/static/targets/8.jpg new file mode 100644 index 0000000..2fc9e2e Binary files /dev/null and b/src/main/resources/static/targets/8.jpg differ diff --git a/src/main/resources/static/targets/86628167016813512467.png b/src/main/resources/static/targets/86628167016813512467.png new file mode 100644 index 0000000..a74f10a Binary files /dev/null and b/src/main/resources/static/targets/86628167016813512467.png differ diff --git a/src/main/resources/static/targets/part-00733-1997.jpg b/src/main/resources/static/targets/part-00733-1997.jpg new file mode 100644 index 0000000..bdbd262 Binary files /dev/null and b/src/main/resources/static/targets/part-00733-1997.jpg differ diff --git a/src/main/resources/static/targets/u=100138589,2319714429&fm=15&gp=0.jpg b/src/main/resources/static/targets/u=100138589,2319714429&fm=15&gp=0.jpg new file mode 100644 index 0000000..9790540 Binary files /dev/null and b/src/main/resources/static/targets/u=100138589,2319714429&fm=15&gp=0.jpg differ diff --git a/src/main/resources/static/targets/u=1038924768,1306201636&fm=26&gp=0.jpg b/src/main/resources/static/targets/u=1038924768,1306201636&fm=26&gp=0.jpg new file mode 100644 index 0000000..16520e1 Binary files /dev/null and b/src/main/resources/static/targets/u=1038924768,1306201636&fm=26&gp=0.jpg differ diff --git a/src/main/resources/static/targets/u=1451069392,1203687152&fm=26&gp=0.jpg b/src/main/resources/static/targets/u=1451069392,1203687152&fm=26&gp=0.jpg new file mode 100644 index 0000000..f195edc Binary files /dev/null and b/src/main/resources/static/targets/u=1451069392,1203687152&fm=26&gp=0.jpg differ diff --git a/src/main/resources/static/targets/u=1645257812,452155237&fm=26&gp=0.jpg b/src/main/resources/static/targets/u=1645257812,452155237&fm=26&gp=0.jpg new file mode 100644 index 0000000..73d77dc Binary files /dev/null and b/src/main/resources/static/targets/u=1645257812,452155237&fm=26&gp=0.jpg differ diff --git a/src/main/resources/static/targets/u=2629640120,728825811&fm=26&gp=0.jpg b/src/main/resources/static/targets/u=2629640120,728825811&fm=26&gp=0.jpg new file mode 100644 index 0000000..395f2db Binary files /dev/null and b/src/main/resources/static/targets/u=2629640120,728825811&fm=26&gp=0.jpg differ diff --git a/src/main/resources/static/targets/u=3118426240,2074476394&fm=26&gp=0.jpg b/src/main/resources/static/targets/u=3118426240,2074476394&fm=26&gp=0.jpg new file mode 100644 index 0000000..6f7992a Binary files /dev/null and b/src/main/resources/static/targets/u=3118426240,2074476394&fm=26&gp=0.jpg differ diff --git a/src/main/resources/static/targets/u=371369331,2871978873&fm=15&gp=0.jpg b/src/main/resources/static/targets/u=371369331,2871978873&fm=15&gp=0.jpg new file mode 100644 index 0000000..f0295f2 Binary files /dev/null and b/src/main/resources/static/targets/u=371369331,2871978873&fm=15&gp=0.jpg differ diff --git a/src/main/resources/static/templates/border.png b/src/main/resources/static/templates/border.png new file mode 100644 index 0000000..4d83dfe Binary files /dev/null and b/src/main/resources/static/templates/border.png differ diff --git a/src/main/resources/static/templates/template.png b/src/main/resources/static/templates/template.png new file mode 100644 index 0000000..794c167 Binary files /dev/null and b/src/main/resources/static/templates/template.png differ diff --git a/src/main/resources/upconfig.properties b/src/main/resources/upconfig.properties new file mode 100644 index 0000000..76ea33a --- /dev/null +++ b/src/main/resources/upconfig.properties @@ -0,0 +1,55 @@ +#docַ +doc.savePath=/doc/ +doc.showPath=/doc/ +doc.tmpPath=/doc/tmp/ +doc.muPath=/mu/ +image.savePath=/uploads/image/ +image.showPath=/uploads/image/ +avatar.savePath=/uploads/avatar/ +avatar.showPath=/uploads/avatar/ +cloud.savePath=/private/cloud/ +cloud.showPath=/common/cloud/ +attachment.savePath=/attachment/ +attachment.showPath=/attachment/ +attachment.muPath=/mu/ +attachment.muShowPath=/mu/ +h5doc.savePath=/h5doc/ +h5doc.showPath=/h5doc/ +audio.savePath=/audio/ +homepage_image.savePath=/common/homepage_image/ +homepage_image.showPath=/common/homepage_image/ +homepage_attachment.savePath=/common/homepage_attachment/ +homepage_attachment.showPath=/common/homepage_attachment/ +homepage_video.savePath=/common/homepage_video/ +homepage_video.showPath=/common/homepage_video/ + + +home.path.default=/uploads +home.savePath=/uploads/design/home/ +## ģ̶ַ +template.savePath=/uploads/design/template/ +template.fileName=index.html +template_mobile.fileName=mobile.html +template_app.fileName=app.html +template_mp.fileName=mp.html +template.mpSavePath=/design/template/applet/ +applet.savePath=/uploads/design/applet/ +applet.footImagePath=/design/image/foot/ +applet.appIdJSFile=lookForAppId.js + +design_logo.savePath=/uploads/design_logo/ +design_logo.showPath=/uploads/design_logo/ +design_thumb.savePath=/uploads/design_thumb/ +design_thumb.showPath=/uploads/design_thumb/ + +brochure_attachment.savePath=/common/brochure_attachment/ +brochure_attachment.showPath=/common/brochure_attachment/ +#֤ͼƬַҪij㱾صĵַ +#·Եʱȫ·Ҫ··jarʱ򣬶ȡļ +#ǰ˷뷽ʽĵã·ӦɷãҪֶ·ʽȡļеCaptchaServiceImplʵselectSlideVerificationCodeļȡʽ +slide-verification-code.path.origin-image=classpath:static/targets +slide-verification-code.path.template-image=classpath:static/templates +# origin-image: "D:/Develop/Files/Idea/Projects/captcha/src/main/resources/static/targets" +# template-image: "D:/Develop/Files/Idea/Projects/captcha/src/main/resources/static/templates" +# webdav ?? +webdav.prefix=webdav \ No newline at end of file diff --git a/src/test/java/com/svnlan/jwt/DiskApplicationTests.java b/src/test/java/com/svnlan/jwt/DiskApplicationTests.java new file mode 100644 index 0000000..eb42fcf --- /dev/null +++ b/src/test/java/com/svnlan/jwt/DiskApplicationTests.java @@ -0,0 +1,876 @@ +package com.svnlan.jwt; + +import com.mpatric.mp3agic.ID3v2; +import com.mpatric.mp3agic.Mp3File; +import com.svnlan.common.GlobalConfig; +import com.svnlan.common.Result; +import com.svnlan.exception.CodeMessageEnum; +import com.svnlan.exception.SvnlanRuntimeException; +import com.svnlan.home.dao.IoSourceDao; +import com.svnlan.home.domain.IOSource; +import com.svnlan.home.dto.CheckFileDTO; +import com.svnlan.home.dto.CompressFileDto; +import com.svnlan.home.dto.HomeExplorerDTO; +import com.svnlan.home.dto.SourceOpDto; +import com.svnlan.home.service.ExplorerFileService; +import com.svnlan.home.service.ExplorerOperationsService; +import com.svnlan.home.service.UploadService; +import com.svnlan.home.service.UploadZipService; +import com.svnlan.home.utils.CompressFileReader; +import com.svnlan.home.utils.CompressFileUtil; +import com.svnlan.home.utils.FileUtil; +import com.svnlan.home.utils.office.LibreOfficeDUtil; +import com.svnlan.home.utils.video.VideoGetUtil; +import com.svnlan.home.utils.zip.ZipUtils; +import com.svnlan.home.vo.ChangeSourceVo; +import com.svnlan.home.vo.YzEditParamsDto; +import com.svnlan.jwt.domain.LoginUser; +import com.svnlan.jwt.service.JWTService; +import com.svnlan.manage.dto.CommonInfoTypeDto; +import com.svnlan.manage.dto.GetDesignListDTO; +import com.svnlan.manage.service.CommonDesignService; +import com.svnlan.manage.service.CommonInfoTypeService; +import com.svnlan.utils.*; +import net.lingala.zip4j.ZipFile; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.xmind.core.Core; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.core.IWorkbookBuilder; +import org.xmind.core.marker.IMarkerSheet; +import sun.misc.BASE64Encoder; + +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +@RunWith(SpringRunner.class) +@SpringBootTest +public class DiskApplicationTests { + + @Test + public void jwtTest() { + + //String winUserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"; + String winUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"; + //String winUserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"; + System.out.println("浏览器组:" + UserAgentUtils.getBorderGroup(winUserAgent)); + String borderName = UserAgentUtils.getOsName(winUserAgent); + System.out.println(borderName + "a"); + System.out.println("浏览器名字:" + UserAgentUtils.getBorderName(winUserAgent)); + System.out.println("浏览器类型" + UserAgentUtils.getBorderType(winUserAgent)); + System.out.println("浏览器生产商:" + UserAgentUtils.getBrowserManufacturer(winUserAgent)); + System.out.println("浏览器版本:" + UserAgentUtils.getBrowserVersion(winUserAgent)); + System.out.println("设备生产厂商:" + UserAgentUtils.getDeviceManufacturer(winUserAgent)); + System.out.println("设备类型:" + UserAgentUtils.getDevicetype(winUserAgent)); + System.out.println("设备操作系统:" + UserAgentUtils.getOs(winUserAgent)); + System.out.println("操作系统的名字:" + UserAgentUtils.getOsName(winUserAgent)); + System.out.println("操作系统浏览器的渲染引擎:" + UserAgentUtils.getBorderRenderingEngine(winUserAgent)); +// String androidUserAgent = "Mozilla/5.0 (Linux; Android 8.0; LON-AL00 Build/HUAWEILON-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044204 Mobile Safari/537.36 V1_AND_SQ_7.7.8_908_YYB_D QQ/7.7.8.3705 NetType/WIFI WebP/0.3.0 Pixel/1440"; +// String iosUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A366 QQ/7.7.8.421 V1_IPH_SQ_7.7.8_1_APP_A Pixel/750 Core/UIWebView Device/Apple(iPhone 6s) NetType/WIFI QBWebViewType/1"; + } + + @Test + public void aa() { + String address = "220.195.66.3"; + IPAddressUtils ipAddressUtils = new IPAddressUtils(); + if (IPAddressUtils.file == null) { + //ipAddressUtils.init(); + String city = ipAddressUtils.getIPLocation(address).getCountry(); + System.out.println(city); + } else { + try { + // ipAddressUtils.init(); + String city = ipAddressUtils.getIPLocation(address).getCountry(); + System.out.println(city); + } catch (Exception e) { + System.out.println(e); + } + } + } + @Autowired + JWTService jwtService; + @Autowired + LoginUserUtil loginUserUtil; + @Autowired + UploadService uploadService; + @Test + public void loginTest(){ +// ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); +// HttpServletRequest request = servletRequestAttributes.getRequest(); +// String serverName = request.getServerName(); +// UserDTO dto = new UserDTO(); +// String username="xiaoman2"; +// String password="Y2PGVLEjTvQMsajbxA4tZw=="; +// dto.setUsername(username); +// dto.setPassword(password); +// System.out.println(jwtService.getAccessToken(dto)); + LoginUser loginUser = loginUserUtil.getAccessToken("+uZCAfeuoQOJ0W+gcYvPLVAlb7duE4cuQ1VAilNTh9WEkTGMqUvdcstz8CDAqP5bRaAxG81U3AhNuPI/P9yLUzuCmhg9SQqCWZvQ+Z2qTlY="); + System.out.println(JsonUtils.beanToJson(loginUser)); + } + + + + /** + * @Description: properties 中午转义 uncode + * @params: [] + * @Return: void + * @Author: sulijuan + * @Date: 2023/2/7 16:20 + * @Modified: + */ + @Test + public void te(){ + long startTime=System.currentTimeMillis(); //获取开始时间 + + System.out.println(StringUtil.encode("该文件不存在")); + System.out.println(StringUtil.encode("該文件不存在")); + try { + + FileInputStream filestream=new FileInputStream("src/messages.txt"); + + byte[] b = new byte[3]; + + filestream.read(b); + + String ecode="utf-8"; + + if(b[0] == -17 && b[1] == -69 && b[2] == -65){ + + ecode="utf-8"; + + } + + InputStreamReader readStream=new InputStreamReader(filestream,ecode); + + BufferedReader reader=new BufferedReader(readStream); + + String temp=null; + + int line=0;//行号 + + while((temp=reader.readLine())!=null){ + + line++; + + String[] sl = temp.split("="); + System.out.println(sl[0].trim()+"="+ StringUtil.encode(sl[1].trim())); + + } + + long endTime=System.currentTimeMillis(); //获取结束时间 + + if(readStream!=null){ + + readStream.close(); + + } + + if(reader!=null){ + + reader.close(); + + } + + System.out.println("程序运行时间: "+(endTime-startTime)/1000+"s"); + }catch (Exception e){ + LogUtil.error(e); + } + + + + + } + + @Test + public void getTxt(){ + //String txt = "D://467046.txt"; + String txt = "cs025.md"; + System.out.println(FileUtil.getFileContent(txt)); + } + + @Test + public void getTxt2(){ + CheckFileDTO checkFileDTO = new CheckFileDTO(); + checkFileDTO.setBusType("cloud"); + checkFileDTO.setSourceID(60914L); + + String text = FileUtil.getFileContent("D://467046.txt", StandardCharsets.UTF_8); + LogUtil.info("**********************re=" + text); + } + @Resource + IoSourceDao ioSourceDao; + @Resource + UploadZipService uploadZipService; + @Test + public void addIOSource(){ + List copyList = ioSourceDao.copySourceList(Arrays.asList(30718L)); + String name = "无极直播摄像机宣传图("; + IOSource source = copyList.get(0); + List list = new ArrayList<>(); + for (int i = 0; i <= 10000; i++) { + source.setTargetID(1L); + source.setCreateUser(1L); + source.setModifyUser(1L); + source.setName(name + (i+1) + ")"); + list.add(source); + } + + for (List subList : Partition.ofSize(list, 2000)) { + try { + // ioSourceDao.batchInsert(subList); + } catch (Exception e) { + LogUtil.error(e, "复制出错"); + } + } + + + } + + + @Resource + StringRedisTemplate stringRedisTemplate; + //@Test + public void toZip(){ + + String targetPath = "E://zip测试打包/"; + String targetFile = "1599794872690_2232915.gif"; + String targetDir = "target/"; + + //基础路径+日期路径 + String finalFolderPath = targetPath + targetDir + FileUtil.getDatePath(); + String fileName = RandomUtil.getuuid() + System.currentTimeMillis() + + "_1" + ".zip"; + String finalFilePath = finalFolderPath + fileName; + // 创建一个目录 + java.nio.file.Path dirPath = ZipUtils.createDirectory("人物.gif", finalFolderPath); + ZipUtils.copyFile(targetPath + targetFile, dirPath); + try { + ZipUtils.toZip(finalFolderPath + "人物.gif", finalFilePath, true, stringRedisTemplate, "555", 856252); + } catch (Exception e){ + + } + } + + // @Test + public void toListZip(){ + + + /*List levelList = new ArrayList<>(); + levelList.add("目录一/"); + levelList.add("目录二/"); + System.out.println(levelList.stream().collect(Collectors.joining("", "", "")));*/ + + + String dir = "E:/zip测试打包/target/"; + + String targetPath = "E://zip测试打包/"; + String targetDir = "target/"; + + + String finalFolderPath = targetPath + targetDir + FileUtil.getDatePath(); + String fileName = "005.zip"; + String finalFilePath = finalFolderPath + fileName; + try { + ZipUtils.toZip(dir, finalFilePath, false, true, stringRedisTemplate,"111", 1545); + }catch (Exception e){ + LogUtil.error(e); + } + } + + @Resource + ExplorerOperationsService operationsService; + + //@Test + public void initPathLevel(){ + operationsService.initSourcePathLevel(null); + } + + + //@Test + public void getAudioPic() { + + + String picPath = "F:/audio/梦然少年.jpg"; + RandomAccessFile file = null; + try { + + Mp3File mp3file = new Mp3File("F:/audio/梦然少年.mp3"); + if (mp3file.hasId3v2Tag()) { + ID3v2 id3v2Tag = mp3file.getId3v2Tag(); + + System.out.println("唱片歌曲数量: " + id3v2Tag.getTrack()); + System.out.println("艺术家: " + id3v2Tag.getArtist()); + System.out.println("歌曲名: " + id3v2Tag.getTitle()); + System.out.println("唱片名: " + id3v2Tag.getAlbum()); + System.out.println("歌曲长度:"+mp3file.getLengthInSeconds()+"秒"); + System.out.println("码率: " + mp3file.getBitrate() + " kbps " + (mp3file.isVbr() ? "(VBR)" : "(CBR)")); + System.out.println("专辑插画 : "+id3v2Tag.getAlbumImage()); + System.out.println("专辑插画类型"+id3v2Tag.getAlbumImageMimeType()); + System.out.println("发行时间: " + id3v2Tag.getYear()); + System.out.println("流派: " + id3v2Tag.getGenre() + " (" + id3v2Tag.getGenreDescription() + ")"); + System.out.println("注释: " + id3v2Tag.getComment()); + System.out.println("歌词: " + id3v2Tag.getLyrics()); + System.out.println("作曲家: " + id3v2Tag.getComposer()); + System.out.println("发行公司: " + id3v2Tag.getPublisher()); + System.out.println("Original artist: " + id3v2Tag.getOriginalArtist()); + System.out.println("Album artist: " + id3v2Tag.getAlbumArtist()); + System.out.println("版权: " + id3v2Tag.getCopyright()); + System.out.println("URL: " + id3v2Tag.getUrl()); + System.out.println("编码格式: " + id3v2Tag.getEncoder()); + byte[] albumImageData = id3v2Tag.getAlbumImage(); + if (albumImageData != null) { + System.out.println("专辑插图长度: " + albumImageData.length + " bytes"); + System.out.println("专辑插图类型: " + id3v2Tag.getAlbumImageMimeType()); + //String mimeType = id3v2Tag.getAlbumImageMimeType(); + // Write image to file - can determine appropriate file extension from the mime type + file = new RandomAccessFile(picPath, "rw"); + file.write(albumImageData); + file.close(); + } + } + }catch (Exception e){ + LogUtil.error(e); + }finally { + + } + + } + + @Resource + DocUtil docUtil; + + @Test + public void yzView(){ + + String filePath = "https://dev.filesbox.cn/uploads/private/cloud/2023_3/2/b3339a08621e422887487b494dedbc121677742502180_30028.xlsx"; + try { + String postUrl = "https://demo.filesbox.cn/fcscloud/composite/httpfile?convertType=61&fileUrl=" + URLEncoder.encode(filePath,"UTF-8"); + + + String res1 = docUtil.postYZFile(postUrl); + LogUtil.info("yongZhong h5 api return retry : " + res1 + "filePath : " + filePath ); + Map resMap = JsonUtils.jsonToMap(res1); + if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorcode") && "0".equals(resMap.get("errorcode").toString())){ + String data = resMap.get("data").toString(); + System.out.println(data); + } + LogUtil.info("yongZhong resMap=" + JsonUtils.beanToJson(resMap)); + System.out.println("yongZhong resMap=" + JsonUtils.beanToJson(resMap)); + } catch (Exception e2){ + LogUtil.error(e2, "转h5提交重试也失败 , o:" + filePath); + } + } + + + @Test + public void yzEdit(){ + + // + + String filePath = "https://demo.filesbox.cn/api/disk/attachment/[定制]定制评估模板 (1).xlsx?busId=60146&busType=cloud&key=yORCT716y2coywUAaUWWMKyi5IUtJuIRhNz%2FJEqyPPFHsf8gQ%2Bz%2BKhq58Z5nfy%2FMZQR4c0BaDN2upMLesW8PoR0xBIe9ax7%2FTBmxcAcL6wly143TZQ1uMZlgblG4ZM30PxE4LeXIodpsiv8O996S%2BVhSf6mKqKjZO8nC9KE1%2BKa4SqddE%2FsgakZ2q4y8kAzjSRYjs%2FcPijXIFIJ%2FJRDRV%2FIuE6rrJBlGQby%2Bn253hKbpn%2FbyysCsgqQf7jJMJLlSnajpQ0oD7pyxRbf9OMCLHdHNPXEpmD9PE7EhJj%2FlbxLzMP9JM8upXCqXarxJdHrZ"; + try { + String postUrl = "https://demo.filesbox.cn/plugin/yzwo/api.do" ; + + Map param = new HashMap<>(); + String callbackUrl = "https://dev.filesbox.cn/api/disk/yzwo/office"; + param.put("method", 1); + param.put("params", new YzEditParamsDto("1", "60146", "[定制]定制评估模板 (1).xlsx", filePath, callbackUrl)); + String res1 = docUtil.postYZFile(postUrl + "?jsonParams=" + URLEncoder.encode(JsonUtils.beanToJson(param),"UTF-8")); + LogUtil.info("yongZhong h5 api return retry : " + res1 + "filePath : " + filePath ); + Map resMap = JsonUtils.jsonToMap(res1); + if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorCode") && "0".equals(resMap.get("errorCode").toString())){ + String data = resMap.get("result").toString(); + Map urlMap = JsonUtils.jsonToMap(data); + if (!ObjectUtils.isEmpty(urlMap) && urlMap.containsKey("urls")){ + String urls = urlMap.get("urls").toString(); + } + System.out.println(data); + }else if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorcode") && "0".equals(resMap.get("errorcode").toString())){ + + } + LogUtil.info("yongZhong resMap=" + JsonUtils.beanToJson(resMap)); + System.out.println("yongZhong resMap=" + JsonUtils.beanToJson(resMap)); + } catch (Exception e2){ + LogUtil.error(e2, "转h5提交重试也失败 , o:" + filePath); + } + } + + @Test + public void yzClose(){ + + // + + String filePath = "https://demo.filesbox.cn/api/disk/attachment/[定制]定制评估模板 (1).xlsx?busId=60146&busType=cloud&key=yORCT716y2coywUAaUWWMKyi5IUtJuIRhNz%2FJEqyPPFHsf8gQ%2Bz%2BKhq58Z5nfy%2FMZQR4c0BaDN2upMLesW8PoR0xBIe9ax7%2FTBmxcAcL6wly143TZQ1uMZlgblG4ZM30PxE4LeXIodpsiv8O996S%2BVhSf6mKqKjZO8nC9KE1%2BKa4SqddE%2FsgakZ2q4y8kAzjSRYjs%2FcPijXIFIJ%2FJRDRV%2FIuE6rrJBlGQby%2Bn253hKbpn%2FbyysCsgqQf7jJMJLlSnajpQ0oD7pyxRbf9OMCLHdHNPXEpmD9PE7EhJj%2FlbxLzMP9JM8upXCqXarxJdHrZ"; + try { + String postUrl = "https://demo.filesbox.cn/plugin/yzwo/api.do" ; + + Map param = new HashMap<>(); + String callbackUrl = "https://dev.filesbox.cn/api/disk/yzwo/office"; + param.put("method", 3); + param.put("params", new YzEditParamsDto(null, "3186", null, null, callbackUrl)); + String paramStr = URLEncoder.encode(JsonUtils.beanToJson(param),"UTF-8"); + String res1 = docUtil.postYZFile(postUrl + "?jsonParams=" + paramStr); + LogUtil.info("yongZhong h5 api return retry : " + res1 + "filePath : " + filePath ); + Map resMap = JsonUtils.jsonToMap(res1); + if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorCode") && "0".equals(resMap.get("errorCode").toString())){ + + }else if (!ObjectUtils.isEmpty(resMap) && resMap.containsKey("errorcode") && "0".equals(resMap.get("errorcode").toString())){ + + } + LogUtil.info("yongZhong resMap=" + JsonUtils.beanToJson(resMap)); + System.out.println("yongZhong resMap=" + JsonUtils.beanToJson(resMap)); + } catch (Exception e2){ + LogUtil.error(e2, "转h5提交重试也失败 , o:" + filePath); + } + } + + @Test + public void tes2(){ + + List soureNamelist = new ArrayList<>(); + /*soureNamelist.add("新"); + soureNamelist.add("新(1)"); + soureNamelist.add("新(2)"); + soureNamelist.add("新(3)"); + soureNamelist.add("新(6)"); + + String a = checkRepeatName("新","新", soureNamelist, 1);*/ + + soureNamelist.add("新.doc"); + soureNamelist.add("新(1).doc"); + soureNamelist.add("新(2).doc"); + soureNamelist.add("新(3).doc"); + soureNamelist.add("新(6).doc"); + + String a = checkRepeatName("新.doc","新.doc", "doc", soureNamelist, 1); + System.out.println(a); + + } + + private String checkRepeatName(String name, String newName, List soureNamelist, int i){ + if (soureNamelist.contains(newName)){ + return checkRepeatName(name , name + "(" + i +")", soureNamelist, i+1); + } + return newName; + } + + private String checkRepeatName(String name, String newName, String fileType, List sourceNameList, int i){ + if (!CollectionUtils.isEmpty(sourceNameList)){ + if (sourceNameList.contains(newName)){ + return checkRepeatName(name , name.replaceAll("." + fileType, "") + "(" + i +")." + fileType, fileType, sourceNameList, i+1); + } + } + return newName; + } + + @Test + public void cretaePPt(){ + FileUtil.writePptFile(new File("E:\\zip测试打包\\999\\newPPT.pptx"), "new ppt"); + } + + + @Resource + CompressFileReader compressFileReader; + @Resource + ExplorerFileService explorerFileService; + @Test + public void unZipList(){ + + //String filePath = "E:\\zip测试打包\\999.zip"; + //String filePath = "E:\\zip测试打包\\解压rar\\测试密码压缩.zip"; + String filePath = "E:\\zip测试打包\\个人空间 (1).zip"; + String fileName = "个人空间 (1).zip"; + + try { + String a = compressFileReader.unRar(filePath, fileName, ""); + System.out.println(a); + }catch (Exception e){ + LogUtil.error(e, "aaa"); + } + + + /* + {"originName":"999.zip","fileName":"999.zip","parentFileName":"","fullName":null,"size":null,"directory":true,"fileKey":null,"childList":[{"originName":"打包555","fileName":"打包555","parentFileName":"999.zip","fullName":"打包555","size":0,"directory":true,"fileKey":"999.zip","childList":[]},{"originName":"打包666","fileName":"打包666","parentFileName":"999.zip","fullName":"打包666/","size":0,"directory":true,"fileKey":"999.zip","childList":[{"originName":"b38f16408466431aa421a13643ba412f1678167794239_30028.mp3","fileName":"999.zip_b38f16408466431aa421a13643ba412f1678167794239_30028.mp3","parentFileName":"打包666","fullName":"打包666\\b38f16408466431aa421a13643ba412f1678167794239_30028.mp3","size":4543462,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"上传文件夹","fileName":"上传文件夹","parentFileName":"打包666","fullName":"打包666/上传文件夹/","size":0,"directory":true,"fileKey":"999.zip","childList":[{"originName":"1599794872690_2232915.gif","fileName":"999.zip_1599794872690_2232915.gif","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\1599794872690_2232915.gif","size":914096,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"txt打开.txt","fileName":"999.zip_txt打开.txt","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\txt打开.txt","size":34,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"枫叶.JPEG","fileName":"999.zip_枫叶.JPEG","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\枫叶.JPEG","size":47509,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"画01.mp4","fileName":"999.zip_画01.mp4","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\画01.mp4","size":4744602,"directory":false,"fileKey":"999.zip","childList":[]}]},{"originName":"新文件夹","fileName":"新文件夹","parentFileName":"打包666","fullName":"打包666\\新文件夹","size":0,"directory":true,"fileKey":"999.zip","childList":[]}]}]} + */ + } + + @Test + public void unZipTest(){ + + String filePath = "E:\\zip测试打包\\999.zip"; + //String filePath = "E:\\zip测试打包\\解压rar\\测试密码压缩.zip"; + String fileName = "测试密码压缩.zip"; + String password = ""; + String finalFolderPath = "E:\\zip测试打包\\解压rar\\测试密码压缩\\"; + String finalFolderPath2 = "E:\\zip测试打包\\解压rar\\测试密码压缩\\8da657289ebc43fd8023de49cdc748761683272563095_1.zip_打包666_上传文件夹_1599794872690_2232915.gif"; + List fileList = new ArrayList<>(); + + CompressFileDto dto = CompressFileUtil.unzipOneFilePassword(filePath, finalFolderPath2, password, 1); + System.out.println(password); + try { + // CompressFileUtil.unzipFilePassword(filePath, finalFolderPath, fileList, 1L, password); + System.out.println(JsonUtils.beanToJson(fileList)); + }catch (Exception e){ + LogUtil.error(e, "aaa"); + } + + + /* + {"originName":"999.zip","fileName":"999.zip","parentFileName":"","fullName":null,"size":null,"directory":true,"fileKey":null,"childList":[{"originName":"打包555","fileName":"打包555","parentFileName":"999.zip","fullName":"打包555","size":0,"directory":true,"fileKey":"999.zip","childList":[]},{"originName":"打包666","fileName":"打包666","parentFileName":"999.zip","fullName":"打包666/","size":0,"directory":true,"fileKey":"999.zip","childList":[{"originName":"b38f16408466431aa421a13643ba412f1678167794239_30028.mp3","fileName":"999.zip_b38f16408466431aa421a13643ba412f1678167794239_30028.mp3","parentFileName":"打包666","fullName":"打包666\\b38f16408466431aa421a13643ba412f1678167794239_30028.mp3","size":4543462,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"上传文件夹","fileName":"上传文件夹","parentFileName":"打包666","fullName":"打包666/上传文件夹/","size":0,"directory":true,"fileKey":"999.zip","childList":[{"originName":"1599794872690_2232915.gif","fileName":"999.zip_1599794872690_2232915.gif","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\1599794872690_2232915.gif","size":914096,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"txt打开.txt","fileName":"999.zip_txt打开.txt","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\txt打开.txt","size":34,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"枫叶.JPEG","fileName":"999.zip_枫叶.JPEG","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\枫叶.JPEG","size":47509,"directory":false,"fileKey":"999.zip","childList":[]},{"originName":"画01.mp4","fileName":"999.zip_画01.mp4","parentFileName":"上传文件夹","fullName":"打包666\\上传文件夹\\画01.mp4","size":4744602,"directory":false,"fileKey":"999.zip","childList":[]}]},{"originName":"新文件夹","fileName":"新文件夹","parentFileName":"打包666","fullName":"打包666\\新文件夹","size":0,"directory":true,"fileKey":"999.zip","childList":[]}]}]} + */ + } + @Test + public void compressByOne(){ + String nodeString = "{\"originName\":\"999.zip\",\"fileName\":\"999.zip\",\"parentFileName\":\"\",\"fullName\":null,\"size\":null,\"directory\":true,\"fileKey\":null,\"childList\":[{\"originName\":\"打包555\",\"fileName\":\"打包555\",\"parentFileName\":\"999.zip\",\"fullName\":\"打包555\",\"size\":0,\"directory\":true,\"fileKey\":\"999.zip\",\"childList\":[]},{\"originName\":\"打包666\",\"fileName\":\"打包666\",\"parentFileName\":\"999.zip\",\"fullName\":\"打包666/\",\"size\":0,\"directory\":true,\"fileKey\":\"999.zip\",\"childList\":[{\"originName\":\"b38f16408466431aa421a13643ba412f1678167794239_30028.mp3\",\"fileName\":\"999.zip_b38f16408466431aa421a13643ba412f1678167794239_30028.mp3\",\"parentFileName\":\"打包666\",\"fullName\":\"打包666\\\\b38f16408466431aa421a13643ba412f1678167794239_30028.mp3\",\"size\":4543462,\"directory\":false,\"fileKey\":\"999.zip\",\"childList\":[]},{\"originName\":\"上传文件夹\",\"fileName\":\"上传文件夹\",\"parentFileName\":\"打包666\",\"fullName\":\"打包666/上传文件夹/\",\"size\":0,\"directory\":true,\"fileKey\":\"999.zip\",\"childList\":[{\"originName\":\"1599794872690_2232915.gif\",\"fileName\":\"999.zip_1599794872690_2232915.gif\",\"parentFileName\":\"上传文件夹\",\"fullName\":\"打包666\\\\上传文件夹\\\\1599794872690_2232915.gif\",\"size\":914096,\"directory\":false,\"fileKey\":\"999.zip\",\"childList\":[]},{\"originName\":\"txt打开.txt\",\"fileName\":\"999.zip_txt打开.txt\",\"parentFileName\":\"上传文件夹\",\"fullName\":\"打包666\\\\上传文件夹\\\\txt打开.txt\",\"size\":34,\"directory\":false,\"fileKey\":\"999.zip\",\"childList\":[]},{\"originName\":\"枫叶.JPEG\",\"fileName\":\"999.zip_枫叶.JPEG\",\"parentFileName\":\"上传文件夹\",\"fullName\":\"打包666\\\\上传文件夹\\\\枫叶.JPEG\",\"size\":47509,\"directory\":false,\"fileKey\":\"999.zip\",\"childList\":[]},{\"originName\":\"画01.mp4\",\"fileName\":\"999.zip_画01.mp4\",\"parentFileName\":\"上传文件夹\",\"fullName\":\"打包666\\\\上传文件夹\\\\画01.mp4\",\"size\":4744602,\"directory\":false,\"fileKey\":\"999.zip\",\"childList\":[]}]},{\"originName\":\"新文件夹\",\"fileName\":\"新文件夹\",\"parentFileName\":\"打包666\",\"fullName\":\"打包666\\\\新文件夹\",\"size\":0,\"directory\":true,\"fileKey\":\"999.zip\",\"childList\":[]}]}]}"; + CompressFileReader.FileNode fileNode = JsonUtils.jsonToBean(nodeString, CompressFileReader.FileNode.class); + + String filePath = "E:\\zip测试打包\\999.zip"; + String fileName = "999.zip"; + LoginUser loginUser = new LoginUser(); + loginUser.setUserID(1L); + String extractPath = "E:\\zip测试打包\\999\\"; + String finalFolderPath = "E:\\zip测试打包\\target\\"; + List fileList = new ArrayList(); + CheckFileDTO checkFileDTO = new CheckFileDTO(); + checkFileDTO.setFullName("打包666/上传文件夹/"); + checkFileDTO.setDirectory(true); + int i = 0; + this.compressFileCopy(fileNode.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO, extractPath, i); + + LogUtil.info("fileList=" + JsonUtils.beanToJson(fileList)); + } + + private void compressFileCopyChangeList(List fileNodeList, String finalFolderPath, List fileList, LoginUser loginUser, CheckFileDTO checkFileDTO + , String extractPath, int i){ + fileNodeList = fileNodeList.stream().sorted(Comparator.comparing(CompressFileReader.FileNode::isDirectory)).collect(Collectors.toList()); + + for (CompressFileReader.FileNode node : fileNodeList) { + if (node.isDirectory()) { + fileList.add(new ChangeSourceVo(node.getOriginName().endsWith("/") ? node.getOriginName().substring(0, node.getOriginName().length() - 1) : node.getOriginName(), + 1, node.getFullName())); + if (!CollectionUtils.isEmpty(node.getChildList())) { + compressFileCopyChangeList(node.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO + , extractPath, i); + } + } else { + String suffix = FileUtil.getFileExtension(node.getOriginName()); + String finalFilePath = finalFolderPath + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + loginUser.getUserID() + "." + suffix; + + File linkFile = new File(finalFilePath); + try {//创建硬链 + if (!linkFile.exists()) { + Files.createLink(Paths.get(finalFilePath), Paths.get(extractPath + node.getFileName())); + fileList.add(new ChangeSourceVo(node.getOriginName(), 0, suffix + , finalFilePath, node.getFullName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO) + , node.getSize(), "")); + } + } catch (FileAlreadyExistsException e) {//文件已存在, 忽略 + LogUtil.error(e, "compressFileCopy 创建硬链接失败 finalFilePath=" + finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + } catch (Exception e) { + LogUtil.error(e, "compressFileCopy error 创建硬链接失败 finalFilePath" + finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + + } + } + } + } + + private void compressFileCopy(List fileNodeList, String finalFolderPath, List fileList, LoginUser loginUser, CheckFileDTO checkFileDTO + , String extractPath, int i){ + if (!CollectionUtils.isEmpty(fileList)){ + return; + } + fileNodeList = fileNodeList.stream().sorted(Comparator.comparing(CompressFileReader.FileNode::isDirectory)).collect(Collectors.toList()); + + for (CompressFileReader.FileNode node : fileNodeList){ + i ++; + LogUtil.info(checkFileDTO.getFullName() + "-----compressFileCopy-------" + node.getFullName()); + if (checkFileDTO.getFullName().equals(node.getFullName())){ + if (node.isDirectory()){ + fileList.add(new ChangeSourceVo(node.getOriginName().endsWith("/") ? node.getOriginName().substring(0,node.getOriginName().length() -1) : node.getOriginName(), + 1, node.getFullName())); + this.compressFileCopyChangeList(node.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO, extractPath, i); + return; + }else { + String suffix = FileUtil.getFileExtension(node.getOriginName()); + String finalFilePath = finalFolderPath + RandomUtil.getuuid() + System.currentTimeMillis() + + "_" + i + "_" + loginUser.getUserID()+ "." + suffix; + + File linkFile = new File(finalFilePath); + try {//创建硬链 + if (!linkFile.exists()){ + Files.createLink(Paths.get(finalFilePath), Paths.get(extractPath + node.getFileName())); + fileList.add(new ChangeSourceVo(node.getOriginName(), 0, suffix + , finalFilePath , node.getFullName().replaceAll(GlobalConfig.separator, GlobalConfig.separatorTO) + , node.getSize(), "")); + } + } catch (FileAlreadyExistsException e){//文件已存在, 忽略 + LogUtil.error(e, "compressFileCopy 创建硬链接失败 finalFilePath=" + finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + } catch (Exception e){ + LogUtil.error(e, "compressFileCopy error 创建硬链接失败 finalFilePath"+ finalFilePath + ", orgPath=" + extractPath + node.getFileName()); + } + return; + } + }else if (!CollectionUtils.isEmpty(node.getChildList())){ + compressFileCopy(node.getChildList(), finalFolderPath, fileList, loginUser, checkFileDTO + , extractPath, i); + } + } + } + + @Test + public void d(){ + + HomeExplorerDTO homeExp = new HomeExplorerDTO(); + homeExp.setSourceID(88608L); + LoginUser loginUser = new LoginUser(); + loginUser.setUserID(1L); + loginUser.setUserType(1); + + try { + Object re = explorerFileService.unzipList(homeExp, loginUser); + LogUtil.info(JsonUtils.beanToJson(re)); + }catch (Exception e){ + LogUtil.error(e, "error"); + } + } + + @Resource + CommonInfoTypeService commonInfoTypeService; + @Test + public void a(){ + + String path = "/uploads/private/cloud/2023_3/2/03d57b92f0e2446c98ac78e63aefc71e1677750335699_30028.swf"; + String a = path.substring(path.lastIndexOf("/") + 1); + String b = path.substring(0,path.lastIndexOf("/") + 1); + String c = path.substring(0,path.lastIndexOf(".") ) + "/"; + + String tempIP = c + a.replace(".", "_")+"_cut_%2d.jpg"; + + System.out.println(a); + System.out.println(b); + System.out.println(c); + System.out.println(tempIP); + + CommonInfoTypeDto infoTypeDto = new CommonInfoTypeDto(); + LoginUser loginUser = new LoginUser(); + List list = commonInfoTypeService.getInfoTypeList(infoTypeDto, loginUser); + System.out.println(JsonUtils.beanToJson(list)); + } + + + @Test + public void getVideoCutImg(){ + + String tempVideoPath = "s01.mp4"; + Double begin = 5.1; + Double end = 9.0; + + + String nameDir = tempVideoPath.substring(tempVideoPath.lastIndexOf("/") + 1); + String tempPath = tempVideoPath.substring(0,tempVideoPath.lastIndexOf(".") ) + "/"; + // 从视频中截取多张图片 + String tempImgPath = tempPath + nameDir.replace(".", "_")+"_cut_%02d.jpg"; + + System.out.println(begin * 24); + System.out.println(end * 24); + Integer beginN = (int)Math.ceil(begin * 24); + Integer endN = (int)Math.ceil(end * 24); + + int num = 1; + if (endN > beginN) { + System.out.println((endN - beginN) / 24); + double n = (endN - beginN); + num = (int) Math.ceil(n / 24); + } + System.out.println("************** num=" + num); + for (int i = 1; i <= num ; i ++){ + System.out.println(String.format(tempImgPath, i)); + } + + boolean a = VideoGetUtil.covPicBatch(tempVideoPath, tempImgPath, beginN, endN, 24); + System.out.println(a); + } + + @Test + public void zipNew(){ + String filePath = "E:\\zip测试打包\\压缩zip\\999_new.zip"; + + String fileName1 = "E:\\zip测试打包\\压缩zip\\txt打开.txt"; + String fileName2 = "E:\\zip测试打包\\压缩zip\\枫叶.JPEG"; + + try { + ZipFile zipFile = new ZipFile(filePath); + + zipFile.addFolder(new File("E:\\zip测试打包\\压缩zip\\aaa")); + zipFile.addFolder(new File("E:\\zip测试打包\\压缩zip\\bbb")); + zipFile.renameFile("bbb/", "aaa/bbb"); + + File file = new File(fileName1); + zipFile.addFile(file); + + zipFile.renameFile("txt打开.txt", "aaa/bbb/txt打开000.txt"); + + }catch (Exception e){ + LogUtil.error(e, ""); + } + + + + } + + @Test + public void zipNew2(){ + Map resultMap = new HashMap<>(1); + LoginUser loginUser = new LoginUser(); + loginUser.setUserType(1); + loginUser.setUserID(1L); + CheckFileDTO updateFileDTO = new CheckFileDTO(); + updateFileDTO.setName("压缩new3.zip"); + updateFileDTO.setSourceID(82110L); + updateFileDTO.setSourceLevel(",0,"); + updateFileDTO.setTaskID(",0,23c26d29ba124832bd06dccde0a93f98"); + + List dataArr = new ArrayList<>(); + SourceOpDto sourceOpDto1 = new SourceOpDto(); + + sourceOpDto1.setName("压缩new2"); + sourceOpDto1.setSourceID(58786L); + sourceOpDto1.setParentID(82110L); + sourceOpDto1.setType("type"); + sourceOpDto1.setParentLevel(",0,82110,"); + + dataArr.add(sourceOpDto1); + updateFileDTO.setDataArr(dataArr); + + + try { + uploadZipService.zipFile(updateFileDTO, resultMap, loginUser); + }catch (Exception e){ + LogUtil.error(e, ""); + } + + } + + @Test + public void te666(){ + /* int[] heightAndWidth; + String path = "E:\\zip测试打包\\压缩zip\\977b8cddf20646e582e18d4167f928b21684720528068_1.mp4"; + try { + heightAndWidth = VideoUtil.getHeightAndWidthAndduration(path); + } catch (Exception e){ + LogUtil.error("获取视频宽高失败, path: " + path + ", e: " + e.getMessage()); + heightAndWidth = new int[]{0, 0, 0}; + } + System.out.println(heightAndWidth); + */ + int w = 1920; + int h = 1080; + + int width = 220; + int height = 480; + + BigDecimal widthRatio = new BigDecimal(width).divide(new BigDecimal(h),1,BigDecimal.ROUND_UP); + BigDecimal heightReal = new BigDecimal(height).divide(widthRatio,BigDecimal.ROUND_UP); + BigDecimal value = new BigDecimal(w).subtract(heightReal).divide(new BigDecimal(2),BigDecimal.ROUND_UP); + + List command = new ArrayList<>(); + command.add("ffmpeg"); + command.add("-i"); + command.add("/uploads/private/cloud/2023_5/22/977b8cddf20646e582e18d4167f928b21684720528068_1.mp4"); + command.add("-vf"); + //command.add("scale=" + h +":"+heightReal.intValue()+",pad=" + h+":" + w +":0:"+value.intValue()+":black"); + command.add("scale=" + h +":"+heightReal.intValue()); + command.add("-r"); + command.add( "30"); + command.add("-vcodec"); + command.add("h264"); + command.add("-b:v"); + command.add("0"); + + command.add("/uploads/private/cloud/2023_5/24/f14e95f76e7042adb2511893ebb79c061684897313404_102.mp4");//文件输出源 + + // ffmpeg -i /uploads/private/cloud/2023_5/22/977b8cddf20646e582e18d4167f928b21684720528068_1.mp4 -s 1920x1080 -r 30 /uploads/private/cloud/2023_5/24/f14e95f76e7042adb2511893ebb79c061684897313404_1.mp4 + StringBuilder sb = new StringBuilder(); + for (String a : command){ + sb.append(a); + sb.append(" "); + } + LogUtil.info("convertVideoMerge cmd:" + sb.toString()); + + } + + @Resource + CommonDesignService commonDesignService; + @Test + public void aaa() { + + GetDesignListDTO dto = new GetDesignListDTO(); + dto.setClientType("1"); + dto.setDesignType("2"); + dto.setCommonDesignId(30011L); + Map map = commonDesignService.getDesignList(dto); + System.out.println(JsonUtils.beanToJson(map)); + } + + @Test + public void bbb() { + + + String filePath = "E:\\smm\\三维动画设计.xmind"; + String imgPath = "E:\\smm\\思维导图2.png"; + String finalFilePath = "E:\\smm\\思维导图.pdf"; + String text = "{\"root\":{\"data\":{\"text\":\"

    中心主题333

    \",\"richText\":true,\"expand\":true,\"isActive\":false,\"uid\":\"d9bbcace-3277-4f71-82b4-ba2ac26680a8\"},\"children\":[{\"data\":{\"text\":\"

    分支主题 133333

    \",\"richText\":true,\"expand\":true,\"isActive\":false,\"uid\":\"6fe19717-9478-4cd0-9fdd-ea669ed6282c\"},\"children\":[]},{\"data\":{\"text\":\"

    分支主题 2

    \",\"richText\":true,\"expand\":true,\"isActive\":false,\"uid\":\"6244b71b-731a-4797-9192-faa46c635fdd\"},\"children\":[]},{\"data\":{\"text\":\"

    分支主题 3

    \",\"richText\":true,\"expand\":true,\"isActive\":false,\"uid\":\"536174cd-d639-499c-ad97-229ede809cc6\"},\"children\":[]},{\"data\":{\"text\":\"

    分支主题 4

    \",\"richText\":true,\"expand\":true,\"isActive\":false,\"uid\":\"15c1925a-9d9b-4743-aef3-14f06d8272fc\"},\"children\":[]}]},\"theme\":{\"template\":\"classic4\",\"config\":{}},\"layout\":\"logicalStructure\",\"config\":{},\"view\":{\"transform\":{\"scaleX\":0.8999999999999999,\"scaleY\":0.8999999999999999,\"shear\":0,\"rotate\":0,\"translateX\":-291.8000000000003,\"translateY\":-48.500000000000426,\"originX\":0,\"originY\":0,\"a\":0.8999999999999999,\"b\":0,\"c\":0,\"d\":0.8999999999999999,\"e\":-291.8000000000003,\"f\":-48.500000000000426},\"state\":{\"scale\":0.8999999999999999,\"x\":-291.8000000000003,\"y\":-48.500000000000426,\"sx\":-291.8000000000003,\"sy\":-48.500000000000426}}}"; + + + + try { + IWorkbookBuilder workbookBuilder = Core.getWorkbookBuilder(); + + FileInputStream stream = new FileInputStream(new File(filePath)); + IWorkbook iWorkbook = workbookBuilder.loadFromStream(stream,"."); + IMarkerSheet sheet = iWorkbook.getMarkerSheet(); + ISheet primarySheet = iWorkbook.getPrimarySheet(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + sheet.save(bos); + //sheet.getWorkbook().write(bos); + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + BufferedImage image = ImageIO.read(bis); + File file = new File(imgPath); + ImageIO.write(image, "png", file); + } catch (Exception e) { + LogUtil.error(e, "读取失败!"); + } + } + + @Test + public void bd(){ + try { + aaaaaaa(); + }catch (SvnlanRuntimeException e){ + Result result = new Result(false, e.getErrorCode(), e.getMessage(), ""); + System.out.println(JsonUtils.beanToJson(result)); + } + } + + private void aaaaaaa(){ + throw new SvnlanRuntimeException(CodeMessageEnum.noPermissionAuthAll.getCode(), new Object[]{"个人空间"}); + } +} diff --git a/src/test/java/com/svnlan/webdav/config/TestDiskSourceUtil.java b/src/test/java/com/svnlan/webdav/config/TestDiskSourceUtil.java new file mode 100644 index 0000000..7f65f9d --- /dev/null +++ b/src/test/java/com/svnlan/webdav/config/TestDiskSourceUtil.java @@ -0,0 +1,28 @@ +package com.svnlan.webdav.config; + +import com.svnlan.home.vo.IOSourceVo; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import javax.annotation.Resource; +import java.nio.file.Path; +import java.nio.file.Paths; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@Slf4j +public class TestDiskSourceUtil { + + @Resource + private DiskSourceUtil diskSourceUtil; + + @Test + public void testGetIoSource() { + Path path = Paths.get("/其他/文档(1)/sdfsdf"); + IOSourceVo ioSource = diskSourceUtil.getIoSource(path, 135L, 14250L); + log.info("testGetIoSource ioSource => {}", ioSource); + } +}