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.
Files changed (44) hide show
  1. package/.eslintrc.js +18 -17
  2. package/.github/workflows/ci-test.yml +24 -0
  3. package/.vscode/launch.json +21 -0
  4. package/README.md +21 -4
  5. package/babel.config.js +1 -0
  6. package/dist/css/{chunk-vendors.b4caa718.css → chunk-vendors.ca61ed63.css} +1 -1
  7. package/dist/img/connecting.26511805.svg +10 -0
  8. package/dist/img/deny.e7b81b94.png +0 -0
  9. package/dist/index.tmp +1 -1
  10. package/dist/js/app-legacy.8589a7d0.js +2 -0
  11. package/dist/js/app-legacy.8589a7d0.js.map +1 -0
  12. package/dist/js/app.8589a7d0.js +2 -0
  13. package/dist/js/app.8589a7d0.js.map +1 -0
  14. package/dist/js/chunk-vendors-legacy.4a6f42ee.js +14 -0
  15. package/dist/js/chunk-vendors-legacy.4a6f42ee.js.map +1 -0
  16. package/dist/js/chunk-vendors.4a6f42ee.js +14 -0
  17. package/dist/js/chunk-vendors.4a6f42ee.js.map +1 -0
  18. package/dist/w-web-api.umd.js +2 -2
  19. package/dist/w-web-api.umd.js.map +1 -1
  20. package/docs/WWebApi.html +111 -23
  21. package/docs/WWebApi.mjs.html +152 -30
  22. package/docs/index.html +4 -1
  23. package/docs/scripts/collapse.js +19 -0
  24. package/docs/scripts/commonNav.js +28 -0
  25. package/docs/scripts/search.js +16 -0
  26. package/docs/styles/jsdoc.css +13 -2
  27. package/docs/styles/prettify.css +1 -0
  28. package/g.getSettings.mjs +1 -1
  29. package/package.json +24 -24
  30. package/server/WWebApi.mjs +148 -29
  31. package/src/App.vue +63 -5
  32. package/src/components/Layout.vue +1 -0
  33. package/src/components/LayoutState.vue +87 -0
  34. package/src/main.js +5 -2
  35. package/src/plugins/mUI.mjs +12 -0
  36. package/src/store/mutations.mjs +13 -6
  37. package/srv.mjs +21 -2
  38. package/tableTags-web-api.json +1 -1
  39. package/test/all.test.mjs +10 -0
  40. package/dist/js/app.32beae37.js +0 -2
  41. package/dist/js/app.32beae37.js.map +0 -1
  42. package/dist/js/chunk-vendors.69cb98c3.js +0 -24
  43. package/dist/js/chunk-vendors.69cb98c3.js.map +0 -1
  44. /package/dist/css/{app.5b03c2b6.css → app.e645631b.css} +0 -0
@@ -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
+ }
@@ -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
  });
@@ -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
+ }
@@ -76,4 +76,5 @@
76
76
  ol.linenums {
77
77
  margin-top: 0;
78
78
  margin-bottom: 0;
79
+ padding-bottom: 2px;
79
80
  }
package/g.getSettings.mjs CHANGED
@@ -8,7 +8,7 @@ function getSettings() {
8
8
  'dbUsername': 'username',
9
9
  'dbPassword': 'password',
10
10
  'dbName': 'wapis',
11
- 'dbIP': 'localhost',
11
+ 'dbIP': '127.0.0.1',
12
12
  'dbPort': 27017,
13
13
  }
14
14
  }
package/package.json CHANGED
@@ -1,40 +1,40 @@
1
1
  {
2
2
  "name": "w-web-api",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "main": "dist/w-web-api.umd.js",
5
5
  "dependencies": {
6
- "@mdi/js": "^7.1.96",
7
- "axios": "^1.2.3",
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.2.64",
11
- "w-data-collector": "^1.0.15",
12
- "w-serv-hapi": "^1.0.10",
13
- "w-serv-orm": "^1.0.4",
14
- "wsemi": "^1.6.89"
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": "^4.5.13",
18
- "@vue/cli-plugin-eslint": "^4.5.13",
19
- "@vue/cli-service": "^4.5.13",
20
- "eslint": "^7.26.0",
21
- "eslint-config-standard": "^16.0.2",
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-loader": "^4.0.2",
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": "^5.1.0",
26
+ "eslint-plugin-promise": "^6.1.1",
27
27
  "eslint-plugin-standard": "^4.1.0",
28
- "eslint-plugin-vue": "^7.9.0",
29
- "sass": "^1.34.0",
30
- "sass-loader": "^10.1.1",
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.4.8",
33
- "vuetify": "^2.6.4",
34
- "vuetify-loader": "^1.7.3",
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.27",
37
- "w-package-tools": "^1.0.66"
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",
@@ -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.bCheckUser=true] 輸入是否檢查使用者資訊布林值,預設true
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 (userId, token) => {
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 (userId, params = {}) => {
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 (userId, params = {}) => {
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
- let fpEntryIn = path.resolve(pathStaticFiles, fnEntryIn)
270
- let fpEntryOut = path.resolve(pathStaticFiles, fnEntryOut)
271
- let c = fs.readFileSync(fpEntryIn, 'utf8')
272
- c = replace(c, '{sfd}', subfolder)
273
- fs.writeFileSync(fpEntryOut, c, 'utf8')
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
- //token
302
- let token = get(req, 'query.token', '')
384
+ //getAPIsList
385
+ let r = await getAPIsList({ isActive: 'y' })
303
386
 
304
- //getAPIsList
305
- let r = await getAPIsList('', token)
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(req, res)
401
+ // console.log('updateAPIs', req)
315
402
  // console.log('payload', req.payload)
316
403
 
317
- //parsePayload
318
- let inp = parsePayload(req)
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
- //updateAPIs
321
- let r = await updateAPIs('', inp)
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(req, res)
432
+ // console.log('replaceAPIsByLevels', req)
331
433
  // console.log('payload', req.payload)
332
434
 
333
- //parsePayload
334
- let inp = parsePayload(req)
435
+ async function core() {
335
436
 
336
- //replaceAPIsByLevels
337
- let r = await replaceAPIsByLevels('', inp)
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 'id-for-admin'
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
- // import get from 'lodash/get'
16
- // import find from 'lodash/find'
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
- mounted: function() {
32
- // console.log('mounted')
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
 
@@ -31,6 +31,7 @@
31
31
 
32
32
  <div style="padding-right:10px; white-space:nowrap">
33
33
  <WTextSelect
34
+ style="width:100px;"
34
35
  :items="tgLangs"
35
36
  v-model="tgLangSelect"
36
37
  @input="changeLang"