w-web-api 1.0.22 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +18 -17
- package/.github/workflows/ci-test.yml +24 -0
- package/.vscode/launch.json +21 -0
- package/README.md +21 -4
- package/babel.config.js +1 -0
- package/dist/css/{chunk-vendors.b4caa718.css → chunk-vendors.ca61ed63.css} +1 -1
- package/dist/img/connecting.26511805.svg +10 -0
- package/dist/img/deny.e7b81b94.png +0 -0
- package/dist/index.tmp +1 -1
- package/dist/js/app-legacy.8589a7d0.js +2 -0
- package/dist/js/app-legacy.8589a7d0.js.map +1 -0
- package/dist/js/app.8589a7d0.js +2 -0
- package/dist/js/app.8589a7d0.js.map +1 -0
- package/dist/js/chunk-vendors-legacy.4a6f42ee.js +14 -0
- package/dist/js/chunk-vendors-legacy.4a6f42ee.js.map +1 -0
- package/dist/js/chunk-vendors.4a6f42ee.js +14 -0
- package/dist/js/chunk-vendors.4a6f42ee.js.map +1 -0
- package/dist/w-web-api.umd.js +2 -2
- package/dist/w-web-api.umd.js.map +1 -1
- package/docs/WWebApi.html +111 -23
- package/docs/WWebApi.mjs.html +152 -30
- package/docs/index.html +4 -1
- package/docs/scripts/collapse.js +19 -0
- package/docs/scripts/commonNav.js +28 -0
- package/docs/scripts/search.js +16 -0
- package/docs/styles/jsdoc.css +13 -2
- package/docs/styles/prettify.css +1 -0
- package/g.getSettings.mjs +1 -1
- package/package.json +24 -24
- package/server/WWebApi.mjs +148 -29
- package/src/App.vue +63 -5
- package/src/components/Layout.vue +1 -0
- package/src/components/LayoutState.vue +87 -0
- package/src/main.js +5 -2
- package/src/plugins/mUI.mjs +12 -0
- package/src/store/mutations.mjs +13 -6
- package/srv.mjs +21 -2
- package/tableTags-web-api.json +1 -1
- package/test/all.test.mjs +10 -0
- package/dist/js/app.32beae37.js +0 -2
- package/dist/js/app.32beae37.js.map +0 -1
- package/dist/js/chunk-vendors.69cb98c3.js +0 -24
- package/dist/js/chunk-vendors.69cb98c3.js.map +0 -1
- /package/dist/css/{app.5b03c2b6.css → app.e645631b.css} +0 -0
package/docs/scripts/collapse.js
CHANGED
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
function hideAllButCurrent(){
|
|
2
2
|
//by default all submenut items are hidden
|
|
3
3
|
//but we need to rehide them for search
|
|
4
|
+
document.querySelectorAll("nav > ul").forEach(function(parent) {
|
|
5
|
+
if (parent.className.indexOf("collapse_top") !== -1) {
|
|
6
|
+
parent.style.display = "none";
|
|
7
|
+
}
|
|
8
|
+
});
|
|
4
9
|
document.querySelectorAll("nav > ul > li > ul li").forEach(function(parent) {
|
|
5
10
|
parent.style.display = "none";
|
|
6
11
|
});
|
|
12
|
+
document.querySelectorAll("nav > h3").forEach(function(section) {
|
|
13
|
+
if (section.className.indexOf("collapsed_header") !== -1) {
|
|
14
|
+
section.addEventListener("click", function(){
|
|
15
|
+
if (section.nextSibling.style.display === "none") {
|
|
16
|
+
section.nextSibling.style.display = "block";
|
|
17
|
+
} else {
|
|
18
|
+
section.nextSibling.style.display = "none";
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
7
23
|
|
|
8
24
|
//only current page (if it exists) should be opened
|
|
9
25
|
var file = window.location.pathname.split("/").pop().replace(/\.html/, '');
|
|
10
26
|
document.querySelectorAll("nav > ul > li > a").forEach(function(parent) {
|
|
11
27
|
var href = parent.attributes.href.value.replace(/\.html/, '');
|
|
12
28
|
if (file === href) {
|
|
29
|
+
if (parent.parentNode.parentNode.className.indexOf("collapse_top") !== -1) {
|
|
30
|
+
parent.parentNode.parentNode.style.display = "block";
|
|
31
|
+
}
|
|
13
32
|
parent.parentNode.querySelectorAll("ul li").forEach(function(elem) {
|
|
14
33
|
elem.style.display = "block";
|
|
15
34
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
if (typeof fetch === 'function') {
|
|
2
|
+
const init = () => {
|
|
3
|
+
if (typeof scrollToNavItem !== 'function') return false
|
|
4
|
+
scrollToNavItem()
|
|
5
|
+
// hideAllButCurrent not always loaded
|
|
6
|
+
if (typeof hideAllButCurrent === 'function') hideAllButCurrent()
|
|
7
|
+
return true
|
|
8
|
+
}
|
|
9
|
+
fetch('./nav.inc.html')
|
|
10
|
+
.then(response => response.ok ? response.text() : `${response.url} => ${response.status} ${response.statusText}`)
|
|
11
|
+
.then(body => {
|
|
12
|
+
document.querySelector('nav').innerHTML += body
|
|
13
|
+
// nav.js should be quicker to load than nav.inc.html, a fallback just in case
|
|
14
|
+
return init()
|
|
15
|
+
})
|
|
16
|
+
.then(done => {
|
|
17
|
+
if (done) return
|
|
18
|
+
let i = 0
|
|
19
|
+
;(function waitUntilNavJs () {
|
|
20
|
+
if (init()) return
|
|
21
|
+
if (i++ < 100) return setTimeout(waitUntilNavJs, 300)
|
|
22
|
+
console.error(Error('nav.js not loaded after 30s waiting for it'))
|
|
23
|
+
})()
|
|
24
|
+
})
|
|
25
|
+
.catch(error => console.error(error))
|
|
26
|
+
} else {
|
|
27
|
+
console.error(Error('Browser too old to display commonNav (remove commonNav docdash option)'))
|
|
28
|
+
}
|
package/docs/scripts/search.js
CHANGED
|
@@ -33,6 +33,9 @@ document.getElementById("nav-search").addEventListener("keyup", function(event)
|
|
|
33
33
|
document.querySelectorAll("nav > ul > li").forEach(function(elem) {
|
|
34
34
|
elem.style.display = "block";
|
|
35
35
|
});
|
|
36
|
+
document.querySelectorAll("nav > ul").forEach(function(elem) {
|
|
37
|
+
elem.style.display = "block";
|
|
38
|
+
});
|
|
36
39
|
//hide all results
|
|
37
40
|
document.querySelectorAll("nav > ul > li > ul li").forEach(function(elem) {
|
|
38
41
|
elem.style.display = "none";
|
|
@@ -79,5 +82,18 @@ document.getElementById("nav-search").addEventListener("keyup", function(event)
|
|
|
79
82
|
parent.style.display = "none";
|
|
80
83
|
}
|
|
81
84
|
});
|
|
85
|
+
document.querySelectorAll("nav > ul.collapse_top").forEach(function(parent) {
|
|
86
|
+
var countVisible = 0;
|
|
87
|
+
parent.querySelectorAll("li").forEach(function(elem) {
|
|
88
|
+
if (elem.style.display !== "none") {
|
|
89
|
+
countVisible++;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (countVisible == 0) {
|
|
94
|
+
//has no child at all and does not contain text
|
|
95
|
+
parent.style.display = "none";
|
|
96
|
+
}
|
|
97
|
+
});
|
|
82
98
|
}
|
|
83
99
|
});
|
package/docs/styles/jsdoc.css
CHANGED
|
@@ -162,12 +162,19 @@ h6 {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
tt, code, kbd, samp {
|
|
165
|
+
tt, code, kbd, samp, pre {
|
|
166
166
|
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
|
167
167
|
background: #f4f4f4;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
tt, code, kbd, samp{
|
|
168
171
|
padding: 1px 5px;
|
|
169
172
|
}
|
|
170
173
|
|
|
174
|
+
pre {
|
|
175
|
+
padding-bottom: 1em;
|
|
176
|
+
}
|
|
177
|
+
|
|
171
178
|
.class-description {
|
|
172
179
|
font-size: 130%;
|
|
173
180
|
line-height: 140%;
|
|
@@ -242,6 +249,10 @@ nav h3 {
|
|
|
242
249
|
color: #000;
|
|
243
250
|
}
|
|
244
251
|
|
|
252
|
+
nav h3.collapsed_header {
|
|
253
|
+
cursor: pointer;
|
|
254
|
+
}
|
|
255
|
+
|
|
245
256
|
nav ul {
|
|
246
257
|
font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
|
|
247
258
|
font-size: 100%;
|
|
@@ -762,4 +773,4 @@ html[data-search-mode] .level-hide {
|
|
|
762
773
|
font-weight: 300;
|
|
763
774
|
font-style: normal;
|
|
764
775
|
|
|
765
|
-
}
|
|
776
|
+
}
|
package/docs/styles/prettify.css
CHANGED
package/g.getSettings.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-web-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
4
4
|
"main": "dist/w-web-api.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@mdi/js": "^7.
|
|
7
|
-
"axios": "^1.
|
|
6
|
+
"@mdi/js": "^7.2.96",
|
|
7
|
+
"axios": "^1.3.4",
|
|
8
8
|
"lodash": "^4.17.21",
|
|
9
9
|
"showdown": "^2.1.0",
|
|
10
|
-
"w-component-vue": "^2.
|
|
11
|
-
"w-data-collector": "^1.0.
|
|
12
|
-
"w-serv-hapi": "^1.0.
|
|
13
|
-
"w-serv-orm": "^1.0.
|
|
14
|
-
"
|
|
10
|
+
"w-component-vue": "^2.3.0",
|
|
11
|
+
"w-data-collector": "^1.0.19",
|
|
12
|
+
"w-serv-hapi": "^1.0.11",
|
|
13
|
+
"w-serv-orm": "^1.0.7",
|
|
14
|
+
"w-ui-loginout": "^1.0.1",
|
|
15
|
+
"wsemi": "^1.7.12"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
|
-
"@vue/cli-plugin-babel": "^
|
|
18
|
-
"@vue/cli-plugin-eslint": "^
|
|
19
|
-
"@vue/cli-service": "^
|
|
20
|
-
"eslint": "^
|
|
21
|
-
"eslint-config-standard": "^
|
|
18
|
+
"@vue/cli-plugin-babel": "^5.0.8",
|
|
19
|
+
"@vue/cli-plugin-eslint": "^5.0.8",
|
|
20
|
+
"@vue/cli-service": "^5.0.8",
|
|
21
|
+
"eslint": "^8.37.0",
|
|
22
|
+
"eslint-config-standard": "^17.0.0",
|
|
22
23
|
"eslint-friendly-formatter": "^4.0.1",
|
|
23
|
-
"eslint-
|
|
24
|
-
"eslint-plugin-import": "^2.22.1",
|
|
24
|
+
"eslint-plugin-import": "^2.27.5",
|
|
25
25
|
"eslint-plugin-node": "^11.1.0",
|
|
26
|
-
"eslint-plugin-promise": "^
|
|
26
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
27
27
|
"eslint-plugin-standard": "^4.1.0",
|
|
28
|
-
"eslint-plugin-vue": "^
|
|
29
|
-
"sass": "^1.
|
|
30
|
-
"sass-loader": "^
|
|
28
|
+
"eslint-plugin-vue": "^9.10.0",
|
|
29
|
+
"sass": "^1.60.0",
|
|
30
|
+
"sass-loader": "^13.2.2",
|
|
31
31
|
"vue": "^2.6.14",
|
|
32
|
-
"vue-cli-plugin-vuetify": "^2.
|
|
33
|
-
"vuetify": "^2.6.
|
|
34
|
-
"vuetify-loader": "^1.
|
|
32
|
+
"vue-cli-plugin-vuetify": "^2.5.8",
|
|
33
|
+
"vuetify": "^2.6.14",
|
|
34
|
+
"vuetify-loader": "^1.9.2",
|
|
35
35
|
"vuex": "^3.6.2",
|
|
36
|
-
"w-orm-mongodb": "^1.1.
|
|
37
|
-
"w-package-tools": "^1.0.
|
|
36
|
+
"w-orm-mongodb": "^1.1.29",
|
|
37
|
+
"w-package-tools": "^1.0.69"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"serve": "vue-cli-service serve",
|
package/server/WWebApi.mjs
CHANGED
|
@@ -10,17 +10,19 @@ import iseobj from 'wsemi/src/iseobj.mjs'
|
|
|
10
10
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
11
11
|
import ispint from 'wsemi/src/ispint.mjs'
|
|
12
12
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
13
|
+
import ispm from 'wsemi/src/ispm.mjs'
|
|
13
14
|
import cint from 'wsemi/src/cint.mjs'
|
|
14
15
|
import strleft from 'wsemi/src/strleft.mjs'
|
|
15
16
|
import strdelleft from 'wsemi/src/strdelleft.mjs'
|
|
16
17
|
import strright from 'wsemi/src/strright.mjs'
|
|
17
18
|
import strdelright from 'wsemi/src/strdelright.mjs'
|
|
19
|
+
import pm2resolve from 'wsemi/src/pm2resolve.mjs'
|
|
18
20
|
import b642str from 'wsemi/src/b642str.mjs'
|
|
19
21
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
20
22
|
import replace from 'wsemi/src/replace.mjs'
|
|
21
23
|
import WServHapiServer from 'w-serv-hapi/src/WServHapiServer.mjs'
|
|
22
|
-
import ds from '../src/schema/index.mjs'
|
|
23
24
|
import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
25
|
+
import ds from '../src/schema/index.mjs'
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
/**
|
|
@@ -30,11 +32,13 @@ import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
|
30
32
|
* @param {Function} WOrm 輸入資料庫ORM函數
|
|
31
33
|
* @param {String} url 輸入資料庫連線字串,例如'mongodb://sername:password@$127.0.0.1:27017'
|
|
32
34
|
* @param {String} db 輸入資料庫名稱字串
|
|
35
|
+
* @param {Function} getUserByToken 輸入處理函數,函數會傳入使用者token,通過此函數處理後並回傳使用者資訊物件,並至少須提供'id'、'email'、'name'、'isAdmin'欄位,且'isAdmin'限輸入'y'或'n',且輸入'y'時會複寫權限系統該使用者之'isAdmin'欄位值
|
|
36
|
+
* @param {Function} verifyUser 輸入處理函數,函數會傳入使用者資訊物件,通過此函數識別後回傳布林值,允許使用者回傳true,反之回傳false
|
|
33
37
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
34
38
|
* @param {Integer} [opt.serverPort=11005] 輸入伺服器通訊port,預設11005
|
|
39
|
+
* @param {Boolean} [opt.bCheckUser=false] 輸入是否檢查使用者資訊布林值,預設false
|
|
35
40
|
* @param {Function} [opt.getUserById=null] 輸入當bCheckUser=true時依照使用者ID取得使用者資訊物件函數,預設null
|
|
36
|
-
* @param {Boolean} [opt.
|
|
37
|
-
* @param {Boolean} [opt.bExcludeWhenNotAdmin=true] 輸入使用ORM的select方法時是否自動刪除數據內isActive欄位之布林值,預設true
|
|
41
|
+
* @param {Boolean} [opt.bExcludeWhenNotAdmin=false] 輸入使用ORM的select方法時是否自動刪除數據內isActive欄位之布林值,預設false
|
|
38
42
|
* @param {Object} [opt.webName={}] 輸入站台名稱物件,至少包含語系eng與cht鍵的名稱,預設{}
|
|
39
43
|
* @param {Object} [opt.webDescription={}] 輸入站台描述物件,至少包含語系eng與cht鍵的名稱,預設{}
|
|
40
44
|
* @param {String} [opt.webLogo=''] 輸入站台logo字串,採base64格式,預設''
|
|
@@ -75,7 +79,7 @@ import WServOrm from 'w-serv-orm/src/WServOrm.mjs'
|
|
|
75
79
|
* })
|
|
76
80
|
*
|
|
77
81
|
*/
|
|
78
|
-
function WWebApi(WOrm, url, db, opt = {}) {
|
|
82
|
+
function WWebApi(WOrm, url, db, getUserByToken, verifyUser, opt = {}) {
|
|
79
83
|
let instWServHapiServer = null
|
|
80
84
|
|
|
81
85
|
|
|
@@ -100,6 +104,20 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
|
|
107
|
+
//check getUserByToken
|
|
108
|
+
if (!isfun(getUserByToken)) {
|
|
109
|
+
console.log('invalid getUserByToken', getUserByToken)
|
|
110
|
+
throw new Error('invalid getUserByToken')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
//check verifyUser
|
|
115
|
+
if (!isfun(verifyUser)) {
|
|
116
|
+
console.log('invalid verifyUser', verifyUser)
|
|
117
|
+
throw new Error('invalid verifyUser')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
103
121
|
//serverPort
|
|
104
122
|
let serverPort = get(opt, 'serverPort')
|
|
105
123
|
if (!ispint(serverPort)) {
|
|
@@ -170,9 +188,35 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
170
188
|
}
|
|
171
189
|
|
|
172
190
|
|
|
191
|
+
//verifyUserByToken
|
|
192
|
+
let verifyUserByToken = async (token) => {
|
|
193
|
+
|
|
194
|
+
//getUserByToken
|
|
195
|
+
let user = getUserByToken(token)
|
|
196
|
+
if (ispm(user)) {
|
|
197
|
+
user = await user
|
|
198
|
+
}
|
|
199
|
+
if (!iseobj(user)) {
|
|
200
|
+
return Promise.reject(`token does not have permission`)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//verifyUser
|
|
204
|
+
let b = verifyUser(user)
|
|
205
|
+
if (ispm(b)) {
|
|
206
|
+
b = await b
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
//check
|
|
210
|
+
if (!b) {
|
|
211
|
+
return Promise.reject(`user does not have permission`)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return user
|
|
215
|
+
}
|
|
216
|
+
|
|
173
217
|
//getAPIsList
|
|
174
|
-
let getAPIsList = async (
|
|
175
|
-
let rs = await woItems.apis.select()
|
|
218
|
+
let getAPIsList = async (query = {}) => {
|
|
219
|
+
let rs = await woItems.apis.select(query)
|
|
176
220
|
return rs
|
|
177
221
|
}
|
|
178
222
|
|
|
@@ -222,7 +266,7 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
222
266
|
|
|
223
267
|
|
|
224
268
|
//updateAPIs
|
|
225
|
-
let updateAPIs = async (
|
|
269
|
+
let updateAPIs = async (params = {}) => {
|
|
226
270
|
|
|
227
271
|
//spread params
|
|
228
272
|
let { apis: rsApis } = params
|
|
@@ -237,7 +281,7 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
237
281
|
|
|
238
282
|
|
|
239
283
|
//replaceAPIsByLevels
|
|
240
|
-
let replaceAPIsByLevels = async (
|
|
284
|
+
let replaceAPIsByLevels = async (params = {}) => {
|
|
241
285
|
|
|
242
286
|
//spread params
|
|
243
287
|
let { group, apis: rsApis } = params
|
|
@@ -266,11 +310,17 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
266
310
|
//subfolder
|
|
267
311
|
let fnEntryIn = 'index.tmp'
|
|
268
312
|
let fnEntryOut = 'index.html'
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
313
|
+
try {
|
|
314
|
+
let fpEntryIn = path.resolve(pathStaticFiles, fnEntryIn)
|
|
315
|
+
let fpEntryOut = path.resolve(pathStaticFiles, fnEntryOut)
|
|
316
|
+
let c = fs.readFileSync(fpEntryIn, 'utf8')
|
|
317
|
+
c = replace(c, '{sfd}', subfolder)
|
|
318
|
+
fs.writeFileSync(fpEntryOut, c, 'utf8')
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
console.log(err)
|
|
322
|
+
console.log(`can not generate ${fnEntryOut}`)
|
|
323
|
+
}
|
|
274
324
|
|
|
275
325
|
|
|
276
326
|
//apis
|
|
@@ -293,16 +343,53 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
293
343
|
return getWebInfor()
|
|
294
344
|
},
|
|
295
345
|
},
|
|
346
|
+
{
|
|
347
|
+
method: 'GET',
|
|
348
|
+
path: '/api/getUserByToken', //未登入界面需先檢測token是否為系統管理員, 確認後回傳為系統管理員資訊物件
|
|
349
|
+
handler: async function (req, res) {
|
|
350
|
+
// console.log('getUserByToken', req)
|
|
351
|
+
|
|
352
|
+
async function core() {
|
|
353
|
+
|
|
354
|
+
//token
|
|
355
|
+
let token = get(req, 'query.token', '')
|
|
356
|
+
|
|
357
|
+
//verifyUserByToken
|
|
358
|
+
let user = await verifyUserByToken(token)
|
|
359
|
+
|
|
360
|
+
return user
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
//pm2resolve core
|
|
364
|
+
let r = await pm2resolve(core)()
|
|
365
|
+
// console.log('verifyIdentity', r)
|
|
366
|
+
|
|
367
|
+
return r
|
|
368
|
+
},
|
|
369
|
+
},
|
|
296
370
|
{
|
|
297
371
|
method: 'GET',
|
|
298
372
|
path: '/getAPIsList',
|
|
299
373
|
handler: async function (req, res) {
|
|
374
|
+
// console.log('getAPIsList', req)
|
|
375
|
+
|
|
376
|
+
async function core() {
|
|
377
|
+
|
|
378
|
+
//token
|
|
379
|
+
let token = get(req, 'query.token', '')
|
|
380
|
+
|
|
381
|
+
//verifyUserByToken
|
|
382
|
+
await verifyUserByToken(token)
|
|
300
383
|
|
|
301
|
-
|
|
302
|
-
|
|
384
|
+
//getAPIsList
|
|
385
|
+
let r = await getAPIsList({ isActive: 'y' })
|
|
303
386
|
|
|
304
|
-
|
|
305
|
-
|
|
387
|
+
return r
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
//pm2resolve core
|
|
391
|
+
let r = await pm2resolve(core)()
|
|
392
|
+
// console.log('verifyIdentity', r)
|
|
306
393
|
|
|
307
394
|
return r
|
|
308
395
|
},
|
|
@@ -311,14 +398,29 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
311
398
|
method: 'POST',
|
|
312
399
|
path: '/updateAPIs',
|
|
313
400
|
handler: async function (req, res) {
|
|
314
|
-
// console.log(
|
|
401
|
+
// console.log('updateAPIs', req)
|
|
315
402
|
// console.log('payload', req.payload)
|
|
316
403
|
|
|
317
|
-
|
|
318
|
-
|
|
404
|
+
async function core() {
|
|
405
|
+
|
|
406
|
+
//token
|
|
407
|
+
let token = get(req, 'query.token', '')
|
|
408
|
+
|
|
409
|
+
//verifyUserByToken
|
|
410
|
+
await verifyUserByToken(token)
|
|
411
|
+
|
|
412
|
+
//parsePayload
|
|
413
|
+
let inp = parsePayload(req)
|
|
414
|
+
|
|
415
|
+
//updateAPIs
|
|
416
|
+
let r = await updateAPIs(inp)
|
|
417
|
+
|
|
418
|
+
return r
|
|
419
|
+
}
|
|
319
420
|
|
|
320
|
-
//
|
|
321
|
-
let r = await
|
|
421
|
+
//pm2resolve core
|
|
422
|
+
let r = await pm2resolve(core)()
|
|
423
|
+
// console.log('verifyIdentity', r)
|
|
322
424
|
|
|
323
425
|
return r
|
|
324
426
|
},
|
|
@@ -327,14 +429,29 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
327
429
|
method: 'POST',
|
|
328
430
|
path: '/replaceAPIsByLevels',
|
|
329
431
|
handler: async function (req, res) {
|
|
330
|
-
// console.log(
|
|
432
|
+
// console.log('replaceAPIsByLevels', req)
|
|
331
433
|
// console.log('payload', req.payload)
|
|
332
434
|
|
|
333
|
-
|
|
334
|
-
let inp = parsePayload(req)
|
|
435
|
+
async function core() {
|
|
335
436
|
|
|
336
|
-
|
|
337
|
-
|
|
437
|
+
//token
|
|
438
|
+
let token = get(req, 'query.token', '')
|
|
439
|
+
|
|
440
|
+
//verifyUserByToken
|
|
441
|
+
await verifyUserByToken(token)
|
|
442
|
+
|
|
443
|
+
//parsePayload
|
|
444
|
+
let inp = parsePayload(req)
|
|
445
|
+
|
|
446
|
+
//replaceAPIsByLevels
|
|
447
|
+
let r = await replaceAPIsByLevels(inp)
|
|
448
|
+
|
|
449
|
+
return r
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
//pm2resolve core
|
|
453
|
+
let r = await pm2resolve(core)()
|
|
454
|
+
// console.log('verifyIdentity', r)
|
|
338
455
|
|
|
339
456
|
return r
|
|
340
457
|
},
|
|
@@ -356,7 +473,7 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
356
473
|
pathStaticFiles,
|
|
357
474
|
apis,
|
|
358
475
|
getUserIDFromToken: async (token) => { //可使用async或sync函數
|
|
359
|
-
return '
|
|
476
|
+
return ''
|
|
360
477
|
},
|
|
361
478
|
useDbORM: true,
|
|
362
479
|
dbORMs: woItems,
|
|
@@ -366,7 +483,9 @@ function WWebApi(WOrm, url, db, opt = {}) {
|
|
|
366
483
|
tableNamesSync,
|
|
367
484
|
extFuncs: { //接收參數第1個為userId, 之後才是前端給予參數
|
|
368
485
|
getWebInfor,
|
|
369
|
-
getAPIsList,
|
|
486
|
+
getAPIsList: (userId, query = {}) => {
|
|
487
|
+
return getAPIsList(query)
|
|
488
|
+
},
|
|
370
489
|
//...
|
|
371
490
|
},
|
|
372
491
|
hookBefores: null,
|
package/src/App.vue
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
@domresize="resize"
|
|
5
5
|
>
|
|
6
6
|
|
|
7
|
+
<LayoutState :style="`opacity:${ready?0:1};`" v-if="!ready"></LayoutState>
|
|
8
|
+
|
|
7
9
|
<transition enter-active-class="fade-enter-active" leave-active-class="fade-leave-active">
|
|
8
10
|
<Layout v-if="ready"></Layout>
|
|
9
11
|
</transition>
|
|
@@ -12,30 +14,86 @@
|
|
|
12
14
|
</template>
|
|
13
15
|
|
|
14
16
|
<script>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
import get from 'lodash/get'
|
|
18
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
19
|
+
import wui from 'w-ui-loginout/src/WUiLoginout.mjs'
|
|
17
20
|
import Layout from './components/Layout.vue'
|
|
21
|
+
import LayoutState from './components/LayoutState.vue'
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
export default {
|
|
21
25
|
components: {
|
|
22
26
|
Layout,
|
|
27
|
+
LayoutState,
|
|
23
28
|
},
|
|
24
29
|
data: function() {
|
|
25
30
|
return {
|
|
26
31
|
|
|
27
|
-
ready: true,
|
|
32
|
+
// ready: true,
|
|
33
|
+
msg: '',
|
|
34
|
+
|
|
35
|
+
ll: null,
|
|
28
36
|
|
|
29
37
|
}
|
|
30
38
|
},
|
|
31
|
-
|
|
32
|
-
// console.log('
|
|
39
|
+
beforeMount: function() {
|
|
40
|
+
// console.log('methods beforeMount')
|
|
33
41
|
|
|
34
42
|
let vo = this
|
|
35
43
|
|
|
36
44
|
//setVo, 更換ui內vo, 才能使用廣播技術, 更換語系才能用廣播通知全部組件forceUpdate
|
|
37
45
|
vo.$ui.setVo(vo)
|
|
38
46
|
|
|
47
|
+
function afterGetUser(u) {
|
|
48
|
+
// console.log('afterGetUser', u)
|
|
49
|
+
|
|
50
|
+
//isAdmin
|
|
51
|
+
let isAdmin = get(u, 'isAdmin', 'n')
|
|
52
|
+
|
|
53
|
+
//check
|
|
54
|
+
if (isAdmin !== 'y') {
|
|
55
|
+
let errTemp = {
|
|
56
|
+
text: '非系統管理員',
|
|
57
|
+
msg: 'user is not an administrator',
|
|
58
|
+
}
|
|
59
|
+
return Promise.reject(errTemp)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function loginSuccess(data) {
|
|
65
|
+
console.log('login success', cloneDeep(data.user))
|
|
66
|
+
vo.$ui.updateConnState('已連線')
|
|
67
|
+
vo.$ui.updateUserToken(data.token)
|
|
68
|
+
vo.$ui.updateUserSelf(data.user)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function loginError(data) {
|
|
72
|
+
console.log('login error', cloneDeep(data))
|
|
73
|
+
vo.$ui.updateConnState(data.text)
|
|
74
|
+
vo.$ui.updateUserToken('')
|
|
75
|
+
vo.$ui.updateUserSelf(get(vo, `$store.state.userDef`))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//login
|
|
79
|
+
console.log('login...')
|
|
80
|
+
let ll = wui('wperm')
|
|
81
|
+
ll.login({
|
|
82
|
+
afterGetUser,
|
|
83
|
+
afterLogin: null,
|
|
84
|
+
loginSuccess,
|
|
85
|
+
loginError,
|
|
86
|
+
})
|
|
87
|
+
vo.ll = ll
|
|
88
|
+
|
|
89
|
+
},
|
|
90
|
+
computed: {
|
|
91
|
+
|
|
92
|
+
ready: function() {
|
|
93
|
+
let connState = get(this, `$store.state.connState`)
|
|
94
|
+
return connState === '已連線'
|
|
95
|
+
},
|
|
96
|
+
|
|
39
97
|
},
|
|
40
98
|
methods: {
|
|
41
99
|
|