@yqg/permission 1.0.1-beta.0 → 1.0.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/.arcconfig +8 -0
- package/.husky/commit-msg +20 -0
- package/.husky/pre-commit +4 -0
- package/README.md +126 -3
- package/arcanist/.phutil_module_cache +1 -0
- package/arcanist/__phutil_library_init__.php +3 -0
- package/arcanist/__phutil_library_map__.php +18 -0
- package/arcanist/lint/engine/YqgWebDiffLintEngine.php +68 -0
- package/commitlint.config.js +32 -0
- package/dist/{apply-modal-BwBRAOgh.js → apply-modal-SzDVxN-2.js} +1913 -1890
- package/dist/card.png +0 -0
- package/dist/{checkbox-item-DpihGkb7.js → checkbox-item-BlnmEaiY.js} +972 -963
- package/dist/dialog.png +0 -0
- package/dist/image.png +0 -0
- package/dist/{index-yyuuant8.js → index-DFUPlAqp.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/index.umd.cjs +56 -56
- package/dist/{yqg-permission-DBFdrj20.js → yqg-permission-Cfoxcf-d.js} +2338 -2297
- package/eslint.config.js +26 -0
- package/package.json +10 -4
- package/public/card.png +0 -0
- package/public/dialog.png +0 -0
- package/public/image.png +0 -0
- package/src/App.vue +12 -4
- package/src/axios/axios.ts +1 -1
- package/src/components/apply-modal.vue +34 -7
- package/src/components/approval-steps.vue +10 -8
- package/src/components/checkbox-item.vue +24 -22
- package/src/components/success-modal.vue +10 -7
- package/src/components/yqg-permission.vue +60 -23
- package/src/i18n/en-US.ts +6 -1
- package/src/i18n/zh-CH.ts +6 -1
- package/src/main.ts +1 -1
- package/src/typings/index.d.ts +5 -0
- package/src/vite-env.d.ts +1 -1
- package/src/yqg-permission/index.ts +2 -2
- package/tsconfig.app.json +10 -1
- package/tsconfig.json +2 -2
- package/dist/vite.svg +0 -1
- package/public/vite.svg +0 -1
package/eslint.config.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import typescriptEslintParser from '@typescript-eslint/parser';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
parser: typescriptEslintParser,
|
|
5
|
+
parserOptions: {
|
|
6
|
+
ecmaVersion: 2020,
|
|
7
|
+
sourceType: 'module',
|
|
8
|
+
},
|
|
9
|
+
plugins: ['@typescript-eslint', 'vue'],
|
|
10
|
+
extends: [
|
|
11
|
+
'plugin:@typescript-eslint/recommended',
|
|
12
|
+
'plugin:vue/vue3-recommended',
|
|
13
|
+
],
|
|
14
|
+
rules: {
|
|
15
|
+
'vue/no-multiple-template-root': 'off',
|
|
16
|
+
},
|
|
17
|
+
env: {
|
|
18
|
+
browser: true,
|
|
19
|
+
node: true,
|
|
20
|
+
},
|
|
21
|
+
settings: {
|
|
22
|
+
'import/resolver': {
|
|
23
|
+
typescript: {},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yqg/permission",
|
|
3
|
-
"version": "1.0.1
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"module": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
|
-
|
|
7
|
+
"publishConfig": {
|
|
8
8
|
"access": "public",
|
|
9
9
|
"registry": "https://registry.npmjs.org/"
|
|
10
10
|
},
|
|
@@ -15,13 +15,19 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@ant-design/icons-vue": "^7.0.1",
|
|
18
|
+
"@commitlint/cli": "^19.5.0",
|
|
19
|
+
"@commitlint/config-conventional": "^19.5.0",
|
|
18
20
|
"ant-design-vue": "4.x",
|
|
19
21
|
"axios": "^1.7.7",
|
|
20
22
|
"vite-plugin-css-injected-by-js": "^3.5.2",
|
|
21
23
|
"vue": "^3.5.12"
|
|
22
24
|
},
|
|
23
25
|
"devDependencies": {
|
|
26
|
+
"@typescript-eslint/parser": "^8.13.0",
|
|
24
27
|
"@vitejs/plugin-vue": "^5.1.4",
|
|
28
|
+
"eslint": "^9.14.0",
|
|
29
|
+
"husky": "^9",
|
|
30
|
+
"lint-staged": "^13.2.0",
|
|
25
31
|
"typescript": "~5.5.4",
|
|
26
32
|
"vite": "^5.4.9",
|
|
27
33
|
"vue-tsc": "^2.1.8"
|
package/public/card.png
ADDED
|
Binary file
|
|
Binary file
|
package/public/image.png
ADDED
|
Binary file
|
package/src/App.vue
CHANGED
|
@@ -8,7 +8,14 @@ type LocaleType = 'zh-CN' | 'en-US' | 'id-ID' | 'fil-PH';
|
|
|
8
8
|
const color = ref<string>('#1677ff');
|
|
9
9
|
const locale = ref<LocaleType>('zh-CN');
|
|
10
10
|
|
|
11
|
-
const permissions = reactive(['
|
|
11
|
+
const permissions = reactive(['CRANE.ROLE.QUERY',
|
|
12
|
+
'CRANE.ROLE.CREATE',
|
|
13
|
+
'CRANE.ROLE.UPDATE',
|
|
14
|
+
'CRANE.ROLE.DELETE',
|
|
15
|
+
'CRANE.ROLE.PERMISSION_ASSIGN',
|
|
16
|
+
'CRANE.ROLE.EMPLOYEE_ASSIGN',
|
|
17
|
+
'CRANE.ROLE.DETAIL_QUERY',
|
|
18
|
+
'CRANE.ROLE.EXPORT']);
|
|
12
19
|
// const permissions = reactive(['CRANE.BUSINESS.QUERY', 'RANE.BUSINESS.CREATE', 'CRANE.BUSINESS.UPDATE', 'CRANE.BUSINESS.DELETE']);
|
|
13
20
|
const changeColor = () => {
|
|
14
21
|
color.value = color.value === '#f00' ? '#1677ff' : '#f00';
|
|
@@ -28,13 +35,14 @@ const changeLocale = () => {
|
|
|
28
35
|
<div>1:默认组件</div>
|
|
29
36
|
<!-- 03541 -->
|
|
30
37
|
<!-- 02124 -->
|
|
38
|
+
<!-- 05184 -->
|
|
31
39
|
<yqg-permission
|
|
32
40
|
:permissions="permissions"
|
|
33
|
-
workNumber="
|
|
34
|
-
businessCode="
|
|
41
|
+
workNumber="05181"
|
|
42
|
+
businessCode="CRANE"
|
|
35
43
|
:color="color"
|
|
36
44
|
:locale="locale"
|
|
37
|
-
@
|
|
45
|
+
@onSuccess="() => {console.log('成功')}"
|
|
38
46
|
>
|
|
39
47
|
</yqg-permission>
|
|
40
48
|
</div>
|
package/src/axios/axios.ts
CHANGED
|
@@ -8,7 +8,7 @@ const YQG_NOT_LOGIN = 10008;
|
|
|
8
8
|
axios.defaults.withCredentials = true;
|
|
9
9
|
// instance.defaults.paramsSerializer = (params) => qs.stringify(params, { arrayFormat: 'repeat' });
|
|
10
10
|
|
|
11
|
-
axios.defaults.headers.common['Accept-Language'] = localStorage.getItem('permission_locale')
|
|
11
|
+
axios.defaults.headers.common['Accept-Language'] = localStorage.getItem('permission_locale');
|
|
12
12
|
|
|
13
13
|
axios.interceptors.response.use(
|
|
14
14
|
(res: any) => {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
width="800px"
|
|
6
6
|
@ok="handleOk"
|
|
7
7
|
:okText="t('submit')"
|
|
8
|
+
:maskClosable="false"
|
|
9
|
+
:ok-button-props="{ loading: loading }"
|
|
8
10
|
:cancelText="t('cancel')">
|
|
9
11
|
<Form
|
|
10
12
|
ref="formRef"
|
|
@@ -33,10 +35,16 @@
|
|
|
33
35
|
|
|
34
36
|
<FormItem
|
|
35
37
|
name="applyReason"
|
|
36
|
-
:label="t('applyReason')"
|
|
37
|
-
:rules="[{
|
|
38
|
+
:label="t('applyReason')"
|
|
39
|
+
:rules="[{
|
|
40
|
+
required: true, message: t('reasonPlaceholder'), trigger: ['change', 'blur']
|
|
41
|
+
}, {
|
|
42
|
+
max: 300, message: t('maxLengthTips', {length: 300}), trigger: ['change', 'blur']
|
|
43
|
+
}]">
|
|
38
44
|
<Textarea
|
|
39
|
-
v-model:value="formState.applyReason"
|
|
45
|
+
v-model:value.trim="formState.applyReason"
|
|
46
|
+
show-count
|
|
47
|
+
:maxlength="300"
|
|
40
48
|
:placeholder="t('applyReasonPlaceholder')"
|
|
41
49
|
:auto-size="{ minRows: 2, maxRows: 5 }">
|
|
42
50
|
</Textarea>
|
|
@@ -61,7 +69,6 @@
|
|
|
61
69
|
</template>
|
|
62
70
|
<script lang="ts" setup>
|
|
63
71
|
import {
|
|
64
|
-
defineModel,
|
|
65
72
|
reactive,
|
|
66
73
|
defineAsyncComponent,
|
|
67
74
|
toRef,
|
|
@@ -76,6 +83,7 @@
|
|
|
76
83
|
CheckboxGroup,
|
|
77
84
|
Textarea,
|
|
78
85
|
Tag,
|
|
86
|
+
message
|
|
79
87
|
} from 'ant-design-vue';
|
|
80
88
|
import SuccessModal from './success-modal.vue';
|
|
81
89
|
import ApprovalSteps from './approval-steps.vue';
|
|
@@ -105,11 +113,12 @@
|
|
|
105
113
|
},
|
|
106
114
|
|
|
107
115
|
});
|
|
108
|
-
const emit = defineEmits(['onSuccess']);
|
|
116
|
+
const emit = defineEmits(['onSubmit', 'onSuccess']);
|
|
109
117
|
const open = defineModel({
|
|
110
118
|
required: true,
|
|
111
119
|
default: false,
|
|
112
120
|
});
|
|
121
|
+
const loading = ref(false);
|
|
113
122
|
const permissionList = toRef(props, 'permissionList');
|
|
114
123
|
const businessCode = toRef(props, 'businessCode');
|
|
115
124
|
const submitWorkNumber = toRef(props, 'workNumber');
|
|
@@ -133,16 +142,22 @@
|
|
|
133
142
|
} else {
|
|
134
143
|
formState.applyReason += `、${item}`;
|
|
135
144
|
}
|
|
145
|
+
formRef.value.validateFields(['applyReason']);
|
|
136
146
|
}
|
|
137
147
|
|
|
138
148
|
const handleOk = async() => {
|
|
149
|
+
if (formState.roleIds.length > 5) {
|
|
150
|
+
return message.warning(t('maxCountTips', {count: 5}));
|
|
151
|
+
}
|
|
139
152
|
formRef.value.validate().then(async() => {
|
|
153
|
+
loading.value = true;
|
|
140
154
|
const params = getParams();
|
|
141
155
|
let res = await Http.submitApply(params);
|
|
142
156
|
const url = res?.body?.oaFlowUrl;
|
|
143
157
|
open.value = false;
|
|
144
|
-
|
|
145
|
-
|
|
158
|
+
loading.value = false;
|
|
159
|
+
emit('onSubmit');
|
|
160
|
+
successModal.value?.countDown(url, () => emit('onSuccess'));
|
|
146
161
|
})
|
|
147
162
|
};
|
|
148
163
|
|
|
@@ -157,6 +172,10 @@
|
|
|
157
172
|
}
|
|
158
173
|
|
|
159
174
|
const onChangeHandler = throttle(async () => {
|
|
175
|
+
if (formState.roleIds.length > 1) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
160
179
|
if (!formState.roleIds.length) {
|
|
161
180
|
stepNodes.value = [];
|
|
162
181
|
return;
|
|
@@ -167,6 +186,14 @@
|
|
|
167
186
|
stepNodes.value = res?.body?.nodes || [];
|
|
168
187
|
}, 0)
|
|
169
188
|
|
|
189
|
+
watch(() => formState.roleIds, (val) => {
|
|
190
|
+
// 写到watch里避免闪烁
|
|
191
|
+
if (val.length > 1) {
|
|
192
|
+
formState.roleIds.pop();
|
|
193
|
+
message.warning(t('maxCountTips', {count: 5}));
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
|
|
170
197
|
watch(() => open.value, (cur) => {
|
|
171
198
|
if (cur) {
|
|
172
199
|
formRef.value?.resetFields();
|
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
<div v-if="stepNodes?.length > 1" class="crane-step-wraper">
|
|
3
3
|
<div v-for="(item, index) in stepNodes" :key="item.auditorName" class="crane-step-node">
|
|
4
4
|
<span style="white-space: nowrap;">
|
|
5
|
-
{{ item.auditorName }}
|
|
5
|
+
{{ item.auditorName }}
|
|
6
|
+
<Popover v-if="item.employeeNameList?.length">
|
|
7
|
+
<template #content>
|
|
8
|
+
<div style="max-width: 400px;">
|
|
9
|
+
{{ item.employeeNameList.join('、')}}
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
<ExclamationCircleOutlined style="margin: 0 2px; color: #1677ff;"/>
|
|
13
|
+
</Popover>
|
|
14
|
+
{{ getSubTip(index) }}
|
|
6
15
|
</span>
|
|
7
16
|
|
|
8
|
-
<Popover v-if="item.employeeNameList?.length">
|
|
9
|
-
<template #content>
|
|
10
|
-
{{item.auditorName}}:{{ item.employeeNameList.join(',')}}
|
|
11
|
-
</template>
|
|
12
|
-
<ExclamationCircleOutlined style="margin: 0 2px"/>
|
|
13
|
-
</Popover>
|
|
14
|
-
|
|
15
17
|
<img
|
|
16
18
|
v-if="index !== stepNodes.length - 1"
|
|
17
19
|
:src="arrowImg"
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="crane-checkbox-line">
|
|
3
|
-
<Checkbox
|
|
3
|
+
<Checkbox
|
|
4
|
+
:value="item.roleId"
|
|
5
|
+
:disabled="['OWNER', 'PENDING', 'NO'].includes(props.item.businessApplyType)"
|
|
6
|
+
@change="onCheck">
|
|
4
7
|
<div class="crane-flex-center crane-checkbox-label">
|
|
5
8
|
<Tag
|
|
6
9
|
v-if="item.securityLevel"
|
|
@@ -19,12 +22,26 @@
|
|
|
19
22
|
<span class="crane-text-overflow">{{ item.name }}</span>
|
|
20
23
|
</Popover>
|
|
21
24
|
<Tag
|
|
22
|
-
v-if="item.businessApplyType"
|
|
25
|
+
v-if="item.businessApplyType && item.businessApplyType !== 'TEMP_OWNER'"
|
|
23
26
|
:bordered="false"
|
|
24
27
|
class="crane-tag-position crane-margin-left-4 crane-margin-right-0"
|
|
25
|
-
:class="item.businessApplyType
|
|
26
|
-
{{ statusMap[item.businessApplyType]
|
|
28
|
+
:class="['PENDING', 'TEMP_OWNER'].includes(item.businessApplyType) ? '' : 'crane-disabled-color'">
|
|
29
|
+
{{ statusMap[item.businessApplyType] }}
|
|
27
30
|
</Tag>
|
|
31
|
+
<Popover>
|
|
32
|
+
<template #content>
|
|
33
|
+
<span v-if="item?.ownStatusVO?.dayDiff>0">{{t('lastDays', {count: item?.ownStatusVO?.dayDiff})}}</span>
|
|
34
|
+
<span v-else>{{ t('taday') }}</span>
|
|
35
|
+
</template>
|
|
36
|
+
<Tag
|
|
37
|
+
v-if="item.businessApplyType === 'TEMP_OWNER'"
|
|
38
|
+
:bordered="false"
|
|
39
|
+
class="crane-tag-position crane-margin-left-4 crane-margin-right-0"
|
|
40
|
+
:class="['PENDING'].includes(item.businessApplyType) ? '' : 'crane-disabled-color'">
|
|
41
|
+
{{ statusMap[item.businessApplyType] }}
|
|
42
|
+
</Tag>
|
|
43
|
+
</Popover>
|
|
44
|
+
|
|
28
45
|
</div>
|
|
29
46
|
</Checkbox>
|
|
30
47
|
|
|
@@ -39,7 +56,7 @@
|
|
|
39
56
|
<template #content>
|
|
40
57
|
{{t('adaptDepartment')}}:{{ item.relatedDepartments.map((item: any) => {
|
|
41
58
|
return item.name;
|
|
42
|
-
}).join('
|
|
59
|
+
}).join('、') }}
|
|
43
60
|
</template>
|
|
44
61
|
<span class="crane-flex-center crane-margin-left-4">
|
|
45
62
|
<img :src="departmentImg" height="14" width="14">
|
|
@@ -47,7 +64,7 @@
|
|
|
47
64
|
</span>
|
|
48
65
|
</Popover>
|
|
49
66
|
|
|
50
|
-
<span v-
|
|
67
|
+
<span v-if="checkedIds.includes(item.roleId)" class="crane-week-color crane-margin-left-12">
|
|
51
68
|
{{t('availableTime')}}:
|
|
52
69
|
<Select
|
|
53
70
|
v-model:value="validTime"
|
|
@@ -81,21 +98,6 @@
|
|
|
81
98
|
text: t('levels.L3')
|
|
82
99
|
},
|
|
83
100
|
};
|
|
84
|
-
|
|
85
|
-
const statusMap:StatusMapType = {
|
|
86
|
-
PENDING: {
|
|
87
|
-
color: 'orange',
|
|
88
|
-
text: t('status.PENDING')
|
|
89
|
-
},
|
|
90
|
-
OWNER: {
|
|
91
|
-
color: 'green',
|
|
92
|
-
text: t('status.OWNER')
|
|
93
|
-
},
|
|
94
|
-
NO: {
|
|
95
|
-
color: 'red',
|
|
96
|
-
text: t('status.NO')
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
101
|
|
|
100
102
|
let props = defineProps({
|
|
101
103
|
item: {
|
|
@@ -112,7 +114,7 @@
|
|
|
112
114
|
}
|
|
113
115
|
});
|
|
114
116
|
const timeStatusOptions = formatOptions('availiables');
|
|
115
|
-
|
|
117
|
+
const statusMap = t('status');
|
|
116
118
|
const validTime = ref('');
|
|
117
119
|
|
|
118
120
|
//1登录人所在部门 = 权限适用范围,都默认90天,不需要区分等级和类型,
|
|
@@ -9,22 +9,25 @@
|
|
|
9
9
|
|
|
10
10
|
const [modal, contextHolder] = Modal.useModal();
|
|
11
11
|
|
|
12
|
-
const countDown = (url: string) => {
|
|
12
|
+
const countDown = (url: string, callback?: ()=>void) => {
|
|
13
13
|
let secondsToGo = 10;
|
|
14
14
|
const modal1 = modal.confirm({
|
|
15
15
|
title: t('resoultTitle'),
|
|
16
16
|
content: t('successTips'),
|
|
17
17
|
cancelText: `${t('close')}(${secondsToGo}s)`,
|
|
18
18
|
okText:`${t('viewApprovalDetail')}>>`,
|
|
19
|
-
wrapClassName: '
|
|
19
|
+
wrapClassName: 'yqg-permission-modal-wrap',
|
|
20
20
|
icon: createVNode(CheckCircleFilled, {style: 'color: #52c41a;'}),
|
|
21
21
|
onOk: () => {
|
|
22
22
|
window.open(url);
|
|
23
|
-
|
|
23
|
+
modal1.destroy();
|
|
24
|
+
callback && callback();
|
|
25
|
+
window.YQG_PERMISSION_CALLBACK && window.YQG_PERMISSION_CALLBACK();
|
|
24
26
|
},
|
|
25
27
|
onCancel: () => {
|
|
26
28
|
modal1.destroy();
|
|
27
|
-
|
|
29
|
+
callback && callback();
|
|
30
|
+
window.YQG_PERMISSION_CALLBACK && window.YQG_PERMISSION_CALLBACK();
|
|
28
31
|
},
|
|
29
32
|
});
|
|
30
33
|
|
|
@@ -44,8 +47,8 @@
|
|
|
44
47
|
defineExpose({countDown});
|
|
45
48
|
|
|
46
49
|
</script>
|
|
47
|
-
<style
|
|
48
|
-
|
|
49
|
-
text-align: center;
|
|
50
|
+
<style>
|
|
51
|
+
.yqg-permission-modal-wrap .yqg-permission-modal-confirm-btns {
|
|
52
|
+
text-align: center!important;
|
|
50
53
|
}
|
|
51
54
|
</style>
|
|
@@ -16,14 +16,15 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
</template>
|
|
18
18
|
<template v-else>
|
|
19
|
-
|
|
20
|
-
:src="curStatus.imageUrl"
|
|
21
|
-
height="200"
|
|
22
|
-
width="200"
|
|
23
|
-
style="margin-top: calc(50vh - 273px)" />
|
|
19
|
+
|
|
24
20
|
<!-- 可申请 -->
|
|
25
21
|
<template v-if="curStatus.status === statusMap.DEFAULT">
|
|
26
|
-
<
|
|
22
|
+
<img
|
|
23
|
+
:src="curStatus.imageUrl"
|
|
24
|
+
height="200"
|
|
25
|
+
width="200"
|
|
26
|
+
style="margin-top: calc(50vh - 273px)" />
|
|
27
|
+
<div class="crane-margin10">
|
|
27
28
|
{{ t('unavailableTips') }}
|
|
28
29
|
</div>
|
|
29
30
|
<div>
|
|
@@ -31,8 +32,13 @@
|
|
|
31
32
|
</div>
|
|
32
33
|
</template>
|
|
33
34
|
<!-- 审批中 -->
|
|
34
|
-
<template v-
|
|
35
|
-
<
|
|
35
|
+
<template v-if="curStatus.status === statusMap.PENDING">
|
|
36
|
+
<img
|
|
37
|
+
:src="curStatus.imageUrl"
|
|
38
|
+
height="200"
|
|
39
|
+
width="200"
|
|
40
|
+
style="margin-top: calc(50vh - 273px)" />
|
|
41
|
+
<div class="crane-margin10">
|
|
36
42
|
<span
|
|
37
43
|
class="crane-unapply"
|
|
38
44
|
v-html="t('appliedTips', {
|
|
@@ -41,19 +47,26 @@
|
|
|
41
47
|
</span>
|
|
42
48
|
</div>
|
|
43
49
|
<div>
|
|
44
|
-
<Button
|
|
50
|
+
<Button class="crane-margin-right10" @click="goViewApproval">{{t('viewApprovalDetail')}}</Button>
|
|
45
51
|
<Button type="primary" @click="showModal">+ {{t('applyMore')}}</Button>
|
|
46
52
|
</div>
|
|
47
53
|
</template>
|
|
48
54
|
<!-- 不可申请 -->
|
|
49
|
-
<div v-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
<div v-if="curStatus.status === statusMap.NO" class="crane-wraper">
|
|
56
|
+
<img
|
|
57
|
+
:src="curStatus.imageUrl"
|
|
58
|
+
height="200"
|
|
59
|
+
width="200"
|
|
60
|
+
style="margin-top: calc(50vh - 273px)" />
|
|
61
|
+
<div class="crane-margin10">
|
|
62
|
+
{{ t('unapplyTips') }}
|
|
63
|
+
<Popover>
|
|
64
|
+
<template #content>
|
|
65
|
+
<div style="max-width: 400px;">{{t('manager')}}: {{ curStatus.tips }}</div>
|
|
66
|
+
</template>
|
|
67
|
+
<span style="color: #1677ff;">{{t('callManager') }}</span>
|
|
68
|
+
</Popover>
|
|
69
|
+
</div>
|
|
57
70
|
</div>
|
|
58
71
|
</template>
|
|
59
72
|
</div>
|
|
@@ -63,7 +76,8 @@
|
|
|
63
76
|
:permissionList="permissionList"
|
|
64
77
|
:workNumber="workNumber"
|
|
65
78
|
:businessCode="businessCode"
|
|
66
|
-
@onSuccess="
|
|
79
|
+
@onSuccess="() => emit('onSuccess')"
|
|
80
|
+
@onSubmit="getPermissions">
|
|
67
81
|
</ApplyModal>
|
|
68
82
|
|
|
69
83
|
</ConfigProvider>
|
|
@@ -113,10 +127,11 @@
|
|
|
113
127
|
const emit = defineEmits(['onSuccess']);
|
|
114
128
|
|
|
115
129
|
const open = ref(false);
|
|
130
|
+
const curApproving = ref<PermissionType>();
|
|
116
131
|
let permissionList = ref<PermissionListType>([]);
|
|
117
132
|
let curStatus = ref<Record<string, any>>({
|
|
118
133
|
imageUrl: noauthority,
|
|
119
|
-
status:
|
|
134
|
+
status: '',
|
|
120
135
|
})
|
|
121
136
|
const allPermissions = computed(() => {
|
|
122
137
|
if (Array.isArray(props.permissions)) {
|
|
@@ -140,7 +155,7 @@
|
|
|
140
155
|
flattenData(data);
|
|
141
156
|
// 需要排序,规则:businessApplyType 为 null 在前面, PENDING. OWNER 在中间, NO 在后面
|
|
142
157
|
// 然后再根据 L1, L2, L3 排序
|
|
143
|
-
const sort = [ null, 'PENDING', 'OWNER', 'NO'];
|
|
158
|
+
const sort = [ null, 'TEMP_OWNER', 'PENDING', 'OWNER', 'NO'];
|
|
144
159
|
const levelSort = ['L1', 'L2', 'L3'];
|
|
145
160
|
arr.sort((a, b) => {
|
|
146
161
|
return sort.indexOf(a.businessApplyType) - sort.indexOf(b.businessApplyType) || levelSort.indexOf(a.securityLevel) - levelSort.indexOf(b.securityLevel);
|
|
@@ -149,10 +164,16 @@
|
|
|
149
164
|
}
|
|
150
165
|
|
|
151
166
|
const getStatus = (data: PermissionListType) => {
|
|
152
|
-
if (!data.length)
|
|
167
|
+
if (!data.length) {
|
|
168
|
+
return {
|
|
169
|
+
imageUrl: noauthority,
|
|
170
|
+
status: '',
|
|
171
|
+
};
|
|
172
|
+
}
|
|
153
173
|
const current = data.find((per) => per.businessApplyType === statusMap.PENDING);
|
|
154
174
|
const cannotApply = data.every((per) => per.businessApplyType === statusMap.NO);
|
|
155
175
|
if (current) {
|
|
176
|
+
curApproving.value = current;
|
|
156
177
|
return {
|
|
157
178
|
imageUrl: applyUrl,
|
|
158
179
|
status: statusMap.PENDING,
|
|
@@ -165,12 +186,22 @@
|
|
|
165
186
|
return {
|
|
166
187
|
imageUrl: noauthority,
|
|
167
188
|
status: statusMap.NO,
|
|
168
|
-
tips: data[0].admin?.map((item) => item.name)?.join('、'),
|
|
189
|
+
tips: data[0].admin?.map((item) => `${item.name}(${item.departmentName})`)?.join('、'),
|
|
169
190
|
};
|
|
170
191
|
};
|
|
171
|
-
return
|
|
192
|
+
return {
|
|
193
|
+
imageUrl: noauthority,
|
|
194
|
+
status: statusMap.DEFAULT,
|
|
195
|
+
}
|
|
172
196
|
};
|
|
173
197
|
|
|
198
|
+
const goViewApproval = () => {
|
|
199
|
+
console.log(curApproving.value)
|
|
200
|
+
if (curApproving.value?.oaFlowUrl) {
|
|
201
|
+
window.open(curApproving.value.oaFlowUrl);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
174
205
|
const getPermissions = async () => {
|
|
175
206
|
if (!allPermissions.value.length || !props.businessCode || !props.workNumber) return;
|
|
176
207
|
|
|
@@ -205,5 +236,11 @@
|
|
|
205
236
|
font-size: 14px;
|
|
206
237
|
white-space: nowrap;
|
|
207
238
|
}
|
|
239
|
+
.crane-margin10 {
|
|
240
|
+
margin: 10px;
|
|
241
|
+
}
|
|
242
|
+
.crane-margin-right10 {
|
|
243
|
+
margin-right: 10px;
|
|
244
|
+
}
|
|
208
245
|
</style>
|
|
209
246
|
|
package/src/i18n/en-US.ts
CHANGED
|
@@ -28,6 +28,10 @@ export default {
|
|
|
28
28
|
availableTime: '有效期',
|
|
29
29
|
selectPlaceholder: '请选择权限点',
|
|
30
30
|
reasonPlaceholder: '请输入申请理由',
|
|
31
|
+
maxCountTips: '一次最多只可申请{count}个权限',
|
|
32
|
+
maxLengthTips: '最多{length}个字符',
|
|
33
|
+
lastDays: '{count}天后到期',
|
|
34
|
+
taday: '今天到期',
|
|
31
35
|
availiables: {
|
|
32
36
|
SEVEN_DAYS: '7天',
|
|
33
37
|
THIRTY_DAYS: '30天',
|
|
@@ -43,7 +47,8 @@ export default {
|
|
|
43
47
|
status: {
|
|
44
48
|
PENDING: '审批中',
|
|
45
49
|
NO: '不可申请',
|
|
46
|
-
OWNER: '
|
|
50
|
+
OWNER: '永久拥有',
|
|
51
|
+
TEMP_OWNER: '临时拥有',
|
|
47
52
|
},
|
|
48
53
|
operationType: {
|
|
49
54
|
QUERY: '查询',
|
package/src/i18n/zh-CH.ts
CHANGED
|
@@ -28,6 +28,10 @@ export default {
|
|
|
28
28
|
availableTime: '有效期',
|
|
29
29
|
selectPlaceholder: '请选择权限点',
|
|
30
30
|
reasonPlaceholder: '请输入申请理由',
|
|
31
|
+
maxCountTips: '一次最多只可申请{count}个权限',
|
|
32
|
+
maxLengthTips: '最多{length}个字符',
|
|
33
|
+
lastDays: '{count}天后到期',
|
|
34
|
+
taday: '今天到期',
|
|
31
35
|
availiables: {
|
|
32
36
|
SEVEN_DAYS: '7天',
|
|
33
37
|
THIRTY_DAYS: '30天',
|
|
@@ -43,7 +47,8 @@ export default {
|
|
|
43
47
|
status: {
|
|
44
48
|
PENDING: '审批中',
|
|
45
49
|
NO: '不可申请',
|
|
46
|
-
OWNER: '
|
|
50
|
+
OWNER: '永久拥有',
|
|
51
|
+
TEMP_OWNER: '临时拥有',
|
|
47
52
|
},
|
|
48
53
|
operationType: {
|
|
49
54
|
QUERY: '查询',
|
package/src/main.ts
CHANGED
package/src/typings/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ declare enum LevelType {
|
|
|
7
7
|
declare enum StatusType {
|
|
8
8
|
PENDING = 'PENDING',
|
|
9
9
|
OWNER = 'OWNER',
|
|
10
|
+
TEMP_OWNER = 'TEMP_OWNER',
|
|
10
11
|
NO = 'NO'
|
|
11
12
|
};
|
|
12
13
|
|
|
@@ -25,6 +26,7 @@ declare type PermissionType = {
|
|
|
25
26
|
businessApplyType: StatusType;
|
|
26
27
|
oaFlowUrl?: string;
|
|
27
28
|
children?: PermissionListType;
|
|
29
|
+
ownStatusVO: any;
|
|
28
30
|
admin?: any[];
|
|
29
31
|
};
|
|
30
32
|
declare type PermissionListType = PermissionType[];
|
|
@@ -51,3 +53,6 @@ declare type formStateType = {
|
|
|
51
53
|
submitWorkNumber: string,
|
|
52
54
|
|
|
53
55
|
};
|
|
56
|
+
declare interface Window {
|
|
57
|
+
YQG_PERMISSION_CALLBACK?: () => void;
|
|
58
|
+
}
|
package/src/vite-env.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -18,7 +18,7 @@ interface Options {
|
|
|
18
18
|
interface YqgPermissionType {
|
|
19
19
|
tagName: string;
|
|
20
20
|
hasInit: boolean;
|
|
21
|
-
|
|
21
|
+
init: (options: Options) => void;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
class YqgPermission implements YqgPermissionType {
|
|
@@ -30,7 +30,7 @@ class YqgPermission implements YqgPermissionType {
|
|
|
30
30
|
this.hasInit = false;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
init(options?: Options): void {
|
|
34
34
|
if (!window || !window.customElements) {
|
|
35
35
|
console.error('yqg-permission is not supported in this environment');
|
|
36
36
|
return;
|
package/tsconfig.app.json
CHANGED
|
@@ -21,5 +21,14 @@
|
|
|
21
21
|
"noFallthroughCasesInSwitch": true
|
|
22
22
|
},
|
|
23
23
|
"composite": true,
|
|
24
|
-
"include": [
|
|
24
|
+
"include": [
|
|
25
|
+
"src/**/*.ts",
|
|
26
|
+
"src/**/*.d.ts",
|
|
27
|
+
"src/**/*.tsx",
|
|
28
|
+
"src/**/*.vue"
|
|
29
|
+
],
|
|
30
|
+
"exclude": [
|
|
31
|
+
"node_modules",
|
|
32
|
+
"vite.config.ts" // 如果不需要解析 vite.config.ts
|
|
33
|
+
],
|
|
25
34
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": [],
|
|
3
|
-
"references": [{ "path": "./tsconfig.app.json" }
|
|
3
|
+
"references": [{ "path": "./tsconfig.app.json" }],
|
|
4
4
|
"path": {
|
|
5
5
|
"@src": "./src"
|
|
6
6
|
},
|
|
7
7
|
"compilerOptions": {
|
|
8
8
|
"typeRoots": ["node_modules/ant-design-vue/typings", "./src/typings"]
|
|
9
|
-
}
|
|
9
|
+
},
|
|
10
10
|
}
|
package/dist/vite.svg
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|