diff --git a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java index 2d3f3940e8402eab33106506e7d93a03c87f7bfb..7c9ed831910cc12f45b2e912a9cdc9ab2aa32f90 100644 --- a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java +++ b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java @@ -85,7 +85,6 @@ public class JdbcUtil { default: sql = "select * from " + table + " where 1=2"; } - log.info(sql); pst = conn.prepareStatement(sql); ResultSetMetaData rsd = pst.executeQuery().getMetaData(); @@ -129,13 +128,13 @@ public class JdbcUtil { public static Object executeSql(Connection connection, String sql, List jdbcParamValues) throws SQLException { log.debug(sql); log.debug(JSON.toJSONString(jdbcParamValues)); - PreparedStatement statement = connection.prepareStatement(sql); //参数注入 for (int i = 1; i <= jdbcParamValues.size(); i++) { statement.setObject(i, jdbcParamValues.get(i - 1)); } boolean hasResultSet = statement.execute(); + if (hasResultSet) { ResultSet rs = statement.getResultSet(); int columnCount = rs.getMetaData().getColumnCount(); diff --git a/dbapi-service/src/main/resources/application.properties b/dbapi-service/src/main/resources/application.properties index 041e5480584d140ba45ffeca5a240d3fb47e9412..b41acf423fce66314cb23853d0776fc5d88d8d95 100644 --- a/dbapi-service/src/main/resources/application.properties +++ b/dbapi-service/src/main/resources/application.properties @@ -53,10 +53,4 @@ spring.datasource.password= #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dbapi?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8 #spring.datasource.username=root -#spring.datasource.password=root - - - - - - +#spring.datasource.password=root \ No newline at end of file diff --git a/dbapi-ui/.gitignore b/dbapi-ui/.gitignore index dfc6081c05588043ee4fddcb26c18863d4e81e66..e1d14df7620f4b0213cc76c896c3b9257c4a692f 100644 --- a/dbapi-ui/.gitignore +++ b/dbapi-ui/.gitignore @@ -22,3 +22,5 @@ pnpm-debug.log* *.njsproj *.sln *.sw? + +**/.history/** diff --git a/dbapi-ui/package.json b/dbapi-ui/package.json index d731ae939bf57621f78995721b96948e2a3bf201..f64b29782419de70b56b0095675e1d06a8800b76 100644 --- a/dbapi-ui/package.json +++ b/dbapi-ui/package.json @@ -1,5 +1,5 @@ { - "name": "DBApi", + "name": "dbapi", "version": "0.1.0", "private": true, "scripts": { @@ -12,13 +12,14 @@ "element-ui": "^2.4.5", "moment": "^2.29.1", "qs.js": "^0.1.12", + "sql-formatter": "^4.0.2", "vue": "^2.6.11", "vue-axios": "^3.1.3", + "vue-clipboard2": "^0.3.3", "vue-codemirror": "^4.0.6", "vue-i18n": "^8.26.7", "vue-router": "^3.2.0", - "vuex": "^3.4.0", - "sql-formatter": "^4.0.2" + "vuex": "^3.4.0" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.0", @@ -29,7 +30,6 @@ "node-sass": "^5.0.0", "sass-loader": "^10.0.5", "vue-cli-plugin-element": "^1.0.1", - "vue-template-compiler": "^2.6.11", - "sql-formatter": "^4.0.2" + "vue-template-compiler": "^2.6.11" } } diff --git a/dbapi-ui/src/components/api/add.vue b/dbapi-ui/src/components/api/add.vue index 96ea7b1059a4ef394734d7f1b9de42dc83bc7e9a..539c0a72b087900e90804c79c88fc87b31526fc9 100644 --- a/dbapi-ui/src/components/api/add.vue +++ b/dbapi-ui/src/components/api/add.vue @@ -23,8 +23,6 @@ export default { save() { const detail = this.$refs.apiAdd.detail - - debugger const sqlList = this.$store.getters.getSql let p = { name: detail.name, @@ -59,7 +57,6 @@ export default { ).then((response) => { if (response.data.success) { this.$message.success(response.data.msg) - debugger this.$router.push("/api") } else { this.$message.error(response.data.msg) diff --git a/dbapi-ui/src/components/api/api.vue b/dbapi-ui/src/components/api/api.vue index 687a33fb72263077b3e7ad6d1e792572263dbbbc..1adfb975235814ea47bd962049296e195c238d88 100644 --- a/dbapi-ui/src/components/api/api.vue +++ b/dbapi-ui/src/components/api/api.vue @@ -3,154 +3,352 @@
- - + + - + - + - + - - + + - - + - - - + + + {{ $t('m.cancel') }} - {{ $t('m.export') }} + {{ $t('m.export') }} - - - + + + {{ $t('m.cancel') }} - {{ $t('m.export') }} + {{ $t('m.export') }} - + - {{ item.name }} + {{ item.name }} {{ item.id }} - + {{ $t('m.cancel') }} - {{ $t('m.export') }} + {{ $t('m.export') }}
@@ -160,11 +358,13 @@ diff --git a/dbapi-ui/src/components/api/common/SqlCode.vue b/dbapi-ui/src/components/api/common/SqlCode.vue index 7ac15ed99d937cc1bce45e489099bba7df7937b3..0d09a29e5cf281332f39dac8d68fee001cb143d7 100644 --- a/dbapi-ui/src/components/api/common/SqlCode.vue +++ b/dbapi-ui/src/components/api/common/SqlCode.vue @@ -2,9 +2,17 @@
- +
-
+
{{ item.label }}
-
+
{{ it.label }} {{ it.TypeName }} @@ -31,37 +46,88 @@
-
运行SQL
-
运行选中SQL
-
解析动态SQL
-
格式化SQL
+
运行SQL
+
运行选中SQL
+
解析动态SQL
+
格式化SQL
-
foreach
-
if
-
where
-
trim
- - +
foreach
+
if
+
where
+
trim
+ +
- +
-
-
+
+
SQL-{{ item.label }}
- +
-
+
添加 @@ -71,34 +137,67 @@
参数设置:
- +
填写sql运行需要的参数值,拼接成json格式
- +
- - json格式化 + + json格式化
-
+
{{ error }}
-
+
{{ updateMsg }}
-
+
{{ sqlMeta.sql }}
{{ sqlMeta.jdbcParamValues }}
- - + +
查询结果为空
@@ -110,15 +209,13 @@ + + \ No newline at end of file diff --git a/dbapi-ui/src/components/api/common/codeUI.vue b/dbapi-ui/src/components/api/common/codeUI.vue index 5328b4e1540721270834226f9d0bb8e2463e4890..0e7f0666f76e3056e6d1f379be8841f276c323de 100644 --- a/dbapi-ui/src/components/api/common/codeUI.vue +++ b/dbapi-ui/src/components/api/common/codeUI.vue @@ -1,30 +1,27 @@ + \ No newline at end of file diff --git a/dbapi-ui/src/components/api/request.vue b/dbapi-ui/src/components/api/request.vue index 375c9930b3edbcbd7e0a7828bfe866240a69c5a7..dd8112f00e639aeaee58b7152e9a4e63f528fcf3 100644 --- a/dbapi-ui/src/components/api/request.vue +++ b/dbapi-ui/src/components/api/request.vue @@ -1,78 +1,180 @@ ")}catch(c){console&&console.log(c)}}function s(){z||(z=!0,a())}function v(){try{m.documentElement.doScroll("left")}catch(c){return void setTimeout(v,50)}s()}l=function(){var c,l=document.createElement("div");l.innerHTML=o,o=null,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(c=document.body).firstChild?i(l,c.firstChild):c.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(h=function(){document.removeEventListener("DOMContentLoaded",h,!1),l()},document.addEventListener("DOMContentLoaded",h,!1)):document.attachEvent&&(a=l,m=c.document,z=!1,v(),m.onreadystatechange=function(){"complete"==m.readyState&&(m.onreadystatechange=null,s())})}(window); \ No newline at end of file +!(function(c) { let l; let h; let a; let m; let z; let o = ''; var t = (t = document.getElementsByTagName("script"))[t.length - 1].getAttribute("data-injectcss"); const i = function(c, l) { l.parentNode.insertBefore(c, l) }; if(t && !c.__iconfont__svg__cssinject__) { c.__iconfont__svg__cssinject__ = !0; try{ document.write("") }catch(c) { console && console.log(c) } }function s() { z || (z = !0, a()) }function v() { try{ m.documentElement.doScroll("left") }catch(c) { return void setTimeout(v, 50) }s() }l = function() { let c; let l = document.createElement("div"); l.innerHTML = o, o = null, (l = l.getElementsByTagName("svg")[0]) && (l.setAttribute("aria-hidden", "true"), l.style.position = "absolute", l.style.width = 0, l.style.height = 0, l.style.overflow = "hidden", l = l, (c = document.body).firstChild ? i(l, c.firstChild) : c.appendChild(l)) }, document.addEventListener ? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? setTimeout(l, 0) : (h = function() { document.removeEventListener("DOMContentLoaded", h, !1), l() }, document.addEventListener("DOMContentLoaded", h, !1)) : document.attachEvent && (a = l, m = c.document, z = !1, v(), m.onreadystatechange = function() { m.readyState == "complete" && (m.onreadystatechange = null, s()) }) }(window)); diff --git a/dbapi-ui/src/main.js b/dbapi-ui/src/main.js index ac9c7cf8433b411943df7cedeb8481d4c92ea3b3..0b0a82e80e5693f1a61e5f345d934fef7cb99e41 100644 --- a/dbapi-ui/src/main.js +++ b/dbapi-ui/src/main.js @@ -14,31 +14,35 @@ import './icon/iconfont.css' import VueCodeMirror from 'vue-codemirror' import 'codemirror/lib/codemirror.css' -Vue.use(VueCodeMirror) - import install from '@/components/common/index.js' -Vue.use(install) +import VueClipboard from 'vue-clipboard2' -import moment from 'moment'; //导入模块 -moment.locale('zh-cn'); //设置语言 或 moment.lang('zh-cn'); -Vue.prototype.$moment = moment;//赋值使用 +import moment from 'moment'; + +import { CONTENT_TYPE } from "@/constant"; + +Vue.use(VueClipboard) +Vue.use(VueCodeMirror) +Vue.use(install) // 导入模块 +moment.locale('zh-cn'); // 设置语言 或 moment.lang('zh-cn'); +Vue.prototype.$moment = moment;// 赋值使用 Vue.config.productionTip = false -//使用vue-axios,这样才可以全局使用this.axios调用 +// 使用vue-axios,这样才可以全局使用this.axios调用 Vue.use(VueAxios, axios); // axios.defaults.baseURL = '/api' -axios.defaults.headers = {'Content-Type': 'application/x-www-form-urlencoded'} -//全局拦截post请求的参数,用qs序列化 +axios.defaults.headers = { 'Content-Type': CONTENT_TYPE.FORM_URLENCODED } +// 全局拦截post请求的参数,用qs序列化 axios.interceptors.request.use(config => { - //form表单提交multipart/form-data的时候,不需要序列化参数 - if (config.method === 'post' && config.headers['Content-Type'] === 'application/x-www-form-urlencoded') { - config.data = qs.stringify(config.data, {indices: false}); + // form表单提交multipart/form-data的时候,不需要序列化参数 + if (config.method === 'post' && config.headers['Content-Type'] === CONTENT_TYPE.FORM_URLENCODED) { + config.data = qs.stringify(config.data, { indices: false }); } - //拦截所有请求,添加登陆用户的token + // 拦截所有请求,添加登陆用户的token if (localStorage.getItem('token')) { const x = config.headers.Authorization if (x === null || x === undefined) { @@ -49,14 +53,12 @@ axios.interceptors.request.use(config => { }) -//后台用户登陆信息校验不成功就跳转到登录页面 +// 后台用户登陆信息校验不成功就跳转到登录页面 axios.interceptors.response.use(response => { - return response }, error => { if (error.response.status == '401') { - - //不是api请求测试的请求,就跳转登录页 + // 不是api请求测试的请求,就跳转登录页 if (!error.response.config.url.startsWith("http://")) { router.push("/login"); } else { @@ -72,12 +74,12 @@ Vue.filter('dateFormat', function (originVal) { const dt = new Date(originVal) const y = dt.getFullYear() - const m = (dt.getMonth() + 1 + '').padStart(2, '0') - const d = (dt.getDate() + '').padStart(2, '0') + const m = (String(dt.getMonth() + 1)).padStart(2, '0') + const d = (String(dt.getDate())).padStart(2, '0') - const hh = (dt.getHours() + '').padStart(2, '0') - const mm = (dt.getMinutes() + '').padStart(2, '0') - const ss = (dt.getSeconds() + '').padStart(2, '0') + const hh = (String(dt.getHours())).padStart(2, '0') + const mm = (String(dt.getMinutes())).padStart(2, '0') + const ss = (String(dt.getSeconds())).padStart(2, '0') return `${y}-${m}-${d} ${hh}:${mm}:${ss}` }) diff --git a/dbapi-ui/src/plugins/element.js b/dbapi-ui/src/plugins/element.js index 779d8509dfbc0c96a82c41990a08ed2acf74fd23..6e5305ace9c6012b4a8fb18a9a3b22112bda3f7f 100644 --- a/dbapi-ui/src/plugins/element.js +++ b/dbapi-ui/src/plugins/element.js @@ -51,7 +51,7 @@ import { // Progress, // Spinner, // Badge, - // Card, + Card, // Rate, // Steps, // Step, @@ -117,7 +117,7 @@ Vue.use(DatePicker); // Vue.use(TimeSelect); // Vue.use(TimePicker); Vue.use(Popover); -Vue.use(Popconfirm ); +Vue.use(Popconfirm); Vue.use(Tooltip); // Vue.use(Breadcrumb); @@ -140,7 +140,7 @@ Vue.use(Upload); // Vue.use(Progress); // Vue.use(Spinner); // Vue.use(Badge); -// Vue.use(Card); +Vue.use(Card); // Vue.use(Rate); // Vue.use(Steps); // Vue.use(Step); diff --git a/dbapi-ui/src/router/index.js b/dbapi-ui/src/router/index.js index 32ca04a49b1a45ebc9048ae3efb473d65fd30810..169529e024888d2c7f54dcfb1252671a17f3595b 100644 --- a/dbapi-ui/src/router/index.js +++ b/dbapi-ui/src/router/index.js @@ -24,27 +24,29 @@ import firewall from '../components/setting/firewall' Vue.use(VueRouter) const routes = [ - {path: '/login', name: 'login', component: Login}, + { path: '/login', name: 'login', component: Login }, { - path: '/', name: 'Home', component: Home, + path: '/', + name: 'Home', + component: Home, children: [ // {path: '/about/donate', name: 'donate', component: donate}, // {path: '/tool/json', name: 'json', component: json}, // {path: '/tool/time', name: 'time', component: time}, - {path: '/datasource', name: 'datasource', component: datasource}, - {path: '/datasource/edit', component: datasourceEdit}, - {path: '/datasource/detail', component: datasourceDetail}, - {path: '/datasource/add', component: datasourceAdd}, - {path: '/api', name: 'api', component: api}, - {path: '/api/add', name: 'apiAdd', component: apiAdd}, - {path: '/api/edit', name: 'apiEdit', component: apiEdit}, - {path: '/api/detail', name: 'detail', component: detail}, - {path: '/api/request', name: 'request', component: request}, - {path: '/token', component: token}, - {path: '/token/add', component: tokenAdd}, - {path: '/setting/password', component: user}, - {path: '/setting/firewall', component: firewall} + { path: '/datasource', name: 'datasource', component: datasource }, + { path: '/datasource/edit', component: datasourceEdit }, + { path: '/datasource/detail', component: datasourceDetail }, + { path: '/datasource/add', component: datasourceAdd }, + { path: '/api', name: 'api', component: api }, + { path: '/api/add', name: 'apiAdd', component: apiAdd }, + { path: '/api/edit', name: 'apiEdit', component: apiEdit }, + { path: '/api/detail', name: 'detail', component: detail }, + { path: '/api/request', name: 'request', component: request }, + { path: '/token', component: token }, + { path: '/token/add', component: tokenAdd }, + { path: '/setting/password', component: user }, + { path: '/setting/firewall', component: firewall } ] } ] diff --git a/dbapi-ui/src/store/index.js b/dbapi-ui/src/store/index.js index 88c03b6048a499bdf69927da2f235f20efd18c74..513c2fed9533a76ebf946b3e57049a21574351c8 100644 --- a/dbapi-ui/src/store/index.js +++ b/dbapi-ui/src/store/index.js @@ -5,14 +5,14 @@ Vue.use(Vuex) export default new Vuex.Store({ state: { - sqls: [{sqlText: 'test', id: 0, transformPlugin: null, transformPluginParams: null}], - seq: 0, //用来做for循环key - labelSeq: 0, //用来显示 + sqls: [{ sqlText: 'test', id: 0, transformPlugin: null, transformPluginParams: null }], + seq: 0, // 用来做for循环key + labelSeq: 0, // 用来显示 cmList: [], mode: null }, mutations: { - clearTransformPluginParam(state,index){ + clearTransformPluginParam(state, index) { state.sqls[index].transformPluginParams = null }, addSql(state) { @@ -36,7 +36,7 @@ export default new Vuex.Store({ emptyCmList(state, payload) { state.cmList = [] }, - //编辑或新增页面初始化sql + // 编辑或新增页面初始化sql initSqls(state, payload) { state.cmList = [] state.labelSeq = 0 @@ -52,8 +52,6 @@ export default new Vuex.Store({ label: state.labelSeq } }) - // debugger - console.log('--------------' + state.sqls) }, setMode(state, payload) { state.mode = payload @@ -65,8 +63,7 @@ export default new Vuex.Store({ const p = [] for (let i = 0; i < state.sqls.length; i++) { - let obj = {} - // debugger + const obj = {} obj.transformPlugin = state.sqls[i].transformPlugin obj.transformPluginParams = state.sqls[i].transformPluginParams obj.sqlText = state.cmList[i].getValue() diff --git a/dbapi-ui/src/utils/code/go/index.js b/dbapi-ui/src/utils/code/go/index.js new file mode 100644 index 0000000000000000000000000000000000000000..47390308b4c00a7dfa5edc99456acaa8dc024db6 --- /dev/null +++ b/dbapi-ui/src/utils/code/go/index.js @@ -0,0 +1,125 @@ +import { DATA_TYPE, CONTENT_TYPE } from "@/constant"; + +export function generateGoCallExampleCode({ + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue +}) { + + const authHeaderStr = ` SetHeader("Authorization", "${token}").\n` + + let bodyStringDesStr = '' + if (isContentTypeJson) { + bodyStringDesStr = `\n bodyString := "${detail.jsonParam.replace(/\n|\r|\t/g, '').replace(/"/g, '\\"')}"\n` + } else if (isContentTypeFormUrlEncoded) { + const param = getParam(params, getEffectValue) + bodyStringDesStr = `data := url.Values{} + ${param.join("\n ")} + bodyString := data.Encode()` + } + + return `package main +import ( + "fmt" + // go get -u github.com/imroc/req/v3 + "github.com/imroc/req/v3" + "log"${isContentTypeFormUrlEncoded ? '\n "net/url"' : ''} +) + +func main() { + requestUrl := "${requestUrl}" + client := req.C() + + ${bodyStringDesStr} + + resp, err := client.R(). + SetHeader("Content-Type", "${contentType}"). +${isPrevilegePrivate ? authHeaderStr : ''} SetBodyString(bodyString). + Post(requestUrl) + if err != nil { + log.Fatal(err) + } + + if !resp.IsSuccess() { + fmt.Println("bad response status:", resp.Status) + return + } + fmt.Println(resp.String()) +} +` +} + +function getParam(params, getEffectValue) { + const param = [] + params.forEach(item => { + const itemType = item.type + const itemName = item.name + // {"name":"id","type":"string","value":"1"} + // {"name":"ids","type":"Array","values":[{"va":"2"},{"va":"3"}]} + // {"name":"date","type":"date","value":"1970-01-01 00:00:00"} + // {"name":"dates","type":"Array","values":[{"va":"1970-01-01 00:00:00"},{"va":"1970-01-01 00:00:00"}]} + const value = getEffectValue(itemType, item.value) + const values = Array.isArray(item.values) ? item.values : [] + switch (itemType) { + case DATA_TYPE.STRING: + param.push(`data.Set("${itemName}", "${value}")`) + break + case DATA_TYPE.BIGINT: + param.push(`data.Set("${itemName}", ${value})`) + break + case DATA_TYPE.DOUBLE: + param.push(`data.Set("${itemName}", ${value})`) + break + case DATA_TYPE.DATE: + param.push(`data.Set("${itemName}", "${value}")`) + break + case DATA_TYPE.ARRAY_STRING: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`data.Add("${itemName}", "${effectValue}")`) + }) + } else { + param.push(`data.Add("${itemName}", "")`) + } + break + case DATA_TYPE.ARRAY_BIGINT: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`data.Add("${itemName}", "${effectValue}")`) + }) + } else { + param.push(`data.Add("${itemName}", 1)`) + } + break + case DATA_TYPE.ARRAY_DOUBLE: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`data.Add("${itemName}", "${effectValue}")`) + }) + } else { + param.push(`data.Add("${itemName}", 1.0")`) + } + break + case DATA_TYPE.ARRAY_DATE: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`data.Add("${itemName}", "${effectValue}")`) + }) + } else { + param.push(`data.Add("${itemName}", "1970-01-01 00:00:00")`) + } + break + default: + break + } + }) + return param +} \ No newline at end of file diff --git a/dbapi-ui/src/utils/code/index.js b/dbapi-ui/src/utils/code/index.js new file mode 100644 index 0000000000000000000000000000000000000000..baf411d552df3af7e722c01b999dababf07571a6 --- /dev/null +++ b/dbapi-ui/src/utils/code/index.js @@ -0,0 +1,92 @@ + +/** + * address 请求地址 "127.0.0.1:8520/api" + * detail 完整示例 + * { + * "path": "test", + * "params": [ + * // "contentType": "application/x-www-form-urlencoded"时才有值 + * { + * "name": "id", + * "type": "string" + * } + * ], + * "previlege": 1, + * // "contentType": "application/json"时才有值 + * "jsonParam": "{\"id\":\"\"}", + * ], + * "contentType": "application/x-www-form-urlencoded", + * } + */ + +import { LANGUAGE, CONTENT_TYPE, PREVILEGE, DATA_TYPE } from '@/constant' +import { generateShellCallExampleCode } from './shell' +import { generatePythonCallExampleCode } from './python' +import { generateGoCallExampleCode } from './go' +import { generateJavaScriptCallExampleCode } from './javascript' +import { generateJavaCallExampleCode } from './java' + +function getEffectValue(type, value, expectValue) { + switch (type) { + case DATA_TYPE.STRING: + return typeof value === 'string' ? value : expectValue || "" + case DATA_TYPE.BIGINT: + return !isNaN(value) ? value : expectValue || 0 + case DATA_TYPE.DOUBLE: + return !isNaN(value) ? value : expectValue || 1.0 + case DATA_TYPE.DATE: + return typeof value === 'string' ? value : expectValue || "1970-01-01 00:00:00" + case DATA_TYPE.ARRAY_STRING: + return typeof value === 'string' ? value : expectValue || "" + case DATA_TYPE.ARRAY_BIGINT: + return !isNaN(value) ? value : expectValue || 0 + case DATA_TYPE.ARRAY_DOUBLE: + return !isNaN(value) ? value : expectValue || 1.0 + case DATA_TYPE.ARRAY_DATE: + return typeof value === 'string' && value.length > 0 ? value : expectValue || "1970-01-01 00:00:00" + default: + return "" + } +} + +function generateParam({ lang, address, detail }) { + const contentType = detail.contentType + const params = detail.params + const requestUrl = address + const previlege = detail.previlege + const isPrevilegePrivate = previlege === PREVILEGE.PRIVATE + const isPrevilegePublic = previlege === PREVILEGE.PUBLIC + const isContentTypeJson = contentType === CONTENT_TYPE.JSON + const isContentTypeFormUrlEncoded = contentType === CONTENT_TYPE.FORM_URLENCODED + // 暂时不知道token,仅作占位用 + const token = detail.token || '' + return { + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue + } +} + +export function generateCallExampleCode({ lang, address, detail }) { + const param = generateParam({ lang, address, detail }) + switch (lang) { + case LANGUAGE.SHELL: + return generateShellCallExampleCode(param) + case LANGUAGE.PYTHON: + return generatePythonCallExampleCode(param) + case LANGUAGE.GO: + return generateGoCallExampleCode(param) + case LANGUAGE.JAVASCRIPT: + return generateJavaScriptCallExampleCode(param) + case LANGUAGE.JAVA: + return generateJavaCallExampleCode(param) + default: + return '' + } +} + + diff --git a/dbapi-ui/src/utils/code/java/index.js b/dbapi-ui/src/utils/code/java/index.js new file mode 100644 index 0000000000000000000000000000000000000000..ffcd2637b44356cbf5b42ff187cb1cd9f079315e --- /dev/null +++ b/dbapi-ui/src/utils/code/java/index.js @@ -0,0 +1,186 @@ +import { DATA_TYPE, CONTENT_TYPE } from "@/constant"; + +export function generateJavaCallExampleCode(param) { + + const { + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue + } = param + + let dataDesStr = '' + if (isContentTypeJson) { + dataDesStr = `String dataStr = "${detail.jsonParam.replace(/\n|\r|\t/g, '').replace(/"/g, '\\"')}";` + } else if (isContentTypeFormUrlEncoded) { + dataDesStr = generateUrlEncodedDataDesStr(param) + } + + const authDesStr = `connection.setRequestProperty("Authorization", "${token}");` + + return `import java.io.*; +import java.net.*;${isContentTypeFormUrlEncoded ? '\nimport java.util.*;\nimport java.util.stream.Collectors;' : ''} + +public class Main { + public static void main(String[] args) throws IOException { + String requestUrl ="${requestUrl}"; + + URL url = new URL(requestUrl); + + HttpURLConnection connection = (HttpURLConnection)url.openConnection(); + connection.setRequestMethod("POST"); + connection.setUseCaches(false); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setRequestProperty("Content-Type", "${contentType}");${isPrevilegePrivate ? '\n ' + authDesStr : ''} + + connection.connect(); + + ${dataDesStr} + + OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(),"UTF-8"); + writer.write(dataStr); + writer.flush(); + writer.close(); + + InputStream is = connection.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + StringBuffer stringBuffer = new StringBuffer(); + String strRead; + while ((strRead = reader.readLine()) != null) { + stringBuffer.append(strRead); + stringBuffer.append("\\r\\n"); + } + reader.close(); + connection.disconnect(); + System.out.println(stringBuffer); + } +}` +} + +function generatePrarmCode(params, getEffectValue) { + const codes = [] + params.forEach(item => { + const itemType = item.type + const itemName = item.name + // {"name":"id","type":"string","value":"1"} + // {"name":"ids","type":"Array","values":[{"va":"2"},{"va":"3"}]} + // {"name":"date","type":"date","value":"1970-01-01 00:00:00"} + // {"name":"dates","type":"Array","values":[{"va":"1970-01-01 00:00:00"},{"va":"1970-01-01 00:00:00"}]} + let value = getEffectValue(itemType, item.value) + const values = Array.isArray(item.values) ? item.values : [] + switch (itemType) { + case DATA_TYPE.STRING: + codes.push(`params.put("${itemName}", "${value}");`) + break + case DATA_TYPE.BIGINT: + value = getEffectValue(itemType, item.value, '0L') + codes.push(`params.put("${itemName}", ${value});`) + break + case DATA_TYPE.DOUBLE: + value = getEffectValue(itemType, item.value, '1D') + codes.push(`params.put("${itemName}", ${value});`) + break + case DATA_TYPE.DATE: + codes.push(`params.put("${itemName}", "${value}");`) + break + case DATA_TYPE.ARRAY_STRING: + codes.push(`List ${itemName}Array = new ArrayList();`) + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + codes.push(`${itemName}Array.add("${effectValue}");`) + }) + } else { + codes.push(`${itemName}Array.add("");`) + } + codes.push(`params.put("${itemName}", ${itemName}Array);`) + break + case DATA_TYPE.ARRAY_BIGINT: + codes.push(`List ${itemName}Array = new ArrayList();`) + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va, "1L") + codes.push(`${itemName}Array.add("${effectValue}");`) + }) + } else { + codes.push(`${itemName}Array.add(1L);`) + } + codes.push(`params.put("${itemName}", ${itemName}Array);`) + break + case DATA_TYPE.ARRAY_DOUBLE: + codes.push(`List ${itemName}Array = new ArrayList();`) + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va, "1D") + codes.push(`${itemName}Array.add("${effectValue}");`) + }) + } else { + codes.push(`${itemName}Array.add(1D);`) + } + codes.push(`params.put("${itemName}", ${itemName}Array);`) + break + case DATA_TYPE.ARRAY_DATE: + codes.push(`List ${itemName}Array = new ArrayList();`) + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + codes.push(`${itemName}Array.add("${effectValue}");`) + }) + } else { + codes.push(`${itemName}Array.add("1970-01-01 00:00:00");`) + } + codes.push(`params.put("${itemName}", ${itemName}Array);`) + break + default: + break + } + }) + return codes +} + +function generateUrlEncodedDataDesStr({ + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue +}) { + const codes = generatePrarmCode(params, getEffectValue) + return `HashMap params = new HashMap<>(); + ${codes.join('\n ')} + + StringBuilder result = new StringBuilder(); + boolean first = true; + for(Map.Entry entry : params.entrySet()){ + if (first){ + first = false; + } else { + result.append("&"); + } + String key = entry.getKey(); + Object value = entry.getValue(); + if(value instanceof List){ + List list = (List)value; + String collectResult = list.stream().map(s -> { + try { + return URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + }).filter(Objects::nonNull).collect(Collectors.joining("&")); + result.append(collectResult); + }else if(value instanceof String){ + result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); + result.append("="); + result.append(URLEncoder.encode((String) entry.getValue(), "UTF-8")); + } + } + String dataStr = result.toString();` +} \ No newline at end of file diff --git a/dbapi-ui/src/utils/code/javascript/index.js b/dbapi-ui/src/utils/code/javascript/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a974945be20d30ab63c2df3a94ec7acdffc2b825 --- /dev/null +++ b/dbapi-ui/src/utils/code/javascript/index.js @@ -0,0 +1,135 @@ +/** +// npm install axios +// npm install qs +const axios = require('axios'); +var qs = require('qs'); + +axios({ + method: 'post', + url: 'http://127.0.0.1:8520/api/test', + + // application/x-www-form-urlencoded + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': '' + }, + data: qs.stringify({ + id: 1 + }), + + // application/json + headers: { + 'Content-Type': 'application/json', + 'Authorization': '' + }, + data: { + id: 1 + } + +}).then(response => { + console.log(response.data); +}).catch(error => { + console.log(error); +}); + */ +import { DATA_TYPE, CONTENT_TYPE } from "@/constant"; + +export function generateJavaScriptCallExampleCode({ + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue +}) { + const authorizationHeader = `'Authorization': '${token}'` + + let dataDesStr = '' + if (isContentTypeJson) { + dataDesStr = detail.jsonParam + } else if (isContentTypeFormUrlEncoded) { + const param = getParam(params, getEffectValue) + dataDesStr = `qs.stringify({ + ${param.join(',\n ')} +}, { indices: false })` + } + + + return `// npm install axios +// npm install qs +const axios = require('axios'); +const qs = require('qs'); +const data = ${dataDesStr} +axios({ + method: 'post', + url: '${requestUrl}', + headers: { + 'Content-Type': '${contentType}'${isPrevilegePrivate ? ',' : ''} +${isPrevilegePrivate ? " " + authorizationHeader + "\n" : ''} }, + data: data, +}).then(response => { + console.log(response.data); +}).catch(error => { + console.log(error); +});` +} + +function getParam(params, getEffectValue) { + const param = [] + params.forEach(item => { + const itemType = item.type + const itemName = item.name + // {"name":"id","type":"string","value":"1"} + // {"name":"ids","type":"Array","values":[{"va":"2"},{"va":"3"}]} + // {"name":"date","type":"date","value":"1970-01-01 00:00:00"} + // {"name":"dates","type":"Array","values":[{"va":"1970-01-01 00:00:00"},{"va":"1970-01-01 00:00:00"}]} + const value = getEffectValue(itemType, item.value) + const values = Array.isArray(item.values) ? item.values : [] + let elements = '' + switch (itemType) { + case DATA_TYPE.STRING: + param.push(`${itemName}: "${value}"`) + break + case DATA_TYPE.BIGINT: + param.push(`${itemName}: ${value}`) + break + case DATA_TYPE.DOUBLE: + param.push(`${itemName}: ${value}`) + break + case DATA_TYPE.DATE: + param.push(`${itemName}: "${value}"`) + break + case DATA_TYPE.ARRAY_STRING: + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join("\", \"") + } + param.push(`${itemName}: ["${elements}"]`) + break + case DATA_TYPE.ARRAY_BIGINT: + elements = '1' + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join(",") + } + param.push(`${itemName}: [${elements}]`) + break + case DATA_TYPE.ARRAY_DOUBLE: + elements = '1.0' + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join(",") + } + param.push(`${itemName}: [${elements}]`) + break + case DATA_TYPE.ARRAY_DATE: + elements = '1970-01-01 00:00:00' + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join("\", \"") + } + param.push(`${itemName}: ["${elements}"]`) + break + default: + break + } + }) + return param +} \ No newline at end of file diff --git a/dbapi-ui/src/utils/code/python/index.js b/dbapi-ui/src/utils/code/python/index.js new file mode 100644 index 0000000000000000000000000000000000000000..8bc00dc8ac14a986e367f666989f2086edea8f6e --- /dev/null +++ b/dbapi-ui/src/utils/code/python/index.js @@ -0,0 +1,95 @@ +import { DATA_TYPE, CONTENT_TYPE } from "@/constant"; + +export function generatePythonCallExampleCode({ + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue +}) { + const authorizationHeader = ` 'Authorization': '${token}'` + let dataDesStr = '' + if (isContentTypeJson) { + dataDesStr = `jsonParam = ${detail.jsonParam} +data = json.dumps(jsonParam)` + } else if (isContentTypeFormUrlEncoded) { + const param = getParam(params, getEffectValue) + dataDesStr = `formData = { + ${param.join(',\n ')} +} +data = parse.urlencode(formData, True)` + } + + return `import requests${isContentTypeJson ? '\nimport json' : ''}${isContentTypeFormUrlEncoded ? '\nfrom urllib import parse' : ''} + +requestUrl = '${requestUrl}' +headers = { + 'Content-Type': '${contentType}'${isPrevilegePrivate ? ',' : ''} +${isPrevilegePrivate ? authorizationHeader + '\n' : ''}} +${dataDesStr} + +response = requests.post(requestUrl, headers = headers, data = data) +print(response.status_code) +print(response.text)` +} + +function getParam(params, getEffectValue) { + const param = [] + params.forEach(item => { + const itemType = item.type + const itemName = `"${item.name}"` + // {"name":"id","type":"string","value":"1"} + // {"name":"ids","type":"Array","values":[{"va":"2"},{"va":"3"}]} + // {"name":"date","type":"date","value":"1970-01-01 00:00:00"} + // {"name":"dates","type":"Array","values":[{"va":"1970-01-01 00:00:00"},{"va":"1970-01-01 00:00:00"}]} + const value = getEffectValue(itemType, item.value) + const values = Array.isArray(item.values) ? item.values : [] + let elements = '' + switch (itemType) { + case DATA_TYPE.STRING: + param.push(`${itemName}: "${value}"`) + break + case DATA_TYPE.BIGINT: + param.push(`${itemName}: ${value}`) + break + case DATA_TYPE.DOUBLE: + param.push(`${itemName}: ${value}`) + break + case DATA_TYPE.DATE: + param.push(`${itemName}: "${value}"`) + break + case DATA_TYPE.ARRAY_STRING: + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join("\", \"") + } + param.push(`${itemName}: ["${elements}"]`) + break + case DATA_TYPE.ARRAY_BIGINT: + elements = '1' + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join(",") + } + param.push(`${itemName}: [${elements}]`) + break + case DATA_TYPE.ARRAY_DOUBLE: + elements = '1.0' + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join(",") + } + param.push(`${itemName}: [${elements}]`) + break + case DATA_TYPE.ARRAY_DATE: + elements = '1970-01-01 00:00:00' + if (values.length > 0) { + elements = values.map(el => getEffectValue(itemType, el.va)).join("\", \"") + } + param.push(`${itemName}: ["${elements}"]`) + break + default: + break + } + }) + return param +} \ No newline at end of file diff --git a/dbapi-ui/src/utils/code/shell/index.js b/dbapi-ui/src/utils/code/shell/index.js new file mode 100644 index 0000000000000000000000000000000000000000..79565a6302edad29df3bbfe8bc4ceb7d20a7511e --- /dev/null +++ b/dbapi-ui/src/utils/code/shell/index.js @@ -0,0 +1,114 @@ +/** + * application/json: + * curl -H 'Content-Type: application/json' \ + * -X POST \ + * --data-raw '{"id":1}' \ + * 'http://127.0.0.1:8520/api/test-json' + * + * application/x-www-form-urlencoded: + * curl -H 'Content-Type: application/x-www-form-urlencoded' \ + * -X POST \ + * --data-urlencode id=1 \ + * 'http://127.0.0.1:8520/api/test' + */ +import { DATA_TYPE, CONTENT_TYPE, PREVILEGE } from "@/constant"; + +export function generateShellCallExampleCode({ + lang, + address, requestUrl, + isContentTypeJson, isContentTypeFormUrlEncoded, contentType, + isPrevilegePrivate, isPrevilegePublic, token, + params, + detail, + getEffectValue +}) { + let realRequestStr = '' + if (isContentTypeFormUrlEncoded) { + const param = getParam(params, getEffectValue) + realRequestStr = `${param.join(' ')}` + } else if (isContentTypeJson) { + const requestStr = detail.jsonParam.replace(/\n|\r|\t/g, '').replace(/"/g, '\\"') + realRequestStr = `--data-raw '${requestStr}'` + } + let previlegeStr = '' + if (isPrevilegePrivate) { + previlegeStr = `-H 'Authorization: ${token}'` + } + + return `curl ${previlegeStr} -H 'Content-Type: ${contentType}' -X POST ${realRequestStr} '${requestUrl}'` +} + +function getParam(params, getEffectValue) { + const param = [] + params.forEach(item => { + const itemType = item.type + const itemName = item.name + // {"name":"id","type":"string","value":"1"} + // {"name":"ids","type":"Array","values":[{"va":"2"},{"va":"3"}]} + // {"name":"date","type":"date","value":"1970-01-01 00:00:00"} + // {"name":"dates","type":"Array","values":[{"va":"1970-01-01 00:00:00"},{"va":"1970-01-01 00:00:00"}]} + const value = getEffectValue(itemType, item.value) + const values = Array.isArray(item.values) ? item.values : [] + switch (itemType) { + case DATA_TYPE.STRING: + param.push(`--data-urlencode ${itemName}="${value}"`) + break + case DATA_TYPE.BIGINT: + param.push(`--data-urlencode ${itemName}=${value}`) + break + case DATA_TYPE.DOUBLE: + param.push(`--data-urlencode ${itemName}=${value}`) + break + case DATA_TYPE.DATE: + param.push(`--data-urlencode ${itemName}="${value}"`) + break + case DATA_TYPE.ARRAY_STRING: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`--data-urlencode ${itemName}="${effectValue}"`) + }) + } else { + param.push(`--data-urlencode ${itemName}=""`) + param.push(`--data-urlencode ${itemName}=""`) + } + break + case DATA_TYPE.ARRAY_BIGINT: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`--data-urlencode ${itemName}=${effectValue}`) + }) + } else { + param.push(`--data-urlencode ${itemName}=1`) + param.push(`--data-urlencode ${itemName}=2`) + } + break + case DATA_TYPE.ARRAY_DOUBLE: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`--data-urlencode ${itemName}=${effectValue}`) + }) + } else { + param.push(`--data-urlencode ${itemName}=1.0`) + param.push(`--data-urlencode ${itemName}=1.0`) + } + break + case DATA_TYPE.ARRAY_DATE: + if (values.length > 0) { + values.forEach(el => { + const effectValue = getEffectValue(itemType, el.va) + param.push(`--data-urlencode ${itemName}="${effectValue}"`) + }) + } else { + param.push(`--data-urlencode ${itemName}="1970-01-01 00:00:00"`) + param.push(`--data-urlencode ${itemName}="1970-01-02 00:00:00"`) + } + break + default: + break + } + }) + return param +} \ No newline at end of file diff --git a/dbapi-ui/src/utils/index.js b/dbapi-ui/src/utils/index.js new file mode 100644 index 0000000000000000000000000000000000000000..5bae8708092324995d578d1414a921f6e39c3314 --- /dev/null +++ b/dbapi-ui/src/utils/index.js @@ -0,0 +1 @@ +export * from './code' \ No newline at end of file diff --git a/dbapi-ui/src/views/Login.vue b/dbapi-ui/src/views/Login.vue index dae4682e91406ac5706f62d14b1ca104e411443e..4a69ee0b421e39f183f4bb10bfc42755ce94c613 100644 --- a/dbapi-ui/src/views/Login.vue +++ b/dbapi-ui/src/views/Login.vue @@ -5,13 +5,23 @@ DBAPI
- +
- +
-
{{$t('m.login')}}
+
{{$t('m.login')}}
@@ -23,49 +33,52 @@ export default { data() { return { username: null, - password: null - - } + password: null, + }; }, methods: { login() { - this.axios.post("/user/login", {username: this.username, password: this.password}).then((response) => { - if (response.data.success) { - localStorage.setItem("token", response.data.msg) - this.$router.push("/api") - } else { - this.$message.error(response.data.msg) - } - }).catch((error) => { - this.$message.error(error) - }) - } + this.axios + .post("/user/login", { + username: this.username, + password: this.password, + }) + .then((response) => { + if (response.data.success) { + localStorage.setItem("token", response.data.msg); + this.$router.push("/api"); + } else { + this.$message.error(response.data.msg); + } + }) + .catch((error) => { + this.$message.error(error); + }); + }, }, created() { //bind login event to enter key document.onkeydown = (e) => { const key = window.event.keyCode; if (key == 13 || key == 100) { - this.login() + this.login(); } - } + }; }, destroyed() { //unbind login event to enter key when go to other pages - document.onkeydown = null - } -} + document.onkeydown = null; + }, +};