apass-opensdk-hugong 1.0.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/index.js CHANGED
@@ -1,5 +1,9 @@
1
1
  const Users = require('./opensdk/users')
2
2
  const Document = require('./opensdk/document')
3
+ const Utils = require('./utils/index')
4
+ const Employee = require('./opensdk/employee')
5
+ const Contract = require('./opensdk/contract')
6
+
3
7
  class HG{
4
8
  #logger
5
9
  #app_id
@@ -8,6 +12,10 @@ class HG{
8
12
  this.#logger = logger
9
13
  this.users = new Users(logger, this)
10
14
  this.document = new Document(logger, this)
15
+ this.employee = new Employee(logger, this)
16
+ this.contract = new Contract(logger, this)
17
+
18
+ this.utils = new Utils(logger, this)
11
19
  this._time = null
12
20
  }
13
21
  /**
@@ -62,41 +70,128 @@ class HG{
62
70
  this.#app_id = app_id
63
71
  this.#app_secret = app_secret
64
72
  }
73
+
65
74
  /**
66
75
  * 开平token
67
76
  * @returns
68
77
  */
69
78
  async getToken(){
70
- const result = await this.request('https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal',{ app_id: this.#app_id, app_secret: this.#app_secret})
79
+ const result = await this.request('https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal',{ app_id: this.#app_id, app_secret: this.#app_secret},false)
71
80
  return result.tenant_access_token
72
81
  }
73
82
 
83
+ async requestGet(url, params, headers=true){
84
+ return this.request([url, params], null, headers, 'GET')
85
+ }
86
+
74
87
  /**
75
88
  * 统一网络请求
76
89
  * @param {*} url
90
+ * @param {*} params
77
91
  * @param {*} data
78
92
  * @param {*} headers
93
+ * @param {*} method
79
94
  * @returns
80
95
  */
81
- async request(url, data, headers){
82
- let HGheader = { 'Content-Type': 'application/json; charset=utf-8' }
96
+ async request(url, data, headers = true, method = 'POST'){
97
+ let newHeaders = { 'Content-Type': 'application/json; charset=utf-8' }
83
98
  if(typeof headers === 'boolean' && headers === true){
84
- HGheader['Authorization'] = `Bearer ${ await this.getToken() }`
99
+ newHeaders['Authorization'] = `Bearer ${ await this.getToken() }`
85
100
  }else{
86
- HGheader = { ...HGheader,...(headers || {}) }
101
+ newHeaders = { ...newHeaders,...(headers || {}) }
102
+ }
103
+ this.#logger.log('req=',url,data,newHeaders)
104
+ let _url = url
105
+ let params = null
106
+ if(Array.isArray(url)){
107
+ _url = url[0]
108
+ params = url[1]
87
109
  }
88
- this.#logger.log('req=',url,data,HGheader)
89
110
  return new Promise((r,s)=>{
90
111
  const now = Date.now()
91
- axios({ method: 'POST', url, data, headers: HGheader}).then(response=>{
112
+ axios({ method, params, url: _url, data, headers: newHeaders}).then(response=>{
92
113
  this.#logger.info('resp=',(Date.now() - now) / 1000, 's',response.status, response.statusText,response.data)
93
114
  r(response.data)
94
115
  }).catch(e=>{
116
+ console.log(e)
95
117
  this.#logger.error('resp=',(Date.now() - now) / 1000, 's',e.response.data)
96
118
  s(e.response.data)
97
119
  })
98
120
  })
99
121
  }
122
+ /**
123
+ * 分页返回开放平台数据
124
+ * @param {*} url
125
+ * @param {*} params
126
+ * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
127
+ * @returns 如果callback为传递则一次性返回所有的数据
128
+ */
129
+ async paginatedSearchGet(url,params,callback){
130
+ return this.paginatedSearch(url, params, null, callback, 'GET')
131
+ }
132
+ /**
133
+ * 分页返回开放平台数据
134
+ * @param {*} url
135
+ * @param {*} params
136
+ * @param {*} data
137
+ * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
138
+ * @returns 如果callback为传递则一次性返回所有的数据
139
+ */
140
+ async paginatedSearch(url,params,data,callback,method='POST'){
141
+ let list = []
142
+ let page_token = null
143
+ let has_more = false
144
+ do {
145
+ const result = await this.request([url, {...(params || {page_size: 100}), page_token}],data,true,method)
146
+ page_token = result.data.page_token
147
+ has_more = result.data.has_more
148
+ if(callback){
149
+ await callback(result.data.items || [])
150
+ }else{
151
+ list.push(...(result.data.items || []))
152
+ }
153
+ } while (has_more);
154
+ return list
155
+ }
156
+
157
+ async getAllUser(field){
158
+ const list = []
159
+ await application.data.object('_user').select(field || ['_id','_name']).findStream(async records=>list.push(...records))
160
+ return list
161
+ }
162
+
163
+ /**
164
+ * 生成多语言对象
165
+ * @param {*} zh
166
+ * @param {*} en
167
+ * @returns
168
+ */
169
+ toMultilingual(zh,en){
170
+ if(Array.isArray(zh)){
171
+ //开放平台一般返回内容
172
+ if(zh[0].hasOwnProperty('lang')){
173
+ return new application.constants.type.Multilingual({ zh: this.toSafeValue(zh.find(it=>it.lang == 'zh-CN'),'value'), en: this.toSafeValue(zh.find(it=>it.lang == 'en-US'),'value') })
174
+ }
175
+ }
176
+ return new application.constants.type.Multilingual({ zh, en })
177
+ }
178
+
179
+ /**
180
+ * 安全的取值
181
+ * @param {*} obj
182
+ * @param {*} key
183
+ * @param {*} defValue
184
+ * @returns
185
+ */
186
+ toSafeValue(obj,key,defValue){
187
+ if(!obj){
188
+ return defValue
189
+ }
190
+ if(!obj.hasOwnProperty(key)){
191
+ return defValue
192
+ }
193
+ return obj[key] || defValue
194
+ }
100
195
 
101
196
  }
102
197
  module.exports = HG
@@ -0,0 +1,19 @@
1
+ class Contract{
2
+ #hg = null
3
+ #logger = null
4
+ constructor(logger,hg){
5
+ this.#logger = logger
6
+ this.#hg = hg
7
+ }
8
+
9
+ /**
10
+ * 通过手机号或邮箱获取用户 ID
11
+ * @param {*} user_id_type user_id、open_id、union_id
12
+ * @returns
13
+ */
14
+ async batch_get_id(data,user_id_type){
15
+ return await this.#hg.request(`https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=${user_id_type || 'open_id'}`,data,true)
16
+ }
17
+
18
+ }
19
+ module.exports = Contract
@@ -1,48 +1,48 @@
1
1
  class Document{
2
- #logger = null
3
- #hg = null
4
- constructor(logger,hg){
5
- this.#logger = logger
6
- this.#hg = hg
7
- }
8
- /**
9
- * 增加协作者权限 https://open.feishu.cn/document/server-docs/docs/permission/permission-member/create
10
- * @param {*} app_token app_token 多维表格 App 的唯一标识
11
- * @param {*} type 文件类型 bitable:多维表格
12
- * @param {*} data {
13
- "member_type": "openchat",
14
- "member_id": "oc_b962e8debdc37712a1d60bb97087a8e8",
15
- "perm": "edit",
16
- "perm_type": "container",
17
- "type": "chat"
18
- }
19
- */
20
- async permissions(app_token,type,data){
21
- if(!type){
22
- throw 'type is not empty'
2
+ #logger = null
3
+ #hg = null
4
+ constructor(logger,hg){
5
+ this.#logger = logger
6
+ this.#hg = hg
7
+ }
8
+ /**
9
+ * 增加协作者权限 https://open.feishu.cn/document/server-docs/docs/permission/permission-member/create
10
+ * @param {*} app_token app_token 多维表格 App 的唯一标识
11
+ * @param {*} type 文件类型 bitable:多维表格
12
+ * @param {*} data {
13
+ "member_type": "openchat",
14
+ "member_id": "oc_b962e8debdc37712a1d60bb97087a8e8",
15
+ "perm": "edit",
16
+ "perm_type": "container",
17
+ "type": "chat"
23
18
  }
24
- return await this.#hg.request(`https://open.feishu.cn/open-apis/drive/v1/permissions/${app_token}/members?type=${type}&need_notification=false`,data,true)
25
- }
26
- /**
27
- * 复制多维表格 https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/copy
28
- * @param {*} app_token 要复制的多维表格 App 的唯一标识
29
- * @param {*} name 多维表格 App 名称。最长为 255 个字符
30
- * @param {*} folder_token 文件夹
31
- * @returns
32
- */
33
- async copy(app_token,name,folder_token,without_content,time_zone){
34
- return await this.#hg.request(`https://open.feishu.cn/open-apis/bitable/v1/apps/${app_token}/copy`,{ name,folder_token,without_content: without_content || false,time_zone: time_zone || 'Asia/Shanghai' },true)
19
+ */
20
+ async permissions(app_token,type,data){
21
+ if(!type){
22
+ throw 'type is not empty'
35
23
  }
36
- /**
37
- * 创建多维表格 https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/create
38
- * @param {*} name 多维表格 App 名称
39
- * @param {*} folder_token 多维表格 App 归属文件夹
40
- * @param {*} time_zone
41
- * @returns
42
- */
43
- async create(name, folder_token, time_zone){
44
- return await this.#hg.request('https://open.feishu.cn/open-apis/bitable/v1/apps',{ name, folder_token, time_zone: time_zone || 'Asia/Shanghai' },true)
45
- }
46
-
24
+ return await this.#hg.request(`https://open.feishu.cn/open-apis/drive/v1/permissions/${app_token}/members?type=${type}&need_notification=false`,data,true)
25
+ }
26
+ /**
27
+ * 复制多维表格 https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/copy
28
+ * @param {*} app_token 要复制的多维表格 App 的唯一标识
29
+ * @param {*} name 多维表格 App 名称。最长为 255 个字符
30
+ * @param {*} folder_token 文件夹
31
+ * @returns
32
+ */
33
+ async copy(app_token,name,folder_token,without_content,time_zone){
34
+ return await this.#hg.request(`https://open.feishu.cn/open-apis/bitable/v1/apps/${app_token}/copy`,{ name,folder_token,without_content: without_content || false,time_zone: time_zone || 'Asia/Shanghai' },true)
35
+ }
36
+ /**
37
+ * 创建多维表格 https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/create
38
+ * @param {*} name 多维表格 App 名称
39
+ * @param {*} folder_token 多维表格 App 归属文件夹
40
+ * @param {*} time_zone
41
+ * @returns
42
+ */
43
+ async create(name, folder_token, time_zone){
44
+ return await this.#hg.request('https://open.feishu.cn/open-apis/bitable/v1/apps',{ name, folder_token, time_zone: time_zone || 'Asia/Shanghai' },true)
47
45
  }
48
- module.exports = Document
46
+
47
+ }
48
+ module.exports = Document
@@ -0,0 +1,20 @@
1
+ class Employee{
2
+ #hg = null
3
+ #logger = null
4
+ constructor(logger,hg){
5
+ this.#logger = logger
6
+ this.#hg = hg
7
+ }
8
+
9
+ /**
10
+ * 搜索员工信息
11
+ * @param {*} params
12
+ * @param {*} data
13
+ * @param {*} callback(items) 结果回调(根据总数可能多次调用)
14
+ */
15
+ async search(params,data,callback){
16
+ return await this.#hg.paginatedSearch(`https://open.feishu.cn/open-apis/corehr/v2/employees/search`,params,data,callback)
17
+ }
18
+
19
+ }
20
+ module.exports = Employee
package/opensdk/users.js CHANGED
@@ -1,19 +1,19 @@
1
1
  class Users{
2
- #hg = null
3
- #logger = null
4
- constructor(logger,hg){
5
- this.#logger = logger
6
- this.#hg = hg
7
- }
8
-
9
- /**
10
- * 通过手机号或邮箱获取用户 ID
11
- * @param {*} user_id_type user_id、open_id、union_id
12
- * @returns
13
- */
14
- async batch_get_id(data,user_id_type){
15
- return await this.#hg.request(`https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=${user_id_type || 'open_id'}`,data,true)
16
- }
2
+ #hg = null
3
+ #logger = null
4
+ constructor(logger,hg){
5
+ this.#logger = logger
6
+ this.#hg = hg
7
+ }
17
8
 
9
+ /**
10
+ * 通过手机号或邮箱获取用户 ID
11
+ * @param {*} user_id_type user_id、open_id、union_id
12
+ * @returns
13
+ */
14
+ async batch_get_id(data,user_id_type){
15
+ return await this.#hg.request(`https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=${user_id_type || 'open_id'}`,data,true)
18
16
  }
19
- module.exports = Users
17
+
18
+ }
19
+ module.exports = Users
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apass-opensdk-hugong",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "飞书Apass低代码平台-飞书开放平台-相关的接口整合和常用的方法整合",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/readme.md ADDED
@@ -0,0 +1,115 @@
1
+ # apass-opensdk-hugong
2
+ ## 简介
3
+ apass-opensdk-hugong 是一个基于apass-opensdk的封装,提供了一些常用的功能,如:
4
+ - 什么人可以使用这个SDK
5
+ - 从事飞书低代码平台(APASS)开发人员.
6
+
7
+ ## 安装
8
+
9
+ ```
10
+ 在飞书低代码平台(云函数)依赖管理-右侧-搜索: apass-opensdk-hugong
11
+ ```
12
+
13
+ ## 如何使用
14
+ ```
15
+ const Hugong = require('apass-opensdk-hugong');
16
+ const hg = new Hugong(logger)
17
+
18
+ do something
19
+ ```
20
+ ## 常用
21
+ ```
22
+ 显示运行时间
23
+ hg.newTime()
24
+ hg.printTime()
25
+
26
+ 线程睡眠
27
+ await hg.sleep(2000)
28
+
29
+ 支持将数组分割成指定长度分段数组
30
+ 第一种用法,一次性返还分割后的数组 [ [50],[50] ]
31
+ const list = hg.utils.splitArray([], 50)
32
+
33
+ 第二种用法,每次输出50条 处理完成后继续下次执行
34
+ await hg.utils.splitArray([], 10, async (items)=>{
35
+ // do something
36
+ })
37
+
38
+ ```
39
+
40
+ ## 小工具/多语言
41
+
42
+ ```
43
+ 对象数据新增多语言对象
44
+
45
+ 生成多语言对象
46
+ hg.toMultilingual([{ lang: 'en-US', value: 'Regular' },{ lang: 'zh-CN', value: '正式' }]) 常用于开放平台返回的多语言数据转换
47
+ hg.toMultilingual(zh,en)
48
+
49
+ /**
50
+ * 安全的取值
51
+ * @param {*} obj
52
+ * @param {*} key
53
+ * @param {*} defValue 默认值
54
+ */
55
+ toSafeValue(obj,key,defValue)
56
+
57
+ ```
58
+
59
+ ## 飞书人事
60
+
61
+ 搜索员工信息
62
+
63
+ ```
64
+ 设置appid和appsecret
65
+ await hg.setAppId('cli_000000000','0000000000000')
66
+
67
+ /**
68
+ * 搜索员工信息
69
+ * @param {*} params
70
+ * @param {*} data
71
+ * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
72
+ * @returns 如果callback为传递则一次性返回所有的数据
73
+ */
74
+ await hg.employee.search(params,data,callback)
75
+
76
+ // 示例[具体参数请参考开放平台定义](https://open.feishu.cn/document/server-docs/corehr-v1/employee/search)
77
+ await hg.employee.search({ page_size:100,user_id_type:'user_id',},{ /* 要查询的字段 */}, async (items)=>{
78
+ // do something 假设服务端有300条数据,每次返回100条,会调用3次, 如果希望一次性返回所有数据,callback传null即可
79
+ })
80
+ const list = await hg.employee.search(params,data) //这将一次性返回所有数据
81
+ ```
82
+ ## 开放平台分页获取所有数据
83
+
84
+ 所有的分页接口都可以使用
85
+
86
+ ```
87
+ 设置appid和appsecret
88
+ await hg.setAppId('cli_000000000','0000000000000')
89
+
90
+ /**
91
+ * GET类型接口分页返回开放平台数据
92
+ * @param {*} url
93
+ * @param {*} params
94
+ * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
95
+ * @returns callback为null,则一次性返回所有的数据
96
+ */
97
+ hg.paginatedSearchGet(url,params,callback)
98
+
99
+ /**
100
+ * POST接口分页返回开放平台数据
101
+ * @param {*} url
102
+ * @param {*} params
103
+ * @param {*} data
104
+ * @param {*} callback callback(items) 结果回调(根据总数可能多次调用)- 可选
105
+ * @returns callback为null,则一次性返回所有的数据
106
+ */
107
+ await hg.paginatedSearch(url,params,data,callback)
108
+
109
+ 示例1
110
+ const list = await hg.paginatedSearchGet(url, params, data)
111
+ 示例2
112
+ await hg.paginatedSearchGet(url, params, async (items)=>{
113
+ // do something 假设服务端有300条数据,每次返回100条,会调用3次, 如果希望一次性返回所有数据,callback传null即可
114
+ })
115
+ ```
package/utils/index.js ADDED
@@ -0,0 +1,33 @@
1
+ const Url = require('./url')
2
+ class Utils{
3
+ #hg = null
4
+ #logger = null
5
+ constructor(logger,hg){
6
+ this.#logger = logger
7
+ this.#hg = hg
8
+
9
+ this.url = new Url(logger,hg)
10
+ }
11
+
12
+ /**
13
+ * 数组分割
14
+ * @param {*} list
15
+ * @param {*} chunkSize 分割长度
16
+ * @param {*} callback(item) 分割后回调(不传递则方法返回切割长度后的数组)
17
+ * @returns
18
+ */
19
+ async splitArray(list, chunkSize, callback) {
20
+ const result = [];
21
+ for (let i = 0; i < list.length; i += chunkSize) {
22
+ const batch = list.slice(i, i + chunkSize)
23
+ if(callback){
24
+ await callback(batch)
25
+ continue
26
+ }
27
+ result.push(batch); // 使用 slice 方法按 chunkSize 进行切割
28
+ }
29
+ return result;
30
+ }
31
+
32
+ }
33
+ module.exports = Utils
package/utils/url.js ADDED
@@ -0,0 +1,20 @@
1
+ class Url{
2
+ #hg = null
3
+ #logger = null
4
+ constructor(logger,hg){
5
+ this.#logger = logger
6
+ this.#hg = hg
7
+ }
8
+
9
+ jsonToUrlParams(jsonData) {
10
+ const params = new URLSearchParams();
11
+ for (const key in jsonData) {
12
+ if (jsonData[key]) {
13
+ params.append(key, jsonData[key]);
14
+ }
15
+ }
16
+ return params.toString();
17
+ }
18
+
19
+ }
20
+ module.exports = Url