Commit 0958eb60 authored by Medicean's avatar Medicean

(Enhance:Database) 数据管理新增「书签」功能和「全局书签」

parent fb42a9bd
......@@ -16,6 +16,14 @@
* 修复搜索数据时正则表达式输入错误导致crash 问题 #157
### 数据管理
* 添加SQL语句书签功能, 将常用的 SQL 语句保存成书签
### 其它
* 「默认设置」数据管理项中, 增加「全局书签」设置, 设置一些自己常用的 SQL 语句
## 2019/04/24 `v(2.1.0)`
### 重要提醒
......
{
"name": "antsword",
"version": "2.1.0.3",
"version": "2.1.0.4",
"description": "中国蚁剑是一款跨平台的开源网站管理工具",
"main": "app.js",
"dependencies": {
......
......@@ -446,7 +446,29 @@ Hot Keys:
query: {
title: 'Exec SQL',
exec: 'Run',
clear: 'Clear'
clear: 'Clear',
bookmark: {
title: 'Bookmark',
add: 'Add bookmark',
del: 'Remove this bookmark',
clear: 'Clear all bookmarks',
},
prompt: {
add: {
title: 'Add to bookmark',
success: (path) => `Add to bookmark success!\n${path}`,
},
remove: {
title: 'Remove bookmark',
confirm: 'Remove this bookmark ?',
success: 'Remove bookmark success!'
},
clear: {
title: 'Clear all bookmarks',
confirm: 'Clear all bookmarks ?',
success: 'Clear all bookmark success!'
}
},
},
result: {
title: 'Result',
......@@ -781,6 +803,38 @@ Hot Keys:
success: 'Edit success'
}
},
},
database: {
title: 'Database',
bookmark: {
title: 'Global Bookmark',
nodata: 'No data, click the right mouse button add',
grid: {
name: 'Name',
path: 'SQL'
},
bmenu: {
add: 'Add Bookmark',
del: 'Del Bookmark'
},
add: {
title: 'Add to global SQL bookmark',
success: 'Add success',
namedup: 'The name cannot be duplicated',
name_invalid: 'Name is invalid',
addbtn: 'Confirm'
},
del: {
title: 'Delete Bookmark',
confirm: (num) => antSword.noxss(`Are you sure to delete ${typeof (num) === 'number' ? num + ' Bookmarks' : num + " "}?`),
success: 'Delete success'
},
edit: {
namedup: 'The name cannot be duplicated',
name_invalid: 'Name is invalid',
success: 'Edit success'
}
},
}
}
},
......
......@@ -448,7 +448,29 @@ module.exports = {
query: {
title: '执行SQL',
exec: '执行',
clear: '清空'
clear: '清空',
bookmark: {
title: '书签',
add: '添加书签',
del: '移除书签',
clear: '清空书签',
},
prompt: {
add: {
title: '添加SQL书签',
success: (sql) => `添加书签成功!\nSQL: ${sql}`,
},
remove: {
title: '移除书签',
confirm: '确定移除此书签?',
success: '移除书签成功',
},
clear: {
title: '清空书签',
confirm: '确定清空所有书签吗?',
success: '清空书签成功',
},
}
},
result: {
title: '执行结果',
......@@ -783,6 +805,38 @@ module.exports = {
success: '更新成功'
}
},
},
database: {
title: '数据管理',
bookmark: {
title: '全局书签',
nodata: '当前暂无数据, 请单击鼠标右键添加',
grid: {
name: '名称',
path: 'SQL'
},
bmenu: {
add: '添加书签',
del: '删除书签'
},
add: {
title: '添加全局SQL书签',
success: '添加成功',
namedup: '名称不能重复',
name_invalid: '名称不合法',
addbtn: '确定'
},
del: {
title: '删除书签',
confirm: (num) => antSword.noxss(`你确定要删除 ${typeof (num) === 'number' ? num + ' 个书签' : num + " "}吗?`),
success: '删除成功'
},
edit: {
namedup: '名称不能重复',
name_invalid: '名称不合法',
success: '更新成功'
}
},
}
}
},
......
......@@ -447,7 +447,29 @@ module.exports = {
query: {
title: '執行SQL',
exec: '執行',
clear: '清空'
clear: '清空',
bookmark: {
title: '書籤',
add: '添加書籤',
del: '移除書籤',
clear: '清空書籤',
},
prompt: {
add: {
title: '添加SQL書籤',
success: (sql) => `添加書籤成功!\nSQL: ${sql}`,
},
remove: {
title: '移除書籤',
confirm: '確定移除此書籤?',
success: '移除書籤成功',
},
clear: {
title: '清空書籤',
confirm: '確定清空所有書籤嗎?',
success: '清空書籤成功',
},
}
},
result: {
title: '執行結果',
......@@ -782,6 +804,38 @@ module.exports = {
success: '更新成功'
}
},
},
database: {
title: '數據管理',
bookmark: {
title: '全局書籤',
nodata: '當前暫無數據, 請單擊鼠標右鍵添加',
grid: {
name: '名稱',
path: 'SQL'
},
bmenu: {
add: '添加書籤',
del: '刪除書籤'
},
add: {
title: '添加全局SQL書籤',
success: '添加成功',
namedup: '名稱不能重複',
name_invalid: '名稱不合法',
addbtn: '確定'
},
del: {
title: '刪除書籤',
confirm: (num) => antSword.noxss(`你確定要刪除 ${typeof (num) === 'number' ? num + ' 個書籤' : num + " "}嗎?`),
success: '刪除成功'
},
edit: {
namedup: '名稱不能重複',
name_invalid: '名稱不合法',
success: '更新成功'
}
},
}
}
},
......
......@@ -447,7 +447,29 @@ module.exports = {
query: {
title: '執行SQL',
exec: '執行',
clear: '清空'
clear: '清空',
bookmark: {
title: '書籤',
add: '添加書籤',
del: '移除書籤',
clear: '清空書籤',
},
prompt: {
add: {
title: '添加SQL書籤',
success: (sql) => `添加書籤成功!\nSQL: ${sql}`,
},
remove: {
title: '移除書籤',
confirm: '確定移除此書籤?',
success: '移除書籤成功',
},
clear: {
title: '清空書籤',
confirm: '確定清空所有書籤嗎?',
success: '清空書籤成功',
},
}
},
result: {
title: '執行結果',
......@@ -782,6 +804,38 @@ module.exports = {
success: '更新成功'
}
},
},
database: {
title: '數據管理',
bookmark: {
title: '全局書籤',
nodata: '當前暫無數據, 請單擊鼠標右鍵添加',
grid: {
name: '名稱',
path: 'SQL'
},
bmenu: {
add: '添加書籤',
del: '刪除書籤'
},
add: {
title: '添加全局SQL書籤',
success: '添加成功',
namedup: '名稱不能重複',
name_invalid: '名稱不合法',
addbtn: '確定'
},
del: {
title: '刪除書籤',
confirm: (num) => antSword.noxss(`你確定要刪除 ${typeof (num) === 'number' ? num + ' 個書籤' : num + " "}嗎?`),
success: '刪除成功'
},
edit: {
namedup: '名稱不能重複',
name_invalid: '名稱不合法',
success: '更新成功'
}
},
}
}
},
......
......@@ -8,12 +8,17 @@
const LANG = antSword['language']['database'];
const LANG_T = antSword['language']['toastr'];
const crypto = require('crypto');
class Database {
constructor(opt) {
this.hash = (+new Date * Math.random()).toString(16).substr(2, 8);
this.opt = opt;
let config = {
bookmarks: {},
};
this.config = JSON.parse(antSword['storage']("adefault_database", false, JSON.stringify(config)));
// 初始化UI
const tabbar = antSword['tabbar'];
tabbar.addTab(
......@@ -32,7 +37,6 @@ class Database {
this.query = this.initQuery(this.layout_right.cells('a'));
this.result = this.initResult(this.layout_right.cells('b'));
this.opt = opt;
this.win = new dhtmlXWindows();
this.win.attachViewportTo(this.cell.cell);
......@@ -98,31 +102,11 @@ class Database {
// 初始化右侧::SQL执行
initQuery(layout) {
let self = this;
layout.setText(`<i class="fa fa-code"></i> ${LANG['query']['title']}`);
layout.setHeight('200');
let editor;
// SQL语句toolbar
const toolbar = layout.attachToolbar();
toolbar.loadStruct([
{ id: 'exec', text: LANG['query']['exec'], icon: 'play', type: 'button', disabled: true },
// { type: 'separator' },
// { id: 'import', text: '导入', icon: 'download', type: 'button' },
{ type: 'separator' },
{ id: 'clear', text: LANG['query']['clear'], icon: 'remove', type: 'button' }
]);
toolbar.attachEvent('onClick', (id) => {
switch(id) {
case 'clear':
editor.session.setValue('');
break;
case 'exec':
this.drive.execSQL(editor.session.getValue());
break;
}
});
// SQL语句编辑器
editor = ace.edit(layout.cell.lastChild);
editor.$blockScrolling = Infinity;
......@@ -152,7 +136,146 @@ class Database {
editor.session.setValue("SELECT 'Hello antSword :)' AS welcome;");
// SQL语句toolbar
const toolbar = layout.attachToolbar();
let bookmark = JSON.parse(this.storage('dbbookmarks').get('{}'));
let reloadToolbar = () => {
let bookmark_opts = [{
id: 'bookmark_add',
type: 'button',
icon: 'plus-circle',
text: LANG['query']['bookmark']['add'],
// enabled: !!bookmark[Buffer.from(editor.session.getValue()).toString('base64')],
}];
let global_bookmarks = this.config.bookmarks || {};
if(Object.keys(global_bookmarks).length > 0) {
bookmark_opts.push({type: 'separator'});
for(let gb in global_bookmarks) {
bookmark_opts.push({
id: 'bookmark_'+ global_bookmarks[gb],
text: antSword.noxss(gb),
icon: 'bookmark',
type: 'button',
// enabled: Buffer.from(editor.session.getValue()).toString('base64') != global_bookmarks[gb] ,
});
}
}
if (!$.isEmptyObject(bookmark)) {
bookmark_opts.push({ type: 'separator' });
};
for (let _ in bookmark) {
bookmark_opts.push({
id: 'bookmark_' + _, // _ 是 base64 格式
text: antSword.noxss(bookmark[_]),
icon: 'bookmark-o',
type: 'button',
// enabled: Buffer.from(editor.session.getValue()).toString('base64') != _ ,
});
}
// 添加清除按钮
if (bookmark_opts.length > 2) {
bookmark_opts.push({
type: 'separator'
});
bookmark_opts.push({
id: 'bookmark_remove',
icon: 'remove',
text: LANG['query']['bookmark']['del'],
type: 'button',
});
bookmark_opts.push({
id: 'bookmark_clear',
icon: 'trash-o',
text: LANG['query']['bookmark']['clear'],
type: 'button'
});
};
let btnstatus = {};
['exec', 'clear'].map((btn)=>{
try{
btnstatus[btn] = toolbar.isEnabled(btn);
}catch(e){
btnstatus[btn] = true;
}
})
toolbar.clearAll();
toolbar.loadStruct([
{ id: 'exec', text: LANG['query']['exec'], icon: 'play', type: 'button', disabled: !btnstatus['exec'] },
// { type: 'separator' },
// { id: 'import', text: '导入', icon: 'download', type: 'button' },
{ type: 'separator' },
{ id: 'clear', text: LANG['query']['clear'], icon: 'remove', type: 'button' },
{ type: 'separator' },
{ id: 'bookmark', text: LANG['query']['bookmark']['title'], icon: 'bookmark', type: 'buttonSelect', openAll: true, options: bookmark_opts },
]);
}
reloadToolbar();
toolbar.attachEvent('onClick', (id) => {
switch(id) {
case 'clear':
editor.session.setValue('');
break;
case 'exec':
this.drive.execSQL(editor.session.getValue());
break;
case 'bookmark_add':
// 添加书签
layer.prompt({
value: antSword.noxss(editor.session.getValue()),
title: LANG['query']['prompt']['add']['title']
}, (value, i, e) => {
bookmark[Buffer.from(editor.session.getValue()).toString('base64')] = value;
self.storage('dbbookmarks').set(JSON.stringify(bookmark));
toastr.success(LANG['query']['prompt']['add']['success'](editor.session.getValue()), LANG_T['success']);
reloadToolbar();
layer.close(i);
});
break;
case 'bookmark_remove':
layer.confirm(
LANG['query']['prompt']['remove']['confirm']
, {
icon: 2, shift: 6,
title: `<i class="fa fa-remove"></i> ${LANG['query']['prompt']['remove']['title']}`,
}
, (_) => {
// 删除书签并刷新
delete bookmark[Buffer.from(editor.session.getValue()).toString('base64')];
self.storage('dbbookmarks').set(JSON.stringify(bookmark));
reloadToolbar();
toastr.success(LANG['query']['prompt']['remove']['success'], LANG_T['success']);
layer.close(_);
}
)
break;
case 'bookmark_clear':
layer.confirm(
LANG['query']['prompt']['clear']['confirm']
, {
icon: 2, shift: 6,
title: `<i class="fa fa-trash-o"></i> ${LANG['query']['prompt']['clear']['title']}`
}
, (_) => {
bookmark = {};
self.storage('dbbookmarks').set('{}');
reloadToolbar();
toastr.success(LANG['query']['prompt']['clear']['success'], LANG_T['success']);
layer.close(_);
}
);
break;
default:
let arr = id.split('_');
if (arr.length === 2 && arr[0] === 'bookmark') {
editor.session.setValue(Buffer.from(arr[1], 'base64').toString());
// toolbar.enableItem('exec');
};
}
});
return {
reloadToolbar: reloadToolbar,
editor: editor,
layout: layout,
toolbar: toolbar
......@@ -267,6 +390,19 @@ class Database {
toastr.error(JSON.stringify(err), LANG_T['error']);
});
}
// 本地存储
// storage('save_key').get('{}')
// storage('save_key').set('{a:123}')
storage(key) {
let md5 = crypto.createHash('md5');
md5.update(this.opt['url']);
const k = `${md5.digest('hex').substr(0, 11)}_${key}`
return {
get: (def) => localStorage.getItem(k) || def,
set: (val) => localStorage.setItem(k, val)
}
}
}
// export default Database;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment