w-web-api 1.0.53 → 1.0.55
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/README.md +1 -1
- package/dist/css/{app.fe69497a.css → app.cad4a1ca.css} +1 -1
- package/dist/index.tmp +1 -1
- package/dist/js/app-legacy.7687b23b.js +1 -0
- package/dist/js/app.7687b23b.js +1 -0
- package/dist/js/chunk-vendors-legacy.4c27cf51.js +15 -0
- package/dist/js/chunk-vendors.4c27cf51.js +15 -0
- package/dist/w-web-api.umd.js +2 -2
- package/dist/w-web-api.umd.js.map +1 -1
- package/docs/WWebApi.html +1 -1
- package/docs/index.html +1 -1
- package/docs/server_WWebApi.mjs.html +24 -34
- package/docs/src_components_Common_CheckYesNo.vue.html +1 -1
- package/logs/2026-06-19T16.log +6 -0
- package/logs/2026-06-20T11.log +4 -0
- package/logs/2026-06-20T14.log +2 -0
- package/logs/2026-06-21T20.log +1 -0
- package/logs/2026-06-21T21.log +4 -0
- package/logs/2026-06-22T07.log +12 -0
- package/logs/2026-06-22T08.log +808 -0
- package/logs/2026-06-22T09.log +104 -0
- package/logs/2026-06-22T10.log +26 -0
- package/logs/2026-06-22T11.log +860 -0
- package/logs/2026-06-22T12.log +430 -0
- package/logs/2026-06-22T23.log +1547 -0
- package/logs/2026-06-23T00.log +473 -0
- package/logs/2026-06-23T08.log +231 -0
- package/logs/2026-06-23T09.log +179 -0
- package/logs/2026-07-01T11.log +488 -0
- package/logs/2026-07-09T22.log +370 -0
- package/logs/2026-07-09T23.log +370 -0
- package/logs/2026-07-10T12.log +284 -0
- package/logs/2026-07-10T13.log +777 -0
- package/logs/2026-07-11T17.log +2 -0
- package/package.json +15 -14
- package/server/WWebApi.mjs +23 -33
- package/server/procLang.mjs +8 -88
- package/server/procProxy.mjs +89 -89
- package/server/srLog.mjs +2 -2
- package/server/staLogs/filterVpfsByWindow.mjs +27 -0
- package/server/staLogs/staEvent.mjs +4 -2
- package/server/staLogs/test_staEvent.mjs +67 -1
- package/settings.json +4 -0
- package/src/components/Layout.vue +1 -20
- package/src/components/LayoutContent.vue +0 -26
- package/src/components/LayoutContentEdit.vue +2 -2
- package/src/components/LayoutContentTest.vue +1 -19
- package/src/main.js +3 -8
- package/src/plugins/mUI.mjs +0 -35
- package/src/store/mutations.mjs +0 -14
- package/src/store/types.mjs +0 -3
- package/srv.mjs +6 -4
- package/tableTags.json +1 -1
- package/z/344/277/256/346/255/243/350/246/217/345/212/203/346/233/270.md +246 -0
- package/_gh-pages-deploy/.nojekyll +0 -0
- package/_gh-pages-deploy/WWebApi.html +0 -898
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/_gh-pages-deploy/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -978
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -1049
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/_gh-pages-deploy/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/_gh-pages-deploy/index.html +0 -84
- package/_gh-pages-deploy/scripts/collapse.js +0 -39
- package/_gh-pages-deploy/scripts/commonNav.js +0 -28
- package/_gh-pages-deploy/scripts/linenumber.js +0 -25
- package/_gh-pages-deploy/scripts/nav.js +0 -12
- package/_gh-pages-deploy/scripts/polyfill.js +0 -4
- package/_gh-pages-deploy/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/_gh-pages-deploy/scripts/prettify/lang-css.js +0 -2
- package/_gh-pages-deploy/scripts/prettify/prettify.js +0 -28
- package/_gh-pages-deploy/scripts/search.js +0 -99
- package/_gh-pages-deploy/server_WWebApi.mjs.html +0 -1012
- package/_gh-pages-deploy/src_components_Common_CheckYesNo.vue.html +0 -187
- package/_gh-pages-deploy/styles/jsdoc.css +0 -776
- package/_gh-pages-deploy/styles/prettify.css +0 -80
- package/dist/js/app-legacy.15819aa7.js +0 -1
- package/dist/js/app.15819aa7.js +0 -1
- package/dist/js/chunk-vendors-legacy.c1a32dd1.js +0 -15
- package/dist/js/chunk-vendors.c1a32dd1.js +0 -15
- package/src/plugins/mDataSelectorSchema.mjs +0 -30
- package/src/plugins/mShare.mjs +0 -44
|
@@ -9,6 +9,7 @@ import genPm from 'wsemi/src/genPm.mjs'
|
|
|
9
9
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
10
10
|
import fsTreeFolder from 'wsemi/src/fsTreeFolder.mjs'
|
|
11
11
|
import fsBuildReadStreamText from 'wsemi/src/fsBuildReadStreamText.mjs'
|
|
12
|
+
import filterVpfsByWindow from './filterVpfsByWindow.mjs'
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
//staEvent(通用事件頻率統計,骨架移植自 w-web-sso server/staLogs/staIp.mjs,但「不過濾特定 event」、
|
|
@@ -25,13 +26,13 @@ import fsBuildReadStreamText from 'wsemi/src/fsBuildReadStreamText.mjs'
|
|
|
25
26
|
//參數:
|
|
26
27
|
// timeLength 往回統計天數(預設 7)
|
|
27
28
|
// timeInterval 時間粒度 'hr'(每小時,預設)/ 'day'(每日)
|
|
28
|
-
// opt.fdLog log 資料夾(預設 './
|
|
29
|
+
// opt.fdLog log 資料夾(預設 './logs',須與 srLog 寫入之 logFd 一致;e2e 可指向合成 log 達 hermetic)
|
|
29
30
|
async function staEvent(timeLength = 7, timeInterval = 'hr', opt = {}) {
|
|
30
31
|
|
|
31
32
|
//fdLog
|
|
32
33
|
let fdLog = get(opt, 'fdLog')
|
|
33
34
|
if (!isestr(fdLog)) {
|
|
34
|
-
fdLog = './
|
|
35
|
+
fdLog = './logs'
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
//fmt
|
|
@@ -53,6 +54,7 @@ async function staEvent(timeLength = 7, timeInterval = 'hr', opt = {}) {
|
|
|
53
54
|
|
|
54
55
|
//vpfs
|
|
55
56
|
let vpfs = fsTreeFolder(fdLog)
|
|
57
|
+
vpfs = filterVpfsByWindow(vpfs, tStart, fmt) //開檔前剔除窗外檔, 見該模組註解
|
|
56
58
|
|
|
57
59
|
//logs(逐檔逐行 stream parse,挑出 tStart 之後、且帶 event 字串者)
|
|
58
60
|
let logs = []
|
|
@@ -10,9 +10,10 @@ import fs from 'fs'
|
|
|
10
10
|
import path from 'path'
|
|
11
11
|
import ot from 'dayjs'
|
|
12
12
|
import staEvent from './staEvent.mjs'
|
|
13
|
+
import filterVpfsByWindow from './filterVpfsByWindow.mjs'
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
//tmp log 資料夾(落在主 cwd ./tmp/,集中可一鍵清;不污染真實 ./
|
|
16
|
+
//tmp log 資料夾(落在主 cwd ./tmp/,集中可一鍵清;不污染真實 ./logs)
|
|
16
17
|
let fdLog = './tmp/_logs-test-staEvent'
|
|
17
18
|
|
|
18
19
|
//以「當前小時正中(:30)」為錨點,避免測試剛好跨小時邊界導致 bucket 飄移
|
|
@@ -71,6 +72,67 @@ function findBucket(rs, time) {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
|
|
75
|
+
//testFilterVpfsByWindowDirect:直測 filterVpfsByWindow「粒度自適應」防線(filterVpfsByWindow.mjs:22),
|
|
76
|
+
//以自造 vpfs 物件陣列覆蓋 P-2 要求之三個分支,不經 staEvent/fsTreeFolder。
|
|
77
|
+
function testFilterVpfsByWindowDirect() {
|
|
78
|
+
|
|
79
|
+
//tStart 固定為 2026-07-08 21:00,keyStart(fmt='YYYY-MM-DDTHH')= '2026-07-08T21'
|
|
80
|
+
let tStart = ot('2026-07-08T21:00:00')
|
|
81
|
+
let fmtHr2 = 'YYYY-MM-DDTHH'
|
|
82
|
+
|
|
83
|
+
//①day 粒度檔名(10 字元)× fmt='YYYY-MM-DDTHH',且 tStart 落在該日內 → 應保留。
|
|
84
|
+
//對應規格:filterVpfsByWindow.mjs:11-14 註解——不 slice 則 '2026-07-08' < '2026-07-08T21'(同日
|
|
85
|
+
//字典序比較,短字串為前綴恆較小)誤判窗外漏讀整天;filterVpfsByWindow.mjs:22 之
|
|
86
|
+
//`bn >= keyStart.slice(0, bn.length)` 為此案例之防線(slice 後同為 '2026-07-08',相等即保留)。
|
|
87
|
+
let vpfDaySameDate = { path: '/x/2026-07-08.log', name: '2026-07-08.log', isFolder: false, level: 1 }
|
|
88
|
+
let rs1 = filterVpfsByWindow([vpfDaySameDate], tStart, fmtHr2)
|
|
89
|
+
assert.strictEqual(rs1.length, 1, 'day 粒度同日檔名(10 字元)於 hr fmt(13 字元)下應被保留')
|
|
90
|
+
|
|
91
|
+
//②明確窗外之 hr 檔名(早於 tStart 所在小時)→ 應剔除。
|
|
92
|
+
//對應規格:filterVpfsByWindow.mjs:22 主邏輯 `bn >= keyStart.slice(0, bn.length)`——
|
|
93
|
+
//bn 與 keyStart 同為 hr 粒度(13 字元)時 slice 為 no-op,純字串比較即可判窗外。
|
|
94
|
+
let vpfHrBefore = { path: '/x/2026-07-08T10.log', name: '2026-07-08T10.log', isFolder: false, level: 1 }
|
|
95
|
+
let rs2 = filterVpfsByWindow([vpfHrBefore], tStart, fmtHr2)
|
|
96
|
+
assert.strictEqual(rs2.length, 0, '明確窗外(早於 tStart 小時)之 hr 檔名應被剔除')
|
|
97
|
+
|
|
98
|
+
//③非 ISO 前綴檔名 → fail-open 保留。
|
|
99
|
+
//對應規格:filterVpfsByWindow.mjs:9,19-20 註解——「fail-open: 檔名不符 ISO 前綴者一律保留
|
|
100
|
+
//(寧可多讀, 不可漏讀)」。
|
|
101
|
+
let vpfNonIso = { path: '/x/current.log', name: 'current.log', isFolder: false, level: 1 }
|
|
102
|
+
let rs3 = filterVpfsByWindow([vpfNonIso], tStart, fmtHr2)
|
|
103
|
+
assert.strictEqual(rs3.length, 1, '非 ISO 前綴檔名應 fail-open 保留')
|
|
104
|
+
|
|
105
|
+
console.log('=== testFilterVpfsByWindowDirect PASS ===')
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
//testGranularityAdaptiveIntegration:整合路徑驗證——srLog 之 logInterval(決定檔名粒度)與 staLogs 之
|
|
110
|
+
//timeInterval(決定 fmt)不同調時(day 粒度檔名 × hr 粒度 fmt),窗內事件仍須被 staEvent 讀到。
|
|
111
|
+
//對應規格:filterVpfsByWindow.mjs:11-14 註解之情境重現於整合路徑(經 fsTreeFolder + fsBuildReadStreamText
|
|
112
|
+
//實際開檔讀行),證明 filterVpfsByWindow.mjs:22 之 slice 防線在 staEvent.mjs:57 呼叫處確實生效,
|
|
113
|
+
//而非僅單元測試層級成立。
|
|
114
|
+
async function testGranularityAdaptiveIntegration() {
|
|
115
|
+
let fdLog2 = './tmp/_logs-test-staEvent-granularity'
|
|
116
|
+
fs.rmSync(fdLog2, { recursive: true, force: true })
|
|
117
|
+
fs.mkdirSync(fdLog2, { recursive: true })
|
|
118
|
+
|
|
119
|
+
//tRef 近似 staEvent 內部之 tStart(timeLength=0 → tStart ≈ now);day 粒度檔名(10 字元)= tRef 當日
|
|
120
|
+
let tRef = ot()
|
|
121
|
+
let dayFileName = `${tRef.format('YYYY-MM-DD')}.log`
|
|
122
|
+
let tEvent = tRef.add(5, 'second') //晚於 tStart,使 staEvent.mjs:76 之 per-line `t.isAfter(tStart)` 成立
|
|
123
|
+
let lines = [logLine(tEvent, 'granularityProbe')]
|
|
124
|
+
fs.writeFileSync(path.join(fdLog2, dayFileName), lines.join('\n') + '\n', 'utf8')
|
|
125
|
+
|
|
126
|
+
let rsG = await staEvent(0, 'hr', { fdLog: fdLog2 })
|
|
127
|
+
let totalG = rsG.reduce((acc, v) => acc + v.data.count, 0)
|
|
128
|
+
assert.strictEqual(totalG, 1, 'day 粒度檔名於 hr timeInterval 下,窗內事件應被 staEvent 計入(不被誤判窗外漏讀)')
|
|
129
|
+
|
|
130
|
+
fs.rmSync(fdLog2, { recursive: true, force: true })
|
|
131
|
+
|
|
132
|
+
console.log('=== testGranularityAdaptiveIntegration PASS ===')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
74
136
|
async function main() {
|
|
75
137
|
|
|
76
138
|
writeSyntheticLogs()
|
|
@@ -119,6 +181,10 @@ async function main() {
|
|
|
119
181
|
//清理
|
|
120
182
|
fs.rmSync(fdLog, { recursive: true, force: true })
|
|
121
183
|
|
|
184
|
+
//=== 粒度自適應防線(P-2)===
|
|
185
|
+
testFilterVpfsByWindowDirect()
|
|
186
|
+
await testGranularityAdaptiveIntegration()
|
|
187
|
+
|
|
122
188
|
console.log('=== test_staEvent PASS ===')
|
|
123
189
|
console.log(`hr buckets: ${rs.length}, 本小時=${JSON.stringify(bNow.data)}, 前一小時=${JSON.stringify(bPrev.data)}`)
|
|
124
190
|
}
|
package/settings.json
CHANGED
|
@@ -106,7 +106,7 @@ export default {
|
|
|
106
106
|
let showLanguage = get(vo, 'webInfor.showLanguage', '')
|
|
107
107
|
// console.log('showLanguage', showLanguage)
|
|
108
108
|
vo.showLangSelect = showLanguage === 'y'
|
|
109
|
-
//setLang(null):改走 getLang 解析(URL ?lang= >
|
|
109
|
+
//setLang(null):改走 getLang 解析(URL ?lang= > window 注入之 server 語系 > store),
|
|
110
110
|
//不再用 webInfor.language 明確覆蓋(否則會蓋掉 URL ?lang= 與使用者切換)。server 初始語系已由
|
|
111
111
|
//window.___pmwperm___.language(WWebApi 注入 index.html)提供,getLang 會取得。
|
|
112
112
|
vo.$ui.setLang(null, 'layout mounted')
|
|
@@ -116,10 +116,6 @@ export default {
|
|
|
116
116
|
},
|
|
117
117
|
computed: {
|
|
118
118
|
|
|
119
|
-
viewState: function() {
|
|
120
|
-
return get(this, `$store.state.viewState`, '')
|
|
121
|
-
},
|
|
122
|
-
|
|
123
119
|
heightToolbar: function() {
|
|
124
120
|
//console.log('computed heightToolbar')
|
|
125
121
|
|
|
@@ -128,11 +124,6 @@ export default {
|
|
|
128
124
|
return get(vo, `$store.state.heightToolbar`, 0)
|
|
129
125
|
},
|
|
130
126
|
|
|
131
|
-
userToken: function() {
|
|
132
|
-
let vo = this
|
|
133
|
-
return get(vo, `$store.state.userToken`)
|
|
134
|
-
},
|
|
135
|
-
|
|
136
127
|
lang: function() {
|
|
137
128
|
let vo = this
|
|
138
129
|
return get(vo, `$store.state.lang`, '')
|
|
@@ -168,16 +159,6 @@ export default {
|
|
|
168
159
|
return get(vo, `$store.state.webInfor.webLogo`, '')
|
|
169
160
|
},
|
|
170
161
|
|
|
171
|
-
userSelf: function() {
|
|
172
|
-
let vo = this
|
|
173
|
-
return get(vo, `$store.state.userSelf`, '')
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
userName: function() {
|
|
177
|
-
let vo = this
|
|
178
|
-
return get(vo, `userSelf.name`, '')
|
|
179
|
-
},
|
|
180
|
-
|
|
181
162
|
},
|
|
182
163
|
methods: {
|
|
183
164
|
|
|
@@ -286,7 +286,6 @@ import filter from 'lodash-es/filter.js'
|
|
|
286
286
|
import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
287
287
|
import isobj from 'wsemi/src/isobj.mjs'
|
|
288
288
|
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
289
|
-
import timemsTZ2day from 'wsemi/src/timemsTZ2day.mjs'
|
|
290
289
|
import convertToTree from 'wsemi/src/convertToTree.mjs'
|
|
291
290
|
import { mdiArrowLeft, mdiArrowRight, mdiCloudBraces, mdiChartBar } from '@mdi/js'
|
|
292
291
|
import WButtonCircle from 'w-component-vue/src/components/WButtonCircle.vue'
|
|
@@ -338,13 +337,6 @@ export default {
|
|
|
338
337
|
mdiArrowRight,
|
|
339
338
|
apiSelect: null,
|
|
340
339
|
|
|
341
|
-
kpColorMethod: {
|
|
342
|
-
GET: '#0082d0',
|
|
343
|
-
POST: '#069061',
|
|
344
|
-
PUT: '#ff5800',
|
|
345
|
-
DEL: '#ef0006',
|
|
346
|
-
},
|
|
347
|
-
|
|
348
340
|
//API 管理:模式切換 / 新增 / 搜尋
|
|
349
341
|
mode: 'docs', //'docs' | 'edit' | 'test'
|
|
350
342
|
newMode: false,
|
|
@@ -509,24 +501,6 @@ export default {
|
|
|
509
501
|
return method
|
|
510
502
|
},
|
|
511
503
|
|
|
512
|
-
getMethodColor: function(item) {
|
|
513
|
-
let vo = this
|
|
514
|
-
let method = vo.getMethod(item)
|
|
515
|
-
let color = get(vo.kpColorMethod, method, '#888')
|
|
516
|
-
return color
|
|
517
|
-
},
|
|
518
|
-
|
|
519
|
-
getMethodColorByKey: function(key) {
|
|
520
|
-
let vo = this
|
|
521
|
-
let method = vo.getMethodByKey(key)
|
|
522
|
-
let color = get(vo.kpColorMethod, method, '#888')
|
|
523
|
-
return color
|
|
524
|
-
},
|
|
525
|
-
|
|
526
|
-
getDay: function(t) {
|
|
527
|
-
return timemsTZ2day(t)
|
|
528
|
-
},
|
|
529
|
-
|
|
530
504
|
jsonHighlight: function(str) {
|
|
531
505
|
let s = (str === null || str === undefined) ? '' : String(str)
|
|
532
506
|
// escape HTML
|
|
@@ -341,7 +341,7 @@ export default {
|
|
|
341
341
|
onClickSave: function() {
|
|
342
342
|
let vo = this
|
|
343
343
|
vo.submitSave()
|
|
344
|
-
.catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), 'error') })
|
|
344
|
+
.catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' }) })
|
|
345
345
|
.finally(function() { vo.$ui.updateLoading(false) })
|
|
346
346
|
},
|
|
347
347
|
|
|
@@ -435,7 +435,7 @@ export default {
|
|
|
435
435
|
|
|
436
436
|
}
|
|
437
437
|
core()
|
|
438
|
-
.catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), 'error') })
|
|
438
|
+
.catch(function(err) { console.log('catch', err); vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' }) })
|
|
439
439
|
.finally(function() { vo.$ui.updateLoading(false) })
|
|
440
440
|
},
|
|
441
441
|
|
|
@@ -372,24 +372,6 @@ export default {
|
|
|
372
372
|
return get(kpColorMethod, method, 'var(--c-2)')
|
|
373
373
|
},
|
|
374
374
|
|
|
375
|
-
getStatusColor: function(status) {
|
|
376
|
-
// let vo = this
|
|
377
|
-
let s = parseInt(status, 10)
|
|
378
|
-
if (s >= 200 && s < 300) {
|
|
379
|
-
return '#2a2'
|
|
380
|
-
}
|
|
381
|
-
if (s >= 300 && s < 400) {
|
|
382
|
-
return '#68f'
|
|
383
|
-
}
|
|
384
|
-
if (s >= 400 && s < 500) {
|
|
385
|
-
return '#f82'
|
|
386
|
-
}
|
|
387
|
-
if (s >= 500) {
|
|
388
|
-
return '#f26'
|
|
389
|
-
}
|
|
390
|
-
return '#888'
|
|
391
|
-
},
|
|
392
|
-
|
|
393
375
|
jsonToRows: function(jsonStr) {
|
|
394
376
|
// let vo = this
|
|
395
377
|
let rows = []
|
|
@@ -605,7 +587,7 @@ export default {
|
|
|
605
587
|
core()
|
|
606
588
|
.catch(function(err) {
|
|
607
589
|
console.log('catch', err)
|
|
608
|
-
vo.$alert(vo.$t('anUnexpectedErrorOccurred'), 'error')
|
|
590
|
+
vo.$alert(vo.$t('anUnexpectedErrorOccurred'), { type: 'error' })
|
|
609
591
|
})
|
|
610
592
|
.finally(function() {
|
|
611
593
|
vo.sending = false
|
package/src/main.js
CHANGED
|
@@ -13,8 +13,6 @@ import domDragDrop from 'w-component-vue/src/js/domDragDrop.mjs'
|
|
|
13
13
|
import App from './App.vue'
|
|
14
14
|
import store from './store/index.mjs'
|
|
15
15
|
import ui from './plugins/mUI.mjs'
|
|
16
|
-
import mDataSelectorSchema from './plugins/mDataSelectorSchema.mjs'
|
|
17
|
-
import * as s from './plugins/mShare.mjs'
|
|
18
16
|
import ds from './schema/index.mjs'
|
|
19
17
|
// console.log('globalState', globalState)
|
|
20
18
|
// console.log('ds', ds)
|
|
@@ -32,9 +30,6 @@ Vue.prototype.$alert = function() {
|
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
//dssm
|
|
36
|
-
let dssm = mDataSelectorSchema(ds)
|
|
37
|
-
|
|
38
33
|
//prototype
|
|
39
34
|
Vue.prototype.$ui = ui
|
|
40
35
|
Vue.prototype.$t = ui.getKpText
|
|
@@ -45,8 +40,6 @@ Vue.prototype.$transErr = (err) => {
|
|
|
45
40
|
let msg = ui.getKpText(key)
|
|
46
41
|
return (msg && msg !== key) ? msg : ui.getKpText('anUnexpectedErrorOccurred')
|
|
47
42
|
}
|
|
48
|
-
Vue.prototype.$s = s
|
|
49
|
-
Vue.prototype.$dssm = dssm
|
|
50
43
|
Vue.prototype.$ds = ds
|
|
51
44
|
Vue.prototype.$dg = {}
|
|
52
45
|
|
|
@@ -87,7 +80,9 @@ WServHapiClient({
|
|
|
87
80
|
|
|
88
81
|
})
|
|
89
82
|
.catch((err) => {
|
|
90
|
-
console.log(err)
|
|
83
|
+
console.log('getWebInfor failed', err)
|
|
84
|
+
//getWebInfor 失敗時導向連線錯誤態,避免 ready(需 webInfor) 永假而卡在「已登入」轉圈無回饋
|
|
85
|
+
ui.updateConnState('csErrConn')
|
|
91
86
|
})
|
|
92
87
|
|
|
93
88
|
},
|
package/src/plugins/mUI.mjs
CHANGED
|
@@ -1,47 +1,12 @@
|
|
|
1
1
|
import Vue from 'vue'
|
|
2
|
-
import min from 'lodash-es/min.js'
|
|
3
|
-
import size from 'lodash-es/size.js'
|
|
4
|
-
import take from 'lodash-es/take.js'
|
|
5
|
-
import isEqual from 'lodash-es/isEqual.js'
|
|
6
|
-
import uniq from 'lodash-es/uniq.js'
|
|
7
|
-
import set from 'lodash-es/set.js'
|
|
8
2
|
import get from 'lodash-es/get.js'
|
|
9
3
|
import each from 'lodash-es/each.js'
|
|
10
|
-
import map from 'lodash-es/map.js'
|
|
11
|
-
import filter from 'lodash-es/filter.js'
|
|
12
|
-
import last from 'lodash-es/last.js'
|
|
13
|
-
import split from 'lodash-es/split.js'
|
|
14
|
-
import join from 'lodash-es/join.js'
|
|
15
|
-
import drop from 'lodash-es/drop.js'
|
|
16
|
-
import dropRight from 'lodash-es/dropRight.js'
|
|
17
|
-
import groupBy from 'lodash-es/groupBy.js'
|
|
18
|
-
import sortBy from 'lodash-es/sortBy.js'
|
|
19
4
|
import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
20
|
-
import cint from 'wsemi/src/cint.mjs'
|
|
21
5
|
import delay from 'wsemi/src/delay.mjs'
|
|
22
|
-
import isarr from 'wsemi/src/isarr.mjs'
|
|
23
6
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
24
7
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
25
8
|
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
26
|
-
import isearr from 'wsemi/src/isearr.mjs'
|
|
27
|
-
import isEle from 'wsemi/src/isEle.mjs'
|
|
28
|
-
import strleft from 'wsemi/src/strleft.mjs'
|
|
29
|
-
import strdelleft from 'wsemi/src/strdelleft.mjs'
|
|
30
|
-
import sep from 'wsemi/src/sep.mjs'
|
|
31
|
-
import aes2str from 'wsemi/src/aes2str.mjs'
|
|
32
|
-
import str2aes from 'wsemi/src/str2aes.mjs'
|
|
33
|
-
import haskey from 'wsemi/src/haskey.mjs'
|
|
34
|
-
import genPm from 'wsemi/src/genPm.mjs'
|
|
35
|
-
import pmSeries from 'wsemi/src/pmSeries.mjs'
|
|
36
9
|
import waitFun from 'wsemi/src/waitFun.mjs'
|
|
37
|
-
import browserView from 'wsemi/src/browserView.mjs'
|
|
38
|
-
import arrHas from 'wsemi/src/arrHas.mjs'
|
|
39
|
-
import arrSort from 'wsemi/src/arrSort.mjs'
|
|
40
|
-
import arrInsert from 'wsemi/src/arrInsert.mjs'
|
|
41
|
-
import replace from 'wsemi/src/replace.mjs'
|
|
42
|
-
import timemsTZ2past from 'wsemi/src/timemsTZ2past.mjs'
|
|
43
|
-
import convertToTree from 'wsemi/src/convertToTree.mjs'
|
|
44
|
-
// import WUiDwload from 'w-ui-dwload/src/WUiDwload.mjs'
|
|
45
10
|
|
|
46
11
|
|
|
47
12
|
let kpFallback = {
|
package/src/store/mutations.mjs
CHANGED
|
@@ -79,12 +79,6 @@ export let mutations = {
|
|
|
79
79
|
state[msg.tableName] = msg.data
|
|
80
80
|
},
|
|
81
81
|
|
|
82
|
-
[types.UpdateData] (state, msg) {
|
|
83
|
-
//msg.path內為存取路徑, 需使用set處理
|
|
84
|
-
// console.log('UpdateData msg', msg)
|
|
85
|
-
set(state, msg.path, msg.data)
|
|
86
|
-
},
|
|
87
|
-
|
|
88
82
|
[types.UpdateHeightApp] (state, heightApp) {
|
|
89
83
|
state.heightApp = heightApp
|
|
90
84
|
},
|
|
@@ -93,14 +87,6 @@ export let mutations = {
|
|
|
93
87
|
state.heightAppEff = heightAppEff
|
|
94
88
|
},
|
|
95
89
|
|
|
96
|
-
[types.UpdateHeightToolbar] (state, heightToolbar) {
|
|
97
|
-
state.heightToolbar = heightToolbar
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
[types.UpdateMenu] (state, menu) {
|
|
101
|
-
state.menu = menu
|
|
102
|
-
},
|
|
103
|
-
|
|
104
90
|
[types.UpdateUserToken] (state, userToken) {
|
|
105
91
|
state.userToken = userToken
|
|
106
92
|
},
|
package/src/store/types.mjs
CHANGED
|
@@ -6,10 +6,7 @@ export const UpdateSyncState = 'UpdateSyncState'
|
|
|
6
6
|
export const UpdateLoading = 'UpdateLoading'
|
|
7
7
|
// export const UpdateViewState = 'UpdateViewState'
|
|
8
8
|
export const UpdateTableData = 'UpdateTableData'
|
|
9
|
-
export const UpdateData = 'UpdateData'
|
|
10
9
|
export const UpdateHeightApp = 'UpdateHeightApp'
|
|
11
10
|
export const UpdateHeightAppEff = 'UpdateHeightAppEff'
|
|
12
|
-
export const UpdateHeightToolbar = 'UpdateHeightToolbar'
|
|
13
|
-
export const UpdateMenu = 'UpdateMenu'
|
|
14
11
|
export const UpdateUserToken = 'UpdateUserToken'
|
|
15
12
|
export const UpdateUserSelf = 'UpdateUserSelf'
|
package/srv.mjs
CHANGED
|
@@ -37,7 +37,7 @@ let opt = {
|
|
|
37
37
|
language: get(stApp, 'language', 'eng'),
|
|
38
38
|
|
|
39
39
|
//log 資料夾與輪檔間隔(srLog 寫入 + staEvent 統計皆讀此)。e2e 可用 genTempSettings({logFd}) 指向合成 log 達 hermetic。
|
|
40
|
-
logFd: get(stApp, 'logFd', './
|
|
40
|
+
logFd: get(stApp, 'logFd', './logs'),
|
|
41
41
|
logInterval: get(stApp, 'logInterval', 'hr'),
|
|
42
42
|
|
|
43
43
|
webName: {
|
|
@@ -46,7 +46,7 @@ let opt = {
|
|
|
46
46
|
},
|
|
47
47
|
webDescription: {
|
|
48
48
|
'eng': 'A web service package as methods to send requests to and receive responses from an API.',
|
|
49
|
-
'cht': '
|
|
49
|
+
'cht': '一套以方法形式,用於發送請求至API並接收其回應的網頁服務套件。',
|
|
50
50
|
},
|
|
51
51
|
webLogo: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMyIDMyIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGcgaWQ9IkxheWVyXzIiLz48ZyBpZD0iTGF5ZXJfMyIvPjxnIGlkPSJMYXllcl80Ij48Zz48cGF0aCBkPSJNOS4wMiw2QzkuMDEyNyw2LDkuMDA2OCw1Ljk5OSw5LDZIMkMxLjQ0NzgsNiwxLDUuNTUyNywxLDVWMmMwLTAuNTUyNywwLjQ0NzgtMSwxLTFoNiAgICBjMC40MzA3LDAsMC44MTI1LDAuMjc1NCwwLjk0ODcsMC42ODM2bDAuOTQwNCwyLjgyMTNDOS45NzIyLDQuNjUxNCwxMC4wMiw0LjgyMDMsMTAuMDIsNUMxMC4wMiw1LjU1MjcsOS41NzIzLDYsOS4wMiw2eiBNMyw0ICAgIGg0LjYxMjhMNy4yNzkzLDNIM1Y0eiIgZmlsbD0iI0Y1RDgwMyIvPjwvZz48Zz48cGF0aCBkPSJNMjQuMDE5NSwyMmMtMC4wMDM5LDAtMC4wMTE3LDAuMDAxLTAuMDE5NSwwaC03Yy0wLjU1MjIsMC0xLTAuNDQ3My0xLTF2LTNjMC0wLjU1MjcsMC40NDc4LTEsMS0xaDYgICAgYzAuNDMwNywwLDAuODEyNSwwLjI3NTQsMC45NDgyLDAuNjgzNmwwLjk0MDQsMi44MjEzYzAuMDg0LDAuMTQ2NSwwLjEzMDksMC4zMTU0LDAuMTMwOSwwLjQ5NTEgICAgQzI1LjAxOTUsMjEuNTUyNywyNC41NzIzLDIyLDI0LjAxOTUsMjJ6IE0xOCwyMGg0LjYxMjNsLTAuMzMzLTFIMThWMjB6IiBmaWxsPSIjRjVEODAzIi8+PC9nPjxnPjxwYXRoIGQ9Ik0xNSwxNUgyYy0wLjU1MjIsMC0xLTAuNDQ3My0xLTFWNWMwLTAuNTUyNywwLjQ0NzgtMSwxLTFoMTNjMC41NTIyLDAsMSwwLjQ0NzMsMSwxdjkgICAgQzE2LDE0LjU1MjcsMTUuNTUyMiwxNSwxNSwxNXogTTMsMTNoMTFWNkgzVjEzeiIgZmlsbD0iIzAxODFCMCIvPjwvZz48Zz48cGF0aCBkPSJNMzAsMzFIMTdjLTAuNTUyMiwwLTEtMC40NDczLTEtMXYtOWMwLTAuNTUyNywwLjQ0NzgtMSwxLTFoMTNjMC41NTI3LDAsMSwwLjQ0NzMsMSwxdjkgICAgQzMxLDMwLjU1MjcsMzAuNTUyNywzMSwzMCwzMXogTTE4LDI5aDExdi03SDE4VjI5eiIgZmlsbD0iIzAxODFCMCIvPjwvZz48Zz48cGF0aCBkPSJNMjYsOGgtOGMtMC41NTI3LDAtMSwwLjQ0NzMtMSwxczAuNDQ3MywxLDEsMWg3djZjMCwwLjU1MjcsMC40NDczLDEsMSwxczEtMC40NDczLDEtMVY5ICAgIEMyNyw4LjQ0NzMsMjYuNTUyNyw4LDI2LDh6IiBmaWxsPSIjMDBBQ0JBIi8+PGc+PHBhdGggZD0iTTIwLDEyYy0wLjI1NTksMC0wLjUxMTctMC4wOTc3LTAuNzA3LTAuMjkzbC0yLTJjLTAuMzkwNi0wLjM5MDYtMC4zOTA2LTEuMDIzNCwwLTEuNDE0MWwyLTIgICAgIGMwLjM5MDYtMC4zOTA2LDEuMDIzNC0wLjM5MDYsMS40MTQxLDBzMC4zOTA2LDEuMDIzNCwwLDEuNDE0MUwxOS40MTQxLDlsMS4yOTMsMS4yOTNjMC4zOTA2LDAuMzkwNiwwLjM5MDYsMS4wMjM0LDAsMS40MTQxICAgICBDMjAuNTExNywxMS45MDIzLDIwLjI1NTksMTIsMjAsMTJ6IiBmaWxsPSIjRjVEODAzIi8+PC9nPjwvZz48Zz48cGF0aCBkPSJNMTQsMjVIN3YtNmMwLTAuNTUyNy0wLjQ0NzgtMS0xLTFzLTEsMC40NDczLTEsMXY3YzAsMC41NTI3LDAuNDQ3OCwxLDEsMWg4YzAuNTUyMiwwLDEtMC40NDczLDEtMSAgICBTMTQuNTUyMiwyNSwxNCwyNXoiIGZpbGw9IiMwMEFDQkEiLz48Zz48cGF0aCBkPSJNMTIsMjljLTAuMjU1OSwwLTAuNTExNy0wLjA5NzctMC43MDctMC4yOTNjLTAuMzkwNi0wLjM5MDYtMC4zOTA2LTEuMDIzNCwwLTEuNDE0MUwxMi41ODU5LDI2ICAgICBsLTEuMjkzLTEuMjkzYy0wLjM5MDYtMC4zOTA2LTAuMzkwNi0xLjAyMzQsMC0xLjQxNDFzMS4wMjM0LTAuMzkwNiwxLjQxNDEsMGwyLDJjMC4zOTA2LDAuMzkwNiwwLjM5MDYsMS4wMjM0LDAsMS40MTQxbC0yLDIgICAgIEMxMi41MTE3LDI4LjkwMjMsMTIuMjU1OSwyOSwxMiwyOXoiIGZpbGw9IiNGNUQ4MDMiLz48L2c+PC9nPjwvZz48ZyBpZD0iTGF5ZXJfNSIvPjxnIGlkPSJMYXllcl82Ii8+PGcgaWQ9IkxheWVyXzciLz48ZyBpZD0iTGF5ZXJfOCIvPjxnIGlkPSJMYXllcl85Ii8+PGcgaWQ9IkxheWVyXzEwIi8+PGcgaWQ9IkxheWVyXzExIi8+PGcgaWQ9IkxheWVyXzEyIi8+PGcgaWQ9IkxheWVyXzEzIi8+PGcgaWQ9IkxheWVyXzE0Ii8+PGcgaWQ9IkxheWVyXzE1Ii8+PGcgaWQ9IkxheWVyXzE2Ii8+PGcgaWQ9IkxheWVyXzE3Ii8+PGcgaWQ9IkxheWVyXzE4Ii8+PGcgaWQ9IkxheWVyXzE5Ii8+PGcgaWQ9IkxheWVyXzIwIi8+PGcgaWQ9IkxheWVyXzIxIi8+PGcgaWQ9IkxheWVyXzIyIi8+PGcgaWQ9IkxheWVyXzIzIi8+PGcgaWQ9IkxheWVyXzI0Ii8+PGcgaWQ9IkxheWVyXzI1Ii8+PGcgaWQ9IkxheWVyXzI2Ii8+PC9zdmc+',
|
|
52
52
|
|
|
@@ -54,8 +54,10 @@ let opt = {
|
|
|
54
54
|
|
|
55
55
|
let getUserByToken = async (token) => {
|
|
56
56
|
// return {} //測試無法登入
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
//'sys' 為開發捷徑(w-ui-loginout 於 localhost 自動帶入)。加環境守門:NODE_ENV==='production' 時不接受,
|
|
58
|
+
//避免 srv.mjs 若作正式入口時 'sys' 成為遠端管理員後門。e2e/dev 未設 NODE_ENV=production 故仍可用;
|
|
59
|
+
//正式部署設 NODE_ENV=production 即停用此捷徑(並應改提供真實 getUserByToken)。
|
|
60
|
+
if (token === 'sys' && process.env.NODE_ENV !== 'production') {
|
|
59
61
|
return { id: 'id-for-admin', name: '測試者', email: 'admin@example.com', isAdmin: 'y' }
|
|
60
62
|
}
|
|
61
63
|
//未設定 SSO app token 時(本機開發未接SSO), 不打SSO直接拒絕
|
package/tableTags.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"apis":"2026-
|
|
1
|
+
{"apis":"2026-07-11T17:47:54+08:00|7AQq2D"}
|