@yqg/permission 1.0.9 → 1.0.11

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yqg/permission",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "type": "module",
@@ -14,20 +14,21 @@
14
14
  "preview": "vite preview"
15
15
  },
16
16
  "devDependencies": {
17
- "@ant-design/icons-vue": "^7.0.1",
17
+ "@ant-design/icons-vue": "^7.0.1",
18
18
  "@commitlint/cli": "^19.5.0",
19
19
  "@commitlint/config-conventional": "^19.5.0",
20
- "ant-design-vue": "4.x",
21
- "axios": "^1.7.7",
22
- "vite-plugin-css-injected-by-js": "^3.5.2",
23
- "vue": "^3.5.12",
20
+ "@types/vue": "^2.0.0",
24
21
  "@typescript-eslint/parser": "^8.13.0",
25
22
  "@vitejs/plugin-vue": "^5.1.4",
23
+ "ant-design-vue": "4.x",
24
+ "axios": "^1.7.7",
26
25
  "eslint": "^9.14.0",
27
26
  "husky": "^9",
28
27
  "lint-staged": "^13.2.0",
29
28
  "typescript": "~5.5.4",
30
29
  "vite": "^5.4.9",
30
+ "vite-plugin-css-injected-by-js": "^3.5.2",
31
+ "vue": "^3.5.12",
31
32
  "vue-tsc": "^2.1.8"
32
33
  }
33
34
  }
package/src/App.vue CHANGED
@@ -8,18 +8,20 @@ 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(['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']);
11
+ const permissions = reactive([
12
+ 'CRANE.ROLE.QUERY',
13
+ 'CRANE.ROLE.CREATE',
14
+ 'CRANE.ROLE.UPDATE',
15
+ 'CRANE.ROLE.DELETE',
16
+ 'CRANE.ROLE.PERMISSION_ASSIGN',
17
+ 'CRANE.ROLE.EMPLOYEE_ASSIGN',
18
+ 'CRANE.ROLE.DETAIL_QUERY',
19
+ 'CRANE.ROLE.EXPORT'
20
+ ]);
19
21
  // const permissions = reactive(['CRANE.BUSINESS.QUERY', 'RANE.BUSINESS.CREATE', 'CRANE.BUSINESS.UPDATE', 'CRANE.BUSINESS.DELETE']);
20
22
  const changeColor = () => {
21
23
  color.value = color.value === '#f00' ? '#1677ff' : '#f00';
22
- }
24
+ }
23
25
  const changeLocale = () => {
24
26
  locale.value = locale.value === 'zh-CN' ? 'en-US' : 'zh-CN';
25
27
  }
