ch3chi-commons-vue 1.8.0 → 1.8.1
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/package.json +2 -1
- package/src/api/ApiService.ts +869 -0
- package/src/auth/AuthorizationService.ts +138 -0
- package/src/auth/PermissionDescriptor.ts +99 -0
- package/src/auth/keys.ts +5 -0
- package/src/components/CAlert.vue +188 -0
- package/src/components/CAlertDefine.ts +20 -0
- package/src/components/CBSToast.vue +119 -0
- package/src/components/CGlobalSpinner.vue +84 -0
- package/src/components/CImage.vue +67 -0
- package/src/components/CRowCheckBox.vue +75 -0
- package/src/components/CRowTextInput.vue +27 -0
- package/src/components/CTable.vue +524 -0
- package/src/components/CTableDefine.ts +566 -0
- package/src/components/CTableTD.vue +28 -0
- package/src/components/HasPermission.vue +28 -0
- package/src/components/form/CChangePasswordFormField.vue +146 -0
- package/src/components/form/CCheckBoxFormField.vue +91 -0
- package/src/components/form/CCheckBoxPlatFormField.vue +94 -0
- package/src/components/form/CDateFormField.vue +149 -0
- package/src/components/form/CDateQueryField.vue +111 -0
- package/src/components/form/CDateRangeFormField.vue +138 -0
- package/src/components/form/CFilePickerFormField.vue +471 -0
- package/src/components/form/CRadioFormField.vue +62 -0
- package/src/components/form/CRadioPlatFormField.vue +67 -0
- package/src/components/form/CSelectFormField.vue +175 -0
- package/src/components/form/CTextAreaFormField.vue +84 -0
- package/src/components/form/CTextInputFormField.vue +99 -0
- package/src/components/form/CTinyMCEEditorFormField.vue +99 -0
- package/src/components/form/SCTextInputFormField.vue +129 -0
- package/src/composables/useCheckBoxFormField.ts +126 -0
- package/src/composables/useRadioFormField.ts +106 -0
- package/src/directive/CBootstrapDirective.ts +83 -0
- package/src/directive/CDateFormatterDirective.ts +37 -0
- package/src/directive/CFTurnstileDirective.ts +46 -0
- package/src/directive/CFormDirective.ts +57 -0
- package/src/directive/PermissionDirective.ts +102 -0
- package/src/env.d.ts +19 -0
- package/src/index.ts +83 -0
- package/src/model/BSFieldStyleConfig.ts +349 -0
- package/src/model/BaseDictionary.ts +86 -0
- package/src/model/BaseFormDataModel.ts +623 -0
- package/src/model/BaseListViewModel.ts +392 -0
- package/src/model/CBSModalViewModel.ts +91 -0
- package/src/model/CFileDataModel.ts +181 -0
- package/src/model/CImageViewModel.ts +34 -0
- package/src/model/CMenuItem.ts +199 -0
- package/src/model/EmailReceiverDataModel.ts +149 -0
- package/src/model/EmptyDataModel.ts +25 -0
- package/src/model/FormOptions.ts +112 -0
- package/src/model/LoginDataModel.ts +51 -0
- package/src/model/PasswordDataModel.ts +70 -0
- package/src/model/QueryParameter.ts +310 -0
- package/src/model/SessionUser.ts +110 -0
- package/src/model/ShowMessageDataModel.ts +69 -0
- package/src/model/TokenUser.ts +157 -0
- package/src/stores/FormDataStore.ts +73 -0
- package/src/stores/ViewStore.ts +701 -0
- package/src/stores/VueSessionStoreInstaller.ts +22 -0
- package/src/types/turnstile.d.ts +8 -0
- package/src/utils/CToolUtils.ts +133 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import HasPermission from '../components/HasPermission.vue';
|
|
3
|
+
import { SESSION_STORE_KEY } from '../auth/keys';
|
|
4
|
+
import { UserSessionActions } from './ViewStore';
|
|
5
|
+
import {createPermissionDirectives} from "../directive/PermissionDirective";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* VueSessionStoreInstaller 是一個 Vue 插件,用於全域註冊與提供使用者會話相關的功能。
|
|
9
|
+
* 它會將傳入的 sessionStore 實例注入到 Vue 應用中,並註冊一個權限檢查的組件和指令。
|
|
10
|
+
*/
|
|
11
|
+
export default {
|
|
12
|
+
install(app: App, options: { sessionStore: UserSessionActions }) {
|
|
13
|
+
// 1. 全域提供 sessionStore 實例
|
|
14
|
+
app.provide(SESSION_STORE_KEY, options.sessionStore);
|
|
15
|
+
|
|
16
|
+
// 2. 註冊全域組件
|
|
17
|
+
app.component('HasPermission', HasPermission);
|
|
18
|
+
|
|
19
|
+
// 3. (選配) 如果你也想保留指令版,也可以在這裡一起註冊
|
|
20
|
+
app.directive('permission', createPermissionDirectives(options));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import _ from "lodash";
|
|
3
|
+
import * as yup from "yup";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 空函式
|
|
7
|
+
*/
|
|
8
|
+
export const voidFunction = () => {}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 延遲指定毫秒數
|
|
12
|
+
* @param ms 毫秒數
|
|
13
|
+
*/
|
|
14
|
+
export const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 從 params 中挑選有值的屬性並指派到 payload 中
|
|
18
|
+
* @param payload
|
|
19
|
+
* @param params
|
|
20
|
+
*/
|
|
21
|
+
export const pickAndAssign = (payload: Record<string, any>, params: Record<string, any>) =>
|
|
22
|
+
_.assign(payload, _.pickBy(params, _.identity));
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 寫入 Vue ref 物件的值
|
|
26
|
+
* @param refObj
|
|
27
|
+
* @param value
|
|
28
|
+
*/
|
|
29
|
+
export const writeVueRefValue = (refObj: any, value: any) => {
|
|
30
|
+
if(_.isNil(refObj) || !('value' in refObj)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
refObj.value = value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Lodash 擴充工具
|
|
38
|
+
*/
|
|
39
|
+
export const lodashExTools = {
|
|
40
|
+
// 安全取得物件屬性值
|
|
41
|
+
getVal: (obj: any, path: string | null | undefined, defaultValue?: any) => {
|
|
42
|
+
if(_.isNil(path) || _.isEmpty(path)) {
|
|
43
|
+
return defaultValue;
|
|
44
|
+
}
|
|
45
|
+
return _.get(obj, path, defaultValue);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 檢查是否有相同的檔案
|
|
51
|
+
* @param fileList 檔案列表
|
|
52
|
+
* @param file 要檢查的檔案
|
|
53
|
+
*/
|
|
54
|
+
export const checkHasSameFile = (fileList: File[], file: File) => {
|
|
55
|
+
return fileList.some(item => item.name === file.name
|
|
56
|
+
&& item.size === file.size
|
|
57
|
+
&& item.type === file.type
|
|
58
|
+
&& item.lastModified === file.lastModified);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 格式化物件中的所有日期屬性為指定格式的字串。
|
|
63
|
+
* @param obj
|
|
64
|
+
*/
|
|
65
|
+
export function formatDatesInObject(obj: any): any {
|
|
66
|
+
if (_.isNil(obj)) {
|
|
67
|
+
return obj;
|
|
68
|
+
}
|
|
69
|
+
// 如果是 FormData,直接回傳,不處理
|
|
70
|
+
if (obj instanceof FormData) {
|
|
71
|
+
return obj;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 如果是 Date 或 dayjs 物件,進行格式化
|
|
75
|
+
if (dayjs.isDayjs(obj) || obj instanceof Date) {
|
|
76
|
+
// 格式化日期成字串
|
|
77
|
+
// console.log(`format date: ${obj} ISO string => ${dayjs(obj).toISOString()}`);
|
|
78
|
+
// console.log(`format date: ${obj} with timezone => ${dayjs(obj).tz('Asia/Taipei').toISOString()}`);
|
|
79
|
+
// console.log(`format date: ${obj} pattern => ${dayjs(obj).format('YYYY-MM-DDTHH:mm:ssZ')}`);
|
|
80
|
+
// return dayjs(obj).toISOString();
|
|
81
|
+
return dayjs(obj).format('YYYY-MM-DDTHH:mm:ss');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 如果是陣列,遞迴處理每個元素
|
|
85
|
+
if (_.isArray(obj)) {
|
|
86
|
+
return obj.map(item => formatDatesInObject(item));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 如果是物件,遞迴處理每個屬性值
|
|
90
|
+
if (_.isObject(obj)) {
|
|
91
|
+
return _.mapValues(obj, value => formatDatesInObject(value));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 其他類型直接回傳
|
|
95
|
+
return obj;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 建立一個日期區間驗證器,用於 yup 的 test 方法中。
|
|
100
|
+
* @param startDateKey
|
|
101
|
+
* @param endDateKey
|
|
102
|
+
* @param startDateMessage
|
|
103
|
+
* @param endDateMessage
|
|
104
|
+
*/
|
|
105
|
+
export function makeDateRangeValidator({
|
|
106
|
+
startDateKey, endDateKey, startDateMessage, endDateMessage
|
|
107
|
+
}: {startDateKey: string, endDateKey: string, startDateMessage: string, endDateMessage: string}) {
|
|
108
|
+
return function (this: yup.TestContext, formValues: Record<string, any>) {
|
|
109
|
+
const startsAt = formValues[startDateKey];
|
|
110
|
+
const endsAt = formValues[endDateKey];
|
|
111
|
+
if (startsAt == null && endsAt == null) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
const errors: yup.ValidationError[] = [];
|
|
115
|
+
|
|
116
|
+
if (startsAt && endsAt && (startsAt > endsAt)) {
|
|
117
|
+
errors.push(this.createError({
|
|
118
|
+
path: startDateKey,
|
|
119
|
+
message: startDateMessage
|
|
120
|
+
}));
|
|
121
|
+
errors.push(this.createError({
|
|
122
|
+
path: endDateKey,
|
|
123
|
+
message: endDateMessage
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
if (errors.length > 0) {
|
|
127
|
+
// 注意:這裡我們回傳一個新的 ValidationError 實例,它包裹了所有收集到的錯誤
|
|
128
|
+
return new yup.ValidationError(errors);
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|