@yqg/permission 1.3.1-alpha.0 → 1.3.2-alpha.0
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/dist/{apply-modal-D3Frqfx8.js → apply-modal-CSpYfIii.js} +957 -995
- package/dist/{category-selector-BsBqfqWu.js → category-selector-RZIDDDzv.js} +4 -4
- package/dist/{index-CHKs7hG7.js → index-BmkUdNAO.js} +3 -3
- package/dist/{index-CvLY5Rbl.js → index-PEBPXz6I.js} +3 -3
- package/dist/index.js +2 -2
- package/dist/{permission-item-DTdDRu0E.js → permission-item-Cblf9DpJ.js} +57 -60
- package/dist/{yqg-permission-CEJEsvl5.js → yqg-permission-TXUFbfxZ.js} +3820 -3780
- package/dist/yqg-permission.umd.js +57 -57
- package/package.json +1 -1
- package/src/axios/index.ts +1 -5
- package/src/components/apply-modal.vue +9 -42
- package/src/components/permission-item.vue +2 -5
- package/src/components/yqg-permission.vue +8 -13
- package/src/hooks/useFormat.ts +3 -15
- package/src/i18n/en-US.ts +49 -50
- package/src/i18n/in-ID.ts +56 -0
- package/src/i18n/index.ts +5 -2
- package/src/i18n/zh-CH.ts +0 -9
- package/src/typings/index.d.ts +0 -1
- package/src/utils/index.ts +17 -2
package/package.json
CHANGED
package/src/axios/index.ts
CHANGED
|
@@ -2,8 +2,6 @@ import axios from './axios';
|
|
|
2
2
|
|
|
3
3
|
const urlPrefix = '/crane';
|
|
4
4
|
|
|
5
|
-
export const controller = new AbortController();
|
|
6
|
-
|
|
7
5
|
type apiType = {
|
|
8
6
|
[key in string]: (params?: any) => Promise<{body: any}>
|
|
9
7
|
}
|
|
@@ -11,9 +9,7 @@ type apiType = {
|
|
|
11
9
|
export default {
|
|
12
10
|
getPermissions: (params: any) => axios.get(`${urlPrefix}/permission/apply`, {params}),
|
|
13
11
|
|
|
14
|
-
getFlowPreview: (params: any)
|
|
15
|
-
signal: controller.signal // 关键配置
|
|
16
|
-
}),
|
|
12
|
+
getFlowPreview: (params: any)=> axios.post(`${urlPrefix}/permission/apply/oa/flow/submit/preview`, params),
|
|
17
13
|
|
|
18
14
|
submitApply: (params: any) => axios.post(`${urlPrefix}/permission/apply/oa/flow/submit`, params),
|
|
19
15
|
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Modal v-model:open="open" width="1100px" :
|
|
3
|
-
|
|
4
|
-
<Button @click="open = false" v-show="!isAllOwn">{{ t('cancel') }}</Button>
|
|
5
|
-
<Button type="primary" @click="handleOk" :loading="loading">{{ t('submit') }}</Button>
|
|
6
|
-
</template>
|
|
7
|
-
<template #title>
|
|
8
|
-
<span>{{ t('permissionApply') }}</span>
|
|
9
|
-
<span v-show="isAllOwn" class="crane-permission-title-tips">{{ t('isAllOwnTips') }}</span>
|
|
10
|
-
</template>
|
|
2
|
+
<Modal v-model:open="open" :title="t('permissionApply')" width="1100px" @ok="handleOk" :okText="t('submit')"
|
|
3
|
+
:maskClosable="false" :ok-button-props="{ loading: loading }" :cancelText="t('cancel')">
|
|
11
4
|
<Form ref="formRef" :model="formState" :labelCol="{ span: 4 }" :wrapperCol="{ span: 19 }">
|
|
12
5
|
<FormItem :label="t('applyPermission')" name="features"
|
|
13
6
|
:rules="[{ required: true, message: t('selectPlaceholder') }]">
|
|
@@ -37,7 +30,7 @@
|
|
|
37
30
|
max: 300, message: t('maxLengthTips', { length: 300 }), trigger: ['change', 'blur']
|
|
38
31
|
}]">
|
|
39
32
|
<Textarea v-model:value.trim="formState.applyReason" :placeholder="t('applyReasonPlaceholder')"
|
|
40
|
-
:auto-size="{ minRows: 4, maxRows: 4 }"
|
|
33
|
+
:auto-size="{ minRows: 4, maxRows: 4 }">
|
|
41
34
|
</Textarea>
|
|
42
35
|
<span class="reason-tips" style="font-size: 12px">
|
|
43
36
|
{{ t('applyReasonTips') }}
|
|
@@ -71,8 +64,7 @@ import {
|
|
|
71
64
|
Textarea,
|
|
72
65
|
message,
|
|
73
66
|
Tree,
|
|
74
|
-
Spin
|
|
75
|
-
Button
|
|
67
|
+
Spin
|
|
76
68
|
} from 'ant-design-vue';
|
|
77
69
|
import SuccessModal from './success-modal.vue';
|
|
78
70
|
import ApprovalSteps from './approval-steps.vue';
|
|
@@ -102,14 +94,6 @@ const props = defineProps({
|
|
|
102
94
|
spining: {
|
|
103
95
|
type: Boolean,
|
|
104
96
|
default: false
|
|
105
|
-
},
|
|
106
|
-
defaultCheckedIds: {
|
|
107
|
-
type: Array as PropType<string[]>,
|
|
108
|
-
default: () => []
|
|
109
|
-
},
|
|
110
|
-
isAllOwn: {
|
|
111
|
-
type: Boolean,
|
|
112
|
-
default: false
|
|
113
97
|
}
|
|
114
98
|
|
|
115
99
|
});
|
|
@@ -146,10 +130,6 @@ const getValidTimeOptions = async () => {
|
|
|
146
130
|
|
|
147
131
|
getValidTimeOptions();
|
|
148
132
|
const handleOk = async () => {
|
|
149
|
-
if (props.isAllOwn) {
|
|
150
|
-
open.value = false;
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
133
|
await Promise.all([formRef.value.validate(), categoryRef.value?.validate()])
|
|
154
134
|
loading.value = true;
|
|
155
135
|
const params = getParams();
|
|
@@ -181,7 +161,7 @@ const getParams = () => {
|
|
|
181
161
|
|
|
182
162
|
});
|
|
183
163
|
deepTree(permissionList.value, (item: any) => {
|
|
184
|
-
if (!item.children && formState.features.includes(item.feature)
|
|
164
|
+
if (!item.children && formState.features.includes(item.feature)) {
|
|
185
165
|
roleVoList.push({
|
|
186
166
|
roleId: item.roleId,
|
|
187
167
|
validTime: item.validTime
|
|
@@ -208,22 +188,20 @@ const onChangeTime = throttle(async () => {
|
|
|
208
188
|
if (params.roleVoList.length === 0) {
|
|
209
189
|
stepNodes.value = [];
|
|
210
190
|
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
191
|
+
}
|
|
213
192
|
let res = await Http.getFlowPreview(params);
|
|
214
193
|
stepNodes.value = res?.body?.nodes || [];
|
|
215
|
-
},
|
|
194
|
+
}, 0)
|
|
216
195
|
const onCheck = (checkedIds: any, info: any) => {
|
|
217
196
|
// 如果选择的是子节点,判断是否超过5个,超过的话,删除当前选的节点,并给予提示
|
|
218
197
|
// 如果选择的是父节点,判断是否超过5个,超过的话,从当前选择的父节点的叶子节点中删除多出的个数,并给予提示
|
|
219
198
|
let total = 0;
|
|
220
199
|
let curTotal = 0;
|
|
221
|
-
|
|
222
200
|
deepTree(permissionList.value, (item: any) => {
|
|
223
|
-
if (!item.children && checkedIds.includes(item.feature)
|
|
201
|
+
if (!item.children && checkedIds.includes(item.feature)) {
|
|
224
202
|
total += 1;
|
|
225
203
|
}
|
|
226
|
-
if (!item.children && formState.features.includes(item.feature)
|
|
204
|
+
if (!item.children && formState.features.includes(item.feature)) {
|
|
227
205
|
curTotal += 1;
|
|
228
206
|
}
|
|
229
207
|
if (!item.children && !formState.features.includes(item.feature)) {
|
|
@@ -279,10 +257,6 @@ watch(() => props.permissionList, (cur) => {
|
|
|
279
257
|
})
|
|
280
258
|
})
|
|
281
259
|
|
|
282
|
-
watch(() => props.defaultCheckedIds, (cur) => {
|
|
283
|
-
formState.features = cur.concat(formState.features);
|
|
284
|
-
}, { immediate: true })
|
|
285
|
-
|
|
286
260
|
watch(() => open.value, (cur) => {
|
|
287
261
|
if (cur) {
|
|
288
262
|
formRef.value?.resetFields();
|
|
@@ -293,13 +267,6 @@ watch(() => open.value, (cur) => {
|
|
|
293
267
|
</script>
|
|
294
268
|
|
|
295
269
|
<style scoped>
|
|
296
|
-
.crane-permission-title-tips {
|
|
297
|
-
color: #FF4D4F;
|
|
298
|
-
font-size: 14px;
|
|
299
|
-
margin-left: 8px;
|
|
300
|
-
font-weight: 400;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
270
|
:deep(.yqg-permission-tree-list) {
|
|
304
271
|
margin-top: 4px;
|
|
305
272
|
}
|
|
@@ -35,10 +35,7 @@
|
|
|
35
35
|
<Popover v-if="item.relatedCompleteNames?.length">
|
|
36
36
|
<template #content>
|
|
37
37
|
<div style="max-width: 400px;">
|
|
38
|
-
|
|
39
|
-
{{ t('adaptDepartment') }}:
|
|
40
|
-
</div>
|
|
41
|
-
{{item.relatedCompleteNames.map((item: any) => {
|
|
38
|
+
{{ t('adaptDepartment') }}:{{item.relatedCompleteNames.map((item: any) => {
|
|
42
39
|
return item;
|
|
43
40
|
}).join('、')}}
|
|
44
41
|
</div>
|
|
@@ -70,7 +67,7 @@
|
|
|
70
67
|
</Popover>
|
|
71
68
|
|
|
72
69
|
<!-- 选择框 -->
|
|
73
|
-
<span v-if="checkedKeys.includes(item.feature)
|
|
70
|
+
<span v-if="checkedKeys.includes(item.feature)" class="crane-weak-color crane-margin-left-12">
|
|
74
71
|
{{ t('availableTime') }}:
|
|
75
72
|
<Select v-model:value="item.validTime" style="width: 100px"
|
|
76
73
|
:disabled="item.businessApplyType === OWNER_STATUS"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
colorPrimary: props.color,
|
|
5
5
|
}
|
|
6
6
|
}">
|
|
7
|
-
<div class="crane-wraper">
|
|
7
|
+
<div class="crane-wraper" :key="props.locale">
|
|
8
8
|
<template v-if="[COM_TYPE.FLOATBUTTON, COM_TYPE.TEXT].includes(type)">
|
|
9
9
|
<FloatButton ref="dragElement" type="primary" :tooltip="t('clickToApply')" :style="{
|
|
10
10
|
right: RIGHT_DEFAULT,
|
|
@@ -63,8 +63,7 @@
|
|
|
63
63
|
</div>
|
|
64
64
|
|
|
65
65
|
<ApplyModal v-model="open" :permissionList="permissionList" :spining="loading" :workNumber="workNumber"
|
|
66
|
-
|
|
67
|
-
@onSubmit="getPermissions">
|
|
66
|
+
@onSuccess="() => emit('onSuccess')" @onSubmit="getPermissions">
|
|
68
67
|
</ApplyModal>
|
|
69
68
|
|
|
70
69
|
</ConfigProvider>
|
|
@@ -75,7 +74,7 @@ import { Button, ConfigProvider, Popover, message, FloatButton } from 'ant-desig
|
|
|
75
74
|
import applyIconUrl from '@/assets/applyicon.png';
|
|
76
75
|
import noauthority from '@/assets/noauthority.png';
|
|
77
76
|
import Http from '../axios/index';
|
|
78
|
-
import t from '../utils';
|
|
77
|
+
import t, { setLocale } from '../utils';
|
|
79
78
|
import useDraggable from '../hooks/useDragable';
|
|
80
79
|
import useStatus from '../hooks/useStatus';
|
|
81
80
|
import useFormat from '../hooks/useFormat';
|
|
@@ -112,7 +111,7 @@ const props = defineProps({
|
|
|
112
111
|
},
|
|
113
112
|
locale: {
|
|
114
113
|
type: String,
|
|
115
|
-
default: 'zh
|
|
114
|
+
default: 'zh'
|
|
116
115
|
},
|
|
117
116
|
color: {
|
|
118
117
|
type: String,
|
|
@@ -131,8 +130,6 @@ const props = defineProps({
|
|
|
131
130
|
const open = ref(false);
|
|
132
131
|
const curApproving = ref<PermissionType>();
|
|
133
132
|
const loading = ref(false);
|
|
134
|
-
const defaultCheckedIds = ref<string[]>([]);
|
|
135
|
-
const isAllOwn = ref(false);
|
|
136
133
|
let permissionList = ref<PermissionListType>([]);
|
|
137
134
|
let curStatus = ref<Record<string, any>>({
|
|
138
135
|
imageUrl: noauthority,
|
|
@@ -166,10 +163,7 @@ const getPermissions = async () => {
|
|
|
166
163
|
|
|
167
164
|
loading.value = true;
|
|
168
165
|
const res = await Http.getPermissions(params);
|
|
169
|
-
|
|
170
|
-
permissionList.value = datalist.data;
|
|
171
|
-
defaultCheckedIds.value = datalist.ownList;
|
|
172
|
-
isAllOwn.value = datalist.isAllOwn;
|
|
166
|
+
permissionList.value = useFormat(res.body || []);
|
|
173
167
|
curStatus.value = useStatus(permissionList.value, curApproving);
|
|
174
168
|
loading.value = false;
|
|
175
169
|
};
|
|
@@ -188,7 +182,7 @@ watchEffect(() => {
|
|
|
188
182
|
});
|
|
189
183
|
watch(() => props.locale, (cur, pre) => {
|
|
190
184
|
if (cur === pre) return;
|
|
191
|
-
|
|
185
|
+
setLocale(cur);
|
|
192
186
|
}, { immediate: true });
|
|
193
187
|
</script>
|
|
194
188
|
|
|
@@ -208,4 +202,5 @@ watch(() => props.locale, (cur, pre) => {
|
|
|
208
202
|
.crane-margin-right10 {
|
|
209
203
|
margin-right: 10px;
|
|
210
204
|
}
|
|
211
|
-
</style>
|
|
205
|
+
</style>
|
|
206
|
+
../hooks/useSort../hooks/useFormat
|
package/src/hooks/useFormat.ts
CHANGED
|
@@ -9,8 +9,6 @@ const StatusType = {
|
|
|
9
9
|
TEMP_OWNER: 'TEMP_OWNER'
|
|
10
10
|
}
|
|
11
11
|
export default function useFormat(tree: PermissionListType) {
|
|
12
|
-
const ownList: string[] = [];
|
|
13
|
-
let allCount: number = 0;
|
|
14
12
|
function sortTree(
|
|
15
13
|
tree: PermissionListType,
|
|
16
14
|
sortMap: Map<string | null, number>,
|
|
@@ -18,7 +16,7 @@ export default function useFormat(tree: PermissionListType) {
|
|
|
18
16
|
) {
|
|
19
17
|
return tree.map((node) => {
|
|
20
18
|
node.key = node.feature;
|
|
21
|
-
|
|
19
|
+
|
|
22
20
|
if (!node.children || node.children.length === 0) {
|
|
23
21
|
node.categoryVOS = (node.categoryVOS || []).filter((item: any) => item.configWay !== Category.AUTO);
|
|
24
22
|
|
|
@@ -28,13 +26,8 @@ export default function useFormat(tree: PermissionListType) {
|
|
|
28
26
|
|
|
29
27
|
if ([StatusType.OWNER].includes(node.businessApplyType) && !node.categoryVOS.length) {
|
|
30
28
|
node.disabled = true;
|
|
31
|
-
ownList.push(node.feature);
|
|
32
29
|
}
|
|
33
30
|
} else {
|
|
34
|
-
// 如果当前节点的所有自节点都符合[StatusType.OWNER].includes(node.businessApplyType) && !node.categoryVOS.length;那么也把当前featrue放到ownList中
|
|
35
|
-
if (node.children.every((child) => [StatusType.OWNER].includes(child.businessApplyType) && !child?.categoryVOS?.length)) {
|
|
36
|
-
ownList.push(node.feature);
|
|
37
|
-
}
|
|
38
31
|
// 递归对子节点进行排序
|
|
39
32
|
node.children = sortTree(node.children, sortMap, levelSortMap);
|
|
40
33
|
|
|
@@ -42,8 +35,7 @@ export default function useFormat(tree: PermissionListType) {
|
|
|
42
35
|
if (node.children.every((child) => child.disabled)) {
|
|
43
36
|
node.disabled = true;
|
|
44
37
|
}
|
|
45
|
-
}
|
|
46
|
-
|
|
38
|
+
}
|
|
47
39
|
|
|
48
40
|
return node;
|
|
49
41
|
}).sort((a, b) => {
|
|
@@ -59,10 +51,6 @@ export default function useFormat(tree: PermissionListType) {
|
|
|
59
51
|
const sortMap = new Map(sort.map((value, index) => [value, index]));
|
|
60
52
|
const levelSortMap = new Map(levelSort.map((value, index) => [value, index]));
|
|
61
53
|
|
|
62
|
-
return
|
|
63
|
-
data: sortTree(tree, sortMap, levelSortMap),
|
|
64
|
-
ownList,
|
|
65
|
-
isAllOwn: allCount === ownList.length
|
|
66
|
-
};
|
|
54
|
+
return sortTree(tree, sortMap, levelSortMap);
|
|
67
55
|
}
|
|
68
56
|
|
package/src/i18n/en-US.ts
CHANGED
|
@@ -1,57 +1,56 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
permissionApply: '
|
|
3
|
-
applyPermission: '
|
|
4
|
-
applyReason: '
|
|
5
|
-
approvalProcess: '
|
|
6
|
-
applyReasonPlaceholder: '
|
|
7
|
-
applyReasonTips: '
|
|
8
|
-
cancel: '
|
|
9
|
-
submit: '
|
|
10
|
-
close: '
|
|
11
|
-
viewApprovalDetail: '
|
|
12
|
-
applyMore: '
|
|
13
|
-
successTips: '
|
|
14
|
-
resoultTitle: '
|
|
15
|
-
start: '
|
|
16
|
-
end: '
|
|
17
|
-
noNeed: '
|
|
18
|
-
adaptDepartment: '
|
|
19
|
-
noApprovalProcess: '
|
|
20
|
-
excessTips: '
|
|
21
|
-
unavailableTips: '
|
|
22
|
-
appliedTips: '
|
|
23
|
-
unapplyTips: '
|
|
24
|
-
callManager: '
|
|
25
|
-
manager: '
|
|
26
|
-
availableTime: '
|
|
27
|
-
selectPlaceholder: '
|
|
28
|
-
reasonPlaceholder: '
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
clickToApply: '
|
|
34
|
-
noPermissionTips: '
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
2
|
+
permissionApply: 'Permission Application',
|
|
3
|
+
applyPermission: 'Apply for Permission',
|
|
4
|
+
applyReason: 'Application Reason',
|
|
5
|
+
approvalProcess: 'Approval Process',
|
|
6
|
+
applyReasonPlaceholder: 'Please describe the reason for application and usage scenarios in as much detail as possible. Avoid simply stating "work requirements" to prevent delays in the approval process.',
|
|
7
|
+
applyReasonTips: 'Example: Due to requirements of XX project, need to view/operate XXXX scenario/issue, which involves the use of XXX permission, hence submitting this application!',
|
|
8
|
+
cancel: 'Cancel',
|
|
9
|
+
submit: 'Confirm',
|
|
10
|
+
close: 'Close',
|
|
11
|
+
viewApprovalDetail: 'View Approval Details',
|
|
12
|
+
applyMore: 'Apply for Other Permissions',
|
|
13
|
+
successTips: 'Application submitted. Relevant permissions will be granted upon approval.',
|
|
14
|
+
resoultTitle: 'Operation Result Feedback',
|
|
15
|
+
start: 'Initiate',
|
|
16
|
+
end: 'End',
|
|
17
|
+
noNeed: 'No Approval Required',
|
|
18
|
+
adaptDepartment: 'Applicable Department',
|
|
19
|
+
noApprovalProcess: 'No Approval Process',
|
|
20
|
+
excessTips: 'Maximum {number} permissions can be applied for at once',
|
|
21
|
+
unavailableTips: 'You currently don\'t have permission to view/operate this page. Please click the button below to apply.',
|
|
22
|
+
appliedTips: 'Permission has been applied, currently {status}...',
|
|
23
|
+
unapplyTips: 'You don\'t have permission to view/operate this page, and there are no applicable permissions you can apply for in this page.',
|
|
24
|
+
callManager: 'If needed, please contact the system administrator',
|
|
25
|
+
manager: 'System Administrator',
|
|
26
|
+
availableTime: 'Validity Period',
|
|
27
|
+
selectPlaceholder: 'Please select permission point',
|
|
28
|
+
reasonPlaceholder: 'Please enter application reason',
|
|
29
|
+
pleaseChoose: 'Please select',
|
|
30
|
+
maxCountTips: 'Maximum {count} permissions can be applied for at once',
|
|
31
|
+
maxLengthTips: 'Maximum {length} characters',
|
|
32
|
+
today: 'Expires today',
|
|
33
|
+
clickToApply: 'Click to apply for permission',
|
|
34
|
+
noPermissionTips: 'No permission points under this menu',
|
|
35
|
+
lastDays: '{count} days',
|
|
36
|
+
categoryTips: 'Your current data scope is as follows:',
|
|
37
|
+
empty: 'Empty',
|
|
38
|
+
category: 'Data Permission',
|
|
39
|
+
categotySelectTips: 'The selected permission above includes data permissions. Please apply for/change the data scope according to actual work requirements.',
|
|
40
|
+
categoryChangeTips: 'Reminder: The data permission scope you selected is relatively large! Please confirm whether your actual work scenario requires full access to 「{category}」permission, and clearly state it in the application reason to avoid rejection!',
|
|
42
41
|
levels: {
|
|
43
|
-
L1: '
|
|
44
|
-
L2: '
|
|
45
|
-
L3: '
|
|
42
|
+
L1: 'Low',
|
|
43
|
+
L2: 'Medium',
|
|
44
|
+
L3: 'High',
|
|
46
45
|
},
|
|
47
46
|
status: {
|
|
48
|
-
PENDING: '
|
|
49
|
-
NO: '
|
|
50
|
-
OWNER: '
|
|
51
|
-
TEMP_OWNER: '
|
|
47
|
+
PENDING: 'Pending Approval',
|
|
48
|
+
NO: 'Not Applicable',
|
|
49
|
+
OWNER: 'Permanently Owned',
|
|
50
|
+
TEMP_OWNER: 'Temporarily Owned',
|
|
52
51
|
},
|
|
53
52
|
operationType: {
|
|
54
|
-
QUERY: '
|
|
55
|
-
MANAGE: '
|
|
53
|
+
QUERY: 'Query',
|
|
54
|
+
MANAGE: 'Operation',
|
|
56
55
|
}
|
|
57
|
-
};
|
|
56
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
permissionApply: 'Aplikasi Izin',
|
|
3
|
+
applyPermission: 'Ajukan Izin',
|
|
4
|
+
applyReason: 'Alasan Pengajuan',
|
|
5
|
+
approvalProcess: 'Proses Persetujuan',
|
|
6
|
+
applyReasonPlaceholder: 'Harap jelaskan alasan pengajuan dan skenario penggunaan selengkap mungkin. Hindari hanya menyebutkan "kebutuhan kerja" untuk mencegah penundaan dalam proses persetujuan.',
|
|
7
|
+
applyReasonTips: 'Contoh: Karena kebutuhan proyek XX, perlu melihat/mengoperasikan skenario/masalah XXXX, yang melibatkan penggunaan izin XXX, oleh karena itu mengajukan permohonan ini!',
|
|
8
|
+
cancel: 'Batal',
|
|
9
|
+
submit: 'Konfirmasi',
|
|
10
|
+
close: 'Tutup',
|
|
11
|
+
viewApprovalDetail: 'Lihat Detail Persetujuan',
|
|
12
|
+
applyMore: 'Ajukan Izin Lainnya',
|
|
13
|
+
successTips: 'Pengajuan telah dikirim. Izin terkait akan diberikan setelah disetujui.',
|
|
14
|
+
resoultTitle: 'Umpan Balik Hasil Operasi',
|
|
15
|
+
start: 'Mulai',
|
|
16
|
+
end: 'Selesai',
|
|
17
|
+
noNeed: 'Tidak Perlu Persetujuan',
|
|
18
|
+
adaptDepartment: 'Departemen yang Berlaku',
|
|
19
|
+
noApprovalProcess: 'Tidak Ada Proses Persetujuan',
|
|
20
|
+
excessTips: 'Maksimal {number} izin dapat diajukan sekaligus',
|
|
21
|
+
unavailableTips: 'Anda saat ini tidak memiliki izin untuk melihat/mengoperasikan halaman ini. Silakan klik tombol di bawah untuk mengajukan.',
|
|
22
|
+
appliedTips: 'Izin telah diajukan, saat ini {status}...',
|
|
23
|
+
unapplyTips: 'Anda tidak memiliki izin untuk melihat/mengoperasikan halaman ini, dan tidak ada izin yang dapat diajukan di halaman ini.',
|
|
24
|
+
callManager: 'Jika diperlukan, silakan hubungi administrator sistem',
|
|
25
|
+
manager: 'Administrator Sistem',
|
|
26
|
+
availableTime: 'Masa Berlaku',
|
|
27
|
+
selectPlaceholder: 'Silakan pilih titik izin',
|
|
28
|
+
reasonPlaceholder: 'Silakan masukkan alasan pengajuan',
|
|
29
|
+
pleaseChoose: 'Silakan pilih',
|
|
30
|
+
maxCountTips: 'Maksimal {count} izin dapat diajukan sekaligus',
|
|
31
|
+
maxLengthTips: 'Maksimal {length} karakter',
|
|
32
|
+
today: 'Kadaluarsa hari ini',
|
|
33
|
+
clickToApply: 'Klik untuk mengajukan izin',
|
|
34
|
+
noPermissionTips: 'Tidak ada titik izin di menu ini',
|
|
35
|
+
lastDays: '{count} hari',
|
|
36
|
+
categoryTips: 'Cakupan data Anda saat ini adalah sebagai berikut:',
|
|
37
|
+
empty: 'Kosong',
|
|
38
|
+
category: 'Izin Data',
|
|
39
|
+
categotySelectTips: 'Izin yang dipilih di atas mencakup izin data. Silakan ajukan/ubah cakupan data sesuai kebutuhan kerja aktual.',
|
|
40
|
+
categoryChangeTips: 'Peringatan: Cakupan izin data yang Anda pilih relatif besar! Harap konfirmasi apakah skenario kerja aktual Anda memerlukan akses penuh ke izin 「{category}」, dan jelaskan secara jelas dalam alasan pengajuan untuk menghindari penolakan!',
|
|
41
|
+
levels: {
|
|
42
|
+
L1: 'Rendah',
|
|
43
|
+
L2: 'Sedang',
|
|
44
|
+
L3: 'Tinggi',
|
|
45
|
+
},
|
|
46
|
+
status: {
|
|
47
|
+
PENDING: 'Menunggu Persetujuan',
|
|
48
|
+
NO: 'Tidak Dapat Diajukan',
|
|
49
|
+
OWNER: 'Dimiliki Secara Permanen',
|
|
50
|
+
TEMP_OWNER: 'Dimiliki Sementara',
|
|
51
|
+
},
|
|
52
|
+
operationType: {
|
|
53
|
+
QUERY: 'Kueri',
|
|
54
|
+
MANAGE: 'Operasi',
|
|
55
|
+
}
|
|
56
|
+
};
|
package/src/i18n/index.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import enUS from './en-US';
|
|
2
2
|
import zhCH from './zh-CH';
|
|
3
|
+
import inID from './in-ID';
|
|
3
4
|
|
|
4
5
|
const language: {
|
|
5
6
|
[key: string]: any;
|
|
6
7
|
} = {
|
|
7
|
-
'zh
|
|
8
|
-
'en
|
|
8
|
+
'zh': zhCH,
|
|
9
|
+
'en': enUS,
|
|
10
|
+
'id': inID,
|
|
9
11
|
};
|
|
10
12
|
|
|
13
|
+
|
|
11
14
|
export default language;
|
package/src/i18n/zh-CH.ts
CHANGED
|
@@ -3,7 +3,6 @@ export default {
|
|
|
3
3
|
applyPermission: '申请权限',
|
|
4
4
|
applyReason: '申请理由',
|
|
5
5
|
approvalProcess: '审批流程',
|
|
6
|
-
isAllOwnTips: '您当前已拥有该页面所有权限,无需申请',
|
|
7
6
|
applyReasonPlaceholder: '请尽可能详细说明申请原因和使用场景,不要只填写“工作需要”之类的理由,以免影响你获取权限的审批时间。',
|
|
8
7
|
applyReasonTips: '示例:由于XX项目需要,需要查看/操作XXXX场景/问题,涉及到XXX权限的使用,因此提交申请!',
|
|
9
8
|
cancel: '取消',
|
|
@@ -39,14 +38,6 @@ export default {
|
|
|
39
38
|
category: '数据权限',
|
|
40
39
|
categotySelectTips: '上方选中的权限包含数据权限,请根据实际工作需要申请/更改数据范围。',
|
|
41
40
|
categoryChangeTips: '提醒:您选择的数据权限范围较大!请确认实际工作场景是否需要全量「{category}」权限,并在申请理由中写明,避免审批不通过!',
|
|
42
|
-
availiables: {
|
|
43
|
-
SEVEN_DAYS: '7天',
|
|
44
|
-
THIRTY_DAYS: '30天',
|
|
45
|
-
SIXTY_DAYS: '60天',
|
|
46
|
-
NINETY_DAYS: '90天',
|
|
47
|
-
ONE_YEARS: '1年',
|
|
48
|
-
FOREVER: '永久有效',
|
|
49
|
-
},
|
|
50
41
|
levels: {
|
|
51
42
|
L1: '低',
|
|
52
43
|
L2: '中',
|
package/src/typings/index.d.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import language from '../i18n';
|
|
2
2
|
|
|
3
|
+
const localkey = 'yqg_permission_sdk_locale';
|
|
4
|
+
|
|
3
5
|
type optionsType = {
|
|
4
6
|
[key: string]: any;
|
|
5
7
|
};
|
|
6
8
|
const t = (key: string, options?: optionsType) => {
|
|
7
9
|
// key的格式为:'xxx.xxx.xxx'//国际化todo
|
|
8
|
-
const en = localStorage.getItem(
|
|
10
|
+
const en = localStorage.getItem(localkey) || 'en';
|
|
11
|
+
console.log('en', localStorage.getItem(localkey));
|
|
9
12
|
const keys = key.split('.');
|
|
10
|
-
let result = language[en as string] || language['en
|
|
13
|
+
let result = language[en as string] || language['en'];
|
|
11
14
|
for (let i = 0; i < keys.length; i++) {
|
|
12
15
|
result = result[keys[i]];
|
|
13
16
|
}
|
|
@@ -54,3 +57,15 @@ export const deepTree = (tree: any[], fn: (item:any) => void) => {
|
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
export default t;
|
|
60
|
+
|
|
61
|
+
export const setLocale = (locale: string) => {
|
|
62
|
+
let finalLocale = '';
|
|
63
|
+
if (locale.startsWith('zh')) {
|
|
64
|
+
finalLocale = 'zh';
|
|
65
|
+
} else if (locale.startsWith('en')) {
|
|
66
|
+
finalLocale = 'en';
|
|
67
|
+
} else if (locale.startsWith('id') || locale.startsWith('in')) {
|
|
68
|
+
finalLocale = 'id';
|
|
69
|
+
}
|
|
70
|
+
localStorage.setItem(localkey, finalLocale);
|
|
71
|
+
}
|