@@ -36,7 +38,7 @@ const changeLocale = () => {
36
38
  <!-- 03541 -->
37
39
  <!-- 02124 -->
38
40
  <!-- 05184 -->
39
- <yqg-permission
41
+ <yqg-permission
40
42
  :permissions="permissions"
41
43
  workNumber="05184"
42
44
  businessCode="CRANE"
@@ -48,7 +50,7 @@ const changeLocale = () => {
48
50
  </div>
49
51
  <!-- <data class="case-card">
50
52
  <div>2:文字组件</div>
51
- <yqg-permission
53
+ <yqg-permission
52
54
  :permissions="permissions"
53
55
  businessCode="CRANE"
54
56
  :color="color"
@@ -59,21 +61,21 @@ const changeLocale = () => {
59
61
  </data>
60
62
  -->
61
63
 
62
-
64
+
63
65
  <!-- <div class="case-card">
64
66
  <div>3:自定义</div>
65
- <yqg-permission
67
+ <yqg-permission
66
68
  :permissions="permissions"
67
69
  businessCode="CRANE"
68
70
  :color="color"
69
71
  workNumber="02124"
70
- locale="zh-CN"
72
+ locale="zh-CN"
71
73
  type="custom"
72
74
  >
73
75
  <div style="color: red;" slot="custom">自定义按钮</div>
74
76
  </yqg-permission>
75
77
  </div> -->
76
-
78
+
77
79
  </div>
78
80
 
79
81
  </template>
@@ -1,18 +1,18 @@
1
1
  <template>
2
2
  <div class="crane-checkbox-line">
3
- <Checkbox
3
+ <Checkbox
4
4
  :value="item.roleId"
5
5
  :disabled="['OWNER', 'PENDING', 'NO'].includes(props.item.businessApplyType)"
6
6
  @change="onCheck">
7
7
  <div class="crane-flex-center crane-checkbox-label">
8
8
  <Tag
9
- v-if="item.securityLevel"
10
- :bordered="false"
9
+ v-if="item.securityLevel"
10
+ :bordered="false"
11
11
  :color="levelMap[item.securityLevel].color"
12
12
  class="crane-tag-position">
13
13
  {{ levelMap[item.securityLevel].text }}
14
14
  </Tag>
15
-
15
+
16
16
  <span>{{t(`operationType.${item.operationType}`)}}|
17
17
  </span>
18
18
  <Popover>
@@ -22,8 +22,8 @@
22
22
  <span class="crane-text-overflow">{{ item.name }}</span>
23
23
  </Popover>
24
24
  <Tag
25
- v-if="item.businessApplyType && item.businessApplyType !== 'TEMP_OWNER'"
26
- :bordered="false"
25
+ v-if="item.businessApplyType && item.businessApplyType !== 'TEMP_OWNER'"
26
+ :bordered="false"
27
27
  class="crane-tag-position crane-margin-left-4 crane-margin-right-0"
28
28
  :class="['PENDING', 'TEMP_OWNER'].includes(item.businessApplyType) ? '' : 'crane-disabled-color'">
29
29
  {{ statusMap[item.businessApplyType] }}
@@ -34,14 +34,14 @@
34
34
  <span v-else>{{ t('taday') }}</span>
35
35
  </template>
36
36
  <Tag
37
- v-if="item.businessApplyType === 'TEMP_OWNER'"
38
- :bordered="false"
37
+ v-if="item.businessApplyType === 'TEMP_OWNER'"
38
+ :bordered="false"
39
39
  class="crane-tag-position crane-margin-left-4 crane-margin-right-0"
40
40
  :class="['PENDING'].includes(item.businessApplyType) ? '' : 'crane-disabled-color'">
41
41
  {{ statusMap[item.businessApplyType] }}
42
42
  </Tag>
43
43
  </Popover>
44
-
44
+
45
45
  </div>
46
46
  </Checkbox>
47
47
 
@@ -94,7 +94,7 @@
94
94
  L2: {
95
95
  color: 'orange',
96
96
  text: t('levels.L2')
97
- },
97
+ },
98
98
  L3: {
99
99
  color: 'red',
100
100
  text: t('levels.L3')
@@ -155,7 +155,7 @@
155
155
  }
156
156
  .crane-checkbox-line {
157
157
  margin-bottom: 12px;
158
- display: flex;
158
+ display: flex;
159
159
  align-items: center;
160
160
  }
161
161
  .crane-checkbox-line:last-child {
@@ -166,8 +166,8 @@
166
166
  }
167
167
  .crane-tag-position {
168
168
  margin-right: 4px;
169
- font-size: 10px;
170
- padding: 2px 4px;
169
+ font-size: 10px;
170
+ padding: 2px 4px;
171
171
  line-height: 12px;
172
172
  font-weight: 500;
173
173
  }
@@ -194,5 +194,5 @@
194
194
  overflow: hidden;
195
195
  text-overflow: ellipsis
196
196
  }
197
-
197
+
198
198
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <contextHolder></contextHolder>
2
+ <contextHolder></contextHolder>
3
3
  </template>
4
4
  <script lang="ts" setup>
5
5
  import { createVNode } from 'vue';
@@ -1,24 +1,25 @@
1
1
  <template>
2
2
  <ConfigProvider
3
- v-if="allPermissions.length"
4
- prefixCls="yqg-permission"
5
- :theme="{
6
- token: {
7
- colorPrimary: props.color,
8
- }}">
3
+ v-if="allPermissions.length"
4
+ prefixCls="yqg-permission"
5
+ :theme="{
6
+ token: {
7
+ colorPrimary: props.color,
8
+ }
9
+ }"
10
+ >
9
11
  <div class="crane-wraper">
