egova-admin-jssdk 0.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/README.md ADDED
@@ -0,0 +1 @@
1
+ egova admin jssdk
@@ -0,0 +1,4 @@
1
+ import { adminAxios } from "./util/axios-util";
2
+ export * from "./service";
3
+ export * from "./types";
4
+ export { adminAxios };
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { adminAxios } from "./util/axios-util";
2
+ export * from "./service";
3
+ export * from "./types";
4
+ export { adminAxios };
@@ -0,0 +1,18 @@
1
+ import type { HumanParams, UnitParams, CountParams } from "@/types";
2
+ /**
3
+ * 获取部门人员
4
+ * @param params
5
+ * @returns
6
+ */
7
+ export declare function gethumanlist(params: HumanParams): Promise<import("axios").AxiosResponse<any, any>> | undefined;
8
+ /**
9
+ * 获取部门树
10
+ * @param params
11
+ * @returns
12
+ */
13
+ export declare function getUnitTree(params: UnitParams): Promise<import("axios").AxiosResponse<any, any>> | undefined;
14
+ /**
15
+ * 获取部门人数
16
+ * @returns
17
+ */
18
+ export declare function countUnitHuman(params: CountParams): Promise<import("axios").AxiosResponse<any, any>> | undefined;
@@ -0,0 +1,40 @@
1
+ import { adminAxios } from "@/util/axios-util";
2
+ import { isNil } from "lodash-es";
3
+ /**
4
+ * 获取部门人员
5
+ * @param params
6
+ * @returns
7
+ */
8
+ export function gethumanlist(params) {
9
+ return adminAxios.getAxiosInstance()?.get("/unity/org/human/gethumanlist", { params });
10
+ }
11
+ /**
12
+ * 获取部门树
13
+ * @param params
14
+ * @returns
15
+ */
16
+ export function getUnitTree(params) {
17
+ return adminAxios.getAxiosInstance()?.get("/unity/builder/org/gettenantunittree", { params });
18
+ }
19
+ /**
20
+ * 获取部门人数
21
+ * @returns
22
+ */
23
+ export function countUnitHuman(params) {
24
+ const url = "/unity/org/unit/countunithumannumber";
25
+ const paramsList = [];
26
+ if (!isNil(params.tenantId)) {
27
+ paramsList.push(`tenantId=${params.tenantId}`);
28
+ }
29
+ if (!isNil(params.roleId)) {
30
+ paramsList.push(`roleId=${params.roleId}`);
31
+ }
32
+ if (!isNil(params.onlyQueryUnbound)) {
33
+ paramsList.push(`onlyQueryUnbound=${params.onlyQueryUnbound}`);
34
+ }
35
+ if (!isNil(params.permissionId)) {
36
+ paramsList.push(`permissionId=${params.permissionId}`);
37
+ }
38
+ const result = paramsList.length ? `${url}?${paramsList.join("&")}` : url;
39
+ return adminAxios.getAxiosInstance()?.post(result, params.ids);
40
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * 查询人员列表条件
3
+ */
4
+ export interface HumanParams {
5
+ /**
6
+ * 租户id
7
+ */
8
+ tenantId?: string;
9
+ /**
10
+ * 部门id
11
+ */
12
+ unitId?: string;
13
+ /**
14
+ * 搜索关键字
15
+ */
16
+ searchWord?: string;
17
+ /**
18
+ * 是否包含子部门
19
+ */
20
+ containChildren?: boolean;
21
+ /**
22
+ * 当前页码
23
+ */
24
+ currentPage?: number;
25
+ /**
26
+ * 每页返回的条数
27
+ */
28
+ numPerPage?: number;
29
+ }
30
+ /**
31
+ * 部门查询条件
32
+ */
33
+ export interface UnitParams {
34
+ /**
35
+ * 租户id
36
+ */
37
+ tenantId?: string;
38
+ /**
39
+ * 上级部门id
40
+ */
41
+ seniorId?: string;
42
+ }
43
+ /**
44
+ * 查询部门人数条件
45
+ */
46
+ export interface CountParams {
47
+ /**
48
+ * 租户id
49
+ */
50
+ tenantId?: string;
51
+ /**
52
+ * 部门id的数组集合
53
+ */
54
+ ids?: Array<string | number>;
55
+ /**
56
+ * 是否只查询未绑定的
57
+ */
58
+ onlyQueryUnbound?: boolean;
59
+ /**
60
+ * 岗位id
61
+ */
62
+ roleId?: string;
63
+ /**
64
+ * 权限id
65
+ */
66
+ permissionId?: string;
67
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { type AxiosInstance } from "axios";
2
+ export declare class AdminAxios {
3
+ private axiosInstance?;
4
+ private egovaAdminToken?;
5
+ /**
6
+ * 初始化统一用户中心的axios
7
+ * @param baseUrl 统一用户中心的baseUrl
8
+ * @param token 统一用户中心的token
9
+ */
10
+ init(baseUrl: string, token: string): void;
11
+ getAxiosInstance(): AxiosInstance | undefined;
12
+ private configAxios;
13
+ /**
14
+ * 配置token
15
+ * @param config
16
+ */
17
+ private configToken;
18
+ /**
19
+ * 接口签名
20
+ * @param config
21
+ */
22
+ private configSignature;
23
+ }
24
+ export declare const adminAxios: AdminAxios;
@@ -0,0 +1,57 @@
1
+ import axios, {} from "axios";
2
+ import { merge } from "lodash-es";
3
+ import { signature } from "./signature";
4
+ export class AdminAxios {
5
+ axiosInstance;
6
+ egovaAdminToken;
7
+ /**
8
+ * 初始化统一用户中心的axios
9
+ * @param baseUrl 统一用户中心的baseUrl
10
+ * @param token 统一用户中心的token
11
+ */
12
+ init(baseUrl, token) {
13
+ this.egovaAdminToken = token;
14
+ this.axiosInstance = axios.create({
15
+ baseURL: baseUrl,
16
+ timeout: 60000
17
+ });
18
+ this.configAxios();
19
+ }
20
+ getAxiosInstance() {
21
+ return this.axiosInstance;
22
+ }
23
+ // 配置axios
24
+ configAxios() {
25
+ this.axiosInstance?.interceptors.request.use(async (config) => {
26
+ // 配置token信息
27
+ this.configToken(config);
28
+ // 接口签名参数
29
+ this.configSignature(config);
30
+ return config;
31
+ }, (error) => {
32
+ return Promise.reject(error);
33
+ });
34
+ }
35
+ /**
36
+ * 配置token
37
+ * @param config
38
+ */
39
+ configToken(config) {
40
+ // 添加 token
41
+ const reg = /^\/?(free)\//;
42
+ if (config.url && !reg.test(config.url)) {
43
+ // 判断是否存在token,如果存在的话,则每个http header都加上token
44
+ if (this.egovaAdminToken) {
45
+ merge(config, { headers: { "X-Authorization": `bearer ${this.egovaAdminToken}` } });
46
+ }
47
+ }
48
+ }
49
+ /**
50
+ * 接口签名
51
+ * @param config
52
+ */
53
+ configSignature(config) {
54
+ signature.signatureConfig(config);
55
+ }
56
+ }
57
+ export const adminAxios = new AdminAxios();
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 判断数据类型
3
+ * @param data - 数据
4
+ * @returns 数据类型
5
+ * @public
6
+ */
7
+ export declare function dataTypeOf(data: any): string;
@@ -0,0 +1,16 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /**
3
+ * 判断数据类型
4
+ * @param data - 数据
5
+ * @returns 数据类型
6
+ * @public
7
+ */
8
+ export function dataTypeOf(data) {
9
+ if (data instanceof Element) {
10
+ return 'element';
11
+ }
12
+ return Object.prototype.toString
13
+ .call(data)
14
+ .replace(/\[object\s(.+)\]/, '$1')
15
+ .toLowerCase();
16
+ }
@@ -0,0 +1,25 @@
1
+ declare class RandomUtil {
2
+ /**
3
+ * 等价于Math.random()
4
+ * @returns
5
+ */
6
+ random(): number;
7
+ /**
8
+ * 随机生成len长度的字符串,比如生成16位随机字符串:randomStr(16) 得到"bb2a6d2fe39bb7ee"
9
+ * @param len
10
+ */
11
+ randomStr(len: number): string;
12
+ /**
13
+ * 随机生成len长度的纯数字字符串,比如randomNumberStr(16)得到 "1842442170233672"
14
+ * @param len
15
+ */
16
+ randomNumberStr(len: number): string;
17
+ /**
18
+ * 随机生成一个密码,同时包含大写字母,小写字母,数字和特殊符号
19
+ * @param len
20
+ */
21
+ getRandomPassword(len: number): string;
22
+ getRandomChar(characters: string): string;
23
+ }
24
+ declare const randomUtil: RandomUtil;
25
+ export default randomUtil;
@@ -0,0 +1,74 @@
1
+ import { random } from "lodash-es";
2
+ class RandomUtil {
3
+ /**
4
+ * 等价于Math.random()
5
+ * @returns
6
+ */
7
+ random() {
8
+ return window.crypto.getRandomValues(new Uint8Array(1))[0] * 0.001;
9
+ }
10
+ /**
11
+ * 随机生成len长度的字符串,比如生成16位随机字符串:randomStr(16) 得到"bb2a6d2fe39bb7ee"
12
+ * @param len
13
+ */
14
+ randomStr(len) {
15
+ const byteLength = Math.ceil(len / 2); // 因为一个字节可以表示两个十六进制字符
16
+ const randomBytes = new Uint8Array(byteLength);
17
+ window.crypto.getRandomValues(randomBytes);
18
+ const hexArray = Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0"));
19
+ const hexString = hexArray.join("").substr(0, len);
20
+ return hexString;
21
+ }
22
+ /**
23
+ * 随机生成len长度的纯数字字符串,比如randomNumberStr(16)得到 "1842442170233672"
24
+ * @param len
25
+ */
26
+ randomNumberStr(len) {
27
+ // 计算需要生成的字节数
28
+ const byteLength = Math.ceil(len / 2);
29
+ // 创建一个 Uint8Array 用于存储随机字节
30
+ const randomBytes = new Uint8Array(byteLength);
31
+ // 使用 window.crypto.getRandomValues 填充数组
32
+ window.crypto.getRandomValues(randomBytes);
33
+ // 将 Uint8Array 转换为一个数字字符串
34
+ let randomNumber = "";
35
+ for (let i = 0; i < byteLength; i++) {
36
+ randomNumber += randomBytes[i].toString().padStart(2, "0");
37
+ }
38
+ // 截取指定长度的字符串
39
+ return randomNumber.slice(0, len);
40
+ }
41
+ /**
42
+ * 随机生成一个密码,同时包含大写字母,小写字母,数字和特殊符号
43
+ * @param len
44
+ */
45
+ getRandomPassword(len) {
46
+ const uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
47
+ const lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
48
+ const numbers = "0123456789";
49
+ const specialChars = ".~!@#$%^&*)(_+}{|:?><";
50
+ const allChars = uppercaseLetters + lowercaseLetters + numbers + specialChars;
51
+ let pass_word = "";
52
+ // 先保证每种字符都有一个
53
+ pass_word += this.getRandomChar(uppercaseLetters);
54
+ pass_word += this.getRandomChar(lowercaseLetters);
55
+ pass_word += this.getRandomChar(numbers);
56
+ pass_word += this.getRandomChar(specialChars);
57
+ // 生成剩下长度的字符串
58
+ for (let i = pass_word.length; i < len; i++) {
59
+ pass_word += this.getRandomChar(allChars);
60
+ }
61
+ // 打乱字符串
62
+ pass_word = pass_word
63
+ .split("")
64
+ .sort(() => random(true) - 0.5)
65
+ .join("");
66
+ return pass_word;
67
+ }
68
+ getRandomChar(characters) {
69
+ const randomIndex = Math.floor(random(true) * characters.length);
70
+ return characters[randomIndex];
71
+ }
72
+ }
73
+ const randomUtil = new RandomUtil();
74
+ export default randomUtil;
@@ -0,0 +1,113 @@
1
+ import type { AxiosRequestConfig } from "axios";
2
+ /**
3
+ * 应用标识
4
+ * @public
5
+ */
6
+ export interface SignatureAppIdCode {
7
+ /**
8
+ * 应用 id
9
+ */
10
+ id: string;
11
+ /**
12
+ * 应用 code
13
+ */
14
+ code: string;
15
+ }
16
+ /**
17
+ * Signature 请求签名配置
18
+ * @public
19
+ */
20
+ export interface SignatureOption {
21
+ /**
22
+ * 随机数
23
+ */
24
+ nonce: string;
25
+ /**
26
+ * 时间戳
27
+ */
28
+ timestamp: string;
29
+ /**
30
+ * 签名
31
+ */
32
+ signature?: string;
33
+ }
34
+ /**
35
+ * Signature 请求签名
36
+ * @public
37
+ */
38
+ export declare class Signature {
39
+ constructor(appIdCode: SignatureAppIdCode);
40
+ /**
41
+ * 应用标识
42
+ */
43
+ private appIdCode;
44
+ /**
45
+ * 随机数前缀
46
+ */
47
+ private noncePrefix;
48
+ /**
49
+ * 生成随机数
50
+ * @returns
51
+ */
52
+ private generateRandomString;
53
+ /**
54
+ * 生成签名参数
55
+ * @returns
56
+ */
57
+ private generateSignatureOption;
58
+ private stringToUTF8ByteSize;
59
+ private isStringOverKB;
60
+ /**
61
+ * 去除空参数
62
+ * @param param - 参数
63
+ * @returns
64
+ */
65
+ private removeNilValue;
66
+ /**
67
+ * 格式化 url value
68
+ * @param value - 值
69
+ * @returns
70
+ */
71
+ private formatEncodeValue;
72
+ /**
73
+ * 格式化 url params
74
+ * @param params - 参数列表
75
+ * @param key - 参数键
76
+ * @param param - 参数
77
+ * @returns
78
+ */
79
+ private formatEncodeParam;
80
+ /**
81
+ * 参数排序
82
+ * @param param - 参数
83
+ * @returns
84
+ */
85
+ private sortParamByKey;
86
+ /**
87
+ * 签名加密
88
+ * @param url - 请求地址
89
+ * @returns
90
+ */
91
+ private cryptoHash;
92
+ /**
93
+ * 获取 url 参数
94
+ * @param url - 请求地址
95
+ * @returns
96
+ */
97
+ private urlSearchParams;
98
+ /**
99
+ * 获取签名 url
100
+ * @param href - 请求地址
101
+ * @returns 签名 url
102
+ * @public
103
+ */
104
+ signatureHref(href: string): string;
105
+ /**
106
+ * 获取签名参数
107
+ * @param config - Axios 请求配置
108
+ * @returns 签名参数
109
+ * @public
110
+ */
111
+ signatureConfig(config: AxiosRequestConfig): void;
112
+ }
113
+ export declare const signature: Signature;
@@ -0,0 +1,279 @@
1
+ import CryptoJS from "crypto-js";
2
+ import { isNil, merge } from "lodash-es";
3
+ import qs from "qs";
4
+ import { toRaw } from "vue";
5
+ import { dataTypeOf } from "./data-type-of";
6
+ import randomUtil from "./random-util";
7
+ import { urlUtil } from "./url";
8
+ /**
9
+ * Signature 请求签名
10
+ * @public
11
+ */
12
+ export class Signature {
13
+ constructor(appIdCode) {
14
+ this.appIdCode = appIdCode;
15
+ this.noncePrefix = this.generateRandomString();
16
+ }
17
+ /**
18
+ * 应用标识
19
+ */
20
+ appIdCode;
21
+ /**
22
+ * 随机数前缀
23
+ */
24
+ noncePrefix;
25
+ /**
26
+ * 生成随机数
27
+ * @returns
28
+ */
29
+ generateRandomString() {
30
+ return randomUtil.randomStr(8);
31
+ }
32
+ /**
33
+ * 生成签名参数
34
+ * @returns
35
+ */
36
+ generateSignatureOption() {
37
+ return {
38
+ nonce: `${this.noncePrefix}_${this.generateRandomString()}`,
39
+ timestamp: Date.now().toString().substring(0, 10)
40
+ };
41
+ }
42
+ stringToUTF8ByteSize(str) {
43
+ const utf8Bytes = new TextEncoder().encode(str);
44
+ return utf8Bytes.length;
45
+ }
46
+ isStringOverKB(str, size) {
47
+ const byteSize = this.stringToUTF8ByteSize(str);
48
+ return byteSize > size * 1024;
49
+ }
50
+ /**
51
+ * 去除空参数
52
+ * @param param - 参数
53
+ * @returns
54
+ */
55
+ removeNilValue(param) {
56
+ if (dataTypeOf(param) === "object") {
57
+ for (const key in param) {
58
+ if (Object.prototype.hasOwnProperty.call(param, key)) {
59
+ const value = param[key];
60
+ const type = dataTypeOf(value);
61
+ if (type === "object") {
62
+ this.removeNilValue(value);
63
+ }
64
+ else {
65
+ if (type === "null" || type === "undefined" || type === "function") {
66
+ delete param[key];
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ * 格式化 url value
75
+ * @param value - 值
76
+ * @returns
77
+ */
78
+ formatEncodeValue(value) {
79
+ const type = dataTypeOf(value);
80
+ const isNilOrFunction = type === "undefined" || type === "function";
81
+ const val = isNilOrFunction ? "" : value;
82
+ return encodeURIComponent(val)
83
+ .replace(/%00/g, "\x00")
84
+ .replace(/%2B/g, "+")
85
+ .replace(/%20/g, "+")
86
+ .replace(/\(/g, "%28")
87
+ .replace(/\)/g, "%29")
88
+ .replace(/'/g, "%27")
89
+ .replace(/!/g, "%21")
90
+ .replace(/~/g, "%7E");
91
+ }
92
+ /**
93
+ * 格式化 url params
94
+ * @param params - 参数列表
95
+ * @param key - 参数键
96
+ * @param param - 参数
97
+ * @returns
98
+ */
99
+ formatEncodeParam(params, key, param) {
100
+ const type = dataTypeOf(param);
101
+ if (type === "object") {
102
+ const keys = Object.keys(param).sort();
103
+ if (keys.length === 0) {
104
+ params.push(`${key}={}`);
105
+ }
106
+ else {
107
+ keys.forEach((k) => {
108
+ this.formatEncodeParam(params, key === "" ? `${k}` : `${key}[${k}]`, param[k]);
109
+ });
110
+ }
111
+ }
112
+ else if (type === "array") {
113
+ if (param.length === 0) {
114
+ params.push(`${key}=[]`);
115
+ }
116
+ else {
117
+ param.forEach((e) => {
118
+ this.formatEncodeParam(params, `${key}[]`, e);
119
+ });
120
+ }
121
+ }
122
+ else {
123
+ params.push(`${key}=${this.formatEncodeValue(param)}`);
124
+ }
125
+ }
126
+ /**
127
+ * 参数排序
128
+ * @param param - 参数
129
+ * @returns
130
+ */
131
+ sortParamByKey(param = {}) {
132
+ const params = [];
133
+ this.formatEncodeParam(params, "", param);
134
+ return params.join("&");
135
+ }
136
+ /**
137
+ * 签名加密
138
+ * @param url - 请求地址
139
+ * @returns
140
+ */
141
+ cryptoHash(url) {
142
+ return CryptoJS.HmacSHA1(url, this.appIdCode.code).toString(CryptoJS.enc.Hex).toUpperCase();
143
+ }
144
+ /**
145
+ * 获取 url 参数
146
+ * @param url - 请求地址
147
+ * @returns
148
+ */
149
+ urlSearchParams(url) {
150
+ if (url && url.indexOf("?") > -1) {
151
+ return qs.parse(url.split("?").pop() ?? "");
152
+ }
153
+ return {};
154
+ }
155
+ /**
156
+ * 获取签名 url
157
+ * @param href - 请求地址
158
+ * @returns 签名 url
159
+ * @public
160
+ */
161
+ signatureHref(href) {
162
+ try {
163
+ // 0. 构造 url
164
+ const { pathname, origin } = new URL(href, window.location.origin);
165
+ // 1. 获取参数
166
+ const params = this.urlSearchParams(href);
167
+ // 2. 生成加密参数
168
+ const signatureOption = this.generateSignatureOption();
169
+ // 3. 参数排序
170
+ merge(params, signatureOption);
171
+ const paramStr = this.sortParamByKey(params);
172
+ // 4. 获取 uri
173
+ const uri = urlUtil.cleanUrl(`/${pathname}`);
174
+ // 5. 拼接
175
+ const full = `${uri}?${paramStr}`;
176
+ // 6. 加密
177
+ const signature = this.cryptoHash(full);
178
+ // 7. 拼接加密参数
179
+ href = `${origin}${full}&signature=${signature}`;
180
+ }
181
+ catch {
182
+ console.error("签名失败,请使用有效的链接", href);
183
+ }
184
+ return href;
185
+ }
186
+ /**
187
+ * 获取签名参数
188
+ * @param config - Axios 请求配置
189
+ * @returns 签名参数
190
+ * @public
191
+ */
192
+ signatureConfig(config) {
193
+ try {
194
+ // 获取 method
195
+ const method = config.method?.toUpperCase();
196
+ const isGet = method === "GET";
197
+ // 获取 data
198
+ const rawData = toRaw(config.data);
199
+ const isObjectPayload = rawData !== null && typeof rawData === "object"; // 参考 axios 源码
200
+ // 获取 contentType
201
+ const contentType = config.headers?.["Content-Type"]?.toString() || "";
202
+ // 数据类型是否为 formData
203
+ const isMultipartFormData = contentType.includes("multipart/form-data");
204
+ // 数据类型是否为 json
205
+ let isApplicationJson = contentType.includes("application/json");
206
+ if (!isGet && !contentType && isObjectPayload) {
207
+ // 若 contentType 为空,且 config.data 为对象,则 axios 会默认添加 application/json header
208
+ isApplicationJson = true;
209
+ }
210
+ // 0. 传入 App-Id,用与服务器识别应用
211
+ merge(config, { headers: { "App-Id": this.appIdCode.id } });
212
+ // 1. 获取参数
213
+ const params = {};
214
+ // 1.1 取 url 参数
215
+ const urlParams = this.urlSearchParams(config.url);
216
+ merge(params, urlParams);
217
+ // 1.2 取 config.params 参数
218
+ if (!isNil(config.params)) {
219
+ const raw = toRaw(config.params);
220
+ // params 内的参数需要去除 null|undefined|function
221
+ this.removeNilValue(raw);
222
+ config.params = raw;
223
+ merge(params, qs.parse(qs.stringify(raw)));
224
+ }
225
+ // 1.3 取 config.data 参数
226
+ if (!isNil(rawData) && isObjectPayload) {
227
+ // 非 json 和 formData 需合并参数
228
+ if (!isMultipartFormData && !isApplicationJson) {
229
+ merge(params, rawData);
230
+ }
231
+ }
232
+ // 2. 生成加密参数
233
+ const signatureOption = this.generateSignatureOption();
234
+ // 3. 参数排序
235
+ merge(params, signatureOption);
236
+ let paramStr = this.sortParamByKey(params);
237
+ // 3.1 数据类型是否为 json 时,将其 stringify 拼接到最后
238
+ if (isApplicationJson) {
239
+ const rawDataStr = JSON.stringify(rawData);
240
+ const isOver128KB = this.isStringOverKB(rawDataStr, 128);
241
+ if (!isOver128KB) {
242
+ if (isObjectPayload) {
243
+ paramStr += this.formatEncodeValue(rawDataStr);
244
+ }
245
+ else {
246
+ paramStr += this.formatEncodeValue(rawData);
247
+ }
248
+ }
249
+ }
250
+ // 4. 获取 uri
251
+ let path = "";
252
+ if (config.url?.startsWith("http")) {
253
+ path = config.url;
254
+ }
255
+ else {
256
+ path = `${config.baseURL}/${config.url || ""}`;
257
+ }
258
+ const { pathname } = new URL(path, window.location.origin);
259
+ const uri = urlUtil.cleanUrl(`/${pathname}`);
260
+ // 5. 拼接
261
+ const full = `${uri}?${paramStr}`;
262
+ // 6. 加密
263
+ signatureOption.signature = this.cryptoHash(full);
264
+ // 7. 拼接加密参数
265
+ config.params = merge({}, config.params, signatureOption);
266
+ }
267
+ catch (error) {
268
+ console.error("签名失败", error);
269
+ }
270
+ }
271
+ }
272
+ /**
273
+ * 签名密钥
274
+ */
275
+ const appIdCode = {
276
+ id: "mis",
277
+ code: "c9d8e36df18ef01ff0da74e0bb13151c"
278
+ };
279
+ export const signature = new Signature(appIdCode);
@@ -0,0 +1,10 @@
1
+ export declare class UrlUtil {
2
+ /**
3
+ * 清除 url 中重复的斜杠
4
+ * @param url 链接地址
5
+ * @returns 链接地址
6
+ * @public
7
+ */
8
+ cleanUrl(url: string): string;
9
+ }
10
+ export declare const urlUtil: UrlUtil;
@@ -0,0 +1,12 @@
1
+ export class UrlUtil {
2
+ /**
3
+ * 清除 url 中重复的斜杠
4
+ * @param url 链接地址
5
+ * @returns 链接地址
6
+ * @public
7
+ */
8
+ cleanUrl(url) {
9
+ return url.replace(/([^:]|^)\/{2,}/g, "$1/");
10
+ }
11
+ }
12
+ export const urlUtil = new UrlUtil();
@@ -0,0 +1,291 @@
1
+ var j = Object.defineProperty;
2
+ var B = (r, t, e) => t in r ? j(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var p = (r, t, e) => B(r, typeof t != "symbol" ? t + "" : t, e);
4
+ import E from "axios";
5
+ import { random as I, merge as u, isNil as d } from "lodash-es";
6
+ import U from "crypto-js";
7
+ import b from "qs";
8
+ import { toRaw as A } from "vue";
9
+ /*! egova-admin-jssdk v0.0.1 */
10
+ function g(r) {
11
+ return r instanceof Element ? "element" : Object.prototype.toString.call(r).replace(/\[object\s(.+)\]/, "$1").toLowerCase();
12
+ }
13
+ class v {
14
+ /**
15
+ * 等价于Math.random()
16
+ * @returns
17
+ */
18
+ random() {
19
+ return window.crypto.getRandomValues(new Uint8Array(1))[0] * 1e-3;
20
+ }
21
+ /**
22
+ * 随机生成len长度的字符串,比如生成16位随机字符串:randomStr(16) 得到"bb2a6d2fe39bb7ee"
23
+ * @param len
24
+ */
25
+ randomStr(t) {
26
+ const e = Math.ceil(t / 2), n = new Uint8Array(e);
27
+ return window.crypto.getRandomValues(n), Array.from(n).map((i) => i.toString(16).padStart(2, "0")).join("").substr(0, t);
28
+ }
29
+ /**
30
+ * 随机生成len长度的纯数字字符串,比如randomNumberStr(16)得到 "1842442170233672"
31
+ * @param len
32
+ */
33
+ randomNumberStr(t) {
34
+ const e = Math.ceil(t / 2), n = new Uint8Array(e);
35
+ window.crypto.getRandomValues(n);
36
+ let o = "";
37
+ for (let s = 0; s < e; s++)
38
+ o += n[s].toString().padStart(2, "0");
39
+ return o.slice(0, t);
40
+ }
41
+ /**
42
+ * 随机生成一个密码,同时包含大写字母,小写字母,数字和特殊符号
43
+ * @param len
44
+ */
45
+ getRandomPassword(t) {
46
+ const e = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", n = "abcdefghijklmnopqrstuvwxyz", o = "0123456789", s = ".~!@#$%^&*)(_+}{|:?><", i = e + n + o + s;
47
+ let a = "";
48
+ a += this.getRandomChar(e), a += this.getRandomChar(n), a += this.getRandomChar(o), a += this.getRandomChar(s);
49
+ for (let c = a.length; c < t; c++)
50
+ a += this.getRandomChar(i);
51
+ return a = a.split("").sort(() => I(!0) - 0.5).join(""), a;
52
+ }
53
+ getRandomChar(t) {
54
+ const e = Math.floor(I(!0) * t.length);
55
+ return t[e];
56
+ }
57
+ }
58
+ const L = new v();
59
+ class V {
60
+ /**
61
+ * 清除 url 中重复的斜杠
62
+ * @param url 链接地址
63
+ * @returns 链接地址
64
+ * @public
65
+ */
66
+ cleanUrl(t) {
67
+ return t.replace(/([^:]|^)\/{2,}/g, "$1/");
68
+ }
69
+ }
70
+ const C = new V();
71
+ class N {
72
+ constructor(t) {
73
+ /**
74
+ * 应用标识
75
+ */
76
+ p(this, "appIdCode");
77
+ /**
78
+ * 随机数前缀
79
+ */
80
+ p(this, "noncePrefix");
81
+ this.appIdCode = t, this.noncePrefix = this.generateRandomString();
82
+ }
83
+ /**
84
+ * 生成随机数
85
+ * @returns
86
+ */
87
+ generateRandomString() {
88
+ return L.randomStr(8);
89
+ }
90
+ /**
91
+ * 生成签名参数
92
+ * @returns
93
+ */
94
+ generateSignatureOption() {
95
+ return {
96
+ nonce: `${this.noncePrefix}_${this.generateRandomString()}`,
97
+ timestamp: Date.now().toString().substring(0, 10)
98
+ };
99
+ }
100
+ stringToUTF8ByteSize(t) {
101
+ return new TextEncoder().encode(t).length;
102
+ }
103
+ isStringOverKB(t, e) {
104
+ return this.stringToUTF8ByteSize(t) > e * 1024;
105
+ }
106
+ /**
107
+ * 去除空参数
108
+ * @param param - 参数
109
+ * @returns
110
+ */
111
+ removeNilValue(t) {
112
+ if (g(t) === "object") {
113
+ for (const e in t)
114
+ if (Object.prototype.hasOwnProperty.call(t, e)) {
115
+ const n = t[e], o = g(n);
116
+ o === "object" ? this.removeNilValue(n) : (o === "null" || o === "undefined" || o === "function") && delete t[e];
117
+ }
118
+ }
119
+ }
120
+ /**
121
+ * 格式化 url value
122
+ * @param value - 值
123
+ * @returns
124
+ */
125
+ formatEncodeValue(t) {
126
+ const e = g(t);
127
+ return encodeURIComponent(e === "undefined" || e === "function" ? "" : t).replace(/%00/g, "\0").replace(/%2B/g, "+").replace(/%20/g, "+").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/'/g, "%27").replace(/!/g, "%21").replace(/~/g, "%7E");
128
+ }
129
+ /**
130
+ * 格式化 url params
131
+ * @param params - 参数列表
132
+ * @param key - 参数键
133
+ * @param param - 参数
134
+ * @returns
135
+ */
136
+ formatEncodeParam(t, e, n) {
137
+ const o = g(n);
138
+ if (o === "object") {
139
+ const s = Object.keys(n).sort();
140
+ s.length === 0 ? t.push(`${e}={}`) : s.forEach((i) => {
141
+ this.formatEncodeParam(t, e === "" ? `${i}` : `${e}[${i}]`, n[i]);
142
+ });
143
+ } else o === "array" ? n.length === 0 ? t.push(`${e}=[]`) : n.forEach((s) => {
144
+ this.formatEncodeParam(t, `${e}[]`, s);
145
+ }) : t.push(`${e}=${this.formatEncodeValue(n)}`);
146
+ }
147
+ /**
148
+ * 参数排序
149
+ * @param param - 参数
150
+ * @returns
151
+ */
152
+ sortParamByKey(t = {}) {
153
+ const e = [];
154
+ return this.formatEncodeParam(e, "", t), e.join("&");
155
+ }
156
+ /**
157
+ * 签名加密
158
+ * @param url - 请求地址
159
+ * @returns
160
+ */
161
+ cryptoHash(t) {
162
+ return U.HmacSHA1(t, this.appIdCode.code).toString(U.enc.Hex).toUpperCase();
163
+ }
164
+ /**
165
+ * 获取 url 参数
166
+ * @param url - 请求地址
167
+ * @returns
168
+ */
169
+ urlSearchParams(t) {
170
+ return t && t.indexOf("?") > -1 ? b.parse(t.split("?").pop() ?? "") : {};
171
+ }
172
+ /**
173
+ * 获取签名 url
174
+ * @param href - 请求地址
175
+ * @returns 签名 url
176
+ * @public
177
+ */
178
+ signatureHref(t) {
179
+ try {
180
+ const { pathname: e, origin: n } = new URL(t, window.location.origin), o = this.urlSearchParams(t), s = this.generateSignatureOption();
181
+ u(o, s);
182
+ const i = this.sortParamByKey(o), c = `${C.cleanUrl(`/${e}`)}?${i}`, h = this.cryptoHash(c);
183
+ t = `${n}${c}&signature=${h}`;
184
+ } catch {
185
+ console.error("签名失败,请使用有效的链接", t);
186
+ }
187
+ return t;
188
+ }
189
+ /**
190
+ * 获取签名参数
191
+ * @param config - Axios 请求配置
192
+ * @returns 签名参数
193
+ * @public
194
+ */
195
+ signatureConfig(t) {
196
+ var e, n, o, s;
197
+ try {
198
+ const a = ((e = t.method) == null ? void 0 : e.toUpperCase()) === "GET", c = A(t.data), h = c !== null && typeof c == "object", f = ((o = (n = t.headers) == null ? void 0 : n["Content-Type"]) == null ? void 0 : o.toString()) || "", R = f.includes("multipart/form-data");
199
+ let y = f.includes("application/json");
200
+ !a && !f && h && (y = !0), u(t, { headers: { "App-Id": this.appIdCode.id } });
201
+ const m = {}, O = this.urlSearchParams(t.url);
202
+ if (u(m, O), !d(t.params)) {
203
+ const l = A(t.params);
204
+ this.removeNilValue(l), t.params = l, u(m, b.parse(b.stringify(l)));
205
+ }
206
+ !d(c) && h && !R && !y && u(m, c);
207
+ const S = this.generateSignatureOption();
208
+ u(m, S);
209
+ let w = this.sortParamByKey(m);
210
+ if (y) {
211
+ const l = JSON.stringify(c);
212
+ this.isStringOverKB(l, 128) || (h ? w += this.formatEncodeValue(l) : w += this.formatEncodeValue(c));
213
+ }
214
+ let $ = "";
215
+ (s = t.url) != null && s.startsWith("http") ? $ = t.url : $ = `${t.baseURL}/${t.url || ""}`;
216
+ const { pathname: P } = new URL($, window.location.origin), T = `${C.cleanUrl(`/${P}`)}?${w}`;
217
+ S.signature = this.cryptoHash(T), t.params = u({}, t.params, S);
218
+ } catch (i) {
219
+ console.error("签名失败", i);
220
+ }
221
+ }
222
+ }
223
+ const H = {
224
+ id: "mis",
225
+ code: "c9d8e36df18ef01ff0da74e0bb13151c"
226
+ }, K = new N(H);
227
+ class z {
228
+ constructor() {
229
+ p(this, "axiosInstance");
230
+ p(this, "egovaAdminToken");
231
+ }
232
+ /**
233
+ * 初始化统一用户中心的axios
234
+ * @param baseUrl 统一用户中心的baseUrl
235
+ * @param token 统一用户中心的token
236
+ */
237
+ init(t, e) {
238
+ this.egovaAdminToken = e, this.axiosInstance = E.create({
239
+ baseURL: t,
240
+ timeout: 6e4
241
+ }), this.configAxios();
242
+ }
243
+ getAxiosInstance() {
244
+ return this.axiosInstance;
245
+ }
246
+ // 配置axios
247
+ configAxios() {
248
+ var t;
249
+ (t = this.axiosInstance) == null || t.interceptors.request.use(
250
+ async (e) => (this.configToken(e), this.configSignature(e), e),
251
+ (e) => Promise.reject(e)
252
+ );
253
+ }
254
+ /**
255
+ * 配置token
256
+ * @param config
257
+ */
258
+ configToken(t) {
259
+ const e = /^\/?(free)\//;
260
+ t.url && !e.test(t.url) && this.egovaAdminToken && u(t, { headers: { "X-Authorization": `bearer ${this.egovaAdminToken}` } });
261
+ }
262
+ /**
263
+ * 接口签名
264
+ * @param config
265
+ */
266
+ configSignature(t) {
267
+ K.signatureConfig(t);
268
+ }
269
+ }
270
+ const x = new z();
271
+ function _(r) {
272
+ var t;
273
+ return (t = x.getAxiosInstance()) == null ? void 0 : t.get("/unity/org/human/gethumanlist", { params: r });
274
+ }
275
+ function W(r) {
276
+ var t;
277
+ return (t = x.getAxiosInstance()) == null ? void 0 : t.get("/unity/builder/org/gettenantunittree", { params: r });
278
+ }
279
+ function X(r) {
280
+ var o;
281
+ const t = "/unity/org/unit/countunithumannumber", e = [];
282
+ d(r.tenantId) || e.push(`tenantId=${r.tenantId}`), d(r.roleId) || e.push(`roleId=${r.roleId}`), d(r.onlyQueryUnbound) || e.push(`onlyQueryUnbound=${r.onlyQueryUnbound}`), d(r.permissionId) || e.push(`permissionId=${r.permissionId}`);
283
+ const n = e.length ? `${t}?${e.join("&")}` : t;
284
+ return (o = x.getAxiosInstance()) == null ? void 0 : o.post(n, r.ids);
285
+ }
286
+ export {
287
+ x as adminAxios,
288
+ X as countUnitHuman,
289
+ W as getUnitTree,
290
+ _ as gethumanlist
291
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "egova-admin-jssdk",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "run-p type-check build-lib build-type",
8
+ "build-lib": "vite build",
9
+ "build-type": "vue-tsc --declaration --emitDeclarationOnly",
10
+ "type-check": "vue-tsc --build"
11
+ },
12
+ "peerDependencies": {
13
+ "axios": ">=0.29.0",
14
+ "crypto-js": ">=4.1.1",
15
+ "lodash-es": ">=4.17.21",
16
+ "qs": ">=6.13.1"
17
+ },
18
+ "dependencies": {
19
+ "axios": "^1.7.9",
20
+ "crypto-js": "^4.2.0",
21
+ "lodash-es": "^4.17.21",
22
+ "qs": "^6.13.1",
23
+ "vue": "^3.5.13"
24
+ },
25
+ "devDependencies": {
26
+ "@tsconfig/node22": "^22.0.0",
27
+ "@types/crypto-js": "^4.2.2",
28
+ "@types/lodash-es": "^4.17.12",
29
+ "@types/node": "^22.10.2",
30
+ "@types/qs": "^6.9.17",
31
+ "@vitejs/plugin-vue": "^5.2.1",
32
+ "@vue/eslint-config-prettier": "^10.1.0",
33
+ "@vue/eslint-config-typescript": "^14.1.3",
34
+ "@vue/tsconfig": "^0.7.0",
35
+ "eslint": "^9.14.0",
36
+ "eslint-plugin-vue": "^9.30.0",
37
+ "npm-run-all2": "^7.0.2",
38
+ "prettier": "^3.3.3",
39
+ "typescript": "~5.6.3",
40
+ "vite": "^6.0.5",
41
+ "vite-plugin-vue-devtools": "^7.6.8",
42
+ "vue-tsc": "^2.1.10"
43
+ },
44
+ "files": [
45
+ "lib",
46
+ "dist"
47
+ ],
48
+ "main": "lib/egova-admin-jssdk.mjs",
49
+ "types": "dist/index.d.ts",
50
+ "publishConfig": {
51
+ "access": "public"
52
+ }
53
+ }