@yqg/permission 1.0.9-beta.0 → 1.0.10

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-beta.0",
3
+ "version": "1.0.10",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "type": "module",
@@ -13,23 +13,22 @@
13
13
  "dev": "vite",
14
14
  "preview": "vite preview"
15
15
  },
16
- "dependencies": {
16
+ "devDependencies": {
17
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"
24
- },
25
- "devDependencies": {
20
+ "@types/vue": "^2.0.0",
26
21
  "@typescript-eslint/parser": "^8.13.0",
27
22
  "@vitejs/plugin-vue": "^5.1.4",
23
+ "ant-design-vue": "4.x",
24
+ "axios": "^1.7.7",
28
25
  "eslint": "^9.14.0",
29
26
  "husky": "^9",
30
27
  "lint-staged": "^13.2.0",
31
28
  "typescript": "~5.5.4",
32
29
  "vite": "^5.4.9",
30
+ "vite-plugin-css-injected-by-js": "^3.5.2",
31
+ "vue": "^3.5.12",
33
32
  "vue-tsc": "^2.1.8"
34
33
  }
35
34
  }
package/src/App.vue CHANGED
@@ -8,14 +8,16 @@ 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';
@@ -38,7 +40,7 @@ const changeLocale = () => {
38
40
  <!-- 05184 -->
39
41
  <yqg-permission
40
42
  :permissions="permissions"
41
- workNumber="05181"
43
+ workNumber="05184"
42
44
  businessCode="CRANE"
43
45
  :color="color"
44
46
  :locale="locale"
@@ -1,6 +1,6 @@
1
1
  import axios from './axios';
2
2
 
3
- const urlPrefix = '/admin/crane';
3
+ const urlPrefix = '/crane';
4
4
 
5
5
  type apiType = {
6
6
  [key in string]: (params: any) => Promise<{body: any}>
@@ -172,7 +172,7 @@
172
172
  }
173
173
 
174
174
  const onChangeHandler = throttle(async () => {
175
- if (formState.roleIds.length > 1) {
175
+ if (formState.roleIds.length > 5) {
176
176
  return;
177
177
  }
178
178
 
@@ -188,7 +188,7 @@
188
188
 
189
189
  watch(() => formState.roleIds, (val) => {
190
190
  // 写到watch里避免闪烁
191
- if (val.length > 1) {
191
+ if (val.length > 5) {
192
192
  formState.roleIds.pop();
193
193
  message.warning(t('maxCountTips', {count: 5}));
194
194
  }
@@ -17,7 +17,7 @@
17
17
  </span>
18
18
  <Popover>
19
19
  <template #content>
20
- {{ item.name }}
20
+ <div style="max-width: 400px;">{{ item.name }}</div>
21
21
  </template>
22
22
  <span class="crane-text-overflow">{{ item.name }}</span>
23
23
  </Popover>
@@ -47,16 +47,18 @@
47
47
 
48
48
  <Popover v-if="item.desc">
49
49
  <template #content>
50
- {{ item.desc }}
50
+ <div style="max-width: 400px;">{{ item.desc }}</div>
51
51
  </template>
52
52
  <QuestionCircleOutlined class=" crane-week-color"/>
53
53
  </Popover>
54
54
 
55
55
  <Popover v-if="item.relatedDepartments">
56
56
  <template #content>
57
- {{t('adaptDepartment')}}:{{ item.relatedDepartments.map((item: any) => {
57
+ <div style="max-width: 400px;">
58
+ {{t('adaptDepartment')}}:{{ item.relatedDepartments.map((item: any) => {
58
59
  return item.name;
59
60
  }).join('、') }}
61
+ </div>
60
62
  </template>
61
63
  <span class="crane-flex-center crane-margin-left-4">
62
64
  <img :src="departmentImg" height="14" width="14">
@@ -21,17 +21,17 @@
21
21
  onOk: () => {
22
22
  window.open(url);
23
23
  modal1.destroy();
24
- if (callback) {
25
- callback();
26
- } else {
24
+ callback && callback();
25
+ window.YQG_PERMISSION_CALLBACK && window.YQG_PERMISSION_CALLBACK();
26
+ if (!window.YQG_PERMISSION_CALLBACK && !callback) {
27
27
  location.reload();
28
28
  }
29
29
  },
30
30
  onCancel: () => {
31
31
  modal1.destroy();
32
- if (callback) {
33
- callback();
34
- } else {
32
+ callback && callback();
33
+ window.YQG_PERMISSION_CALLBACK && window.YQG_PERMISSION_CALLBACK();
34
+ if (!window.YQG_PERMISSION_CALLBACK && !callback) {
35
35
  location.reload();
36
36
  }
37
37
  },
@@ -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
12
  <template v-if="type==='text'">
11
13
  <TypographyLink @click="showModal">{{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,12 +138,13 @@
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
 
144
150
  const formatPermissionsData = (data: PermissionListType) => {
@@ -153,13 +159,19 @@
153
159
  })
154
160
  };
155
161
  flattenData(data);
162
+
156
163
  // 需要排序,规则:businessApplyType 为 null 在前面, PENDING. OWNER 在中间, NO 在后面
157
164
  // 然后再根据 L1, L2, L3 排序
158
165
  const sort = [ null, 'TEMP_OWNER', 'PENDING', 'OWNER', 'NO'];
159
166
  const levelSort = ['L1', 'L2', 'L3'];
167
+ const sortMap = new Map(sort.map((value, index) => [value, index]));
168
+ const levelSortMap = new Map(levelSort.map((value, index) => [value, index]));
169
+
160
170
  arr.sort((a, b) => {
161
- return sort.indexOf(a.businessApplyType) - sort.indexOf(b.businessApplyType) || levelSort.indexOf(a.securityLevel) - levelSort.indexOf(b.securityLevel);
171
+ return (sortMap.get(a.businessApplyType) ?? 0) - (sortMap.get(b.businessApplyType) ?? 0)
172
+ || (levelSortMap.get(a.securityLevel) ?? 0) - (levelSortMap.get(b.securityLevel) ?? 0);
162
173
  });
174
+
163
175
  return arr;
164
176
  }
165
177
 
@@ -167,16 +179,18 @@
167
179
  if (!data.length) {
168
180
  return {
169
181
  imageUrl: noauthority,
170
- status: '',
182
+ status: ''
171
183
  };
172
184
  }
173
- const current = data.find((per) => per.businessApplyType === statusMap.PENDING);
174
- const cannotApply = data.every((per) => per.businessApplyType === statusMap.NO);
185
+
186
+ const current = data.find((per) => per.businessApplyType === STATUS_MAP.PENDING);
187
+ const cannotApply = data.every((per) => per.businessApplyType === STATUS_MAP.NO);
188
+
175
189
  if (current) {
176
190
  curApproving.value = current;
177
191
  return {
178
192
  imageUrl: applyUrl,
179
- status: statusMap.PENDING,
193
+ status: STATUS_MAP.PENDING,
180
194
  tips: t('status.PENDING'),
181
195
  url: current.oaFlowUrl,
182
196
  };
@@ -185,38 +199,44 @@
185
199
  if (cannotApply) {
186
200
  return {
187
201
  imageUrl: noauthority,
188
- status: statusMap.NO,
202
+ status: STATUS_MAP.NO,
189
203
  tips: data[0].admin?.map((item) => `${item.name}(${item.departmentName})`)?.join('、'),
190
204
  };
191
205
  };
206
+
192
207
  return {
193
208
  imageUrl: noauthority,
194
- status: statusMap.DEFAULT,
209
+ status: STATUS_MAP.DEFAULT,
195
210
  }
196
211
  };
197
212
 
198
213
  const goViewApproval = () => {
199
- console.log(curApproving.value)
200
- if (curApproving.value?.oaFlowUrl) {
201
- window.open(curApproving.value.oaFlowUrl);
202
- }
214
+ const url = curApproving.value?.oaFlowUrl;
215
+ if (!url) return;
216
+
217
+ window.open(url, '_blank');
203
218
  };
204
219
 
205
220
  const getPermissions = async () => {
206
- if (!allPermissions.value.length || !props.businessCode || !props.workNumber) return;
221
+ const { businessCode, workNumber } = props;
222
+ const permissions = allPermissions.value;
223
+
224
+ if (!permissions?.length || !businessCode || !workNumber) return;
207
225
 
208
226
  const params = {
209
- businessCode: props.businessCode,
210
- features: allPermissions.value.toString(),
211
- workNumber: props.workNumber,
227
+ businessCode,
228
+ workNumber,
229
+ features: permissions.toString(),
212
230
  };
213
231
 
214
- let res = await Http.getPermissions(params);
232
+ const res = await Http.getPermissions(params);
215
233
  permissionList.value = formatPermissionsData(res.body || []);
234
+
216
235
  curStatus.value = getStatus(permissionList.value);
217
236
  };
218
237
 
219
238
  const showModal = () => {
239
+ getPermissions();
220
240
  open.value = !open.value;
221
241
  };
222
242
 
@@ -226,8 +246,8 @@
226
246
  if (cur === pre) return;
227
247
  localStorage.setItem('permission_locale', props.locale);
228
248
  }, {immediate: true})
229
-
230
249
  </script>
250
+
231
251
  <style scoped>
232
252
  .crane-wraper {
233
253
  display: flex;
package/src/i18n/en-US.ts CHANGED
@@ -4,7 +4,7 @@ export default {
4
4
  applyReason: '申请理由',
5
5
  approvalProcess: '审批流程',
6
6
  applyReason1: '新入职员工申请',
7
- applyReason2: '临时项目',
7
+ applyReason2: '项目需要',
8
8
  applyReason3: '数据查询与分析',
9
9
  applyReasonPlaceholder: '请尽可能详细描述申请理由',
10
10
  cancel: '取消',
@@ -20,7 +20,7 @@ export default {
20
20
  adaptDepartment: '适用部门',
21
21
  noApprovalProcess: '无审批流程',
22
22
  excessTips: '一次最多可申请{number}个权限',
23
- unavailableTips: '您暂无权限查看/操作该页面,请点击按钮进行申请',
23
+ unavailableTips: '您暂无权限查看/操作该页面,请点击下方按钮进行申请',
24
24
  appliedTips: '权限已申请,正在{status}...',
25
25
  unapplyTips: '您暂无权限查看/操作该页面,且该页面中没有您可以申请的权限,',
26
26
  callManager: '如有需要请联系系统管理员',
package/src/i18n/zh-CH.ts CHANGED
@@ -4,7 +4,7 @@ export default {
4
4
  applyReason: '申请理由',
5
5
  approvalProcess: '审批流程',
6
6
  applyReason1: '新入职员工申请',
7
- applyReason2: '临时项目',
7
+ applyReason2: '项目需要',
8
8
  applyReason3: '数据查询与分析',
9
9
  applyReasonPlaceholder: '请尽可能详细描述申请理由',
10
10
  cancel: '取消',
@@ -20,7 +20,7 @@ export default {
20
20
  adaptDepartment: '适用部门',
21
21
  noApprovalProcess: '无审批流程',
22
22
  excessTips: '一次最多可申请{number}个权限',
23
- unavailableTips: '您暂无权限查看/操作该页面,请点击按钮进行申请',
23
+ unavailableTips: '您暂无权限查看/操作该页面,请点击下方按钮进行申请',
24
24
  appliedTips: '权限已申请,正在{status}...',
25
25
  unapplyTips: '您暂无权限查看/操作该页面,且该页面中没有您可以申请的权限,',
26
26
  callManager: '如有需要请联系系统管理员',
@@ -53,3 +53,6 @@ declare type formStateType = {
53
53
  submitWorkNumber: string,
54
54
 
55
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" />
package/vite.config.ts CHANGED
@@ -13,7 +13,7 @@ export default defineConfig({
13
13
  },
14
14
  server: {
15
15
  proxy: {
16
- '/admin': {
16
+ '/crane': {
17
17
  target: 'https://crane-test.yangqianguan.com',
18
18
  changeOrigin: true,
19
19
  },