10
- <template v-if="type==='text'">
11
- <TypographyLink @click="showModal">{{t('permissionApply')}}</TypographyLink>
12
+ <template v-if="type === 'text'">
13
+ <TypographyLink @click="showModal" v-show="isShowText">{{t('permissionApply')}}</TypographyLink>
12
14
  </template>
13
15
  <template v-else-if="type==='custom'">
14
16
  <div @click="showModal">
15
- <slot name="custom"></slot>
17
+ <slot name="custom"/>
16
18
  </div>
17
19
  </template>
18
20
  <template v-else>
19
-
20
21
  <!-- 可申请 -->
21
- <template v-if="curStatus.status === statusMap.DEFAULT">
22
+ <template v-if="curStatus.status === STATUS_MAP.DEFAULT">
22
23
  <img
23
24
  :src="curStatus.imageUrl"
24
25
  height="200"
@@ -32,7 +33,7 @@
32
33
  </div>
33
34
  </template>
34
35
  <!-- 审批中 -->
35
- <template v-if="curStatus.status === statusMap.PENDING">
36
+ <template v-if="curStatus.status === STATUS_MAP.PENDING">
36
37
  <img
37
38
  :src="curStatus.imageUrl"
38
39
  height="200"
@@ -52,7 +53,7 @@
52
53
  </div>
53
54
  </template>
54
55
  <!-- 不可申请 -->
55
- <div v-if="curStatus.status === statusMap.NO" class="crane-wraper">
56
+ <div v-if="curStatus.status === STATUS_MAP.NO" class="crane-wraper">
56
57
  <img
57
58
  :src="curStatus.imageUrl"
58
59
  height="200"
@@ -84,19 +85,24 @@
84
85
  </template>
85
86
  <script lang="ts" setup>
86
87
  import { ref, defineAsyncComponent, computed, watchEffect, watch} from 'vue';
87
- import {Button, ConfigProvider, TypographyLink, Popover } from 'ant-design-vue';
88
+ import { Button, ConfigProvider, TypographyLink, Popover , message} from 'ant-design-vue';
88
89
  import applyUrl from '@/assets/applying.png';
89
90
  import noauthority from '@/assets/noauthority.png';
90
91
  import Http from '../axios/index';
91
92
  import t from '../utils';
92
- const ApplyModal = defineAsyncComponent(() =>
93
- import('./apply-modal.vue')
94
- );
95
- const statusMap = {
93
+
94
+ const STATUS_MAP = {
96
95
  DEFAULT: 'DEFAULT',
97
96
  PENDING: 'PENDING',
98
97
  NO: 'NO',
99
- }
98
+ } as const;
99
+
100
+ // 重置 message 类名,避免被全局样式覆盖
101
+ message.config({prefixCls: 'yqg-permission-message'});
102
+
103
+ const ApplyModal = defineAsyncComponent(() =>import('./apply-modal.vue'));
104
+
105
+ const emit = defineEmits(['onSuccess']);
100
106
 
101
107
  const props = defineProps({
102
108
  workNumber: {
@@ -124,7 +130,6 @@
124
130
  default: 'default'
125
131
  },
126
132
  });
127
- const emit = defineEmits(['onSuccess']);
128
133
 
129
134
  const open = ref(false);
130
135
  const curApproving = ref<PermissionType>();
@@ -133,14 +138,21 @@
133
138
  imageUrl: noauthority,
134
139
  status: '',
135
140
  })
141
+
136
142
  const allPermissions = computed(() => {
137
143
  if (Array.isArray(props.permissions)) {
138
144
  return props.permissions;
139
- } else {
140
- return props.permissions.split(',');
141
145
  }
146
+
147
+ return props.permissions.split(',');
142
148
  });
143
149
 
150
+ const isShowText = computed(() => {
151
+ // 所有权限点的状态要么是NO,要么是OWNER,那么不显示文字组件
152
+ return !permissionList.value.every((item) => item.businessApplyType === 'NO' || item.businessApplyType === 'OWNER');
153
+
154
+ });
155
+
144
156
  const formatPermissionsData = (data: PermissionListType) => {
145
157
  const arr:PermissionListType = [];
146
158
  const flattenData = (list: PermissionListType) => {
@@ -153,13 +165,19 @@
153
165
  })
154
166
  };
155
167
  flattenData(data);
168
+
156
169
  // 需要排序,规则:businessApplyType 为 null 在前面, PENDING. OWNER 在中间, NO 在后面
157
170
  // 然后再根据 L1, L2, L3 排序
158
171
  const sort = [ null, 'TEMP_OWNER', 'PENDING', 'OWNER', 'NO'];
159
172
  const levelSort = ['L1', 'L2', 'L3'];
173
+ const sortMap = new Map(sort.map((value, index) => [value, index]));
174
+ const levelSortMap = new Map(levelSort.map((value, index) => [value, index]));
175
+
160
176
  arr.sort((a, b) => {
161
- return sort.indexOf(a.businessApplyType) - sort.indexOf(b.businessApplyType) || levelSort.indexOf(a.securityLevel) - levelSort.indexOf(b.securityLevel);
177
+ return (sortMap.get(a.businessApplyType) ?? 0) - (sortMap.get(b.businessApplyType) ?? 0)
178
+ || (levelSortMap.get(a.securityLevel) ?? 0) - (levelSortMap.get(b.securityLevel) ?? 0);
162
179
  });
180
+
163
181
  return arr;
164
182
  }
165
183
 
@@ -167,16 +185,18 @@
167
185
  if (!data.length) {
168
186
  return {
169
187
  imageUrl: noauthority,
170
- status: '',
188
+ status: ''
171
189
  };
172
190
  }
173
- const current = data.find((per) => per.businessApplyType === statusMap.PENDING);
174
- const cannotApply = data.every((per) => per.businessApplyType === statusMap.NO);
191
+
192
+ const current = data.find((per) => per.businessApplyType === STATUS_MAP.PENDING);
193
+ const cannotApply = data.every((per) => per.businessApplyType === STATUS_MAP.NO);
194
+
175
195
  if (current) {
176
196
  curApproving.value = current;
177
197
  return {
178
198
  imageUrl: applyUrl,
179
- status: statusMap.PENDING,
199
+ status: STATUS_MAP.PENDING,
180
200
  tips: t('status.PENDING'),
181
201
  url: current.oaFlowUrl,
182
202
  };
@@ -185,34 +205,39 @@
185
205
  if (cannotApply) {
186
206
  return {
187
207
  imageUrl: noauthority,
188
- status: statusMap.NO,
208
+ status: STATUS_MAP.NO,
189
209
  tips: data[0].admin?.map((item) => `${item.name}(${item.departmentName})`)?.join('、'),
190
210
  };
191
211
  };
212
+
192
213
  return {
193
214
  imageUrl: noauthority,
194
- status: statusMap.DEFAULT,
215
+ status: STATUS_MAP.DEFAULT,
195
216
  }
196
217
  };
197
218
 
198
219
  const goViewApproval = () => {
199
- console.log(curApproving.value)
200
- if (curApproving.value?.oaFlowUrl) {
201
- window.open(curApproving.value.oaFlowUrl);
202
- }
220
+ const url = curApproving.value?.oaFlowUrl;
221
+ if (!url) return;
222
+
223
+ window.open(url, '_blank');
203
224
  };
204
225
 
205
226
  const getPermissions = async () => {
206
- if (!allPermissions.value.length || !props.businessCode || !props.workNumber) return;
227
+ const { businessCode, workNumber } = props;
228
+ const permissions = allPermissions.value;
229
+
230
+ if (!permissions?.length || !businessCode || !workNumber) return;
207
231
 
208
232
  const params = {
209
- businessCode: props.businessCode,
210
- features: allPermissions.value.toString(),
211
- workNumber: props.workNumber,
233
+ businessCode,
234
+ workNumber,
235
+ features: permissions.toString(),
212
236
  };
213
237
 
214
- let res = await Http.getPermissions(params);
238
+ const res = await Http.getPermissions(params);
215
239
  permissionList.value = formatPermissionsData(res.body || []);
240
+
216
241
  curStatus.value = getStatus(permissionList.value);
217
242
  };
218
243
 
@@ -227,8 +252,8 @@
227
252
  if (cur === pre) return;
228
253
  localStorage.setItem('permission_locale', props.locale);
229
254
  }, {immediate: true})
230
-
231
255
  </script>
256
+
232
257
  <style scoped>
233
258
  .crane-wraper {
234
259
  display: flex;